import { useEffect, useRef, useState } from 'react'; import { CreateLibrary, DeleteLibrary, ImportCSV, ListLibraries, SwitchLibrary } from 'wailsjs/go/main/App'; import type { handler } from 'wailsjs/go/models'; interface LibraryBarProps { activeName: string; onSwitch: (name: string) => void; } export default function LibraryBar({ activeName, onSwitch }: LibraryBarProps) { const [open, setOpen] = useState(false); const [libs, setLibs] = useState([]); const [creating, setCreating] = useState(false); const [newName, setNewName] = useState(''); const [importing, setImporting] = useState(false); const [msg, setMsg] = useState(''); const ref = useRef(null); const load = async () => { setLibs(await ListLibraries()); }; useEffect(() => { if (open) load(); }, [open]); // Close on outside click useEffect(() => { const handler = (e: MouseEvent) => { if (ref.current && !ref.current.contains(e.target as Node)) setOpen(false); }; document.addEventListener('mousedown', handler); return () => document.removeEventListener('mousedown', handler); }, []); const handleSwitch = async (name: string) => { await SwitchLibrary(name); onSwitch(name); setOpen(false); }; const handleCreate = async () => { if (!newName.trim()) return; const err = await CreateLibrary(newName.trim(), ''); if (!err) { onSwitch(newName.trim()); setNewName(''); setCreating(false); load(); } else setMsg(err); }; const handleImport = async () => { setImporting(true); setMsg(''); const result = await ImportCSV(); setImporting(false); if (result.error && result.error !== '已取消') setMsg(result.error); else if (result.imported > 0) { setMsg(`✓ 导入了 ${result.imported} 条(跳过 ${result.skipped} 条)`); load(); } setTimeout(() => setMsg(''), 4000); }; return (
{/* Button row */}
{msg &&

{msg}

} {/* Dropdown */} {open && (
{libs.map(lib => (
handleSwitch(lib.name)}> {lib.is_active ? '✅' : '📁'}

{lib.name}

{lib.entry_count} 条记录

{!lib.is_active && ( )}
))}
{/* Create new */}
{creating ? (
setNewName(e.target.value)} onKeyDown={e => e.key === 'Enter' && handleCreate()} style={{ paddingLeft: '10px', paddingRight: '10px' }} />
) : ( )}
)}
); }