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

214 lines
8.2 KiB
TypeScript
Raw 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 { useRouter } from "next/navigation"
import { useForm, type Resolver } 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 { Checkbox } from "@/components/ui/checkbox"
import {
Form,
FormControl,
FormDescription,
FormField,
FormItem,
FormLabel,
FormMessage,
} from "@/components/ui/form"
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"
import { toast } from "sonner"
import { Loader2 } from "lucide-react"
import { ImageUpload } from "@/components/ui/image-upload"
import { createSlider, updateSlider } from "@/app/(dashboard)/dashboard/sliders/actions"
const sliderSchema = z.object({
title: z.string().min(2, "Başlık en az 2 karakter olmalıdır"),
description: z.string().optional(),
image_url: z.string().min(1, "Görsel yüklemek zorunludur"),
link: z.string().optional(),
order: z.coerce.number().default(0),
is_active: z.boolean().default(true),
})
type SliderFormValues = z.infer<typeof sliderSchema>
interface Slider {
id: string
title: string
description: string | null
image_url: string
link: string | null
order: number | null
is_active: boolean | null
}
interface SliderFormProps {
initialData?: Slider
}
export function SliderForm({ initialData }: SliderFormProps) {
const router = useRouter()
const [loading, setLoading] = useState(false)
const form = useForm<SliderFormValues>({
resolver: zodResolver(sliderSchema) as Resolver<SliderFormValues>,
defaultValues: initialData ? {
title: initialData.title,
description: initialData.description || "",
image_url: initialData.image_url,
link: initialData.link || "",
order: initialData.order || 0,
is_active: initialData.is_active ?? true,
} : {
title: "",
description: "",
image_url: "",
link: "",
order: 0,
is_active: true,
},
})
async function onSubmit(data: SliderFormValues) {
setLoading(true)
try {
let result
if (initialData) {
result = await updateSlider(initialData.id, data)
} else {
result = await createSlider(data)
}
if (result.error) {
toast.error(result.error)
return
}
toast.success(initialData ? "Slider güncellendi" : "Slider oluşturuldu")
router.push("/dashboard/sliders")
router.refresh()
} catch {
toast.error("Bir sorun oluştu.")
} finally {
setLoading(false)
}
}
return (
<Card>
<CardHeader>
<CardTitle>{initialData ? "Slider Düzenle" : "Yeni Slider Ekle"}</CardTitle>
</CardHeader>
<CardContent>
<Form {...form}>
<form onSubmit={form.handleSubmit(onSubmit)} className="space-y-6">
<FormField
name="image_url"
render={({ field }) => (
<FormItem>
<FormLabel>Görsel</FormLabel>
<FormControl>
<ImageUpload
value={field.value}
onChange={field.onChange}
onRemove={() => field.onChange("")}
disabled={loading}
/>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
<FormField
name="title"
render={({ field }) => (
<FormItem>
<FormLabel>Başlık</FormLabel>
<FormControl>
<Input placeholder="Örn: Yeni Sezon Modelleri" {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
name="order"
render={({ field }) => (
<FormItem>
<FormLabel>Sıralama</FormLabel>
<FormControl>
<Input type="number" {...field} />
</FormControl>
<FormDescription>Düşük numara önce gösterilir (0, 1, 2...)</FormDescription>
<FormMessage />
</FormItem>
)}
/>
</div>
<FormField
name="description"
render={({ field }) => (
<FormItem>
<FormLabel>ıklama</FormLabel>
<FormControl>
<Textarea placeholder="Kısa açıklama metni..." {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
name="link"
render={({ field }) => (
<FormItem>
<FormLabel>Yönlendirme Linki (Opsiyonel)</FormLabel>
<FormControl>
<Input placeholder="/kategori/ev-tipi" {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
name="is_active"
render={({ field }) => (
<FormItem className="flex flex-row items-start space-x-3 space-y-0 rounded-md border p-4">
<FormControl>
<Checkbox
checked={field.value}
onCheckedChange={field.onChange}
/>
</FormControl>
<div className="space-y-1 leading-none">
<FormLabel>
Aktif
</FormLabel>
<FormDescription>
Bu slider ana sayfada gösterilsin mi?
</FormDescription>
</div>
</FormItem>
)}
/>
<Button type="submit" disabled={loading} className="w-full sm:w-auto">
{loading && <Loader2 className="mr-2 h-4 w-4 animate-spin" />}
{initialData ? "Kaydet" : "Oluştur"}
</Button>
</form>
</Form>
</CardContent>
</Card>
)
}