113 lines
15 KiB
JavaScript
113 lines
15 KiB
JavaScript
import { defineComponent, ref, computed, unref, useSSRContext } from "vue";
|
|
import { ssrRenderAttrs, ssrInterpolate, ssrRenderList, ssrRenderStyle, ssrRenderAttr, ssrRenderClass } from "vue/server-renderer";
|
|
import "/app/node_modules/hookable/dist/index.mjs";
|
|
import "/app/node_modules/klona/dist/index.mjs";
|
|
import { a as useI18n } from "../server.mjs";
|
|
import "/app/node_modules/ofetch/dist/node.mjs";
|
|
import "#internal/nuxt/paths";
|
|
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 "vue-router";
|
|
import "/app/node_modules/ufo/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 { t } = useI18n();
|
|
const loading = ref(true);
|
|
const error = ref(false);
|
|
const stats = ref({
|
|
total_users: 0,
|
|
active_users: 0,
|
|
deleted_users: 0,
|
|
banned_users: 0,
|
|
new_users_today: 0,
|
|
new_users_this_week: 0,
|
|
new_users_this_month: 0,
|
|
users_by_role: {},
|
|
users_by_plan: {},
|
|
users_by_language: {},
|
|
users_with_person: 0,
|
|
users_without_person: 0,
|
|
total_vehicles: 0,
|
|
active_organizations_count: 0,
|
|
total_memberships: 0,
|
|
registration_trend: []
|
|
});
|
|
const registrationTrend = computed(() => {
|
|
const trend = stats.value.registration_trend;
|
|
if (!trend.length) return [];
|
|
const maxCount = Math.max(...trend.map((d) => d.count));
|
|
return trend.map((d) => ({
|
|
date: d.date,
|
|
count: d.count,
|
|
height: maxCount > 0 ? d.count / maxCount * 100 : 0
|
|
}));
|
|
});
|
|
function formatNumber(num) {
|
|
return new Intl.NumberFormat().format(num);
|
|
}
|
|
const recentActivities = [
|
|
{ text: "New user registered: john.doe@example.com", time: "2 minutes ago", dotColor: "bg-emerald-400" },
|
|
{ text: "Vehicle #V-8842 added to catalog", time: "15 minutes ago", dotColor: "bg-cyan-400" },
|
|
{ text: "Payment received: €120.00 from Garage XYZ", time: "1 hour ago", dotColor: "bg-emerald-400" },
|
|
{ text: "System error: DVLA API timeout on request #4421", time: "2 hours ago", dotColor: "bg-rose-400" },
|
|
{ text: "Permission updated for user: superadmin@sf.hu", time: "3 hours ago", dotColor: "bg-indigo-400" }
|
|
];
|
|
return (_ctx, _push, _parent, _attrs) => {
|
|
_push(`<div${ssrRenderAttrs(_attrs)}><div class="mb-8"><h1 class="text-2xl font-bold text-white">${ssrInterpolate(unref(t)("dashboard.title"))}</h1><p class="text-slate-400 mt-1">${ssrInterpolate(unref(t)("dashboard.subtitle"))}</p></div>`);
|
|
if (unref(loading)) {
|
|
_push(`<div class="flex items-center justify-center py-20"><div class="text-slate-400 flex items-center gap-3"><svg class="w-5 h-5 animate-spin" fill="none" stroke="currentColor" viewBox="0 0 24 24"><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"></path></svg> ${ssrInterpolate(unref(t)("dashboard.loading"))}</div></div>`);
|
|
} else if (unref(error)) {
|
|
_push(`<div class="bg-rose-500/10 border border-rose-500/30 rounded-xl p-6 mb-8"><p class="text-rose-400">${ssrInterpolate(unref(t)("dashboard.error"))}</p></div>`);
|
|
} else {
|
|
_push(`<!--[--><div class="grid grid-cols-1 sm:grid-cols-2 xl:grid-cols-4 gap-6 mb-8"><div class="bg-slate-800 rounded-xl border border-slate-700 p-6 hover:border-indigo-500/50 transition group"><div class="flex items-center justify-between mb-4"><div class="p-2 rounded-lg bg-indigo-500/10 text-indigo-400 group-hover:bg-indigo-500/20 transition"><svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24"><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.25 2.25 0 11-4.5 0 2.25 2.25 0 014.5 0z"></path></svg></div>`);
|
|
if (unref(stats).new_users_this_month > 0) {
|
|
_push(`<span class="text-xs font-medium text-emerald-400 bg-emerald-400/10 px-2 py-1 rounded-full">+${ssrInterpolate(unref(stats).new_users_this_month)}</span>`);
|
|
} else {
|
|
_push(`<!---->`);
|
|
}
|
|
_push(`</div><h3 class="text-sm font-medium text-slate-400 uppercase tracking-wider">${ssrInterpolate(unref(t)("dashboard.active_users"))}</h3><p class="text-3xl font-bold text-white mt-2">${ssrInterpolate(formatNumber(unref(stats).active_users))}</p><p class="text-xs text-slate-500 mt-1">${ssrInterpolate(formatNumber(unref(stats).new_users_this_month))} ${ssrInterpolate(unref(t)("dashboard.new_this_month"))}</p></div><div class="bg-slate-800 rounded-xl border border-slate-700 p-6 hover:border-cyan-500/50 transition group"><div class="flex items-center justify-between mb-4"><div class="p-2 rounded-lg bg-cyan-500/10 text-cyan-400 group-hover:bg-cyan-500/20 transition"><svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13.5 21v-7.5a.75.75 0 01.75-.75h3a.75.75 0 01.75.75V21m-4.5 0H2.36m11.14 0H18m0 0h3.64m-1.39 0V9.349m-16.5 11.65V9.35m0 0a3.001 3.001 0 003.75-.615A2.993 2.993 0 009.75 9.75c.896 0 1.7-.393 2.25-1.016a2.993 2.993 0 002.25 1.016c.896 0 1.7-.393 2.25-1.016a3.001 3.001 0 003.75.614m-16.5 0a3.004 3.004 0 01-.621-4.72L4.318 3.44A1.5 1.5 0 015.378 3h13.243a1.5 1.5 0 011.06.44l1.19 1.189a3 3 0 01-.621 4.72m-13.5 8.65h3.75a.75.75 0 00.75-.75V13.5a.75.75 0 00-.75-.75H6.75a.75.75 0 00-.75.75v3.75c0 .415.336.75.75.75z"></path></svg></div></div><h3 class="text-sm font-medium text-slate-400 uppercase tracking-wider">${ssrInterpolate(unref(t)("dashboard.total_vehicles"))}</h3><p class="text-3xl font-bold text-white mt-2">${ssrInterpolate(formatNumber(unref(stats).total_vehicles))}</p></div><div class="bg-slate-800 rounded-xl border border-slate-700 p-6 hover:border-emerald-500/50 transition group"><div class="flex items-center justify-between mb-4"><div class="p-2 rounded-lg bg-emerald-500/10 text-emerald-400 group-hover:bg-emerald-500/20 transition"><svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M2.25 21h19.5m-18-18v18m10.5-18v18m6-13.5V21M6.75 6.75h.75m-.75 3h.75m-.75 3h.75m3-6h.75m-.75 3h.75m-.75 3h.75M6.75 21v-3.375c0-.621.504-1.125 1.125-1.125h2.25c.621 0 1.125.504 1.125 1.125V21M3 3h12m-.75 4.5H21m-3.75 3.75h.008v.008h-.008v-.008zm0 3h.008v.008h-.008v-.008zm0 3h.008v.008h-.008v-.008z"></path></svg></div></div><h3 class="text-sm font-medium text-slate-400 uppercase tracking-wider">${ssrInterpolate(unref(t)("dashboard.organizations"))}</h3><p class="text-3xl font-bold text-white mt-2">${ssrInterpolate(formatNumber(unref(stats).active_organizations_count))}</p><p class="text-xs text-slate-500 mt-1">${ssrInterpolate(formatNumber(unref(stats).total_memberships))} ${ssrInterpolate(unref(t)("dashboard.memberships"))}</p></div><div class="bg-slate-800 rounded-xl border border-slate-700 p-6 hover:border-violet-500/50 transition group"><div class="flex items-center justify-between mb-4"><div class="p-2 rounded-lg bg-violet-500/10 text-violet-400 group-hover:bg-violet-500/20 transition"><svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M18 18.72a9.094 9.094 0 003.741-.479 3 3 0 00-4.682-2.72m.94 3.198l.001.031c0 .225-.012.447-.037.666A11.944 11.944 0 0112 21c-2.17 0-4.207-.576-5.963-1.584A6.062 6.062 0 016 18.719m12 0a5.971 5.971 0 00-.941-3.197m0 0A5.995 5.995 0 0012 12.75a5.995 5.995 0 00-5.058 2.772m0 0a3 3 0 00-4.681 2.72 8.986 8.986 0 003.74.477m.94-3.197a5.971 5.971 0 00-.94 3.197M15 6.75a3 3 0 11-6 0 3 3 0 016 0zm6 3a2.25 2.25 0 11-4.5 0 2.25 2.25 0 014.5 0zm-13.5 0a2.25 2.25 0 11-4.5 0 2.25 2.25 0 014.5 0z"></path></svg></div></div><h3 class="text-sm font-medium text-slate-400 uppercase tracking-wider">${ssrInterpolate(unref(t)("dashboard.new_users"))}</h3><p class="text-3xl font-bold text-white mt-2">${ssrInterpolate(formatNumber(unref(stats).new_users_this_month))}</p><p class="text-xs text-slate-500 mt-1">${ssrInterpolate(formatNumber(unref(stats).new_users_today))} ${ssrInterpolate(unref(t)("dashboard.new_today"))}</p></div></div><div class="grid grid-cols-1 lg:grid-cols-3 gap-6 mb-8"><div class="bg-slate-800 rounded-xl border border-slate-700 p-6"><h3 class="text-sm font-medium text-slate-400 uppercase tracking-wider mb-4">${ssrInterpolate(unref(t)("dashboard.users_by_role"))}</h3><div class="space-y-3"><!--[-->`);
|
|
ssrRenderList(unref(stats).users_by_role, (count, role) => {
|
|
_push(`<div class="flex items-center justify-between"><span class="text-sm text-slate-300">${ssrInterpolate(role)}</span><span class="text-sm font-semibold text-white">${ssrInterpolate(count)}</span></div>`);
|
|
});
|
|
_push(`<!--]--></div></div><div class="bg-slate-800 rounded-xl border border-slate-700 p-6"><h3 class="text-sm font-medium text-slate-400 uppercase tracking-wider mb-4">${ssrInterpolate(unref(t)("dashboard.users_by_plan"))}</h3><div class="space-y-3"><!--[-->`);
|
|
ssrRenderList(unref(stats).users_by_plan, (count, plan) => {
|
|
_push(`<div class="flex items-center justify-between"><span class="text-sm text-slate-300">${ssrInterpolate(plan)}</span><span class="text-sm font-semibold text-white">${ssrInterpolate(count)}</span></div>`);
|
|
});
|
|
_push(`<!--]--></div></div><div class="bg-slate-800 rounded-xl border border-slate-700 p-6"><h3 class="text-sm font-medium text-slate-400 uppercase tracking-wider mb-4">${ssrInterpolate(unref(t)("dashboard.users_by_language"))}</h3><div class="space-y-3"><!--[-->`);
|
|
ssrRenderList(unref(stats).users_by_language, (count, lang) => {
|
|
_push(`<div class="flex items-center justify-between"><span class="text-sm text-slate-300">${ssrInterpolate(lang)}</span><span class="text-sm font-semibold text-white">${ssrInterpolate(count)}</span></div>`);
|
|
});
|
|
_push(`<!--]--></div></div></div><div class="bg-slate-800 rounded-xl border border-slate-700 p-6 mb-8"><h3 class="text-sm font-medium text-slate-400 uppercase tracking-wider mb-4">${ssrInterpolate(unref(t)("dashboard.registration_trend"))}</h3><div class="flex items-end gap-1 h-32"><!--[-->`);
|
|
ssrRenderList(unref(registrationTrend), (day, idx) => {
|
|
_push(`<div class="flex-1 bg-indigo-500/60 hover:bg-indigo-400/80 rounded-t transition-all cursor-pointer relative group" style="${ssrRenderStyle({ height: day.height + "%" })}"${ssrRenderAttr("title", day.date + ": " + day.count + " users")}><div class="absolute -top-8 left-1/2 -translate-x-1/2 bg-slate-700 text-xs text-white px-2 py-1 rounded opacity-0 group-hover:opacity-100 transition whitespace-nowrap">${ssrInterpolate(day.date)}: ${ssrInterpolate(day.count)}</div></div>`);
|
|
});
|
|
_push(`<!--]--></div></div><div class="grid grid-cols-1 lg:grid-cols-2 gap-6"><div class="bg-slate-800 rounded-xl border border-slate-700 p-6"><h2 class="text-lg font-semibold text-white mb-4">${ssrInterpolate(unref(t)("dashboard.quick_actions"))}</h2><div class="space-y-3"><button class="w-full flex items-center gap-3 px-4 py-3 bg-slate-700/50 hover:bg-slate-700 rounded-lg text-sm text-slate-300 hover:text-white transition text-left"><svg class="w-5 h-5 text-indigo-400 flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24"><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.25 2.25 0 11-4.5 0 2.25 2.25 0 014.5 0z"></path></svg> ${ssrInterpolate(unref(t)("dashboard.invite_admin"))}</button><button class="w-full flex items-center gap-3 px-4 py-3 bg-slate-700/50 hover:bg-slate-700 rounded-lg text-sm text-slate-300 hover:text-white transition text-left"><svg class="w-5 h-5 text-cyan-400 flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13.5 21v-7.5a.75.75 0 01.75-.75h3a.75.75 0 01.75.75V21m-4.5 0H2.36m11.14 0H18m0 0h3.64m-1.39 0V9.349m-16.5 11.65V9.35m0 0a3.001 3.001 0 003.75-.615A2.993 2.993 0 009.75 9.75c.896 0 1.7-.393 2.25-1.016a2.993 2.993 0 002.25 1.016c.896 0 1.7-.393 2.25-1.016a3.001 3.001 0 003.75.614m-16.5 0a3.004 3.004 0 01-.621-4.72L4.318 3.44A1.5 1.5 0 015.378 3h13.243a1.5 1.5 0 011.06.44l1.19 1.189a3 3 0 01-.621 4.72m-13.5 8.65h3.75a.75.75 0 00.75-.75V13.5a.75.75 0 00-.75-.75H6.75a.75.75 0 00-.75.75v3.75c0 .415.336.75.75.75z"></path></svg> ${ssrInterpolate(unref(t)("dashboard.add_vehicle"))}</button><button class="w-full flex items-center gap-3 px-4 py-3 bg-slate-700/50 hover:bg-slate-700 rounded-lg text-sm text-slate-300 hover:text-white transition text-left"><svg class="w-5 h-5 text-emerald-400 flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12h3.75M9 15h3.75M9 18h3.75m3 .75H18a2.25 2.25 0 002.25-2.25V6.108c0-1.135-.845-2.098-1.976-2.192a48.424 48.424 0 00-1.123-.08m-5.801 0c-.065.21-.1.433-.1.664 0 .414.336.75.75.75h4.5a.75.75 0 00.75-.75 2.25 2.25 0 00-.1-.664m-5.8 0A2.251 2.251 0 0113.5 2.25H15a2.25 2.25 0 012.15 1.586m-5.8 0c-.376.023-.75.05-1.124.08C9.095 4.01 8.25 4.973 8.25 6.108V8.25m0 0H4.875c-.621 0-1.125.504-1.125 1.125v11.25c0 .621.504 1.125 1.125 1.125h9.75c.621 0 1.125-.504 1.125-1.125V9.375c0-.621-.504-1.125-1.125-1.125H8.25zM6.75 12h.008v.008H6.75V12zm0 3h.008v.008H6.75V15zm0 3h.008v.008H6.75V18z"></path></svg> ${ssrInterpolate(unref(t)("dashboard.view_reports"))}</button></div></div><div class="bg-slate-800 rounded-xl border border-slate-700 p-6"><h2 class="text-lg font-semibold text-white mb-4">${ssrInterpolate(unref(t)("dashboard.recent_activity"))}</h2><div class="space-y-4"><!--[-->`);
|
|
ssrRenderList(recentActivities, (activity, index) => {
|
|
_push(`<div class="flex items-start gap-3"><div class="${ssrRenderClass([activity.dotColor, "w-2 h-2 mt-2 rounded-full flex-shrink-0"])}"></div><div class="flex-1 min-w-0"><p class="text-sm text-slate-300">${ssrInterpolate(activity.text)}</p><p class="text-xs text-slate-500 mt-0.5">${ssrInterpolate(activity.time)}</p></div></div>`);
|
|
});
|
|
_push(`<!--]--></div></div></div><!--]-->`);
|
|
}
|
|
_push(`</div>`);
|
|
};
|
|
}
|
|
});
|
|
const _sfc_setup = _sfc_main.setup;
|
|
_sfc_main.setup = (props, ctx) => {
|
|
const ssrContext = useSSRContext();
|
|
(ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("pages/index.vue");
|
|
return _sfc_setup ? _sfc_setup(props, ctx) : void 0;
|
|
};
|
|
export {
|
|
_sfc_main as default
|
|
};
|
|
//# sourceMappingURL=index-Cv2HQkhy.js.map
|