feat(ideas): vervang inline statuschips door IdeasFilterPopover met user-settings persistentie

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Scrum4Me Agent 2026-05-15 04:01:21 +02:00
parent b8eb724d17
commit e398b84930

View file

@ -12,6 +12,10 @@ import { useMemo, useState, useTransition } from 'react'
import { useRouter } from 'next/navigation'
import { Plus, ArrowUp, ArrowDown, ArrowUpDown } from 'lucide-react'
import { toast } from 'sonner'
import { useShallow } from 'zustand/react/shallow'
import { useUserSettingsStore } from '@/stores/user-settings/store'
import { IdeasFilterPopover } from '@/components/ideas/ideas-filter-popover'
import { cn } from '@/lib/utils'
import { Button } from '@/components/ui/button'
@ -122,7 +126,11 @@ export function IdeaList({ ideas, products, isDemo }: IdeaListProps) {
// Filter state
const [search, setSearch] = useState('')
const [productFilter, setProductFilter] = useState<string>('all')
const [statusFilter, setStatusFilter] = useState<Set<IdeaStatusApi>>(new Set())
const filterStatuses = useUserSettingsStore(useShallow(
(s) => s.entities.settings.views?.ideasList?.filterStatuses ?? []))
const setPref = useUserSettingsStore((s) => s.setPref)
const statusFilter = useMemo(() => new Set(filterStatuses), [filterStatuses])
const [filterPopoverOpen, setFilterPopoverOpen] = useState(false)
// Sort state
const [sortKey, setSortKey] = useState<SortKey>('code')
@ -197,12 +205,14 @@ export function IdeaList({ ideas, products, isDemo }: IdeaListProps) {
}
function toggleStatus(s: IdeaStatusApi) {
setStatusFilter((prev) => {
const next = new Set(prev)
if (next.has(s)) next.delete(s)
else next.add(s)
return next
})
const next = filterStatuses.includes(s)
? filterStatuses.filter((v) => v !== s)
: [...filterStatuses, s]
void setPref(['views', 'ideasList', 'filterStatuses'], next)
}
function clearStatusFilter() {
void setPref(['views', 'ideasList', 'filterStatuses'], [])
}
function handleCreate() {
@ -289,6 +299,15 @@ export function IdeaList({ ideas, products, isDemo }: IdeaListProps) {
))}
</select>
<div className="ml-auto flex items-center gap-2">
<IdeasFilterPopover
open={filterPopoverOpen}
onOpenChange={setFilterPopoverOpen}
statusOptions={STATUS_FILTERS}
selected={statusFilter}
onToggle={toggleStatus}
onClear={clearStatusFilter}
activeFilterCount={statusFilter.size}
/>
<DemoTooltip show={isDemo}>
<Button
size="sm"
@ -313,27 +332,6 @@ export function IdeaList({ ideas, products, isDemo }: IdeaListProps) {
</div>
</div>
{/* Status-chips als multi-select filter */}
<div className="flex flex-wrap gap-2">
{STATUS_FILTERS.map((s) => {
const active = statusFilter.has(s.value)
return (
<button
key={s.value}
type="button"
onClick={() => toggleStatus(s.value)}
className={`rounded-full border px-2.5 py-0.5 text-xs transition-colors ${
active
? 'bg-primary text-on-primary border-primary'
: 'bg-background text-muted-foreground border-input hover:bg-muted'
}`}
>
{s.label}
</button>
)
})}
</div>
{/* Snel idee form — geen product-dropdown */}
{showQuick && (
<div className="rounded-md border border-input bg-surface-container p-4 space-y-3">