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
All checks were successful
Deploy Flowstate to VPS / deploy (push) Successful in 5s
This commit is contained in:
parent
f3a526a68c
commit
9802febef3
5 changed files with 54 additions and 35 deletions
31
actions/auth.actions.ts
Normal file
31
actions/auth.actions.ts
Normal 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: "/" });
|
||||||
|
}
|
||||||
|
|
@ -9,6 +9,7 @@ import { useState, useRef, useEffect } from "react";
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
import { MoreHorizontal, X } from "lucide-react";
|
import { MoreHorizontal, X } from "lucide-react";
|
||||||
import { LEGAL_LINKS, COPYRIGHT_TEXT, ICON_MAP } from "@/utils/legal";
|
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
|
* Renders a mobile menu button and a slide-up modal overlay containing
|
||||||
|
|
@ -130,6 +131,9 @@ export default function MobileLegalMenu() {
|
||||||
</Link>
|
</Link>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
|
|
||||||
|
{/* Sign Out Button */}
|
||||||
|
<SignOutButton />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Shared Copyright */}
|
{/* Shared Copyright */}
|
||||||
|
|
|
||||||
|
|
@ -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.
|
* @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>
|
</div>
|
||||||
|
|
||||||
{/* Lower Section */}
|
{/* Lower Section */}
|
||||||
<div className="flex justify-center">
|
<SignOutButton align="center" />
|
||||||
<SignOutButton />
|
|
||||||
</div>
|
|
||||||
</aside>
|
</aside>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,25 +1,33 @@
|
||||||
/**
|
/**
|
||||||
* @file SignOutButton.tsx
|
* @file components/ui/buttons/SignOutButton.tsx
|
||||||
* @description Server Action-powered client component rendering a sign-out button that triggers session termination via a server action.
|
* @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";
|
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.
|
* @returns {JSX.Element} The rendered sign-out button component.
|
||||||
*/
|
*/
|
||||||
export default function SignOutButton() {
|
export default function SignOutButton({
|
||||||
|
align = "left",
|
||||||
|
}: {
|
||||||
|
align?: "left" | "center";
|
||||||
|
}) {
|
||||||
return (
|
return (
|
||||||
<form action={handleSignOut}>
|
<form action={handleSignOut} className="w-full">
|
||||||
<button
|
<button
|
||||||
type="submit"
|
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" />
|
<LogOut className="w-4 h-4 shrink-0" />
|
||||||
<span>Sign out</span>
|
<span>Sign Out</span>
|
||||||
</button>
|
</button>
|
||||||
</form>
|
</form>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
22
auth.ts
22
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<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: "/" });
|
|
||||||
}
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue