Files
service-finder/frontend_admin/.nuxt/dist/server/_nuxt/index-CKl-ge5n.js.map.json
2026-06-29 14:11:15 +00:00

1 line
148 KiB
JSON
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{"file":"index-CKl-ge5n.js","mappings":"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","names":["_ssrRenderAttrs","_mergeProps","$t","_ssrInterpolate","_ssrRenderList","_ssrRenderClass","_ssrRenderAttr","_ssrRenderComponent","_unref","_ssrIncludeBooleanAttr"],"sources":["../../../../components/garages/GarageGeneralTab.vue","../../../../components/garages/GarageFleetTab.vue","../../../../components/garages/GarageSubscriptionTab.vue","../../../../pages/garages/[id]/index.vue"],"sourcesContent":["<template>\n <div class=\"space-y-6\">\n <!-- Company Info -->\n <div class=\"bg-slate-800/50 border border-slate-700 rounded-xl overflow-hidden\">\n <div class=\"px-6 py-4 border-b border-slate-700 flex items-center gap-3\">\n <div class=\"p-2 rounded-lg bg-indigo-500/10 text-indigo-400\">\n <svg class=\"w-5 h-5\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M19 21V5a2 2 0 00-2-2H7a2 2 0 00-2 2v16m14 0h2m-2 0h-5m-9 0H3m2 0h5M9 7h1m-1 4h1m4-4h1m-1 4h1m-5 10v-5a1 1 0 011-1h2a1 1 0 011 1v5m-4 0h4\" />\n </svg>\n </div>\n <h3 class=\"text-base font-semibold text-white\">{{ $t('garages.details.company_info') }}</h3>\n </div>\n <div class=\"px-6 py-5\">\n <div class=\"grid grid-cols-1 md:grid-cols-2 gap-6\">\n <div class=\"space-y-4\">\n <div>\n <p class=\"text-xs text-slate-500 uppercase tracking-wider\">{{ $t('garages.details.company_name') }}</p>\n <p class=\"text-sm text-white mt-1\">{{ garage.full_name }}</p>\n </div>\n <div>\n <p class=\"text-xs text-slate-500 uppercase tracking-wider\">{{ $t('garages.details.display_name') }}</p>\n <p class=\"text-sm text-white mt-1\">{{ garage.display_name || '—' }}</p>\n </div>\n <div>\n <p class=\"text-xs text-slate-500 uppercase tracking-wider\">{{ $t('garages.details.org_type') }}</p>\n <p class=\"text-sm text-white mt-1\">{{ orgTypeLabel(garage.org_type) }}</p>\n </div>\n </div>\n <div class=\"space-y-4\">\n <div>\n <p class=\"text-xs text-slate-500 uppercase tracking-wider\">{{ $t('garages.details.tax_number') }}</p>\n <p class=\"text-sm text-white mt-1\">{{ garage.tax_number || '—' }}</p>\n </div>\n <div>\n <p class=\"text-xs text-slate-500 uppercase tracking-wider\">{{ $t('garages.details.reg_number') }}</p>\n <p class=\"text-sm text-white mt-1\">{{ garage.reg_number || '—' }}</p>\n </div>\n <div>\n <p class=\"text-xs text-slate-500 uppercase tracking-wider\">{{ $t('garages.details.created_at') }}</p>\n <p class=\"text-sm text-white mt-1\">{{ formatDate(garage.created_at) }}</p>\n </div>\n </div>\n </div>\n <div class=\"mt-6 pt-6 border-t border-slate-700/50\">\n <p class=\"text-xs text-slate-500 uppercase tracking-wider mb-3\">{{ $t('garages.details.address') }}</p>\n <p class=\"text-sm text-white\">{{ formattedAddress }}</p>\n </div>\n\n <!-- Billing Address -->\n <div v-if=\"formattedBillingAddress\" class=\"mt-4 pt-4 border-t border-slate-700/50\">\n <p class=\"text-xs text-slate-500 uppercase tracking-wider mb-3\">{{ $t('garages.details.billing_address') }}</p>\n <p class=\"text-sm text-white\">{{ formattedBillingAddress }}</p>\n </div>\n\n <!-- Notification Address -->\n <div v-if=\"formattedNotificationAddress\" class=\"mt-4 pt-4 border-t border-slate-700/50\">\n <p class=\"text-xs text-slate-500 uppercase tracking-wider mb-3\">{{ $t('garages.details.notification_address') }}</p>\n <p class=\"text-sm text-white\">{{ formattedNotificationAddress }}</p>\n </div>\n\n <!-- System IDs Footer -->\n <div class=\"mt-6 pt-4 border-t border-slate-700/50\">\n <p class=\"text-xs text-slate-500 uppercase tracking-wider mb-3\">Rendszer Azonosítók</p>\n <div class=\"flex gap-6 text-xs font-mono text-slate-500\">\n <span>Garázs ID: <span class=\"text-slate-400\">{{ garage.id }}</span></span>\n <span>User ID: <span class=\"text-slate-400\">{{ garage.owner_user_id ?? 'N/A' }}</span></span>\n <span>Person ID: <span class=\"text-slate-400\">{{ garage.owner_person_id ?? 'N/A' }}</span></span>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Contact Info -->\n <div class=\"bg-slate-800/50 border border-slate-700 rounded-xl overflow-hidden\">\n <div class=\"px-6 py-4 border-b border-slate-700 flex items-center gap-3\">\n <div class=\"p-2 rounded-lg bg-emerald-500/10 text-emerald-400\">\n <svg class=\"w-5 h-5\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M17 20h5v-2a3 3 0 00-5.356-1.857M17 20H7m10 0v-2c0-.656-.126-1.283-.356-1.857M7 20H2v-2a3 3 0 015.356-1.857M7 20v-2c0-.656.126-1.283.356-1.857m0 0a5.002 5.002 0 019.288 0M15 7a3 3 0 11-6 0 3 3 0 016 0z\" />\n </svg>\n </div>\n <h3 class=\"text-base font-semibold text-white\">{{ $t('garages.details.contact_info') }}</h3>\n </div>\n <div class=\"px-6 py-5\">\n <!-- Show block if ANY contact data exists (top-level fields or primary_contact) -->\n <div v-if=\"garage.contact_person_name || garage.contact_email || garage.contact_phone || garage.primary_contact\" class=\"grid grid-cols-1 md:grid-cols-2 gap-6\">\n <div class=\"space-y-4\">\n <div>\n <p class=\"text-xs text-slate-500 uppercase tracking-wider\">{{ $t('garages.details.contact_name') }}</p>\n <p class=\"text-sm text-white mt-1 font-medium\">{{ garage.contact_person_name || garage.primary_contact?.full_name || '—' }}</p>\n </div>\n <div>\n <p class=\"text-xs text-slate-500 uppercase tracking-wider\">{{ $t('garages.details.contact_email') }}</p>\n <p class=\"text-sm text-white mt-1 flex items-center gap-1.5\">\n <svg class=\"w-4 h-4 text-slate-400 flex-shrink-0\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M3 8l7.89 5.26a2 2 0 002.22 0L21 8M5 19h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z\" />\n </svg>\n <span>{{ garage.contact_email || garage.primary_contact?.email || '—' }}</span>\n </p>\n </div>\n </div>\n <div class=\"space-y-4\">\n <div>\n <p class=\"text-xs text-slate-500 uppercase tracking-wider\">{{ $t('garages.details.contact_phone') }}</p>\n <p class=\"text-sm text-white mt-1 flex items-center gap-1.5\">\n <svg class=\"w-4 h-4 text-slate-400 flex-shrink-0\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M3 5a2 2 0 012-2h3.28a1 1 0 01.948.684l1.498 4.493a1 1 0 01-.502 1.21l-2.257 1.13a11.042 11.042 0 005.516 5.516l1.13-2.257a1 1 0 011.21-.502l4.493 1.498a1 1 0 01.684.949V19a2 2 0 01-2 2h-1C9.716 21 3 14.284 3 6V5z\" />\n </svg>\n <span>{{ garage.contact_phone || garage.primary_contact?.phone || '—' }}</span>\n </p>\n </div>\n <!-- Extra metadata from primary_contact if available -->\n <div v-if=\"garage.primary_contact?.role || garage.primary_contact?.department\">\n <p class=\"text-xs text-slate-500 uppercase tracking-wider\">{{ $t('garages.details.contact_role') }}</p>\n <p class=\"text-sm text-white mt-1\">{{ garage.primary_contact.role || '—' }}<span v-if=\"garage.primary_contact?.department\"> · {{ garage.primary_contact.department }}</span></p>\n </div>\n </div>\n </div>\n <div v-else class=\"text-center py-4\">\n <p class=\"text-sm text-slate-400\">{{ $t('garages.details.no_contact') }}</p>\n </div>\n </div>\n </div>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed } from 'vue'\n\nconst props = defineProps<{\n garage: any\n}>()\n\nfunction orgTypeLabel(type: string): string {\n const map: Record<string, string> = {\n dealership: 'Dealership',\n service: 'Service Center',\n rental: 'Rental Agency',\n fleet: 'Fleet Operator',\n individual: 'Individual',\n workshop: 'Workshop',\n garage: 'Garage',\n other: 'Other',\n }\n return map[type?.toLowerCase()] || type || '-'\n}\n\nfunction formatDate(dateStr: string | null | undefined): string {\n if (!dateStr) return '-'\n try {\n return new Intl.DateTimeFormat('hu-HU', {\n year: 'numeric',\n month: '2-digit',\n day: '2-digit',\n }).format(new Date(dateStr))\n } catch {\n return dateStr\n }\n}\n\nconst formattedAddress = computed(() => {\n if (!props.garage) return ''\n const parts = [\n props.garage.address_zip,\n props.garage.address_city,\n props.garage.address_street_name,\n props.garage.address_street_type,\n props.garage.address_house_number,\n ].filter(Boolean)\n return parts.join(' ') || '-'\n})\n\nconst formattedBillingAddress = computed(() => {\n if (!props.garage) return ''\n const parts = [\n props.garage.billing_zip,\n props.garage.billing_city,\n props.garage.billing_street_name,\n props.garage.billing_street_type,\n props.garage.billing_house_number,\n ].filter(Boolean)\n return parts.join(' ') || ''\n})\n\nconst formattedNotificationAddress = computed(() => {\n if (!props.garage) return ''\n const parts = [\n props.garage.notification_zip,\n props.garage.notification_city,\n props.garage.notification_street_name,\n props.garage.notification_street_type,\n props.garage.notification_house_number,\n ].filter(Boolean)\n return parts.join(' ') || ''\n})\n</script>\n","<template>\n <div class=\"space-y-6\">\n <!-- RBAC guard: hide content without fleet:view -->\n <template v-if=\"hasOrgPermission('fleet:view')\">\n <div class=\"flex items-center justify-between\">\n <div class=\"flex items-center gap-3\">\n <div class=\"p-2 rounded-lg bg-indigo-500/10 text-indigo-400\">\n <svg class=\"w-5 h-5\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M9 17a2 2 0 11-4 0 2 2 0 014 0zM19 17a2 2 0 11-4 0 2 2 0 014 0z\" />\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M13 16V6a1 1 0 00-1-1H4a1 1 0 00-1 1v10a1 1 0 001 1h1m8-1a1 1 0 01-1 1H9m4-1V8a1 1 0 011-1h2.586a1 1 0 01.707.293l3.414 3.414a1 1 0 01.293.707V16a1 1 0 01-1 1h-1m-6-1a1 1 0 001 1h1M5 17a2 2 0 104 0m-4 0a2 2 0 114 0m6 0a2 2 0 104 0m-4 0a2 2 0 114 0\" />\n </svg>\n </div>\n <div>\n <h3 class=\"text-base font-semibold text-white\">{{ $t('garages.fleet.title') }}</h3>\n <p class=\"text-xs text-slate-400 mt-0.5\">{{ $t('garages.fleet.total_vehicles', { count: fleetVehicles.length }) }}</p>\n </div>\n </div>\n </div>\n\n <div class=\"bg-slate-800/50 border border-slate-700 rounded-xl overflow-hidden\">\n <div class=\"overflow-x-auto\">\n <table class=\"w-full text-sm\">\n <thead>\n <tr class=\"border-b border-slate-700\">\n <th class=\"text-left px-4 py-3 text-xs font-medium text-slate-400 uppercase tracking-wider\">{{ $t('garages.fleet.plate') }}</th>\n <th class=\"text-left px-4 py-3 text-xs font-medium text-slate-400 uppercase tracking-wider\">{{ $t('garages.fleet.brand_model') }}</th>\n <th class=\"text-left px-4 py-3 text-xs font-medium text-slate-400 uppercase tracking-wider\">{{ $t('garages.fleet.year') }}</th>\n <th class=\"text-left px-4 py-3 text-xs font-medium text-slate-400 uppercase tracking-wider\">{{ $t('garages.fleet.vin') }}</th>\n <th class=\"text-left px-4 py-3 text-xs font-medium text-slate-400 uppercase tracking-wider\">{{ $t('garages.fleet.status') }}</th>\n </tr>\n </thead>\n <tbody>\n <tr v-for=\"v in fleetVehicles\" :key=\"v.id\" class=\"border-b border-slate-700/50 last:border-b-0 hover:bg-slate-700/30 transition\">\n <td class=\"px-4 py-3\">\n <span class=\"text-sm font-bold text-white\">{{ v.license_plate || '—' }}</span>\n </td>\n <td class=\"px-4 py-3\">\n <span class=\"text-sm text-slate-300\">{{ v.brand || '—' }}</span>\n <span v-if=\"v.brand && v.model\" class=\"text-slate-500 mx-1\">·</span>\n <span v-if=\"v.model\" class=\"text-sm text-slate-300\">{{ v.model }}</span>\n </td>\n <td class=\"px-4 py-3 text-sm text-slate-300\">{{ v.year || '—' }}</td>\n <td class=\"px-4 py-3\">\n <span class=\"text-xs font-mono text-slate-400\">{{ v.vin || '—' }}</span>\n </td>\n <td class=\"px-4 py-3\">\n <span\n class=\"inline-flex items-center gap-1.5 px-2.5 py-0.5 rounded-full text-xs font-medium\"\n :class=\"fleetStatusBadgeClass(v.status)\"\n >\n <span class=\"w-1.5 h-1.5 rounded-full\" :class=\"fleetStatusDotClass(v.status)\"></span>\n {{ fleetStatusLabel(v.status) }}\n </span>\n </td>\n </tr>\n <tr v-if=\"fleetVehicles.length === 0 && !fleetLoading\">\n <td colspan=\"5\" class=\"px-4 py-12 text-center\">\n <svg class=\"w-12 h-12 text-slate-600 mx-auto mb-4\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"1.5\" d=\"M9 17a2 2 0 11-4 0 2 2 0 014 0zM19 17a2 2 0 11-4 0 2 2 0 014 0z\" />\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"1.5\" d=\"M13 16V6a1 1 0 00-1-1H4a1 1 0 00-1 1v10a1 1 0 001 1h1m8-1a1 1 0 01-1 1H9m4-1V8a1 1 0 011-1h2.586a1 1 0 01.707.293l3.414 3.414a1 1 0 01.293.707V16a1 1 0 01-1 1h-1m-6-1a1 1 0 001 1h1M5 17a2 2 0 104 0m-4 0a2 2 0 114 0m6 0a2 2 0 104 0m-4 0a2 2 0 114 0\" />\n </svg>\n <p class=\"text-sm text-slate-400\">{{ $t('garages.fleet.no_vehicles') }}</p>\n </td>\n </tr>\n <tr v-if=\"fleetLoading\">\n <td colspan=\"5\" class=\"px-4 py-12 text-center\">\n <svg class=\"w-8 h-8 text-indigo-400 animate-spin mx-auto\" fill=\"none\" viewBox=\"0 0 24 24\">\n <circle class=\"opacity-25\" cx=\"12\" cy=\"12\" r=\"10\" stroke=\"currentColor\" stroke-width=\"4\" />\n <path class=\"opacity-75\" fill=\"currentColor\" d=\"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z\" />\n </svg>\n <p class=\"text-sm text-slate-400 mt-2\">{{ $t('garages.details.loading') }}</p>\n </td>\n </tr>\n </tbody>\n </table>\n </div>\n </div>\n </template>\n <!-- RBAC: No fleet access fallback -->\n <template v-else>\n <div class=\"bg-slate-800/50 border border-slate-700 rounded-xl p-12 text-center\">\n <svg class=\"w-12 h-12 text-slate-600 mx-auto mb-4\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"1.5\" d=\"M18.364 18.364A9 9 0 005.636 5.636m12.728 12.728A9 9 0 015.636 5.636m12.728 12.728L5.636 5.636\" />\n </svg>\n <p class=\"text-sm text-slate-400\">{{ $t('garages.fleet.no_fleet_access') }}</p>\n </div>\n </template>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { useAuthStore } from '~/stores/auth'\n\nconst props = defineProps<{\n garage: any\n orgId: string\n fleetVehicles: any[]\n fleetLoading: boolean\n}>()\n\nconst auth = useAuthStore()\n\n// RBAC helper\nfunction hasOrgPermission(perm: string): boolean {\n if (auth.isAdmin) return true\n if (auth.user?.system_capabilities?.[perm]) return true\n if (auth.user?.org_capabilities?.[props.orgId]?.[perm]) return true\n return false\n}\n\nfunction fleetStatusLabel(status: string): string {\n const map: Record<string, string> = {\n active: 'Active',\n inactive: 'Inactive',\n sold: 'Sold',\n scrapped: 'Scrapped',\n pending: 'Pending',\n draft: 'Draft',\n }\n return map[status?.toLowerCase()] || status || 'Unknown'\n}\n\nfunction fleetStatusBadgeClass(status: string): string {\n const map: Record<string, string> = {\n active: 'bg-green-500/10 text-green-400',\n inactive: 'bg-gray-500/10 text-gray-400',\n sold: 'bg-red-500/10 text-red-400',\n scrapped: 'bg-red-500/10 text-red-400',\n pending: 'bg-yellow-500/10 text-yellow-400',\n draft: 'bg-gray-500/10 text-gray-400',\n }\n return map[status?.toLowerCase()] || 'bg-gray-500/10 text-gray-400'\n}\n\nfunction fleetStatusDotClass(status: string): string {\n const map: Record<string, string> = {\n active: 'bg-green-400',\n inactive: 'bg-gray-400',\n sold: 'bg-red-400',\n scrapped: 'bg-red-400',\n pending: 'bg-yellow-400',\n draft: 'bg-gray-400',\n }\n return map[status?.toLowerCase()] || 'bg-gray-400'\n}\n</script>\n","<template>\n <div class=\"space-y-6\">\n <!-- Current Package Card - Densified with Utilization Stats -->\n <div class=\"bg-slate-800/50 border border-slate-700 rounded-xl overflow-hidden\">\n <div class=\"px-6 py-4 border-b border-slate-700 flex items-center gap-3\">\n <div class=\"p-2 rounded-lg bg-amber-500/10 text-amber-400\">\n <svg class=\"w-5 h-5\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M3 7v10a2 2 0 002 2h14a2 2 0 002-2V9a2 2 0 00-2-2h-6l-2-2H5a2 2 0 00-2 2z\" />\n </svg>\n </div>\n <h3 class=\"text-base font-semibold text-white\">{{ $t('garages.details.subscription_info') }}</h3>\n </div>\n <div class=\"px-6 py-5\">\n <div v-if=\"garage.subscription\" class=\"grid grid-cols-2 md:grid-cols-4 gap-4\">\n <!-- Tier Name -->\n <div class=\"bg-slate-900/30 rounded-lg p-3\">\n <p class=\"text-xs text-slate-500 uppercase tracking-wider mb-1\">{{ $t('garages.details.tier_name') }}</p>\n <span class=\"inline-flex px-2.5 py-0.5 rounded-full text-xs font-medium\" :class=\"tierBadgeClass(garage.subscription.tier_name)\">\n {{ garage.subscription.tier_name }}\n </span>\n </div>\n <!-- Tier Level -->\n <div class=\"bg-slate-900/30 rounded-lg p-3\">\n <p class=\"text-xs text-slate-500 uppercase tracking-wider mb-1\">{{ $t('garages.details.tier_level') }}</p>\n <p class=\"text-sm font-semibold text-white\">{{ $t('garages.details.level_n', { n: garage.subscription.tier_level }) }}</p>\n </div>\n <!-- Expiration -->\n <div class=\"bg-slate-900/30 rounded-lg p-3\">\n <p class=\"text-xs text-slate-500 uppercase tracking-wider mb-1\">{{ $t('garages.details.expires_at') }}</p>\n <p v-if=\"garage.subscription.expires_at\" class=\"text-sm font-semibold text-white\">{{ formatDate(garage.subscription.expires_at) }}</p>\n <p v-else class=\"text-sm text-slate-400 italic\">{{ $t('garages.indefinite') }}</p>\n </div>\n <!-- Asset Limit -->\n <div class=\"bg-slate-900/30 rounded-lg p-3\">\n <p class=\"text-xs text-slate-500 uppercase tracking-wider mb-1\">{{ $t('garages.details.asset_limit') }}</p>\n <p class=\"text-sm font-semibold text-white\">{{ garage.subscription.asset_limit }} {{ $t('garages.details.vehicles') }}</p>\n </div>\n </div>\n <!-- Utilization Stats Row -->\n <div v-if=\"garage.subscription\" class=\"mt-4 grid grid-cols-2 gap-4\">\n <!-- Vehicles Utilization -->\n <div class=\"bg-slate-900/30 rounded-lg p-3\">\n <p class=\"text-xs text-slate-500 uppercase tracking-wider mb-1\">{{ $t('garages.details.vehicles_used') }}</p>\n <p class=\"text-sm font-semibold text-white\">\n {{ fleetVehicles.length }} / {{ garage.subscription?.asset_limit ?? '∞' }}\n </p>\n <div class=\"mt-2 w-full h-1.5 bg-slate-700 rounded-full overflow-hidden\">\n <div\n class=\"h-full rounded-full transition-all duration-500\"\n :class=\"vehicleQuotaPercent >= 90 ? 'bg-red-500' : vehicleQuotaPercent >= 70 ? 'bg-amber-500' : 'bg-blue-500'\"\n :style=\"{ width: Math.min(100, vehicleQuotaPercent) + '%' }\"\n ></div>\n </div>\n </div>\n <!-- Branches Utilization -->\n <div class=\"bg-slate-900/30 rounded-lg p-3\">\n <p class=\"text-xs text-slate-500 uppercase tracking-wider mb-1\">{{ $t('garages.details.branches_used') }}</p>\n <p class=\"text-sm font-semibold text-white\">\n {{ garage.branches?.length || 0 }} / {{ garage.subscription?.branch_limit ?? '∞' }}\n </p>\n <div class=\"mt-2 w-full h-1.5 bg-slate-700 rounded-full overflow-hidden\">\n <div\n class=\"h-full rounded-full transition-all duration-500\"\n :class=\"branchQuotaPercent >= 90 ? 'bg-red-500' : branchQuotaPercent >= 70 ? 'bg-amber-500' : 'bg-emerald-500'\"\n :style=\"{ width: Math.min(100, branchQuotaPercent) + '%' }\"\n ></div>\n </div>\n </div>\n <!-- Employees Count (P0 ADD-ON: Now with user_limit bar) -->\n <div class=\"bg-slate-900/30 rounded-lg p-3\">\n <p class=\"text-xs text-slate-500 uppercase tracking-wider mb-1\">{{ $t('garages.details.employees_used') }}</p>\n <p class=\"text-sm font-semibold text-white\">\n {{ garage.member_count || 0 }} / {{ (garage.subscription?.user_limit && garage.subscription.user_limit > 0) ? garage.subscription.user_limit : '∞' }}\n </p>\n <div v-if=\"garage.subscription?.user_limit && garage.subscription.user_limit > 0\" class=\"mt-2 w-full h-1.5 bg-slate-700 rounded-full overflow-hidden\">\n <div\n class=\"h-full rounded-full transition-all duration-500\"\n :class=\"employeeQuotaPercent >= 90 ? 'bg-red-500' : employeeQuotaPercent >= 70 ? 'bg-amber-500' : 'bg-purple-500'\"\n :style=\"{ width: Math.min(100, employeeQuotaPercent) + '%' }\"\n ></div>\n </div>\n </div>\n <!-- Status Badge -->\n <div class=\"bg-slate-900/30 rounded-lg p-3 flex flex-col justify-center\">\n <p class=\"text-xs text-slate-500 uppercase tracking-wider mb-1\">{{ $t('garages.details.status') }}</p>\n <span\n class=\"inline-flex items-center gap-1.5 px-2.5 py-1 rounded-full text-xs font-medium self-start\"\n :class=\"statusBadgeClass(garage.status)\"\n >\n <span class=\"w-1.5 h-1.5 rounded-full\" :class=\"statusDotClass(garage.status)\"></span>\n {{ statusLabel(garage.status) }}\n </span>\n </div>\n </div>\n <!-- P0 UI/UX: Active Add-ons section inside the Subscription Status card -->\n <div v-if=\"garage.subscription?.addons?.length\" class=\"mt-4 border-t border-slate-700/50 pt-4\">\n <p class=\"text-xs text-slate-500 uppercase tracking-wider mb-3\">{{ $t('garages.active_addons') }}</p>\n <div class=\"overflow-hidden border border-slate-700/50 rounded-lg\">\n <table class=\"w-full text-sm\">\n <thead>\n <tr class=\"bg-slate-900/40\">\n <th class=\"px-3 py-2 text-left text-xs font-medium text-slate-400 uppercase tracking-wider\">{{ $t('garages.addon_type') }}</th>\n <th class=\"px-3 py-2 text-center text-xs font-medium text-slate-400 uppercase tracking-wider\">{{ $t('garages.addon_quantity') }}</th>\n <th class=\"px-3 py-2 text-right text-xs font-medium text-slate-400 uppercase tracking-wider\">{{ $t('garages.addon_expires') }}</th>\n </tr>\n </thead>\n <tbody class=\"divide-y divide-slate-700/50\">\n <tr v-for=\"addon in garage.subscription.addons\" :key=\"addon.type\" class=\"bg-slate-900/20 hover:bg-slate-900/40 transition\">\n <td class=\"px-3 py-2.5 text-slate-300\">{{ addonLabel(addon.type) }}</td>\n <td class=\"px-3 py-2.5 text-center\">\n <span class=\"inline-flex items-center justify-center w-7 h-7 rounded-full bg-indigo-500/20 text-indigo-300 text-xs font-bold\">{{ addon.quantity }}</span>\n </td>\n <td class=\"px-3 py-2.5 text-right text-slate-500\">\n <span v-if=\"addon.expires_at || addon.valid_until\">{{ formatDate(addon.expires_at || addon.valid_until) }}</span>\n <span v-else class=\"italic\">{{ $t('garages.indefinite') }}</span>\n </td>\n </tr>\n </tbody>\n </table>\n </div>\n </div>\n <div v-else-if=\"garage.subscription\" class=\"mt-4 border-t border-slate-700/50 pt-4\">\n <p class=\"text-xs text-slate-500 uppercase tracking-wider mb-1\">{{ $t('garages.active_addons') }}</p>\n <div class=\"bg-slate-900/20 border border-slate-700/30 rounded-lg px-4 py-3 text-center\">\n <p class=\"text-xs text-slate-500 italic\">{{ $t('garages.no_active_addons') }}</p>\n </div>\n </div>\n <div v-else class=\"text-center py-4\">\n <p class=\"text-sm text-slate-400\">{{ $t('garages.details.no_subscription') }}</p>\n </div>\n </div>\n </div>\n\n <!-- Change Package Section -->\n <div class=\"bg-slate-800/50 border border-slate-700 rounded-xl overflow-hidden\">\n <div class=\"px-6 py-4 border-b border-slate-700 flex items-center gap-3\">\n <div class=\"p-2 rounded-lg bg-indigo-500/10 text-indigo-400\">\n <svg class=\"w-5 h-5\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15\" />\n </svg>\n </div>\n <h3 class=\"text-base font-semibold text-white\">{{ $t('garages.change_package') }}</h3>\n </div>\n <div class=\"px-6 py-5 space-y-5\">\n <!-- Tier Selection -->\n <div>\n <label class=\"block text-sm font-medium text-slate-300 mb-2\">{{ $t('garages.select_package') }}</label>\n <select\n v-model=\"selectedTierId\"\n class=\"w-full px-3 py-2.5 bg-slate-900 border border-slate-700 rounded-lg text-sm text-white focus:outline-none focus:ring-2 focus:ring-indigo-500/50 transition\"\n >\n <option value=\"\" disabled>{{ $t('garages.select_package_placeholder') }}</option>\n <option\n v-for=\"tier in availableTiers\"\n :key=\"tier.id\"\n :value=\"tier.id\"\n >\n {{ tier.name }} (Level {{ tier.tier_level }})\n </option>\n </select>\n </div>\n\n <!-- Custom Expiration Date -->\n <div>\n <label class=\"block text-sm font-medium text-slate-300 mb-2\">\n {{ $t('garages.custom_expiration') }}\n <span class=\"text-xs text-slate-500 ml-1\">({{ $t('garages.optional') }})</span>\n </label>\n <input\n v-model=\"customExpiresAt\"\n type=\"date\"\n class=\"w-full px-3 py-2.5 bg-slate-900 border border-slate-700 rounded-lg text-sm text-white focus:outline-none focus:ring-2 focus:ring-indigo-500/50 transition\"\n />\n <p class=\"text-xs text-slate-500 mt-1.5\">{{ $t('garages.custom_expiration_hint') }}</p>\n </div>\n\n <!-- ── P0 ITEMIZED ADD-ON: Add-on editor with individual date pickers ── -->\n <div>\n <label class=\"block text-sm font-medium text-slate-300 mb-3\">\n {{ $t('garages.addons_title') }}\n <span class=\"text-xs text-slate-500 ml-1\">({{ $t('garages.optional') }})</span>\n </label>\n\n <!-- Add-on editor: number inputs with +/- buttons and individual date pickers -->\n <div class=\"grid grid-cols-1 md:grid-cols-3 gap-3\">\n <!-- Extra Vehicles -->\n <div class=\"bg-slate-900/30 border border-slate-700/50 rounded-lg p-3\">\n <label class=\"block text-xs text-slate-400 mb-1.5\">{{ $t('garages.addon_vehicles') }}</label>\n <div class=\"flex items-center gap-2\">\n <button\n @click=\"extraVehicles = Math.max(0, extraVehicles - 1)\"\n class=\"w-8 h-8 rounded-lg bg-slate-800 hover:bg-slate-700 text-slate-300 flex items-center justify-center transition text-sm font-bold\"\n ></button>\n <input\n v-model.number=\"extraVehicles\"\n type=\"number\"\n min=\"0\"\n max=\"999\"\n class=\"w-full px-2 py-1.5 bg-slate-900 border border-slate-700 rounded-lg text-sm text-white text-center focus:outline-none focus:ring-2 focus:ring-indigo-500/50 transition [appearance:textfield] [&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none\"\n />\n <button\n @click=\"extraVehicles = Math.min(999, extraVehicles + 1)\"\n class=\"w-8 h-8 rounded-lg bg-slate-800 hover:bg-slate-700 text-slate-300 flex items-center justify-center transition text-sm font-bold\"\n >+</button>\n </div>\n <label class=\"block text-xs text-slate-500 mt-2 mb-1\">{{ $t('garages.addon_vehicles_expiration') }}</label>\n <input\n v-model=\"addonDates.vehicles\"\n type=\"date\"\n class=\"w-full px-3 py-2 bg-slate-900 border border-slate-700 rounded-lg text-sm text-white focus:outline-none focus:ring-2 focus:ring-indigo-500/50 transition\"\n />\n </div>\n <!-- Extra Branches -->\n <div class=\"bg-slate-900/30 border border-slate-700/50 rounded-lg p-3\">\n <label class=\"block text-xs text-slate-400 mb-1.5\">{{ $t('garages.addon_branches') }}</label>\n <div class=\"flex items-center gap-2\">\n <button\n @click=\"extraBranches = Math.max(0, extraBranches - 1)\"\n class=\"w-8 h-8 rounded-lg bg-slate-800 hover:bg-slate-700 text-slate-300 flex items-center justify-center transition text-sm font-bold\"\n ></button>\n <input\n v-model.number=\"extraBranches\"\n type=\"number\"\n min=\"0\"\n max=\"999\"\n class=\"w-full px-2 py-1.5 bg-slate-900 border border-slate-700 rounded-lg text-sm text-white text-center focus:outline-none focus:ring-2 focus:ring-indigo-500/50 transition [appearance:textfield] [&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none\"\n />\n <button\n @click=\"extraBranches = Math.min(999, extraBranches + 1)\"\n class=\"w-8 h-8 rounded-lg bg-slate-800 hover:bg-slate-700 text-slate-300 flex items-center justify-center transition text-sm font-bold\"\n >+</button>\n </div>\n <label class=\"block text-xs text-slate-500 mt-2 mb-1\">{{ $t('garages.addon_branches_expiration') }}</label>\n <input\n v-model=\"addonDates.branches\"\n type=\"date\"\n class=\"w-full px-3 py-2 bg-slate-900 border border-slate-700 rounded-lg text-sm text-white focus:outline-none focus:ring-2 focus:ring-indigo-500/50 transition\"\n />\n </div>\n <!-- Extra Users -->\n <div class=\"bg-slate-900/30 border border-slate-700/50 rounded-lg p-3\">\n <label class=\"block text-xs text-slate-400 mb-1.5\">{{ $t('garages.addon_users') }}</label>\n <div class=\"flex items-center gap-2\">\n <button\n @click=\"extraUsers = Math.max(0, extraUsers - 1)\"\n class=\"w-8 h-8 rounded-lg bg-slate-800 hover:bg-slate-700 text-slate-300 flex items-center justify-center transition text-sm font-bold\"\n ></button>\n <input\n v-model.number=\"extraUsers\"\n type=\"number\"\n min=\"0\"\n max=\"999\"\n class=\"w-full px-2 py-1.5 bg-slate-900 border border-slate-700 rounded-lg text-sm text-white text-center focus:outline-none focus:ring-2 focus:ring-indigo-500/50 transition [appearance:textfield] [&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none\"\n />\n <button\n @click=\"extraUsers = Math.min(999, extraUsers + 1)\"\n class=\"w-8 h-8 rounded-lg bg-slate-800 hover:bg-slate-700 text-slate-300 flex items-center justify-center transition text-sm font-bold\"\n >+</button>\n </div>\n <label class=\"block text-xs text-slate-500 mt-2 mb-1\">{{ $t('garages.addon_users_expiration') }}</label>\n <input\n v-model=\"addonDates.users\"\n type=\"date\"\n class=\"w-full px-3 py-2 bg-slate-900 border border-slate-700 rounded-lg text-sm text-white focus:outline-none focus:ring-2 focus:ring-indigo-500/50 transition\"\n />\n </div>\n </div>\n\n <p class=\"text-xs text-slate-500 mt-3\">{{ $t('garages.addon_expiration_hint') }}</p>\n </div>\n\n <!-- Save Error -->\n <div\n v-if=\"subscriptionSaveError\"\n class=\"bg-red-500/10 border border-red-500/20 rounded-lg px-4 py-3\"\n >\n <p class=\"text-sm text-red-400\">{{ subscriptionSaveError }}</p>\n </div>\n\n <!-- Save Button -->\n <div class=\"flex items-center justify-end gap-3 pt-2\">\n <button\n @click=\"updateSubscription\"\n :disabled=\"subscriptionSaving || (!selectedTierId && !addonsChanged)\"\n class=\"px-5 py-2 text-sm font-medium rounded-lg transition disabled:opacity-50 disabled:cursor-not-allowed\"\n :class=\"subscriptionSaving\n ? 'bg-indigo-600/50 text-indigo-200 cursor-wait'\n : 'bg-indigo-600 text-white hover:bg-indigo-500'\"\n >\n <span v-if=\"subscriptionSaving\" class=\"flex items-center gap-2\">\n <svg class=\"w-4 h-4 animate-spin\" fill=\"none\" viewBox=\"0 0 24 24\">\n <circle class=\"opacity-25\" cx=\"12\" cy=\"12\" r=\"10\" stroke=\"currentColor\" stroke-width=\"4\" />\n <path class=\"opacity-75\" fill=\"currentColor\" d=\"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z\" />\n </svg>\n {{ $t('garages.saving') }}\n </span>\n <span v-else>{{ $t('garages.save') }}</span>\n </button>\n </div>\n </div>\n </div>\n\n <!-- Subscription History Section -->\n <div class=\"bg-slate-800/50 border border-slate-700 rounded-xl overflow-hidden\">\n <div class=\"px-6 py-4 border-b border-slate-700 flex items-center gap-3\">\n <div class=\"p-2 rounded-lg bg-cyan-500/10 text-cyan-400\">\n <svg class=\"w-5 h-5\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z\" />\n </svg>\n </div>\n <h3 class=\"text-base font-semibold text-white\">{{ $t('garages.details.subscription_history') }}</h3>\n </div>\n <div class=\"px-6 py-5\">\n <div class=\"overflow-x-auto\">\n <table class=\"w-full text-sm\">\n <thead>\n <tr class=\"border-b border-slate-700\">\n <th class=\"text-left px-4 py-3 text-xs font-medium text-slate-400 uppercase tracking-wider\">{{ $t('garages.details.history_date') }}</th>\n <th class=\"text-left px-4 py-3 text-xs font-medium text-slate-400 uppercase tracking-wider\">{{ $t('garages.details.history_package') }}</th>\n <th class=\"text-left px-4 py-3 text-xs font-medium text-slate-400 uppercase tracking-wider\">{{ $t('garages.details.history_action') }}</th>\n <th class=\"text-left px-4 py-3 text-xs font-medium text-slate-400 uppercase tracking-wider\">{{ $t('garages.details.history_status') }}</th>\n </tr>\n </thead>\n <tbody>\n <template v-if=\"garage?.subscription_history?.length\">\n <tr v-for=\"hist in garage.subscription_history\" :key=\"hist.id\" class=\"border-b border-slate-700/50 last:border-b-0 hover:bg-slate-700/30 transition\">\n <td class=\"px-4 py-3 text-sm text-slate-300\">\n {{ formatDate(hist.timestamp) }}\n </td>\n <td class=\"px-4 py-3 text-sm text-slate-300\">\n {{ hist.tier_name || '—' }}\n </td>\n <td class=\"px-4 py-3 text-sm text-slate-300 max-w-xs\">\n <!-- P0 AUDIT DETAILS: Show parsed data diff instead of generic changes_summary -->\n <div class=\"space-y-1\">\n <span class=\"text-xs text-slate-400 block\">{{ hist.action || '—' }}</span>\n <div v-if=\"formatChanges(hist)\" class=\"text-xs text-slate-300 space-y-0.5\">\n <div v-for=\"(line, li) in formatChanges(hist)\" :key=\"li\" class=\"flex items-start gap-1\">\n <span class=\"text-cyan-400 shrink-0\"></span>\n <span>{{ line }}</span>\n </div>\n </div>\n <span v-else class=\"text-xs text-slate-500 italic\">Nincs részletes adat</span>\n </div>\n </td>\n <td class=\"px-4 py-3\">\n <div class=\"flex flex-col gap-1\">\n <span\n class=\"inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-green-500/10 text-green-400\"\n >\n Sikeres\n </span>\n <!-- P0 AUDIT DETAILS: Show admin_user_id -->\n <span v-if=\"hist.admin_user_id\" class=\"text-[10px] text-slate-500 text-center\">\n Admin #{{ hist.admin_user_id }}\n </span>\n </div>\n </td>\n </tr>\n </template>\n <template v-else>\n <tr>\n <td colspan=\"4\" class=\"px-4 py-12 text-center\">\n <div class=\"flex flex-col items-center gap-3\">\n <svg class=\"w-10 h-10 text-slate-600\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"1.5\" d=\"M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z\" />\n </svg>\n <p class=\"text-sm text-slate-400\">{{ $t('garages.details.no_subscription_history') }}</p>\n </div>\n </td>\n </tr>\n </template>\n </tbody>\n </table>\n </div>\n </div>\n </div>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { ref, reactive, computed, onMounted, watch } from 'vue'\nimport { useAuthStore } from '~/stores/auth'\n\nconst props = defineProps<{\n garage: any\n fleetVehicles: any[]\n}>()\n\nconst emit = defineEmits<{\n refresh: []\n}>()\n\nconst auth = useAuthStore()\n\n// ── Subscription tab state ──\nconst availableTiers = ref<any[]>([])\n\n// ── Fetch tiers on mount so the dropdown is populated ──\nonMounted(() => {\n fetchTiers()\n})\nconst selectedTierId = ref<number | ''>('')\nconst customExpiresAt = ref('')\nconst subscriptionSaving = ref(false)\nconst subscriptionSaveError = ref<string | null>(null)\n\n// ── P0 CRITICAL FIX: Initialize add-on refs from existing subscription data ──\n// Previously these were hardcoded to 0, which caused existing add-ons to be\n// deleted on save (the frontend sent 0 for all add-on types, overwriting them).\nconst extraVehicles = ref(0)\nconst extraBranches = ref(0)\nconst extraUsers = ref(0)\nconst addonDates = reactive({\n vehicles: '',\n branches: '',\n users: '',\n})\n\n// ── P0 CRITICAL FIX: Sync add-on refs when garage subscription data loads ──\n// This ensures the form inputs reflect the ACTUAL stored values, not zero.\nfunction syncAddonFromSubscription() {\n const sub = props.garage?.subscription\n if (!sub) return\n const allowances = sub.extra_allowances || {}\n extraVehicles.value = allowances.extra_vehicles ?? 0\n extraBranches.value = allowances.extra_branches ?? 0\n extraUsers.value = allowances.extra_users ?? 0\n // Also sync add-on dates from the addons array if available\n if (sub.addons?.length) {\n for (const addon of sub.addons) {\n if (addon.type === 'extra_vehicles' && addon.expires_at) {\n addonDates.vehicles = addon.expires_at.slice(0, 10)\n } else if (addon.type === 'extra_branches' && addon.expires_at) {\n addonDates.branches = addon.expires_at.slice(0, 10)\n } else if (addon.type === 'extra_users' && addon.expires_at) {\n addonDates.users = addon.expires_at.slice(0, 10)\n }\n }\n }\n}\n\n// Watch for garage subscription changes and sync add-on values\nwatch(() => props.garage?.subscription, (newSub) => {\n if (newSub) {\n syncAddonFromSubscription()\n }\n}, { immediate: true })\n\n// ── Computed ──\nconst vehicleQuotaLimit = computed(() => {\n if (!props.garage?.subscription?.asset_limit) return 5\n return props.garage.subscription.asset_limit\n})\n\nconst vehicleQuotaPercent = computed(() => {\n const limit = vehicleQuotaLimit.value\n if (limit <= 0) return 0\n return Math.min(100, Math.round((props.fleetVehicles.length / limit) * 100))\n})\n\nconst branchQuotaPercent = computed(() => {\n const branches = props.garage?.branches?.length || 0\n const limit = props.garage?.subscription?.branch_limit\n if (!limit || limit <= 0) return 0\n return Math.min(100, Math.round((branches / limit) * 100))\n})\n\nconst employeeQuotaPercent = computed(() => {\n const count = props.garage?.member_count || 0\n const limit = props.garage?.subscription?.user_limit\n if (!limit || limit <= 0) return 0\n return Math.min(100, Math.round((count / limit) * 100))\n})\n\nconst addonsChanged = computed(() => {\n if (!props.garage?.subscription) return false\n const sub = props.garage.subscription\n const baselineVehicles = sub.extra_allowances?.extra_vehicles ?? 0\n const baselineBranches = sub.extra_allowances?.extra_branches ?? 0\n const baselineUsers = sub.extra_allowances?.extra_users ?? 0\n return (\n extraVehicles.value !== baselineVehicles ||\n extraBranches.value !== baselineBranches ||\n extraUsers.value !== baselineUsers\n )\n})\n\n// ── P0 AUDIT DETAILS: Parse old_data/new_data into human-readable diff lines ──\nfunction formatChanges(hist: any): string[] | null {\n if (!hist) return null\n const oldData = hist.old_data || {}\n const newData = hist.new_data || {}\n const lines: string[] = []\n\n // SUBSCRIPTION_TIER_CHANGE: Show tier_id change\n if (hist.action === 'SUBSCRIPTION_TIER_CHANGE') {\n const oldTier = oldData.tier_id\n const newTier = newData.tier_id\n const newTierName = newData.tier_name\n if (oldTier !== undefined || newTier !== undefined) {\n lines.push(`Csomag: #${oldTier ?? '?'} → ${newTierName ?? '#' + newTier}`)\n }\n // Show addon changes within tier change\n const oldAddons = oldData.addons || {}\n const newAddons = newData.addons || {}\n for (const key of ['extra_vehicles', 'extra_branches', 'extra_users']) {\n const oldVal = oldAddons[key] ?? 0\n const newVal = newAddons[key] ?? 0\n if (oldVal !== newVal) {\n const label = key === 'extra_vehicles' ? 'Extra Jármű'\n : key === 'extra_branches' ? 'Extra Telephely'\n : 'Extra Dolgozó'\n lines.push(`${label}: ${oldVal} → ${newVal}`)\n }\n }\n return lines.length > 0 ? lines : null\n }\n\n // SUBSCRIPTION_ADDON_OVERRIDE: Show individual add-on changes\n if (hist.action === 'SUBSCRIPTION_ADDON_OVERRIDE') {\n const oldAddons = oldData.addons || {}\n const newAddons = newData.addons || {}\n let hasChanges = false\n for (const key of ['extra_vehicles', 'extra_branches', 'extra_users']) {\n const oldVal = oldAddons[key] ?? 0\n const newVal = newAddons[key] ?? 0\n if (oldVal !== newVal) {\n hasChanges = true\n const label = key === 'extra_vehicles' ? 'Extra Jármű'\n : key === 'extra_branches' ? 'Extra Telephely'\n : 'Extra Dolgozó'\n lines.push(`${label}: ${oldVal} → ${newVal}`)\n }\n }\n return hasChanges ? lines : null\n }\n\n // Generic fallback: show any differing keys between old_data and new_data\n const allKeys = new Set([...Object.keys(oldData), ...Object.keys(newData)])\n for (const key of allKeys) {\n if (key === 'addons') continue // already handled above\n const oldVal = JSON.stringify(oldData[key] ?? null)\n const newVal = JSON.stringify(newData[key] ?? null)\n if (oldVal !== newVal) {\n lines.push(`${key}: ${oldVal} → ${newVal}`)\n }\n }\n\n return lines.length > 0 ? lines : null\n}\n\n// ── Helpers ──\nfunction formatDate(dateStr: string | null | undefined): string {\n if (!dateStr) return '-'\n try {\n return new Intl.DateTimeFormat('hu-HU', {\n year: 'numeric',\n month: '2-digit',\n day: '2-digit',\n }).format(new Date(dateStr))\n } catch {\n return dateStr\n }\n}\n\nfunction addonLabel(type: string): string {\n const map: Record<string, string> = {\n extra_vehicles: 'Extra Jármű',\n extra_branches: 'Extra Telephely',\n extra_users: 'Extra Dolgozó',\n }\n return map[type] || type\n}\n\nfunction tierBadgeClass(tier: string | null | undefined): string {\n const map: Record<string, string> = {\n basic: 'bg-gray-100 text-gray-800',\n premium: 'bg-yellow-100 text-yellow-800',\n enterprise: 'bg-purple-100 text-purple-800',\n trial: 'bg-blue-100 text-blue-800',\n }\n return map[tier?.toLowerCase()] || 'bg-gray-100 text-gray-800'\n}\n\nfunction statusLabel(status: string): string {\n const map: Record<string, string> = {\n active: 'Active',\n inactive: 'Inactive',\n suspended: 'Suspended',\n pending: 'Pending',\n }\n return map[status?.toLowerCase()] || status\n}\n\nfunction statusBadgeClass(status: string): string {\n const map: Record<string, string> = {\n active: 'bg-green-100 text-green-800',\n inactive: 'bg-gray-100 text-gray-800',\n suspended: 'bg-red-100 text-red-800',\n pending: 'bg-yellow-100 text-yellow-800',\n }\n return map[status?.toLowerCase()] || 'bg-gray-100 text-gray-800'\n}\n\nfunction statusDotClass(status: string): string {\n const map: Record<string, string> = {\n active: 'bg-green-400',\n inactive: 'bg-gray-400',\n suspended: 'bg-red-400',\n pending: 'bg-yellow-400',\n }\n return map[status?.toLowerCase()] || 'bg-gray-400'\n}\n\n// ── Subscription Tab Functions ──\n\nasync function fetchTiers() {\n try {\n const tokenCookie = useCookie('access_token')\n const token = (tokenCookie.value || auth.token || '').trim()\n console.log('[GarageSubscriptionTab] Fetching tiers...')\n const res = await fetch('/api/v1/admin/packages?include_hidden=true&limit=100', {\n headers: {\n 'Authorization': `Bearer ${token}`,\n 'Content-Type': 'application/json',\n },\n })\n if (!res.ok) {\n const errBody = await res.text().catch(() => '')\n console.error(`[GarageSubscriptionTab] Fetch tiers failed: ${res.status} ${res.statusText}`, errBody)\n throw new Error(`Failed to fetch tiers: ${res.status} ${errBody}`)\n }\n const data = await res.json()\n console.log('[GarageSubscriptionTab] Fetched tiers response:', JSON.stringify(data))\n availableTiers.value = data.tiers || []\n console.log('[GarageSubscriptionTab] availableTiers set:', availableTiers.value.length, 'items')\n } catch (e: any) {\n console.error('[GarageSubscriptionTab] Failed to fetch tiers:', e)\n subscriptionSaveError.value = `Hiba a csomagok betöltésekor: ${e.message}`\n }\n}\n\nasync function updateSubscription() {\n if (!selectedTierId.value && !addonsChanged.value) return\n\n subscriptionSaving.value = true\n subscriptionSaveError.value = null\n\n try {\n const tokenCookie = useCookie('access_token')\n const token = (tokenCookie.value || auth.token || '').trim()\n const orgId = props.garage?.id\n\n const payload: Record<string, unknown> = {}\n\n if (selectedTierId.value) {\n payload.tier_id = selectedTierId.value\n }\n\n if (customExpiresAt.value) {\n payload.expires_at = new Date(customExpiresAt.value).toISOString()\n }\n\n payload.extra_vehicles = extraVehicles.value\n payload.extra_branches = extraBranches.value\n payload.extra_users = extraUsers.value\n\n // P0 ITEMIZED ADD-ON: Send individual expiration dates per add-on type\n payload.extra_vehicles_expires_at = addonDates.vehicles || null\n payload.extra_branches_expires_at = addonDates.branches || null\n payload.extra_users_expires_at = addonDates.users || null\n\n // ── P0 DEBUG: Log the exact payload being sent to the backend ──\n console.log('[GarageSubscriptionTab] PATCH Payload:', JSON.stringify(payload, null, 2))\n\n const res = await fetch(`/api/v1/admin/organizations/${orgId}/subscription`, {\n method: 'PATCH',\n headers: {\n 'Authorization': `Bearer ${token}`,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(payload),\n })\n\n if (!res.ok) {\n const errData = await res.json().catch(() => ({}))\n throw new Error(errData.detail || `Update subscription failed: ${res.status}`)\n }\n\n // Reset form state\n selectedTierId.value = ''\n emit('refresh')\n } catch (e: any) {\n subscriptionSaveError.value = e.message || 'Failed to update subscription'\n } finally {\n subscriptionSaving.value = false\n }\n}\n\n// Expose fetchTiers so the parent can call it on tab activation\ndefineExpose({ fetchTiers })\n</script>\n","<template>\n <div>\n <!-- Loading State -->\n <div v-if=\"loading\" class=\"flex items-center justify-center py-20\">\n <div class=\"flex flex-col items-center gap-3\">\n <svg class=\"w-8 h-8 text-indigo-400 animate-spin\" fill=\"none\" viewBox=\"0 0 24 24\">\n <circle class=\"opacity-25\" cx=\"12\" cy=\"12\" r=\"10\" stroke=\"currentColor\" stroke-width=\"4\" />\n <path class=\"opacity-75\" fill=\"currentColor\" d=\"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z\" />\n </svg>\n <p class=\"text-slate-400 text-sm\">{{ $t('garages.details.loading') }}</p>\n </div>\n </div>\n\n <!-- Error State -->\n <div v-else-if=\"error\" class=\"flex flex-col items-center justify-center py-20 text-center\">\n <svg class=\"w-12 h-12 text-red-500 mb-4\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"1.5\" d=\"M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-2.5L13.732 4c-.77-.833-1.964-.833-2.732 0L4.082 16.5c-.77.833.192 2.5 1.732 2.5z\" />\n </svg>\n <p class=\"text-red-400 text-sm mb-2\">{{ error }}</p>\n <button @click=\"fetchDetails\" class=\"px-4 py-2 text-sm bg-indigo-600/20 text-indigo-300 hover:bg-indigo-600/30 rounded-lg transition\">\n {{ $t('garages.details.retry') }}\n </button>\n </div>\n\n <!-- Content -->\n <template v-else-if=\"garage\">\n <!-- Missing Data Alerter -->\n <div\n v-if=\"missingFields.length > 0\"\n class=\"mb-6 p-4 bg-amber-500/10 border border-amber-500/30 rounded-xl\"\n >\n <div class=\"flex items-start gap-3\">\n <div class=\"p-1.5 rounded-lg bg-amber-500/20 text-amber-400 flex-shrink-0\">\n <svg class=\"w-5 h-5\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-2.5L13.732 4c-.77-.833-1.964-.833-2.732 0L4.082 16.5c-.77.833.192 2.5 1.732 2.5z\" />\n </svg>\n </div>\n <div class=\"flex-1 min-w-0\">\n <div class=\"flex items-center justify-between\">\n <p class=\"text-sm font-semibold text-amber-300\">{{ $t('garages.details.missing_data_title') }}</p>\n <span class=\"text-xs text-amber-400/70\">{{ $t('garages.details.missing_data_count', { count: missingFields.length }) }}</span>\n </div>\n <p class=\"text-xs text-amber-400/80 mt-1\">\n {{ garage.status !== 'active' ? $t('garages.details.missing_data_activation_required') : $t('garages.details.missing_data_desc') }}\n </p>\n <div class=\"flex flex-wrap gap-2 mt-3\">\n <span\n v-for=\"field in missingFields\"\n :key=\"field.key\"\n class=\"inline-flex items-center gap-1 px-2.5 py-1 rounded-md text-xs font-medium bg-amber-500/10 text-amber-300\"\n >\n <svg class=\"w-3 h-3\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M6 18L18 6M6 6l12 12\" />\n </svg>\n {{ $t(field.label) }}\n </span>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Header -->\n <div class=\"mb-8\">\n <button\n @click=\"goBack\"\n class=\"inline-flex items-center gap-1.5 text-sm text-slate-400 hover:text-white transition mb-4\"\n >\n <svg class=\"w-4 h-4\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M15 19l-7-7 7-7\" />\n </svg>\n {{ $t('garages.details.back') }}\n </button>\n\n <div class=\"flex items-center justify-between\">\n <div class=\"flex items-center gap-4\">\n <div\n class=\"w-12 h-12 rounded-xl flex items-center justify-center text-lg font-bold text-white\"\n :class=\"getInitialsColor(garageDisplayName())\"\n >\n {{ getInitials(garageDisplayName()) }}\n </div>\n <div>\n <div class=\"flex items-center gap-3\">\n <h1 class=\"text-2xl font-bold text-white\">{{ cleanGarageName }}</h1>\n <span\n class=\"inline-flex items-center px-3 py-1 rounded-full text-xs font-medium\"\n :class=\"statusBadgeClass(garage.status)\"\n >\n <span class=\"w-1.5 h-1.5 rounded-full mr-1.5\" :class=\"statusDotClass(garage.status)\"></span>\n {{ statusLabel(garage.status) }}\n </span>\n </div>\n <p class=\"text-sm text-slate-400 mt-0.5\">\n {{ garage.full_name }}\n <span v-if=\"garage.tax_number\" class=\"ml-2 text-slate-500\">· {{ $t('garages.details.tax_number') }}: {{ garage.tax_number }}</span>\n </p>\n </div>\n </div>\n <div class=\"flex items-center gap-3\">\n <button\n v-if=\"hasOrgPermission('org:edit')\"\n @click=\"openEditModal\"\n class=\"inline-flex items-center gap-1.5 px-4 py-2 text-sm font-medium bg-indigo-600/20 text-indigo-300 hover:bg-indigo-600/30 rounded-lg transition\"\n >\n <svg class=\"w-4 h-4\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z\" />\n </svg>\n {{ $t('garages.details.edit_details') }}\n </button>\n </div>\n </div>\n </div>\n\n <!-- Tab Navigation -->\n <div class=\"border-b border-slate-700 mb-6\">\n <nav class=\"flex gap-6\">\n <button\n v-for=\"tab in tabs\"\n :key=\"tab.key\"\n @click=\"activeTab = tab.key\"\n class=\"pb-3 text-sm font-medium transition border-b-2 -mb-px\"\n :class=\"activeTab === tab.key\n ? 'text-indigo-400 border-indigo-400'\n : 'text-slate-400 border-transparent hover:text-slate-300'\"\n >\n {{ $t(tab.label) }}\n </button>\n </nav>\n </div>\n\n <!-- ============================================================ -->\n <!-- General Tab - Extracted Component -->\n <!-- ============================================================ -->\n <GaragesGarageGeneralTab v-if=\"activeTab === 'general'\" :garage=\"garage\" />\n\n <!-- ============================================================ -->\n <!-- Employees Tab (Dolgozók) -->\n <!-- ============================================================ -->\n <div v-if=\"activeTab === 'employees'\" class=\"space-y-6\">\n <div class=\"flex items-center justify-between\">\n <div class=\"flex items-center gap-3\">\n <div class=\"p-2 rounded-lg bg-cyan-500/10 text-cyan-400\">\n <svg class=\"w-5 h-5\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M12 4.354a4 4 0 110 5.292M15 21H3v-1a6 6 0 0112 0v1zm0 0h6v-1a6 6 0 00-9-5.197m13.5-9a2.5 2.5 0 11-5 0 2.5 2.5 0 015 0z\" />\n </svg>\n </div>\n <div>\n <h3 class=\"text-base font-semibold text-white\">{{ $t('garages.employees.title') }}</h3>\n <p class=\"text-xs text-slate-400 mt-0.5\">{{ $t('garages.employees.total_count', { count: members.length }) }}</p>\n </div>\n </div>\n <button\n v-if=\"hasOrgPermission('org:manage-members')\"\n @click=\"openAddEmployeeModal\"\n class=\"inline-flex items-center gap-1.5 px-4 py-2 text-sm font-medium bg-emerald-600/20 text-emerald-300 hover:bg-emerald-600/30 rounded-lg transition\"\n >\n <svg class=\"w-4 h-4\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M18 9v3m0 0v3m0-3h3m-3 0h-3m-2-5a4 4 0 11-8 0 4 4 0 018 0zM3 20a6 6 0 0112 0v1H3v-1z\" />\n </svg>\n {{ $t('garages.employees.add_employee') }}\n </button>\n </div>\n\n <div class=\"bg-slate-800/50 border border-slate-700 rounded-xl overflow-hidden\">\n <div class=\"overflow-x-auto\">\n <table class=\"w-full text-sm\">\n <thead>\n <tr class=\"border-b border-slate-700\">\n <th class=\"text-left px-4 py-3 text-xs font-medium text-slate-400 uppercase tracking-wider\">{{ $t('garages.employees.name') }}</th>\n <th class=\"text-left px-4 py-3 text-xs font-medium text-slate-400 uppercase tracking-wider\">{{ $t('garages.employees.email_phone') }}</th>\n <th class=\"text-left px-4 py-3 text-xs font-medium text-slate-400 uppercase tracking-wider\">{{ $t('garages.employees.role') }}</th>\n <th class=\"text-left px-4 py-3 text-xs font-medium text-slate-400 uppercase tracking-wider\">{{ $t('garages.employees.status') }}</th>\n <th class=\"text-right px-4 py-3 text-xs font-medium text-slate-400 uppercase tracking-wider\">{{ $t('garages.employees.actions') }}</th>\n </tr>\n </thead>\n <tbody>\n <tr v-for=\"member in members\" :key=\"member.id\" class=\"border-b border-slate-700/50 last:border-b-0 hover:bg-slate-700/30 transition\">\n <td class=\"px-4 py-3\">\n <div class=\"flex items-center gap-3\">\n <div class=\"w-8 h-8 rounded-lg flex items-center justify-center text-xs font-bold text-white flex-shrink-0\" :class=\"getInitialsColor(memberFullName(member))\">\n {{ getInitials(memberFullName(member)) }}\n </div>\n <div>\n <p class=\"text-sm font-medium text-white\">{{ memberFullName(member) }}</p>\n <p class=\"text-xs text-slate-500\">ID: {{ member.user_id || member.id }}</p>\n <div class=\"flex gap-3 mt-0.5 text-xs text-slate-500 font-mono\">\n <span>User_id: <span class=\"text-slate-400\">{{ member.user_id || 'N/A' }}</span></span>\n <span>Person_id: <span class=\"text-slate-400\">{{ member.person?.id || 'N/A' }}</span></span>\n </div>\n </div>\n </div>\n </td>\n <td class=\"px-4 py-3\">\n <div class=\"space-y-0.5\">\n <p v-if=\"member.person?.email\" class=\"text-sm text-slate-300\">{{ member.person.email }}</p>\n <p v-else class=\"text-sm text-slate-500 italic\">—</p>\n <p v-if=\"member.person?.phone\" class=\"text-xs text-slate-400\">{{ member.person.phone }}</p>\n </div>\n </td>\n <td class=\"px-4 py-3\">\n <span class=\"inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium\" :class=\"roleBadgeClass(member.role)\">\n {{ roleLabel(member.role) }}\n </span>\n </td>\n <td class=\"px-4 py-3\">\n <span class=\"inline-flex items-center gap-1.5 px-2.5 py-0.5 rounded-full text-xs font-medium\" :class=\"memberStatusBadgeClass(member.status)\">\n <span class=\"w-1.5 h-1.5 rounded-full\" :class=\"memberStatusDotClass(member.status)\"></span>\n {{ memberStatusLabel(member.status) }}\n </span>\n </td>\n <td class=\"px-4 py-3 text-right\">\n <div class=\"flex items-center justify-end gap-2\">\n <button\n v-if=\"hasOrgPermission('org:manage-members')\"\n @click=\"openEditRole(member)\"\n class=\"inline-flex items-center gap-1.5 px-3 py-1.5 text-xs font-medium text-indigo-300 bg-indigo-500/10 hover:bg-indigo-500/20 rounded-lg transition\"\n >\n <svg class=\"w-3.5 h-3.5\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z\" />\n </svg>\n {{ $t('garages.employees.edit_role') }}\n </button>\n <button\n v-if=\"hasOrgPermission('org:manage-members')\"\n @click=\"confirmRemoveMember(member)\"\n class=\"inline-flex items-center gap-1.5 px-3 py-1.5 text-xs font-medium text-red-300 bg-red-500/10 hover:bg-red-500/20 rounded-lg transition\"\n >\n <svg class=\"w-3.5 h-3.5\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16\" />\n </svg>\n {{ $t('garages.employees.remove') }}\n </button>\n </div>\n </td>\n </tr>\n <tr v-if=\"members.length === 0\">\n <td colspan=\"5\" class=\"px-4 py-12 text-center\">\n <svg class=\"w-10 h-10 text-slate-600 mx-auto mb-3\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"1.5\" d=\"M17 20h5v-2a3 3 0 00-5.356-1.857M17 20H7m10 0v-2c0-.656-.126-1.283-.356-1.857M7 20H2v-2a3 3 0 015.356-1.857M7 20v-2c0-.656.126-1.283.356-1.857m0 0a5.002 5.002 0 019.288 0M15 7a3 3 0 11-6 0 3 3 0 016 0z\" />\n </svg>\n <p class=\"text-sm text-slate-400\">{{ $t('garages.employees.no_employees') }}</p>\n </td>\n </tr>\n </tbody>\n </table>\n </div>\n </div>\n </div>\n\n <!-- ============================================================ -->\n <!-- Fleet Tab - Extracted Component -->\n <!-- ============================================================ -->\n <GaragesGarageFleetTab\n v-if=\"activeTab === 'fleet'\"\n :garage=\"garage\"\n :org-id=\"orgId\"\n :fleet-vehicles=\"fleetVehicles\"\n :fleet-loading=\"fleetLoading\"\n />\n\n <!-- ============================================================ -->\n <!-- Subscription Tab - Extracted Component -->\n <!-- ============================================================ -->\n <GaragesGarageSubscriptionTab\n v-if=\"activeTab === 'subscription'\"\n ref=\"subscriptionTabRef\"\n :garage=\"garage\"\n :fleet-vehicles=\"fleetVehicles\"\n @refresh=\"fetchDetails\"\n />\n\n <!-- ============================================================ -->\n <!-- Analytics Tab - Full Dashboard with Gamification -->\n <!-- ============================================================ -->\n <div v-if=\"activeTab === 'analytics'\" class=\"space-y-6\">\n\n <!-- SECTION 1: Financial & Revenue (Top Row - 3 Cards) -->\n <div class=\"grid grid-cols-1 md:grid-cols-3 gap-4\">\n <!-- Card 1: LTV - Élettartam Érték -->\n <div class=\"bg-slate-800/50 border border-slate-700 rounded-xl p-5\">\n <div class=\"flex items-center gap-3 mb-3\">\n <div class=\"p-2 rounded-lg bg-emerald-500/10 text-emerald-400\">\n <svg class=\"w-5 h-5\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M13 7h8m0 0v8m0-8l-8 8-4-4-6 6\" />\n </svg>\n </div>\n <span class=\"text-xs font-medium text-slate-400 uppercase tracking-wider\">{{ $t('garages.analytics.ltv') }}</span>\n </div>\n <p class=\"text-2xl font-bold text-white\">150 000 Ft</p>\n <p class=\"text-xs text-emerald-400 mt-1 flex items-center gap-1\">\n <svg class=\"w-3 h-3\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M5 10l7-7m0 0l7 7m-7-7v18\" />\n </svg>\n +12% ezen a hónapon\n </p>\n </div>\n\n <!-- Card 2: MRR - Havi Bevétel -->\n <div class=\"bg-slate-800/50 border border-slate-700 rounded-xl p-5\">\n <div class=\"flex items-center gap-3 mb-3\">\n <div class=\"p-2 rounded-lg bg-blue-500/10 text-blue-400\">\n <svg class=\"w-5 h-5\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M12 8c-1.657 0-3 .895-3 2s1.343 2 3 2 3 .895 3 2-1.343 2-3 2m0-8c1.11 0 2.08.402 2.599 1M12 8V7m0 1v8m0 0v1m0-1c-1.11 0-2.08-.402-2.599-1M21 12a9 9 0 11-18 0 9 9 0 0118 0z\" />\n </svg>\n </div>\n <span class=\"text-xs font-medium text-slate-400 uppercase tracking-wider\">{{ $t('garages.analytics.mrr') }}</span>\n </div>\n <p class=\"text-2xl font-bold text-white\">15 000 Ft</p>\n <p class=\"text-xs text-slate-400 mt-1\">{{ $t('garages.analytics.monthly_recurring') }}</p>\n </div>\n\n <!-- Card 3: Kintlévőség -->\n <div class=\"bg-slate-800/50 border border-slate-700 rounded-xl p-5\">\n <div class=\"flex items-center gap-3 mb-3\">\n <div class=\"p-2 rounded-lg bg-amber-500/10 text-amber-400\">\n <svg class=\"w-5 h-5\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M9 14l6-6m-5.5.5h.01m4.99 5h.01M19 21V5a2 2 0 00-2-2H7a2 2 0 00-2 2v16l3.5-2 3.5 2 3.5-2 3.5 2zM10 8.5a.5.5 0 11-1 0 .5.5 0 011 0zm5 5a.5.5 0 11-1 0 .5.5 0 011 0z\" />\n </svg>\n </div>\n <span class=\"text-xs font-medium text-slate-400 uppercase tracking-wider\">{{ $t('garages.analytics.outstanding') }}</span>\n </div>\n <p class=\"text-2xl font-bold text-white\">0 Ft</p>\n <p class=\"text-xs text-emerald-400 mt-1 flex items-center gap-1\">\n <svg class=\"w-3 h-3\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z\" />\n </svg>\n {{ $t('garages.analytics.all_settled') }}\n </p>\n </div>\n </div>\n\n <!-- SECTION 2: Gamification & Rewards (Second Row - 3 Cards) -->\n <div class=\"grid grid-cols-1 md:grid-cols-3 gap-4\">\n <!-- Card 1: Szerzett Kreditek -->\n <div class=\"bg-slate-800/50 border border-slate-700 rounded-xl p-5\">\n <div class=\"flex items-center gap-3 mb-3\">\n <div class=\"p-2 rounded-lg bg-yellow-500/10 text-yellow-400\">\n <svg class=\"w-5 h-5\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M11.049 2.927c.3-.921 1.603-.921 1.902 0l1.519 4.674a1 1 0 00.95.69h4.915c.969 0 1.371 1.24.588 1.81l-3.976 2.888a1 1 0 00-.363 1.118l1.518 4.674c.3.922-.755 1.688-1.538 1.118l-3.976-2.888a1 1 0 00-1.176 0l-3.976 2.888c-.783.57-1.838-.197-1.538-1.118l1.518-4.674a1 1 0 00-.363-1.118l-3.976-2.888c-.784-.57-.38-1.81.588-1.81h4.914a1 1 0 00.951-.69l1.519-4.674z\" />\n </svg>\n </div>\n <span class=\"text-xs font-medium text-slate-400 uppercase tracking-wider\">{{ $t('garages.analytics.earned_credits') }}</span>\n </div>\n <p class=\"text-2xl font-bold text-yellow-300\">450 XP</p>\n <p class=\"text-xs text-slate-400 mt-1\">{{ $t('garages.analytics.contribution_xp') }}</p>\n </div>\n\n <!-- Card 2: Meghívott Cégek -->\n <div class=\"bg-slate-800/50 border border-slate-700 rounded-xl p-5\">\n <div class=\"flex items-center gap-3 mb-3\">\n <div class=\"p-2 rounded-lg bg-purple-500/10 text-purple-400\">\n <svg class=\"w-5 h-5\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M18 9v3m0 0v3m0-3h3m-3 0h-3m-2-5a4 4 0 11-8 0 4 4 0 018 0zM3 20a6 6 0 0112 0v1H3v-1z\" />\n </svg>\n </div>\n <span class=\"text-xs font-medium text-slate-400 uppercase tracking-wider\">{{ $t('garages.analytics.invited_companies') }}</span>\n </div>\n <p class=\"text-2xl font-bold text-white\">12</p>\n <p class=\"text-xs text-slate-400 mt-1\">{{ $t('garages.analytics.companies_joined') }}</p>\n </div>\n\n <!-- Card 3: Validált Garázsok -->\n <div class=\"bg-slate-800/50 border border-slate-700 rounded-xl p-5\">\n <div class=\"flex items-center gap-3 mb-3\">\n <div class=\"p-2 rounded-lg bg-cyan-500/10 text-cyan-400\">\n <svg class=\"w-5 h-5\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M9 12l2 2 4-4m5.618-4.016A11.955 11.955 0 0112 2.944a11.955 11.955 0 01-8.618 3.04A12.02 12.02 0 003 9c0 5.591 3.824 10.29 9 11.622 5.176-1.332 9-6.03 9-11.622 0-1.042-.133-2.052-.382-3.016z\" />\n </svg>\n </div>\n <span class=\"text-xs font-medium text-slate-400 uppercase tracking-wider\">{{ $t('garages.analytics.validated_garages') }}</span>\n </div>\n <p class=\"text-2xl font-bold text-white\">8</p>\n <p class=\"text-xs text-slate-400 mt-1\">{{ $t('garages.analytics.garages_confirmed') }}</p>\n </div>\n </div>\n\n <!-- SECTION 3 & 4: Bottom Row - Utilization + Marketplace -->\n <div class=\"grid grid-cols-1 md:grid-cols-2 gap-4\">\n <!-- SECTION 3: Utilization Bars (Bottom Left) -->\n <div class=\"bg-slate-800/50 border border-slate-700 rounded-xl p-5\">\n <div class=\"flex items-center gap-3 mb-4\">\n <div class=\"p-2 rounded-lg bg-indigo-500/10 text-indigo-400\">\n <svg class=\"w-5 h-5\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M9 19v-6a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2a2 2 0 002-2zm0 0V9a2 2 0 012-2h2a2 2 0 012 2v10m-6 0a2 2 0 002 2h2a2 2 0 002-2m0 0V5a2 2 0 012-2h2a2 2 0 012 2v14a2 2 0 01-2 2h-2a2 2 0 01-2-2z\" />\n </svg>\n </div>\n <h3 class=\"text-sm font-semibold text-white\">{{ $t('garages.analytics.utilization') }}</h3>\n </div>\n\n <!-- Vehicle Quota Bar -->\n <div class=\"mb-4\">\n <div class=\"flex items-center justify-between mb-1.5\">\n <span class=\"text-xs text-slate-400\">{{ $t('garages.analytics.vehicle_quota') }}</span>\n <span class=\"text-xs text-slate-500\">{{ fleetVehicles.length }} / {{ vehicleQuotaLimit }}</span>\n </div>\n <div class=\"w-full h-2 bg-slate-700 rounded-full overflow-hidden\">\n <div\n class=\"h-full rounded-full transition-all duration-500\"\n :class=\"vehicleQuotaPercent >= 90 ? 'bg-red-500' : vehicleQuotaPercent >= 70 ? 'bg-amber-500' : 'bg-blue-500'\"\n :style=\"{ width: vehicleQuotaPercent + '%' }\"\n ></div>\n </div>\n <p class=\"text-xs text-slate-500 mt-1\">{{ vehicleQuotaPercent }}% {{ $t('garages.analytics.utilized') }}</p>\n </div>\n\n </div>\n\n <!-- SECTION 4: Marketplace & Engagement (Bottom Right) -->\n <div class=\"bg-slate-800/50 border border-slate-700 rounded-xl p-5\">\n <div class=\"flex items-center gap-3 mb-4\">\n <div class=\"p-2 rounded-lg bg-pink-500/10 text-pink-400\">\n <svg class=\"w-5 h-5\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M11 3.055A9.001 9.001 0 1020.945 13H11V3.055z\" />\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M20.488 9H15V3.512A9.025 9.025 0 0120.488 9z\" />\n </svg>\n </div>\n <h3 class=\"text-sm font-semibold text-white\">{{ $t('garages.analytics.marketplace_engagement') }}</h3>\n </div>\n\n <!-- Average Rating -->\n <div class=\"flex items-center justify-between py-2 border-b border-slate-700/50\">\n <span class=\"text-xs text-slate-400\">{{ $t('garages.analytics.avg_rating') }}</span>\n <div class=\"flex items-center gap-1\">\n <svg class=\"w-4 h-4 text-yellow-400\" fill=\"currentColor\" viewBox=\"0 0 20 20\">\n <path d=\"M9.049 2.927c.3-.921 1.603-.921 1.902 0l1.07 3.292a1 1 0 00.95.69h3.462c.969 0 1.371 1.24.588 1.81l-2.8 2.034a1 1 0 00-.364 1.118l1.07 3.292c.3.921-.755 1.688-1.54 1.118l-2.8-2.034a1 1 0 00-1.175 0l-2.8 2.034c-.784.57-1.838-.197-1.539-1.118l1.07-3.292a1 1 0 00-.364-1.118L2.98 8.72c-.783-.57-.38-1.81.588-1.81h3.461a1 1 0 00.951-.69l1.07-3.292z\" />\n </svg>\n <span class=\"text-sm font-medium text-white\">4.8</span>\n </div>\n </div>\n\n <!-- Total Reviews -->\n <div class=\"flex items-center justify-between py-2 border-b border-slate-700/50\">\n <span class=\"text-xs text-slate-400\">{{ $t('garages.analytics.total_reviews') }}</span>\n <span class=\"text-sm font-medium text-white\">124</span>\n </div>\n\n <!-- Service Requests -->\n <div class=\"flex items-center justify-between py-2 border-b border-slate-700/50\">\n <span class=\"text-xs text-slate-400\">{{ $t('garages.analytics.service_requests') }}</span>\n <span class=\"text-sm font-medium text-white\">47</span>\n </div>\n\n <!-- Response Rate -->\n <div class=\"flex items-center justify-between py-2\">\n <span class=\"text-xs text-slate-400\">{{ $t('garages.analytics.response_rate') }}</span>\n <span class=\"text-sm font-medium text-emerald-400\">92%</span>\n </div>\n </div>\n </div>\n </div>\n\n <!-- ============================================================ -->\n <!-- STEP 5: Comprehensive Edit Modal with tabs -->\n <!-- ============================================================ -->\n <div\n v-if=\"showEditModal\"\n class=\"fixed inset-0 z-50 flex items-center justify-center p-4\"\n >\n <!-- Backdrop -->\n <div class=\"absolute inset-0 bg-black/60 backdrop-blur-sm\" @click=\"closeEditModal\"></div>\n\n <!-- Modal -->\n <div class=\"relative w-full max-w-2xl bg-slate-800 border border-slate-700 rounded-2xl shadow-2xl max-h-[90vh] overflow-hidden flex flex-col\">\n <!-- Header -->\n <div class=\"px-6 py-4 border-b border-slate-700 flex items-center justify-between flex-shrink-0\">\n <h3 class=\"text-lg font-semibold text-white\">{{ $t('garages.details.edit_details') }}</h3>\n <button @click=\"closeEditModal\" class=\"p-1.5 rounded-lg text-slate-400 hover:text-white hover:bg-slate-700 transition\">\n <svg class=\"w-5 h-5\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M6 18L18 6M6 6l12 12\" />\n </svg>\n </button>\n </div>\n\n <!-- Tab Navigation -->\n <div class=\"px-6 pt-4 border-b border-slate-700 flex-shrink-0\">\n <nav class=\"flex gap-4\">\n <button\n v-for=\"tab in editModalTabs\"\n :key=\"tab.key\"\n @click=\"editModalTab = tab.key\"\n class=\"pb-3 text-sm font-medium transition border-b-2 -mb-px\"\n :class=\"editModalTab === tab.key\n ? 'text-indigo-400 border-indigo-400'\n : 'text-slate-400 border-transparent hover:text-slate-300'\"\n >\n {{ $t(tab.label) }}\n </button>\n </nav>\n </div>\n\n <!-- Scrollable Body -->\n <div class=\"flex-1 overflow-y-auto p-6 space-y-6\">\n <!-- Alapadatok Tab -->\n <div v-if=\"editModalTab === 'basic'\" class=\"space-y-5\">\n <div class=\"grid grid-cols-1 md:grid-cols-2 gap-4\">\n <div>\n <label class=\"block text-xs font-medium text-slate-400 mb-1.5\">{{ $t('garages.details.company_name') }}</label>\n <input\n v-model=\"editForm.full_name\"\n type=\"text\"\n class=\"w-full px-3 py-2 text-sm bg-slate-700/50 border border-slate-600 rounded-lg text-white placeholder-slate-500 focus:outline-none focus:ring-2 focus:ring-indigo-500/50 focus:border-indigo-500\"\n />\n </div>\n <div>\n <label class=\"block text-xs font-medium text-slate-400 mb-1.5\">{{ $t('garages.details.display_name') }}</label>\n <input\n v-model=\"editForm.display_name\"\n type=\"text\"\n class=\"w-full px-3 py-2 text-sm bg-slate-700/50 border border-slate-600 rounded-lg text-white placeholder-slate-500 focus:outline-none focus:ring-2 focus:ring-indigo-500/50 focus:border-indigo-500\"\n />\n </div>\n </div>\n <div class=\"grid grid-cols-1 md:grid-cols-2 gap-4\">\n <div>\n <label class=\"block text-xs font-medium text-slate-400 mb-1.5\">{{ $t('garages.details.tax_number') }}</label>\n <input\n v-model=\"editForm.tax_number\"\n type=\"text\"\n class=\"w-full px-3 py-2 text-sm bg-slate-700/50 border border-slate-600 rounded-lg text-white placeholder-slate-500 focus:outline-none focus:ring-2 focus:ring-indigo-500/50 focus:border-indigo-500\"\n />\n </div>\n <div>\n <label class=\"block text-xs font-medium text-slate-400 mb-1.5\">{{ $t('garages.details.reg_number') }}</label>\n <input\n v-model=\"editForm.reg_number\"\n type=\"text\"\n class=\"w-full px-3 py-2 text-sm bg-slate-700/50 border border-slate-600 rounded-lg text-white placeholder-slate-500 focus:outline-none focus:ring-2 focus:ring-indigo-500/50 focus:border-indigo-500\"\n />\n </div>\n </div>\n <div class=\"grid grid-cols-1 md:grid-cols-2 gap-4\">\n <div>\n <label class=\"block text-xs font-medium text-slate-400 mb-1.5\">{{ $t('garages.details.zip') }}</label>\n <input\n v-model=\"editForm.address_zip\"\n type=\"text\"\n class=\"w-full px-3 py-2 text-sm bg-slate-700/50 border border-slate-600 rounded-lg text-white placeholder-slate-500 focus:outline-none focus:ring-2 focus:ring-indigo-500/50 focus:border-indigo-500\"\n />\n </div>\n <div>\n <label class=\"block text-xs font-medium text-slate-400 mb-1.5\">{{ $t('garages.details.city') }}</label>\n <input\n v-model=\"editForm.address_city\"\n type=\"text\"\n class=\"w-full px-3 py-2 text-sm bg-slate-700/50 border border-slate-600 rounded-lg text-white placeholder-slate-500 focus:outline-none focus:ring-2 focus:ring-indigo-500/50 focus:border-indigo-500\"\n />\n </div>\n </div>\n <div class=\"grid grid-cols-1 md:grid-cols-2 gap-4\">\n <div>\n <label class=\"block text-xs font-medium text-slate-400 mb-1.5\">{{ $t('garages.details.street_name') }}</label>\n <input\n v-model=\"editForm.address_street_name\"\n type=\"text\"\n class=\"w-full px-3 py-2 text-sm bg-slate-700/50 border border-slate-600 rounded-lg text-white placeholder-slate-500 focus:outline-none focus:ring-2 focus:ring-indigo-500/50 focus:border-indigo-500\"\n />\n </div>\n <div>\n <label class=\"block text-xs font-medium text-slate-400 mb-1.5\">{{ $t('garages.details.street_type') }}</label>\n <input\n v-model=\"editForm.address_street_type\"\n type=\"text\"\n class=\"w-full px-3 py-2 text-sm bg-slate-700/50 border border-slate-600 rounded-lg text-white placeholder-slate-500 focus:outline-none focus:ring-2 focus:ring-indigo-500/50 focus:border-indigo-500\"\n />\n </div>\n </div>\n <div class=\"grid grid-cols-1 md:grid-cols-2 gap-4\">\n <div>\n <label class=\"block text-xs font-medium text-slate-400 mb-1.5\">{{ $t('garages.details.house_number') }}</label>\n <input\n v-model=\"editForm.address_house_number\"\n type=\"text\"\n class=\"w-full px-3 py-2 text-sm bg-slate-700/50 border border-slate-600 rounded-lg text-white placeholder-slate-500 focus:outline-none focus:ring-2 focus:ring-indigo-500/50 focus:border-indigo-500\"\n />\n </div>\n </div>\n </div>\n\n <!-- Contact Tab -->\n <div v-if=\"editModalTab === 'contact'\" class=\"space-y-5\">\n <div class=\"grid grid-cols-1 md:grid-cols-2 gap-4\">\n <div>\n <label class=\"block text-xs font-medium text-slate-400 mb-1.5\">{{ $t('garages.details.contact_person') }}</label>\n <input\n v-model=\"editForm.contact_person_name\"\n type=\"text\"\n class=\"w-full px-3 py-2 text-sm bg-slate-700/50 border border-slate-600 rounded-lg text-white placeholder-slate-500 focus:outline-none focus:ring-2 focus:ring-indigo-500/50 focus:border-indigo-500\"\n />\n </div>\n <div>\n <label class=\"block text-xs font-medium text-slate-400 mb-1.5\">{{ $t('garages.details.contact_email') }}</label>\n <input\n v-model=\"editForm.contact_email\"\n type=\"email\"\n class=\"w-full px-3 py-2 text-sm bg-slate-700/50 border border-slate-600 rounded-lg text-white placeholder-slate-500 focus:outline-none focus:ring-2 focus:ring-indigo-500/50 focus:border-indigo-500\"\n />\n </div>\n </div>\n <div class=\"grid grid-cols-1 md:grid-cols-2 gap-4\">\n <div>\n <label class=\"block text-xs font-medium text-slate-400 mb-1.5\">{{ $t('garages.details.contact_phone') }}</label>\n <input\n v-model=\"editForm.contact_phone\"\n type=\"text\"\n class=\"w-full px-3 py-2 text-sm bg-slate-700/50 border border-slate-600 rounded-lg text-white placeholder-slate-500 focus:outline-none focus:ring-2 focus:ring-indigo-500/50 focus:border-indigo-500\"\n />\n </div>\n </div>\n </div>\n\n <!-- Addresses Tab -->\n <div v-if=\"editModalTab === 'addresses'\" class=\"space-y-8\">\n <!-- Billing Address -->\n <div>\n <h4 class=\"text-sm font-semibold text-white mb-3\">{{ $t('garages.details.billing_address') }}</h4>\n <div class=\"grid grid-cols-1 md:grid-cols-2 gap-4\">\n <div>\n <label class=\"block text-xs font-medium text-slate-400 mb-1.5\">{{ $t('garages.details.zip') }}</label>\n <input v-model=\"editForm.billing_zip\" type=\"text\" class=\"w-full px-3 py-2 text-sm bg-slate-700/50 border border-slate-600 rounded-lg text-white placeholder-slate-500 focus:outline-none focus:ring-2 focus:ring-indigo-500/50 focus:border-indigo-500\" />\n </div>\n <div>\n <label class=\"block text-xs font-medium text-slate-400 mb-1.5\">{{ $t('garages.details.city') }}</label>\n <input v-model=\"editForm.billing_city\" type=\"text\" class=\"w-full px-3 py-2 text-sm bg-slate-700/50 border border-slate-600 rounded-lg text-white placeholder-slate-500 focus:outline-none focus:ring-2 focus:ring-indigo-500/50 focus:border-indigo-500\" />\n </div>\n </div>\n <div class=\"grid grid-cols-1 md:grid-cols-2 gap-4 mt-4\">\n <div>\n <label class=\"block text-xs font-medium text-slate-400 mb-1.5\">{{ $t('garages.details.street_name') }}</label>\n <input v-model=\"editForm.billing_street_name\" type=\"text\" class=\"w-full px-3 py-2 text-sm bg-slate-700/50 border border-slate-600 rounded-lg text-white placeholder-slate-500 focus:outline-none focus:ring-2 focus:ring-indigo-500/50 focus:border-indigo-500\" />\n </div>\n <div>\n <label class=\"block text-xs font-medium text-slate-400 mb-1.5\">{{ $t('garages.details.street_type') }}</label>\n <input v-model=\"editForm.billing_street_type\" type=\"text\" class=\"w-full px-3 py-2 text-sm bg-slate-700/50 border border-slate-600 rounded-lg text-white placeholder-slate-500 focus:outline-none focus:ring-2 focus:ring-indigo-500/50 focus:border-indigo-500\" />\n </div>\n </div>\n <div class=\"mt-4\">\n <label class=\"block text-xs font-medium text-slate-400 mb-1.5\">{{ $t('garages.details.house_number') }}</label>\n <input v-model=\"editForm.billing_house_number\" type=\"text\" class=\"w-full px-3 py-2 text-sm bg-slate-700/50 border border-slate-600 rounded-lg text-white placeholder-slate-500 focus:outline-none focus:ring-2 focus:ring-indigo-500/50 focus:border-indigo-500\" />\n </div>\n </div>\n\n <!-- Notification Address -->\n <div>\n <h4 class=\"text-sm font-semibold text-white mb-3\">{{ $t('garages.details.notification_address') }}</h4>\n <div class=\"grid grid-cols-1 md:grid-cols-2 gap-4\">\n <div>\n <label class=\"block text-xs font-medium text-slate-400 mb-1.5\">{{ $t('garages.details.zip') }}</label>\n <input v-model=\"editForm.notification_zip\" type=\"text\" class=\"w-full px-3 py-2 text-sm bg-slate-700/50 border border-slate-600 rounded-lg text-white placeholder-slate-500 focus:outline-none focus:ring-2 focus:ring-indigo-500/50 focus:border-indigo-500\" />\n </div>\n <div>\n <label class=\"block text-xs font-medium text-slate-400 mb-1.5\">{{ $t('garages.details.city') }}</label>\n <input v-model=\"editForm.notification_city\" type=\"text\" class=\"w-full px-3 py-2 text-sm bg-slate-700/50 border border-slate-600 rounded-lg text-white placeholder-slate-500 focus:outline-none focus:ring-2 focus:ring-indigo-500/50 focus:border-indigo-500\" />\n </div>\n </div>\n <div class=\"grid grid-cols-1 md:grid-cols-2 gap-4 mt-4\">\n <div>\n <label class=\"block text-xs font-medium text-slate-400 mb-1.5\">{{ $t('garages.details.street_name') }}</label>\n <input v-model=\"editForm.notification_street_name\" type=\"text\" class=\"w-full px-3 py-2 text-sm bg-slate-700/50 border border-slate-600 rounded-lg text-white placeholder-slate-500 focus:outline-none focus:ring-2 focus:ring-indigo-500/50 focus:border-indigo-500\" />\n </div>\n <div>\n <label class=\"block text-xs font-medium text-slate-400 mb-1.5\">{{ $t('garages.details.street_type') }}</label>\n <input v-model=\"editForm.notification_street_type\" type=\"text\" class=\"w-full px-3 py-2 text-sm bg-slate-700/50 border border-slate-600 rounded-lg text-white placeholder-slate-500 focus:outline-none focus:ring-2 focus:ring-indigo-500/50 focus:border-indigo-500\" />\n </div>\n </div>\n <div class=\"mt-4\">\n <label class=\"block text-xs font-medium text-slate-400 mb-1.5\">{{ $t('garages.details.house_number') }}</label>\n <input v-model=\"editForm.notification_house_number\" type=\"text\" class=\"w-full px-3 py-2 text-sm bg-slate-700/50 border border-slate-600 rounded-lg text-white placeholder-slate-500 focus:outline-none focus:ring-2 focus:ring-indigo-500/50 focus:border-indigo-500\" />\n </div>\n </div>\n </div>\n </div>\n\n <!-- Footer -->\n <div class=\"px-6 py-4 border-t border-slate-700 flex items-center justify-end gap-3 flex-shrink-0\">\n <button @click=\"closeEditModal\" class=\"px-4 py-2 text-sm font-medium text-slate-300 hover:text-white bg-slate-700/50 hover:bg-slate-700 rounded-lg transition\">\n {{ $t('garages.details.cancel') }}\n </button>\n <button @click=\"saveEdit\" :disabled=\"saving\" class=\"inline-flex items-center gap-2 px-4 py-2 text-sm font-medium text-white bg-indigo-600 hover:bg-indigo-500 rounded-lg transition disabled:opacity-50 disabled:cursor-not-allowed\">\n <svg v-if=\"saving\" class=\"w-4 h-4 animate-spin\" fill=\"none\" viewBox=\"0 0 24 24\">\n <circle class=\"opacity-25\" cx=\"12\" cy=\"12\" r=\"10\" stroke=\"currentColor\" stroke-width=\"4\" />\n <path class=\"opacity-75\" fill=\"currentColor\" d=\"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z\" />\n </svg>\n {{ saving ? $t('garages.details.saving') : $t('garages.details.save') }}\n </button>\n </div>\n </div>\n </div>\n\n <!-- ============================================================ -->\n <!-- Add Employee Modal -->\n <!-- ============================================================ -->\n <div v-if=\"showAddEmployeeModal\" class=\"fixed inset-0 z-50 flex items-center justify-center p-4\">\n <div class=\"absolute inset-0 bg-black/60 backdrop-blur-sm\" @click=\"showAddEmployeeModal = false\"></div>\n <div class=\"relative w-full max-w-md bg-slate-800 border border-slate-700 rounded-2xl shadow-2xl p-6\">\n <h3 class=\"text-lg font-semibold text-white mb-4\">{{ $t('garages.employees.add_employee') }}</h3>\n <div class=\"space-y-4\">\n <div>\n <label class=\"block text-xs font-medium text-slate-400 mb-1.5\">{{ $t('garages.employees.email') }}</label>\n <input\n v-model=\"newMemberEmail\"\n type=\"email\"\n class=\"w-full px-3 py-2 text-sm bg-slate-700/50 border border-slate-600 rounded-lg text-white placeholder-slate-500 focus:outline-none focus:ring-2 focus:ring-indigo-500/50 focus:border-indigo-500\"\n :placeholder=\"$t('garages.employees.email_placeholder')\"\n />\n </div>\n <div>\n <label class=\"block text-xs font-medium text-slate-400 mb-1.5\">{{ $t('garages.employees.role') }}</label>\n <select\n v-model=\"newMemberRole\"\n class=\"w-full px-3 py-2 text-sm bg-slate-700/50 border border-slate-600 rounded-lg text-white focus:outline-none focus:ring-2 focus:ring-indigo-500/50 focus:border-indigo-500\"\n >\n <option value=\"member\">{{ $t('garages.roles.member') }}</option>\n <option value=\"manager\">{{ $t('garages.roles.manager') }}</option>\n <option value=\"admin\">{{ $t('garages.roles.admin') }}</option>\n </select>\n </div>\n </div>\n <div class=\"flex justify-end gap-3 mt-6\">\n <button @click=\"showAddEmployeeModal = false\" class=\"px-4 py-2 text-sm font-medium text-slate-300 hover:text-white bg-slate-700/50 hover:bg-slate-700 rounded-lg transition\">\n {{ $t('garages.employees.cancel') }}\n </button>\n <button @click=\"addEmployee\" :disabled=\"addingMember || !newMemberEmail\" class=\"inline-flex items-center gap-2 px-4 py-2 text-sm font-medium text-white bg-emerald-600 hover:bg-emerald-500 rounded-lg transition disabled:opacity-50 disabled:cursor-not-allowed\">\n <svg v-if=\"addingMember\" class=\"w-4 h-4 animate-spin\" fill=\"none\" viewBox=\"0 0 24 24\">\n <circle class=\"opacity-25\" cx=\"12\" cy=\"12\" r=\"10\" stroke=\"currentColor\" stroke-width=\"4\" />\n <path class=\"opacity-75\" fill=\"currentColor\" d=\"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z\" />\n </svg>\n {{ addingMember ? $t('garages.employees.adding') : $t('garages.employees.add') }}\n </button>\n </div>\n </div>\n </div>\n\n <!-- ============================================================ -->\n <!-- Edit Role Modal -->\n <!-- ============================================================ -->\n <div v-if=\"showEditRoleModal\" class=\"fixed inset-0 z-50 flex items-center justify-center p-4\">\n <div class=\"absolute inset-0 bg-black/60 backdrop-blur-sm\" @click=\"showEditRoleModal = false\"></div>\n <div class=\"relative w-full max-w-md bg-slate-800 border border-slate-700 rounded-2xl shadow-2xl p-6\">\n <h3 class=\"text-lg font-semibold text-white mb-4\">{{ $t('garages.employees.edit_role') }}</h3>\n <div>\n <label class=\"block text-xs font-medium text-slate-400 mb-1.5\">{{ $t('garages.employees.role') }}</label>\n <select\n v-model=\"editingRole\"\n class=\"w-full px-3 py-2 text-sm bg-slate-700/50 border border-slate-600 rounded-lg text-white focus:outline-none focus:ring-2 focus:ring-indigo-500/50 focus:border-indigo-500\"\n >\n <option value=\"member\">{{ $t('garages.roles.member') }}</option>\n <option value=\"manager\">{{ $t('garages.roles.manager') }}</option>\n <option value=\"admin\">{{ $t('garages.roles.admin') }}</option>\n </select>\n </div>\n <div class=\"flex justify-end gap-3 mt-6\">\n <button @click=\"showEditRoleModal = false\" class=\"px-4 py-2 text-sm font-medium text-slate-300 hover:text-white bg-slate-700/50 hover:bg-slate-700 rounded-lg transition\">\n {{ $t('garages.employees.cancel') }}\n </button>\n <button @click=\"saveRoleEdit\" :disabled=\"savingRole\" class=\"inline-flex items-center gap-2 px-4 py-2 text-sm font-medium text-white bg-indigo-600 hover:bg-indigo-500 rounded-lg transition disabled:opacity-50 disabled:cursor-not-allowed\">\n <svg v-if=\"savingRole\" class=\"w-4 h-4 animate-spin\" fill=\"none\" viewBox=\"0 0 24 24\">\n <circle class=\"opacity-25\" cx=\"12\" cy=\"12\" r=\"10\" stroke=\"currentColor\" stroke-width=\"4\" />\n <path class=\"opacity-75\" fill=\"currentColor\" d=\"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z\" />\n </svg>\n {{ savingRole ? $t('garages.employees.saving') : $t('garages.employees.save') }}\n </button>\n </div>\n </div>\n </div>\n\n <!-- ============================================================ -->\n <!-- Remove Confirmation Modal -->\n <!-- ============================================================ -->\n <div v-if=\"showRemoveModal\" class=\"fixed inset-0 z-50 overflow-y-auto\" aria-labelledby=\"modal-title\" role=\"dialog\" aria-modal=\"true\">\n <div class=\"flex items-end justify-center min-h-screen pt-4 px-4 pb-20 text-center sm:block sm:p-0\">\n <div class=\"fixed inset-0 bg-black/60 backdrop-blur-sm transition-opacity\" @click=\"showRemoveModal = false\"></div>\n <span class=\"hidden sm:inline-block sm:align-middle sm:h-screen\" aria-hidden=\"true\">&#8203;</span>\n <div class=\"inline-block align-bottom bg-slate-800 rounded-2xl px-4 pt-5 pb-4 text-left overflow-hidden shadow-xl border border-slate-700 transform transition-all sm:my-8 sm:align-middle sm:max-w-lg sm:w-full sm:p-6\">\n <div class=\"sm:flex sm:items-start\">\n <div class=\"mx-auto flex-shrink-0 flex items-center justify-center h-12 w-12 rounded-full bg-red-500/20 sm:mx-0 sm:h-10 sm:w-10\">\n <svg class=\"h-6 w-6 text-red-400\" fill=\"none\" viewBox=\"0 0 24 24\" stroke-width=\"1.5\" stroke=\"currentColor\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M12 9v3.75m-9.303 3.376c-.866 1.5.217 3.374 1.948 3.374h14.71c1.73 0 2.813-1.874 1.948-3.374L13.949 3.378c-.866-1.5-3.032-1.5-3.898 0L2.697 16.126zM12 15.75h.007v.008H12v-.008z\" />\n </svg>\n </div>\n <div class=\"mt-3 text-center sm:mt-0 sm:ml-4 sm:text-left\">\n <h3 class=\"text-lg leading-6 font-medium text-white\">\n {{ $t('garages.employees.removeTitle') }}\n </h3>\n <div class=\"mt-2\">\n <p class=\"text-sm text-slate-400\">\n {{ $t('garages.employees.removeConfirm', { name: memberFullName(removingMember) }) }}\n </p>\n </div>\n </div>\n </div>\n <div class=\"mt-5 sm:mt-4 sm:flex sm:flex-row-reverse gap-2\">\n <button @click=\"executeRemove\" :disabled=\"removing\" type=\"button\" class=\"w-full inline-flex justify-center rounded-xl border border-transparent shadow-sm px-4 py-2.5 bg-red-600 text-base font-medium text-white hover:bg-red-500 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500 sm:w-auto sm:text-sm disabled:opacity-50 disabled:cursor-not-allowed transition\">\n <svg v-if=\"removing\" class=\"w-4 h-4 animate-spin mr-2\" fill=\"none\" viewBox=\"0 0 24 24\">\n <circle class=\"opacity-25\" cx=\"12\" cy=\"12\" r=\"10\" stroke=\"currentColor\" stroke-width=\"4\" />\n <path class=\"opacity-75\" fill=\"currentColor\" d=\"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z\" />\n </svg>\n {{ removing ? $t('garages.employees.removing') : $t('garages.employees.remove') }}\n </button>\n <button @click=\"showRemoveModal = false\" type=\"button\" class=\"mt-3 w-full inline-flex justify-center rounded-xl border border-slate-600 shadow-sm px-4 py-2.5 bg-slate-700/50 text-base font-medium text-slate-300 hover:bg-slate-700 hover:text-white focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 sm:mt-0 sm:w-auto sm:text-sm transition\">\n {{ $t('garages.employees.cancel') }}\n </button>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Notification Toast (Dark Theme) -->\n <transition enter-active-class=\"transition ease-out duration-300\" enter-from-class=\"translate-y-2 opacity-0 sm:translate-y-0 sm:translate-x-2\" enter-to-class=\"translate-y-0 opacity-100 sm:translate-x-0\" leave-active-class=\"transition ease-in duration-100\" leave-from-class=\"opacity-100\" leave-to-class=\"opacity-0\">\n <div v-if=\"notification.show\" class=\"fixed top-4 right-4 z-[100] max-w-sm w-full bg-slate-800 border border-slate-700 shadow-lg rounded-xl pointer-events-auto overflow-hidden\">\n <div class=\"p-4\">\n <div class=\"flex items-start\">\n <div class=\"flex-shrink-0\">\n <svg v-if=\"notification.type === 'success'\" class=\"h-6 w-6 text-green-400\" fill=\"none\" viewBox=\"0 0 24 24\" stroke-width=\"1.5\" stroke=\"currentColor\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 12.75L11.25 15 15 9.75M21 12a9 9 0 11-18 0 9 9 0 0118 0z\" />\n </svg>\n <svg v-if=\"notification.type === 'error'\" class=\"h-6 w-6 text-red-400\" fill=\"none\" viewBox=\"0 0 24 24\" stroke-width=\"1.5\" stroke=\"currentColor\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M12 9v3.75m9-.75a9 9 0 11-18 0 9 9 0 0118 0zm-9 3.75h.008v.008H12v-.008z\" />\n </svg>\n </div>\n <div class=\"ml-3 w-0 flex-1 pt-0.5\">\n <p class=\"text-sm font-medium text-white\">{{ notification.message }}</p>\n </div>\n <div class=\"ml-4 flex-shrink-0 flex\">\n <button @click=\"notification.show = false\" class=\"bg-slate-700/50 rounded-md inline-flex text-slate-400 hover:text-slate-300 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500\">\n <span class=\"sr-only\">Close</span>\n <svg class=\"h-5 w-5\" fill=\"none\" viewBox=\"0 0 24 24\" stroke-width=\"1.5\" stroke=\"currentColor\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M6 18L18 6M6 6l12 12\" />\n </svg>\n </button>\n </div>\n </div>\n </div>\n </div>\n </transition>\n </template>\n </div>\n</template>\n<script setup lang=\"ts\">\nimport { ref, computed, onMounted, watch } from 'vue'\nimport { useRoute, useRouter } from 'vue-router'\nimport { useAuthStore } from '~/stores/auth'\n\nconst route = useRoute()\nconst router = useRouter()\nconst auth = useAuthStore()\n\nconst orgId = route.params.id as string\n\n// State\nconst loading = ref(true)\nconst error = ref<string | null>(null)\nconst garage = ref<any>(null)\nconst members = ref<any[]>([])\nconst activeTab = ref('general')\nconst fleetVehicles = ref<any[]>([])\nconst fleetLoading = ref(false)\n\n// Template refs for child components\nconst subscriptionTabRef = ref<InstanceType<typeof GaragesGarageSubscriptionTab> | null>(null)\n\n// Edit Modal\nconst showEditModal = ref(false)\nconst editModalTab = ref('basic')\nconst saving = ref(false)\nconst editForm = ref({\n full_name: '',\n name: '',\n display_name: '',\n email: '',\n phone: '',\n tax_number: '',\n reg_number: '',\n org_type: '',\n address_zip: '',\n address_city: '',\n address_street_name: '',\n address_street_type: '',\n address_house_number: '',\n contact_person_name: '',\n contact_email: '',\n contact_phone: '',\n billing_zip: '',\n billing_city: '',\n billing_street_name: '',\n billing_street_type: '',\n billing_house_number: '',\n notification_zip: '',\n notification_city: '',\n notification_street_name: '',\n notification_street_type: '',\n notification_house_number: '',\n})\n\n// Add Employee Modal\nconst showAddEmployeeModal = ref(false)\nconst newMemberEmail = ref('')\nconst newMemberRole = ref('member')\nconst addingMember = ref(false)\n\n// Edit Role Modal\nconst showEditRoleModal = ref(false)\nconst editingMember = ref<any>(null)\nconst editingRole = ref('member')\nconst savingRole = ref(false)\n\n// Remove Modal\nconst showRemoveModal = ref(false)\nconst removingMember = ref<any>(null)\nconst removing = ref(false)\n\n// Notification\nconst notification = ref({ show: false, type: 'success' as 'success' | 'error', message: '' })\n\n// Tab definitions\nconst tabs = [\n { key: 'general', label: 'garages.details.generalTab' },\n { key: 'employees', label: 'garages.details.employeesTab' },\n { key: 'fleet', label: 'garages.details.fleetTab' },\n { key: 'subscription', label: 'garages.details.subscriptionTab' },\n { key: 'analytics', label: 'garages.details.analyticsTab' },\n]\n\nconst editModalTabs = [\n { key: 'basic', label: 'garages.details.editBasicTab' },\n { key: 'contact', label: 'garages.details.editContactTab' },\n { key: 'addresses', label: 'garages.details.editAddressTab' },\n]\n\n// RBAC helper\nfunction hasOrgPermission(perm: string): boolean {\n if (auth.isAdmin) return true\n if (auth.user?.system_capabilities?.[perm]) return true\n if (auth.user?.org_capabilities?.[orgId]?.[perm]) return true\n return false\n}\n\n// Computed\nconst vehicleQuotaLimit = computed(() => {\n if (!garage.value?.subscription?.asset_limit) return 5\n return garage.value.subscription.asset_limit\n})\n\nconst vehicleQuotaPercent = computed(() => {\n const limit = vehicleQuotaLimit.value\n if (limit <= 0) return 0\n return Math.min(100, Math.round((fleetVehicles.value.length / limit) * 100))\n})\n\nconst branchQuotaPercent = computed(() => {\n const branches = garage.value?.branches?.length || 0\n const limit = garage.value?.subscription?.branch_limit\n if (!limit || limit <= 0) return 0\n return Math.min(100, Math.round((branches / limit) * 100))\n})\n\nconst employeeQuotaPercent = computed(() => {\n const count = garage.value?.member_count || 0\n const limit = garage.value?.subscription?.user_limit\n if (!limit || limit <= 0) return 0\n return Math.min(100, Math.round((count / limit) * 100))\n})\n\nconst missingFields = computed(() => {\n if (!garage.value) return []\n const missing: { key: string; label: string }[] = []\n const g = garage.value\n const isIndividual = g.org_type === 'individual'\n\n if (!isIndividual) {\n if (!g.tax_number) missing.push({ key: 'tax_number', label: 'garages.details.missing_tax_number' })\n }\n\n if (!g.contact_email && !g.email) missing.push({ key: 'contact_email', label: 'garages.details.missing_contact_email' })\n if (!g.contact_phone && !g.phone) missing.push({ key: 'contact_phone', label: 'garages.details.missing_contact_phone' })\n\n if (!isIndividual) {\n if (!g.billing_city || !g.billing_zip) missing.push({ key: 'billing', label: 'garages.details.missing_billing' })\n }\n\n return missing\n})\n\n// API calls\nasync function fetchDetails() {\n loading.value = true\n error.value = null\n try {\n const tokenCookie = useCookie('access_token')\n const token = (tokenCookie.value || auth.token || '').trim()\n const headers: Record<string, string> = {\n 'Authorization': `Bearer ${token}`,\n 'Content-Type': 'application/json',\n }\n\n const res = await fetch(`/api/v1/admin/organizations/${orgId}/details`, { headers })\n\n if (!res.ok) throw new Error(`Failed to fetch organization: ${res.status}`)\n\n const data = await res.json()\n garage.value = data\n members.value = data.members || []\n } catch (e: any) {\n error.value = e.message || 'Failed to load garage details'\n } finally {\n loading.value = false\n }\n}\n\nasync function fetchFleetVehicles() {\n fleetLoading.value = true\n try {\n const tokenCookie = useCookie('access_token')\n const token = (tokenCookie.value || auth.token || '').trim()\n const res = await fetch(`/api/v1/admin/organizations/${orgId}/vehicles`, {\n headers: {\n 'Authorization': `Bearer ${token}`,\n 'Content-Type': 'application/json',\n },\n })\n if (!res.ok) throw new Error(`Failed to fetch fleet: ${res.status}`)\n const data = await res.json()\n fleetVehicles.value = data.vehicles || []\n } catch (e: any) {\n console.error('Fleet fetch error:', e)\n fleetVehicles.value = []\n } finally {\n fleetLoading.value = false\n }\n}\n\n// Edit Modal\nfunction openEditModal() {\n if (!garage.value) return\n editForm.value = {\n full_name: garage.value.full_name || '',\n name: garage.value.name || '',\n display_name: garage.value.display_name || '',\n email: garage.value.email || '',\n phone: garage.value.phone || '',\n tax_number: garage.value.tax_number || '',\n reg_number: garage.value.reg_number || '',\n org_type: garage.value.org_type || '',\n address_zip: garage.value.address_zip || '',\n address_city: garage.value.address_city || '',\n address_street_name: garage.value.address_street_name || '',\n address_street_type: garage.value.address_street_type || '',\n address_house_number: garage.value.address_house_number || '',\n contact_person_name: garage.value.contact_person_name || '',\n contact_email: garage.value.contact_email || '',\n contact_phone: garage.value.contact_phone || '',\n billing_zip: garage.value.billing_zip || '',\n billing_city: garage.value.billing_city || '',\n billing_street_name: garage.value.billing_street_name || '',\n billing_street_type: garage.value.billing_street_type || '',\n billing_house_number: garage.value.billing_house_number || '',\n notification_zip: garage.value.notification_zip || '',\n notification_city: garage.value.notification_city || '',\n notification_street_name: garage.value.notification_street_name || '',\n notification_street_type: garage.value.notification_street_type || '',\n notification_house_number: garage.value.notification_house_number || '',\n }\n editModalTab.value = 'basic'\n showEditModal.value = true\n}\n\nfunction closeEditModal() {\n showEditModal.value = false\n}\n\nasync function saveEdit() {\n saving.value = true\n try {\n const tokenCookie = useCookie('access_token')\n const token = (tokenCookie.value || auth.token || '').trim()\n\n const payload: Record<string, any> = {}\n for (const [key, value] of Object.entries(editForm.value)) {\n if (value !== '' && value !== null && value !== undefined) {\n payload[key] = value\n }\n }\n\n if (garage.value?.org_type === 'individual') {\n if (payload.contact_email && !payload.email) payload.email = payload.contact_email\n if (payload.contact_phone && !payload.phone) payload.phone = payload.contact_phone\n }\n\n const res = await fetch(`/api/v1/admin/organizations/${orgId}`, {\n method: 'PUT',\n headers: {\n 'Authorization': `Bearer ${token}`,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(payload),\n })\n if (!res.ok) throw new Error(`Save failed: ${res.status}`)\n const result = await res.json()\n if (result.organization) {\n garage.value = { ...garage.value, ...result.organization }\n } else {\n garage.value = { ...garage.value, ...result }\n }\n closeEditModal()\n showNotification('success', 'Garage updated successfully')\n await fetchDetails()\n } catch (e: any) {\n showNotification('error', e.message || 'Failed to save')\n } finally {\n saving.value = false\n }\n}\n\n// Employee actions\nasync function addEmployee() {\n if (!newMemberEmail.value) return\n addingMember.value = true\n try {\n const tokenCookie = useCookie('access_token')\n const token = (tokenCookie.value || auth.token || '').trim()\n const res = await fetch(`/api/v1/admin/organizations/${orgId}/members`, {\n method: 'POST',\n headers: {\n 'Authorization': `Bearer ${token}`,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n email: newMemberEmail.value,\n role: newMemberRole.value,\n }),\n })\n if (!res.ok) {\n const errData = await res.json().catch(() => ({}))\n throw new Error(errData.detail || `Add member failed: ${res.status}`)\n }\n showAddEmployeeModal.value = false\n newMemberEmail.value = ''\n newMemberRole.value = 'member'\n showNotification('success', 'Member added successfully')\n await fetchDetails()\n } catch (e: any) {\n showNotification('error', e.message || 'Failed to add member')\n } finally {\n addingMember.value = false\n }\n}\n\nfunction openEditRole(member: any) {\n editingMember.value = member\n editingRole.value = member.role || 'member'\n showEditRoleModal.value = true\n}\n\nasync function saveRoleEdit() {\n if (!editingMember.value) return\n savingRole.value = true\n try {\n const tokenCookie = useCookie('access_token')\n const token = (tokenCookie.value || auth.token || '').trim()\n const res = await fetch(`/api/v1/admin/organizations/${orgId}/members/${editingMember.value.id}`, {\n method: 'PUT',\n headers: {\n 'Authorization': `Bearer ${token}`,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({ role: editingRole.value }),\n })\n if (!res.ok) throw new Error(`Update role failed: ${res.status}`)\n showEditRoleModal.value = false\n editingMember.value = null\n showNotification('success', 'Role updated successfully')\n await fetchDetails()\n } catch (e: any) {\n showNotification('error', e.message || 'Failed to update role')\n } finally {\n savingRole.value = false\n }\n}\n\nfunction confirmRemoveMember(member: any) {\n removingMember.value = member\n showRemoveModal.value = true\n}\n\nasync function executeRemove() {\n if (!removingMember.value) return\n removing.value = true\n try {\n const tokenCookie = useCookie('access_token')\n const token = (tokenCookie.value || auth.token || '').trim()\n const res = await fetch(`/api/v1/admin/organizations/${orgId}/members/${removingMember.value.id}`, {\n method: 'DELETE',\n headers: {\n 'Authorization': `Bearer ${token}`,\n },\n })\n if (!res.ok) throw new Error(`Remove failed: ${res.status}`)\n showRemoveModal.value = false\n removingMember.value = null\n showNotification('success', 'Member removed successfully')\n await fetchDetails()\n } catch (e: any) {\n showNotification('error', e.message || 'Failed to remove member')\n } finally {\n removing.value = false\n }\n}\n\n// Notification helper\nfunction showNotification(type: 'success' | 'error', message: string) {\n notification.value = { show: true, type, message }\n setTimeout(() => {\n notification.value.show = false\n }, 4000)\n}\n\n// Navigation\nfunction goBack() {\n router.push('/garages')\n}\n\n// Helpers\nconst cleanGarageName = computed(() => {\n if (!garage.value) return ''\n const raw = garage.value.display_name || garage.value.name || garage.value.full_name || ''\n return raw.replace(/[\\s-]*#\\d+\\s*$/g, '').trim() || 'Garage #' + garage.value.id\n})\n\nfunction garageDisplayName() {\n if (!garage.value) return ''\n return garage.value.name || garage.value.email || garage.value.full_name || 'Garage #' + garage.value.id\n}\n\nfunction getInitials(name: string): string {\n if (!name) return '?'\n return name.split(' ').map(w => w[0]).join('').toUpperCase().slice(0, 2)\n}\n\nfunction getInitialsColor(name: string): string {\n const colors = [\n 'bg-red-500', 'bg-yellow-500', 'bg-green-500', 'bg-blue-500',\n 'bg-indigo-500', 'bg-purple-500', 'bg-pink-500', 'bg-teal-500',\n ]\n let hash = 0\n for (let i = 0; i < (name || '').length; i++) {\n hash = name.charCodeAt(i) + ((hash << 5) - hash)\n }\n return colors[Math.abs(hash) % colors.length]\n}\n\nfunction statusLabel(status: string): string {\n const map: Record<string, string> = {\n active: 'Active',\n inactive: 'Inactive',\n suspended: 'Suspended',\n pending: 'Pending',\n }\n return map[status?.toLowerCase()] || status\n}\n\nfunction statusBadgeClass(status: string): string {\n const map: Record<string, string> = {\n active: 'bg-green-100 text-green-800',\n inactive: 'bg-gray-100 text-gray-800',\n suspended: 'bg-red-100 text-red-800',\n pending: 'bg-yellow-100 text-yellow-800',\n }\n return map[status?.toLowerCase()] || 'bg-gray-100 text-gray-800'\n}\n\nfunction statusDotClass(status: string): string {\n const map: Record<string, string> = {\n active: 'bg-green-400',\n inactive: 'bg-gray-400',\n suspended: 'bg-red-400',\n pending: 'bg-yellow-400',\n }\n return map[status?.toLowerCase()] || 'bg-gray-400'\n}\n\nfunction memberFullName(member: any): string {\n if (!member) return ''\n if (member.display_name) return member.display_name\n if (member.name) return member.name\n if (member.email) return member.email\n if (member.person) {\n const first = member.person.first_name || ''\n const last = member.person.last_name || ''\n const full = `${last} ${first}`.trim()\n if (full) return full\n if (member.person.email) return member.person.email\n }\n if (member.user_id) return String(member.user_id)\n return 'Unknown'\n}\n\nfunction roleLabel(role: string): string {\n const map: Record<string, string> = {\n admin: 'Admin',\n manager: 'Manager',\n member: 'Member',\n owner: 'Owner',\n }\n return map[role?.toLowerCase()] || role || 'Member'\n}\n\nfunction roleBadgeClass(role: string): string {\n const map: Record<string, string> = {\n admin: 'bg-purple-100 text-purple-800',\n manager: 'bg-blue-100 text-blue-800',\n member: 'bg-green-100 text-green-800',\n owner: 'bg-yellow-100 text-yellow-800',\n }\n return map[role?.toLowerCase()] || 'bg-gray-100 text-gray-800'\n}\n\nfunction memberStatusLabel(status: string): string {\n const map: Record<string, string> = {\n active: 'Active',\n invited: 'Invited',\n suspended: 'Suspended',\n inactive: 'Inactive',\n }\n return map[status?.toLowerCase()] || status || 'Unknown'\n}\n\nfunction memberStatusBadgeClass(status: string): string {\n const map: Record<string, string> = {\n active: 'bg-green-100 text-green-800',\n invited: 'bg-blue-100 text-blue-800',\n suspended: 'bg-red-100 text-red-800',\n inactive: 'bg-gray-100 text-gray-800',\n }\n return map[status?.toLowerCase()] || 'bg-gray-100 text-gray-800'\n}\n\nfunction memberStatusDotClass(status: string): string {\n const map: Record<string, string> = {\n active: 'bg-green-400',\n invited: 'bg-blue-400',\n suspended: 'bg-red-400',\n inactive: 'bg-gray-400',\n }\n return map[status?.toLowerCase()] || 'bg-gray-400'\n}\n\n// Lifecycle\nonMounted(() => {\n fetchDetails()\n})\n\n// Watch activeTab to trigger data fetching\nwatch(activeTab, (newTab) => {\n // Fetch fleet data for fleet tab, analytics tab, or subscription tab (for utilization stats)\n if (newTab === 'fleet' || newTab === 'analytics' || newTab === 'subscription') {\n if (fleetVehicles.value.length === 0) {\n fetchFleetVehicles()\n }\n }\n // Trigger child component data fetching via template refs\n if (newTab === 'subscription') {\n subscriptionTabRef.value?.fetchTiers()\n }\n})\n</script>\n"],"version":3}