import { useState, useEffect } from 'react'; import { useParams, useNavigate } from 'react-router-dom'; import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'; import toast from 'react-hot-toast'; import { ArrowLeft, Save, Plus, X } from 'lucide-react'; import { api } from '../../lib/api-client'; import { AppShell, PageHeader, PageBody } from '../../layout/AppShell'; import { Button, Badge, Card, CardContent, Input, Label, Select, Textarea } from '../../components/ui/primitives'; import { Tabs, TabsList, TabsTrigger, TabsContent } from '../../components/ui/tabs'; interface Rule { field: 'brand' | 'price' | 'gender' | 'is_sneaker' | 'in_stock'; op: 'eq' | 'neq' | 'lt' | 'gt' | 'lte' | 'gte' | 'contains'; value: string; } interface RuleSet { match: 'all' | 'any'; rules: Rule[]; } interface Collection { id: string; name: string; slug: string; type: 'smart' | 'manual'; rules: RuleSet | null; sort_field: string; sort_dir: 'asc' | 'desc'; item_limit: number; description: string | null; seo_title: string | null; seo_desc: string | null; enabled: boolean; } export function CollectionEditor() { const { id } = useParams<{ id: string }>(); const qc = useQueryClient(); const navigate = useNavigate(); const [form, setForm] = useState | null>(null); const { data } = useQuery({ queryKey: ['collection', id], queryFn: () => api.get<{ collection: Collection }>(`/collections/${id}`), enabled: !!id, }); useEffect(() => { if (data?.collection) setForm(data.collection); }, [data?.collection]); const saveMut = useMutation({ mutationFn: (body: Partial) => api.put(`/collections/${id}`, body), onSuccess: () => { toast.success('Collectie opgeslagen'); qc.invalidateQueries({ queryKey: ['collection', id] }); qc.invalidateQueries({ queryKey: ['collections'] }); }, onError: (e: Error) => toast.error(e.message), }); if (!form) { return ( ); } const rules: RuleSet = form.rules ?? { match: 'all', rules: [] }; function updateRules(next: RuleSet) { setForm((f) => ({ ...f!, rules: next })); } function addRule() { updateRules({ ...rules, rules: [...rules.rules, { field: 'brand', op: 'eq', value: '' }] }); } function updateRule(i: number, patch: Partial) { const next = [...rules.rules]; next[i] = { ...next[i], ...patch }; updateRules({ ...rules, rules: next }); } function removeRule(i: number) { const next = [...rules.rules]; next.splice(i, 1); updateRules({ ...rules, rules: next }); } return ( } /> Configuratie Regels SEO
setForm({ ...form, name: e.target.value })} />
setForm({ ...form, slug: e.target.value })} />
setForm({ ...form, item_limit: Number(e.target.value) })} />