Booking Card
NewAn appointment picker for barbers, clinics and repair shops. A scrolling day strip, slots that animate in per day, and a booked summary with Add to calendar.
motionlucide-reactutilsavatarbuttonbutton-groupcardemptyitemseparatorskeletonspinner@soultel/use-reduced-motion-safe
Installation
$ pnpm dlx shadcn@latest add @soultel/booking-cardNo namespace set up? npx shadcn@latest add https://asafefe.dev/r/booking-card.json works too.
Manual installation
- 1. Install the dependencies.
terminal1 lines npm install motion lucide-react - 2. Copy the source from the Code tab into components/booking-card.tsx.
Usage
import { BookingCard } from "@/components/booking-card"
export function BookACut() {
return (
<BookingCard
service={{ name: "Haircut and beard trim", duration: 45, price: 38, provider: "Sam Ortiz", location: "Fade Bros, Main St" }}
onConfirm={async (booking) => {
await fetch("/api/bookings", { method: "POST", body: JSON.stringify(booking) })
}}
/>
)
}Props
| Prop | Type | Default | Description |
|---|---|---|---|
| service | BookingService | - | name, duration in minutes, and optional price, provider and location. |
| days | BookingDay[] | - | Explicit availability: { date: "YYYY-MM-DD", slots: { time: "HH:mm", available }[] }[]. An empty slots array means closed. |
| getSlots | (date: Date) => BookingSlot[] | - | Generates slots when days is not passed. Defaults to 9 to 5 with a lunch break, stepped by duration, closed Sundays. |
| startDate | Date | string | today | First generated day. |
| dayCount | number | 14 | Number of generated days. |
| defaultValue | { date: string; time?: string } | - | Initial selection. |
| onConfirm | (booking: Booking) => void | Promise<void> | - | Called on confirm with date, time, start, end and service. A promise shows a pending state; a rejection returns to the picker. |
| onAddToCalendar | (booking: Booking) => void | - | Replaces the default .ics download. |
| locale | string | "en-US" | Used for day names and times. |
| hour12 | boolean | true | 12 or 24 hour times. |
| currency | string | "$" | Symbol shown before the price. |
