1 line
129 KiB
JSON
1 line
129 KiB
JSON
{"file":"index-1I7UC9HP.js","mappings":"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","names":["$t","_ssrInterpolate","_ssrRenderList","_ssrRenderClass","_ssrIncludeBooleanAttr","_ssrRenderAttr"],"sources":["../../../../pages/garages/[id]/index.vue"],"sourcesContent":["<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 <!-- ============================================================ -->\n <!-- STEP 4: Missing Data Alerter -->\n <!-- ============================================================ -->\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 <!-- P0: Activation-aware missing data description -->\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(garage))\"\n >\n {{ getInitials(garageDisplayName(garage)) }}\n </div>\n <div>\n <div class=\"flex items-center gap-3\">\n <h1 class=\"text-2xl font-bold text-white\">{{ cleanGarageName }}</h1>\n <!-- P0: Status badge prominently displayed next to Garage Name -->\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 <!-- STEP 6: RBAC - Edit button hidden without org:edit permission -->\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 <!-- General Tab Content -->\n <div v-if=\"activeTab === 'general'\" class=\"space-y-6\">\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?.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 <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\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 <!-- STEP 8: Add Employee button with RBAC -->\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>\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 <!-- STEP 6: RBAC - Edit role button hidden without org:manage-members -->\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 <!-- STEP 6: RBAC - Remove button hidden without org:manage-members -->\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 <!-- STEP 7: Fleet Tab with data table -->\n <!-- ============================================================ -->\n <div v-if=\"activeTab === 'fleet'\" 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\n <!-- ============================================================ -->\n <!-- Subscription Tab - Package Management -->\n <!-- ============================================================ -->\n <div v-if=\"activeTab === 'subscription'\" 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 md:grid-cols-4 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 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.employees_used') }}</p>\n <p class=\"text-sm font-semibold text-white\">\n {{ members.length }} / {{ employeeQuotaLimit }}\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=\"employeeQuotaPercent >= 90 ? 'bg-red-500' : employeeQuotaPercent >= 70 ? 'bg-amber-500' : 'bg-emerald-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 <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=\"datetime-local\"\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 <!-- 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\"\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 <!-- Empty State -->\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 </tbody>\n </table>\n </div>\n </div>\n </div>\n </div>\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 <!-- Employee Quota Bar -->\n <div>\n <div class=\"flex items-center justify-between mb-1.5\">\n <span class=\"text-xs text-slate-400\">{{ $t('garages.analytics.employee_quota') }}</span>\n <span class=\"text-xs text-slate-500\">{{ members.length }} / {{ employeeQuotaLimit }}</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=\"employeeQuotaPercent >= 90 ? 'bg-red-500' : employeeQuotaPercent >= 70 ? 'bg-amber-500' : 'bg-emerald-500'\"\n :style=\"{ width: employeeQuotaPercent + '%' }\"\n ></div>\n </div>\n <p class=\"text-xs text-slate-500 mt-1\">{{ employeeQuotaPercent }}% {{ $t('garages.analytics.utilized') }}</p>\n </div>\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.5\">\n <div class=\"flex items-center\">\n <svg v-for=\"i in 5\" :key=\"i\" class=\"w-4 h-4\" :class=\"i <= 4 ? 'text-yellow-400' : 'text-slate-600'\" fill=\"currentColor\" viewBox=\"0 0 20 20\">\n <path d=\"M9.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-sm font-semibold text-white\">4.8</span>\n <span class=\"text-xs text-slate-500\">/ 5.0</span>\n </div>\n </div>\n\n <!-- Review Count -->\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.reviews') }}</span>\n <span class=\"text-sm text-white font-medium\">124 {{ $t('garages.analytics.reviews_count') }}</span>\n </div>\n\n <!-- Last Login -->\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.last_activity') }}</span>\n <span class=\"text-sm text-white font-medium\">{{ $t('garages.analytics.last_login_mock') }}</span>\n </div>\n\n <!-- 30-Day Services -->\n <div class=\"flex items-center justify-between py-2\">\n <span class=\"text-xs text-slate-400\">{{ $t('garages.analytics.services_30d') }}</span>\n <span class=\"text-sm text-white font-medium\">42</span>\n </div>\n </div>\n </div>\n </div>\n\n <!-- END: template v-else-if=\"garage\" -->\n </template>\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-3 gap-4\">\n <div class=\"md:col-span-2\">\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 <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 <!-- Kapcsolat 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_name') }}</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>\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\n <!-- Címek Tab -->\n <div v-if=\"editModalTab === 'addresses'\" class=\"space-y-6\">\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.billing_zip') }}</label>\n <input\n v-model=\"editForm.billing_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.billing_city') }}</label>\n <input\n v-model=\"editForm.billing_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-3 gap-4 mt-4\">\n <div class=\"md:col-span-1\">\n <label class=\"block text-xs font-medium text-slate-400 mb-1.5\">{{ $t('garages.details.billing_street_name') }}</label>\n <input\n v-model=\"editForm.billing_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.billing_street_type') }}</label>\n <input\n v-model=\"editForm.billing_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 <label class=\"block text-xs font-medium text-slate-400 mb-1.5\">{{ $t('garages.details.billing_house_number') }}</label>\n <input\n v-model=\"editForm.billing_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 <!-- Notification Address -->\n <div class=\"pt-4 border-t border-slate-700/50\">\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.notification_zip') }}</label>\n <input\n v-model=\"editForm.notification_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.notification_city') }}</label>\n <input\n v-model=\"editForm.notification_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-3 gap-4 mt-4\">\n <div class=\"md:col-span-1\">\n <label class=\"block text-xs font-medium text-slate-400 mb-1.5\">{{ $t('garages.details.notification_street_name') }}</label>\n <input\n v-model=\"editForm.notification_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.notification_street_type') }}</label>\n <input\n v-model=\"editForm.notification_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 <label class=\"block text-xs font-medium text-slate-400 mb-1.5\">{{ $t('garages.details.notification_house_number') }}</label>\n <input\n v-model=\"editForm.notification_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 </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\n @click=\"closeEditModal\"\n 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 >\n {{ $t('garages.details.cancel') }}\n </button>\n <button\n @click=\"saveEdit\"\n :disabled=\"saving\"\n class=\"px-4 py-2 text-sm font-medium text-white bg-indigo-600 hover:bg-indigo-500 disabled:opacity-50 disabled:cursor-not-allowed rounded-lg transition inline-flex items-center gap-2\"\n >\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 <!-- Add Employee Modal (Dark Theme) -->\n <div v-if=\"showAddEmployeeModal\" 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-slate-900/80 backdrop-blur-sm transition-opacity\" @click=\"showAddEmployeeModal = false\"></div>\n <span class=\"hidden sm:inline-block sm:align-middle sm:h-screen\" aria-hidden=\"true\">​</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-indigo-500/20 sm:mx-0 sm:h-10 sm:w-10\">\n <svg class=\"h-6 w-6 text-indigo-400\" fill=\"none\" viewBox=\"0 0 24 24\" stroke-width=\"1.5\" stroke=\"currentColor\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M19 7.5v-1m0 0a3 3 0 00-3-3m3 3a3 3 0 013 3m0 0v1m0 0a3 3 0 01-3 3m3-3h-1m-4-3a3 3 0 01-3 3m0 0a3 3 0 01-3-3m3 3v1m0 0a3 3 0 013 3m-3-3H8m4 3h1m-4-3a3 3 0 01-3-3m3 3v-1m0 0a3 3 0 013-3m-3 3h1m4-3h-1\" />\n </svg>\n </div>\n <div class=\"mt-3 text-center sm:mt-0 sm:ml-4 sm:text-left w-full\">\n <h3 class=\"text-lg leading-6 font-medium text-white\" id=\"modal-title\">\n {{ $t('garages.employees.addTitle') }}\n </h3>\n <div class=\"mt-4 space-y-4\">\n <div>\n <label class=\"block text-sm font-medium text-slate-300\">{{ $t('garages.employees.email') }}</label>\n <input v-model=\"newMemberEmail\" type=\"email\" class=\"mt-1 block w-full rounded-lg border-slate-600 bg-slate-700/50 text-white shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm px-3 py-2.5 border placeholder-slate-400\" :placeholder=\"$t('garages.employees.emailPlaceholder')\" />\n </div>\n <div>\n <label class=\"block text-sm font-medium text-slate-300\">{{ $t('garages.employees.role') }}</label>\n <select v-model=\"newMemberRole\" class=\"mt-1 block w-full rounded-lg border-slate-600 bg-slate-700/50 text-white shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm px-3 py-2.5 border\">\n <option value=\"member\">{{ $t('garages.employees.roleMember') }}</option>\n <option value=\"manager\">{{ $t('garages.employees.roleManager') }}</option>\n <option value=\"admin\">{{ $t('garages.employees.roleAdmin') }}</option>\n </select>\n </div>\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=\"addEmployee\" :disabled=\"addingMember || !newMemberEmail\" type=\"button\" class=\"w-full inline-flex justify-center rounded-xl border border-transparent shadow-sm px-4 py-2.5 bg-indigo-600 text-base font-medium text-white hover:bg-indigo-500 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 sm:w-auto sm:text-sm disabled:opacity-50 disabled:cursor-not-allowed transition\">\n <svg v-if=\"addingMember\" 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 {{ addingMember ? $t('garages.employees.adding') : $t('garages.employees.add') }}\n </button>\n <button @click=\"showAddEmployeeModal = 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 <!-- Edit Role Modal (Dark Theme) -->\n <div v-if=\"showEditRoleModal\" 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-slate-900/80 backdrop-blur-sm transition-opacity\" @click=\"showEditRoleModal = false\"></div>\n <span class=\"hidden sm:inline-block sm:align-middle sm:h-screen\" aria-hidden=\"true\">​</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-yellow-500/20 sm:mx-0 sm:h-10 sm:w-10\">\n <svg class=\"h-6 w-6 text-yellow-400\" fill=\"none\" viewBox=\"0 0 24 24\" stroke-width=\"1.5\" stroke=\"currentColor\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M16.862 4.487l1.687-1.688a1.875 1.875 0 112.652 2.652L10.582 16.07a4.5 4.5 0 01-1.897 1.13L6 18l.8-2.685a4.5 4.5 0 011.13-1.897l8.932-8.931zm0 0L19.5 7.125M18 14v4.75A2.25 2.25 0 0115.75 21H5.25A2.25 2.25 0 013 18.75V8.25A2.25 2.25 0 015.25 6H10\" />\n </svg>\n </div>\n <div class=\"mt-3 text-center sm:mt-0 sm:ml-4 sm:text-left w-full\">\n <h3 class=\"text-lg leading-6 font-medium text-white\">\n {{ $t('garages.employees.editRoleTitle') }}\n </h3>\n <p class=\"text-sm text-slate-400 mt-1\">{{ $t('garages.employees.editRoleFor', { name: memberFullName(editingMember) }) }}</p>\n <div class=\"mt-4\">\n <select v-model=\"editingRole\" class=\"mt-1 block w-full rounded-lg border-slate-600 bg-slate-700/50 text-white shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm px-3 py-2.5 border\">\n <option value=\"member\">{{ $t('garages.employees.roleMember') }}</option>\n <option value=\"manager\">{{ $t('garages.employees.roleManager') }}</option>\n <option value=\"admin\">{{ $t('garages.employees.roleAdmin') }}</option>\n </select>\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=\"saveRoleEdit\" :disabled=\"savingRole\" type=\"button\" class=\"w-full inline-flex justify-center rounded-xl border border-transparent shadow-sm px-4 py-2.5 bg-indigo-600 text-base font-medium text-white hover:bg-indigo-500 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 sm:w-auto sm:text-sm disabled:opacity-50 disabled:cursor-not-allowed transition\">\n <svg v-if=\"savingRole\" 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 {{ savingRole ? $t('garages.employees.saving') : $t('garages.employees.saveRole') }}\n </button>\n <button @click=\"showEditRoleModal = 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 <!-- Remove Confirmation Modal (Dark Theme) -->\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-slate-900/80 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\">​</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 </div>\n</template>\n\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// 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// Subscription tab state\nconst availableTiers = ref<any[]>([])\nconst selectedTierId = ref<number | ''>('')\nconst customExpiresAt = ref('')\nconst subscriptionSaving = ref(false)\nconst subscriptionSaveError = ref<string | null>(null)\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 employeeQuotaLimit = computed(() => {\n if (!garage.value?.subscription?.employee_limit) return 10\n return garage.value.subscription.employee_limit\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 limit = employeeQuotaLimit.value\n if (limit <= 0) return 0\n return Math.min(100, Math.round((members.value.length / 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 // Private garages (individual) don't need tax_number or reg_number\n if (!isIndividual) {\n if (!g.tax_number) missing.push({ key: 'tax_number', label: 'garages.details.missing_tax_number' })\n }\n\n // Contact email/phone - always required\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 // Billing address - always required for business, optional for individual\n if (!isIndividual) {\n if (!g.billing_city || !g.billing_zip) missing.push({ key: 'billing', label: 'garages.details.missing_billing' })\n }\n\n // Subscription check - \"Free\" tier is valid, don't flag it\n if (!g.subscription || !g.subscription.tier_name) {\n // Only flag if there's truly no subscription object at all\n // A subscription with tier_name='Free' is valid\n }\n\n return missing\n})\n\nconst formattedAddress = computed(() => {\n if (!garage.value) return ''\n const parts = [\n garage.value.address_zip,\n garage.value.address_city,\n garage.value.address_street_name,\n garage.value.address_street_type,\n garage.value.address_house_number,\n ].filter(Boolean)\n return parts.join(' ') || '-'\n})\n\nconst formattedBillingAddress = computed(() => {\n if (!garage.value) return ''\n const parts = [\n garage.value.billing_zip,\n garage.value.billing_city,\n garage.value.billing_street_name,\n garage.value.billing_street_type,\n garage.value.billing_house_number,\n ].filter(Boolean)\n return parts.join(' ') || ''\n})\n\nconst formattedNotificationAddress = computed(() => {\n if (!garage.value) return ''\n const parts = [\n garage.value.notification_zip,\n garage.value.notification_city,\n garage.value.notification_street_name,\n garage.value.notification_street_type,\n garage.value.notification_house_number,\n ].filter(Boolean)\n return parts.join(' ') || ''\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 // Build payload: only send non-empty fields\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 // For individual (private) garages, also map contact_email/phone to org-level email/phone\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 // API returns { status, message, org_id, updated_fields, organization: {...} }\n if (result.organization) {\n // Merge the returned org fields into our local garage object\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 // P0 HOTFIX: Refresh all data from server after successful save\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 openRemoveModal(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// ── Subscription Tab Functions ──────────────────────────────────────\n\nasync function fetchTiers() {\n try {\n const tokenCookie = useCookie('access_token')\n const token = (tokenCookie.value || auth.token || '').trim()\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) throw new Error(`Failed to fetch tiers: ${res.status}`)\n const data = await res.json()\n availableTiers.value = data.tiers || []\n } catch (e: any) {\n console.error('[GarageDetails] Failed to fetch tiers:', e)\n }\n}\n\nasync function updateSubscription() {\n if (!selectedTierId.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\n const payload: Record<string, unknown> = {\n tier_id: selectedTierId.value,\n }\n\n if (customExpiresAt.value) {\n payload.expires_at = new Date(customExpiresAt.value).toISOString()\n }\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 showNotification('success', 'Subscription updated successfully')\n selectedTierId.value = ''\n customExpiresAt.value = ''\n await fetchDetails()\n } catch (e: any) {\n subscriptionSaveError.value = e.message || 'Failed to update subscription'\n showNotification('error', e.message || 'Failed to update subscription')\n } finally {\n subscriptionSaving.value = false\n }\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 // Strip trailing (#\\d+) or -\\s*#\\d+ patterns\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 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 Date(dateStr).toLocaleDateString('en-US', {\n year: 'numeric',\n month: 'short',\n day: 'numeric',\n })\n } catch {\n return dateStr\n }\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 memberFullName(member: any): string {\n if (!member) return ''\n // P0 HOTFIX: Try person data as additional fallback chain\n // for synthetic OWNER entries that only have person nested data\n if (member.display_name) return member.display_name\n if (member.name) return member.name\n if (member.email) return member.email\n // Try person nested data\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\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\n// Lifecycle\nonMounted(() => {\n fetchDetails()\n})\n\n// Watch activeTab to fetch fleet vehicles when the Fleet tab becomes active\nwatch(activeTab, (newTab) => {\n if (newTab === 'fleet' && fleetVehicles.value.length === 0) {\n fetchFleetVehicles()\n }\n // Fetch available tiers when the Subscription tab becomes active\n if (newTab === 'subscription' && availableTiers.value.length === 0) {\n fetchTiers()\n }\n})\n</script>\n"],"version":3} |