From a28f0249e54af3570857f1a7e499877bfd85ad5d Mon Sep 17 00:00:00 2001 From: Janpeter Visser <30029041+madhura68@users.noreply.github.com> Date: Wed, 6 May 2026 07:24:20 +0200 Subject: [PATCH] ST-1230: Sorteerstate en -logica toevoegen aan IdeaList (#126) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat(ideas): STATUS_SORT_ORDER + sorteerstate (ST-cmotjj9uf000104l5i70so19b) - Voeg STATUS_SORT_ORDER toe: workflow-volgorde map (draft→plan_failed) - Zet standaard sortDir op 'desc' conform AC (code aflopend bij laden) Co-Authored-By: Claude Sonnet 4.6 * feat(ideas): sorted useMemo + tabel-render koppelen (ST-cmotjj9uf000104l5i70so19b) - Voeg sorted useMemo toe na filtered: locale-aware sort met STATUS_SORT_ORDER - Ideeën zonder product sorteren achteraan bij oplopende productsortering - Vervang filtered.length/filtered.map door sorted in tabel-render Co-Authored-By: Claude Sonnet 4.6 --------- Co-authored-by: Claude Sonnet 4.6 --- components/ideas/idea-list.tsx | 31 ++++++++++++++++++++++++++++--- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/components/ideas/idea-list.tsx b/components/ideas/idea-list.tsx index 2b92ca2..d052fd1 100644 --- a/components/ideas/idea-list.tsx +++ b/components/ideas/idea-list.tsx @@ -70,6 +70,11 @@ const STATUS_FILTERS: { value: IdeaStatusApi; label: string }[] = [ { value: 'plan_failed', label: 'Plan mislukt' }, ] +const STATUS_SORT_ORDER: Record = { + draft: 0, grilling: 1, grilled: 2, planning: 3, + plan_ready: 4, planned: 5, grill_failed: 6, plan_failed: 7, +} + function SortHeader({ col, label, @@ -113,7 +118,7 @@ export function IdeaList({ ideas, products, isDemo }: IdeaListProps) { // Sort state const [sortKey, setSortKey] = useState('code') - const [sortDir, setSortDir] = useState<'asc' | 'desc'>('asc') + const [sortDir, setSortDir] = useState<'asc' | 'desc'>('desc') // Create-form state const [showCreate, setShowCreate] = useState(false) @@ -149,6 +154,26 @@ export function IdeaList({ ideas, products, isDemo }: IdeaListProps) { }) }, [ideas, search, productFilter, statusFilter, sortKey, sortDir]) + const sorted = useMemo(() => { + return [...filtered].sort((a, b) => { + let cmp = 0 + if (sortKey === 'code') { + cmp = (a.code ?? '').localeCompare(b.code ?? '', 'nl', { numeric: true }) + } else if (sortKey === 'title') { + cmp = a.title.localeCompare(b.title, 'nl') + } else if (sortKey === 'product') { + const aN = a.product?.name ?? '' + const bN = b.product?.name ?? '' + if (!aN && bN) return sortDir === 'asc' ? 1 : -1 + if (aN && !bN) return sortDir === 'asc' ? -1 : 1 + cmp = aN.localeCompare(bN, 'nl') + } else { + cmp = (STATUS_SORT_ORDER[a.status] ?? 99) - (STATUS_SORT_ORDER[b.status] ?? 99) + } + return sortDir === 'asc' ? cmp : -cmp + }) + }, [filtered, sortKey, sortDir]) + function handleSort(col: SortKey) { if (sortKey === col) { setSortDir((d) => (d === 'asc' ? 'desc' : 'asc')) @@ -311,7 +336,7 @@ export function IdeaList({ ideas, products, isDemo }: IdeaListProps) { )} {/* Tabel */} - {filtered.length === 0 ? ( + {sorted.length === 0 ? (

{ideas.length === 0 ? 'Nog geen ideeën — start hierboven met "Nieuw idee".' @@ -329,7 +354,7 @@ export function IdeaList({ ideas, products, isDemo }: IdeaListProps) { - {filtered.map((idea) => { + {sorted.map((idea) => { const badge = getIdeaStatusBadge(API_TO_DB[idea.status]) return (