diff --git a/frontend/src/tools/whiteboard.jsx b/frontend/src/tools/whiteboard.jsx index 5a5523a..a2cf1b8 100644 --- a/frontend/src/tools/whiteboard.jsx +++ b/frontend/src/tools/whiteboard.jsx @@ -188,6 +188,8 @@ export default function Whiteboard({ toast, mobile }) { const [current, setCurrent] = useState(null); // { id, title, role } const [creating, setCreating] = useState(false); const [newTitle, setNewTitle] = useState(''); + const [editingId, setEditingId] = useState(null); // ID des gerade umbenannten Boards + const [editTitle, setEditTitle] = useState(''); // ── Canvas-State ────────────────────────────────────────────────────────── const [elements, setElements] = useState([]); @@ -224,6 +226,16 @@ export default function Whiteboard({ toast, mobile }) { .finally(() => setLoading(false)); }, []); + const renameBoard = async (id, title) => { + if (!title?.trim()) return; + try { + await api(`/tools/whiteboard/${id}/title`, { method:'PATCH', body:{ title: title.trim() } }); + setBoards(prev => prev.map(b => b.id === id ? { ...b, title: title.trim() } : b)); + if (current?.id === id) setCurrent(prev => ({ ...prev, title: title.trim() })); + } catch(e) { toast(e.message, 'error'); } + finally { setEditingId(null); } + }; + useEffect(() => { loadBoards(); }, [loadBoards]); // Canvas rendern wenn sich Elemente oder Viewport ändern @@ -560,16 +572,34 @@ export default function Whiteboard({ toast, mobile }) { {boards.map(b => (
openBoard(b)}> + onClick={() => { if (editingId !== b.id) openBoard(b); }}>
🖊
-
{b.title}
+ {editingId === b.id ? ( + setEditTitle(e.target.value)} + onKeyDown={e => { if (e.key==='Enter') renameBoard(b.id, editTitle); if (e.key==='Escape') setEditingId(null); }} + onBlur={() => renameBoard(b.id, editTitle)} + onClick={e => e.stopPropagation()} + style={{ ...S.inp, fontSize:12, fontWeight:700, padding:'3px 8px', width:'100%' }} + /> + ) : ( +
{ e.stopPropagation(); if (b.role==='owner'||b.role==='edit'){ setEditingId(b.id); setEditTitle(b.title); } }}> + {b.title} +
+ )}
{b.role === 'owner' ? '👑 Eigenes' : b.role === 'edit' ? '✏ Bearbeiten' : '👁 Lesen'} {b.owner_name && b.role !== 'owner' && ` · von ${b.owner_name}`} {' · ' + new Date(b.updated_at).toLocaleDateString('de-DE', { day:'2-digit', month:'2-digit', year:'numeric' })}
+ {(b.role === 'owner' || b.role === 'edit') && ( + + )} {b.role === 'owner' && ( - - {current?.title} - {current?.role === 'view' && 👁 nur lesen} - + {editingId === current?.id ? ( + setEditTitle(e.target.value)} + onKeyDown={e => { if (e.key==='Enter') renameBoard(current.id, editTitle); if (e.key==='Escape') setEditingId(null); }} + onBlur={() => renameBoard(current.id, editTitle)} + style={{ ...S.inp, fontSize:13, fontWeight:700, flex:1, padding:'3px 8px' }} + /> + ) : ( + { if (current?.role !== 'view'){ setEditingId(current.id); setEditTitle(current.title); } }} + title={current?.role !== 'view' ? 'Doppelklick zum Umbenennen' : ''} + style={{ color:'#fff', fontFamily:'monospace', fontSize:13, fontWeight:700, flex:1, minWidth:0, + overflow:'hidden', textOverflow:'ellipsis', whiteSpace:'nowrap', + cursor: current?.role !== 'view' ? 'text' : 'default' }}> + {current?.title} + {current?.role === 'view' && 👁 nur lesen} + + )} {/* Aktive User */} {collab.length > 0 && (