161 lines
4.9 KiB
TypeScript
161 lines
4.9 KiB
TypeScript
'use client'
|
|
|
|
import { useState } from 'react'
|
|
import { useForm } from 'react-hook-form'
|
|
import { zodResolver } from '@hookform/resolvers/zod'
|
|
import * as z from 'zod'
|
|
import {
|
|
Dialog,
|
|
DialogContent,
|
|
DialogDescription,
|
|
DialogFooter,
|
|
DialogHeader,
|
|
DialogTitle,
|
|
DialogTrigger,
|
|
} from '@/components/ui/dialog'
|
|
import {
|
|
Form,
|
|
FormControl,
|
|
FormField,
|
|
FormItem,
|
|
FormLabel,
|
|
FormMessage,
|
|
} from '@/components/ui/form'
|
|
import { Input } from '@/components/ui/input'
|
|
import { Button } from '@/components/ui/button'
|
|
import { createCategory, updateCategory } from '@/lib/actions/products'
|
|
import { Category } from '@/lib/types'
|
|
import {
|
|
Select,
|
|
SelectContent,
|
|
SelectItem,
|
|
SelectTrigger,
|
|
SelectValue
|
|
} from '@/components/ui/select'
|
|
import { Cloud, Utensils, HardDrive, Package } from 'lucide-react'
|
|
|
|
const categorySchema = z.object({
|
|
name: z.string().min(2, 'Name muss mindestens 2 Zeichen lang sein'),
|
|
description: z.string().optional(),
|
|
icon: z.string().default('Package'),
|
|
})
|
|
|
|
type CategoryFormValues = z.infer<typeof categorySchema>
|
|
|
|
export function CategoryDialog({
|
|
children,
|
|
category
|
|
}: {
|
|
children: React.ReactNode,
|
|
category?: Category
|
|
}) {
|
|
const [open, setOpen] = useState(false)
|
|
|
|
const form = useForm<CategoryFormValues>({
|
|
resolver: zodResolver(categorySchema) as any,
|
|
defaultValues: {
|
|
name: category?.name || '',
|
|
description: category?.description || '',
|
|
icon: category?.icon || 'Package',
|
|
},
|
|
})
|
|
|
|
async function onSubmit(values: CategoryFormValues) {
|
|
try {
|
|
if (category) {
|
|
await updateCategory(category.id, values)
|
|
} else {
|
|
await createCategory(values)
|
|
}
|
|
setOpen(false)
|
|
form.reset()
|
|
} catch (error) {
|
|
console.error('Error saving category:', error)
|
|
}
|
|
}
|
|
|
|
const icons = [
|
|
{ name: 'Cloud', Icon: Cloud },
|
|
{ name: 'Utensils', Icon: Utensils },
|
|
{ name: 'HardDrive', Icon: HardDrive },
|
|
{ name: 'Package', Icon: Package },
|
|
]
|
|
|
|
return (
|
|
<Dialog open={open} onOpenChange={setOpen}>
|
|
<DialogTrigger asChild>{children}</DialogTrigger>
|
|
<DialogContent className="glass-dark border-white/10 text-white shadow-2xl">
|
|
<DialogHeader>
|
|
<DialogTitle>{category ? 'Kategorie bearbeiten' : 'Neue Kategorie erstellen'}</DialogTitle>
|
|
<DialogDescription>
|
|
Definieren Sie eine Kategorie für Ihre Produkte.
|
|
</DialogDescription>
|
|
</DialogHeader>
|
|
|
|
<Form {...form}>
|
|
<form onSubmit={form.handleSubmit(onSubmit)} className="space-y-4">
|
|
<FormField
|
|
control={form.control}
|
|
name="name"
|
|
render={({ field }) => (
|
|
<FormItem>
|
|
<FormLabel>Name</FormLabel>
|
|
<FormControl>
|
|
<Input placeholder="z.B. Software" className="bg-white/5 border-white/10" {...field} />
|
|
</FormControl>
|
|
<FormMessage />
|
|
</FormItem>
|
|
)}
|
|
/>
|
|
<FormField
|
|
control={form.control}
|
|
name="description"
|
|
render={({ field }) => (
|
|
<FormItem>
|
|
<FormLabel>Beschreibung</FormLabel>
|
|
<FormControl>
|
|
<Input placeholder="Kurze Beschreibung" className="bg-white/5 border-white/10" {...field} />
|
|
</FormControl>
|
|
<FormMessage />
|
|
</FormItem>
|
|
)}
|
|
/>
|
|
<FormField
|
|
control={form.control}
|
|
name="icon"
|
|
render={({ field }) => (
|
|
<FormItem>
|
|
<FormLabel>Icon</FormLabel>
|
|
<Select onValueChange={field.onChange} defaultValue={field.value}>
|
|
<FormControl>
|
|
<SelectTrigger className="bg-white/5 border-white/10">
|
|
<SelectValue placeholder="Icon wählen" />
|
|
</SelectTrigger>
|
|
</FormControl>
|
|
<SelectContent className="glass-dark border-white/10 text-white">
|
|
{icons.map(({ name, Icon }) => (
|
|
<SelectItem key={name} value={name}>
|
|
<div className="flex items-center gap-2">
|
|
<Icon className="w-4 h-4" />
|
|
{name}
|
|
</div>
|
|
</SelectItem>
|
|
))}
|
|
</SelectContent>
|
|
</Select>
|
|
<FormMessage />
|
|
</FormItem>
|
|
)}
|
|
/>
|
|
<DialogFooter>
|
|
<Button type="submit" className="w-full bg-primary hover:bg-primary/90">
|
|
{category ? 'Aktualisieren' : 'Erstellen'}
|
|
</Button>
|
|
</DialogFooter>
|
|
</form>
|
|
</Form>
|
|
</DialogContent>
|
|
</Dialog>
|
|
)
|
|
}
|