mega-plant/components/auth/LogoutButton.tsx

34 lines
2.1 KiB
TypeScript

"use client";
import { useState, useTransition } from "react";
import { LogOut, LoaderCircle } from "lucide-react";
export function LogoutButton({ iconOnly = false, fullWidth = false, returnTo = "/login" }: { iconOnly?: boolean; fullWidth?: boolean; returnTo?: "/login" | "/clock/login" }) {
const [pending, startTransition] = useTransition();
const [failed, setFailed] = useState(false);
return <div className="relative">
<button type="button" aria-label="Sign out" title="Sign out" disabled={pending}
className={`flex min-h-11 min-w-11 items-center gap-3 rounded-lg text-sm font-medium text-gray-500 transition hover:bg-gray-100 focus-visible:outline-2 focus-visible:outline-[#30638E] dark:text-gray-400 dark:hover:bg-white/5 ${fullWidth ? "w-full justify-start px-3" : iconOnly ? "h-11 w-11 justify-center" : "justify-center px-4"}`}
onClick={() => startTransition(async () => {
setFailed(false);
try {
const response = await fetch("/api/auth/logout", { method: "POST" });
if (!response.ok) throw new Error("Could not sign out.");
// Old workers may have cached dashboards. Clear them even after upgrading.
try {
if ("caches" in window) await Promise.all((await caches.keys()).map((key) => caches.delete(key)));
} catch { /* Cookie deletion still signs the user out if cache storage is unavailable. */ }
if ("BroadcastChannel" in window) {
const channel = new BroadcastChannel("mega-auth");
channel.postMessage("logout");
channel.close();
}
window.location.replace(returnTo);
} catch { setFailed(true); }
})}>
{pending ? <LoaderCircle className="h-4 w-4 animate-spin" /> : <LogOut className="h-4 w-4" />}
{!iconOnly && (pending ? "Signing out…" : "Sign out")}
</button>
{failed && <p role="alert" className="absolute right-0 top-full z-50 mt-2 w-56 rounded-xl border border-[#D1495B]/20 bg-white p-3 text-sm text-[#D1495B] shadow-lg dark:bg-surface">Couldn't sign out. Please try again.</p>}
</div>;
}