62 lines
1.7 KiB
React
62 lines
1.7 KiB
React
"use client";
|
|
|
|
import { useEffect, useState } from "react";
|
|
import { createClient } from "@/lib/supabase/browser.js";
|
|
|
|
export default function LogoutButton() {
|
|
const [visible, setVisible] = useState(false);
|
|
const [error, setError] = useState("");
|
|
const [loggingOut, setLoggingOut] = useState(false);
|
|
|
|
useEffect(() => {
|
|
const client = createClient();
|
|
|
|
async function checkSession() {
|
|
const { data: { session } } = await client.auth.getSession();
|
|
setVisible(!!session);
|
|
}
|
|
|
|
checkSession();
|
|
|
|
const { data: { subscription } } = client.auth.onAuthStateChange((_event, session) => {
|
|
setVisible(!!session);
|
|
});
|
|
|
|
return () => subscription.unsubscribe();
|
|
}, []);
|
|
|
|
async function handleLogout() {
|
|
setLoggingOut(true);
|
|
setError("");
|
|
try {
|
|
const client = createClient();
|
|
await client.auth.signOut();
|
|
window.location.href = "/login";
|
|
} catch (err) {
|
|
setError("Could not logout. Try again.");
|
|
setLoggingOut(false);
|
|
}
|
|
}
|
|
|
|
if (!visible) return null;
|
|
|
|
return (
|
|
<div className="flex items-center gap-2">
|
|
<button
|
|
type="button"
|
|
onClick={handleLogout}
|
|
disabled={loggingOut}
|
|
aria-label="Logout"
|
|
className="rounded-lg border border-gray-300 px-3 py-2 text-sm font-medium text-gray-600 transition hover:bg-gray-100 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-teal-500 focus-visible:ring-offset-2 disabled:cursor-wait disabled:opacity-60"
|
|
>
|
|
{loggingOut ? "Logging out…" : "Logout"}
|
|
</button>
|
|
{error && (
|
|
<p className="text-xs text-red-600" role="alert">
|
|
{error}
|
|
</p>
|
|
)}
|
|
</div>
|
|
);
|
|
}
|