{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "trial-expiry-card",
  "title": "Trial Expiry Card",
  "description": "A card component that displays trial expiration countdown with progress indicator and feature list",
  "dependencies": ["lucide-react", "motion"],
  "registryDependencies": ["button", "card", "badge", "utils"],
  "files": [
    {
      "path": "src/registry/billingsdk/trial-expiry-card.tsx",
      "content": "\"use client\";\n\nimport { useState, useEffect } from \"react\";\nimport { Button } from \"@/components/ui/button\";\nimport { Badge } from \"@/components/ui/badge\";\nimport {\n  Card,\n  CardContent,\n  CardDescription,\n  CardHeader,\n  CardTitle,\n} from \"@/components/ui/card\";\nimport { cn } from \"@/lib/utils\";\nimport { Check } from \"lucide-react\";\n\nexport interface TrialExpiryCardProps {\n  trialEndDate?: Date | string | number;\n  daysRemaining?: number;\n  onUpgrade?: () => void | Promise<void>;\n  className?: string;\n  title?: string;\n  description?: string;\n  upgradeButtonText?: string;\n  features?: string[];\n}\n\ninterface TimeRemaining {\n  days: number;\n  hours: number;\n  minutes: number;\n  seconds: number;\n}\n\nconst calculateTimeRemaining = (\n  endDate: Date | string | number,\n): TimeRemaining => {\n  try {\n    let end: Date;\n    if (typeof endDate === \"string\") {\n      end = new Date(endDate);\n    } else if (typeof endDate === \"number\") {\n      end = new Date(endDate);\n    } else if (endDate instanceof Date) {\n      end = endDate;\n    } else {\n      // Fallback for any other type\n      return { days: 0, hours: 0, minutes: 0, seconds: 0 };\n    }\n\n    // Validate that we have a valid date\n    if (isNaN(end.getTime())) {\n      return { days: 0, hours: 0, minutes: 0, seconds: 0 };\n    }\n\n    const now = new Date();\n    const diff = end.getTime() - now.getTime();\n\n    if (diff <= 0) {\n      return { days: 0, hours: 0, minutes: 0, seconds: 0 };\n    }\n\n    return {\n      days: Math.floor(diff / (1000 * 60 * 60 * 24)),\n      hours: Math.floor((diff % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60)),\n      minutes: Math.floor((diff % (1000 * 60 * 60)) / (1000 * 60)),\n      seconds: Math.floor((diff % (1000 * 60)) / 1000),\n    };\n  } catch (error) {\n    console.error(\"Error calculating time remaining:\", error);\n    return { days: 0, hours: 0, minutes: 0, seconds: 0 };\n  }\n};\n\nexport function TrialExpiryCard({\n  trialEndDate,\n  daysRemaining: propDaysRemaining,\n  onUpgrade,\n  className,\n  title = \"Trial Period\",\n  description,\n  upgradeButtonText = \"Upgrade Now\",\n  features = [\n    \"Unlimited projects\",\n    \"Priority support\",\n    \"Advanced analytics\",\n    \"Custom integrations\",\n  ],\n}: TrialExpiryCardProps) {\n  const [isLoading, setIsLoading] = useState(false);\n  const [timeRemaining, setTimeRemaining] = useState<TimeRemaining>(() => {\n    if (trialEndDate) {\n      return calculateTimeRemaining(trialEndDate);\n    }\n    return { days: propDaysRemaining || 0, hours: 0, minutes: 0, seconds: 0 };\n  });\n\n  useEffect(() => {\n    if (!trialEndDate) return;\n\n    const interval = setInterval(() => {\n      setTimeRemaining(calculateTimeRemaining(trialEndDate));\n    }, 1000);\n\n    return () => clearInterval(interval);\n  }, [trialEndDate]);\n\n  const daysRemaining = propDaysRemaining ?? timeRemaining.days;\n\n  const handleUpgrade = async () => {\n    if (onUpgrade) {\n      setIsLoading(true);\n      try {\n        await onUpgrade();\n      } finally {\n        setIsLoading(false);\n      }\n    }\n  };\n\n  const getStatusBadge = () => {\n    if (daysRemaining <= 0) return <Badge variant=\"destructive\">Expired</Badge>;\n    if (daysRemaining <= 2)\n      return <Badge variant=\"destructive\">Expiring Soon</Badge>;\n    if (daysRemaining <= 6) return <Badge variant=\"secondary\">Active</Badge>;\n    return <Badge variant=\"default\">Active</Badge>;\n  };\n\n  return (\n    <Card className={cn(\"w-full max-w-md\", className)}>\n      <CardHeader>\n        <div className=\"flex items-center justify-between\">\n          <CardTitle className=\"text-base font-medium\">{title}</CardTitle>\n          {getStatusBadge()}\n        </div>\n        {description && <CardDescription>{description}</CardDescription>}\n      </CardHeader>\n      <CardContent className=\"space-y-6\">\n        {/* Countdown Timer */}\n        {trialEndDate && daysRemaining > 0 && (\n          <div\n            className=\"bg-muted/30 rounded-lg border p-4\"\n            role=\"status\"\n            aria-live=\"polite\"\n            aria-atomic=\"true\"\n            aria-label={`Trial time remaining: ${timeRemaining.days} days, ${timeRemaining.hours} hours, ${timeRemaining.minutes} minutes, ${timeRemaining.seconds} seconds`}\n          >\n            <div className=\"flex items-center justify-center gap-2 sm:gap-4\">\n              <TimeUnit value={timeRemaining.days} label=\"Days\" />\n              <span className=\"text-muted-foreground\">:</span>\n              <TimeUnit value={timeRemaining.hours} label=\"Hours\" />\n              <span className=\"text-muted-foreground\">:</span>\n              <TimeUnit value={timeRemaining.minutes} label=\"Min\" />\n              <span className=\"text-muted-foreground\">:</span>\n              <TimeUnit value={timeRemaining.seconds} label=\"Sec\" />\n            </div>\n          </div>\n        )}\n\n        {/* Features */}\n        <div className=\"space-y-3\">\n          <h3 className=\"text-sm font-semibold\">Included with upgrade</h3>\n          <div className=\"space-y-2\">\n            {features.slice(0, 4).map((feature, index) => (\n              <div\n                key={index}\n                className=\"text-muted-foreground flex items-center gap-2 text-sm\"\n              >\n                <Check className=\"text-primary h-4 w-4\" />\n                <span>{feature}</span>\n              </div>\n            ))}\n          </div>\n        </div>\n\n        {/* CTA Button */}\n        {onUpgrade && (\n          <Button\n            onClick={handleUpgrade}\n            disabled={isLoading}\n            className=\"w-full\"\n            size=\"lg\"\n          >\n            {isLoading ? \"Processing...\" : upgradeButtonText}\n          </Button>\n        )}\n      </CardContent>\n    </Card>\n  );\n}\n\nfunction TimeUnit({ value, label }: { value: number; label: string }) {\n  return (\n    <div className=\"flex flex-col items-center\">\n      <div className=\"text-2xl font-bold tabular-nums sm:text-3xl\">\n        {String(value).padStart(2, \"0\")}\n      </div>\n      <div className=\"text-muted-foreground text-xs\">{label}</div>\n    </div>\n  );\n}\n",
      "type": "registry:component",
      "target": "components/billingsdk/trial-expiry-card.tsx"
    },
    {
      "path": "src/registry/billingsdk/demo/trial-expiry-card-demo.tsx",
      "content": "\"use client\";\n\nimport { TrialExpiryCard } from \"@/components/billingsdk/trial-expiry-card\";\n\nexport default function TrialExpiryCardDemo() {\n  // Set trial to expire in 5 days\n  const trialEndDate = new Date();\n  trialEndDate.setDate(trialEndDate.getDate() + 5);\n\n  return (\n    <div className=\"bg-background flex h-full min-h-[500px] w-full items-center justify-center rounded-lg border-2 p-6\">\n      <TrialExpiryCard\n        trialEndDate={trialEndDate}\n        onUpgrade={() => {\n          console.log(\"Upgrade clicked\");\n        }}\n        features={[\n          \"Unlimited API requests\",\n          \"Advanced analytics dashboard\",\n          \"Priority email support\",\n          \"Custom domain integration\",\n        ]}\n        className=\"w-full max-w-md\"\n      />\n    </div>\n  );\n}\n",
      "type": "registry:component",
      "target": "components/trial-expiry-card-demo.tsx"
    }
  ],
  "type": "registry:block"
}
