-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathconfidence-indicator.tsx
More file actions
75 lines (66 loc) · 2.49 KB
/
confidence-indicator.tsx
File metadata and controls
75 lines (66 loc) · 2.49 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
'use client';
import { useState } from 'react';
import { t, type Language } from '@/lib/translations';
// ============================================================================
// Types
// ============================================================================
export type ConfidenceLevel = 1 | 2 | 3;
interface ConfidenceIndicatorProps {
language: Language;
onSelect: (level: ConfidenceLevel) => void;
disabled?: boolean;
selected?: ConfidenceLevel | null;
}
// ============================================================================
// Component
// ============================================================================
const LEVELS: { level: ConfidenceLevel; key: Parameters<typeof t>[0] }[] = [
{ level: 1, key: 'confidence.low' },
{ level: 2, key: 'confidence.medium' },
{ level: 3, key: 'confidence.high' },
];
export function ConfidenceIndicator({
language,
onSelect,
disabled = false,
selected = null,
}: ConfidenceIndicatorProps) {
const [localSelected, setLocalSelected] = useState<ConfidenceLevel | null>(selected);
const isLocked = localSelected !== null || disabled;
const handleSelect = (level: ConfidenceLevel) => {
if (isLocked) return;
setLocalSelected(level);
onSelect(level);
};
return (
<div className="animate-in fade-in duration-300">
<p className="font-mono text-[9px] tracking-[0.15em] text-j-text-tertiary uppercase mb-2">
{t('confidence.prompt', language)}
</p>
<div className="flex gap-2">
{LEVELS.map(({ level, key }) => {
const isActive = localSelected === level;
return (
<button
key={level}
type="button"
onClick={() => handleSelect(level)}
disabled={isLocked && !isActive}
aria-pressed={isActive}
aria-label={`${t(key, language)} — nivel de confianza ${level} de 3`}
className={`flex-1 font-mono text-[10px] tracking-[0.1em] py-2 px-3 border transition-all duration-200 uppercase min-h-[44px] ${
isActive
? 'border-j-accent bg-j-accent-light text-j-accent'
: isLocked
? 'border-j-border bg-j-bg-alt text-j-text-tertiary opacity-40'
: 'border-j-border-input bg-[var(--j-bg)] text-j-text-secondary hover:border-j-accent cursor-pointer'
}`}
>
{t(key, language)}
</button>
);
})}
</div>
</div>
);
}