Files
JohnRiceMLandClaude Opus 4.6 3fd836f3f8 feat: add Lucide icons to all action buttons + dynamic accent contrast
Add missing icons to every actionable button across the app for a more
polished feel. Also introduce dynamic text contrast on accent-colored
backgrounds so dark accents (red, purple, indigo) get white text
automatically via WCAG luminance calculation.

- ErrorState: RotateCcw icon on Try Again, add focus-ring + btn-scale
- Memory: RefreshCw, Copy/Check, Download icons on toolbar buttons
- Crons: RefreshCw refresh, BarChart3/Calendar/GitBranch tab icons,
  Copy/Check on error copy buttons
- Home: Map/LayoutGrid/List view switcher icons, X close icon,
  MessageSquare + btn-scale on Message, User + btn-scale on Profile
- Kanban: Plus icon on New Ticket, add btn-scale
- Settings: RotateCcw on Reset to Default + Re-run Setup, Trash2 on
  Reset All Settings, btn-scale on CTAs
- Onboarding: ArrowLeft/ArrowRight/Rocket/RotateCcw on nav buttons
- New hexToContrastText() in lib/settings.ts (WCAG 2.0 luminance)
- --accent-contrast CSS var set in all 5 theme blocks + settings provider
- All hardcoded #000 on accent backgrounds replaced with var(--accent-contrast)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-03 10:19:00 -06:00

98 lines
2.6 KiB
TypeScript

'use client'
import { RotateCcw } from 'lucide-react'
interface ErrorStateProps {
message: string
onRetry?: () => void
}
export function ErrorState({ message, onRetry }: ErrorStateProps) {
return (
<div
className="flex items-center justify-center h-full"
role="alert"
style={{ background: 'var(--bg)' }}
>
<div style={{ textAlign: 'center', padding: '0 24px', maxWidth: 360 }}>
<div style={{
width: 56,
height: 56,
borderRadius: '50%',
background: 'var(--fill-secondary)',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
fontSize: 24,
margin: '0 auto 16px',
}}>
<svg
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
strokeWidth="1.5"
strokeLinecap="round"
strokeLinejoin="round"
style={{ color: 'var(--text-secondary)' }}
>
<circle cx="12" cy="12" r="10" />
<line x1="12" y1="8" x2="12" y2="12" />
<line x1="12" y1="16" x2="12.01" y2="16" />
</svg>
</div>
<div style={{
fontSize: 17,
fontWeight: 600,
color: 'var(--text-primary)',
marginBottom: 4,
}}>
Something went wrong
</div>
<p style={{
fontSize: 14,
lineHeight: 1.5,
color: 'var(--text-secondary)',
margin: '0 0 20px',
}}>
{message}
</p>
{onRetry && (
<button
onClick={onRetry}
className="focus-ring btn-scale"
style={{
height: 40,
padding: '0 20px',
borderRadius: 'var(--radius-md)',
background: 'var(--fill-secondary)',
color: 'var(--text-primary)',
fontWeight: 600,
fontSize: 14,
border: 'none',
cursor: 'pointer',
transition: 'all 150ms var(--ease-spring)',
display: 'flex',
alignItems: 'center',
gap: 6,
}}
onMouseEnter={(e) => {
e.currentTarget.style.background = 'var(--fill-primary)';
}}
onMouseLeave={(e) => {
e.currentTarget.style.background = 'var(--fill-secondary)';
}}
>
<RotateCcw size={16} />
Try Again
</button>
)}
</div>
</div>
)
}