Streamline the purchasing process with Tailwind CSS checkout form sections. These layouts feature organized fields, clear labels, and responsive design to ensure smooth and user-friendly transactions. Perfect for online stores and marketplaces aiming for modern, secure, and conversion-optimized checkout experiences.
"use client";
import { useState } from "react";
import { Card, CardContent, CardFooter } from "@/components/ui/card";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Button } from "@/components/ui/button";
import { Checkbox } from "@/components/ui/checkbox";
import { Check, Gift } from "lucide-react";
import { Separator } from "@/components/ui/separator";
export default function Page() {
const [selectedPayment, setSelectedPayment] = useState("card");
const [formData, setFormData] = useState({
cardName: "John Cena",
cardNumber: "1234 5678 9012 3456",
expiryDate: "09/27",
cvc: "123",
agreeTerms: true
});
const paymentMethods = [
{
id: "card",
name: "Credit/Debit Card",
logos: ["Visa", "Mastercard"],
component: "card"
},
{
id: "paypal",
name: "Paypal",
logos: ["PayPal"],
component: "external"
},
{
id: "bank-transfer",
name: "Bank Transfer",
logos: ["GoPay"],
component: "external"
}
];
const handleInputChange = (field: string, value: string) => {
setFormData((prev) => ({ ...prev, [field]: value }));
};
return (
<section className="py-10 lg:py-20">
<div className="container mx-auto px-4">
<div className="grid grid-cols-1 gap-8 lg:grid-cols-2">
{/* Payment Method Section */}
<div className="space-y-6">
<h2 className="font-semibold">Payment Method</h2>
<div className="space-y-4">
{paymentMethods.map((method) => (
<Card
key={method.id}
className={`cursor-pointer shadow-none transition-all duration-200 ${
selectedPayment === method.id
? "ring-primary ring"
: "hover:border-muted-foreground/20"
}`}
onClick={() => setSelectedPayment(method.id)}>
<CardContent>
<div className="flex items-center justify-between">
<div className="flex items-center space-x-3">
<div
className={`flex h-4 w-4 items-center justify-center rounded-full border-2 ${
selectedPayment === method.id
? "border-primary bg-primary"
: "border-muted-foreground"
}`}>
{selectedPayment === method.id && (
<div className="bg-primary-foreground h-2 w-2 rounded-full"></div>
)}
</div>
<span className="font-medium">{method.name}</span>
</div>
<div className="flex items-center space-x-2">
{method.logos.map((logo) => (
<div
key={logo}
className="bg-muted text-muted-foreground rounded px-2 py-1 text-xs font-semibold">
{logo}
</div>
))}
</div>
</div>
{/* Card Form */}
{selectedPayment === "card" && method.id === "card" && (
<div className="mt-6 space-y-4">
<div>
<Label htmlFor="cardName" className="text-sm font-medium">
Name on Card
</Label>
<Input
id="cardName"
value={formData.cardName}
onChange={(e) => handleInputChange("cardName", e.target.value)}
className="mt-1"
placeholder="John Cena"
/>
</div>
<div>
<Label htmlFor="cardNumber" className="text-sm font-medium">
Card Number
</Label>
<Input
id="cardNumber"
value={formData.cardNumber}
onChange={(e) => handleInputChange("cardNumber", e.target.value)}
className="mt-1"
placeholder="1234 5678 9012 3456"
/>
</div>
<div className="grid grid-cols-2 gap-4">
<div>
<Label htmlFor="expiryDate" className="text-sm font-medium">
Expiry Date
</Label>
<Input
id="expiryDate"
value={formData.expiryDate}
onChange={(e) => handleInputChange("expiryDate", e.target.value)}
className="mt-1"
placeholder="09/27"
/>
</div>
<div>
<Label htmlFor="cvc" className="text-sm font-medium">
CVC
</Label>
<Input
id="cvc"
value={formData.cvc}
onChange={(e) => handleInputChange("cvc", e.target.value)}
className="ring-primary/20 border-primary/30 mt-1 ring-2"
placeholder="123"
/>
</div>
</div>
</div>
)}
</CardContent>
</Card>
))}
</div>
</div>
{/* Order Details Section */}
<div className="space-y-4">
<h2 className="font-semibold">Order Details</h2>
{/* Course Card */}
<Card className="bg-muted/50 border-0 shadow-none">
<CardContent className="space-y-4">
<div className="flex gap-4">
<img
src="/images/products/list1.png"
alt="Mastering Illustration Course"
className="aspect-square w-20 rounded-md object-cover"
/>
<div className="flex-1 space-y-2">
<div>
<h3 className="font-semibold">Mastering Illustration</h3>
<p className="text-muted-foreground text-xs">25 Lessons • 72 Hours</p>
</div>
<p className="mt-1">$300</p>
</div>
</div>
<div className="flex gap-4">
<img
src="/images/products/list2.png"
alt="Mastering Illustration Course"
className="aspect-square w-20 rounded-md object-cover"
/>
<div className="flex-1 space-y-2">
<div>
<h3 className="font-semibold">Mastering Illustration</h3>
<p className="text-muted-foreground text-xs">25 Lessons • 72 Hours</p>
</div>
<p className="mt-1">$300</p>
</div>
</div>
</CardContent>
</Card>
{/* Discount Section */}
<Card className="bg-muted/50 border-0 shadow-none">
<CardContent>
<div className="flex items-center justify-between">
<div className="flex items-center space-x-2">
<Gift className="text-muted-foreground h-5 w-5" />
<span className="font-medium">GWENCHANA</span>
</div>
<Button variant="secondary">Discount Code</Button>
</div>
<p className="text-primary mt-2 text-sm">Yeay, you got $10 discount!</p>
</CardContent>
</Card>
{/* Price Breakdown */}
<Card className="bg-muted/50 border-0 shadow-none">
<CardContent className="space-y-3 text-sm">
<div className="flex items-center justify-between">
<span className="">Price</span>
<span className="">$300</span>
</div>
<div className="flex items-center justify-between">
<span className="">Discount</span>
<span className="text-destructive">-$10</span>
</div>
<div className="flex items-center justify-between">
<span className="">Tax</span>
<span className="text-green-600">+$1</span>
</div>
<Separator />
<div className="flex items-center justify-between">
<span className="font-semibold">Total</span>
<span className="font-semibold">$289</span>
</div>
</CardContent>
</Card>
<div className="space-y-4">
<div className="flex items-start space-x-2">
<Checkbox
id="terms"
checked={formData.agreeTerms}
onCheckedChange={(checked) =>
setFormData((prev) => ({ ...prev, agreeTerms: checked === true }))
}
className="mt-1"
/>
<Label htmlFor="terms" className="text-sm leading-5">
By clicking this you are agree to our
</Label>
</div>
<Button size="lg" className="w-full" disabled={!formData.agreeTerms}>
Checkout Now
</Button>
</div>
</div>
</div>
</div>
</section>
);
}
npx shadcn@latest add @bundui/checkout-forms-01import { CheckoutForms01 } from "@/components/checkout-forms-01"<CheckoutForms01 />