Remove Companion module entirely from admin-v2. Rebuild in studio-v2 as a focused lesson timer (no dashboard mode). Direct flow: start → active → ended. Fix timer bug where lastTickRef reset prevented countdown. Add companion link to Sidebar and i18n translations. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
195 lines
5.3 KiB
TypeScript
195 lines
5.3 KiB
TypeScript
'use client'
|
|
|
|
import { Plus, Pause, Play, SkipForward, Square, Clock } from 'lucide-react'
|
|
|
|
interface QuickActionsBarProps {
|
|
onExtend: (minutes: number) => void
|
|
onPause: () => void
|
|
onResume: () => void
|
|
onSkip: () => void
|
|
onEnd: () => void
|
|
isPaused: boolean
|
|
isLastPhase: boolean
|
|
disabled?: boolean
|
|
}
|
|
|
|
export function QuickActionsBar({
|
|
onExtend,
|
|
onPause,
|
|
onResume,
|
|
onSkip,
|
|
onEnd,
|
|
isPaused,
|
|
isLastPhase,
|
|
disabled,
|
|
}: QuickActionsBarProps) {
|
|
return (
|
|
<div
|
|
className="flex items-center justify-center gap-3 p-4 bg-white border border-slate-200 rounded-xl"
|
|
role="toolbar"
|
|
aria-label="Steuerung"
|
|
>
|
|
{/* Extend +5 Min */}
|
|
<button
|
|
onClick={() => onExtend(5)}
|
|
disabled={disabled || isPaused}
|
|
className={`
|
|
flex items-center gap-2 px-4 py-3 rounded-xl
|
|
font-medium transition-all duration-200
|
|
min-w-[52px] justify-center
|
|
${disabled || isPaused
|
|
? 'bg-slate-100 text-slate-400 cursor-not-allowed'
|
|
: 'bg-blue-50 text-blue-700 hover:bg-blue-100 active:scale-95'
|
|
}
|
|
`}
|
|
title="+5 Minuten (E)"
|
|
aria-keyshortcuts="e"
|
|
aria-label="5 Minuten verlaengern"
|
|
>
|
|
<Plus className="w-5 h-5" />
|
|
<span>5 Min</span>
|
|
</button>
|
|
|
|
{/* Pause / Resume */}
|
|
<button
|
|
onClick={isPaused ? onResume : onPause}
|
|
disabled={disabled}
|
|
className={`
|
|
flex items-center gap-2 px-6 py-3 rounded-xl
|
|
font-semibold transition-all duration-200
|
|
min-w-[52px] min-h-[52px] justify-center
|
|
${disabled
|
|
? 'bg-slate-100 text-slate-400 cursor-not-allowed'
|
|
: isPaused
|
|
? 'bg-green-600 text-white hover:bg-green-700 shadow-lg shadow-green-500/25 active:scale-95'
|
|
: 'bg-amber-500 text-white hover:bg-amber-600 shadow-lg shadow-amber-500/25 active:scale-95'
|
|
}
|
|
`}
|
|
title={isPaused ? 'Fortsetzen (Leertaste)' : 'Pausieren (Leertaste)'}
|
|
aria-keyshortcuts="Space"
|
|
aria-label={isPaused ? 'Stunde fortsetzen' : 'Stunde pausieren'}
|
|
>
|
|
{isPaused ? (
|
|
<>
|
|
<Play className="w-5 h-5" />
|
|
<span>Fortsetzen</span>
|
|
</>
|
|
) : (
|
|
<>
|
|
<Pause className="w-5 h-5" />
|
|
<span>Pause</span>
|
|
</>
|
|
)}
|
|
</button>
|
|
|
|
{/* Skip Phase / End Lesson */}
|
|
{isLastPhase ? (
|
|
<button
|
|
onClick={onEnd}
|
|
disabled={disabled}
|
|
className={`
|
|
flex items-center gap-2 px-4 py-3 rounded-xl
|
|
font-medium transition-all duration-200
|
|
min-w-[52px] justify-center
|
|
${disabled
|
|
? 'bg-slate-100 text-slate-400 cursor-not-allowed'
|
|
: 'bg-red-50 text-red-700 hover:bg-red-100 active:scale-95'
|
|
}
|
|
`}
|
|
title="Stunde beenden"
|
|
aria-label="Stunde beenden"
|
|
>
|
|
<Square className="w-5 h-5" />
|
|
<span>Beenden</span>
|
|
</button>
|
|
) : (
|
|
<button
|
|
onClick={onSkip}
|
|
disabled={disabled || isPaused}
|
|
className={`
|
|
flex items-center gap-2 px-4 py-3 rounded-xl
|
|
font-medium transition-all duration-200
|
|
min-w-[52px] justify-center
|
|
${disabled || isPaused
|
|
? 'bg-slate-100 text-slate-400 cursor-not-allowed'
|
|
: 'bg-slate-100 text-slate-700 hover:bg-slate-200 active:scale-95'
|
|
}
|
|
`}
|
|
title="Naechste Phase (N)"
|
|
aria-keyshortcuts="n"
|
|
aria-label="Zur naechsten Phase springen"
|
|
>
|
|
<SkipForward className="w-5 h-5" />
|
|
<span>Weiter</span>
|
|
</button>
|
|
)}
|
|
</div>
|
|
)
|
|
}
|
|
|
|
/**
|
|
* Compact version for mobile or sidebar
|
|
*/
|
|
export function QuickActionsCompact({
|
|
onExtend,
|
|
onPause,
|
|
onResume,
|
|
onSkip,
|
|
isPaused,
|
|
isLastPhase,
|
|
disabled,
|
|
}: Omit<QuickActionsBarProps, 'onEnd'>) {
|
|
return (
|
|
<div className="flex items-center gap-2">
|
|
<button
|
|
onClick={() => onExtend(5)}
|
|
disabled={disabled || isPaused}
|
|
className={`
|
|
p-2 rounded-lg transition-all
|
|
${disabled || isPaused
|
|
? 'text-slate-300'
|
|
: 'text-blue-600 hover:bg-blue-50'
|
|
}
|
|
`}
|
|
title="+5 Min"
|
|
>
|
|
<Clock className="w-5 h-5" />
|
|
</button>
|
|
|
|
<button
|
|
onClick={isPaused ? onResume : onPause}
|
|
disabled={disabled}
|
|
className={`
|
|
p-2 rounded-lg transition-all
|
|
${disabled
|
|
? 'text-slate-300'
|
|
: isPaused
|
|
? 'text-green-600 hover:bg-green-50'
|
|
: 'text-amber-600 hover:bg-amber-50'
|
|
}
|
|
`}
|
|
title={isPaused ? 'Fortsetzen' : 'Pausieren'}
|
|
>
|
|
{isPaused ? <Play className="w-5 h-5" /> : <Pause className="w-5 h-5" />}
|
|
</button>
|
|
|
|
{!isLastPhase && (
|
|
<button
|
|
onClick={onSkip}
|
|
disabled={disabled || isPaused}
|
|
className={`
|
|
p-2 rounded-lg transition-all
|
|
${disabled || isPaused
|
|
? 'text-slate-300'
|
|
: 'text-slate-600 hover:bg-slate-50'
|
|
}
|
|
`}
|
|
title="Naechste Phase"
|
|
>
|
|
<SkipForward className="w-5 h-5" />
|
|
</button>
|
|
)}
|
|
</div>
|
|
)
|
|
}
|