feat: complete full CRUD for products with unified edit dialog and robust mapping

This commit is contained in:
DanielS
2026-05-01 01:26:12 +02:00
parent e6d801e9df
commit e6cfc45c67
3 changed files with 43 additions and 22 deletions

View File

@@ -26,7 +26,7 @@ import { Input } from '@/components/ui/input'
import { Button } from '@/components/ui/button'
import { Checkbox } from '@/components/ui/checkbox'
import { Plus, Trash2, X, PlusCircle } from 'lucide-react'
import { createProduct } from '@/lib/actions/products'
import { createProduct, updateProduct } from '@/lib/actions/products'
import { ScrollArea } from '@/components/ui/scroll-area'
import { Separator } from '@/components/ui/separator'
import { Category } from '@/lib/types'
@@ -58,18 +58,25 @@ const productSchema = z.object({
type ProductFormValues = z.infer<typeof productSchema>
export function CreateProductDialog({ categories }: { categories: Category[] }) {
export function CreateProductDialog({ children, categories, product }: { children?: React.ReactNode, categories: Category[], product?: Product }) {
const [open, setOpen] = useState(false)
const form = useForm<ProductFormValues>({
resolver: zodResolver(productSchema) as any,
defaultValues: {
name: '',
description: '',
base_price: 0,
category_id: '',
is_active: true,
modules: [],
name: product?.name || '',
description: product?.description || '',
base_price: product?.base_price || 0,
category_id: product?.category_id || '',
is_active: product?.is_active ?? true,
modules: product?.modules?.map(m => ({
name: m.name,
description: m.description || '',
price: m.price,
is_required: m.is_required,
requirements: m.requirements?.join(', ') || '',
exclusions: m.exclusions?.join(', ') || '',
})) || [],
},
})
@@ -86,24 +93,34 @@ export function CreateProductDialog({ categories }: { categories: Category[] })
requirements: m.requirements ? m.requirements.split(',').map(s => s.trim()).filter(Boolean) : [],
exclusions: m.exclusions ? m.exclusions.split(',').map(s => s.trim()).filter(Boolean) : [],
}))
await createProduct(productData as any, formattedModules as any)
if (product) {
await updateProduct(product.id, productData as any, formattedModules as any)
} else {
await createProduct(productData as any, formattedModules as any)
}
setOpen(false)
form.reset()
if (!product) form.reset()
} catch (error) {
console.error('Error creating product:', error)
console.error('Error saving product:', error)
}
}
return (
<Dialog open={open} onOpenChange={setOpen}>
<DialogTrigger asChild>
<Button className="bg-primary hover:bg-primary/90">
<Plus className="mr-2 h-4 w-4" /> Produkt hinzufügen
</Button>
{children || (
<Button className="bg-primary hover:bg-primary/90">
<Plus className="mr-2 h-4 w-4" /> Produkt hinzufügen
</Button>
)}
</DialogTrigger>
<DialogContent className="sm:max-w-[700px] max-h-[90vh] overflow-hidden flex flex-col glass-dark border-white/10 text-white shadow-2xl">
<DialogHeader>
<DialogTitle className="text-2xl font-bold">Neues Produkt erstellen</DialogTitle>
<DialogTitle className="text-2xl font-bold">
{product ? 'Produkt bearbeiten' : 'Neues Produkt erstellen'}
</DialogTitle>
<DialogDescription className="text-muted-foreground">
Definieren Sie das Basisprodukt und fügen Sie optionale oder erforderliche Module hinzu.
</DialogDescription>
@@ -111,7 +128,7 @@ export function CreateProductDialog({ categories }: { categories: Category[] })
<Form {...form}>
<form onSubmit={form.handleSubmit(onSubmit)} className="space-y-6 flex-1 overflow-hidden flex flex-col">
<ScrollArea className="flex-1 pr-4">
<ScrollArea className="flex-1 max-h-[60vh] pr-4">
<div className="space-y-6 py-4">
<div className="grid grid-cols-2 gap-4">
<FormField