import type { JSX } from 'solid-js'; import { createEffect, createMemo, createSignal, Match, Switch } from 'solid-js'; import { FilterPanel } from '@/components/FilterPanel'; import { OpportunityTable } from '@/components/OpportunityTable'; import { buttonPrimary } from '@/components/styles'; import { ThemeToggle } from '@/components/ThemeToggle'; import { ToastList } from '@/components/ToastList'; import type { OpportunityFilters } from '@/lib/filterOpportunities'; import { emptyFilters, filterOpportunities, statusOptions } from '@/lib/filterOpportunities'; import { createLiveUpdates } from '@/primitives/createLiveUpdates'; import { createClassifications, createOpportunities } from '@/primitives/createOpportunities'; import { createOpportunityAnnotations } from '@/primitives/createOpportunityAnnotations'; import { createTheme } from '@/primitives/createTheme'; import { createToasts } from '@/primitives/createToasts'; const statePanel = 'rounded-[10px] border border-line bg-surface px-6 py-12 text-center'; /** The page: the filters, the table of opportunities, and toasts for errors. */ export function App(): JSX.Element { const toasts = createToasts(); const opportunities = createOpportunities(); const classifications = createClassifications(); const annotations = createOpportunityAnnotations(opportunities.items, toasts.show); createLiveUpdates({ opportunities, classifications, annotations }); const theme = createTheme(); const [filters, setFilters] = createSignal(emptyFilters()); const statuses = createMemo(() => statusOptions(opportunities.items())); // annotations.get reads from a store, so hiding an opportunity re-runs this. const rows = createMemo(() => filterOpportunities(opportunities.items(), filters(), annotations.get), ); const clear = (): void => { setFilters(emptyFilters()); }; // A failed load is shown where the list would be, with a retry, and as a // toast, so it's seen wherever the user is looking. createEffect(() => { const err = opportunities.error(); if (err) toasts.show(`Opportunities didn't load: ${err.message}`); }); createEffect(() => { const err = classifications.error(); if (err) toasts.show(`Classifications didn't load: ${err.message}`); }); return (

Opportunities

} >

Loading opportunities…

{(err) => ( )}

There are no opportunities yet.

No opportunities match these filters.

); }