Files
fintrack/components/settings/theme-card.tsx
2025-12-23 07:59:33 +01:00

94 lines
2.5 KiB
TypeScript

"use client";
import { useTheme } from "next-themes";
import { useEffect, useState } from "react";
import {
Card,
CardContent,
CardDescription,
CardHeader,
CardTitle,
} from "@/components/ui/card";
import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group";
import { Moon, Sun } from "lucide-react";
import { cn } from "@/lib/utils";
const THEMES = [
{
value: "light",
label: "Clair",
icon: Sun,
description: "Thème clair",
},
{
value: "dark",
label: "Sombre",
icon: Moon,
description: "Thème sombre",
},
] as const;
export function ThemeCard() {
const { theme, setTheme } = useTheme();
const [mounted, setMounted] = useState(false);
// Éviter le flash de contenu non stylé
useEffect(() => {
setMounted(true);
}, []);
if (!mounted) {
return null;
}
const currentTheme = theme || "light";
return (
<Card className="card-hover">
<CardHeader>
<CardTitle className="flex items-center gap-2">
<Moon className="w-5 h-5" />
Thème
</CardTitle>
<CardDescription>
Choisissez le thème d'affichage de l'application
</CardDescription>
</CardHeader>
<CardContent>
<RadioGroup
value={currentTheme}
onValueChange={(value) => setTheme(value)}
>
<div className="grid grid-cols-2 gap-3">
{THEMES.map((themeOption) => {
const Icon = themeOption.icon;
return (
<label
key={themeOption.value}
htmlFor={`theme-${themeOption.value}`}
className={cn(
"relative flex flex-col items-center justify-center p-4 rounded-lg border-2 cursor-pointer transition-all",
currentTheme === themeOption.value
? "border-primary bg-primary/5"
: "border-border hover:border-primary/50"
)}
>
<RadioGroupItem
value={themeOption.value}
id={`theme-${themeOption.value}`}
className="sr-only"
/>
<Icon className="w-6 h-6 mb-2" />
<span className="text-sm font-medium">
{themeOption.label}
</span>
</label>
);
})}
</div>
</RadioGroup>
</CardContent>
</Card>
);
}