feat(shell): integrate auth-aware nav into locale layout
Add AuthNavActions component and integrate shell into locale layout Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
parent
e8d557b0d2
commit
2a6a7980ec
2 changed files with 78 additions and 1 deletions
|
|
@ -2,6 +2,8 @@ import { setRequestLocale } from 'next-intl/server';
|
||||||
import { hasLocale } from 'next-intl';
|
import { hasLocale } from 'next-intl';
|
||||||
import { notFound } from 'next/navigation';
|
import { notFound } from 'next/navigation';
|
||||||
import { routing } from '@/i18n/routing';
|
import { routing } from '@/i18n/routing';
|
||||||
|
import { AppShell } from '@/components/core/AppShell';
|
||||||
|
import { AppNav } from '@/components/core/AppNav';
|
||||||
|
|
||||||
export function generateStaticParams() {
|
export function generateStaticParams() {
|
||||||
return routing.locales.map((locale) => ({ locale }));
|
return routing.locales.map((locale) => ({ locale }));
|
||||||
|
|
@ -22,5 +24,10 @@ export default async function LocaleLayout({
|
||||||
|
|
||||||
setRequestLocale(locale);
|
setRequestLocale(locale);
|
||||||
|
|
||||||
return <>{children}</>;
|
return (
|
||||||
|
<AppShell>
|
||||||
|
<AppNav />
|
||||||
|
<main className="flex-1">{children}</main>
|
||||||
|
</AppShell>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
70
src/components/core/AuthNavActions.tsx
Normal file
70
src/components/core/AuthNavActions.tsx
Normal file
|
|
@ -0,0 +1,70 @@
|
||||||
|
"use client";
|
||||||
|
|
||||||
|
import Link from "next/link";
|
||||||
|
import { useTranslations } from "next-intl";
|
||||||
|
import { routes } from "@/lib/routes";
|
||||||
|
import { authClient } from "@/lib/auth-client";
|
||||||
|
import { Button } from "@/components/ui/button";
|
||||||
|
import { cn } from "@/lib/utils";
|
||||||
|
|
||||||
|
interface AuthNavActionsProps {
|
||||||
|
className?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function AuthNavActions({ className }: AuthNavActionsProps) {
|
||||||
|
const t = useTranslations("Navigation");
|
||||||
|
const { data: session, isPending } = authClient.useSession();
|
||||||
|
|
||||||
|
if (isPending) {
|
||||||
|
return (
|
||||||
|
<div className={cn("flex items-center gap-2", className)}>
|
||||||
|
<div className="h-9 w-20 bg-muted animate-pulse rounded" />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const isAuthenticated = !!session?.user;
|
||||||
|
|
||||||
|
const handleSignOut = async () => {
|
||||||
|
await authClient.signOut({
|
||||||
|
fetchOptions: {
|
||||||
|
onSuccess: () => {
|
||||||
|
window.location.href = routes.public.home;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div data-testid="nav-auth-actions" className={cn("flex items-center gap-2", className)}>
|
||||||
|
{isAuthenticated ? (
|
||||||
|
<>
|
||||||
|
<div data-testid="nav-private-links" className="flex items-center gap-2">
|
||||||
|
<Button variant="ghost" asChild>
|
||||||
|
<Link href={routes.private.dashboard}>{t("Dashboard")}</Link>
|
||||||
|
</Button>
|
||||||
|
<Button variant="ghost" asChild>
|
||||||
|
<Link href={routes.private.settings}>{t("Settings")}</Link>
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
<Button
|
||||||
|
data-testid="sign-out-button"
|
||||||
|
variant="outline"
|
||||||
|
onClick={handleSignOut}
|
||||||
|
>
|
||||||
|
{t("SignOut")}
|
||||||
|
</Button>
|
||||||
|
</>
|
||||||
|
) : (
|
||||||
|
<div data-testid="nav-public-links" className="flex items-center gap-2">
|
||||||
|
<Button variant="ghost" asChild>
|
||||||
|
<Link href={routes.public.signIn}>{t("SignIn")}</Link>
|
||||||
|
</Button>
|
||||||
|
<Button asChild>
|
||||||
|
<Link href={routes.public.signUp}>{t("SignUp")}</Link>
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
Loading…
Reference in a new issue