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:
354
frontend/app/color-preview/page.tsx
Normal file
354
frontend/app/color-preview/page.tsx
Normal 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>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user