mirror of
https://github.com/jakejarvis/sofa.git
synced 2026-08-29 01:35:39 -04:00
- Add global MotionConfig reducedMotion="user" in root layout
- Add color-scheme: dark, theme-color meta, skip-to-main-content link
- Add aria-hidden={true} to ~60+ decorative icons across 33 files
- Add aria-label to all icon-only buttons (logout, star rating, play, delete, etc.)
- Replace transition-all with specific properties (11 files)
- Add motion-safe: prefix for CSS hover transforms and animate-pulse
- Add prefers-reduced-motion: reduce override in globals.css
- Add useReducedMotion guard to status-dot pulsing animation
- Fix focus-visible styles on auth form inputs (focus → focus-visible, stronger ring)
- Add text-balance to all headings (13 files)
- Replace "..." with "…" (U+2026) in all loading/placeholder text
- Add autocomplete, spellCheck, role="alert" to auth form
- Add aria-label to Switch controls and filmography select
- Fix heading hierarchy (h3 → h2 where h2 was skipped)
- Add break-words to title overview, overscroll-contain to drawer
- Add confirmation dialog for destructive library removal
- Add group-focus-within:opacity-100 for keyboard-accessible backup actions
- Add role="radio" + aria-checked to star rating buttons
- Add aria-label to carousel region, role="img" to TMDB logo SVG
- Add text-foreground to native select for dark mode consistency
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
70 lines
2.1 KiB
TypeScript
70 lines
2.1 KiB
TypeScript
"use client";
|
|
|
|
import { IconLogout, IconUser } from "@tabler/icons-react";
|
|
import { useRouter } from "next/navigation";
|
|
import { Button } from "@/components/ui/button";
|
|
import {
|
|
Card,
|
|
CardContent,
|
|
CardDescription,
|
|
CardTitle,
|
|
} from "@/components/ui/card";
|
|
import { signOut } from "@/lib/auth/client";
|
|
|
|
export function AccountSection({
|
|
user,
|
|
}: {
|
|
user: { name: string; email: string; createdAt: string; role?: string };
|
|
}) {
|
|
const router = useRouter();
|
|
|
|
const memberSince = new Date(user.createdAt).toLocaleDateString(undefined, {
|
|
year: "numeric",
|
|
month: "long",
|
|
});
|
|
const initial = user.name?.charAt(0).toUpperCase() ?? "?";
|
|
|
|
return (
|
|
<div>
|
|
<div className="mb-3 flex items-center gap-2">
|
|
<IconUser aria-hidden={true} className="size-4 text-muted-foreground" />
|
|
<h2 className="text-xs font-medium uppercase tracking-wider text-muted-foreground">
|
|
Account
|
|
</h2>
|
|
</div>
|
|
<Card>
|
|
<CardContent className="flex items-center gap-4">
|
|
<div className="flex h-12 w-12 shrink-0 items-center justify-center rounded-full bg-primary/10 font-display text-lg text-primary">
|
|
{initial}
|
|
</div>
|
|
<div className="min-w-0 flex-1">
|
|
<CardTitle>
|
|
{user.name}
|
|
{user.role === "admin" && (
|
|
<span className="ml-2 inline-flex items-center rounded-md bg-primary/10 px-1.5 py-0.5 align-middle text-[10px] font-medium text-primary">
|
|
Admin
|
|
</span>
|
|
)}
|
|
</CardTitle>
|
|
<CardDescription>{user.email}</CardDescription>
|
|
<p className="mt-0.5 text-xs text-muted-foreground/60">
|
|
Member since {memberSince}
|
|
</p>
|
|
</div>
|
|
<Button
|
|
variant="destructive"
|
|
onClick={async () => {
|
|
await signOut();
|
|
router.push("/");
|
|
router.refresh();
|
|
}}
|
|
>
|
|
<IconLogout aria-hidden={true} />
|
|
Sign out
|
|
</Button>
|
|
</CardContent>
|
|
</Card>
|
|
</div>
|
|
);
|
|
}
|