Files
parakasa/components/dashboard/category-form.tsx

187 lines
7.0 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"use client"
import { useState } from "react"
import { useForm } from "react-hook-form"
import { zodResolver } from "@hookform/resolvers/zod"
import * as z from "zod"
import { Button } from "@/components/ui/button"
import { Input } from "@/components/ui/input"
import { Textarea } from "@/components/ui/textarea"
import {
Form,
FormControl,
FormField,
FormItem,
FormLabel,
FormMessage,
} from "@/components/ui/form"
import { toast } from "sonner"
import { useRouter } from "next/navigation"
import { createCategory, updateCategory, deleteCategory } from "@/app/(dashboard)/dashboard/categories/actions"
import { Trash } from "lucide-react"
import { AlertModal } from "@/components/modals/alert-modal"
const formSchema = z.object({
name: z.string().min(2, "Kategori adı en az 2 karakter olmalıdır."),
description: z.string().optional(),
image_url: z.string().optional(),
})
type CategoryFormValues = z.infer<typeof formSchema>
interface CategoryFormProps {
initialData?: {
id: string
name: string
description?: string
image_url?: string
} | null
}
export function CategoryForm({ initialData }: CategoryFormProps) {
const router = useRouter()
const [open, setOpen] = useState(false)
const [loading, setLoading] = useState(false)
const title = initialData ? "Kategoriyi Düzenle" : "Yeni Kategori"
const description = initialData ? "Kategori detaylarını düzenleyin." : "Yeni bir kategori ekleyin."
const toastMessage = initialData ? "Kategori güncellendi." : "Kategori oluşturuldu."
const action = initialData ? "Kaydet" : "Oluştur"
const form = useForm<CategoryFormValues>({
resolver: zodResolver(formSchema),
defaultValues: initialData || {
name: "",
description: "",
image_url: "",
},
})
const onSubmit = async (data: CategoryFormValues) => {
setLoading(true)
try {
if (initialData) {
const result = await updateCategory(initialData.id, data)
if ((result as any).error) {
toast.error((result as any).error)
} else {
toast.success(toastMessage)
router.push(`/dashboard/categories`)
router.refresh()
}
} else {
const result = await createCategory(data)
if ((result as any).error) {
toast.error((result as any).error)
} else {
toast.success(toastMessage)
router.push(`/dashboard/categories`)
router.refresh()
}
}
} catch (error) {
toast.error("Bir hata oluştu.")
} finally {
setLoading(false)
}
}
const onDelete = async () => {
setLoading(true)
try {
const result = await deleteCategory(initialData!.id)
if ((result as any).error) {
toast.error((result as any).error)
} else {
toast.success("Kategori silindi.")
router.push(`/dashboard/categories`)
router.refresh()
}
} catch (error) {
toast.error("Silme işlemi başarısız.")
} finally {
setLoading(false)
setOpen(false)
}
}
return (
<>
<AlertModal
isOpen={open}
onClose={() => setOpen(false)}
onConfirm={onDelete}
loading={loading}
/>
<div className="flex items-center justify-between">
<div className="space-y-1">
<h2 className="text-2xl font-bold tracking-tight">{title}</h2>
<p className="text-sm text-muted-foreground">{description}</p>
</div>
{initialData && (
<Button
variant="destructive"
size="sm"
onClick={() => setOpen(true)}
disabled={loading}
>
<Trash className="h-4 w-4" />
</Button>
)}
</div>
<div className="p-4 border rounded-md mt-4">
<Form {...form}>
<form onSubmit={form.handleSubmit(onSubmit)} className="space-y-8 w-full">
<div className="grid grid-cols-1 gap-8 md:grid-cols-2">
<FormField
control={form.control}
name="name"
render={({ field }) => (
<FormItem>
<FormLabel>Başlık</FormLabel>
<FormControl>
<Input disabled={loading} placeholder="Kategori adı..." {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="image_url"
render={({ field }) => (
<FormItem>
<FormLabel>Görsel URL (Opsiyonel)</FormLabel>
<FormControl>
<Input disabled={loading} placeholder="https://..." {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<div className="col-span-1 md:col-span-2">
<FormField
control={form.control}
name="description"
render={({ field }) => (
<FormItem>
<FormLabel>ıklama</FormLabel>
<FormControl>
<Textarea disabled={loading} placeholder="Kategori açıklaması..." {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
</div>
</div>
<Button disabled={loading} className="ml-auto" type="submit">
{action}
</Button>
</form>
</Form>
</div>
</>
)
}