feat: update theme management across the application; change default theme to 'light', disable system theme option, and add ThemeCard component in settings for enhanced user customization
All checks were successful
Deploy with Docker Compose / deploy (push) Successful in 2m23s

This commit is contained in:
Julien Froidefond
2025-12-23 07:59:33 +01:00
parent b2eac21bdf
commit e0597b0dcb
5 changed files with 101 additions and 4 deletions

View File

@@ -27,8 +27,8 @@ export default function RootLayout({
<body className="font-sans antialiased"> <body className="font-sans antialiased">
<ThemeProvider <ThemeProvider
attribute="class" attribute="class"
defaultTheme="system" defaultTheme="light"
enableSystem enableSystem={false}
disableTransitionOnChange disableTransitionOnChange
> >
<BackgroundProvider /> <BackgroundProvider />

View File

@@ -10,6 +10,7 @@ import {
PasswordCard, PasswordCard,
ReconcileDateRangeCard, ReconcileDateRangeCard,
BackgroundCard, BackgroundCard,
ThemeCard,
} from "@/components/settings"; } from "@/components/settings";
import { useBankingData } from "@/lib/hooks"; import { useBankingData } from "@/lib/hooks";
import type { BankingData } from "@/lib/types"; import type { BankingData } from "@/lib/types";
@@ -127,6 +128,8 @@ export default function SettingsPage() {
<PasswordCard /> <PasswordCard />
<ThemeCard />
<BackgroundCard /> <BackgroundCard />
<ReconcileDateRangeCard /> <ReconcileDateRangeCard />

View File

@@ -5,3 +5,4 @@ export { BackupCard } from "./backup-card";
export { PasswordCard } from "./password-card"; export { PasswordCard } from "./password-card";
export { ReconcileDateRangeCard } from "./reconcile-date-range-card"; export { ReconcileDateRangeCard } from "./reconcile-date-range-card";
export { BackgroundCard } from "./background-card"; export { BackgroundCard } from "./background-card";
export { ThemeCard } from "./theme-card";

View File

@@ -0,0 +1,93 @@
"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>
);
}

View File

@@ -4,11 +4,11 @@ import { useTheme } from "next-themes";
import { Toaster as Sonner, ToasterProps } from "sonner"; import { Toaster as Sonner, ToasterProps } from "sonner";
const Toaster = ({ ...props }: ToasterProps) => { const Toaster = ({ ...props }: ToasterProps) => {
const { theme = "system" } = useTheme(); const { theme = "light" } = useTheme();
return ( return (
<Sonner <Sonner
theme={theme as ToasterProps["theme"]} theme={theme === "system" ? "dark" : (theme as ToasterProps["theme"])}
className="toaster group" className="toaster group"
style={ style={
{ {