"use client"; import { useMemo, useCallback, useState } from "react"; import type { ColumnDef, ColumnPreferences, ViewKey } from "@capakraken/shared"; import { trpc } from "~/lib/trpc/client.js"; // Simple localStorage helper (no external lib needed) function readLocalVisible(view: ViewKey): string[] | null { if (typeof window === "undefined") return null; try { const raw = localStorage.getItem(`colvis_${view}`); return raw ? (JSON.parse(raw) as string[]) : null; } catch { return null; } } function writeLocalVisible(view: ViewKey, keys: string[]) { if (typeof window === "undefined") return; localStorage.setItem(`colvis_${view}`, JSON.stringify(keys)); } export function useColumnConfig( view: ViewKey, builtinColumns: ColumnDef[], customColumns: ColumnDef[] = [], ) { const allColumns = useMemo( () => [...builtinColumns, ...customColumns], [builtinColumns, customColumns], ); // Local optimistic state — immediately reflects user toggles without waiting for server const [localVisible, setLocalVisible] = useState( () => readLocalVisible(view), ); const { data: serverPrefs } = trpc.user.getColumnPreferences.useQuery(undefined, { staleTime: 300_000, placeholderData: (prev) => prev, }); const setMutation = trpc.user.setColumnPreferences.useMutation(); const visibleKeys = useMemo(() => { const alwaysVisible = allColumns.filter((c) => !c.hideable).map((c) => c.key); // Local state (optimistic) → server prefs → defaults const saved = localVisible ?? (serverPrefs as ColumnPreferences | undefined)?.[view]?.visible ?? null; if (saved) { const valid = saved.filter((k) => allColumns.some((c) => c.key === k)); return [...new Set([...alwaysVisible, ...valid])]; } return allColumns.filter((c) => c.defaultVisible).map((c) => c.key); }, [localVisible, serverPrefs, allColumns, view]); const visibleColumns = useMemo( () => allColumns .filter((c) => visibleKeys.includes(c.key)) .sort((a, b) => visibleKeys.indexOf(a.key) - visibleKeys.indexOf(b.key)), [allColumns, visibleKeys], ); const setVisible = useCallback( (keys: string[]) => { setLocalVisible(keys); // immediate re-render writeLocalVisible(view, keys); // persist for next page load setMutation.mutate({ view, visible: keys }); // sync to server }, [view, setMutation], ); return { allColumns, visibleColumns, visibleKeys, setVisible }; }