feat: implement theme system and UI updates

- Added theme context and provider for light/dark mode support.
- Integrated theme toggle button in the Header component.
- Updated UI components to utilize CSS variables for consistent theming.
- Enhanced Kanban components and forms with new theme styles for better visual coherence.
- Adjusted global styles to define color variables for both themes, improving maintainability.
This commit is contained in:
Julien Froidefond
2025-09-15 11:49:54 +02:00
parent dce11e0569
commit 07cd3bde3b
23 changed files with 298 additions and 160 deletions

View File

@@ -1,5 +1,6 @@
import { Card, CardContent } from '@/components/ui/Card';
import { TaskStats } from '@/lib/types';
import { useTheme } from '@/contexts/ThemeContext';
import Link from 'next/link';
interface HeaderProps {
@@ -10,8 +11,10 @@ interface HeaderProps {
}
export function Header({ title, subtitle, stats, syncing = false }: HeaderProps) {
const { theme, toggleTheme } = useTheme();
return (
<header className="bg-slate-900/80 backdrop-blur-sm border-b border-slate-700/50 shadow-lg shadow-slate-900/20">
<header className="bg-[var(--card)]/80 backdrop-blur-sm border-b border-[var(--border)]/50 shadow-lg shadow-[var(--card)]/20">
<div className="container mx-auto px-6 py-4">
<div className="flex flex-col sm:flex-row sm:items-center sm:justify-between gap-6">
{/* Titre tech avec glow */}
@@ -23,10 +26,10 @@ export function Header({ title, subtitle, stats, syncing = false }: HeaderProps)
: 'bg-cyan-400 animate-pulse shadow-cyan-400/50'
}`}></div>
<div>
<h1 className="text-2xl font-mono font-bold text-slate-100 tracking-wider">
<h1 className="text-2xl font-mono font-bold text-[var(--foreground)] tracking-wider">
{title}
</h1>
<p className="text-slate-400 mt-1 font-mono text-sm">
<p className="text-[var(--muted-foreground)] mt-1 font-mono text-sm">
{subtitle} {syncing && '• Synchronisation...'}
</p>
</div>
@@ -36,16 +39,33 @@ export function Header({ title, subtitle, stats, syncing = false }: HeaderProps)
<nav className="hidden sm:flex items-center gap-4">
<Link
href="/"
className="text-slate-400 hover:text-cyan-400 transition-colors font-mono text-sm uppercase tracking-wider"
className="text-[var(--muted-foreground)] hover:text-[var(--primary)] transition-colors font-mono text-sm uppercase tracking-wider"
>
Kanban
</Link>
<Link
href="/tags"
className="text-slate-400 hover:text-purple-400 transition-colors font-mono text-sm uppercase tracking-wider"
className="text-[var(--muted-foreground)] hover:text-[var(--accent)] transition-colors font-mono text-sm uppercase tracking-wider"
>
Tags
</Link>
{/* Theme Toggle */}
<button
onClick={toggleTheme}
className="text-[var(--muted-foreground)] hover:text-[var(--primary)] transition-colors p-1 rounded-md hover:bg-[var(--card-hover)]"
title={`Switch to ${theme === 'dark' ? 'light' : 'dark'} theme`}
>
{theme === 'dark' ? (
<svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 3v1m0 16v1m9-9h-1M4 12H3m15.364 6.364l-.707-.707M6.343 6.343l-.707-.707m12.728 0l-.707.707M6.343 17.657l-.707.707M16 12a4 4 0 11-8 0 4 4 0 018 0z" />
</svg>
) : (
<svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M20.354 15.354A9 9 0 018.646 3.646 9.003 9.003 0 0012 21a9.003 9.003 0 008.354-5.646z" />
</svg>
)}
</button>
</nav>
</div>
@@ -119,11 +139,11 @@ interface StatCardProps {
function StatCard({ label, value, color }: StatCardProps) {
const textColors = {
blue: 'text-cyan-300',
green: 'text-emerald-300',
yellow: 'text-yellow-300',
gray: 'text-slate-300',
purple: 'text-purple-300'
blue: 'text-[var(--primary)]',
green: 'text-[var(--success)]',
yellow: 'text-[var(--accent)]',
gray: 'text-[var(--muted-foreground)]',
purple: 'text-[var(--accent)]'
};
return (