import { useCallback, useEffect, useRef, useState } from 'react'; import { useSearchParams } from 'react-router'; import { useClient } from 'hooks/useClient'; import { Folder, Settings2, Layers } from 'lucide-react'; import { SettingsForm } from './SettingsForm'; /** * The collections, and a way back to the settings. * * Selection is `?collection=` in the URL rather than a channel, so which collection you are looking * at survives a reload and can be linked to — `docs/navigation-audit.md`. The links panel reads the same * parameter rather than being handed the id. * * The settings live behind the gear rather than on a screen of their own. They were a screen of their * own for an afternoon and it was the wrong shape: nothing else was built, so opening the plugin put you * on a configuration form with no way forward, which reads as broken rather than unfinished. */ type Collection = { id: number; name: string; _count?: { links?: number } }; /** `?collection=` for "everything", which is a real choice and not the absence of one. */ export const ALL = 'all'; export const CollectionsPanel = () => { const client = useClient(); const clientRef = useRef(client); clientRef.current = client; const [rows, setRows] = useState(null); const [error, setError] = useState(null); const [showSettings, setShowSettings] = useState(false); const [params, setParams] = useSearchParams(); const selected = params.get('collection') ?? ALL; const load = useCallback(async () => { try { const body = await clientRef.current.get<{ response: Collection[] }>('/linkwarden/api/v1/collections'); setRows(body.response ?? []); setError(null); } catch (failure) { // The message matters here. "No account is mapped to you" is something the owner can fix and is // the state every user starts in, so it must not read as an outage. setError(failure instanceof Error ? failure.message : 'Could not read your collections.'); setRows(null); setShowSettings(true); } }, []); useEffect(() => { void load(); }, [load]); const select = (id: string) => setParams( (p) => { p.set('collection', id); return p; }, { replace: true }, ); return (
Collections
{error &&

{error}

}
  • {rows?.map((row) => (
  • ))}
{showSettings && }
); };