src/registry/default/templates/ecommerce-checkout-form.tsx
"use client";
import { useForm, Controller } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import * as z from "zod";
import { Button } from "@/components/ui/button";
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { toast } from "sonner";
import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group";
const formSchema = z.object({
fullName: z.string().min(2, "Full name is required"),
email: z.string().email("Invalid email"),
address: z.string().min(5, "Address is required"),
city: z.string().min(2, "City is required"),
zipCode: z.string().min(4, "ZIP code is required"),
paymentMethod: z.enum(["credit_card", "paypal", "apple_pay"]),
});
type FormValues = z.infer<typeof formSchema>;
export function EcommerceCheckoutForm() {
const form = useForm<FormValues>({
resolver: zodResolver(formSchema),
defaultValues: {
fullName: "",
email: "",
address: "",
city: "",
zipCode: "",
paymentMethod: "credit_card",
},
});
const onSubmit = async (data: FormValues) => {
console.log("Form submitted:", data);
toast.success("Form submitted successfully!");
};
return (
<Card className="w-full max-w-md mx-auto">
<CardHeader>
<CardTitle>Checkout</CardTitle>
<CardDescription>Checkout form with shipping and payment details</CardDescription>
</CardHeader>
<CardContent>
<form onSubmit={form.handleSubmit(onSubmit)} className="space-y-4">
<div className="space-y-2">
<Label htmlFor="fullName">Full Name</Label>
<Input
id="fullName"
type="text"
placeholder="John Doe"
{...form.register("fullName")}
/>
{form.formState.errors.fullName && (
<p className="text-sm text-destructive">{form.formState.errors.fullName.message}</p>
)}
</div>
<div className="space-y-2">
<Label htmlFor="email">Email Address</Label>
<Input
id="email"
type="email"
placeholder="john@example.com"
{...form.register("email")}
/>
{form.formState.errors.email && (
<p className="text-sm text-destructive">{form.formState.errors.email.message}</p>
)}
</div>
<div className="space-y-2">
<Label htmlFor="address">Shipping Address</Label>
<Input
id="address"
type="text"
placeholder="123 Main St"
{...form.register("address")}
/>
{form.formState.errors.address && (
<p className="text-sm text-destructive">{form.formState.errors.address.message}</p>
)}
</div>
<div className="space-y-2">
<Label htmlFor="city">City</Label>
<Input
id="city"
type="text"
placeholder="New York"
{...form.register("city")}
/>
{form.formState.errors.city && (
<p className="text-sm text-destructive">{form.formState.errors.city.message}</p>
)}
</div>
<div className="space-y-2">
<Label htmlFor="zipCode">ZIP Code</Label>
<Input
id="zipCode"
type="text"
placeholder="10001"
{...form.register("zipCode")}
/>
{form.formState.errors.zipCode && (
<p className="text-sm text-destructive">{form.formState.errors.zipCode.message}</p>
)}
</div>
<div className="space-y-2">
<Label>Payment Method</Label>
<Controller
control={form.control}
name="paymentMethod"
render={({ field }) => (
<RadioGroup
onValueChange={field.onChange}
defaultValue={field.value}
className="flex flex-col space-y-1"
>
<div className="flex items-center space-x-2">
<RadioGroupItem value="credit_card" id="paymentMethod-credit_card" />
<Label htmlFor="paymentMethod-credit_card">Credit Card</Label>
</div>
<div className="flex items-center space-x-2">
<RadioGroupItem value="paypal" id="paymentMethod-paypal" />
<Label htmlFor="paymentMethod-paypal">PayPal</Label>
</div>
<div className="flex items-center space-x-2">
<RadioGroupItem value="apple_pay" id="paymentMethod-apple_pay" />
<Label htmlFor="paymentMethod-apple_pay">Apple Pay</Label>
</div>
</RadioGroup>
)}
/>
{form.formState.errors.paymentMethod && (
<p className="text-sm text-destructive">{form.formState.errors.paymentMethod.message}</p>
)}
</div>
<Button type="submit" className="w-full">Submit</Button>
</form>
</CardContent>
</Card>
);
}






























