feat: add theme-based layouts

Each theme now has a unique layout:
- Light: Standard fixed sidebar
- Vibrant: Horizontal top navigation
- Corporate: Compact sidebar (expands on hover)
- Dark: Floating sidebar with glass effect

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Consultoria AS
2026-01-22 03:46:02 +00:00
parent 74b1bb8c02
commit 6e3e69005b
10 changed files with 499 additions and 64 deletions

View File

@@ -5,13 +5,37 @@ import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/com
import { useThemeStore } from '@/stores/theme-store';
import { useAuthStore } from '@/stores/auth-store';
import { themes, type ThemeName } from '@/themes';
import { Check, Palette, User, Building } from 'lucide-react';
import { Check, Palette, User, Building, Sidebar, PanelTop, Minimize2, Sparkles } from 'lucide-react';
const themeOptions: { name: ThemeName; label: string; description: string }[] = [
{ name: 'light', label: 'Light', description: 'Tema claro profesional' },
{ name: 'vibrant', label: 'Vibrant', description: 'Colores vivos y modernos' },
{ name: 'corporate', label: 'Corporate', description: 'Diseño empresarial denso' },
{ name: 'dark', label: 'Dark', description: 'Modo oscuro con acentos neón' },
const themeOptions: { name: ThemeName; label: string; description: string; layoutDesc: string; layoutIcon: typeof Sidebar }[] = [
{
name: 'light',
label: 'Light',
description: 'Tema claro profesional',
layoutDesc: 'Sidebar estándar fijo',
layoutIcon: Sidebar,
},
{
name: 'vibrant',
label: 'Vibrant',
description: 'Colores vivos y modernos',
layoutDesc: 'Navegación horizontal superior',
layoutIcon: PanelTop,
},
{
name: 'corporate',
label: 'Corporate',
description: 'Diseño empresarial denso',
layoutDesc: 'Sidebar compacto (expande al hover)',
layoutIcon: Minimize2,
},
{
name: 'dark',
label: 'Dark',
description: 'Modo oscuro con acentos neón',
layoutDesc: 'Sidebar flotante con efecto glass',
layoutIcon: Sparkles,
},
];
export default function ConfiguracionPage() {
@@ -71,41 +95,72 @@ export default function ConfiguracionPage() {
<CardHeader>
<CardTitle className="flex items-center gap-2 text-base">
<Palette className="h-4 w-4" />
Tema Visual
Tema Visual y Layout
</CardTitle>
<CardDescription>
Elige el tema que mejor se adapte a tu preferencia
Cada tema incluye colores y distribución de elementos únicos
</CardDescription>
</CardHeader>
<CardContent>
<div className="grid gap-4 md:grid-cols-2 lg:grid-cols-4">
{themeOptions.map((option) => (
<button
key={option.name}
onClick={() => setTheme(option.name)}
className={`relative p-4 rounded-lg border-2 text-left transition-all ${
theme === option.name
? 'border-primary bg-primary/5'
: 'border-border hover:border-primary/50'
}`}
>
{theme === option.name && (
<div className="absolute top-2 right-2">
<Check className="h-4 w-4 text-primary" />
<div className="grid gap-4 md:grid-cols-2">
{themeOptions.map((option) => {
const LayoutIcon = option.layoutIcon;
return (
<button
key={option.name}
onClick={() => setTheme(option.name)}
className={`relative p-4 rounded-lg border-2 text-left transition-all ${
theme === option.name
? 'border-primary bg-primary/5 shadow-md'
: 'border-border hover:border-primary/50'
}`}
>
{theme === option.name && (
<div className="absolute top-3 right-3">
<div className="h-6 w-6 rounded-full bg-primary flex items-center justify-center">
<Check className="h-4 w-4 text-primary-foreground" />
</div>
</div>
)}
{/* Color Preview */}
<div className="flex gap-2 mb-4">
<div
className="h-12 w-12 rounded-lg shadow-inner"
style={{
background: `hsl(${themes[option.name].cssVars['--primary']})`,
}}
/>
<div
className="h-12 w-8 rounded-lg shadow-inner"
style={{
background: `hsl(${themes[option.name].cssVars['--secondary']})`,
}}
/>
<div
className="h-12 w-8 rounded-lg shadow-inner"
style={{
background: `hsl(${themes[option.name].cssVars['--accent']})`,
}}
/>
</div>
)}
<div
className="h-20 rounded-md mb-3"
style={{
background: `hsl(${themes[option.name].cssVars['--primary']})`,
}}
/>
<p className="font-medium">{option.label}</p>
<p className="text-xs text-muted-foreground">
{option.description}
</p>
</button>
))}
{/* Theme Info */}
<p className="font-semibold text-lg mb-1">{option.label}</p>
<p className="text-sm text-muted-foreground mb-3">
{option.description}
</p>
{/* Layout Info */}
<div className="flex items-center gap-2 pt-3 border-t">
<LayoutIcon className="h-4 w-4 text-muted-foreground" />
<span className="text-xs text-muted-foreground">
{option.layoutDesc}
</span>
</div>
</button>
);
})}
</div>
</CardContent>
</Card>