Services: Admin-Lehrer, Backend-Lehrer, Studio v2, Website, Klausur-Service, School-Service, Voice-Service, Geo-Service, BreakPilot Drive, Agent-Core Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
140 lines
4.8 KiB
TypeScript
140 lines
4.8 KiB
TypeScript
'use client'
|
|
|
|
/**
|
|
* AnnotationToolbar
|
|
*
|
|
* Toolbar for selecting annotation tools and controlling the document viewer.
|
|
*/
|
|
|
|
import type { AnnotationType } from '../types'
|
|
import { ANNOTATION_COLORS } from '../types'
|
|
|
|
interface AnnotationToolbarProps {
|
|
selectedTool: AnnotationType | null
|
|
onSelectTool: (tool: AnnotationType | null) => void
|
|
zoom: number
|
|
onZoomChange: (zoom: number) => void
|
|
annotationCounts: Record<AnnotationType, number>
|
|
disabled?: boolean
|
|
}
|
|
|
|
const ANNOTATION_TOOLS: { type: AnnotationType; label: string; shortcut: string }[] = [
|
|
{ type: 'rechtschreibung', label: 'Rechtschreibung', shortcut: 'R' },
|
|
{ type: 'grammatik', label: 'Grammatik', shortcut: 'G' },
|
|
{ type: 'inhalt', label: 'Inhalt', shortcut: 'I' },
|
|
{ type: 'struktur', label: 'Struktur', shortcut: 'S' },
|
|
{ type: 'stil', label: 'Stil', shortcut: 'T' },
|
|
{ type: 'comment', label: 'Kommentar', shortcut: 'K' },
|
|
]
|
|
|
|
export default function AnnotationToolbar({
|
|
selectedTool,
|
|
onSelectTool,
|
|
zoom,
|
|
onZoomChange,
|
|
annotationCounts,
|
|
disabled = false,
|
|
}: AnnotationToolbarProps) {
|
|
const handleToolClick = (type: AnnotationType) => {
|
|
if (disabled) return
|
|
onSelectTool(selectedTool === type ? null : type)
|
|
}
|
|
|
|
return (
|
|
<div className="p-3 border-b border-slate-200 flex items-center justify-between bg-slate-50">
|
|
{/* Annotation tools */}
|
|
<div className="flex items-center gap-1">
|
|
<span className="text-xs text-slate-500 mr-2">Markieren:</span>
|
|
{ANNOTATION_TOOLS.map(({ type, label, shortcut }) => {
|
|
const isSelected = selectedTool === type
|
|
const count = annotationCounts[type] || 0
|
|
const color = ANNOTATION_COLORS[type]
|
|
|
|
return (
|
|
<button
|
|
key={type}
|
|
onClick={() => handleToolClick(type)}
|
|
disabled={disabled}
|
|
className={`
|
|
relative px-2 py-1.5 text-xs rounded border-2 transition-all
|
|
${disabled ? 'opacity-50 cursor-not-allowed' : 'hover:opacity-80'}
|
|
${isSelected ? 'ring-2 ring-offset-1 ring-slate-400' : ''}
|
|
`}
|
|
style={{
|
|
borderColor: color,
|
|
color: isSelected ? 'white' : color,
|
|
backgroundColor: isSelected ? color : 'transparent',
|
|
}}
|
|
title={`${label} (${shortcut})`}
|
|
>
|
|
<span className="font-medium">{shortcut}</span>
|
|
{count > 0 && (
|
|
<span
|
|
className="absolute -top-2 -right-2 w-4 h-4 text-[10px] rounded-full flex items-center justify-center text-white"
|
|
style={{ backgroundColor: color }}
|
|
>
|
|
{count > 99 ? '99+' : count}
|
|
</span>
|
|
)}
|
|
</button>
|
|
)
|
|
})}
|
|
|
|
{/* Clear selection button */}
|
|
{selectedTool && (
|
|
<button
|
|
onClick={() => onSelectTool(null)}
|
|
className="ml-2 px-2 py-1 text-xs text-slate-500 hover:text-slate-700 hover:bg-slate-200 rounded"
|
|
>
|
|
<svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M6 18L18 6M6 6l12 12" />
|
|
</svg>
|
|
</button>
|
|
)}
|
|
</div>
|
|
|
|
{/* Mode indicator */}
|
|
{selectedTool && (
|
|
<div
|
|
className="px-3 py-1 text-xs rounded-full text-white"
|
|
style={{ backgroundColor: ANNOTATION_COLORS[selectedTool] }}
|
|
>
|
|
{ANNOTATION_TOOLS.find((t) => t.type === selectedTool)?.label || selectedTool}
|
|
</div>
|
|
)}
|
|
|
|
{/* Zoom controls */}
|
|
<div className="flex items-center gap-2">
|
|
<button
|
|
onClick={() => onZoomChange(Math.max(50, zoom - 10))}
|
|
disabled={zoom <= 50}
|
|
className="p-1 rounded hover:bg-slate-200 disabled:opacity-50"
|
|
title="Verkleinern"
|
|
>
|
|
<svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M20 12H4" />
|
|
</svg>
|
|
</button>
|
|
<span className="text-sm w-12 text-center">{zoom}%</span>
|
|
<button
|
|
onClick={() => onZoomChange(Math.min(200, zoom + 10))}
|
|
disabled={zoom >= 200}
|
|
className="p-1 rounded hover:bg-slate-200 disabled:opacity-50"
|
|
title="Vergroessern"
|
|
>
|
|
<svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 4v16m8-8H4" />
|
|
</svg>
|
|
</button>
|
|
<button
|
|
onClick={() => onZoomChange(100)}
|
|
className="px-2 py-1 text-xs rounded hover:bg-slate-200"
|
|
title="Zuruecksetzen"
|
|
>
|
|
Fit
|
|
</button>
|
|
</div>
|
|
</div>
|
|
)
|
|
}
|