import { useState, useEffect, useCallback, useRef } from 'react' import DrawCanvas, { type DrawCanvasHandle } from '../components/DrawCanvas' import Topbar from '../components/Topbar' import { getDirectusPictures, directusAssetUrl, type DirectusPicture, getDirectusObjects, createDirectusObject, updateDirectusObject, deleteDirectusObject, updatePictureStatus, getPictureWords, savePictureWords, } from '../api' import { useAuth } from '../context/AuthContext' import type { DirectusObject, Selection, CanvasObject, PictureWord } from '../types' const ChevronLeftIcon = () => ( ) const ChevronRightIcon = () => ( ) const TrashIcon = () => ( ) export default function DrawIt() { const { token } = useAuth() const [pictureList, setPictureList] = useState([]) const [currentIndex, setCurrentIndex] = useState(-1) const [objects, setObjects] = useState([]) const [selectedObjectId, setSelectedObjectId] = useState(null) const [currentSelections, setCurrentSelections] = useState([]) const [userNotes, setUserNotes] = useState('') const [safeWords, setSafeWords] = useState<{ title: string; level: number }[]>([]) const [safeWordInput, setSafeWordInput] = useState('') const [safeWordLevel, setSafeWordLevel] = useState(50) const [safeWordInputVisible, setSafeWordInputVisible] = useState(false) const safeWordInputRef = useRef(null) const [pictureWords, setPictureWords] = useState([]) const [savingWords, setSavingWords] = useState(false) const [parentId, setParentId] = useState(null) const [editingNotes, setEditingNotes] = useState<{ id: string; notes: string } | null>(null) const [mode, setMode] = useState<'rect' | 'polygon'>('polygon') const [hasSelection, setHasSelection] = useState(false) const [saving, setSaving] = useState(false) const [finishing, setFinishing] = useState(false) const [status, setStatus] = useState('') const [statusError, setStatusError] = useState(false) const canvasRef = useRef(null) useEffect(() => { if (safeWordInputVisible) safeWordInputRef.current?.focus() }, [safeWordInputVisible]) const addSafeWord = () => { const title = safeWordInput.trim() if (!title || safeWords.some(w => w.title === title) || pictureWords.some(w => w.title_de === title)) { setSafeWordInput(''); return } setSafeWords(prev => [...prev, { title, level: safeWordLevel }]) setSafeWordInput('') setSafeWordLevel(50) setSafeWordInputVisible(false) } const saveSafeWords = async () => { if (!currentPicture || !token || safeWords.length === 0) return setSavingWords(true) try { await savePictureWords(currentPicture.id, safeWords.map(w => ({ title_de: w.title, level: w.level })), token) const updated = await getPictureWords(currentPicture.id, token) setPictureWords(updated) setSafeWords([]) showStatus('Wörter gespeichert.') } catch (e) { showStatus(e instanceof Error ? e.message : 'Fehler beim Speichern der Wörter.', true) } finally { setSavingWords(false) } } const currentPicture: DirectusPicture | null = currentIndex >= 0 && currentIndex < pictureList.length ? pictureList[currentIndex] : null // Map DirectusObject → CanvasObject for rendering const canvasObjects: CanvasObject[] = objects.map((obj, i) => ({ id: obj.id, visible: obj.visible !== false, selections: obj.selections, index: i + 1, hierarchy: 1, })) useEffect(() => { if (!token) return getDirectusPictures(token) .then(pics => { setPictureList(pics); setCurrentIndex(pics.length > 0 ? 0 : -1) }) .catch(console.error) }, [token]) useEffect(() => { if (!currentPicture || !token) { setObjects([]); setSelectedObjectId(null) setPictureWords([]); setSafeWords([]) return } getDirectusObjects(currentPicture.id, token) .then(objs => { setObjects(objs.map(o => ({ ...o, visible: true }))); setSelectedObjectId(null) }) .catch(console.error) getPictureWords(currentPicture.id, token) .then(setPictureWords) .catch(console.error) }, [currentPicture?.id, token]) const showStatus = (msg: string, isError = false) => { setStatus(msg); setStatusError(isError) } const handleHasSelection = useCallback((has: boolean) => setHasSelection(has), []) const addSelection = () => { const sel = canvasRef.current?.getCurrentSelection() if (!sel) { showStatus('Bitte zuerst einen Bereich auswählen.', true); return } setCurrentSelections(prev => { const next = [...prev, sel]; showStatus(`Auswahl ${next.length} hinzugefügt.`); return next }) canvasRef.current?.resetSelection() setHasSelection(false) } const saveObject = async () => { if (!currentPicture || !token || currentSelections.length === 0) return setSaving(true) try { const obj = await createDirectusObject({ picture: currentPicture.id, selections: currentSelections, user_notes: userNotes.trim() || null, parent: parentId, }, token) setObjects(prev => [...prev, { ...obj, visible: true }]) setCurrentSelections([]) setUserNotes('') setParentId(null) canvasRef.current?.resetSelection() showStatus('Objekt gespeichert.') } catch (e) { showStatus(e instanceof Error ? e.message : 'Fehler beim Speichern.', true) } finally { setSaving(false) } } const finishPicture = async () => { if (!currentPicture || !token) return setFinishing(true) try { await updatePictureStatus(currentPicture.id, 'drawing_created', token) setPictureList(prev => prev.filter(p => p.id !== currentPicture.id)) setCurrentIndex(i => Math.max(0, i - 1)) setObjects([]) showStatus('Bild fertiggestellt.') } catch (e) { showStatus(e instanceof Error ? e.message : 'Fehler.', true) } finally { setFinishing(false) } } const saveNoteEdit = async () => { if (!editingNotes || !token) return try { await updateDirectusObject(editingNotes.id, { user_notes: editingNotes.notes }, token) setObjects(prev => prev.map(o => o.id === editingNotes.id ? { ...o, user_notes: editingNotes.notes } : o)) setEditingNotes(null) showStatus('Notizen gespeichert.') } catch (e) { showStatus(e instanceof Error ? e.message : 'Fehler.', true) } } const deleteObject = async (objId: string) => { if (!token) return try { await deleteDirectusObject(objId, token) setObjects(prev => prev.filter(o => o.id !== objId)) if (selectedObjectId === objId) setSelectedObjectId(null) showStatus('Objekt gelöscht.') } catch (e) { showStatus(e instanceof Error ? e.message : 'Fehler beim Löschen.', true) } } const imageNav = (
{pictureList.length > 0 ? <>{currentIndex + 1}/{pictureList.length} : Keine Bilder}
) return (
{/* Left sidebar: saved objects */}