diff --git a/src/components/ui/provider.tsx b/src/components/ui/provider.tsx
index d604350..1286b30 100644
--- a/src/components/ui/provider.tsx
+++ b/src/components/ui/provider.tsx
@@ -6,15 +6,18 @@ import { ColorModeProvider, type ColorModeProviderProps } from "./color-mode";
import { system } from "../../theme/theme";
import { Toaster } from "./feedback/toaster";
import TopLoader from "./top-loader";
+import ReactQueryProvider from "@/provider/react-query-provider";
export function Provider(props: ColorModeProviderProps) {
return (
-
-
-
-
-
+
+
+
+
+
+
+
);
}
diff --git a/src/config/navigation.ts b/src/config/navigation.ts
index 26626bf..19c44ce 100644
--- a/src/config/navigation.ts
+++ b/src/config/navigation.ts
@@ -1,15 +1,14 @@
-export type NavChildItem = {
- label: string;
- href: string;
-};
-
export type NavItem = {
label: string;
href: string;
- children?: NavChildItem[];
+ protected?: boolean;
+ public?: boolean;
+ onlyPublic?: boolean;
+ visible?: boolean;
+ children?: NavItem[];
};
export const NAV_ITEMS: NavItem[] = [
- { label: "home", href: "/home" },
- { label: "about", href: "/about" },
+ { label: "home", href: "/home", public: true },
+ { label: "predictions", href: "/predictions", public: true },
];
diff --git a/src/provider/react-query-provider.tsx b/src/provider/react-query-provider.tsx
new file mode 100644
index 0000000..3a96bbe
--- /dev/null
+++ b/src/provider/react-query-provider.tsx
@@ -0,0 +1,16 @@
+"use client";
+
+import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
+import { ReactNode } from "react";
+
+interface Props {
+ children: ReactNode;
+}
+
+export default function ReactQueryProvider({ children }: Props) {
+ const queryClient = new QueryClient();
+
+ return (
+ {children}
+ );
+}
diff --git a/src/proxy.ts b/src/proxy.ts
index 5a8a588..4e17c5a 100644
--- a/src/proxy.ts
+++ b/src/proxy.ts
@@ -1,50 +1,55 @@
-import { NextResponse } from 'next/server';
-import { withAuth } from 'next-auth/middleware';
-import createIntlMiddleware from 'next-intl/middleware';
-import { routing } from './i18n/routing';
+import { NAV_ITEMS } from "@/config/navigation";
+import { withAuth } from "next-auth/middleware";
+import createMiddleware from "next-intl/middleware";
+import { NextRequest } from "next/server";
+import { routing } from "./i18n/routing";
-const intlMiddleware = createIntlMiddleware(routing);
+const publicPages = NAV_ITEMS.flatMap((item) => [
+ ...(!item.protected ? [item.href] : []),
+ ...(item.children
+ ?.filter((child) => !child.protected)
+ .map((child) => child.href) ?? []),
+]);
-const publicPaths = ['/signin', '/signup', '/forgot-password', '/reset-password'];
-const localizedPublicPaths = routing.locales.flatMap((locale) => publicPaths.map((path) => `/${locale}${path}`));
-const allPublicPaths = [...publicPaths, ...localizedPublicPaths];
+const handleI18nRouting = createMiddleware(routing);
-export default withAuth(
- async function middleware(req) {
- const intlResponse = intlMiddleware(req);
- if (intlResponse) return intlResponse;
-
- const token = req.nextauth?.token;
- const { pathname } = req.nextUrl;
-
- // Kullanıcı giriş yaptıysa ve public bir sayfadaysa → home'a yönlendir
- if (token && allPublicPaths.some((p) => pathname.startsWith(p))) {
- const redirectUrl = new URL(`/${routing.defaultLocale}/home`, req.url);
- return NextResponse.redirect(redirectUrl);
- }
-
- return NextResponse.next();
+const authMiddleware = withAuth(
+ // Note that this callback is only invoked if
+ // the `authorized` callback has returned `true`
+ // and not for pages listed in `pages`.
+ function onSuccess(req) {
+ return handleI18nRouting(req);
},
{
- pages: {
- signIn: `/${routing.defaultLocale}/signin`,
- },
callbacks: {
- /**
- * Eğer public route'taysa -> yetkilendirme kontrolü atla
- * Aksi halde -> token gerekli
- */
- authorized: ({ token, req }) => {
- const { pathname } = req.nextUrl;
- if (allPublicPaths.some((p) => pathname.startsWith(p))) {
- return true; // public sayfa, izin ver
- }
- return !!token; // diğerleri için token gerekli
- },
+ authorized: ({ token }) => token != null,
+ },
+ pages: {
+ signIn: "/home",
},
},
);
+export default function proxy(req: NextRequest) {
+ // CRITICAL: Skip API routes entirely - they should not go through i18n or auth middleware
+ if (req.nextUrl.pathname.startsWith("/api/")) {
+ return; // Return undefined to pass through without modification
+ }
+
+ const publicPathnameRegex = RegExp(
+ `^(/(${routing.locales.join("|")}))?(${publicPages.flatMap((p) => (p === "/" ? ["", "/"] : p)).join("|")})/?$`,
+ "i",
+ );
+ const isPublicPage = publicPathnameRegex.test(req.nextUrl.pathname);
+
+ if (isPublicPage) {
+ return handleI18nRouting(req);
+ } else {
+ return (authMiddleware as any)(req);
+ }
+}
+
export const config = {
- matcher: ['/((?!api|trpc|_next|_vercel|.*\\..*).*)'],
+ matcher: "/((?!api|trpc|_next|_vercel|.*\\..*).*)",
+ // matcher: ['/', '/(de|en|tr)/:path*'],
};