188 lines
7.0 KiB
TypeScript
188 lines
7.0 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 { Customer, CustomerInsert } from "@/types/customer"
|
||
import { addCustomer, updateCustomer } from "@/lib/customers/actions"
|
||
|
||
import { Button } from "@/components/ui/button"
|
||
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 { Textarea } from "@/components/ui/textarea"
|
||
import { Plus, Loader2 } from "lucide-react"
|
||
import { toast } from "sonner"
|
||
|
||
const formSchema = z.object({
|
||
full_name: z.string().min(2, "Ad soyad en az 2 karakter olmalıdır"),
|
||
email: z.string().email("Geçersiz e-posta adresi").or(z.literal("")).optional(),
|
||
phone: z.string().optional(),
|
||
address: z.string().optional(),
|
||
notes: z.string().optional(),
|
||
})
|
||
|
||
interface CustomerFormProps {
|
||
customer?: Customer
|
||
trigger?: React.ReactNode
|
||
}
|
||
|
||
export function CustomerForm({ customer, trigger }: CustomerFormProps) {
|
||
const [open, setOpen] = useState(false)
|
||
const [loading, setLoading] = useState(false)
|
||
|
||
const form = useForm<z.infer<typeof formSchema>>({
|
||
resolver: zodResolver(formSchema),
|
||
defaultValues: {
|
||
full_name: customer?.full_name || "",
|
||
email: customer?.email || "",
|
||
phone: customer?.phone || "",
|
||
address: customer?.address || "",
|
||
notes: customer?.notes || "",
|
||
},
|
||
})
|
||
|
||
async function onSubmit(values: z.infer<typeof formSchema>) {
|
||
setLoading(true)
|
||
try {
|
||
const customerData = {
|
||
...values,
|
||
email: values.email || null,
|
||
phone: values.phone || null,
|
||
address: values.address || null,
|
||
notes: values.notes || null,
|
||
} as CustomerInsert
|
||
|
||
let result
|
||
if (customer) {
|
||
result = await updateCustomer(customer.id, customerData)
|
||
} else {
|
||
result = await addCustomer(customerData)
|
||
}
|
||
|
||
if (result.success) {
|
||
toast.success(customer ? "Müşteri güncellendi" : "Müşteri eklendi")
|
||
setOpen(false)
|
||
form.reset()
|
||
} else {
|
||
toast.error(result.error)
|
||
}
|
||
} catch {
|
||
toast.error("Bir hata oluştu")
|
||
} finally {
|
||
setLoading(false)
|
||
}
|
||
}
|
||
|
||
return (
|
||
<Dialog open={open} onOpenChange={setOpen}>
|
||
<DialogTrigger asChild>
|
||
{trigger || (
|
||
<Button>
|
||
<Plus className="mr-2 h-4 w-4" /> Yeni Müşteri
|
||
</Button>
|
||
)}
|
||
</DialogTrigger>
|
||
<DialogContent className="sm:max-w-[425px]">
|
||
<DialogHeader>
|
||
<DialogTitle>{customer ? "Müşteriyi Düzenle" : "Yeni Müşteri Ekle"}</DialogTitle>
|
||
<DialogDescription>
|
||
Müşteri bilgilerini aşağıdan yönetebilirsiniz.
|
||
</DialogDescription>
|
||
</DialogHeader>
|
||
<Form {...form}>
|
||
<form onSubmit={form.handleSubmit(onSubmit)} className="space-y-4">
|
||
<FormField
|
||
control={form.control}
|
||
name="full_name"
|
||
render={({ field }) => (
|
||
<FormItem>
|
||
<FormLabel>Ad Soyad</FormLabel>
|
||
<FormControl>
|
||
<Input placeholder="Ad Soyad" {...field} />
|
||
</FormControl>
|
||
<FormMessage />
|
||
</FormItem>
|
||
)}
|
||
/>
|
||
<FormField
|
||
control={form.control}
|
||
name="email"
|
||
render={({ field }) => (
|
||
<FormItem>
|
||
<FormLabel>E-Posta</FormLabel>
|
||
<FormControl>
|
||
<Input placeholder="ornek@site.com" {...field} />
|
||
</FormControl>
|
||
<FormMessage />
|
||
</FormItem>
|
||
)}
|
||
/>
|
||
<FormField
|
||
control={form.control}
|
||
name="phone"
|
||
render={({ field }) => (
|
||
<FormItem>
|
||
<FormLabel>Telefon</FormLabel>
|
||
<FormControl>
|
||
<Input placeholder="0555..." {...field} />
|
||
</FormControl>
|
||
<FormMessage />
|
||
</FormItem>
|
||
)}
|
||
/>
|
||
<FormField
|
||
control={form.control}
|
||
name="address"
|
||
render={({ field }) => (
|
||
<FormItem>
|
||
<FormLabel>Adres</FormLabel>
|
||
<FormControl>
|
||
<Textarea placeholder="Adres..." {...field} />
|
||
</FormControl>
|
||
<FormMessage />
|
||
</FormItem>
|
||
)}
|
||
/>
|
||
<FormField
|
||
control={form.control}
|
||
name="notes"
|
||
render={({ field }) => (
|
||
<FormItem>
|
||
<FormLabel>Özel Notlar</FormLabel>
|
||
<FormControl>
|
||
<Textarea placeholder="Notlar..." {...field} />
|
||
</FormControl>
|
||
<FormMessage />
|
||
</FormItem>
|
||
)}
|
||
/>
|
||
<DialogFooter>
|
||
<Button type="submit" disabled={loading}>
|
||
{loading && <Loader2 className="mr-2 h-4 w-4 animate-spin" />}
|
||
Kaydet
|
||
</Button>
|
||
</DialogFooter>
|
||
</form>
|
||
</Form>
|
||
</DialogContent>
|
||
</Dialog>
|
||
)
|
||
}
|