import { defineComponent, ref, computed, watch, useSSRContext } from "vue"; import { ssrRenderAttrs, ssrInterpolate, ssrRenderList, ssrRenderClass, ssrRenderStyle, ssrIncludeBooleanAttr, ssrLooseContain, ssrLooseEqual, ssrRenderAttr } from "vue/server-renderer"; import { useRoute, useRouter } from "vue-router"; import { b as useAuthStore, c as useCookie } from "../server.mjs"; import "/app/node_modules/ofetch/dist/node.mjs"; import "#internal/nuxt/paths"; import "/app/node_modules/hookable/dist/index.mjs"; import "/app/node_modules/unctx/dist/index.mjs"; import "/app/node_modules/h3/dist/index.mjs"; import "pinia"; import "/app/node_modules/defu/dist/defu.mjs"; import "/app/node_modules/ufo/dist/index.mjs"; import "/app/node_modules/klona/dist/index.mjs"; import "/app/node_modules/cookie-es/dist/index.mjs"; import "/app/node_modules/destr/dist/index.mjs"; import "/app/node_modules/ohash/dist/index.mjs"; import "/app/node_modules/@unhead/vue/dist/index.mjs"; import "@vue/devtools-api"; const _sfc_main = /* @__PURE__ */ defineComponent({ __name: "index", __ssrInlineRender: true, setup(__props) { const route = useRoute(); useRouter(); const auth = useAuthStore(); const orgId = route.params.id; const loading = ref(true); const error = ref(null); const garage = ref(null); const members = ref([]); const activeTab = ref("general"); const fleetVehicles = ref([]); const fleetLoading = ref(false); const showEditModal = ref(false); const editModalTab = ref("basic"); const saving = ref(false); const editForm = ref({ full_name: "", name: "", display_name: "", email: "", phone: "", tax_number: "", reg_number: "", org_type: "", address_zip: "", address_city: "", address_street_name: "", address_street_type: "", address_house_number: "", contact_person_name: "", contact_email: "", contact_phone: "", billing_zip: "", billing_city: "", billing_street_name: "", billing_street_type: "", billing_house_number: "", notification_zip: "", notification_city: "", notification_street_name: "", notification_street_type: "", notification_house_number: "" }); const showAddEmployeeModal = ref(false); const newMemberEmail = ref(""); const newMemberRole = ref("member"); const addingMember = ref(false); const showEditRoleModal = ref(false); const editingMember = ref(null); const editingRole = ref("member"); const savingRole = ref(false); const showRemoveModal = ref(false); const removingMember = ref(null); const removing = ref(false); const notification = ref({ show: false, type: "success", message: "" }); const availableTiers = ref([]); const selectedTierId = ref(""); const customExpiresAt = ref(""); const subscriptionSaving = ref(false); const subscriptionSaveError = ref(null); const tabs = [ { key: "general", label: "garages.details.generalTab" }, { key: "employees", label: "garages.details.employeesTab" }, { key: "fleet", label: "garages.details.fleetTab" }, { key: "subscription", label: "garages.details.subscriptionTab" }, { key: "analytics", label: "garages.details.analyticsTab" } ]; const editModalTabs = [ { key: "basic", label: "garages.details.editBasicTab" }, { key: "contact", label: "garages.details.editContactTab" }, { key: "addresses", label: "garages.details.editAddressTab" } ]; function hasOrgPermission(perm) { if (auth.isAdmin) return true; if (auth.user?.system_capabilities?.[perm]) return true; if (auth.user?.org_capabilities?.[orgId]?.[perm]) return true; return false; } const vehicleQuotaLimit = computed(() => { if (!garage.value?.subscription?.asset_limit) return 5; return garage.value.subscription.asset_limit; }); const vehicleQuotaPercent = computed(() => { const limit = vehicleQuotaLimit.value; if (limit <= 0) return 0; return Math.min(100, Math.round(fleetVehicles.value.length / limit * 100)); }); const employeeQuotaLimit = computed(() => { if (!garage.value?.subscription?.employee_limit) return 10; return garage.value.subscription.employee_limit; }); const branchQuotaPercent = computed(() => { const branches = garage.value?.branches?.length || 0; const limit = garage.value?.subscription?.branch_limit; if (!limit || limit <= 0) return 0; return Math.min(100, Math.round(branches / limit * 100)); }); const employeeQuotaPercent = computed(() => { const limit = employeeQuotaLimit.value; if (limit <= 0) return 0; return Math.min(100, Math.round(members.value.length / limit * 100)); }); const missingFields = computed(() => { if (!garage.value) return []; const missing = []; const g = garage.value; const isIndividual = g.org_type === "individual"; if (!isIndividual) { if (!g.tax_number) missing.push({ key: "tax_number", label: "garages.details.missing_tax_number" }); } if (!g.contact_email && !g.email) missing.push({ key: "contact_email", label: "garages.details.missing_contact_email" }); if (!g.contact_phone && !g.phone) missing.push({ key: "contact_phone", label: "garages.details.missing_contact_phone" }); if (!isIndividual) { if (!g.billing_city || !g.billing_zip) missing.push({ key: "billing", label: "garages.details.missing_billing" }); } if (!g.subscription || !g.subscription.tier_name) ; return missing; }); const formattedAddress = computed(() => { if (!garage.value) return ""; const parts = [ garage.value.address_zip, garage.value.address_city, garage.value.address_street_name, garage.value.address_street_type, garage.value.address_house_number ].filter(Boolean); return parts.join(" ") || "-"; }); const formattedBillingAddress = computed(() => { if (!garage.value) return ""; const parts = [ garage.value.billing_zip, garage.value.billing_city, garage.value.billing_street_name, garage.value.billing_street_type, garage.value.billing_house_number ].filter(Boolean); return parts.join(" ") || ""; }); const formattedNotificationAddress = computed(() => { if (!garage.value) return ""; const parts = [ garage.value.notification_zip, garage.value.notification_city, garage.value.notification_street_name, garage.value.notification_street_type, garage.value.notification_house_number ].filter(Boolean); return parts.join(" ") || ""; }); async function fetchFleetVehicles() { fleetLoading.value = true; try { const tokenCookie = useCookie("access_token"); const token = (tokenCookie.value || auth.token || "").trim(); const res = await fetch(`/api/v1/admin/organizations/${orgId}/vehicles`, { headers: { "Authorization": `Bearer ${token}`, "Content-Type": "application/json" } }); if (!res.ok) throw new Error(`Failed to fetch fleet: ${res.status}`); const data = await res.json(); fleetVehicles.value = data.vehicles || []; } catch (e) { console.error("Fleet fetch error:", e); fleetVehicles.value = []; } finally { fleetLoading.value = false; } } async function fetchTiers() { try { const tokenCookie = useCookie("access_token"); const token = (tokenCookie.value || auth.token || "").trim(); const res = await fetch("/api/v1/admin/packages?include_hidden=true&limit=100", { headers: { "Authorization": `Bearer ${token}`, "Content-Type": "application/json" } }); if (!res.ok) throw new Error(`Failed to fetch tiers: ${res.status}`); const data = await res.json(); availableTiers.value = data.tiers || []; } catch (e) { console.error("[GarageDetails] Failed to fetch tiers:", e); } } const cleanGarageName = computed(() => { if (!garage.value) return ""; const raw = garage.value.display_name || garage.value.name || garage.value.full_name || ""; return raw.replace(/[\s-]*#\d+\s*$/g, "").trim() || "Garage #" + garage.value.id; }); function garageDisplayName() { if (!garage.value) return ""; return garage.value.name || garage.value.email || garage.value.full_name || "Garage #" + garage.value.id; } function getInitials(name) { if (!name) return "?"; return name.split(" ").map((w) => w[0]).join("").toUpperCase().slice(0, 2); } function getInitialsColor(name) { const colors = [ "bg-red-500", "bg-yellow-500", "bg-green-500", "bg-blue-500", "bg-indigo-500", "bg-purple-500", "bg-pink-500", "bg-teal-500" ]; let hash = 0; for (let i = 0; i < (name || "").length; i++) { hash = name.charCodeAt(i) + ((hash << 5) - hash); } return colors[Math.abs(hash) % colors.length]; } function statusLabel(status) { const map = { active: "Active", inactive: "Inactive", suspended: "Suspended", pending: "Pending" }; return map[status?.toLowerCase()] || status; } function statusBadgeClass(status) { const map = { active: "bg-green-100 text-green-800", inactive: "bg-gray-100 text-gray-800", suspended: "bg-red-100 text-red-800", pending: "bg-yellow-100 text-yellow-800" }; return map[status?.toLowerCase()] || "bg-gray-100 text-gray-800"; } function statusDotClass(status) { const map = { active: "bg-green-400", inactive: "bg-gray-400", suspended: "bg-red-400", pending: "bg-yellow-400" }; return map[status?.toLowerCase()] || "bg-gray-400"; } function orgTypeLabel(type) { const map = { dealership: "Dealership", service: "Service Center", rental: "Rental Agency", fleet: "Fleet Operator", individual: "Individual", workshop: "Workshop", garage: "Garage", other: "Other" }; return map[type?.toLowerCase()] || type || "-"; } function formatDate(dateStr) { if (!dateStr) return "-"; try { return new Date(dateStr).toLocaleDateString("en-US", { year: "numeric", month: "short", day: "numeric" }); } catch { return dateStr; } } function tierBadgeClass(tier) { const map = { basic: "bg-gray-100 text-gray-800", premium: "bg-yellow-100 text-yellow-800", enterprise: "bg-purple-100 text-purple-800", trial: "bg-blue-100 text-blue-800" }; return map[tier?.toLowerCase()] || "bg-gray-100 text-gray-800"; } function memberFullName(member) { if (!member) return ""; if (member.display_name) return member.display_name; if (member.name) return member.name; if (member.email) return member.email; if (member.person) { const first = member.person.first_name || ""; const last = member.person.last_name || ""; const full = `${last} ${first}`.trim(); if (full) return full; if (member.person.email) return member.person.email; } if (member.user_id) return String(member.user_id); return "Unknown"; } function roleLabel(role) { const map = { admin: "Admin", manager: "Manager", member: "Member", owner: "Owner" }; return map[role?.toLowerCase()] || role || "Member"; } function roleBadgeClass(role) { const map = { admin: "bg-purple-100 text-purple-800", manager: "bg-blue-100 text-blue-800", member: "bg-green-100 text-green-800", owner: "bg-yellow-100 text-yellow-800" }; return map[role?.toLowerCase()] || "bg-gray-100 text-gray-800"; } function memberStatusLabel(status) { const map = { active: "Active", invited: "Invited", suspended: "Suspended", inactive: "Inactive" }; return map[status?.toLowerCase()] || status || "Unknown"; } function memberStatusBadgeClass(status) { const map = { active: "bg-green-100 text-green-800", invited: "bg-blue-100 text-blue-800", suspended: "bg-red-100 text-red-800", inactive: "bg-gray-100 text-gray-800" }; return map[status?.toLowerCase()] || "bg-gray-100 text-gray-800"; } function memberStatusDotClass(status) { const map = { active: "bg-green-400", invited: "bg-blue-400", suspended: "bg-red-400", inactive: "bg-gray-400" }; return map[status?.toLowerCase()] || "bg-gray-400"; } function fleetStatusLabel(status) { const map = { active: "Active", inactive: "Inactive", sold: "Sold", scrapped: "Scrapped", pending: "Pending", draft: "Draft" }; return map[status?.toLowerCase()] || status || "Unknown"; } function fleetStatusBadgeClass(status) { const map = { active: "bg-green-500/10 text-green-400", inactive: "bg-gray-500/10 text-gray-400", sold: "bg-red-500/10 text-red-400", scrapped: "bg-red-500/10 text-red-400", pending: "bg-yellow-500/10 text-yellow-400", draft: "bg-gray-500/10 text-gray-400" }; return map[status?.toLowerCase()] || "bg-gray-500/10 text-gray-400"; } function fleetStatusDotClass(status) { const map = { active: "bg-green-400", inactive: "bg-gray-400", sold: "bg-red-400", scrapped: "bg-red-400", pending: "bg-yellow-400", draft: "bg-gray-400" }; return map[status?.toLowerCase()] || "bg-gray-400"; } watch(activeTab, (newTab) => { if (newTab === "fleet" && fleetVehicles.value.length === 0) { fetchFleetVehicles(); } if (newTab === "subscription" && availableTiers.value.length === 0) { fetchTiers(); } }); return (_ctx, _push, _parent, _attrs) => { _push(`
${ssrInterpolate(_ctx.$t("garages.details.loading"))}
${ssrInterpolate(error.value)}
${ssrInterpolate(_ctx.$t("garages.details.missing_data_title"))}
${ssrInterpolate(_ctx.$t("garages.details.missing_data_count", { count: missingFields.value.length }))}${ssrInterpolate(garage.value.status !== "active" ? _ctx.$t("garages.details.missing_data_activation_required") : _ctx.$t("garages.details.missing_data_desc"))}
${ssrInterpolate(garage.value.full_name)} `); if (garage.value.tax_number) { _push(`· ${ssrInterpolate(_ctx.$t("garages.details.tax_number"))}: ${ssrInterpolate(garage.value.tax_number)}`); } else { _push(``); } _push(`
${ssrInterpolate(_ctx.$t("garages.details.company_name"))}
${ssrInterpolate(garage.value.full_name)}
${ssrInterpolate(_ctx.$t("garages.details.display_name"))}
${ssrInterpolate(garage.value.display_name || "—")}
${ssrInterpolate(_ctx.$t("garages.details.org_type"))}
${ssrInterpolate(orgTypeLabel(garage.value.org_type))}
${ssrInterpolate(_ctx.$t("garages.details.tax_number"))}
${ssrInterpolate(garage.value.tax_number || "—")}
${ssrInterpolate(_ctx.$t("garages.details.reg_number"))}
${ssrInterpolate(garage.value.reg_number || "—")}
${ssrInterpolate(_ctx.$t("garages.details.created_at"))}
${ssrInterpolate(formatDate(garage.value.created_at))}
${ssrInterpolate(_ctx.$t("garages.details.address"))}
${ssrInterpolate(formattedAddress.value)}
${ssrInterpolate(_ctx.$t("garages.details.billing_address"))}
${ssrInterpolate(formattedBillingAddress.value)}
${ssrInterpolate(_ctx.$t("garages.details.notification_address"))}
${ssrInterpolate(formattedNotificationAddress.value)}
Rendszer Azonosítók
${ssrInterpolate(_ctx.$t("garages.details.contact_name"))}
${ssrInterpolate(garage.value.contact_person_name || garage.value.primary_contact?.full_name || "—")}
${ssrInterpolate(_ctx.$t("garages.details.contact_email"))}
${ssrInterpolate(garage.value.contact_email || garage.value.primary_contact?.email || "—")}
${ssrInterpolate(_ctx.$t("garages.details.contact_phone"))}
${ssrInterpolate(garage.value.contact_phone || garage.value.primary_contact?.phone || "—")}
${ssrInterpolate(_ctx.$t("garages.details.contact_role"))}
${ssrInterpolate(garage.value.primary_contact.role || "—")}`); if (garage.value.primary_contact?.department) { _push(` · ${ssrInterpolate(garage.value.primary_contact.department)}`); } else { _push(``); } _push(`
${ssrInterpolate(_ctx.$t("garages.details.no_contact"))}
${ssrInterpolate(_ctx.$t("garages.employees.total_count", { count: members.value.length }))}
| ${ssrInterpolate(_ctx.$t("garages.employees.name"))} | ${ssrInterpolate(_ctx.$t("garages.employees.email_phone"))} | ${ssrInterpolate(_ctx.$t("garages.employees.role"))} | ${ssrInterpolate(_ctx.$t("garages.employees.status"))} | ${ssrInterpolate(_ctx.$t("garages.employees.actions"))} |
|---|---|---|---|---|
${ssrInterpolate(getInitials(memberFullName(member)))} ${ssrInterpolate(memberFullName(member))} ID: ${ssrInterpolate(member.user_id || member.id)} | `);
if (member.person?.email) {
_push(` ${ssrInterpolate(member.person.email)} `); } else { _push(`— `); } if (member.person?.phone) { _push(`${ssrInterpolate(member.person.phone)} `); } else { _push(``); } _push(` | ${ssrInterpolate(roleLabel(member.role))} | ${ssrInterpolate(memberStatusLabel(member.status))} | `);
if (hasOrgPermission("org:manage-members")) {
_push(``);
} else {
_push(``);
}
if (hasOrgPermission("org:manage-members")) {
_push(``);
} else {
_push(``);
}
_push(` |
${ssrInterpolate(_ctx.$t("garages.employees.no_employees"))} | ||||
${ssrInterpolate(_ctx.$t("garages.fleet.total_vehicles", { count: fleetVehicles.value.length }))}
| ${ssrInterpolate(_ctx.$t("garages.fleet.plate"))} | ${ssrInterpolate(_ctx.$t("garages.fleet.brand_model"))} | ${ssrInterpolate(_ctx.$t("garages.fleet.year"))} | ${ssrInterpolate(_ctx.$t("garages.fleet.vin"))} | ${ssrInterpolate(_ctx.$t("garages.fleet.status"))} |
|---|---|---|---|---|
| ${ssrInterpolate(v.license_plate || "—")} | ${ssrInterpolate(v.brand || "—")}`); if (v.brand && v.model) { _push(`·`); } else { _push(``); } if (v.model) { _push(`${ssrInterpolate(v.model)}`); } else { _push(``); } _push(` | ${ssrInterpolate(v.year || "—")} | ${ssrInterpolate(v.vin || "—")} | ${ssrInterpolate(fleetStatusLabel(v.status))} |
${ssrInterpolate(_ctx.$t("garages.fleet.no_vehicles"))} | ||||
${ssrInterpolate(_ctx.$t("garages.details.loading"))} | ||||
${ssrInterpolate(_ctx.$t("garages.fleet.no_fleet_access"))}
${ssrInterpolate(_ctx.$t("garages.details.tier_name"))}
${ssrInterpolate(garage.value.subscription.tier_name)}${ssrInterpolate(_ctx.$t("garages.details.tier_level"))}
${ssrInterpolate(_ctx.$t("garages.details.level_n", { n: garage.value.subscription.tier_level }))}
${ssrInterpolate(_ctx.$t("garages.details.expires_at"))}
`); if (garage.value.subscription.expires_at) { _push(`${ssrInterpolate(formatDate(garage.value.subscription.expires_at))}
`); } else { _push(`${ssrInterpolate(_ctx.$t("garages.indefinite"))}
`); } _push(`${ssrInterpolate(_ctx.$t("garages.details.asset_limit"))}
${ssrInterpolate(garage.value.subscription.asset_limit)} ${ssrInterpolate(_ctx.$t("garages.details.vehicles"))}
${ssrInterpolate(_ctx.$t("garages.details.vehicles_used"))}
${ssrInterpolate(fleetVehicles.value.length)} / ${ssrInterpolate(garage.value.subscription?.asset_limit || "∞")}
${ssrInterpolate(_ctx.$t("garages.details.branches_used"))}
${ssrInterpolate(garage.value.branches?.length || 0)} / ${ssrInterpolate(garage.value.subscription?.branch_limit || "∞")}
${ssrInterpolate(_ctx.$t("garages.details.employees_used"))}
${ssrInterpolate(members.value.length)} / ${ssrInterpolate(employeeQuotaLimit.value)}
${ssrInterpolate(_ctx.$t("garages.details.status"))}
${ssrInterpolate(statusLabel(garage.value.status))}${ssrInterpolate(_ctx.$t("garages.details.no_subscription"))}
${ssrInterpolate(_ctx.$t("garages.custom_expiration_hint"))}
${ssrInterpolate(subscriptionSaveError.value)}
| ${ssrInterpolate(_ctx.$t("garages.details.history_date"))} | ${ssrInterpolate(_ctx.$t("garages.details.history_package"))} | ${ssrInterpolate(_ctx.$t("garages.details.history_action"))} | ${ssrInterpolate(_ctx.$t("garages.details.history_status"))} |
|---|---|---|---|
${ssrInterpolate(_ctx.$t("garages.details.no_subscription_history"))} | |||
150 000 Ft
+12% ezen a hónapon
15 000 Ft
${ssrInterpolate(_ctx.$t("garages.analytics.monthly_recurring"))}
0 Ft
${ssrInterpolate(_ctx.$t("garages.analytics.all_settled"))}
450 XP
${ssrInterpolate(_ctx.$t("garages.analytics.contribution_xp"))}
12
${ssrInterpolate(_ctx.$t("garages.analytics.companies_joined"))}
8
${ssrInterpolate(_ctx.$t("garages.analytics.garages_confirmed"))}
${ssrInterpolate(vehicleQuotaPercent.value)}% ${ssrInterpolate(_ctx.$t("garages.analytics.utilized"))}
${ssrInterpolate(employeeQuotaPercent.value)}% ${ssrInterpolate(_ctx.$t("garages.analytics.utilized"))}
${ssrInterpolate(_ctx.$t("garages.employees.editRoleFor", { name: memberFullName(editingMember.value) }))}
${ssrInterpolate(_ctx.$t("garages.employees.removeConfirm", { name: memberFullName(removingMember.value) }))}
${ssrInterpolate(notification.value.message)}