|
| 1 | +import { ArrowLeft, Check, X, AlertTriangle } from 'lucide-react' |
| 2 | +import { Button } from '@/components/ui/button' |
| 3 | +import { Card } from '@/components/ui/card' |
| 4 | +import { Badge } from '@/components/ui/badge' |
| 5 | + |
| 6 | +interface AuditIssue { |
| 7 | + id: string |
| 8 | + category: string |
| 9 | + description: string |
| 10 | + severity: 'critical' | 'serious' | 'moderate' | 'minor' |
| 11 | + wcag: string |
| 12 | + status: 'pass' | 'fail' | 'warning' |
| 13 | + fix: string |
| 14 | +} |
| 15 | + |
| 16 | +const issues: AuditIssue[] = [ |
| 17 | + { id: '1', category: 'Farba a kontrast', description: 'Kontrast textu v hero sekcii nespĺňa pomer 4.5:1', severity: 'serious', wcag: '1.4.3', status: 'fail', fix: 'Zvýšiť kontrast primárneho textu na pozadí — použiť tmavší odtieň.' }, |
| 18 | + { id: '2', category: 'Klávesnica', description: 'Dropdown menu nie je ovládateľné klávesnicou', severity: 'serious', wcag: '2.1.1', status: 'fail', fix: 'Pridať onKeyDown handler a focus management pre dropdown.' }, |
| 19 | + { id: '3', category: 'Screen reader', description: 'Ikony v navigácii nemajú aria-label', severity: 'moderate', wcag: '1.1.1', status: 'warning', fix: 'Pridať aria-label k tlačidlám s ikonami.' }, |
| 20 | + { id: '4', category: 'Farba a kontrast', description: 'Error stav v kontaktnom formulári používa len farbu', severity: 'serious', wcag: '1.4.1', status: 'fail', fix: 'Pridať textové označenie chyby + ikonu.' }, |
| 21 | + { id: '5', category: 'Touch ciele', description: 'Tlačidlá v mobilnom menu majú menej ako 44px', severity: 'moderate', wcag: '2.5.5', status: 'fail', fix: 'Zväčšiť touch ciele na minimálne 44x44px.' }, |
| 22 | + { id: '6', category: 'Štruktúra', description: 'Chýba skip-to-content link', severity: 'minor', wcag: '2.4.1', status: 'warning', fix: 'Pridať skip-navigation link ako prvý element.' }, |
| 23 | + { id: '7', category: 'Formuláre', description: 'Inputy majú správne label prvky', severity: 'minor', wcag: '1.3.1', status: 'pass', fix: '' }, |
| 24 | + { id: '8', category: 'Responzívny dizajn', description: 'Stránka sa správne škáluje na všetkých veľkostiach', severity: 'minor', wcag: '1.4.10', status: 'pass', fix: '' }, |
| 25 | +] |
| 26 | + |
| 27 | +const passes = issues.filter((i) => i.status === 'pass').length |
| 28 | +const totalIssues = issues.filter((i) => i.status !== 'pass').length |
| 29 | +const criticals = issues.filter((i) => i.severity === 'critical' || i.severity === 'serious').length |
| 30 | + |
| 31 | +export function AccessibilityReview({ onBack }: { onBack: () => void }) { |
| 32 | + return ( |
| 33 | + <div data-component="src/components/AccessibilityReview.tsx" className="min-h-screen bg-muted/30"> |
| 34 | + <div className="mx-auto max-w-6xl px-4 py-8 sm:px-6"> |
| 35 | + <div className="mb-8 flex items-center justify-between"> |
| 36 | + <div> |
| 37 | + <h1 className="font-display text-3xl font-bold tracking-tight">WCAG Audit</h1> |
| 38 | + <p className="mt-1 text-sm text-muted-foreground">Audit prístupnosti podľa WCAG 2.1 AA</p> |
| 39 | + </div> |
| 40 | + <Button variant="outline" size="sm" onClick={onBack}> |
| 41 | + <ArrowLeft className="mr-2 h-4 w-4" /> Späť |
| 42 | + </Button> |
| 43 | + </div> |
| 44 | + |
| 45 | + <div className="mb-8 grid gap-4 sm:grid-cols-4"> |
| 46 | + <Card className="p-5 text-center"> |
| 47 | + <div className="text-sm text-muted-foreground">Celkové skóre</div> |
| 48 | + <div className="mt-1 font-display text-3xl font-bold">{Math.round((passes / issues.length) * 100)}%</div> |
| 49 | + </Card> |
| 50 | + <Card className="p-5 text-center"> |
| 51 | + <div className="text-sm text-muted-foreground">Vyhovuje</div> |
| 52 | + <div className="mt-1 font-display text-3xl font-bold text-green-600">{passes}</div> |
| 53 | + </Card> |
| 54 | + <Card className="p-5 text-center"> |
| 55 | + <div className="text-sm text-muted-foreground">Nálezy</div> |
| 56 | + <div className="mt-1 font-display text-3xl font-bold text-orange-600">{totalIssues}</div> |
| 57 | + </Card> |
| 58 | + <Card className="p-5 text-center"> |
| 59 | + <div className="text-sm text-muted-foreground">Vážne</div> |
| 60 | + <div className="mt-1 font-display text-3xl font-bold text-red-600">{criticals}</div> |
| 61 | + </Card> |
| 62 | + </div> |
| 63 | + |
| 64 | + <div className="space-y-3"> |
| 65 | + {issues.map((issue) => ( |
| 66 | + <Card key={issue.id} className={`p-5 transition-shadow hover:shadow-sm ${issue.status === 'fail' ? 'border-l-4 border-l-red-500' : issue.status === 'warning' ? 'border-l-4 border-l-yellow-500' : 'border-l-4 border-l-green-500'}`}> |
| 67 | + <div className="flex items-start gap-4"> |
| 68 | + <div className={`flex h-10 w-10 shrink-0 items-center justify-center rounded-xl ${issue.status === 'pass' ? 'bg-green-100 text-green-600' : issue.status === 'fail' ? 'bg-red-100 text-red-600' : 'bg-yellow-100 text-yellow-600'}`}> |
| 69 | + {issue.status === 'pass' ? <Check className="h-5 w-5" /> : issue.status === 'fail' ? <X className="h-5 w-5" /> : <AlertTriangle className="h-5 w-5" />} |
| 70 | + </div> |
| 71 | + <div className="min-w-0 flex-1"> |
| 72 | + <div className="flex flex-wrap items-center gap-2"> |
| 73 | + <span className="font-medium">{issue.description}</span> |
| 74 | + <Badge variant="outline">{issue.category}</Badge> |
| 75 | + <Badge variant="secondary">WCAG {issue.wcag}</Badge> |
| 76 | + </div> |
| 77 | + {issue.fix && ( |
| 78 | + <p className="mt-1 text-sm text-muted-foreground"> |
| 79 | + <span className="font-medium text-foreground">Oprava:</span> {issue.fix} |
| 80 | + </p> |
| 81 | + )} |
| 82 | + </div> |
| 83 | + <Badge className={issue.status === 'pass' ? 'bg-green-100 text-green-700' : issue.status === 'fail' ? 'bg-red-100 text-red-700' : 'bg-yellow-100 text-yellow-700'}> |
| 84 | + {issue.status === 'pass' ? 'OK' : issue.status === 'fail' ? 'Chyba' : 'Varovanie'} |
| 85 | + </Badge> |
| 86 | + </div> |
| 87 | + </Card> |
| 88 | + ))} |
| 89 | + </div> |
| 90 | + |
| 91 | + <Card className="mt-8 p-6"> |
| 92 | + <h3 className="mb-2 font-display text-lg font-semibold">Zhrnutie auditu</h3> |
| 93 | + <p className="text-sm text-muted-foreground"> |
| 94 | + Stránka dosahuje <strong>{Math.round((passes / issues.length) * 100)}%</strong> z WCAG 2.1 AA kritérií. |
| 95 | + Zostáva <strong>{criticals} vážnych</strong> nálezov na opravu. |
| 96 | + Hlavné oblasti na zlepšenie: kontrast farieb, ovládanie klávesnicou, a screen reader podpora. |
| 97 | + </p> |
| 98 | + </Card> |
| 99 | + </div> |
| 100 | + </div> |
| 101 | + ) |
| 102 | +} |
0 commit comments