Spa Day Package Builder

Multi-service booking composer. Customers assemble their own wellness day by adding services across categories (massage/facial/body/nails/add-ons), with live package summary, duration totals, animated bundle-discount progress bar, quick-start presets, and remove-from-package controls.

PRO

Booking22: Spa Day Package Builder

A multi-service booking composer that renders a category-tabbed catalog of services (each with an icon, name, description, duration, and price) above a live "Your package" panel, where each pick gets a quantity stepper, a running subtotal and total-duration tally, an animated bundle-discount progress bar that applies a percentage off once a minimum item count is reached, per-line remove controls, and a final book button.

Upgrade to Pro

Pro blocks install through the shadcn CLI with your license key and ship their full source. Docs and live previews stay open to everyone, so you can read every block's details first.

Installation

Swap YOUR_EMAIL and YOUR_KEY for the email and license key on your account. Find your license key on your account page.

Radix flavor

bash
npx shadcn add "https://ui.beste.co/r/booking22?email=YOUR_EMAIL&license_key=YOUR_KEY"

Base UI flavor

bash
npx shadcn add "https://ui.beste.co/r-base/booking22?email=YOUR_EMAIL&license_key=YOUR_KEY"

This installs the block to components/beste/block/booking22.tsx, plus the badge, button, and tabs shadcn/ui primitives it uses for the eyebrow badge, the add/book buttons, and the category filter tabs.

Quick start

The installed file exports booking22Demo alongside the block: the exact props behind the preview above. Spread it to get a working package builder in one line.

tsx
import { Booking22, booking22Demo } from "@/components/beste/block/booking22";

export default function Page() {
  return <Booking22 {...booking22Demo} />;
}

Then replace the demo with your own props. Written out, a trimmed setup looks like this:

tsx
import { Hand, Heart, Sparkles } from "lucide-react";
import { Booking22 } from "@/components/beste/block/booking22";

export default function Page() {
  return (
    <Booking22
      badge={{ label: "Build your day", variant: "secondary" }}
      heading="Design your <strong>spa day</strong>"
      description="Mix and match across categories, bundle three or more and save."
      currency="$"
      categories={[
        { value: "massage", label: "Massage", icon: Hand },
        { value: "facial", label: "Facial", icon: Heart },
      ]}
      services={[
        {
          value: "swedish",
          category: "massage",
          name: "Swedish Massage",
          description: "Gentle full-body massage to release tension",
          duration: 60,
          price: 89,
          icon: Hand,
        },
        {
          value: "aromatherapy",
          category: "facial",
          name: "Aromatherapy",
          description: "Essential oil upgrade for any service",
          duration: 0,
          price: 25,
          icon: Sparkles,
          maxQty: 5,
        },
      ]}
      bundleDiscount={{
        minItems: 3,
        percent: 15,
        progressTemplate: "Add {remaining} more to save {percent}%",
        activeTemplate: "Bundle discount applied · −{percent}%",
      }}
    />
  );
}

Props

PropTypeDefaultDescription
badge{ label: string; variant?: "default" | "secondary" | "outline" }Optional eyebrow badge above the heading
headingstringSection heading, supports inline <strong>
descriptionstringParagraph rendered under the heading
currencystring"$"Symbol prefixed to every price and total
categoriesPackageCategory[][]Tabs that filter the service list
servicesPackageService[][]All bookable services, shown by active category
bundleDiscountBundleDiscountConfigOptional minimum-items discount and progress bar
labelsBooking22Labels{}Overrides for every piece of UI text
classNamestringExtra classes for the outer <section>
ts
type PackageCategory = {
  value: string;
  label: string;
  icon: LucideIcon;
};

type PackageService = {
  value: string;
  category: string;
  name: string;
  description: string;
  duration: number; // minutes; 0 hides the duration line
  price: number;
  icon: LucideIcon;
  maxQty?: number; // caps the stepper; defaults to 10
};

type BundleDiscountConfig = {
  minItems: number;
  percent: number;
  progressTemplate: string; // supports {remaining} and {percent}
  activeTemplate: string; // supports {percent}
};

type Booking22Labels = {
  addButton?: string;
  addedLabel?: string;
  packageHeading?: string;
  emptyPackage?: string;
  emptyHint?: string;
  subtotalLabel?: string;
  discountLabel?: string;
  totalLabel?: string;
  totalDurationLabel?: string;
  bookButton?: string;
  clearButton?: string;
  singleServiceSuffix?: string;
  multipleServicesSuffix?: string;
};

Behavior notes

More Booking blocks

View all Booking
FREE

booking4

Service Selector

Service selection grid with category filter tabs, service cards showing icon, name, description, duration, price, and selected state. Ideal for spa, salon, clinic, and fitness booking flows.

PRO

booking3

Appointment List

Upcoming and past appointments list grouped by date, with service name, provider avatar, time, duration, status badges (confirmed/pending/cancelled), and reschedule/cancel action buttons.

PRO

booking21

Weekly Class Schedule

Gym or studio weekly schedule with day tabs, class list per day (instructor avatar, duration, spots remaining, difficulty), and quick reserve action. Tap a day to see its classes, tap a class to book a spot.

PRO

booking14

Activity Experience Booking

Tours and experiences booking card with hero image overlay, rating, duration, difficulty badge, date picker, traveler counter, language selector, highlights list, and reserve CTA. Perfect for guided tours, classes, and local experiences.

PRO

booking16

Home Cleaning Service Booking

Residential cleaning service booking with service type tabs (standard/deep/move-out), bedroom/bathroom selectors, recurring frequency pills, add-ons checklist, date picker, estimated duration, and price breakdown footer.

PRO

booking1

Date & Time Picker

Split-panel booking interface with interactive monthly calendar on the left and time slot grid on the right. Features today highlight, disabled dates, selected state, morning/afternoon grouping, and booking summary footer.