"use client"; import { zodResolver } from "@hookform/resolvers/zod"; import { useTransition } from "react"; import { useForm } from "react-hook-form"; import { z } from "zod"; import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage, } from "@/components/ui/form"; import { Button } from "@/components/ui/button"; import { Checkbox } from "@/components/ui/checkbox"; import { Input } from "@/components/ui/input"; import { SelectItem } from "@/components/ui/select"; import { SelectContent, SelectValue } from "@/components/ui/select"; import { SelectTrigger } from "@/components/ui/select"; import { Select } from "@/components/ui/select"; import { Textarea } from "@/components/ui/textarea"; import { cn } from "@/lib/utils"; import { toast } from "sonner"; export const types = [ { label: "Report a bug", value: "bug" as const, }, { label: "Book a demo", value: "demo" as const, }, { label: "Suggest a feature", value: "feature" as const, }, { label: "Report a security issue", value: "security" as const, }, { label: "Something else", value: "question" as const, }, ]; export const schema = z.object({ name: z.string().min(1, { error: "Name is required", }), type: z.enum(["bug", "demo", "feature", "security", "question"]), email: z.email({ error: "Invalid email address", }), message: z.string().min(1, { error: "Message is required", }), blocker: z.boolean(), }); export type FormValues = z.infer; interface ContactFormProps { defaultValues?: Partial; onSubmit: (data: FormValues) => Promise; className?: string; } export function ContactForm({ defaultValues, onSubmit, className, }: ContactFormProps) { const form = useForm({ resolver: zodResolver(schema), defaultValues: { name: defaultValues?.name ?? "", email: defaultValues?.email ?? "", type: defaultValues?.type ?? undefined, message: defaultValues?.message ?? "", blocker: defaultValues?.blocker ?? false, }, }); const [isPending, startTransition] = useTransition(); const watchType = form.watch("type"); async function submitAction(values: FormValues) { if (isPending) return; startTransition(async () => { try { const promise = onSubmit(values); toast.promise(promise, { loading: "Sending message...", success: "Message sent. We'll get back to you soon.", error: "Failed to send message. Please try again.", }); await promise; } catch (error) { console.error(error); } }); } return (
( Name )} /> ( Email )} /> ( Type )} /> {watchType ? ( ( Message