import { useState } from 'react' import { useNavigate, useLocation } from 'react-router-dom' import { useSheetStore } from '../../stores/useSheetStore' import { useAuthStore } from '../../stores/useAuthStore' // Inline SVGs — no extra deps const IconFile = () => ( ) const IconGrid = () => ( ) const IconSettings = () => ( ) const IconUpload = () => ( ) const IconPlus = () => ( ) const IconHelp = () => ( ) export default function Sidebar() { const navigate = useNavigate() const location = useLocation() const { sheets, activeSheetId, loadSheet, createSheet, renameSheet, deleteSheet, duplicateSheet } = useSheetStore() const user = useAuthStore(s => s.user) const [renamingId, setRenamingId] = useState(null) const [renameValue, setRenameValue] = useState('') const [contextMenu, setContextMenu] = useState<{ id: string; x: number; y: number } | null>(null) const isActive = (path: string) => location.pathname === path || location.pathname.startsWith(path + '/') const handleNewSheet = async () => { const name = `Sheet ${new Date().toLocaleDateString()}` const id = await createSheet(name) navigate(`/sheet/${id}`) } const handleSelect = async (id: string) => { await loadSheet(id) navigate(`/sheet/${id}`) } const handleContextMenu = (e: React.MouseEvent, id: string) => { e.preventDefault() setContextMenu({ id, x: e.clientX, y: e.clientY }) } const handleRename = (id: string, current: string) => { setRenamingId(id) setRenameValue(current) setContextMenu(null) } const commitRename = async (id: string) => { if (renameValue.trim()) await renameSheet(id, renameValue.trim()) setRenamingId(null) } return (
setContextMenu(null)} > {/* ── Logo ── */}
{/* ── Nav items ── */}
{/* ── Divider ── */}
{/* ── Sheets list ── */}
Sheets
{sheets.map(sheet => { const active = activeSheetId === sheet.id return (
handleContextMenu(e, sheet.id)} className="group flex items-center gap-2 px-3 py-2 rounded-lg cursor-pointer mb-0.5 transition-colors" style={{ background: active ? 'var(--accent-dim)' : 'transparent', borderLeft: active ? '2px solid var(--accent)' : '2px solid transparent', }} onClick={() => handleSelect(sheet.id)} > {renamingId === sheet.id ? ( setRenameValue(e.target.value)} onBlur={() => commitRename(sheet.id)} onKeyDown={e => { if (e.key === 'Enter') commitRename(sheet.id) if (e.key === 'Escape') setRenamingId(null) }} className="flex-1 bg-transparent text-sm outline-none border-b" style={{ color: 'var(--text-primary)', borderColor: 'var(--accent)' }} onClick={e => e.stopPropagation()} /> ) : ( <>
{sheet.name}
{sheet.itemCount} items
)}
) })} {sheets.length === 0 && (
No sheets yet
Click + to create one
)}
{/* ── Admin ── */} {user?.role === 'admin' && (
{[ { label: 'Users', path: '/admin/users' }, { label: 'Clients', path: '/admin/clients' }, { label: 'Dropdowns', path: '/admin/dropdowns' }, ].map(item => ( ))}
)} {/* ── Context menu ── */} {contextMenu && (
e.stopPropagation()} > {[ { label: 'Rename', action: () => { const s = sheets.find(sh => sh.id === contextMenu.id); if (s) handleRename(s.id, s.name) } }, { label: 'Duplicate', action: async () => { await duplicateSheet(contextMenu.id); setContextMenu(null) } }, { label: 'Delete', action: async () => { if (confirm('Delete this sheet?')) { await deleteSheet(contextMenu.id); setContextMenu(null) } }, danger: true }, ].map(item => ( ))}
)}
) }