55 lines
1.9 KiB
TypeScript
55 lines
1.9 KiB
TypeScript
import { Avatar, AvatarFallback } from "@xtablo/ui/components/avatar";
|
|
import { Button } from "@xtablo/ui/components/button";
|
|
import { Outlet, useNavigate } from "react-router-dom";
|
|
import { useClientLogout, useClientSession } from "../hooks/useClientSession";
|
|
|
|
function getInitials(email: string): string {
|
|
const parts = email.split("@")[0].split(/[._-]/);
|
|
return parts
|
|
.slice(0, 2)
|
|
.map((p) => p[0]?.toUpperCase() ?? "")
|
|
.join("");
|
|
}
|
|
|
|
export function ClientLayout() {
|
|
const navigate = useNavigate();
|
|
const { data: client } = useClientSession();
|
|
const logout = useClientLogout();
|
|
|
|
if (!client) return null;
|
|
|
|
const email = client.email ?? "";
|
|
const initials = email ? getInitials(email) : "?";
|
|
|
|
const handleLogout = async () => {
|
|
await logout.mutateAsync();
|
|
navigate("/login", { replace: true });
|
|
};
|
|
|
|
return (
|
|
<div className="flex h-screen flex-col overflow-hidden bg-background">
|
|
<header className="h-[75px] shrink-0 border-b border-[#EAECF0] bg-navbar-background dark:border-gray-700">
|
|
<div className="mx-auto flex h-full w-full max-w-7xl items-center justify-between gap-4 px-4 sm:px-6">
|
|
<span className="text-lg font-semibold text-foreground">Xtablo</span>
|
|
<div className="flex items-center gap-3">
|
|
<div className="flex items-center gap-2">
|
|
<Avatar className="h-8 w-8">
|
|
<AvatarFallback className="text-xs">{initials}</AvatarFallback>
|
|
</Avatar>
|
|
<span className="text-sm text-muted-foreground hidden sm:block">{email}</span>
|
|
</div>
|
|
<Button variant="outline" size="sm" onClick={handleLogout} disabled={logout.isPending}>
|
|
Déconnexion
|
|
</Button>
|
|
</div>
|
|
</div>
|
|
</header>
|
|
|
|
<main className="flex-1 overflow-auto">
|
|
<div className="mx-auto w-full max-w-7xl px-4 sm:px-6">
|
|
<Outlet />
|
|
</div>
|
|
</main>
|
|
</div>
|
|
);
|
|
}
|