{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "booking5",
  "title": "Provider Picker",
  "description": "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.",
  "dependencies": [
    "clsx",
    "tailwind-merge",
    "lucide-react"
  ],
  "registryDependencies": [
    "badge",
    "button",
    "avatar"
  ],
  "files": [
    {
      "path": "registry/booking5/booking5.tsx",
      "content": "\"use client\";\n\nimport { Avatar, AvatarFallback, AvatarImage } from \"@/components/ui/avatar\";\nimport { Award, Check, ChevronRight, Clock, Shuffle, Star, User } from \"lucide-react\";\n\nimport { Badge } from \"@/components/ui/badge\";\nimport { Button } from \"@/components/ui/button\";\nimport { cn } from \"@/lib/utils\";\nimport { useState } from \"react\";\n\ninterface ProviderInfo {\n  name: string;\n  specialty: string;\n  avatar?: string;\n  rating: number;\n  reviews: number;\n  experience: string;\n  availability: string;\n  availableToday?: boolean;\n}\n\ninterface Booking5Labels {\n  anyProviderTitle?: string;\n  anyProviderDescription?: string;\n  availableTodayBadge?: string;\n  noSelection?: string;\n  anyProviderSummary?: string;\n  nextButton?: string;\n}\n\ninterface Booking5Props {\n  badge?: {\n    label: string;\n    variant?: \"default\" | \"secondary\" | \"outline\";\n  };\n  heading?: string;\n  description?: string;\n  providers?: ProviderInfo[];\n  allowAny?: boolean;\n  labels?: Booking5Labels;\n  className?: string;\n}\n\nexport const booking5Demo: Booking5Props = {\n  badge: { label: \"Step 2 of 3\", variant: \"secondary\" },\n  heading: \"Choose your <strong>specialist</strong>\",\n  description: \"Pick a provider for your Deep Tissue Massage appointment.\",\n  allowAny: true,\n  providers: [\n    {\n      name: \"Dr. Emily Carter\",\n      specialty: \"Sports & Deep Tissue\",\n      avatar: \"https://images.unsplash.com/photo-1494790108377-be9c29b29330?w=100&h=100&fit=crop\",\n      rating: 4.9,\n      reviews: 127,\n      experience: \"8 years\",\n      availability: \"Next: Today, 2:00 PM\",\n      availableToday: true,\n    },\n    {\n      name: \"Marcus Chen\",\n      specialty: \"Therapeutic & Recovery\",\n      avatar: \"https://images.unsplash.com/photo-1507003211169-0a1dd7228f2d?w=100&h=100&fit=crop\",\n      rating: 4.8,\n      reviews: 94,\n      experience: \"12 years\",\n      availability: \"Next: Tomorrow, 10:00 AM\",\n      availableToday: false,\n    },\n    {\n      name: \"Sofia Andersson\",\n      specialty: \"Relaxation & Prenatal\",\n      avatar: \"https://images.unsplash.com/photo-1438761681033-6461ffad8d80?w=100&h=100&fit=crop\",\n      rating: 5.0,\n      reviews: 203,\n      experience: \"15 years\",\n      availability: \"Next: Today, 4:30 PM\",\n      availableToday: true,\n    },\n    {\n      name: \"James Okafor\",\n      specialty: \"Deep Tissue & Myofascial\",\n      avatar: \"https://images.unsplash.com/photo-1472099645785-5658abf4ff4e?w=100&h=100&fit=crop\",\n      rating: 4.7,\n      reviews: 68,\n      experience: \"5 years\",\n      availability: \"Next: April 18, 9:00 AM\",\n      availableToday: false,\n    },\n  ],\n  labels: {\n    anyProviderTitle: \"Any Available Provider\",\n    anyProviderDescription: \"We'll match you with the next available specialist\",\n    availableTodayBadge: \"Today\",\n    noSelection: \"No provider selected\",\n    anyProviderSummary: \"Any Provider\",\n    nextButton: \"Next Step\",\n  },\n};\n\nexport function Booking5({\n  badge,\n  heading,\n  description,\n  providers = [],\n  allowAny = false,\n  labels = {},\n  className,\n}: Booking5Props) {\n  const {\n    anyProviderTitle,\n    anyProviderDescription,\n    availableTodayBadge,\n    noSelection,\n    anyProviderSummary,\n    nextButton,\n  } = labels;\n\n  const [selected, setSelected] = useState<string | null>(null);\n\n  const selectedProvider =\n    selected && selected !== \"any\" ? providers.find((p) => p.name === selected) : null;\n\n  const handleConfirm = () => {\n    if (!selected) return;\n    if (selected === \"any\") {\n      console.log(\"Selected provider: any available\");\n    } else if (selectedProvider) {\n      console.log(\"Selected provider:\", selectedProvider);\n    }\n  };\n\n  return (\n    <section className={cn(\"py-16 md:py-24 w-full\", className)}>\n      <div className=\"mx-auto max-w-lg px-4 md:px-6\">\n        {(badge || heading || description) && (\n          <div className=\"mx-auto mb-12 max-w-3xl text-center\">\n            {badge && (\n              <div className=\"mb-4 flex justify-center\">\n                <Badge variant={badge.variant ?? \"default\"}>{badge.label}</Badge>\n              </div>\n            )}\n            {heading && (\n              <h2\n                className=\"text-2xl font-semibold md:text-4xl [&>strong]:font-bold [&>strong]:text-primary\"\n                dangerouslySetInnerHTML={{ __html: heading }}\n              />\n            )}\n            {description && (\n              <p className=\"mt-4 text-base text-muted-foreground md:text-lg\">{description}</p>\n            )}\n          </div>\n        )}\n\n        <div className=\"group/booking5 overflow-hidden rounded-md border bg-card shadow-sm\">\n          <div className=\"divide-y\">\n            {allowAny && (\n              <button\n                type=\"button\"\n                onClick={() => setSelected(\"any\")}\n                className={cn(\n                  \"flex w-full cursor-pointer items-center gap-4 px-5 py-4 text-left transition-all\",\n                  selected === \"any\" ? \"bg-primary/5\" : \"hover:bg-muted/50\"\n                )}\n              >\n                <div\n                  className={cn(\n                    \"flex size-12 shrink-0 items-center justify-center rounded-full\",\n                    selected === \"any\"\n                      ? \"bg-primary text-primary-foreground\"\n                      : \"bg-muted text-muted-foreground\"\n                  )}\n                >\n                  <Shuffle className=\"size-5\" />\n                </div>\n                <div className=\"flex-1\">\n                  <h3 className=\"text-base font-semibold\">{anyProviderTitle}</h3>\n                  <p className=\"text-sm text-muted-foreground\">{anyProviderDescription}</p>\n                </div>\n                <div className=\"shrink-0\">\n                  {selected === \"any\" ? (\n                    <div className=\"flex size-6 items-center justify-center rounded-full bg-primary text-primary-foreground\">\n                      <Check className=\"size-4\" />\n                    </div>\n                  ) : (\n                    <div className=\"size-6 rounded-full border-2 border-muted-foreground/20\" />\n                  )}\n                </div>\n              </button>\n            )}\n\n            {providers.map((provider, index) => {\n              const isSelected = selected === provider.name;\n\n              return (\n                <button\n                  key={index}\n                  type=\"button\"\n                  onClick={() => setSelected(provider.name)}\n                  className={cn(\n                    \"flex w-full cursor-pointer items-start gap-4 px-5 py-4 text-left transition-all\",\n                    isSelected ? \"bg-primary/5\" : \"hover:bg-muted/50\"\n                  )}\n                >\n                  <div className=\"relative shrink-0\">\n                    <Avatar\n                      className={cn(\n                        \"size-14\",\n                        isSelected && \"ring-2 ring-primary ring-offset-2 ring-offset-background\"\n                      )}\n                    >\n                      {provider.avatar && (\n                        <AvatarImage\n                          src={provider.avatar}\n                          alt={provider.name}\n                          className=\"object-cover\"\n                        />\n                      )}\n                      <AvatarFallback>\n                        <User className=\"size-5\" />\n                      </AvatarFallback>\n                    </Avatar>\n                    {provider.availableToday && (\n                      <span className=\"absolute -bottom-0.5 -right-0.5 flex size-4 items-center justify-center rounded-full border-2 border-background bg-emerald-500\">\n                        <span className=\"size-1.5 rounded-full bg-white\" />\n                      </span>\n                    )}\n                  </div>\n\n                  <div className=\"min-w-0 flex-1\">\n                    <div className=\"flex items-center gap-2\">\n                      <h3 className=\"text-base font-semibold\">{provider.name}</h3>\n                      {provider.availableToday && availableTodayBadge && (\n                        <Badge\n                          variant=\"secondary\"\n                          className=\"bg-emerald-500/10 text-xs text-emerald-500\"\n                        >\n                          {availableTodayBadge}\n                        </Badge>\n                      )}\n                    </div>\n                    <p className=\"text-sm text-muted-foreground\">{provider.specialty}</p>\n\n                    <div className=\"mt-2 flex items-center gap-3 text-sm\">\n                      <span className=\"flex items-center gap-1 font-medium\">\n                        <Star className=\"size-4 fill-yellow-400 text-yellow-400\" />\n                        {provider.rating}\n                        <span className=\"text-muted-foreground\">({provider.reviews})</span>\n                      </span>\n                      <span className=\"flex items-center gap-1 text-muted-foreground\">\n                        <Award className=\"size-4\" />\n                        {provider.experience}\n                      </span>\n                    </div>\n\n                    <div className=\"mt-1.5 flex items-center gap-1.5 text-sm text-muted-foreground\">\n                      <Clock className=\"size-4\" />\n                      {provider.availability}\n                    </div>\n                  </div>\n\n                  <div className=\"mt-2 shrink-0\">\n                    {isSelected ? (\n                      <div className=\"flex size-6 items-center justify-center rounded-full bg-primary text-primary-foreground\">\n                        <Check className=\"size-4\" />\n                      </div>\n                    ) : (\n                      <div className=\"size-6 rounded-full border-2 border-muted-foreground/20\" />\n                    )}\n                  </div>\n                </button>\n              );\n            })}\n          </div>\n\n          <div className=\"flex flex-wrap items-center justify-between gap-3 border-t bg-muted/30 px-5 py-4\">\n            <div className=\"text-base\">\n              {selected ? (\n                <span className=\"font-medium\">\n                  {selected === \"any\" ? anyProviderSummary : selected}\n                </span>\n              ) : (\n                <span className=\"text-muted-foreground\">{noSelection}</span>\n              )}\n            </div>\n            <Button disabled={!selected} className=\"cursor-pointer\" onClick={handleConfirm}>\n              {nextButton}\n              <ChevronRight className=\"size-5\" />\n            </Button>\n          </div>\n        </div>\n      </div>\n    </section>\n  );\n}\n",
      "type": "registry:component",
      "target": "components/beste/block/booking5.tsx"
    }
  ],
  "type": "registry:block"
}