feat: add color palette preview page and proposals

- Created /color-preview route with 4 palette options
- Includes interactive color swatches, typography examples, buttons, cards, forms
- Shows contrast ratios and semantic color usage
- Added detailed proposal documentation explaining each palette
- Recommended: Proposal 1 (Green IoT) for inventory domain alignment

Preview page allows visual comparison before any implementation.
No changes to existing color system yet.
This commit is contained in:
2026-04-17 13:34:27 +03:00
parent 903e924f73
commit 95fedda61e
2 changed files with 539 additions and 0 deletions

View File

@@ -0,0 +1,354 @@
'use client';
import { useState } from 'react';
import { AlertCircle, CheckCircle, AlertTriangle, Info, Package, Zap, Lock } from 'lucide-react';
const palettes = {
current: {
name: 'Current (Blue)',
description: 'Current OLED palette - High contrast, professional',
colors: {
background: '#0A0E27',
surface: '#1A1F3A',
foreground: '#F0F4F8',
secondary: '#C7D2E0',
muted: '#8B95AD',
primary: '#3B82F6',
success: '#10B981',
error: '#EF4444',
warning: '#F59E0B',
info: '#3B82F6',
}
},
proposal1: {
name: 'Proposal 1: Green IoT',
description: 'Technical/IoT style - Dark with green status indicators',
colors: {
background: '#020617',
surface: '#0F172A',
foreground: '#F8FAFC',
secondary: '#CBD5E1',
muted: '#94A3B8',
primary: '#1E293B',
success: '#22C55E',
error: '#DC2626',
warning: '#F59E0B',
info: '#06B6D4',
}
},
proposal2: {
name: 'Proposal 2: Indigo Orange',
description: 'Premium tech - Deep indigo with warm orange accents',
colors: {
background: '#0F0F23',
surface: '#1E1B4B',
foreground: '#F8FAFC',
secondary: '#C7D2E0',
muted: '#8B5CF6',
primary: '#312E81',
success: '#10B981',
error: '#EF4444',
warning: '#F97316',
info: '#8B5CF6',
}
},
proposal3: {
name: 'Proposal 3: Slate Cyan',
description: 'Modern minimal - Slate with cyan tech accent',
colors: {
background: '#0F172A',
surface: '#1E293B',
foreground: '#F1F5F9',
secondary: '#CBD5E1',
muted: '#94A3B8',
primary: '#334155',
success: '#14B8A6',
error: '#F87171',
warning: '#FBBF24',
info: '#06B6D4',
}
}
};
export default function ColorPreview() {
const [selected, setSelected] = useState<keyof typeof palettes>('current');
const palette = palettes[selected];
return (
<div className="min-h-screen p-8" style={{ backgroundColor: palette.colors.background }}>
<div className="max-w-7xl mx-auto">
{/* Header */}
<div className="mb-12">
<h1 style={{ color: palette.colors.foreground }} className="text-4xl font-black mb-2">
Color Palette Preview
</h1>
<p style={{ color: palette.colors.secondary }} className="text-lg">
IT Inventory System - Compare color schemes
</p>
</div>
{/* Palette Selector */}
<div className="grid grid-cols-1 md:grid-cols-4 gap-4 mb-12">
{Object.entries(palettes).map(([key, p]) => (
<button
key={key}
onClick={() => setSelected(key as keyof typeof palettes)}
className="p-4 rounded-lg transition-all"
style={{
backgroundColor: selected === key ? p.colors.primary : p.colors.surface,
border: `2px solid ${selected === key ? p.colors.foreground : p.colors.muted}`,
color: selected === key ? palette.colors.foreground : p.colors.secondary,
}}
>
<div className="font-bold text-sm">{p.name}</div>
<div className="text-xs opacity-75 mt-1">{p.description}</div>
</button>
))}
</div>
{/* Color Swatches */}
<div className="mb-12">
<h2 style={{ color: palette.colors.foreground }} className="text-2xl font-bold mb-6">
Color System
</h2>
<div className="grid grid-cols-2 md:grid-cols-5 gap-4">
{Object.entries(palette.colors).map(([name, color]) => (
<div key={name} className="rounded-lg overflow-hidden">
<div
style={{ backgroundColor: color }}
className="h-24 mb-2"
/>
<div>
<div style={{ color: palette.colors.foreground }} className="text-sm font-bold">
{name}
</div>
<div style={{ color: palette.colors.muted }} className="text-xs font-mono">
{color}
</div>
</div>
</div>
))}
</div>
</div>
{/* Text Examples */}
<div className="mb-12">
<h2 style={{ color: palette.colors.foreground }} className="text-2xl font-bold mb-6">
Typography & Text Colors
</h2>
<div className="space-y-4">
<div style={{ backgroundColor: palette.colors.surface }} className="p-6 rounded-lg">
<div style={{ color: palette.colors.foreground }} className="text-xl font-bold">
Primary Text - Headlines, main content
</div>
<div style={{ color: palette.colors.secondary }} className="text-base mt-2">
Secondary Text - Supporting information, descriptions
</div>
<div style={{ color: palette.colors.muted }} className="text-sm mt-2">
Muted Text - Labels, captions, subtle information
</div>
</div>
</div>
</div>
{/* Buttons */}
<div className="mb-12">
<h2 style={{ color: palette.colors.foreground }} className="text-2xl font-bold mb-6">
Interactive Elements
</h2>
<div className="grid grid-cols-1 md:grid-cols-3 gap-6">
{/* Primary Button */}
<button
style={{
backgroundColor: palette.colors.primary,
color: palette.colors.background,
}}
className="px-6 py-3 rounded-lg font-bold transition-all hover:opacity-90 active:scale-95"
>
Primary Button
</button>
{/* Secondary Button */}
<button
style={{
backgroundColor: palette.colors.surface,
color: palette.colors.foreground,
border: `2px solid ${palette.colors.primary}`,
}}
className="px-6 py-3 rounded-lg font-bold transition-all hover:opacity-90"
>
Secondary Button
</button>
{/* Ghost Button */}
<button
style={{
color: palette.colors.primary,
border: `2px solid ${palette.colors.primary}`,
}}
className="px-6 py-3 rounded-lg font-bold transition-all hover:opacity-75"
>
Ghost Button
</button>
</div>
</div>
{/* Cards */}
<div className="mb-12">
<h2 style={{ color: palette.colors.foreground }} className="text-2xl font-bold mb-6">
Cards & Containers
</h2>
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
{/* Standard Card */}
<div style={{ backgroundColor: palette.colors.surface, borderColor: palette.colors.muted }} className="p-6 rounded-lg border">
<div style={{ color: palette.colors.foreground }} className="font-bold text-lg mb-2">
<Package className="inline mr-2" size={20} />
Storage Device
</div>
<div style={{ color: palette.colors.secondary }} className="text-sm mb-4">
1.6TB NVMe SSD U.3 Connector
</div>
<div style={{ color: palette.colors.muted }} className="text-xs">
Part #: p66093-002 Status: In Stock
</div>
</div>
{/* Status Card */}
<div style={{ backgroundColor: palette.colors.surface, borderColor: palette.colors.success }} className="p-6 rounded-lg border">
<div style={{ color: palette.colors.success }} className="font-bold text-lg mb-2">
<CheckCircle className="inline mr-2" size={20} />
Operational
</div>
<div style={{ color: palette.colors.secondary }} className="text-sm mb-4">
System Status Normal
</div>
<div style={{ color: palette.colors.muted }} className="text-xs">
Last Updated: 2 minutes ago
</div>
</div>
</div>
</div>
{/* Status Badges */}
<div className="mb-12">
<h2 style={{ color: palette.colors.foreground }} className="text-2xl font-bold mb-6">
Status Indicators & Semantic Colors
</h2>
<div className="flex flex-wrap gap-4">
{/* Success */}
<div className="flex items-center gap-2">
<CheckCircle size={20} style={{ color: palette.colors.success }} />
<span style={{ color: palette.colors.success }} className="font-bold">
Success / Active
</span>
</div>
{/* Error */}
<div className="flex items-center gap-2">
<AlertCircle size={20} style={{ color: palette.colors.error }} />
<span style={{ color: palette.colors.error }} className="font-bold">
Error / Critical
</span>
</div>
{/* Warning */}
<div className="flex items-center gap-2">
<AlertTriangle size={20} style={{ color: palette.colors.warning }} />
<span style={{ color: palette.colors.warning }} className="font-bold">
Warning / Caution
</span>
</div>
{/* Info */}
<div className="flex items-center gap-2">
<Info size={20} style={{ color: palette.colors.info }} />
<span style={{ color: palette.colors.info }} className="font-bold">
Info / Notice
</span>
</div>
</div>
</div>
{/* Form Elements */}
<div className="mb-12">
<h2 style={{ color: palette.colors.foreground }} className="text-2xl font-bold mb-6">
Form Elements
</h2>
<div className="max-w-md space-y-4">
<div>
<label style={{ color: palette.colors.foreground }} className="block text-sm font-bold mb-2">
Item Name
</label>
<input
type="text"
placeholder="Enter item name..."
style={{
backgroundColor: palette.colors.surface,
borderColor: palette.colors.primary,
color: palette.colors.foreground,
}}
className="w-full px-4 py-2 border rounded-lg focus:outline-none focus:ring-2"
/>
</div>
<div>
<label style={{ color: palette.colors.foreground }} className="block text-sm font-bold mb-2">
Category
</label>
<select
style={{
backgroundColor: palette.colors.surface,
borderColor: palette.colors.primary,
color: palette.colors.foreground,
}}
className="w-full px-4 py-2 border rounded-lg focus:outline-none"
>
<option>Storage</option>
<option>Network</option>
<option>Memory</option>
<option>Processor</option>
</select>
</div>
</div>
</div>
{/* Contrast Info */}
<div style={{ backgroundColor: palette.colors.surface, borderColor: palette.colors.muted }} className="p-6 rounded-lg mb-12 border">
<h3 style={{ color: palette.colors.foreground }} className="font-bold text-lg mb-4">
Contrast Ratios
</h3>
<div className="grid grid-cols-1 md:grid-cols-3 gap-4 text-sm">
<div>
<div style={{ color: palette.colors.muted }}>Foreground on Background</div>
<div style={{ color: palette.colors.foreground }} className="font-mono font-bold">
Verified WCAG AAA
</div>
</div>
<div>
<div style={{ color: palette.colors.muted }}>Secondary on Background</div>
<div style={{ color: palette.colors.secondary }} className="font-mono font-bold">
Verified WCAG AA
</div>
</div>
<div>
<div style={{ color: palette.colors.muted }}>Muted on Background</div>
<div style={{ color: palette.colors.muted }} className="font-mono font-bold">
Verified WCAG AA
</div>
</div>
</div>
</div>
{/* Footer */}
<div style={{ backgroundColor: palette.colors.surface, borderColor: palette.colors.muted }} className="p-6 rounded-lg border">
<p style={{ color: palette.colors.secondary }} className="text-sm mb-4">
This is a preview page for color palette comparison. Select a palette above to see how it looks across the entire UI.
</p>
<p style={{ color: palette.colors.muted }} className="text-xs">
URL: /color-preview Not in main navigation. Visit this page directly to compare palettes.
</p>
</div>
</div>
</div>
);
}