'use client'; import { useState } from 'react'; import { Theme, PlatformTheme } from '@/types/theme'; import tokensJson from '@bytelyst/design-tokens/tokens.json'; function ColorInput({ label, value, onChange, }: { label: string; value: string; onChange: (value: string) => void; }) { return (
onChange(e.target.value)} className="w-12 h-8 border rounded cursor-pointer" /> onChange(e.target.value)} className="flex-1 px-2 py-1 border rounded text-sm font-mono" placeholder="#00000000" />
); } function PlatformSection({ title, colors, onChange, }: { title: string; colors: PlatformTheme; onChange: (key: keyof PlatformTheme, value: string) => void; }) { return (

{title}

onChange('primary', v)} /> onChange('secondary', v)} /> onChange('accent', v)} /> onChange('background', v)} /> onChange('surface', v)} /> onChange('error', v)} /> onChange('warning', v)} /> onChange('success', v)} /> {title === 'Desktop' && ( <> onChange('idle', v)} /> >).lysnrai ?.hotkeyActive ?? '#5A8CFF') } onChange={v => onChange('listening', v)} /> onChange('processing', v)} /> onChange('offline', v)} /> )}
); } interface ThemeEditorProps { theme?: Theme; onSave: (theme: Partial) => void; onCancel: () => void; } export default function ThemeEditor({ theme, onSave, onCancel }: ThemeEditorProps) { const [name, setName] = useState(theme?.name || ''); const [description, setDescription] = useState(theme?.description || ''); const [iosColors, setIosColors] = useState( theme?.ios || { primary: tokensJson.color.semantic.dark.success, secondary: tokensJson.color.palette.neutral['700'], accent: tokensJson.color.semantic.dark.accentPrimary, background: tokensJson.color.palette.neutral['0'], surface: tokensJson.color.palette.neutral['50'], error: tokensJson.color.semantic.dark.danger, warning: tokensJson.color.semantic.dark.warning, success: tokensJson.color.semantic.dark.success, } ); const [androidColors, setAndroidColors] = useState(theme?.android || iosColors); const [desktopColors, setDesktopColors] = useState( theme?.desktop || { ...iosColors, idle: tokensJson.color.semantic.dark.success, listening: (tokensJson.color as unknown as Record>).lysnrai ?.hotkeyActive ?? '#5A8CFF', processing: tokensJson.color.semantic.dark.warning, offline: tokensJson.color.semantic.dark.textSecondary, } ); const handleColorChange = ( platform: 'ios' | 'android' | 'desktop', colorKey: keyof PlatformTheme, value: string ) => { // Validate hex color format const hexPattern = /^#[0-9A-Fa-f]{6}$/; if (value && !hexPattern.test(value)) { return; // Don't update if invalid } const setter = platform === 'ios' ? setIosColors : platform === 'android' ? setAndroidColors : setDesktopColors; setter(prev => ({ ...prev, [colorKey]: value })); }; const handleSave = () => { onSave({ name, description, ios: iosColors, android: androidColors, desktop: desktopColors, }); }; return (

{theme ? 'Edit Theme' : 'Create New Theme'}

setName(e.target.value)} className="w-full px-3 py-2 border rounded-lg" placeholder="Enter theme name" />