Staff/provider selection cards with avatar, name, specialty, star rating, review count, availability badge, experience years, and selected state. Grid layout with "Any Provider" option.
Step-two staff picker for a booking flow: provider cards show an avatar with a same-day availability dot, a star rating with review count, years of experience, and the next available slot, with an optional "Any Available Provider" row pinned above the list.
Free block
This block is free. No license or account is required: install it with the CLI and use it in unlimited projects.
Radix flavor
npx shadcn add "https://ui.beste.co/r/booking5"Base UI flavor
npx shadcn add "https://ui.beste.co/r-base/booking5"This installs the block to components/beste/block/booking5.tsx, plus the badge, button, and avatar shadcn/ui primitives it uses for the availability badge, footer button, and provider avatars.
The installed file exports booking5Demo alongside the block: the exact props behind the preview above. Spread it to get a working provider picker in one line.
import { Booking5, booking5Demo } from "@/components/beste/block/booking5";
export default function BookingStep2Page() {
return <Booking5 {...booking5Demo} />;
}Then replace the demo with your own props. Written out, a trimmed setup looks like this:
import { Booking5 } from "@/components/beste/block/booking5";
export default function BookingStep2Page() {
return (
<Booking5
badge={{ label: "Step 2 of 3", variant: "secondary" }}
heading="Choose your <strong>specialist</strong>"
description="Pick a provider for your appointment."
allowAny
providers={[
{
name: "Dr. Emily Carter",
specialty: "Sports & Deep Tissue",
rating: 4.9,
reviews: 127,
experience: "8 years",
availability: "Next: Today, 2:00 PM",
availableToday: true,
},
{
name: "Marcus Chen",
specialty: "Therapeutic & Recovery",
rating: 4.8,
reviews: 94,
experience: "12 years",
availability: "Next: Tomorrow, 10:00 AM",
},
]}
labels={{
anyProviderTitle: "Any Available Provider",
anyProviderDescription: "We'll match you with the next available specialist",
availableTodayBadge: "Today",
noSelection: "No provider selected",
anyProviderSummary: "Any Provider",
nextButton: "Next Step",
}}
/>
);
}| Prop | Type | Default | Description |
|---|---|---|---|
badge | { label: string; variant?: "default" | "secondary" | "outline" } | – | Section eyebrow badge |
heading | string | – | Section heading, supports inline <strong> |
description | string | – | Section intro text |
providers | ProviderInfo[] | [] | Provider rows rendered below the optional "Any" row |
allowAny | boolean | false | Shows the "Any Available Provider" row above the list |
labels | Booking5Labels | {} | UI copy: "Any" row text, badge text, empty-state and footer text |
className | string | – | Extra classes for the outer <section> |
type ProviderInfo = {
name: string;
specialty: string;
avatar?: string;
rating: number;
reviews: number;
experience: string;
availability: string;
availableToday?: boolean;
};
type Booking5Labels = {
anyProviderTitle?: string;
anyProviderDescription?: string;
availableTodayBadge?: string;
noSelection?: string;
anyProviderSummary?: string;
nextButton?: string;
};allowAny is true, and always sits first in the list with a shuffle icon in place of an avatar.provider.name (or the literal string "any"), not an index, so provider names must be unique within one instance for selection state to behave correctly.availableToday drives two independent visuals: a small emerald dot on the avatar's corner, and an emerald-tinted "Today" badge next to the name (from labels.availableTodayBadge); both are skipped entirely when the flag is false.onClick only calls console.log with the resolved provider (or "any available"). No network request or navigation happens, real submission logic is left to the integrator.heading supports inline <strong> markup via dangerouslySetInnerHTML, matching the pattern used across the booking blocks in this set.booking4
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.
booking18
Interactive seat selection grid for cinemas, theaters, and events. Row/column layout with an aisle gap, tier-based pricing (standard/premium/VIP), occupied seats, a live selection summary, and a legend. Includes screen indicator at the top.
booking1
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.
booking7
Hotel room selection with room type cards showing images, amenity icons, guest capacity, price per night, check-in/check-out date picker, guest counter, and total price summary.
booking3
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.
booking14
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.