'use client' import { useState, useRef, useCallback } from 'react' import type { Annotation, AnnotationType, AnnotationPosition } from '@/app/korrektur/types' import { ANNOTATION_COLORS } from '@/app/korrektur/types' interface AnnotationLayerProps { annotations: Annotation[] selectedAnnotation: string | null currentTool: AnnotationType | null onAnnotationCreate: (position: AnnotationPosition, type: AnnotationType) => void onAnnotationSelect: (id: string | null) => void onAnnotationDelete: (id: string) => void isEditable?: boolean className?: string } export function AnnotationLayer({ annotations, selectedAnnotation, currentTool, onAnnotationCreate, onAnnotationSelect, onAnnotationDelete, isEditable = true, className = '', }: AnnotationLayerProps) { const containerRef = useRef(null) const [isDrawing, setIsDrawing] = useState(false) const [drawStart, setDrawStart] = useState<{ x: number; y: number } | null>(null) const [drawEnd, setDrawEnd] = useState<{ x: number; y: number } | null>(null) const getRelativePosition = useCallback( (e: React.MouseEvent | MouseEvent): { x: number; y: number } => { if (!containerRef.current) return { x: 0, y: 0 } const rect = containerRef.current.getBoundingClientRect() return { x: ((e.clientX - rect.left) / rect.width) * 100, y: ((e.clientY - rect.top) / rect.height) * 100, } }, [] ) const handleMouseDown = (e: React.MouseEvent) => { if (!isEditable || !currentTool) return e.preventDefault() e.stopPropagation() const pos = getRelativePosition(e) setIsDrawing(true) setDrawStart(pos) setDrawEnd(pos) onAnnotationSelect(null) } const handleMouseMove = useCallback( (e: React.MouseEvent) => { if (!isDrawing || !drawStart) return const pos = getRelativePosition(e) setDrawEnd(pos) }, [isDrawing, drawStart, getRelativePosition] ) const handleMouseUp = useCallback( (e: React.MouseEvent) => { if (!isDrawing || !drawStart || !drawEnd || !currentTool) { setIsDrawing(false) return } // Calculate rectangle bounds const minX = Math.min(drawStart.x, drawEnd.x) const minY = Math.min(drawStart.y, drawEnd.y) const maxX = Math.max(drawStart.x, drawEnd.x) const maxY = Math.max(drawStart.y, drawEnd.y) // Minimum size check (at least 2% width/height) const width = maxX - minX const height = maxY - minY if (width >= 1 && height >= 1) { const position: AnnotationPosition = { x: minX, y: minY, width: width, height: height, } onAnnotationCreate(position, currentTool) } setIsDrawing(false) setDrawStart(null) setDrawEnd(null) }, [isDrawing, drawStart, drawEnd, currentTool, onAnnotationCreate] ) const handleAnnotationClick = (e: React.MouseEvent, id: string) => { e.stopPropagation() onAnnotationSelect(selectedAnnotation === id ? null : id) } const handleBackgroundClick = () => { onAnnotationSelect(null) } // Drawing preview rectangle const drawingRect = isDrawing && drawStart && drawEnd ? { x: Math.min(drawStart.x, drawEnd.x), y: Math.min(drawStart.y, drawEnd.y), width: Math.abs(drawEnd.x - drawStart.x), height: Math.abs(drawEnd.y - drawStart.y), } : null return (
{/* Existing Annotations */} {annotations.map((annotation) => { const color = ANNOTATION_COLORS[annotation.type] || '#6b7280' const isSelected = selectedAnnotation === annotation.id return ( handleAnnotationClick(e, annotation.id)} > {/* Highlight Rectangle */} {/* Type Indicator */} {/* Severity Indicator */} {annotation.severity === 'critical' && ( )} ) })} {/* Drawing Preview */} {drawingRect && currentTool && ( )} {/* Selected Annotation Popup */} {selectedAnnotation && ( a.id === selectedAnnotation)!} onDelete={() => onAnnotationDelete(selectedAnnotation)} onClose={() => onAnnotationSelect(null)} /> )}
) } // ============================================================================= // ANNOTATION POPUP // ============================================================================= interface AnnotationPopupProps { annotation: Annotation onDelete: () => void onClose: () => void } function AnnotationPopup({ annotation, onDelete, onClose }: AnnotationPopupProps) { const color = ANNOTATION_COLORS[annotation.type] || '#6b7280' const typeLabels: Record = { rechtschreibung: 'Rechtschreibung', grammatik: 'Grammatik', inhalt: 'Inhalt', struktur: 'Struktur', stil: 'Stil', comment: 'Kommentar', highlight: 'Markierung', } return (
e.stopPropagation()} > {/* Header */}
{typeLabels[annotation.type]}
{/* Content */}
{annotation.text && (

{annotation.text}

)} {annotation.suggestion && (

Vorschlag:

{annotation.suggestion}

)} {/* Severity Badge */}
{annotation.severity === 'critical' ? 'Kritisch' : annotation.severity === 'major' ? 'Wichtig' : 'Hinweis'}
{/* Actions */}
) }