{
  "$schema": "https://shadcn-vue.com/schema/registry-item.json",
  "name": "maintenance-request-ticket",
  "title": "Maintenance Request Ticket",
  "type": "registry:block",
  "files": [
    {
      "path": "packages/registry-vue/blocks/maintenance-request-ticket/MaintenanceRequestTicket.vue",
      "content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport { computed, ref } from 'vue'\nimport {\n  AlertCircle,\n  Bug,\n  Building2,\n  Check,\n  CheckCircle2,\n  ChevronDown,\n  Clock,\n  Droplets,\n  FileImage,\n  FileVideo,\n  Flame,\n  KeyRound,\n  PhoneCall,\n  Plus,\n  RefreshCw,\n  ShieldAlert,\n  ShieldCheck,\n  Trash2,\n  UploadCloud,\n  UserCheck,\n  Wrench,\n  Zap,\n} from 'lucide-vue-next'\nimport { cn } from '@/lib/utils'\nimport { Badge } from '@/components/ui/badge'\nimport { Button } from '@/components/ui/button'\nimport { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from '@/components/ui/card'\nimport { RadioGroup, RadioGroupItem } from '@/components/ui/radio-group'\nimport {\n  Select,\n  SelectContent,\n  SelectGroup,\n  SelectItem,\n  SelectLabel,\n  SelectTrigger,\n  SelectValue,\n} from '@/components/ui/select'\nimport { Separator } from '@/components/ui/separator'\nimport { Textarea } from '@/components/ui/textarea'\n\nexport interface AttachedFile {\n  id: string\n  name: string\n  size: string\n  type: 'image' | 'video'\n  uploadedAt: string\n}\n\nexport interface MaintenanceRequestTicketProps {\n  class?: HTMLAttributes['class']\n  initialCategory?: string\n  initialUrgency?: 'routine' | 'standard' | 'emergency'\n  initialLocation?: string\n  initialDescription?: string\n  initialPermission?: 'granted' | 'call_first'\n  initialFiles?: AttachedFile[]\n}\n\nconst props = withDefaults(defineProps<MaintenanceRequestTicketProps>(), {\n  initialCategory: 'appliances',\n  initialUrgency: 'standard',\n  initialLocation: 'kitchen',\n  initialDescription:\n    'Kitchen sink garbage disposal is jammed and leaking slightly under the cabinet when water runs. Motor makes a low humming sound.',\n  initialPermission: 'granted',\n  initialFiles: () => [\n    {\n      id: 'f-1',\n      name: 'kitchen-sink-leak-pipe.jpg',\n      size: '2.4 MB',\n      type: 'image',\n      uploadedAt: 'Today, 10:14 AM',\n    },\n    {\n      id: 'f-2',\n      name: 'disposal-motor-hum.mp4',\n      size: '8.1 MB',\n      type: 'video',\n      uploadedAt: 'Today, 10:16 AM',\n    },\n  ],\n})\n\n// Form state\nconst category = ref<string>(props.initialCategory)\nconst urgency = ref<'routine' | 'standard' | 'emergency'>(props.initialUrgency)\nconst location = ref<string>(props.initialLocation)\nconst description = ref<string>(props.initialDescription)\nconst permission = ref<'granted' | 'call_first'>(props.initialPermission)\nconst attachedFiles = ref<AttachedFile[]>([...props.initialFiles])\nconst isDragging = ref(false)\nconst showOpenRequests = ref(false)\nconst isSubmitting = ref(false)\nconst isSubmitted = ref(false)\nconst draftSaved = ref(false)\nconst generatedTicketId = ref('MNT-9042')\n\n// Category options\nconst categories = [\n  {\n    id: 'plumbing',\n    label: 'Plumbing & Leaks',\n    description: 'Faucets, pipes, toilets, drains',\n    icon: Droplets,\n    badgeColor: 'text-info bg-info/10 text-info',\n  },\n  {\n    id: 'electrical',\n    label: 'Electrical & Lighting',\n    description: 'Outlets, switches, fixtures, breakers',\n    icon: Zap,\n    badgeColor: 'text-warning bg-warning/10 text-warning',\n  },\n  {\n    id: 'hvac',\n    label: 'HVAC & AC Heating',\n    description: 'AC, thermostat, heater, airflow',\n    icon: Flame,\n    badgeColor: 'text-chart-2 bg-chart-2/10',\n  },\n  {\n    id: 'appliances',\n    label: 'Appliances',\n    description: 'Dishwasher, oven, disposal, fridge',\n    icon: Wrench,\n    badgeColor: 'text-chart-1 bg-chart-1/10',\n  },\n  {\n    id: 'locks',\n    label: 'Doors & Locks',\n    description: 'Keys, latches, deadbolts, windows',\n    icon: KeyRound,\n    badgeColor: 'text-success bg-success/10 text-success',\n  },\n  {\n    id: 'pest',\n    label: 'Pest Control',\n    description: 'Insects, rodents, preventative traps',\n    icon: Bug,\n    badgeColor: 'text-destructive bg-destructive/10 text-destructive',\n  },\n]\n\n// Urgency options\nconst urgencyOptions = [\n  {\n    value: 'routine',\n    label: 'Low / Routine',\n    badge: '3–5 Business Days',\n    badgeVariant: 'outline' as const,\n    description: 'Non-urgent preventative maintenance or routine hardware adjustments.',\n  },\n  {\n    value: 'standard',\n    label: 'Medium / Standard 48h',\n    badge: '24–48h SLA',\n    badgeVariant: 'secondary' as const,\n    description: 'Standard repair with moderate impact on daily convenience or appliance usage.',\n  },\n  {\n    value: 'emergency',\n    label: 'High / Emergency 2h SLA',\n    badge: 'Emergency < 2h',\n    badgeVariant: 'destructive' as const,\n    description: 'Immediate hazard to property or habitability. Triggers 24/7 on-call dispatch.',\n  },\n]\n\n// Location options\nconst locationOptions = [\n  { value: 'kitchen', label: 'Kitchen' },\n  { value: 'master_bathroom', label: 'Master Bathroom' },\n  { value: 'guest_bathroom', label: 'Guest Bathroom' },\n  { value: 'living_room', label: 'Living Room' },\n  { value: 'balcony', label: 'Balcony / Patio' },\n  { value: 'master_bedroom', label: 'Master Bedroom' },\n  { value: 'guest_bedroom', label: 'Guest Bedroom' },\n  { value: 'hallway', label: 'Hallway / Entryway' },\n  { value: 'laundry', label: 'Laundry & Utility Closet' },\n]\n\n// Sample quick description chips\nconst quickSnippets = [\n  'Motor humming but not spinning',\n  'Water leaking under sink',\n  'Reset button tripped',\n  'Slow draining',\n]\n\nconst maxChars = 500\nconst descriptionLength = computed(() => description.value.length)\n\nfunction selectCategory(id: string) {\n  category.value = id\n}\n\nfunction appendSnippet(snippet: string) {\n  if (!description.value) {\n    description.value = snippet\n  } else if (!description.value.includes(snippet)) {\n    description.value = `${description.value.trim()} ${snippet}.`\n  }\n}\n\nfunction removeFile(id: string) {\n  attachedFiles.value = attachedFiles.value.filter((f) => f.id !== id)\n}\n\nfunction handleDrop(e: DragEvent) {\n  e.preventDefault()\n  isDragging.value = false\n  if (e.dataTransfer?.files && e.dataTransfer.files.length > 0) {\n    for (let i = 0; i < e.dataTransfer.files.length; i++) {\n      const file = e.dataTransfer.files[i]\n      attachedFiles.value.push({\n        id: `f-${Date.now()}-${i}`,\n        name: file.name,\n        size: `${(file.size / (1024 * 1024)).toFixed(1)} MB`,\n        type: file.type.startsWith('video') ? 'video' : 'image',\n        uploadedAt: 'Just now',\n      })\n    }\n  }\n}\n\nfunction simulateAddFile() {\n  const sampleNames = ['cabinet-water-mark.jpg', 'under-sink-plumbing.jpg', 'noise-recording.mp4']\n  const randomName = sampleNames[attachedFiles.value.length % sampleNames.length]\n  attachedFiles.value.push({\n    id: `f-${Date.now()}`,\n    name: randomName,\n    size: '3.1 MB',\n    type: randomName.endsWith('.mp4') ? 'video' : 'image',\n    uploadedAt: 'Just now',\n  })\n}\n\nfunction handleSaveDraft() {\n  draftSaved.value = true\n  setTimeout(() => {\n    draftSaved.value = false\n  }, 3000)\n}\n\nfunction handleSubmit() {\n  isSubmitting.value = true\n  setTimeout(() => {\n    isSubmitting.value = false\n    isSubmitted.value = true\n    generatedTicketId.value = `MNT-${Math.floor(1000 + Math.random() * 9000)}`\n  }, 700)\n}\n\nfunction handleReset() {\n  isSubmitted.value = false\n  category.value = 'appliances'\n  urgency.value = 'standard'\n  location.value = 'kitchen'\n  description.value =\n    'Kitchen sink garbage disposal is jammed and leaking slightly under the cabinet when water runs. Motor makes a low humming sound.'\n  permission.value = 'granted'\n  attachedFiles.value = [\n    {\n      id: 'f-1',\n      name: 'kitchen-sink-leak-pipe.jpg',\n      size: '2.4 MB',\n      type: 'image',\n      uploadedAt: 'Today, 10:14 AM',\n    },\n    {\n      id: 'f-2',\n      name: 'disposal-motor-hum.mp4',\n      size: '8.1 MB',\n      type: 'video',\n      uploadedAt: 'Today, 10:16 AM',\n    },\n  ]\n}\n</script>\n\n<template>\n  <div data-slot=\"maintenance-request-ticket\" :class=\"cn('w-full space-y-6', props.class)\">\n    <!-- Header Banner -->\n    <Card class=\"border-border shadow-xs\">\n      <CardContent class=\"p-4 sm:p-6\">\n        <div class=\"flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between\">\n          <div class=\"space-y-1.5\">\n            <div class=\"flex flex-wrap items-center gap-2.5\">\n              <h1 class=\"text-foreground text-xl font-bold tracking-tight sm:text-2xl\">Submit Maintenance Request</h1>\n              <Badge variant=\"outline\" class=\"gap-1.5 font-mono text-xs\">\n                <span class=\"bg-success size-1.5 rounded-full\"></span>\n                Unit 4B · Pacific Heights\n              </Badge>\n            </div>\n            <p class=\"text-muted-foreground text-sm\">\n              Resident: <span class=\"text-foreground font-medium\">Elena Rostova</span> · Facility maintenance & repair\n              portal\n            </p>\n          </div>\n\n          <div class=\"flex flex-wrap items-center gap-2.5\">\n            <div class=\"bg-muted/60 border-border inline-flex items-center gap-2 rounded-lg border px-3 py-1.5 text-xs\">\n              <span class=\"relative flex size-2\">\n                <span class=\"bg-warning absolute inline-flex size-full rounded-full opacity-75\"></span>\n                <span class=\"bg-warning relative inline-flex size-2 rounded-full\"></span>\n              </span>\n              <span class=\"text-foreground font-medium\">1 In Progress</span>\n              <span class=\"text-muted-foreground hidden sm:inline\">· #MNT-8821</span>\n            </div>\n            <Button variant=\"outline\" size=\"sm\" class=\"gap-1.5 shadow-xs\" @click=\"showOpenRequests = !showOpenRequests\">\n              <span>{{ showOpenRequests ? 'Hide Open Requests' : 'View Open Requests' }}</span>\n              <ChevronDown\n                :class=\"cn('size-3.5 transition-transform duration-200', showOpenRequests && 'rotate-180')\"\n              />\n            </Button>\n          </div>\n        </div>\n\n        <!-- Collapsible Active Work Orders Panel -->\n        <div\n          v-if=\"showOpenRequests\"\n          class=\"border-border bg-muted/30 mt-4 space-y-3 rounded-lg border p-4 transition-colors\"\n        >\n          <div class=\"flex items-center justify-between\">\n            <div class=\"flex items-center gap-2\">\n              <Clock class=\"text-muted-foreground size-4\" />\n              <span class=\"text-foreground text-xs font-semibold tracking-wider uppercase\">\n                Currently Active Work Orders (1)\n              </span>\n            </div>\n            <Badge variant=\"secondary\" class=\"text-xs\">Technician Assigned</Badge>\n          </div>\n          <div\n            class=\"bg-card border-border flex flex-col justify-between gap-3 rounded-md border p-3 sm:flex-row sm:items-center\"\n          >\n            <div class=\"space-y-1\">\n              <div class=\"flex items-center gap-2\">\n                <span class=\"text-foreground text-sm font-semibold\"\n                  >#MNT-8821 · HVAC Filter & Thermostat Inspection</span\n                >\n                <Badge variant=\"outline\" class=\"text-xs\">Living Room</Badge>\n              </div>\n              <p class=\"text-muted-foreground text-xs\">\n                Assigned to: <span class=\"text-foreground font-medium\">Dave Miller (Lead HVAC Specialist)</span> ·\n                Scheduled window: Today 2:00 PM – 4:00 PM\n              </p>\n            </div>\n            <div class=\"flex shrink-0 items-center gap-2\">\n              <Badge variant=\"info\" class=\"text-xs\">In Progress</Badge>\n            </div>\n          </div>\n        </div>\n      </CardContent>\n    </Card>\n\n    <!-- Main 2-Column Layout -->\n    <div class=\"grid grid-cols-1 gap-6 lg:grid-cols-12 lg:gap-8\">\n      <!-- Left Column: Work Order Form (8 cols) -->\n      <div class=\"space-y-6 lg:col-span-8\">\n        <!-- Submission Success State -->\n        <Card v-if=\"isSubmitted\" class=\"border-success/30 bg-success/5 dark:bg-success/10 shadow-xs\">\n          <CardContent class=\"space-y-4 p-6 text-center sm:p-8\">\n            <div class=\"bg-success/10 text-success mx-auto flex size-14 items-center justify-center rounded-full\">\n              <CheckCircle2 class=\"size-8\" />\n            </div>\n            <div class=\"space-y-2\">\n              <h2 class=\"text-foreground text-xl font-bold\">Maintenance Request Submitted!</h2>\n              <p class=\"text-muted-foreground mx-auto max-w-md text-sm\">\n                Your request <span class=\"text-foreground font-mono font-semibold\">#{{ generatedTicketId }}</span> has\n                been logged and dispatched to the Pacific Heights Facility Operations team.\n              </p>\n            </div>\n            <div class=\"border-border bg-card mx-auto max-w-lg space-y-2 rounded-lg border p-4 text-left text-xs\">\n              <div class=\"flex justify-between\">\n                <span class=\"text-muted-foreground\">Ticket ID:</span>\n                <span class=\"text-foreground font-mono font-medium\">#{{ generatedTicketId }}</span>\n              </div>\n              <div class=\"flex justify-between\">\n                <span class=\"text-muted-foreground\">Unit:</span>\n                <span class=\"text-foreground font-medium\">Unit 4B (Pacific Heights)</span>\n              </div>\n              <div class=\"flex justify-between\">\n                <span class=\"text-muted-foreground\">Category:</span>\n                <span class=\"text-foreground font-medium capitalize\">{{ category }}</span>\n              </div>\n              <div class=\"flex justify-between\">\n                <span class=\"text-muted-foreground\">Urgency Tier:</span>\n                <span class=\"text-foreground font-medium capitalize\">{{ urgency }} SLA</span>\n              </div>\n              <div class=\"flex justify-between\">\n                <span class=\"text-muted-foreground\">Entry Authorization:</span>\n                <span class=\"text-foreground font-medium\">\n                  {{ permission === 'granted' ? 'Permission Granted (Master Key)' : 'Call Resident First' }}\n                </span>\n              </div>\n            </div>\n            <div class=\"flex flex-wrap justify-center gap-3 pt-2\">\n              <Button class=\"gap-1.5 shadow-xs\" @click=\"handleReset\">\n                <RefreshCw class=\"size-4\" />\n                <span>Submit Another Request</span>\n              </Button>\n            </div>\n          </CardContent>\n        </Card>\n\n        <!-- Work Order Submission Form -->\n        <Card v-else class=\"border-border shadow-xs\">\n          <CardHeader class=\"pb-4\">\n            <CardTitle class=\"text-lg\">Work Order Details</CardTitle>\n            <CardDescription> Complete the fields below to schedule a maintenance technician visit. </CardDescription>\n          </CardHeader>\n\n          <CardContent class=\"space-y-6\">\n            <!-- 1. Category Selection Grid -->\n            <div class=\"space-y-3\">\n              <div class=\"flex items-center justify-between\">\n                <label class=\"text-foreground text-sm font-semibold\">\n                  1. Issue Category <span class=\"text-destructive\">*</span>\n                </label>\n                <span class=\"text-muted-foreground text-xs\">Select one primary discipline</span>\n              </div>\n\n              <div class=\"grid grid-cols-2 gap-3 sm:grid-cols-3\">\n                <button\n                  v-for=\"cat in categories\"\n                  :key=\"cat.id\"\n                  type=\"button\"\n                  :aria-pressed=\"category === cat.id\"\n                  :class=\"\n                    cn(\n                      'group focus-visible:ring-ring relative flex cursor-pointer flex-col items-start gap-2.5 rounded-lg border p-3.5 text-left transition-colors outline-none select-none focus-visible:ring-2',\n                      category === cat.id\n                        ? 'border-primary bg-primary/5 ring-primary/30 shadow-xs ring-1'\n                        : 'border-border bg-card hover:bg-muted/40 hover:border-muted-foreground/30',\n                    )\n                  \"\n                  @click=\"selectCategory(cat.id)\"\n                >\n                  <div class=\"flex w-full items-center justify-between\">\n                    <div :class=\"cn('flex size-8 items-center justify-center rounded-md', cat.badgeColor)\">\n                      <component :is=\"cat.icon\" class=\"size-4.5\" />\n                    </div>\n                    <div\n                      :class=\"\n                        cn(\n                          'flex size-4 items-center justify-center rounded-full border transition-colors',\n                          category === cat.id\n                            ? 'border-primary bg-primary text-primary-foreground'\n                            : 'border-muted-foreground/30 opacity-0 group-hover:opacity-60',\n                        )\n                      \"\n                    >\n                      <Check v-if=\"category === cat.id\" class=\"size-2.5 stroke-[3]\" />\n                    </div>\n                  </div>\n                  <div>\n                    <p class=\"text-foreground text-xs font-semibold\">{{ cat.label }}</p>\n                    <p class=\"text-muted-foreground mt-0.5 line-clamp-1 text-xs\">{{ cat.description }}</p>\n                  </div>\n                </button>\n              </div>\n            </div>\n\n            <Separator />\n\n            <!-- 2. Urgency Level Radios -->\n            <div class=\"space-y-3\">\n              <div class=\"flex items-center justify-between\">\n                <label class=\"text-foreground text-sm font-semibold\">\n                  2. Urgency Priority <span class=\"text-destructive\">*</span>\n                </label>\n                <span class=\"text-muted-foreground text-xs\">Determines facility response window</span>\n              </div>\n\n              <!-- Emergency Banner Alert if High Selected -->\n              <div\n                v-if=\"urgency === 'emergency'\"\n                class=\"border-destructive/30 bg-destructive/10 text-destructive flex items-start gap-3 rounded-lg border p-3.5 text-xs\"\n              >\n                <AlertCircle class=\"mt-0.5 size-4 shrink-0\" />\n                <div class=\"space-y-1\">\n                  <p class=\"font-semibold\">High / Emergency SLA Activated</p>\n                  <p class=\"text-destructive/90 leading-relaxed\">\n                    Emergency requests notify on-call building engineers immediately. For active gas leaks or major\n                    structural flooding, call the 24/7 hotline directly at <strong>(415) 555-0192</strong>.\n                  </p>\n                </div>\n              </div>\n\n              <RadioGroup v-model=\"urgency\" class=\"grid gap-3 sm:grid-cols-3\">\n                <div\n                  v-for=\"opt in urgencyOptions\"\n                  :key=\"opt.value\"\n                  :class=\"\n                    cn(\n                      'border-border relative flex cursor-pointer flex-col justify-between gap-3 rounded-lg border p-3.5 transition-colors',\n                      urgency === opt.value\n                        ? 'border-primary bg-primary/5 ring-primary/30 shadow-xs ring-1'\n                        : 'bg-card hover:bg-muted/40 hover:border-muted-foreground/30',\n                    )\n                  \"\n                  @click=\"urgency = opt.value as any\"\n                >\n                  <div class=\"flex items-start justify-between gap-2\">\n                    <div class=\"flex items-center gap-2\">\n                      <RadioGroupItem :id=\"`urgency-${opt.value}`\" :value=\"opt.value\" />\n                      <label\n                        :for=\"`urgency-${opt.value}`\"\n                        class=\"text-foreground cursor-pointer text-xs font-semibold select-none\"\n                      >\n                        {{ opt.label }}\n                      </label>\n                    </div>\n                  </div>\n                  <div>\n                    <Badge :variant=\"opt.badgeVariant\" class=\"mb-1 text-xs\">\n                      {{ opt.badge }}\n                    </Badge>\n                    <p class=\"text-muted-foreground text-xs leading-relaxed\">\n                      {{ opt.description }}\n                    </p>\n                  </div>\n                </div>\n              </RadioGroup>\n            </div>\n\n            <Separator />\n\n            <!-- 3. Location in Unit -->\n            <div class=\"space-y-3\">\n              <div class=\"flex items-center justify-between\">\n                <label class=\"text-foreground text-sm font-semibold\">\n                  3. Location in Unit <span class=\"text-destructive\">*</span>\n                </label>\n                <span class=\"text-muted-foreground text-xs\">Specific area or room</span>\n              </div>\n\n              <Select v-model=\"location\">\n                <SelectTrigger class=\"w-full\">\n                  <SelectValue placeholder=\"Select location in unit...\" />\n                </SelectTrigger>\n                <SelectContent>\n                  <SelectGroup>\n                    <SelectLabel>Unit 4B Interior Areas</SelectLabel>\n                    <SelectItem v-for=\"loc in locationOptions\" :key=\"loc.value\" :value=\"loc.value\">\n                      {{ loc.label }}\n                    </SelectItem>\n                  </SelectGroup>\n                </SelectContent>\n              </Select>\n            </div>\n\n            <Separator />\n\n            <!-- 4. Issue Description -->\n            <div class=\"space-y-3\">\n              <div class=\"flex items-center justify-between\">\n                <label for=\"mnt-description\" class=\"text-foreground text-sm font-semibold\">\n                  4. Issue Description <span class=\"text-destructive\">*</span>\n                </label>\n                <span\n                  class=\"text-xs\"\n                  :class=\"descriptionLength > maxChars ? 'text-destructive font-medium' : 'text-muted-foreground'\"\n                >\n                  {{ descriptionLength }} / {{ maxChars }}\n                </span>\n              </div>\n\n              <Textarea\n                id=\"mnt-description\"\n                v-model=\"description\"\n                :rows=\"4\"\n                placeholder=\"Please describe the maintenance issue with as much detail as possible...\"\n                class=\"w-full text-sm\"\n              />\n\n              <!-- Quick Snippet Helper Chips -->\n              <div class=\"space-y-1.5\">\n                <p class=\"text-muted-foreground text-xs\">Quick details:</p>\n                <div class=\"flex flex-wrap gap-1.5\">\n                  <button\n                    v-for=\"chip in quickSnippets\"\n                    :key=\"chip\"\n                    type=\"button\"\n                    class=\"bg-muted hover:bg-muted/80 text-muted-foreground hover:text-foreground inline-flex cursor-pointer items-center gap-1 rounded-md px-2.5 py-1 text-xs transition-colors\"\n                    @click=\"appendSnippet(chip)\"\n                  >\n                    <Plus class=\"size-3\" />\n                    <span>{{ chip }}</span>\n                  </button>\n                </div>\n              </div>\n            </div>\n\n            <Separator />\n\n            <!-- 5. Permission to Enter Unit -->\n            <div class=\"space-y-3\">\n              <div class=\"flex items-center justify-between\">\n                <label class=\"text-foreground text-sm font-semibold\">\n                  5. Permission to Enter Unit <span class=\"text-destructive\">*</span>\n                </label>\n                <span class=\"text-muted-foreground text-xs\">Access protocol</span>\n              </div>\n\n              <RadioGroup v-model=\"permission\" class=\"grid gap-3 sm:grid-cols-2\">\n                <div\n                  :class=\"\n                    cn(\n                      'border-border relative flex cursor-pointer flex-col justify-between gap-2.5 rounded-lg border p-4 transition-colors',\n                      permission === 'granted'\n                        ? 'border-primary bg-primary/5 ring-primary/30 shadow-xs ring-1'\n                        : 'bg-card hover:bg-muted/40 hover:border-muted-foreground/30',\n                    )\n                  \"\n                  @click=\"permission = 'granted'\"\n                >\n                  <div class=\"flex items-start gap-2.5\">\n                    <RadioGroupItem id=\"perm-granted\" value=\"granted\" class=\"mt-0.5\" />\n                    <div class=\"space-y-1\">\n                      <label\n                        for=\"perm-granted\"\n                        class=\"text-foreground cursor-pointer text-xs font-semibold select-none\"\n                      >\n                        Permission Granted to Enter\n                      </label>\n                      <p class=\"text-muted-foreground text-xs leading-relaxed\">\n                        Authorized staff may enter with master key if resident is not home. Work order sign-off notice\n                        will be left in unit.\n                      </p>\n                    </div>\n                  </div>\n                  <div class=\"text-success flex items-center gap-1.5 pl-6 text-xs font-medium\">\n                    <UserCheck class=\"size-3.5\" />\n                    <span>Faster dispatch window</span>\n                  </div>\n                </div>\n\n                <div\n                  :class=\"\n                    cn(\n                      'border-border relative flex cursor-pointer flex-col justify-between gap-2.5 rounded-lg border p-4 transition-colors',\n                      permission === 'call_first'\n                        ? 'border-primary bg-primary/5 ring-primary/30 shadow-xs ring-1'\n                        : 'bg-card hover:bg-muted/40 hover:border-muted-foreground/30',\n                    )\n                  \"\n                  @click=\"permission = 'call_first'\"\n                >\n                  <div class=\"flex items-start gap-2.5\">\n                    <RadioGroupItem id=\"perm-call\" value=\"call_first\" class=\"mt-0.5\" />\n                    <div class=\"space-y-1\">\n                      <label for=\"perm-call\" class=\"text-foreground cursor-pointer text-xs font-semibold select-none\">\n                        Call Resident Before Entering\n                      </label>\n                      <p class=\"text-muted-foreground text-xs leading-relaxed\">\n                        Technician must call <span class=\"text-foreground font-medium\">(415) 890-4412</span> 30 mins\n                        prior to arrival. Adult must be present.\n                      </p>\n                    </div>\n                  </div>\n                  <div class=\"text-muted-foreground flex items-center gap-1.5 pl-6 text-xs\">\n                    <Clock class=\"size-3.5\" />\n                    <span>Requires resident appointment</span>\n                  </div>\n                </div>\n              </RadioGroup>\n            </div>\n\n            <Separator />\n\n            <!-- 6. Photo & Video Dropzone -->\n            <div class=\"space-y-3\">\n              <div class=\"flex items-center justify-between\">\n                <label class=\"text-foreground text-sm font-semibold\">\n                  6. Photo & Video Dropzone <span class=\"text-muted-foreground text-xs font-normal\">(Optional)</span>\n                </label>\n                <span class=\"text-muted-foreground text-xs\">{{ attachedFiles.length }} Attached</span>\n              </div>\n\n              <!-- Interactive Drop Area -->\n              <div\n                :class=\"\n                  cn(\n                    'cursor-pointer rounded-lg border-2 border-dashed p-6 text-center transition-colors',\n                    isDragging\n                      ? 'border-primary bg-primary/10'\n                      : 'border-border bg-muted/20 hover:border-muted-foreground/40 hover:bg-muted/40',\n                  )\n                \"\n                @dragover.prevent=\"isDragging = true\"\n                @dragleave.prevent=\"isDragging = false\"\n                @drop=\"handleDrop\"\n                @click=\"simulateAddFile\"\n              >\n                <div\n                  class=\"bg-muted text-muted-foreground mx-auto flex size-10 items-center justify-center rounded-full\"\n                >\n                  <UploadCloud class=\"size-5\" />\n                </div>\n                <div class=\"mt-2.5 space-y-1\">\n                  <p class=\"text-foreground text-xs font-medium\">\n                    <span class=\"text-primary font-semibold hover:underline\">Click to upload</span> or drag and drop\n                    media files\n                  </p>\n                  <p class=\"text-muted-foreground text-xs\">\n                    PNG, JPG, HEIC, MP4 up to 25MB (helps technician arrive with correct parts)\n                  </p>\n                </div>\n              </div>\n\n              <!-- Attached Files Previews -->\n              <div v-if=\"attachedFiles.length > 0\" class=\"space-y-2 pt-1\">\n                <div\n                  v-for=\"f in attachedFiles\"\n                  :key=\"f.id\"\n                  class=\"bg-card border-border flex items-center justify-between gap-3 rounded-lg border p-2.5 text-xs transition-colors\"\n                >\n                  <div class=\"flex min-w-0 items-center gap-2.5\">\n                    <div class=\"bg-primary/10 text-primary flex size-8 shrink-0 items-center justify-center rounded-md\">\n                      <FileVideo v-if=\"f.type === 'video'\" class=\"size-4\" />\n                      <FileImage v-else class=\"size-4\" />\n                    </div>\n                    <div class=\"min-w-0\">\n                      <p class=\"text-foreground truncate font-medium\">{{ f.name }}</p>\n                      <p class=\"text-muted-foreground text-xs\">{{ f.size }} · {{ f.uploadedAt }}</p>\n                    </div>\n                  </div>\n                  <div class=\"flex shrink-0 items-center gap-2\">\n                    <Badge variant=\"outline\" class=\"border-success/30 text-success text-xs\"> Attached </Badge>\n                    <Button\n                      variant=\"ghost\"\n                      size=\"icon-sm\"\n                      class=\"text-muted-foreground hover:text-destructive size-7\"\n                      @click=\"removeFile(f.id)\"\n                    >\n                      <Trash2 class=\"size-3.5\" />\n                      <span class=\"sr-only\">Remove file</span>\n                    </Button>\n                  </div>\n                </div>\n              </div>\n            </div>\n          </CardContent>\n\n          <CardFooter\n            class=\"border-border bg-muted/20 flex flex-col-reverse justify-between gap-3 border-t p-4 sm:flex-row sm:items-center\"\n          >\n            <div class=\"flex items-center gap-2\">\n              <Button variant=\"outline\" size=\"sm\" class=\"shadow-xs\" :disabled=\"isSubmitting\" @click=\"handleSaveDraft\">\n                <span>{{ draftSaved ? 'Draft Saved!' : 'Save as Draft' }}</span>\n              </Button>\n              <span v-if=\"draftSaved\" class=\"text-success flex items-center gap-1 text-xs\">\n                <Check class=\"size-3\" />\n                Saved locally\n              </span>\n            </div>\n\n            <Button\n              size=\"default\"\n              class=\"w-full gap-2 shadow-xs sm:w-auto\"\n              :disabled=\"isSubmitting || !description.trim()\"\n              @click=\"handleSubmit\"\n            >\n              <Wrench v-if=\"!isSubmitting\" class=\"size-4\" />\n              <RefreshCw v-else class=\"size-4 animate-spin\" />\n              <span>{{ isSubmitting ? 'Dispatching Work Order...' : 'Submit Maintenance Request' }}</span>\n            </Button>\n          </CardFooter>\n        </Card>\n      </div>\n\n      <!-- Right Column: Emergency & SLA Sidebar (4 cols) -->\n      <div class=\"space-y-6 lg:sticky lg:top-6 lg:col-span-4\">\n        <!-- 24/7 Emergency Maintenance Hotline Card -->\n        <Card class=\"border-destructive/40 bg-destructive/5 dark:bg-destructive/10 shadow-xs\">\n          <CardHeader class=\"pb-3\">\n            <div class=\"text-destructive flex items-center gap-2\">\n              <ShieldAlert class=\"size-5 shrink-0\" />\n              <CardTitle class=\"text-destructive text-base\">24/7 Emergency Hotline</CardTitle>\n            </div>\n            <CardDescription class=\"text-foreground/80 text-xs\">\n              For urgent situations threatening life safety, gas leaks, or active flooding.\n            </CardDescription>\n          </CardHeader>\n          <CardContent class=\"space-y-4\">\n            <div class=\"bg-card border-destructive/30 space-y-1 rounded-lg border p-3 text-center\">\n              <p class=\"text-muted-foreground text-xs font-medium\">Immediate Dispatch Phone</p>\n              <p class=\"text-foreground font-mono text-xl font-semibold tracking-tight\">(415) 555-0192</p>\n              <p class=\"text-muted-foreground text-xs\">Facility Operations On-Call Desk</p>\n            </div>\n\n            <div class=\"space-y-2\">\n              <p class=\"text-foreground text-xs font-semibold\">What qualifies as an emergency:</p>\n              <ul class=\"text-muted-foreground space-y-1.5 text-xs\">\n                <li class=\"flex items-start gap-2\">\n                  <span class=\"text-destructive font-bold\">•</span>\n                  <span>Active uncontrolled water leaks or burst pipes</span>\n                </li>\n                <li class=\"flex items-start gap-2\">\n                  <span class=\"text-destructive font-bold\">•</span>\n                  <span>Smell of natural gas or carbon monoxide alert</span>\n                </li>\n                <li class=\"flex items-start gap-2\">\n                  <span class=\"text-destructive font-bold\">•</span>\n                  <span>Complete electrical power loss in unit</span>\n                </li>\n                <li class=\"flex items-start gap-2\">\n                  <span class=\"text-destructive font-bold\">•</span>\n                  <span>Inoperable exterior lock or door security issue</span>\n                </li>\n                <li class=\"flex items-start gap-2\">\n                  <span class=\"text-destructive font-bold\">•</span>\n                  <span>Total loss of heating when temp is below 55°F</span>\n                </li>\n              </ul>\n            </div>\n\n            <Button as=\"a\" href=\"tel:4155550192\" variant=\"destructive\" class=\"w-full gap-2 shadow-xs\">\n              <PhoneCall class=\"size-4\" />\n              <span>Call Emergency Dispatch</span>\n            </Button>\n          </CardContent>\n        </Card>\n\n        <!-- Service Level Agreement (SLA) Card -->\n        <Card class=\"border-border shadow-xs\">\n          <CardHeader class=\"pb-3\">\n            <div class=\"flex items-center gap-2\">\n              <Clock class=\"text-primary size-4.5\" />\n              <CardTitle class=\"text-base\">Service Level Agreement (SLA)</CardTitle>\n            </div>\n            <CardDescription class=\"text-xs\">\n              Response benchmarks for Pacific Heights property maintenance.\n            </CardDescription>\n          </CardHeader>\n          <CardContent class=\"space-y-3.5\">\n            <div class=\"bg-muted/40 border-border space-y-2 rounded-lg border p-3\">\n              <div class=\"flex items-center justify-between\">\n                <div class=\"flex items-center gap-2\">\n                  <span class=\"bg-destructive size-2 rounded-full\"></span>\n                  <span class=\"text-foreground text-xs font-semibold\">Emergency Priority</span>\n                </div>\n                <Badge variant=\"destructive\" class=\"text-xs\">&lt; 2 Hours</Badge>\n              </div>\n              <p class=\"text-muted-foreground text-xs\">24/7/365 immediate dispatch with on-call technician response.</p>\n            </div>\n\n            <div class=\"bg-muted/40 border-border space-y-2 rounded-lg border p-3\">\n              <div class=\"flex items-center justify-between\">\n                <div class=\"flex items-center gap-2\">\n                  <span class=\"bg-secondary-foreground size-2 rounded-full\"></span>\n                  <span class=\"text-foreground text-xs font-semibold\">Standard Priority</span>\n                </div>\n                <Badge variant=\"secondary\" class=\"text-xs\">24–48 Hours</Badge>\n              </div>\n              <p class=\"text-muted-foreground text-xs\">\n                Standard repairs scheduled Mon–Fri during normal operational hours.\n              </p>\n            </div>\n\n            <div class=\"bg-muted/40 border-border space-y-2 rounded-lg border p-3\">\n              <div class=\"flex items-center justify-between\">\n                <div class=\"flex items-center gap-2\">\n                  <span class=\"bg-muted-foreground size-2 rounded-full\"></span>\n                  <span class=\"text-foreground text-xs font-semibold\">Routine / Preventative</span>\n                </div>\n                <Badge variant=\"outline\" class=\"text-xs\">3–5 Days</Badge>\n              </div>\n              <p class=\"text-muted-foreground text-xs\">\n                Filter changes, caulking touch-ups, and scheduled inspections.\n              </p>\n            </div>\n\n            <div class=\"border-border bg-card flex items-start gap-2.5 rounded-lg border p-3 text-xs\">\n              <ShieldCheck class=\"text-primary mt-0.5 size-4 shrink-0\" />\n              <p class=\"text-muted-foreground leading-relaxed\">\n                Status notifications are automatically sent via SMS and resident email as work orders progress.\n              </p>\n            </div>\n          </CardContent>\n        </Card>\n\n        <!-- Building Operations Info Card -->\n        <Card class=\"border-border shadow-xs\">\n          <CardHeader class=\"pb-3\">\n            <div class=\"flex items-center gap-2\">\n              <Building2 class=\"text-muted-foreground size-4.5\" />\n              <CardTitle class=\"text-base\">Building Operations</CardTitle>\n            </div>\n          </CardHeader>\n          <CardContent class=\"space-y-2.5 text-xs\">\n            <div class=\"border-border/60 flex justify-between border-b py-1\">\n              <span class=\"text-muted-foreground\">Building Super:</span>\n              <span class=\"text-foreground font-medium\">Marcus Vance (Office #102)</span>\n            </div>\n            <div class=\"border-border/60 flex justify-between border-b py-1\">\n              <span class=\"text-muted-foreground\">Service Window:</span>\n              <span class=\"text-foreground font-medium\">Mon – Sat · 8:00 AM – 6:00 PM</span>\n            </div>\n            <div class=\"border-border/60 flex justify-between border-b py-1\">\n              <span class=\"text-muted-foreground\">Quiet Hours:</span>\n              <span class=\"text-foreground font-medium\">10:00 PM – 8:00 AM</span>\n            </div>\n            <div class=\"flex justify-between py-1\">\n              <span class=\"text-muted-foreground\">Resident Portal ID:</span>\n              <span class=\"text-foreground font-mono font-medium\">PH-RES-4B</span>\n            </div>\n          </CardContent>\n        </Card>\n      </div>\n    </div>\n  </div>\n</template>\n",
      "type": "registry:block",
      "target": "~/app/components/blocks/MaintenanceRequestTicket.vue"
    }
  ],
  "dependencies": [
    "lucide-vue-next"
  ],
  "devDependencies": [],
  "registryDependencies": [
    "https://uipkge.dev/r/vue/badge.json",
    "https://uipkge.dev/r/vue/button.json",
    "https://uipkge.dev/r/vue/card.json",
    "https://uipkge.dev/r/vue/radio-group.json",
    "https://uipkge.dev/r/vue/select.json",
    "https://uipkge.dev/r/vue/separator.json",
    "https://uipkge.dev/r/vue/textarea.json"
  ],
  "description": "Resident repair and facility work order submission portal with urgency priority and photo dropzone.",
  "categories": [
    "real-estate",
    "hospitality",
    "app",
    "forms"
  ]
}