{
  "$schema": "https://shadcn-vue.com/schema/registry-item.json",
  "name": "cloud-backup-schedule",
  "title": "Cloud Backup Schedule",
  "type": "registry:block",
  "files": [
    {
      "path": "packages/registry-vue/blocks/cloud-backup-schedule/CloudBackupSchedule.vue",
      "content": "<script setup lang=\"ts\">\nimport { computed, ref } from 'vue'\nimport {\n  Cloud,\n  Database,\n  HardDrive,\n  Clock,\n  CheckCircle2,\n  AlertCircle,\n  RotateCw,\n  ShieldCheck,\n  Calendar,\n  Play,\n  ArrowUpRight,\n} from 'lucide-vue-next'\nimport { cn } from '@/lib/utils'\nimport { Card, CardHeader, CardTitle, CardDescription, CardContent, CardFooter } from '@/components/ui/card'\nimport { Button } from '@/components/ui/button'\nimport { Badge } from '@/components/ui/badge'\nimport { Progress } from '@/components/ui/progress'\nimport { Switch } from '@/components/ui/switch'\nimport { Separator } from '@/components/ui/separator'\n\ninterface BackupSnapshot {\n  id: string\n  label: string\n  size: string\n  timestamp: string\n  status: 'completed' | 'in_progress' | 'failed'\n  checksum: string\n}\n\nconst props = withDefaults(\n  defineProps<{\n    initialAutoBackup?: boolean\n    frequency?: string\n    retentionDays?: number\n    storageUsedGb?: number\n    storageTotalGb?: number\n    class?: string\n  }>(),\n  {\n    initialAutoBackup: true,\n    frequency: 'Everyday at 02:00 UTC',\n    retentionDays: 30,\n    storageUsedGb: 68.4,\n    storageTotalGb: 100,\n    class: undefined,\n  },\n)\n\nconst autoBackupEnabled = ref(props.initialAutoBackup)\nconst isBackingUp = ref(false)\nconst lastBackupSuccess = ref('12 minutes ago')\n\nconst snapshots = ref<BackupSnapshot[]>([\n  {\n    id: 'snap-9842',\n    label: 'Daily Scheduled Snapshot',\n    size: '14.2 GB',\n    timestamp: 'Today, 02:00 UTC',\n    status: 'completed',\n    checksum: 'sha256:7f9b...a1c3',\n  },\n  {\n    id: 'snap-9841',\n    label: 'Daily Scheduled Snapshot',\n    size: '14.1 GB',\n    timestamp: 'Yesterday, 02:00 UTC',\n    status: 'completed',\n    checksum: 'sha256:4d8e...90f2',\n  },\n  {\n    id: 'snap-9840',\n    label: 'Manual Pre-migration Checkpoint',\n    size: '13.9 GB',\n    timestamp: 'Sep 15, 14:22 UTC',\n    status: 'completed',\n    checksum: 'sha256:1a2b...3c4d',\n  },\n  {\n    id: 'snap-9839',\n    label: 'Automated Snapshot',\n    size: '13.8 GB',\n    timestamp: 'Sep 14, 02:00 UTC',\n    status: 'failed',\n    checksum: 'sha256:9e8f...5d2a',\n  },\n])\n\nconst usagePercentage = computed(() => Math.round((props.storageUsedGb / props.storageTotalGb) * 100))\n\nconst handleTriggerBackup = async () => {\n  if (isBackingUp.value) return\n  isBackingUp.value = true\n\n  // Simulate network backup trigger\n  setTimeout(() => {\n    isBackingUp.value = false\n    lastBackupSuccess.value = 'Just now'\n    snapshots.value.unshift({\n      id: `snap-${Math.floor(1000 + Math.random() * 9000)}`,\n      label: 'Manual On-demand Snapshot',\n      size: '14.3 GB',\n      timestamp: 'Just now',\n      status: 'completed',\n      checksum: `sha256:${Math.random().toString(36).substring(2, 6)}...${Math.random().toString(36).substring(2, 6)}`,\n    })\n  }, 1200)\n}\n</script>\n\n<template>\n  <div :class=\"cn('@container w-full max-w-4xl space-y-6', props.class)\">\n    <!-- Main Backup Management Card -->\n    <Card class=\"border-border shadow-xs\">\n      <CardHeader class=\"flex flex-col justify-between gap-4 pb-4 @md:flex-row @md:items-center\">\n        <div class=\"min-w-0 space-y-1\">\n          <div class=\"flex flex-wrap items-center gap-2\">\n            <div class=\"bg-primary/10 text-primary flex size-8 shrink-0 items-center justify-center rounded-lg\">\n              <Cloud class=\"size-4 shrink-0\" />\n            </div>\n            <CardTitle class=\"text-base font-semibold tracking-tight sm:text-lg\">Cloud Backup & Recovery</CardTitle>\n            <Badge variant=\"outline\" class=\"border-success/20 bg-success/10 text-success shrink-0 gap-1\">\n              <ShieldCheck class=\"size-3 shrink-0\" />\n              AES-256\n            </Badge>\n          </div>\n          <CardDescription class=\"text-xs sm:text-sm\">\n            Automated cluster snapshot schedules, retention policies, and disaster recovery replication.\n          </CardDescription>\n        </div>\n\n        <div class=\"flex shrink-0 items-center gap-2\">\n          <Button\n            size=\"sm\"\n            variant=\"default\"\n            class=\"w-full cursor-pointer gap-1.5 shadow-xs @md:w-auto\"\n            :disabled=\"isBackingUp\"\n            @click=\"handleTriggerBackup\"\n          >\n            <RotateCw v-if=\"isBackingUp\" class=\"size-3.5 shrink-0 animate-spin\" />\n            <Play v-else class=\"size-3.5 shrink-0 fill-current\" />\n            {{ isBackingUp ? 'Snapshotting...' : 'Backup Now' }}\n          </Button>\n        </div>\n      </CardHeader>\n\n      <Separator />\n\n      <CardContent class=\"grid grid-cols-1 gap-4 p-4 pt-4 sm:gap-6 sm:p-6 sm:pt-6 @md:grid-cols-2\">\n        <!-- Automation Schedule Tile -->\n        <div class=\"border-border bg-card min-w-0 space-y-4 rounded-lg border p-3.5 sm:p-4\">\n          <div class=\"flex items-center justify-between gap-2\">\n            <div class=\"flex min-w-0 items-center gap-2.5\">\n              <Clock class=\"text-muted-foreground size-4 shrink-0\" />\n              <span class=\"text-sm font-medium\">Daily Automation</span>\n            </div>\n            <Switch v-model=\"autoBackupEnabled\" aria-label=\"Toggle daily automated backup\" class=\"shrink-0\" />\n          </div>\n\n          <div class=\"text-muted-foreground space-y-2 text-xs\">\n            <div class=\"flex items-center justify-between gap-2\">\n              <span class=\"shrink-0\">Window:</span>\n              <span class=\"text-foreground truncate text-right font-medium\">{{ frequency }}</span>\n            </div>\n            <div class=\"flex items-center justify-between gap-2\">\n              <span class=\"shrink-0\">Retention:</span>\n              <span class=\"text-foreground truncate text-right font-medium\">{{ retentionDays }} days (rolling)</span>\n            </div>\n            <div class=\"flex items-center justify-between gap-2\">\n              <span class=\"shrink-0\">Target:</span>\n              <span class=\"text-foreground truncate text-right font-medium\">AWS S3 (us-east-1)</span>\n            </div>\n          </div>\n        </div>\n\n        <!-- Storage Quota Gauge Tile -->\n        <div class=\"border-border bg-card min-w-0 space-y-4 rounded-lg border p-3.5 sm:p-4\">\n          <div class=\"flex items-center justify-between gap-2\">\n            <div class=\"flex min-w-0 items-center gap-2\">\n              <HardDrive class=\"text-muted-foreground size-4 shrink-0\" />\n              <span class=\"truncate text-sm font-medium\">Vault Storage</span>\n            </div>\n            <span class=\"text-muted-foreground shrink-0 text-xs font-semibold tabular-nums\"\n              >{{ usagePercentage }}% used</span\n            >\n          </div>\n\n          <Progress :model-value=\"usagePercentage\" class=\"h-2\" />\n\n          <div class=\"text-muted-foreground flex items-center justify-between gap-2 text-xs tabular-nums\">\n            <span>{{ storageUsedGb }} GB used</span>\n            <span class=\"text-right\">{{ storageTotalGb }} GB total</span>\n          </div>\n        </div>\n      </CardContent>\n\n      <Separator />\n\n      <!-- Recent Snapshot Ledger -->\n      <CardContent class=\"space-y-4 p-4 pt-4 sm:p-6 sm:pt-6\">\n        <div class=\"flex flex-wrap items-center justify-between gap-2\">\n          <div class=\"flex items-center gap-2\">\n            <Database class=\"text-muted-foreground size-4 shrink-0\" />\n            <h4 class=\"text-sm font-semibold tracking-tight\">Recent Snapshots</h4>\n          </div>\n          <span class=\"text-muted-foreground text-xs\">Last verified: {{ lastBackupSuccess }}</span>\n        </div>\n\n        <div class=\"divide-border border-border bg-card divide-y rounded-lg border\">\n          <div\n            v-for=\"snap in snapshots\"\n            :key=\"snap.id\"\n            class=\"hover:bg-muted/40 flex flex-col justify-between gap-2 p-3.5 text-sm transition-colors @md:flex-row @md:items-center\"\n          >\n            <div class=\"flex min-w-0 items-center gap-3\">\n              <CheckCircle2 v-if=\"snap.status === 'completed'\" class=\"text-success size-4 shrink-0\" />\n              <AlertCircle v-else-if=\"snap.status === 'failed'\" class=\"text-destructive size-4 shrink-0\" />\n              <RotateCw v-else class=\"text-primary size-4 shrink-0 animate-spin\" />\n              <div class=\"min-w-0 flex-1 space-y-0.5\">\n                <div class=\"text-foreground flex flex-wrap items-center gap-1.5 font-medium\">\n                  <span class=\"truncate\">{{ snap.label }}</span>\n                  <span class=\"text-muted-foreground shrink-0 font-mono text-xs\">({{ snap.id }})</span>\n                </div>\n                <div class=\"text-muted-foreground flex items-center gap-2 font-mono text-xs\">\n                  <span class=\"truncate font-mono\">{{ snap.checksum }}</span>\n                  <span class=\"shrink-0\">•</span>\n                  <span class=\"shrink-0\">{{ snap.size }}</span>\n                </div>\n              </div>\n            </div>\n\n            <div class=\"flex shrink-0 items-center justify-between gap-3 pl-7 @md:justify-end @md:pl-0\">\n              <span class=\"text-muted-foreground text-xs whitespace-nowrap\">{{ snap.timestamp }}</span>\n              <Badge\n                :variant=\"\n                  snap.status === 'completed' ? 'secondary' : snap.status === 'failed' ? 'destructive' : 'outline'\n                \"\n                class=\"shrink-0 text-xs whitespace-nowrap capitalize\"\n              >\n                {{ snap.status.replace('_', ' ') }}\n              </Badge>\n            </div>\n          </div>\n        </div>\n      </CardContent>\n\n      <CardFooter\n        class=\"border-border text-muted-foreground flex flex-col items-start justify-between gap-3 border-t pt-4 text-xs @md:flex-row @md:items-center\"\n      >\n        <div class=\"flex items-center gap-2\">\n          <Calendar class=\"size-3.5 shrink-0\" />\n          <span>Next scheduled backup: Tonight at 02:00 UTC</span>\n        </div>\n        <a\n          href=\"#docs\"\n          class=\"text-primary inline-flex shrink-0 items-center gap-1 font-medium hover:underline\"\n          @click.prevent\n        >\n          Disaster recovery runbook\n          <ArrowUpRight class=\"size-3 shrink-0\" />\n        </a>\n      </CardFooter>\n    </Card>\n  </div>\n</template>\n",
      "type": "registry:block",
      "target": "~/app/components/blocks/CloudBackupSchedule.vue"
    },
    {
      "path": "packages/registry-vue/blocks/cloud-backup-schedule/index.ts",
      "content": "export { default as CloudBackupSchedule } from './CloudBackupSchedule.vue'\n",
      "type": "registry:block",
      "target": "~/app/components/blocks/cloud-backup-schedule/index.ts"
    }
  ],
  "dependencies": [
    "lucide-vue-next"
  ],
  "devDependencies": [],
  "registryDependencies": [
    "https://uipkge.dev/r/vue/card.json",
    "https://uipkge.dev/r/vue/button.json",
    "https://uipkge.dev/r/vue/badge.json",
    "https://uipkge.dev/r/vue/progress.json",
    "https://uipkge.dev/r/vue/switch.json",
    "https://uipkge.dev/r/vue/separator.json"
  ],
  "description": "Automated cloud snapshot scheduler with storage quota metering, encryption status, and recent snapshot timeline.",
  "categories": [
    "dashboard",
    "devops",
    "data"
  ]
}