diff --git a/src/app/layout.tsx b/src/app/layout.tsx
index 027afb7..26b47e0 100644
--- a/src/app/layout.tsx
+++ b/src/app/layout.tsx
@@ -3,6 +3,7 @@ import type { Metadata, Viewport } from "next";
// import ThemeRegistry from "@/theme/ThemeRegistry";
import { detectLanguage } from "../i18n";
import ThemeRegistry from "../theme/ThemeRegistry";
+import SessionProviderWrapper from "@/components/SessionProviderWrapper/SessionProviderWrapper";
export const metadata: Metadata = {
title: "FPSMS",
@@ -27,7 +28,9 @@ export default async function RootLayout({
return (
- {children}
+
+ {children}
+
);
diff --git a/src/app/login/page.tsx b/src/app/login/page.tsx
index 5b91f93..78898a2 100644
--- a/src/app/login/page.tsx
+++ b/src/app/login/page.tsx
@@ -1,26 +1,19 @@
-import { getServerSession } from "next-auth";
-import { redirect } from "next/navigation";
-import { authOptions } from "@/config/authConfig";
import { I18nProvider } from "@/i18n";
import LoginPage from "@/components/LoginPage/LoginPage";
+import LoginRedirectIfAuthenticated from "@/components/LoginPage/LoginRedirectIfAuthenticated";
-type Props = { searchParams?: Promise<{ [key: string]: string | string[] | undefined }> };
-
-const Login: React.FC = async ({ searchParams }) => {
- const session = await getServerSession(authOptions);
- const params = await searchParams;
- const sessionParam = params?.session;
- const forceLogin = sessionParam === "expired" || (Array.isArray(sessionParam) && sessionParam.includes("expired"));
- const now = Math.floor(Date.now() / 1000);
- const notExpired = !session?.exp || session.exp > now;
- if (session?.user && notExpired && !forceLogin) {
- redirect("/");
- }
-
+/**
+ * Redirect when already authenticated is done in LoginRedirectIfAuthenticated
+ * (client-side with useSearchParams) so it works in production where server
+ * searchParams can be undefined after build.
+ */
+const Login: React.FC = () => {
return (
-
-
-
+
+
+
+
+
);
};
diff --git a/src/components/LoginPage/LoginRedirectIfAuthenticated.tsx b/src/components/LoginPage/LoginRedirectIfAuthenticated.tsx
new file mode 100644
index 0000000..a2ae5b4
--- /dev/null
+++ b/src/components/LoginPage/LoginRedirectIfAuthenticated.tsx
@@ -0,0 +1,31 @@
+"use client";
+
+import { useSession } from "next-auth/react";
+import { useSearchParams } from "next/navigation";
+import { useRouter } from "next/navigation";
+import { useEffect, type ReactNode } from "react";
+
+/**
+ * Client-side only: redirect to "/" when user is authenticated and this page
+ * was not opened after a 401 (session=expired). Relies on useSearchParams() so
+ * it works in production where server searchParams can be undefined.
+ */
+export default function LoginRedirectIfAuthenticated({
+ children,
+}: {
+ children: ReactNode;
+}) {
+ const { status } = useSession();
+ const searchParams = useSearchParams();
+ const router = useRouter();
+
+ useEffect(() => {
+ if (status !== "authenticated") return;
+ const sessionExpired = searchParams.get("session") === "expired";
+ if (!sessionExpired) {
+ router.replace("/");
+ }
+ }, [status, searchParams, router]);
+
+ return <>{children}>;
+}