import React, { useCallback, useEffect, useMemo, useState } from 'react'; import { ThemeProvider, createTheme, useMediaQuery, Box, Grid, Card, CardContent, CardActions, Typography, Button, TextField, Dialog, DialogTitle, DialogContent, DialogActions, IconButton, styled } from '@mui/material'; import EditIcon from '@mui/icons-material/Edit'; import DeleteIcon from '@mui/icons-material/Delete'; import AddIcon from '@mui/icons-material/Add'; import { useTLDraw } from '../../../../../contexts/TLDrawContext'; import { useAuth } from '../../../../../contexts/AuthContext'; type Cabinet = { id: string; name: string }; const Toolbar = styled('div')(() => ({ display: 'flex', gap: '8px', marginBottom: '8px' })); export const CCCabinetsPanel: React.FC = () => { const { tldrawPreferences } = useTLDraw() as { tldrawPreferences?: { colorScheme?: 'light' | 'dark' | 'system' } }; const { user: authUser, accessToken } = useAuth(); const prefersDarkMode = useMediaQuery('(prefers-color-scheme: dark)'); const [cabinets, setCabinets] = useState([]); const [createOpen, setCreateOpen] = useState(false); const [renameOpen, setRenameOpen] = useState(null); const [newName, setNewName] = useState(''); const theme = useMemo(() => { const mode = (tldrawPreferences?.colorScheme === 'system') ? (prefersDarkMode ? 'dark' : 'light') : (tldrawPreferences?.colorScheme === 'dark' ? 'dark' : 'light'); return createTheme({ palette: { mode, divider: 'var(--color-divider)' } }); }, [tldrawPreferences?.colorScheme, prefersDarkMode]); const API_BASE: string = import.meta.env.VITE_API_BASE || '/api'; type RequestInitLite = { method?: string; body?: string | FormData | Blob | null; headers?: Record } | undefined; const apiFetch = useCallback(async (url: string, init?: RequestInitLite) => { const fullUrl = url.startsWith('http') ? url : `${API_BASE}${url}`; const res = await fetch(fullUrl, { ...init, headers: { 'Authorization': `Bearer ${accessToken || ''}`, ...(init?.headers || {}) } }); if (!res.ok) throw new Error(await res.text()); return res.json(); }, [accessToken, API_BASE]); const loadCabinets = useCallback(async () => { const data = await apiFetch('/database/cabinets'); setCabinets([...(data.owned || []), ...(data.shared || [])]); }, [apiFetch]); useEffect(() => { if (authUser?.id) { loadCabinets(); } }, [loadCabinets, authUser?.id]); const handleCreate = async () => { if (!newName.trim()) return; await apiFetch('/database/cabinets', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ name: newName }) }); setNewName(''); setCreateOpen(false); await loadCabinets(); }; const handleRename = async () => { if (!renameOpen || !newName.trim()) return; await apiFetch(`/database/cabinets/${renameOpen.id}`, { method: 'PATCH', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ name: newName }) }); setRenameOpen(null); setNewName(''); await loadCabinets(); }; const handleDelete = async (cabinetId: string) => { await apiFetch(`/database/cabinets/${cabinetId}`, { method: 'DELETE' }); await loadCabinets(); }; return ( {cabinets.map(c => (
{c.name} {c.id}
{ setRenameOpen(c); setNewName(c.name); }} title="Rename"> handleDelete(c.id)} title="Delete">
))}
setCreateOpen(false)}> Create Cabinet setNewName(e.target.value)} /> setRenameOpen(null)}> Rename Cabinet setNewName(e.target.value)} />
); };