import { defineComponent, computed, mergeProps, useSSRContext, ref, reactive, watch, unref } from "vue";
import { ssrRenderAttrs, ssrInterpolate, ssrRenderList, ssrRenderClass, ssrRenderStyle, ssrIncludeBooleanAttr, ssrLooseContain, ssrLooseEqual, ssrRenderAttr, ssrRenderComponent } from "vue/server-renderer";
import { c as useAuthStore, d as useCookie } from "../server.mjs";
import { useRoute, useRouter } from "vue-router";
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$3 = /* @__PURE__ */ defineComponent({
__name: "GarageGeneralTab",
__ssrInlineRender: true,
props: {
garage: {}
},
setup(__props) {
const props = __props;
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 Intl.DateTimeFormat("hu-HU", {
year: "numeric",
month: "2-digit",
day: "2-digit"
}).format(new Date(dateStr));
} catch {
return dateStr;
}
}
const formattedAddress = computed(() => {
if (!props.garage) return "";
const parts = [
props.garage.address_zip,
props.garage.address_city,
props.garage.address_street_name,
props.garage.address_street_type,
props.garage.address_house_number
].filter(Boolean);
return parts.join(" ") || "-";
});
const formattedBillingAddress = computed(() => {
if (!props.garage) return "";
const parts = [
props.garage.billing_zip,
props.garage.billing_city,
props.garage.billing_street_name,
props.garage.billing_street_type,
props.garage.billing_house_number
].filter(Boolean);
return parts.join(" ") || "";
});
const formattedNotificationAddress = computed(() => {
if (!props.garage) return "";
const parts = [
props.garage.notification_zip,
props.garage.notification_city,
props.garage.notification_street_name,
props.garage.notification_street_type,
props.garage.notification_house_number
].filter(Boolean);
return parts.join(" ") || "";
});
return (_ctx, _push, _parent, _attrs) => {
_push(`
${ssrInterpolate(_ctx.$t("garages.details.company_info"))}
${ssrInterpolate(_ctx.$t("garages.details.company_name"))}
${ssrInterpolate(__props.garage.full_name)}
${ssrInterpolate(_ctx.$t("garages.details.display_name"))}
${ssrInterpolate(__props.garage.display_name || "—")}
${ssrInterpolate(_ctx.$t("garages.details.org_type"))}
${ssrInterpolate(orgTypeLabel(__props.garage.org_type))}
${ssrInterpolate(_ctx.$t("garages.details.tax_number"))}
${ssrInterpolate(__props.garage.tax_number || "—")}
${ssrInterpolate(_ctx.$t("garages.details.reg_number"))}
${ssrInterpolate(__props.garage.reg_number || "—")}
${ssrInterpolate(_ctx.$t("garages.details.created_at"))}
${ssrInterpolate(formatDate(__props.garage.created_at))}
${ssrInterpolate(_ctx.$t("garages.details.address"))}
${ssrInterpolate(formattedAddress.value)}
`);
if (formattedBillingAddress.value) {
_push(`
${ssrInterpolate(_ctx.$t("garages.details.billing_address"))}
${ssrInterpolate(formattedBillingAddress.value)}
`);
} else {
_push(``);
}
if (formattedNotificationAddress.value) {
_push(`
${ssrInterpolate(_ctx.$t("garages.details.notification_address"))}
${ssrInterpolate(formattedNotificationAddress.value)}
`);
} else {
_push(``);
}
_push(`
Rendszer Azonosítók
Garázs ID: ${ssrInterpolate(__props.garage.id)}User ID: ${ssrInterpolate(__props.garage.owner_user_id ?? "N/A")}Person ID: ${ssrInterpolate(__props.garage.owner_person_id ?? "N/A")}
${ssrInterpolate(_ctx.$t("garages.details.contact_info"))}
`);
if (__props.garage.contact_person_name || __props.garage.contact_email || __props.garage.contact_phone || __props.garage.primary_contact) {
_push(`
${ssrInterpolate(_ctx.$t("garages.details.contact_name"))}
${ssrInterpolate(__props.garage.contact_person_name || __props.garage.primary_contact?.full_name || "—")}
${ssrInterpolate(_ctx.$t("garages.details.contact_email"))}
${ssrInterpolate(__props.garage.contact_email || __props.garage.primary_contact?.email || "—")}
${ssrInterpolate(_ctx.$t("garages.details.contact_phone"))}
${ssrInterpolate(__props.garage.contact_phone || __props.garage.primary_contact?.phone || "—")}
`);
if (__props.garage.primary_contact?.role || __props.garage.primary_contact?.department) {
_push(`
${ssrInterpolate(_ctx.$t("garages.details.contact_role"))}
${ssrInterpolate(__props.garage.primary_contact.role || "—")}`);
if (__props.garage.primary_contact?.department) {
_push(` · ${ssrInterpolate(__props.garage.primary_contact.department)}`);
} else {
_push(``);
}
_push(`
`);
} else {
_push(``);
}
_push(`
`);
} else {
_push(`
${ssrInterpolate(_ctx.$t("garages.details.no_contact"))}
`);
}
_push(`
`);
};
}
});
const _sfc_setup$3 = _sfc_main$3.setup;
_sfc_main$3.setup = (props, ctx) => {
const ssrContext = useSSRContext();
(ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("components/garages/GarageGeneralTab.vue");
return _sfc_setup$3 ? _sfc_setup$3(props, ctx) : void 0;
};
const _sfc_main$2 = /* @__PURE__ */ defineComponent({
__name: "GarageFleetTab",
__ssrInlineRender: true,
props: {
garage: {},
orgId: {},
fleetVehicles: {},
fleetLoading: { type: Boolean }
},
setup(__props) {
const props = __props;
const auth = useAuthStore();
function hasOrgPermission(perm) {
if (auth.isAdmin) return true;
if (auth.user?.system_capabilities?.[perm]) return true;
if (auth.user?.org_capabilities?.[props.orgId]?.[perm]) return true;
return false;
}
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";
}
return (_ctx, _push, _parent, _attrs) => {
_push(``);
if (hasOrgPermission("fleet:view")) {
_push(`
${ssrInterpolate(_ctx.$t("garages.fleet.title"))}
${ssrInterpolate(_ctx.$t("garages.fleet.total_vehicles", { count: __props.fleetVehicles.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"))} |
`);
ssrRenderList(__props.fleetVehicles, (v) => {
_push(`| ${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))} |
`);
});
_push(``);
if (__props.fleetVehicles.length === 0 && !__props.fleetLoading) {
_push(`${ssrInterpolate(_ctx.$t("garages.fleet.no_vehicles"))} |
`);
} else {
_push(``);
}
if (__props.fleetLoading) {
_push(`${ssrInterpolate(_ctx.$t("garages.details.loading"))} |
`);
} else {
_push(``);
}
_push(`
`);
} else {
_push(`
${ssrInterpolate(_ctx.$t("garages.fleet.no_fleet_access"))}
`);
}
_push(`
`);
};
}
});
const _sfc_setup$2 = _sfc_main$2.setup;
_sfc_main$2.setup = (props, ctx) => {
const ssrContext = useSSRContext();
(ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("components/garages/GarageFleetTab.vue");
return _sfc_setup$2 ? _sfc_setup$2(props, ctx) : void 0;
};
const _sfc_main$1 = /* @__PURE__ */ defineComponent({
__name: "GarageSubscriptionTab",
__ssrInlineRender: true,
props: {
garage: {},
fleetVehicles: {}
},
emits: ["refresh"],
setup(__props, { expose: __expose, emit: __emit }) {
const props = __props;
const auth = useAuthStore();
const availableTiers = ref([]);
const selectedTierId = ref("");
const customExpiresAt = ref("");
const subscriptionSaving = ref(false);
const subscriptionSaveError = ref(null);
const extraVehicles = ref(0);
const extraBranches = ref(0);
const extraUsers = ref(0);
const addonDates = reactive({
vehicles: "",
branches: "",
users: ""
});
function syncAddonFromSubscription() {
const sub = props.garage?.subscription;
if (!sub) return;
const allowances = sub.extra_allowances || {};
extraVehicles.value = allowances.extra_vehicles ?? 0;
extraBranches.value = allowances.extra_branches ?? 0;
extraUsers.value = allowances.extra_users ?? 0;
if (sub.addons?.length) {
for (const addon of sub.addons) {
if (addon.type === "extra_vehicles" && addon.expires_at) {
addonDates.vehicles = addon.expires_at.slice(0, 10);
} else if (addon.type === "extra_branches" && addon.expires_at) {
addonDates.branches = addon.expires_at.slice(0, 10);
} else if (addon.type === "extra_users" && addon.expires_at) {
addonDates.users = addon.expires_at.slice(0, 10);
}
}
}
}
watch(() => props.garage?.subscription, (newSub) => {
if (newSub) {
syncAddonFromSubscription();
}
}, { immediate: true });
const vehicleQuotaLimit = computed(() => {
if (!props.garage?.subscription?.asset_limit) return 5;
return props.garage.subscription.asset_limit;
});
const vehicleQuotaPercent = computed(() => {
const limit = vehicleQuotaLimit.value;
if (limit <= 0) return 0;
return Math.min(100, Math.round(props.fleetVehicles.length / limit * 100));
});
const branchQuotaPercent = computed(() => {
const branches = props.garage?.branches?.length || 0;
const limit = props.garage?.subscription?.branch_limit;
if (!limit || limit <= 0) return 0;
return Math.min(100, Math.round(branches / limit * 100));
});
const employeeQuotaPercent = computed(() => {
const count = props.garage?.member_count || 0;
const limit = props.garage?.subscription?.user_limit;
if (!limit || limit <= 0) return 0;
return Math.min(100, Math.round(count / limit * 100));
});
const addonsChanged = computed(() => {
if (!props.garage?.subscription) return false;
const sub = props.garage.subscription;
const baselineVehicles = sub.extra_allowances?.extra_vehicles ?? 0;
const baselineBranches = sub.extra_allowances?.extra_branches ?? 0;
const baselineUsers = sub.extra_allowances?.extra_users ?? 0;
return extraVehicles.value !== baselineVehicles || extraBranches.value !== baselineBranches || extraUsers.value !== baselineUsers;
});
function formatChanges(hist) {
if (!hist) return null;
const oldData = hist.old_data || {};
const newData = hist.new_data || {};
const lines = [];
if (hist.action === "SUBSCRIPTION_TIER_CHANGE") {
const oldTier = oldData.tier_id;
const newTier = newData.tier_id;
const newTierName = newData.tier_name;
if (oldTier !== void 0 || newTier !== void 0) {
lines.push(`Csomag: #${oldTier ?? "?"} → ${newTierName ?? "#" + newTier}`);
}
const oldAddons = oldData.addons || {};
const newAddons = newData.addons || {};
for (const key of ["extra_vehicles", "extra_branches", "extra_users"]) {
const oldVal = oldAddons[key] ?? 0;
const newVal = newAddons[key] ?? 0;
if (oldVal !== newVal) {
const label = key === "extra_vehicles" ? "Extra Jármű" : key === "extra_branches" ? "Extra Telephely" : "Extra Dolgozó";
lines.push(`${label}: ${oldVal} → ${newVal}`);
}
}
return lines.length > 0 ? lines : null;
}
if (hist.action === "SUBSCRIPTION_ADDON_OVERRIDE") {
const oldAddons = oldData.addons || {};
const newAddons = newData.addons || {};
let hasChanges = false;
for (const key of ["extra_vehicles", "extra_branches", "extra_users"]) {
const oldVal = oldAddons[key] ?? 0;
const newVal = newAddons[key] ?? 0;
if (oldVal !== newVal) {
hasChanges = true;
const label = key === "extra_vehicles" ? "Extra Jármű" : key === "extra_branches" ? "Extra Telephely" : "Extra Dolgozó";
lines.push(`${label}: ${oldVal} → ${newVal}`);
}
}
return hasChanges ? lines : null;
}
const allKeys = /* @__PURE__ */ new Set([...Object.keys(oldData), ...Object.keys(newData)]);
for (const key of allKeys) {
if (key === "addons") continue;
const oldVal = JSON.stringify(oldData[key] ?? null);
const newVal = JSON.stringify(newData[key] ?? null);
if (oldVal !== newVal) {
lines.push(`${key}: ${oldVal} → ${newVal}`);
}
}
return lines.length > 0 ? lines : null;
}
function formatDate(dateStr) {
if (!dateStr) return "-";
try {
return new Intl.DateTimeFormat("hu-HU", {
year: "numeric",
month: "2-digit",
day: "2-digit"
}).format(new Date(dateStr));
} catch {
return dateStr;
}
}
function addonLabel(type) {
const map = {
extra_vehicles: "Extra Jármű",
extra_branches: "Extra Telephely",
extra_users: "Extra Dolgozó"
};
return map[type] || type;
}
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 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";
}
async function fetchTiers() {
try {
const tokenCookie = useCookie("access_token");
const token = (tokenCookie.value || auth.token || "").trim();
console.log("[GarageSubscriptionTab] Fetching tiers...");
const res = await fetch("/api/v1/admin/packages?include_hidden=true&limit=100", {
headers: {
"Authorization": `Bearer ${token}`,
"Content-Type": "application/json"
}
});
if (!res.ok) {
const errBody = await res.text().catch(() => "");
console.error(`[GarageSubscriptionTab] Fetch tiers failed: ${res.status} ${res.statusText}`, errBody);
throw new Error(`Failed to fetch tiers: ${res.status} ${errBody}`);
}
const data = await res.json();
console.log("[GarageSubscriptionTab] Fetched tiers response:", JSON.stringify(data));
availableTiers.value = data.tiers || [];
console.log("[GarageSubscriptionTab] availableTiers set:", availableTiers.value.length, "items");
} catch (e) {
console.error("[GarageSubscriptionTab] Failed to fetch tiers:", e);
subscriptionSaveError.value = `Hiba a csomagok betöltésekor: ${e.message}`;
}
}
__expose({ fetchTiers });
return (_ctx, _push, _parent, _attrs) => {
_push(`${ssrInterpolate(_ctx.$t("garages.details.subscription_info"))}
`);
if (__props.garage.subscription) {
_push(`
${ssrInterpolate(_ctx.$t("garages.details.tier_name"))}
${ssrInterpolate(__props.garage.subscription.tier_name)}${ssrInterpolate(_ctx.$t("garages.details.tier_level"))}
${ssrInterpolate(_ctx.$t("garages.details.level_n", { n: __props.garage.subscription.tier_level }))}
${ssrInterpolate(_ctx.$t("garages.details.expires_at"))}
`);
if (__props.garage.subscription.expires_at) {
_push(`
${ssrInterpolate(formatDate(__props.garage.subscription.expires_at))}
`);
} else {
_push(`
${ssrInterpolate(_ctx.$t("garages.indefinite"))}
`);
}
_push(`
${ssrInterpolate(_ctx.$t("garages.details.asset_limit"))}
${ssrInterpolate(__props.garage.subscription.asset_limit)} ${ssrInterpolate(_ctx.$t("garages.details.vehicles"))}
`);
} else {
_push(``);
}
if (__props.garage.subscription) {
_push(`
${ssrInterpolate(_ctx.$t("garages.details.vehicles_used"))}
${ssrInterpolate(__props.fleetVehicles.length)} / ${ssrInterpolate(__props.garage.subscription?.asset_limit ?? "∞")}
= 70 ? "bg-amber-500" : "bg-blue-500", "h-full rounded-full transition-all duration-500"])}" style="${ssrRenderStyle({ width: Math.min(100, vehicleQuotaPercent.value) + "%" })}">
${ssrInterpolate(_ctx.$t("garages.details.branches_used"))}
${ssrInterpolate(__props.garage.branches?.length || 0)} / ${ssrInterpolate(__props.garage.subscription?.branch_limit ?? "∞")}
= 70 ? "bg-amber-500" : "bg-emerald-500", "h-full rounded-full transition-all duration-500"])}" style="${ssrRenderStyle({ width: Math.min(100, branchQuotaPercent.value) + "%" })}">
${ssrInterpolate(_ctx.$t("garages.details.employees_used"))}
${ssrInterpolate(__props.garage.member_count || 0)} / ${ssrInterpolate(__props.garage.subscription?.user_limit && __props.garage.subscription.user_limit > 0 ? __props.garage.subscription.user_limit : "∞")}
`);
if (__props.garage.subscription?.user_limit && __props.garage.subscription.user_limit > 0) {
_push(`
= 70 ? "bg-amber-500" : "bg-purple-500", "h-full rounded-full transition-all duration-500"])}" style="${ssrRenderStyle({ width: Math.min(100, employeeQuotaPercent.value) + "%" })}">
`);
} else {
_push(``);
}
_push(`
${ssrInterpolate(_ctx.$t("garages.details.status"))}
${ssrInterpolate(statusLabel(__props.garage.status))}`);
} else {
_push(``);
}
if (__props.garage.subscription?.addons?.length) {
_push(`
${ssrInterpolate(_ctx.$t("garages.active_addons"))}
| ${ssrInterpolate(_ctx.$t("garages.addon_type"))} | ${ssrInterpolate(_ctx.$t("garages.addon_quantity"))} | ${ssrInterpolate(_ctx.$t("garages.addon_expires"))} |
`);
ssrRenderList(__props.garage.subscription.addons, (addon) => {
_push(`| ${ssrInterpolate(addonLabel(addon.type))} | ${ssrInterpolate(addon.quantity)} | `);
if (addon.expires_at || addon.valid_until) {
_push(`${ssrInterpolate(formatDate(addon.expires_at || addon.valid_until))}`);
} else {
_push(`${ssrInterpolate(_ctx.$t("garages.indefinite"))}`);
}
_push(` |
`);
});
_push(`
`);
} else if (__props.garage.subscription) {
_push(`
${ssrInterpolate(_ctx.$t("garages.active_addons"))}
${ssrInterpolate(_ctx.$t("garages.no_active_addons"))}
`);
} else {
_push(`
${ssrInterpolate(_ctx.$t("garages.details.no_subscription"))}
`);
}
_push(`
${ssrInterpolate(_ctx.$t("garages.change_package"))}
${ssrInterpolate(_ctx.$t("garages.addon_expiration_hint"))}
`);
if (subscriptionSaveError.value) {
_push(`
${ssrInterpolate(subscriptionSaveError.value)}
`);
} else {
_push(``);
}
_push(`
${ssrInterpolate(_ctx.$t("garages.details.subscription_history"))}
| ${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"))} |
`);
if (__props.garage?.subscription_history?.length) {
_push(``);
ssrRenderList(__props.garage.subscription_history, (hist) => {
_push(`| ${ssrInterpolate(formatDate(hist.timestamp))} | ${ssrInterpolate(hist.tier_name || "—")} | ${ssrInterpolate(hist.action || "—")}`);
if (formatChanges(hist)) {
_push(` `);
ssrRenderList(formatChanges(hist), (line, li) => {
_push(` ›${ssrInterpolate(line)} `);
});
_push(` `);
} else {
_push(` Nincs részletes adat`);
}
_push(` | Sikeres `);
if (hist.admin_user_id) {
_push(` Admin #${ssrInterpolate(hist.admin_user_id)}`);
} else {
_push(``);
}
_push(` |
`);
});
_push(``);
} else {
_push(`${ssrInterpolate(_ctx.$t("garages.details.no_subscription_history"))} |
`);
}
_push(`
`);
};
}
});
const _sfc_setup$1 = _sfc_main$1.setup;
_sfc_main$1.setup = (props, ctx) => {
const ssrContext = useSSRContext();
(ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("components/garages/GarageSubscriptionTab.vue");
return _sfc_setup$1 ? _sfc_setup$1(props, ctx) : void 0;
};
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 subscriptionTabRef = ref(null);
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);
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 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));
});
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));
});
computed(() => {
const count = garage.value?.member_count || 0;
const limit = garage.value?.subscription?.user_limit;
if (!limit || limit <= 0) return 0;
return Math.min(100, Math.round(count / 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" });
}
return missing;
});
async function fetchDetails() {
loading.value = true;
error.value = null;
try {
const tokenCookie = useCookie("access_token");
const token = (tokenCookie.value || auth.token || "").trim();
const headers = {
"Authorization": `Bearer ${token}`,
"Content-Type": "application/json"
};
const res = await fetch(`/api/v1/admin/organizations/${orgId}/details`, { headers });
if (!res.ok) throw new Error(`Failed to fetch organization: ${res.status}`);
const data = await res.json();
garage.value = data;
members.value = data.members || [];
} catch (e) {
error.value = e.message || "Failed to load garage details";
} finally {
loading.value = false;
}
}
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;
}
}
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 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";
}
watch(activeTab, (newTab) => {
if (newTab === "fleet" || newTab === "analytics" || newTab === "subscription") {
if (fleetVehicles.value.length === 0) {
fetchFleetVehicles();
}
}
if (newTab === "subscription") {
subscriptionTabRef.value?.fetchTiers();
}
});
return (_ctx, _push, _parent, _attrs) => {
const _component_GaragesGarageGeneralTab = _sfc_main$3;
const _component_GaragesGarageFleetTab = _sfc_main$2;
const _component_GaragesGarageSubscriptionTab = _sfc_main$1;
_push(``);
if (loading.value) {
_push(`
${ssrInterpolate(_ctx.$t("garages.details.loading"))}
`);
} else if (error.value) {
_push(`
${ssrInterpolate(error.value)}
`);
} else if (garage.value) {
_push(``);
if (missingFields.value.length > 0) {
_push(`
${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"))}
`);
ssrRenderList(missingFields.value, (field) => {
_push(`
${ssrInterpolate(_ctx.$t(field.label))}`);
});
_push(`
`);
} else {
_push(``);
}
_push(`
${ssrInterpolate(getInitials(garageDisplayName()))}
${ssrInterpolate(cleanGarageName.value)}
${ssrInterpolate(statusLabel(garage.value.status))}${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(`
`);
if (hasOrgPermission("org:edit")) {
_push(`
`);
} else {
_push(``);
}
_push(`
`);
if (activeTab.value === "general") {
_push(ssrRenderComponent(_component_GaragesGarageGeneralTab, { garage: garage.value }, null, _parent));
} else {
_push(``);
}
if (activeTab.value === "employees") {
_push(`
${ssrInterpolate(_ctx.$t("garages.employees.title"))}
${ssrInterpolate(_ctx.$t("garages.employees.total_count", { count: members.value.length }))}
`);
if (hasOrgPermission("org:manage-members")) {
_push(`
`);
} else {
_push(``);
}
_push(`
| ${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"))} |
`);
ssrRenderList(members.value, (member) => {
_push(`${ssrInterpolate(getInitials(memberFullName(member)))} ${ssrInterpolate(memberFullName(member))} ID: ${ssrInterpolate(member.user_id || member.id)} User_id: ${ssrInterpolate(member.user_id || "N/A")}Person_id: ${ssrInterpolate(member.person?.id || "N/A")} | `);
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(` |
`);
});
_push(``);
if (members.value.length === 0) {
_push(`${ssrInterpolate(_ctx.$t("garages.employees.no_employees"))} |
`);
} else {
_push(``);
}
_push(`
`);
} else {
_push(``);
}
if (activeTab.value === "fleet") {
_push(ssrRenderComponent(_component_GaragesGarageFleetTab, {
garage: garage.value,
"org-id": unref(orgId),
"fleet-vehicles": fleetVehicles.value,
"fleet-loading": fleetLoading.value
}, null, _parent));
} else {
_push(``);
}
if (activeTab.value === "subscription") {
_push(ssrRenderComponent(_component_GaragesGarageSubscriptionTab, {
ref_key: "subscriptionTabRef",
ref: subscriptionTabRef,
garage: garage.value,
"fleet-vehicles": fleetVehicles.value,
onRefresh: fetchDetails
}, null, _parent));
} else {
_push(``);
}
if (activeTab.value === "analytics") {
_push(`
${ssrInterpolate(_ctx.$t("garages.analytics.ltv"))} 150 000 Ft
+12% ezen a hónapon
${ssrInterpolate(_ctx.$t("garages.analytics.mrr"))} 15 000 Ft
${ssrInterpolate(_ctx.$t("garages.analytics.monthly_recurring"))}
${ssrInterpolate(_ctx.$t("garages.analytics.outstanding"))} 0 Ft
${ssrInterpolate(_ctx.$t("garages.analytics.all_settled"))}
${ssrInterpolate(_ctx.$t("garages.analytics.earned_credits"))} 450 XP
${ssrInterpolate(_ctx.$t("garages.analytics.contribution_xp"))}
${ssrInterpolate(_ctx.$t("garages.analytics.invited_companies"))} 12
${ssrInterpolate(_ctx.$t("garages.analytics.companies_joined"))}
${ssrInterpolate(_ctx.$t("garages.analytics.validated_garages"))} 8
${ssrInterpolate(_ctx.$t("garages.analytics.garages_confirmed"))}
${ssrInterpolate(_ctx.$t("garages.analytics.utilization"))}
${ssrInterpolate(_ctx.$t("garages.analytics.vehicle_quota"))}${ssrInterpolate(fleetVehicles.value.length)} / ${ssrInterpolate(vehicleQuotaLimit.value)}
= 70 ? "bg-amber-500" : "bg-blue-500", "h-full rounded-full transition-all duration-500"])}" style="${ssrRenderStyle({ width: vehicleQuotaPercent.value + "%" })}">
${ssrInterpolate(vehicleQuotaPercent.value)}% ${ssrInterpolate(_ctx.$t("garages.analytics.utilized"))}
${ssrInterpolate(_ctx.$t("garages.analytics.marketplace_engagement"))}
${ssrInterpolate(_ctx.$t("garages.analytics.avg_rating"))} ${ssrInterpolate(_ctx.$t("garages.analytics.total_reviews"))}124
${ssrInterpolate(_ctx.$t("garages.analytics.service_requests"))}47
${ssrInterpolate(_ctx.$t("garages.analytics.response_rate"))}92%
`);
} else {
_push(``);
}
if (showEditModal.value) {
_push(`
${ssrInterpolate(_ctx.$t("garages.details.edit_details"))}
`);
if (editModalTab.value === "basic") {
_push(`
`);
} else {
_push(``);
}
if (editModalTab.value === "contact") {
_push(`
`);
} else {
_push(``);
}
if (editModalTab.value === "addresses") {
_push(`
`);
} else {
_push(``);
}
_push(`
`);
} else {
_push(``);
}
if (showAddEmployeeModal.value) {
_push(`
${ssrInterpolate(_ctx.$t("garages.employees.add_employee"))}
`);
} else {
_push(``);
}
if (showEditRoleModal.value) {
_push(`
${ssrInterpolate(_ctx.$t("garages.employees.edit_role"))}
`);
} else {
_push(``);
}
if (showRemoveModal.value) {
_push(`
${ssrInterpolate(_ctx.$t("garages.employees.removeTitle"))}
${ssrInterpolate(_ctx.$t("garages.employees.removeConfirm", { name: memberFullName(removingMember.value) }))}
`);
} else {
_push(``);
}
if (notification.value.show) {
_push(`
`);
if (notification.value.type === "success") {
_push(`
`);
} else {
_push(``);
}
if (notification.value.type === "error") {
_push(`
`);
} else {
_push(``);
}
_push(`
${ssrInterpolate(notification.value.message)}
`);
} else {
_push(``);
}
_push(``);
} else {
_push(``);
}
_push(`
`);
};
}
});
const _sfc_setup = _sfc_main.setup;
_sfc_main.setup = (props, ctx) => {
const ssrContext = useSSRContext();
(ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("pages/garages/[id]/index.vue");
return _sfc_setup ? _sfc_setup(props, ctx) : void 0;
};
export {
_sfc_main as default
};
//# sourceMappingURL=index-CKl-ge5n.js.map