{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "checkout",
  "type": "registry:ui",
  "title": "Checkout Dialog",
  "description": "A responsive checkout form dialog with payment inputs and plan selection - drawer on mobile, modal on desktop.",
  "dependencies": [
    "lucide-react",
    "react-payment-inputs"
  ],
  "registryDependencies": [
    "badge",
    "button",
    "input",
    "label",
    "radio-group",
    "https://revola.sameerjs.com/r/revola.json"
  ],
  "files": [
    {
      "path": "registry/revola/examples/origin-ui/forms/payment/checkout.tsx",
      "content": "\"use client\";\n\nimport { useEffect, useId, useRef, useState } from \"react\";\nimport { usePaymentInputs } from \"react-payment-inputs\";\nimport images, { type CardImages } from \"react-payment-inputs/images\";\n\nimport { CreditCardIcon, StoreIcon } from \"lucide-react\";\n\nimport { Badge } from \"@/components/ui/badge\";\nimport { Button } from \"@/components/ui/button\";\nimport { Input } from \"@/components/ui/input\";\nimport { Label } from \"@/components/ui/label\";\nimport { RadioGroup, RadioGroupItem } from \"@/components/ui/radio-group\";\nimport {\n  ResponsiveDialog,\n  ResponsiveDialogContent,\n  ResponsiveDialogDescription,\n  ResponsiveDialogHeader,\n  ResponsiveDialogTitle,\n  ResponsiveDialogTrigger,\n} from \"@/components/ui/revola\";\n\nexport default function CheckoutDialog() {\n  const id = useId();\n  const { meta, getCardNumberProps, getExpiryDateProps, getCVCProps, getCardImageProps } = usePaymentInputs();\n  const couponInputRef = useRef<HTMLInputElement>(null);\n  const [showCouponInput, setShowCouponInput] = useState(false);\n  const [couponCode, setCouponCode] = useState(\"\");\n\n  // Auto-focus the coupon input when it's shown\n  useEffect(() => {\n    if (showCouponInput && couponInputRef.current) {\n      couponInputRef.current.focus();\n    }\n  }, [showCouponInput]);\n\n  return (\n    <ResponsiveDialog>\n      <ResponsiveDialogTrigger asChild>\n        <Button variant=\"outline\" className=\"h-12 rounded-full px-6 capitalize\">\n          Checkout\n        </Button>\n      </ResponsiveDialogTrigger>\n      <ResponsiveDialogContent className=\"sm:max-w-[400px]\">\n        <div className=\"space-y-4 overflow-y-auto p-6 max-sm:pt-4\">\n          <div className=\"mb-2 flex flex-col gap-2\">\n            <div className=\"flex size-11 shrink-0 items-center justify-center rounded-full border\" aria-hidden=\"true\">\n              <StoreIcon className=\"opacity-80\" size={16} />\n            </div>\n            <ResponsiveDialogHeader className=\"text-left\">\n              <ResponsiveDialogTitle>Confirm and pay</ResponsiveDialogTitle>\n              <ResponsiveDialogDescription>Pay securely and cancel any time.</ResponsiveDialogDescription>\n            </ResponsiveDialogHeader>\n          </div>\n\n          <form className=\"space-y-5\">\n            <div className=\"space-y-4\">\n              <RadioGroup className=\"grid-cols-2\" defaultValue=\"yearly\">\n                {/* Monthly */}\n                <label className=\"shadow-xs relative flex cursor-pointer flex-col gap-1 rounded-md border border-input px-4 py-3 outline-none transition-[color,box-shadow] has-[:focus-visible]:border-ring has-[[data-state=checked]]:border-primary/50 has-[:focus-visible]:ring-[3px] has-[:focus-visible]:ring-ring/50\">\n                  <RadioGroupItem id=\"radio-monthly\" value=\"monthly\" className=\"sr-only after:absolute after:inset-0\" />\n                  <p className=\"text-sm font-medium text-foreground\">Monthly</p>\n                  <p className=\"text-sm text-muted-foreground\">$32/month</p>\n                </label>\n                {/* Yearly */}\n                <label className=\"shadow-xs relative flex cursor-pointer flex-col gap-1 rounded-md border border-input px-4 py-3 outline-none transition-[color,box-shadow] has-[:focus-visible]:border-ring has-[[data-state=checked]]:border-primary/50 has-[:focus-visible]:ring-[3px] has-[:focus-visible]:ring-ring/50\">\n                  <RadioGroupItem id=\"radio-yearly\" value=\"yearly\" className=\"sr-only after:absolute after:inset-0\" />\n                  <div className=\"inline-flex items-start justify-between gap-2\">\n                    <p className=\"text-sm font-medium text-foreground\">Yearly</p>\n                    <Badge>Popular</Badge>\n                  </div>\n                  <p className=\"text-sm text-muted-foreground\">$320/year</p>\n                </label>\n              </RadioGroup>\n              <div className=\"space-y-2\">\n                <Label htmlFor={`name-${id}`}>Name on card</Label>\n                <Input id={`name-${id}`} type=\"text\" required placeholder=\"John Doe\" />\n              </div>\n              <div className=\"space-y-2\">\n                <legend className=\"text-sm font-medium text-foreground\">Card Details</legend>\n                <div className=\"shadow-xs rounded-md\">\n                  <div className=\"relative focus-within:z-10\">\n                    <Input\n                      className=\"peer rounded-b-none pe-9 shadow-none [direction:inherit]\"\n                      {...getCardNumberProps()}\n                      placeholder=\"4242 4242 4242 4242\"\n                    />\n                    <div className=\"pointer-events-none absolute inset-y-0 end-0 flex items-center justify-center pe-3 text-muted-foreground/80 peer-disabled:opacity-50\">\n                      {meta.cardType ? (\n                        <svg\n                          className=\"overflow-hidden rounded-sm\"\n                          // Todo: remove this type case at build time in rehype-component.ts\n                          {...getCardImageProps({\n                            images: images as unknown as CardImages,\n                          })}\n                          width={20}\n                        />\n                      ) : (\n                        <CreditCardIcon size={16} aria-hidden=\"true\" />\n                      )}\n                    </div>\n                  </div>\n                  <div className=\"-mt-px flex\">\n                    <div className=\"min-w-0 flex-1 focus-within:z-10\">\n                      <Input\n                        className=\"rounded-e-none rounded-t-none shadow-none [direction:inherit]\"\n                        {...getExpiryDateProps()}\n                        placeholder=\"06/28\"\n                      />\n                    </div>\n                    <div className=\"-ms-px min-w-0 flex-1 focus-within:z-10\">\n                      <Input\n                        className=\"rounded-s-none rounded-t-none shadow-none [direction:inherit]\"\n                        {...getCVCProps()}\n                        placeholder=\"123\"\n                      />\n                    </div>\n                  </div>\n                </div>\n              </div>\n              {!showCouponInput ? (\n                <button\n                  type=\"button\"\n                  onClick={() => setShowCouponInput(true)}\n                  className=\"text-sm underline hover:no-underline\"\n                >\n                  + Add coupon\n                </button>\n              ) : (\n                <div className=\"space-y-2\">\n                  <Label htmlFor={`coupon-${id}`}>Coupon code</Label>\n                  <Input\n                    id={`coupon-${id}`}\n                    ref={couponInputRef}\n                    placeholder=\"MONSOON25\"\n                    value={couponCode}\n                    onChange={(e) => setCouponCode(e.target.value)}\n                  />\n                </div>\n              )}\n            </div>\n            <Button type=\"button\" className=\"w-full\">\n              Subscribe\n            </Button>\n          </form>\n          <p className=\"text-center text-xs text-muted-foreground\">Payments are non-refundable. Cancel anytime.</p>\n        </div>\n      </ResponsiveDialogContent>\n    </ResponsiveDialog>\n  );\n}\n",
      "type": "registry:ui"
    }
  ]
}