From 9802febef355a37ce7784192c93212f08b9aa5e5 Mon Sep 17 00:00:00 2001 From: Chneemann Date: Sat, 22 Aug 2026 06:56:07 +0200 Subject: [PATCH] refactor(auth): extract handleSignOut server action into dedicated module to fix client build error --- actions/auth.actions.ts | 31 +++++++++++++++++++++ app/components/layout/MobileLegalMenu.tsx | 4 +++ app/components/layout/Sidebar.tsx | 6 ++-- app/components/ui/buttons/SignOutButton.tsx | 26 +++++++++++------ auth.ts | 22 --------------- 5 files changed, 54 insertions(+), 35 deletions(-) create mode 100644 actions/auth.actions.ts diff --git a/actions/auth.actions.ts b/actions/auth.actions.ts new file mode 100644 index 0000000..a6a9881 --- /dev/null +++ b/actions/auth.actions.ts @@ -0,0 +1,31 @@ +/** + * @file actions/auth.actions.ts + * @description Server actions for handling user logout and status updates. + */ + +"use server"; + +import { auth, signOut } from "@/auth"; +import { db } from "@/db"; +import { usersTable } from "@/db/schema"; +import { eq } from "drizzle-orm"; + +/** + * Handles user sign-out by updating the user's online status to offline in the database + * and terminating the active session, redirecting to the homepage. + * + * @async + * @returns {Promise} Resolves when the user is signed out and redirected. + */ +export async function handleSignOut() { + const session = await auth(); + + if (session?.user?.id) { + await db + .update(usersTable) + .set({ isOnline: false }) + .where(eq(usersTable.id, session.user.id)); + } + + await signOut({ redirectTo: "/" }); +} diff --git a/app/components/layout/MobileLegalMenu.tsx b/app/components/layout/MobileLegalMenu.tsx index 9b1fee5..d88c6f1 100644 --- a/app/components/layout/MobileLegalMenu.tsx +++ b/app/components/layout/MobileLegalMenu.tsx @@ -9,6 +9,7 @@ import { useState, useRef, useEffect } from "react"; import Link from "next/link"; import { MoreHorizontal, X } from "lucide-react"; import { LEGAL_LINKS, COPYRIGHT_TEXT, ICON_MAP } from "@/utils/legal"; +import SignOutButton from "../ui/buttons/SignOutButton"; /** * Renders a mobile menu button and a slide-up modal overlay containing @@ -130,6 +131,9 @@ export default function MobileLegalMenu() { ); })} + + {/* Sign Out Button */} + {/* Shared Copyright */} diff --git a/app/components/layout/Sidebar.tsx b/app/components/layout/Sidebar.tsx index e80d208..a791b0a 100644 --- a/app/components/layout/Sidebar.tsx +++ b/app/components/layout/Sidebar.tsx @@ -1,5 +1,5 @@ /** - * @file Sidebar.tsx + * @file components/layout/Sidebar.tsx * @description Server/Client component rendering the desktop application sidebar layout including the brand logo, navigation links, and sign-out option. */ @@ -23,9 +23,7 @@ export default function Sidebar() { {/* Lower Section */} -
- -
+ ); } diff --git a/app/components/ui/buttons/SignOutButton.tsx b/app/components/ui/buttons/SignOutButton.tsx index bd62a68..d7dbc85 100644 --- a/app/components/ui/buttons/SignOutButton.tsx +++ b/app/components/ui/buttons/SignOutButton.tsx @@ -1,25 +1,33 @@ /** - * @file SignOutButton.tsx - * @description Server Action-powered client component rendering a sign-out button that triggers session termination via a server action. + * @file components/ui/buttons/SignOutButton.tsx + * @description Server Action-powered client component rendering a sign-out button with customizable alignment. */ -import { handleSignOut } from "@/auth"; +import { handleSignOut } from "@/actions/auth.actions"; import { LogOut } from "lucide-react"; /** - * Renders a form containing a submit button to securely sign out the current user session using a server action. + * Renders a sign-out button wrapped in a form that invokes the handleSignOut Server Action upon submission. * + * @param {Object} props - The component props. + * @param {"left" | "center"} [props.align="left"] - Text and content alignment for the button contents. * @returns {JSX.Element} The rendered sign-out button component. */ -export default function SignOutButton() { +export default function SignOutButton({ + align = "left", +}: { + align?: "left" | "center"; +}) { return ( -
+
); diff --git a/auth.ts b/auth.ts index 3252851..bb3c402 100644 --- a/auth.ts +++ b/auth.ts @@ -95,25 +95,3 @@ export const { handlers, auth, signIn, signOut } = NextAuth({ }, }, }); - -/** - * Handles the secure logout process, setting the user's online status to false in the database - * and destroying the active session. - * - * @async - * @returns {Promise} - */ -export async function handleSignOut() { - "use server"; - - const session = await auth(); - - if (session?.user?.id) { - await db - .update(usersTable) - .set({ isOnline: false }) - .where(eq(usersTable.id, session.user.id)); - } - - await signOut({ redirectTo: "/" }); -}