'use client' import { useState, useTransition } from 'react' import { Category, Product, ProductModule } from '@/lib/types' import { updateProduct, createProduct, updateCategory, createCategory, deleteProduct, deleteCategory } from '@/lib/actions/products' import { InlineInput } from './components/inline-input' import { ModulePopover } from './components/module-popover' import { Trash2 } from 'lucide-react' export function WysiwygAdminClient({ initialCategories, initialProducts, allModules }: { initialCategories: Category[] initialProducts: Product[] allModules: ProductModule[] }) { const [mode, setMode] = useState<'purchase' | 'subscription'>('purchase') const [categories, setCategories] = useState(initialCategories) const [products, setProducts] = useState(initialProducts) const [isPending, startTransition] = useTransition() const handleDeleteCategory = async (catId: string) => { // Cascade-Check: check if there are products belonging to this category const categoryProducts = products.filter(p => p.category_id === catId) if (categoryProducts.length > 0) { alert(`Diese Kategorie enthält noch ${categoryProducts.length} Produkte. Bitte lösche oder verschiebe diese zuerst!`) return } if (!window.confirm('Möchten Sie diese Kategorie wirklich löschen?')) { return } startTransition(async () => { try { await deleteCategory(catId) setCategories(categories.filter(c => c.id !== catId)) } catch (e) { console.error(e) alert('Fehler beim Löschen der Kategorie.') } }) } const handleDeleteProduct = async (prodId: string) => { if (!window.confirm('Möchten Sie dieses Produkt wirklich löschen?')) { return } startTransition(async () => { try { await deleteProduct(prodId) setProducts(products.filter(p => p.id !== prodId)) } catch (e) { console.error(e) alert('Fehler beim Löschen des Produkts.') } }) } // Filterung der Kategorien nach aktivem Modus const filteredCategories = categories.filter(cat => mode === 'purchase' ? cat.show_in_kauf : cat.show_in_abo ) // Filterung der Produkte nach aktivem Modus const filteredProducts = products.filter(p => mode === 'purchase' ? p.billing_interval === 'one_time' : p.billing_interval === 'monthly' ) const handleAddCategory = async () => { startTransition(async () => { try { const newCat = await createCategory({ name: 'Neue Kategorie', description: 'Beschreibung hier...', sort_order: categories.length + 1, is_required: false, allow_multiselect: false, free_items_limit: 0, preselect: false, show_in_kauf: mode === 'purchase', show_in_abo: mode === 'subscription' }) setCategories([...categories, newCat]) } catch (e) { console.error(e) } }) } const handleAddProduct = async (categoryId: string) => { startTransition(async () => { try { const newProd = await createProduct({ name: 'Neues Produkt', description: 'Produktbeschreibung...', base_price: 19.99, tax_rate: 19, billing_interval: mode === 'purchase' ? 'one_time' : 'monthly', category_id: categoryId, show_in_kauf: mode === 'purchase', show_in_abo: mode === 'subscription' }, []) setProducts([...products, newProd]) } catch (e) { console.error(e) } }) } const handleCategoryToggle = async (catId: string, fields: Partial) => { startTransition(async () => { try { setCategories(categories.map(c => c.id === catId ? { ...c, ...fields } : c)) await updateCategory(catId, fields) } catch (e) { console.error(e) } }) } return (
{isPending && Speichere Änderungen...}
{filteredCategories .sort((a, b) => a.sort_order - b.sort_order) .map(cat => { const catProducts = filteredProducts.filter(p => p.category_id === cat.id) return (
{ await updateCategory(cat.id, { name: newName }) setCategories(categories.map(c => c.id === cat.id ? { ...c, name: newName } : c)) }} className="text-2xl font-bold text-white block w-full" /> { await updateCategory(cat.id, { description: newDesc }) setCategories(categories.map(c => c.id === cat.id ? { ...c, description: newDesc } : c)) }} className="text-slate-400 text-sm mt-1 block w-full" /> {/* Kategorie Attribute (Toggles) */}
{catProducts.map(prod => (
{ await updateProduct(prod.id, { name: newName }, prod.modules || []) setProducts(products.map(p => p.id === prod.id ? { ...p, name: newName } : p)) }} className="font-semibold text-white block" />
{ await updateProduct(prod.id, { description: newDesc }, prod.modules || []) setProducts(products.map(p => p.id === prod.id ? { ...p, description: newDesc } : p)) }} className="text-xs text-slate-400 block" />
{ const priceNum = parseFloat(newPrice) || 0 await updateProduct(prod.id, { base_price: priceNum }, prod.modules || []) setProducts(products.map(p => p.id === prod.id ? { ...p, base_price: priceNum } : p)) }} className="inline-block" />
{/* Modul-Badges */}
Module:
{(prod.modules || []).length > 0 ? ( (prod.modules || []).map((m) => ( {m.name} )) ) : ( Keine Module )}
{/* Modul hinzufügen Popover */}
{ const newMod = { name: mod.name, description: mod.description, price: mod.price, requirements: mod.requirements || [], exclusions: mod.exclusions || [], has_quantity: mod.has_quantity || false } const updatedModules = [...(prod.modules || []), newMod] setProducts(products.map(p => p.id === prod.id ? { ...p, modules: updatedModules as any } : p)) await updateProduct(prod.id, {}, updatedModules) }} />
))}
) })}
) }