Feat: Add searchable customer combobox to ReservationForm
This commit is contained in:
@@ -7,7 +7,7 @@ export default async function NewReservationPage() {
|
||||
|
||||
// Fetch necessary data for the form
|
||||
const { data: halls } = await supabase.from('halls').select('id, name')
|
||||
const { data: customers } = await supabase.from('customers').select('id, full_name').order('created_at', { ascending: false }).limit(50)
|
||||
const { data: customers } = await supabase.from('customers').select('id, full_name, phone').order('created_at', { ascending: false }).limit(100)
|
||||
const { data: packages } = await supabase.from('packages').select('id, name, price').eq('is_active', true)
|
||||
|
||||
return (
|
||||
|
||||
@@ -18,6 +18,21 @@ import { Textarea } from "@/components/ui/textarea"
|
||||
import { createReservation } from "./actions"
|
||||
import { useState } from "react"
|
||||
import { toast } from "sonner"
|
||||
import { Check, ChevronsUpDown } from "lucide-react"
|
||||
import { cn } from "@/lib/utils"
|
||||
import {
|
||||
Command,
|
||||
CommandEmpty,
|
||||
CommandGroup,
|
||||
CommandInput,
|
||||
CommandItem,
|
||||
CommandList,
|
||||
} from "@/components/ui/command"
|
||||
import {
|
||||
Popover,
|
||||
PopoverContent,
|
||||
PopoverTrigger,
|
||||
} from "@/components/ui/popover"
|
||||
|
||||
const formSchema = z.object({
|
||||
hall_id: z.string().min(1, "Salon seçmelisiniz."),
|
||||
@@ -31,13 +46,14 @@ const formSchema = z.object({
|
||||
|
||||
interface ReservationFormProps {
|
||||
halls: { id: string, name: string }[]
|
||||
customers: { id: string, full_name: string }[]
|
||||
customers: { id: string, full_name: string, phone?: string | null }[]
|
||||
packages: { id: string, name: string, price: number }[]
|
||||
}
|
||||
|
||||
export function ReservationForm({ halls, customers, packages }: ReservationFormProps) {
|
||||
const [loading, setLoading] = useState(false)
|
||||
const [error, setError] = useState<string | null>(null)
|
||||
const [openCustomer, setOpenCustomer] = useState(false)
|
||||
|
||||
const form = useForm<z.infer<typeof formSchema>>({
|
||||
resolver: zodResolver(formSchema),
|
||||
@@ -123,20 +139,63 @@ export function ReservationForm({ halls, customers, packages }: ReservationFormP
|
||||
control={form.control}
|
||||
name="customer_id"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormItem className="flex flex-col">
|
||||
<FormLabel>Müşteri</FormLabel>
|
||||
<Select onValueChange={field.onChange} defaultValue={field.value}>
|
||||
<FormControl>
|
||||
<SelectTrigger>
|
||||
<SelectValue placeholder="Müşteri Seçin" />
|
||||
</SelectTrigger>
|
||||
</FormControl>
|
||||
<SelectContent>
|
||||
{customers.map(c => (
|
||||
<SelectItem key={c.id} value={c.id}>{c.full_name}</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
<Popover open={openCustomer} onOpenChange={setOpenCustomer}>
|
||||
<PopoverTrigger asChild>
|
||||
<FormControl>
|
||||
<Button
|
||||
variant="outline"
|
||||
role="combobox"
|
||||
aria-expanded={openCustomer}
|
||||
className={cn(
|
||||
"w-full justify-between",
|
||||
!field.value && "text-muted-foreground"
|
||||
)}
|
||||
>
|
||||
{field.value
|
||||
? customers.find((customer) => customer.id === field.value)?.full_name
|
||||
: "Müşteri Seçin"}
|
||||
<ChevronsUpDown className="ml-2 h-4 w-4 shrink-0 opacity-50" />
|
||||
</Button>
|
||||
</FormControl>
|
||||
</PopoverTrigger>
|
||||
<PopoverContent className="w-[300px] p-0">
|
||||
<Command>
|
||||
<CommandInput placeholder="Müşteri ara (İsim veya Telefon)..." />
|
||||
<CommandList>
|
||||
<CommandEmpty>Müşteri bulunamadı.</CommandEmpty>
|
||||
<CommandGroup>
|
||||
{customers.map((customer) => (
|
||||
<CommandItem
|
||||
value={`${customer.full_name} ${customer.phone || ''}`}
|
||||
key={customer.id}
|
||||
onSelect={() => {
|
||||
form.setValue("customer_id", customer.id)
|
||||
setOpenCustomer(false)
|
||||
}}
|
||||
>
|
||||
<Check
|
||||
className={cn(
|
||||
"mr-2 h-4 w-4",
|
||||
customer.id === field.value
|
||||
? "opacity-100"
|
||||
: "opacity-0"
|
||||
)}
|
||||
/>
|
||||
<div className="flex flex-col">
|
||||
<span>{customer.full_name}</span>
|
||||
{customer.phone && (
|
||||
<span className="text-xs text-muted-foreground">{customer.phone}</span>
|
||||
)}
|
||||
</div>
|
||||
</CommandItem>
|
||||
))}
|
||||
</CommandGroup>
|
||||
</CommandList>
|
||||
</Command>
|
||||
</PopoverContent>
|
||||
</Popover>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
|
||||
Reference in New Issue
Block a user