refactor(auth): extract handleSignOut server action into dedicated module to fix client build error
All checks were successful
Deploy Flowstate to VPS / deploy (push) Successful in 5s

This commit is contained in:
Chneemann 2026-08-22 06:56:07 +02:00
parent f3a526a68c
commit 9802febef3
No known key found for this signature in database
5 changed files with 54 additions and 35 deletions

31
actions/auth.actions.ts Normal file
View file

@ -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<void>} 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: "/" });
}

View file

@ -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() {
</Link>
);
})}
{/* Sign Out Button */}
<SignOutButton />
</div>
{/* Shared Copyright */}

View file

@ -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() {
</div>
{/* Lower Section */}
<div className="flex justify-center">
<SignOutButton />
</div>
<SignOutButton align="center" />
</aside>
);
}

View file

@ -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 (
<form action={handleSignOut}>
<form action={handleSignOut} className="w-full">
<button
type="submit"
className="flex items-center gap-2 px-3 py-2 rounded-lg text-xs font-medium hover:text-primary-hover transition-colors w-full cursor-pointer"
className={`flex items-center gap-3 w-full px-3 py-2.5 rounded-lg text-sm font-medium text-destructive hover:bg-destructive/10 transition-colors cursor-pointer ${
align === "center" ? "justify-center" : "text-left"
}`}
>
<LogOut className="w-4 h-4" />
<span>Sign out</span>
<LogOut className="w-4 h-4 shrink-0" />
<span>Sign Out</span>
</button>
</form>
);

22
auth.ts
View file

@ -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<void>}
*/
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: "/" });
}