Spaces:
Running
Running
File size: 2,992 Bytes
a17d02d 4e4ab34 a17d02d 4e4ab34 be8595f a17d02d be8595f a17d02d be8595f a17d02d be8595f a17d02d | 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 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 | import CalcIcon from 'lucide-react/dist/esm/icons/calculator'
import Send from 'lucide-react/dist/esm/icons/send'
import clsx from 'clsx'
import Logo from '../shared/Logo'
import Spinner from '../shared/Spinner'
import TimerDisplay from './TimerDisplay'
export default function TestHeader({
attemptNumber,
currentQuestion,
endTimeMs,
handleTimerExpire,
maxAttempts,
onSubmitClick,
questions,
setCurrent,
setShowCalc,
showCalc,
subjects,
submitting,
test,
totalViolations,
}) {
return (
<div className="app-header flex items-center px-2 sm:px-4 h-12 border-b flex-shrink-0 theme-header-surface">
<div className="flex items-center gap-2 mr-3 flex-shrink-0">
<Logo size="xs" />
<span className="text-foreground text-sm font-semibold hidden md:block truncate max-w-[160px]">
{test?.title}
</span>
</div>
<div className="flex items-center gap-0 flex-1 overflow-x-auto scrollbar-hide" role="tablist" aria-label="Subjects">
{subjects.map(subject => {
const isActive = (currentQuestion?.subject || 'General') === subject
return (
<button
key={subject}
role="tab"
aria-selected={isActive}
tabIndex={isActive ? 0 : -1}
onClick={() => {
const idx = questions.findIndex(q => (q.subject || 'General') === subject)
if (idx >= 0) setCurrent(idx)
}}
className={clsx('subject-tab text-xs', isActive && 'active')}
>
{subject}
</button>
)
})}
</div>
<div className="flex items-center gap-2 flex-shrink-0 ml-2">
{attemptNumber && (
<span className="text-xs font-medium hidden sm:block theme-header-muted">
Attempt {attemptNumber}/{maxAttempts}
</span>
)}
{totalViolations > 0 && (
<span className="text-xs font-medium text-destructive hidden sm:block">
{totalViolations}/3 Violations
</span>
)}
<button
onClick={() => setShowCalc(s => !s)}
className={clsx(
'flex items-center gap-1 px-2 py-1 rounded text-xs border transition-colors',
showCalc
? 'bg-primary border-primary text-white'
: 'theme-border text-muted-foreground hover:text-foreground hover:border-muted-foreground'
)}
>
<CalcIcon size={13} /> Calc
</button>
<TimerDisplay endTime={endTimeMs} onExpire={handleTimerExpire} />
<button
onClick={onSubmitClick}
disabled={submitting}
className="flex items-center gap-1 px-3 py-1 rounded bg-primary hover:bg-primary text-white text-xs font-medium transition-colors disabled:opacity-50"
>
{submitting ? <Spinner size={12} /> : <Send size={12} />} Submit
</button>
</div>
</div>
)
}
|