@oneclick.dev/cms-core-modules 0.0.78 → 0.0.79
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{AppointmentDetailsCard-SMNXi117.mjs → AppointmentDetailsCard-Bu9VzIRx.mjs} +54 -55
- package/dist/AppointmentDetailsCard-LL-6PARb.js +1 -0
- package/dist/{AppointmentListTable-vMSMt0M5.mjs → AppointmentListTable-B8YLwOfT.mjs} +41 -42
- package/dist/AppointmentListTable-DNvvb4sz.js +1 -0
- package/dist/CountryBreakdownCard-BpDXbxwZ.js +1 -0
- package/dist/{CountryBreakdownCard-B_VhBsm8.mjs → CountryBreakdownCard-oDzmpvAd.mjs} +45 -46
- package/dist/DeviceBreakdownCard-OXiU9Cf0.js +1 -0
- package/dist/DeviceBreakdownCard-Oh_yzipG.mjs +159 -0
- package/dist/{PeakHoursCard-_1JS0tpZ.mjs → PeakHoursCard-DzNo4SNo.mjs} +56 -57
- package/dist/PeakHoursCard-OkgI1vnd.js +1 -0
- package/dist/ProductDetailsCard-BBOorNmB.js +1 -0
- package/dist/{ProductDetailsCard-C5gqBJag.mjs → ProductDetailsCard-CYK9Mtt4.mjs} +44 -45
- package/dist/RealtimeCard-DESm9Fs_.js +1 -0
- package/dist/{RealtimeCard-CtX6Yyk-.mjs → RealtimeCard-tNUSIw6B.mjs} +44 -45
- package/dist/{SearchTermsCard-DzSu9jzo.mjs → SearchTermsCard-BVHFHWUZ.mjs} +66 -67
- package/dist/SearchTermsCard-DmyhGQVM.js +1 -0
- package/dist/{TopPagesCard-D7lH_QYV.mjs → TopPagesCard-CRIa3rSZ.mjs} +52 -53
- package/dist/TopPagesCard-CgtNyhwY.js +1 -0
- package/dist/TrafficSourcesCard-CPAxaQTi.js +1 -0
- package/dist/{TrafficSourcesCard-Fng3fVh7.mjs → TrafficSourcesCard-Ct20QYax.mjs} +48 -49
- package/dist/VisitorStatsCard-Cs6jPehw.js +1 -0
- package/dist/{VisitorStatsCard-CuXXnMBc.mjs → VisitorStatsCard-DMULybKV.mjs} +57 -58
- package/dist/index.cjs.js +1 -1
- package/dist/index.mjs +11 -11
- package/package.json +2 -2
- package/dist/AppointmentDetailsCard-BfBwWxTU.js +0 -1
- package/dist/AppointmentListTable-Dk-CnNR6.js +0 -1
- package/dist/CountryBreakdownCard-Ghg0Wz-h.js +0 -1
- package/dist/DeviceBreakdownCard-CQR65Zr_.mjs +0 -160
- package/dist/DeviceBreakdownCard-Cpcj75Rv.js +0 -1
- package/dist/PeakHoursCard-CFIg8dys.js +0 -1
- package/dist/ProductDetailsCard-Ce11f_9r.js +0 -1
- package/dist/RealtimeCard-CatAzdxv.js +0 -1
- package/dist/SearchTermsCard-BPAdRL-r.js +0 -1
- package/dist/TopPagesCard-BA9Are_Z.js +0 -1
- package/dist/TrafficSourcesCard-DV13ZOBq.js +0 -1
- package/dist/VisitorStatsCard-CAzAZtKD.js +0 -1
|
@@ -1,22 +1,21 @@
|
|
|
1
|
-
import { defineComponent as
|
|
2
|
-
import { Loader2 as
|
|
3
|
-
|
|
4
|
-
const H = { class: "w-full" }, J = {
|
|
1
|
+
import { defineComponent as A, computed as T, ref as x, onMounted as L, resolveComponent as j, openBlock as d, createElementBlock as l, unref as r, createVNode as i, createElementVNode as t, toDisplayString as a, Fragment as P, renderList as M, normalizeClass as E, createCommentVNode as V, withCtx as D, createTextVNode as F } from "vue";
|
|
2
|
+
import { Loader2 as R, CalendarDays as g, Mail as B, Clock as O, Users as U, ExternalLink as q } from "lucide-vue-next";
|
|
3
|
+
const G = { class: "w-full" }, H = {
|
|
5
4
|
key: 0,
|
|
6
5
|
class: "flex items-center gap-2 py-3"
|
|
7
|
-
},
|
|
6
|
+
}, J = {
|
|
8
7
|
key: 1,
|
|
9
8
|
class: "text-xs text-destructive py-2"
|
|
10
|
-
},
|
|
9
|
+
}, K = {
|
|
11
10
|
key: 2,
|
|
12
11
|
class: "rounded-xl border bg-background p-4 text-center"
|
|
13
|
-
},
|
|
12
|
+
}, Q = {
|
|
14
13
|
key: 3,
|
|
15
14
|
class: "space-y-3"
|
|
16
|
-
},
|
|
15
|
+
}, W = { class: "flex items-start gap-3" }, X = { class: "shrink-0 size-10 rounded-lg bg-primary/10 flex items-center justify-center" }, Y = { class: "flex-1 min-w-0" }, Z = { class: "text-sm font-semibold truncate" }, ee = { class: "flex items-center gap-2 mt-1 flex-wrap" }, te = {
|
|
17
16
|
key: 0,
|
|
18
17
|
class: "text-xs font-medium"
|
|
19
|
-
},
|
|
18
|
+
}, se = { class: "grid grid-cols-2 gap-2 text-xs text-muted-foreground" }, re = { class: "flex items-center gap-1.5" }, ne = { class: "truncate" }, ae = { class: "flex items-center gap-1.5" }, oe = { class: "flex items-center gap-1.5" }, ie = { class: "flex items-center gap-1.5" }, ue = /* @__PURE__ */ A({
|
|
20
19
|
__name: "AppointmentDetailsCard",
|
|
21
20
|
props: {
|
|
22
21
|
toolName: {},
|
|
@@ -28,21 +27,21 @@ const H = { class: "w-full" }, J = {
|
|
|
28
27
|
},
|
|
29
28
|
emits: ["submit"],
|
|
30
29
|
setup(v, { emit: b }) {
|
|
31
|
-
const f = v,
|
|
32
|
-
async function
|
|
33
|
-
const { name: s, email:
|
|
34
|
-
if (!
|
|
30
|
+
const { $useRoute: h, $useModuleOverlay: de } = useNuxtApp(), f = v, k = b, y = h(), N = T(() => y.params.slug), I = $useModuleApi(f.instanceId), p = x(!0), c = x(null), u = x([]);
|
|
31
|
+
async function C() {
|
|
32
|
+
const { name: s, email: o, date: m } = f.resolvedArgs || {};
|
|
33
|
+
if (!m) {
|
|
35
34
|
c.value = "No date provided", p.value = !1;
|
|
36
35
|
return;
|
|
37
36
|
}
|
|
38
37
|
p.value = !0, c.value = null;
|
|
39
38
|
try {
|
|
40
39
|
const e = new URLSearchParams();
|
|
41
|
-
s && e.set("name", s),
|
|
42
|
-
const w = await
|
|
43
|
-
|
|
44
|
-
count:
|
|
45
|
-
appointments:
|
|
40
|
+
s && e.set("name", s), o && e.set("email", o), m && e.set("date", m);
|
|
41
|
+
const w = await I.get(`/appointments/find?${e.toString()}`);
|
|
42
|
+
u.value = w.appointments || [], _({
|
|
43
|
+
count: u.value.length,
|
|
44
|
+
appointments: u.value.map((n) => ({
|
|
46
45
|
orderId: n.orderId,
|
|
47
46
|
reservationId: n.reservationId,
|
|
48
47
|
customerName: `${n.customerInfo?.firstName || ""} ${n.customerInfo?.lastName || ""}`.trim(),
|
|
@@ -62,12 +61,12 @@ const H = { class: "w-full" }, J = {
|
|
|
62
61
|
}
|
|
63
62
|
}
|
|
64
63
|
L(() => {
|
|
65
|
-
|
|
64
|
+
C();
|
|
66
65
|
});
|
|
67
66
|
function _(s) {
|
|
68
|
-
f.status !== "completed" &&
|
|
67
|
+
f.status !== "completed" && k("submit", s);
|
|
69
68
|
}
|
|
70
|
-
const
|
|
69
|
+
const z = (s) => {
|
|
71
70
|
switch (s) {
|
|
72
71
|
case "approved":
|
|
73
72
|
return "text-emerald-600 dark:text-emerald-400 bg-emerald-50 dark:bg-emerald-900/20";
|
|
@@ -79,7 +78,7 @@ const H = { class: "w-full" }, J = {
|
|
|
79
78
|
default:
|
|
80
79
|
return "text-amber-600 dark:text-amber-400 bg-amber-50 dark:bg-amber-900/20";
|
|
81
80
|
}
|
|
82
|
-
},
|
|
81
|
+
}, $ = (s) => {
|
|
83
82
|
switch (s) {
|
|
84
83
|
case "approved":
|
|
85
84
|
return "Approved";
|
|
@@ -95,59 +94,59 @@ const H = { class: "w-full" }, J = {
|
|
|
95
94
|
return s || "Pending";
|
|
96
95
|
}
|
|
97
96
|
}, S = (s) => s == null ? "" : `€${s.toFixed(2)}`;
|
|
98
|
-
return (s,
|
|
99
|
-
const
|
|
100
|
-
return d(), l("div",
|
|
101
|
-
r(p) ? (d(), l("div",
|
|
102
|
-
i(r(
|
|
103
|
-
|
|
104
|
-
])) : r(c) ? (d(), l("div",
|
|
97
|
+
return (s, o) => {
|
|
98
|
+
const m = j("NuxtLink");
|
|
99
|
+
return d(), l("div", G, [
|
|
100
|
+
r(p) ? (d(), l("div", H, [
|
|
101
|
+
i(r(R), { class: "size-4 animate-spin text-muted-foreground" }),
|
|
102
|
+
o[0] || (o[0] = t("span", { class: "text-xs text-muted-foreground" }, "Searching appointments…", -1))
|
|
103
|
+
])) : r(c) ? (d(), l("div", J, a(r(c)), 1)) : r(u).length === 0 ? (d(), l("div", K, [
|
|
105
104
|
i(r(g), { class: "size-8 text-muted-foreground mx-auto mb-2" }),
|
|
106
|
-
|
|
107
|
-
])) : (d(), l("div",
|
|
108
|
-
(d(!0), l(
|
|
105
|
+
o[1] || (o[1] = t("p", { class: "text-sm text-muted-foreground" }, "No appointments found for the given criteria.", -1))
|
|
106
|
+
])) : (d(), l("div", Q, [
|
|
107
|
+
(d(!0), l(P, null, M(r(u), (e) => (d(), l("div", {
|
|
109
108
|
key: e.reservationId || e.orderId,
|
|
110
109
|
class: "rounded-xl border bg-background p-3 space-y-3"
|
|
111
110
|
}, [
|
|
112
|
-
t("div",
|
|
113
|
-
t("div",
|
|
111
|
+
t("div", W, [
|
|
112
|
+
t("div", X, [
|
|
114
113
|
i(r(g), { class: "size-5 text-primary" })
|
|
115
114
|
]),
|
|
116
|
-
t("div",
|
|
117
|
-
t("p",
|
|
118
|
-
t("div",
|
|
115
|
+
t("div", Y, [
|
|
116
|
+
t("p", Z, a(e.customerInfo?.firstName) + " " + a(e.customerInfo?.lastName), 1),
|
|
117
|
+
t("div", ee, [
|
|
119
118
|
t("span", {
|
|
120
|
-
class: E(["text-[10px] font-medium px-1.5 py-0.5 rounded-full uppercase",
|
|
121
|
-
},
|
|
122
|
-
e.reservationPrice != null ? (d(), l("span",
|
|
119
|
+
class: E(["text-[10px] font-medium px-1.5 py-0.5 rounded-full uppercase", z(e.reservationStatus || e.status)])
|
|
120
|
+
}, a($(e.reservationStatus || e.status)), 3),
|
|
121
|
+
e.reservationPrice != null ? (d(), l("span", te, a(S(e.reservationPrice)), 1)) : V("", !0)
|
|
123
122
|
])
|
|
124
123
|
])
|
|
125
124
|
]),
|
|
126
|
-
t("div",
|
|
127
|
-
t("div",
|
|
128
|
-
i(r(
|
|
129
|
-
t("span",
|
|
125
|
+
t("div", se, [
|
|
126
|
+
t("div", re, [
|
|
127
|
+
i(r(B), { class: "size-3" }),
|
|
128
|
+
t("span", ne, a(e.customerInfo?.email || "—"), 1)
|
|
130
129
|
]),
|
|
131
130
|
t("div", ae, [
|
|
132
131
|
i(r(g), { class: "size-3" }),
|
|
133
|
-
t("span", null,
|
|
132
|
+
t("span", null, a(e.date), 1)
|
|
134
133
|
]),
|
|
135
|
-
t("div",
|
|
136
|
-
i(r(
|
|
137
|
-
t("span", null,
|
|
134
|
+
t("div", oe, [
|
|
135
|
+
i(r(O), { class: "size-3" }),
|
|
136
|
+
t("span", null, a(e.startTime) + " – " + a(e.endTime), 1)
|
|
138
137
|
]),
|
|
139
|
-
t("div",
|
|
138
|
+
t("div", ie, [
|
|
140
139
|
i(r(U), { class: "size-3" }),
|
|
141
|
-
t("span", null,
|
|
140
|
+
t("span", null, a(e.spots || 1) + " " + a((e.spots || 1) === 1 ? "spot" : "spots"), 1)
|
|
142
141
|
])
|
|
143
142
|
]),
|
|
144
|
-
i(
|
|
145
|
-
to: `/projects/${r(
|
|
143
|
+
i(m, {
|
|
144
|
+
to: `/projects/${r(N)}/modules/${v.instanceId}`,
|
|
146
145
|
class: "inline-flex items-center gap-1.5 text-xs text-primary hover:underline"
|
|
147
146
|
}, {
|
|
148
|
-
default:
|
|
149
|
-
i(r(
|
|
150
|
-
|
|
147
|
+
default: D(() => [
|
|
148
|
+
i(r(q), { class: "size-3" }),
|
|
149
|
+
o[2] || (o[2] = F(" Open in agenda ", -1))
|
|
151
150
|
]),
|
|
152
151
|
_: 1
|
|
153
152
|
}, 8, ["to"])
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("vue"),o=require("lucide-vue-next"),E={class:"w-full"},h={key:0,class:"flex items-center gap-2 py-3"},S={key:1,class:"text-xs text-destructive py-2"},B={key:2,class:"rounded-xl border bg-background p-4 text-center"},D={key:3,class:"space-y-3"},I={class:"flex items-start gap-3"},C={class:"shrink-0 size-10 rounded-lg bg-primary/10 flex items-center justify-center"},z={class:"flex-1 min-w-0"},$={class:"text-sm font-semibold truncate"},T={class:"flex items-center gap-2 mt-1 flex-wrap"},w={key:0,class:"text-xs font-medium"},A={class:"grid grid-cols-2 gap-2 text-xs text-muted-foreground"},j={class:"flex items-center gap-1.5"},L={class:"truncate"},P={class:"flex items-center gap-1.5"},M={class:"flex items-center gap-1.5"},F={class:"flex items-center gap-1.5"},O=e.defineComponent({__name:"AppointmentDetailsCard",props:{toolName:{},instanceId:{},instanceName:{},moduleType:{},resolvedArgs:{},status:{}},emits:["submit"],setup(u,{emit:p}){const{$useRoute:f,$useModuleOverlay:R}=useNuxtApp(),d=u,g=p,x=f(),v=e.computed(()=>x.params.slug),N=$useModuleApi(d.instanceId),c=e.ref(!0),a=e.ref(null),l=e.ref([]);async function k(){const{name:s,email:n,date:i}=d.resolvedArgs||{};if(!i){a.value="No date provided",c.value=!1;return}c.value=!0,a.value=null;try{const t=new URLSearchParams;s&&t.set("name",s),n&&t.set("email",n),i&&t.set("date",i);const V=await N.get(`/appointments/find?${t.toString()}`);l.value=V.appointments||[],m({count:l.value.length,appointments:l.value.map(r=>({orderId:r.orderId,reservationId:r.reservationId,customerName:`${r.customerInfo?.firstName||""} ${r.customerInfo?.lastName||""}`.trim(),email:r.customerInfo?.email,date:r.date,startTime:r.startTime,endTime:r.endTime,spots:r.spots,status:r.reservationStatus||r.status,price:r.reservationPrice}))})}catch(t){a.value=t?.data?.statusMessage||t?.message||"Failed to find appointment",m(`Error finding appointment: ${a.value}`)}finally{c.value=!1}}e.onMounted(()=>{k()});function m(s){d.status!=="completed"&&g("submit",s)}const y=s=>{switch(s){case"approved":return"text-emerald-600 dark:text-emerald-400 bg-emerald-50 dark:bg-emerald-900/20";case"needs_approval":return"text-blue-600 dark:text-blue-400 bg-blue-50 dark:bg-blue-900/20";case"rejected":case"cancelled":return"text-red-600 dark:text-red-400 bg-red-50 dark:bg-red-900/20";default:return"text-amber-600 dark:text-amber-400 bg-amber-50 dark:bg-amber-900/20"}},_=s=>{switch(s){case"approved":return"Approved";case"needs_approval":return"Needs Approval";case"rejected":return"Rejected";case"cancelled":return"Cancelled";case"confirmed":return"Confirmed";default:return s||"Pending"}},b=s=>s==null?"":`€${s.toFixed(2)}`;return(s,n)=>{const i=e.resolveComponent("NuxtLink");return e.openBlock(),e.createElementBlock("div",E,[e.unref(c)?(e.openBlock(),e.createElementBlock("div",h,[e.createVNode(e.unref(o.Loader2),{class:"size-4 animate-spin text-muted-foreground"}),n[0]||(n[0]=e.createElementVNode("span",{class:"text-xs text-muted-foreground"},"Searching appointments…",-1))])):e.unref(a)?(e.openBlock(),e.createElementBlock("div",S,e.toDisplayString(e.unref(a)),1)):e.unref(l).length===0?(e.openBlock(),e.createElementBlock("div",B,[e.createVNode(e.unref(o.CalendarDays),{class:"size-8 text-muted-foreground mx-auto mb-2"}),n[1]||(n[1]=e.createElementVNode("p",{class:"text-sm text-muted-foreground"},"No appointments found for the given criteria.",-1))])):(e.openBlock(),e.createElementBlock("div",D,[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(e.unref(l),t=>(e.openBlock(),e.createElementBlock("div",{key:t.reservationId||t.orderId,class:"rounded-xl border bg-background p-3 space-y-3"},[e.createElementVNode("div",I,[e.createElementVNode("div",C,[e.createVNode(e.unref(o.CalendarDays),{class:"size-5 text-primary"})]),e.createElementVNode("div",z,[e.createElementVNode("p",$,e.toDisplayString(t.customerInfo?.firstName)+" "+e.toDisplayString(t.customerInfo?.lastName),1),e.createElementVNode("div",T,[e.createElementVNode("span",{class:e.normalizeClass(["text-[10px] font-medium px-1.5 py-0.5 rounded-full uppercase",y(t.reservationStatus||t.status)])},e.toDisplayString(_(t.reservationStatus||t.status)),3),t.reservationPrice!=null?(e.openBlock(),e.createElementBlock("span",w,e.toDisplayString(b(t.reservationPrice)),1)):e.createCommentVNode("",!0)])])]),e.createElementVNode("div",A,[e.createElementVNode("div",j,[e.createVNode(e.unref(o.Mail),{class:"size-3"}),e.createElementVNode("span",L,e.toDisplayString(t.customerInfo?.email||"—"),1)]),e.createElementVNode("div",P,[e.createVNode(e.unref(o.CalendarDays),{class:"size-3"}),e.createElementVNode("span",null,e.toDisplayString(t.date),1)]),e.createElementVNode("div",M,[e.createVNode(e.unref(o.Clock),{class:"size-3"}),e.createElementVNode("span",null,e.toDisplayString(t.startTime)+" – "+e.toDisplayString(t.endTime),1)]),e.createElementVNode("div",F,[e.createVNode(e.unref(o.Users),{class:"size-3"}),e.createElementVNode("span",null,e.toDisplayString(t.spots||1)+" "+e.toDisplayString((t.spots||1)===1?"spot":"spots"),1)])]),e.createVNode(i,{to:`/projects/${e.unref(v)}/modules/${u.instanceId}`,class:"inline-flex items-center gap-1.5 text-xs text-primary hover:underline"},{default:e.withCtx(()=>[e.createVNode(e.unref(o.ExternalLink),{class:"size-3"}),n[2]||(n[2]=e.createTextVNode(" Open in agenda ",-1))]),_:1},8,["to"])]))),128))]))])}}});exports.default=O;
|
|
@@ -1,19 +1,18 @@
|
|
|
1
|
-
import { defineComponent as C, computed as L, ref as x, onMounted as
|
|
2
|
-
import { Loader2 as
|
|
3
|
-
|
|
4
|
-
const B = { class: "w-full" }, R = {
|
|
1
|
+
import { defineComponent as C, computed as L, ref as x, onMounted as A, resolveComponent as S, openBlock as i, createElementBlock as u, unref as a, createVNode as c, createElementVNode as e, toDisplayString as n, Fragment as j, renderList as D, normalizeClass as P, withCtx as z, createTextVNode as E } from "vue";
|
|
2
|
+
import { Loader2 as M, CalendarDays as V, ExternalLink as q } from "lucide-vue-next";
|
|
3
|
+
const F = { class: "w-full" }, B = {
|
|
5
4
|
key: 0,
|
|
6
5
|
class: "flex items-center gap-2 py-3"
|
|
7
|
-
},
|
|
6
|
+
}, R = {
|
|
8
7
|
key: 1,
|
|
9
8
|
class: "text-xs text-destructive py-2"
|
|
10
|
-
},
|
|
9
|
+
}, O = {
|
|
11
10
|
key: 2,
|
|
12
11
|
class: "rounded-xl border bg-background p-4 text-center"
|
|
13
|
-
},
|
|
12
|
+
}, U = {
|
|
14
13
|
key: 3,
|
|
15
14
|
class: "rounded-xl border bg-background overflow-hidden"
|
|
16
|
-
},
|
|
15
|
+
}, G = { class: "overflow-x-auto" }, H = { class: "w-full text-xs" }, J = { class: "px-3 py-2" }, K = { class: "font-medium truncate max-w-[160px]" }, Q = { class: "text-muted-foreground truncate max-w-[160px]" }, W = { class: "px-3 py-2 whitespace-nowrap" }, X = { class: "px-3 py-2 whitespace-nowrap" }, Y = { class: "px-3 py-2 text-center" }, Z = { class: "px-3 py-2" }, ee = { class: "px-3 py-2 text-right font-medium whitespace-nowrap" }, te = { class: "px-3 py-2 border-t bg-muted/20 flex items-center justify-between" }, se = { class: "text-xs text-muted-foreground" }, ae = /* @__PURE__ */ C({
|
|
17
16
|
__name: "AppointmentListTable",
|
|
18
17
|
props: {
|
|
19
18
|
toolName: {},
|
|
@@ -25,12 +24,12 @@ const B = { class: "w-full" }, R = {
|
|
|
25
24
|
},
|
|
26
25
|
emits: ["submit"],
|
|
27
26
|
setup(f, { emit: b }) {
|
|
28
|
-
const m = f,
|
|
29
|
-
async function
|
|
27
|
+
const { $useRoute: h, $useModuleOverlay: oe } = useNuxtApp(), m = f, v = b, y = h(), _ = L(() => y.params.slug), k = $useModuleApi(m.instanceId), p = x(!0), l = x(null), d = x([]);
|
|
28
|
+
async function w() {
|
|
30
29
|
const t = m.resolvedArgs?.quantity || 20;
|
|
31
30
|
p.value = !0, l.value = null;
|
|
32
31
|
try {
|
|
33
|
-
const s = await
|
|
32
|
+
const s = await k.get(`/appointments?quantity=${t}`);
|
|
34
33
|
d.value = s.appointments || [], g({
|
|
35
34
|
count: d.value.length,
|
|
36
35
|
appointments: d.value.map((o) => ({
|
|
@@ -52,13 +51,13 @@ const B = { class: "w-full" }, R = {
|
|
|
52
51
|
p.value = !1;
|
|
53
52
|
}
|
|
54
53
|
}
|
|
55
|
-
|
|
56
|
-
|
|
54
|
+
A(() => {
|
|
55
|
+
w();
|
|
57
56
|
});
|
|
58
57
|
function g(t) {
|
|
59
|
-
m.status !== "completed" &&
|
|
58
|
+
m.status !== "completed" && v("submit", t);
|
|
60
59
|
}
|
|
61
|
-
const
|
|
60
|
+
const I = (t) => {
|
|
62
61
|
switch (t) {
|
|
63
62
|
case "approved":
|
|
64
63
|
return "text-emerald-600 dark:text-emerald-400 bg-emerald-50 dark:bg-emerald-900/20";
|
|
@@ -70,7 +69,7 @@ const B = { class: "w-full" }, R = {
|
|
|
70
69
|
default:
|
|
71
70
|
return "text-amber-600 dark:text-amber-400 bg-amber-50 dark:bg-amber-900/20";
|
|
72
71
|
}
|
|
73
|
-
},
|
|
72
|
+
}, N = (t) => {
|
|
74
73
|
switch (t) {
|
|
75
74
|
case "approved":
|
|
76
75
|
return "Approved";
|
|
@@ -85,7 +84,7 @@ const B = { class: "w-full" }, R = {
|
|
|
85
84
|
default:
|
|
86
85
|
return t || "Pending";
|
|
87
86
|
}
|
|
88
|
-
},
|
|
87
|
+
}, T = (t) => t == null ? "—" : `€${t.toFixed(2)}`, $ = (t) => {
|
|
89
88
|
if (!t) return "—";
|
|
90
89
|
try {
|
|
91
90
|
return new Date(t).toLocaleDateString("en-US", { weekday: "short", month: "short", day: "numeric" });
|
|
@@ -94,17 +93,17 @@ const B = { class: "w-full" }, R = {
|
|
|
94
93
|
}
|
|
95
94
|
};
|
|
96
95
|
return (t, s) => {
|
|
97
|
-
const o =
|
|
98
|
-
return i(), u("div",
|
|
99
|
-
a(p) ? (i(), u("div",
|
|
100
|
-
c(a(
|
|
96
|
+
const o = S("NuxtLink");
|
|
97
|
+
return i(), u("div", F, [
|
|
98
|
+
a(p) ? (i(), u("div", B, [
|
|
99
|
+
c(a(M), { class: "size-4 animate-spin text-muted-foreground" }),
|
|
101
100
|
s[0] || (s[0] = e("span", { class: "text-xs text-muted-foreground" }, "Loading appointments…", -1))
|
|
102
|
-
])) : a(l) ? (i(), u("div",
|
|
101
|
+
])) : a(l) ? (i(), u("div", R, n(a(l)), 1)) : a(d).length === 0 ? (i(), u("div", O, [
|
|
103
102
|
c(a(V), { class: "size-8 text-muted-foreground mx-auto mb-2" }),
|
|
104
103
|
s[1] || (s[1] = e("p", { class: "text-sm text-muted-foreground" }, "No recent appointments found.", -1))
|
|
105
|
-
])) : (i(), u("div",
|
|
106
|
-
e("div",
|
|
107
|
-
e("table",
|
|
104
|
+
])) : (i(), u("div", U, [
|
|
105
|
+
e("div", G, [
|
|
106
|
+
e("table", H, [
|
|
108
107
|
s[2] || (s[2] = e("thead", null, [
|
|
109
108
|
e("tr", { class: "border-b bg-muted/40" }, [
|
|
110
109
|
e("th", { class: "text-left px-3 py-2 font-medium text-muted-foreground" }, "Customer"),
|
|
@@ -116,36 +115,36 @@ const B = { class: "w-full" }, R = {
|
|
|
116
115
|
])
|
|
117
116
|
], -1)),
|
|
118
117
|
e("tbody", null, [
|
|
119
|
-
(i(!0), u(
|
|
118
|
+
(i(!0), u(j, null, D(a(d), (r) => (i(), u("tr", {
|
|
120
119
|
key: r.reservationId || r.orderId,
|
|
121
120
|
class: "border-b last:border-b-0 hover:bg-muted/30 transition-colors"
|
|
122
121
|
}, [
|
|
123
|
-
e("td",
|
|
124
|
-
e("div",
|
|
125
|
-
e("div",
|
|
122
|
+
e("td", J, [
|
|
123
|
+
e("div", K, n(r.customerInfo?.firstName) + " " + n(r.customerInfo?.lastName), 1),
|
|
124
|
+
e("div", Q, n(r.customerInfo?.email), 1)
|
|
126
125
|
]),
|
|
127
|
-
e("td",
|
|
128
|
-
e("td",
|
|
129
|
-
e("td",
|
|
130
|
-
e("td",
|
|
126
|
+
e("td", W, n($(r.date)), 1),
|
|
127
|
+
e("td", X, n(r.startTime) + " – " + n(r.endTime), 1),
|
|
128
|
+
e("td", Y, n(r.spots || 1), 1),
|
|
129
|
+
e("td", Z, [
|
|
131
130
|
e("span", {
|
|
132
|
-
class:
|
|
133
|
-
}, n(
|
|
131
|
+
class: P(["inline-block text-[10px] font-medium px-1.5 py-0.5 rounded-full uppercase whitespace-nowrap", I(r.reservationStatus || r.status)])
|
|
132
|
+
}, n(N(r.reservationStatus || r.status)), 3)
|
|
134
133
|
]),
|
|
135
|
-
e("td",
|
|
134
|
+
e("td", ee, n(T(r.reservationPrice)), 1)
|
|
136
135
|
]))), 128))
|
|
137
136
|
])
|
|
138
137
|
])
|
|
139
138
|
]),
|
|
140
|
-
e("div",
|
|
141
|
-
e("span",
|
|
139
|
+
e("div", te, [
|
|
140
|
+
e("span", se, n(a(d).length) + " appointment" + n(a(d).length === 1 ? "" : "s"), 1),
|
|
142
141
|
c(o, {
|
|
143
|
-
to: `/projects/${a(
|
|
142
|
+
to: `/projects/${a(_)}/modules/${f.instanceId}`,
|
|
144
143
|
class: "inline-flex items-center gap-1.5 text-xs text-primary hover:underline"
|
|
145
144
|
}, {
|
|
146
|
-
default:
|
|
145
|
+
default: z(() => [
|
|
147
146
|
c(a(q), { class: "size-3" }),
|
|
148
|
-
s[3] || (s[3] =
|
|
147
|
+
s[3] || (s[3] = E(" View all ", -1))
|
|
149
148
|
]),
|
|
150
149
|
_: 1
|
|
151
150
|
}, 8, ["to"])
|
|
@@ -156,5 +155,5 @@ const B = { class: "w-full" }, R = {
|
|
|
156
155
|
}
|
|
157
156
|
});
|
|
158
157
|
export {
|
|
159
|
-
|
|
158
|
+
ae as default
|
|
160
159
|
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("vue"),c=require("lucide-vue-next"),k={class:"w-full"},E={key:0,class:"flex items-center gap-2 py-3"},V={key:1,class:"text-xs text-destructive py-2"},w={key:2,class:"rounded-xl border bg-background p-4 text-center"},S={key:3,class:"rounded-xl border bg-background overflow-hidden"},D={class:"overflow-x-auto"},I={class:"w-full text-xs"},B={class:"px-3 py-2"},T={class:"font-medium truncate max-w-[160px]"},$={class:"text-muted-foreground truncate max-w-[160px]"},C={class:"px-3 py-2 whitespace-nowrap"},L={class:"px-3 py-2 whitespace-nowrap"},A={class:"px-3 py-2 text-center"},j={class:"px-3 py-2"},P={class:"px-3 py-2 text-right font-medium whitespace-nowrap"},q={class:"px-3 py-2 border-t bg-muted/20 flex items-center justify-between"},M={class:"text-xs text-muted-foreground"},z=e.defineComponent({__name:"AppointmentListTable",props:{toolName:{},instanceId:{},instanceName:{},moduleType:{},resolvedArgs:{},status:{}},emits:["submit"],setup(i,{emit:m}){const{$useRoute:p,$useModuleOverlay:F}=useNuxtApp(),d=i,x=m,f=p(),g=e.computed(()=>f.params.slug),y=$useModuleApi(d.instanceId),l=e.ref(!0),a=e.ref(null),s=e.ref([]);async function b(){const t=d.resolvedArgs?.quantity||20;l.value=!0,a.value=null;try{const o=await y.get(`/appointments?quantity=${t}`);s.value=o.appointments||[],u({count:s.value.length,appointments:s.value.map(r=>({orderId:r.orderId,reservationId:r.reservationId,customerName:`${r.customerInfo?.firstName||""} ${r.customerInfo?.lastName||""}`.trim(),email:r.customerInfo?.email,date:r.date,startTime:r.startTime,endTime:r.endTime,spots:r.spots,status:r.reservationStatus||r.status,price:r.reservationPrice}))})}catch(o){a.value=o?.data?.statusMessage||o?.message||"Failed to load appointments",u(`Error loading appointments: ${a.value}`)}finally{l.value=!1}}e.onMounted(()=>{b()});function u(t){d.status!=="completed"&&x("submit",t)}const N=t=>{switch(t){case"approved":return"text-emerald-600 dark:text-emerald-400 bg-emerald-50 dark:bg-emerald-900/20";case"needs_approval":return"text-blue-600 dark:text-blue-400 bg-blue-50 dark:bg-blue-900/20";case"rejected":case"cancelled":return"text-red-600 dark:text-red-400 bg-red-50 dark:bg-red-900/20";default:return"text-amber-600 dark:text-amber-400 bg-amber-50 dark:bg-amber-900/20"}},v=t=>{switch(t){case"approved":return"Approved";case"needs_approval":return"Needs Approval";case"rejected":return"Rejected";case"cancelled":return"Cancelled";case"confirmed":return"Confirmed";default:return t||"Pending"}},h=t=>t==null?"—":`€${t.toFixed(2)}`,_=t=>{if(!t)return"—";try{return new Date(t).toLocaleDateString("en-US",{weekday:"short",month:"short",day:"numeric"})}catch{return t}};return(t,o)=>{const r=e.resolveComponent("NuxtLink");return e.openBlock(),e.createElementBlock("div",k,[e.unref(l)?(e.openBlock(),e.createElementBlock("div",E,[e.createVNode(e.unref(c.Loader2),{class:"size-4 animate-spin text-muted-foreground"}),o[0]||(o[0]=e.createElementVNode("span",{class:"text-xs text-muted-foreground"},"Loading appointments…",-1))])):e.unref(a)?(e.openBlock(),e.createElementBlock("div",V,e.toDisplayString(e.unref(a)),1)):e.unref(s).length===0?(e.openBlock(),e.createElementBlock("div",w,[e.createVNode(e.unref(c.CalendarDays),{class:"size-8 text-muted-foreground mx-auto mb-2"}),o[1]||(o[1]=e.createElementVNode("p",{class:"text-sm text-muted-foreground"},"No recent appointments found.",-1))])):(e.openBlock(),e.createElementBlock("div",S,[e.createElementVNode("div",D,[e.createElementVNode("table",I,[o[2]||(o[2]=e.createElementVNode("thead",null,[e.createElementVNode("tr",{class:"border-b bg-muted/40"},[e.createElementVNode("th",{class:"text-left px-3 py-2 font-medium text-muted-foreground"},"Customer"),e.createElementVNode("th",{class:"text-left px-3 py-2 font-medium text-muted-foreground"},"Date"),e.createElementVNode("th",{class:"text-left px-3 py-2 font-medium text-muted-foreground"},"Time"),e.createElementVNode("th",{class:"text-center px-3 py-2 font-medium text-muted-foreground"},"Spots"),e.createElementVNode("th",{class:"text-left px-3 py-2 font-medium text-muted-foreground"},"Status"),e.createElementVNode("th",{class:"text-right px-3 py-2 font-medium text-muted-foreground"},"Price")])],-1)),e.createElementVNode("tbody",null,[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(e.unref(s),n=>(e.openBlock(),e.createElementBlock("tr",{key:n.reservationId||n.orderId,class:"border-b last:border-b-0 hover:bg-muted/30 transition-colors"},[e.createElementVNode("td",B,[e.createElementVNode("div",T,e.toDisplayString(n.customerInfo?.firstName)+" "+e.toDisplayString(n.customerInfo?.lastName),1),e.createElementVNode("div",$,e.toDisplayString(n.customerInfo?.email),1)]),e.createElementVNode("td",C,e.toDisplayString(_(n.date)),1),e.createElementVNode("td",L,e.toDisplayString(n.startTime)+" – "+e.toDisplayString(n.endTime),1),e.createElementVNode("td",A,e.toDisplayString(n.spots||1),1),e.createElementVNode("td",j,[e.createElementVNode("span",{class:e.normalizeClass(["inline-block text-[10px] font-medium px-1.5 py-0.5 rounded-full uppercase whitespace-nowrap",N(n.reservationStatus||n.status)])},e.toDisplayString(v(n.reservationStatus||n.status)),3)]),e.createElementVNode("td",P,e.toDisplayString(h(n.reservationPrice)),1)]))),128))])])]),e.createElementVNode("div",q,[e.createElementVNode("span",M,e.toDisplayString(e.unref(s).length)+" appointment"+e.toDisplayString(e.unref(s).length===1?"":"s"),1),e.createVNode(r,{to:`/projects/${e.unref(g)}/modules/${i.instanceId}`,class:"inline-flex items-center gap-1.5 text-xs text-primary hover:underline"},{default:e.withCtx(()=>[e.createVNode(e.unref(c.ExternalLink),{class:"size-3"}),o[3]||(o[3]=e.createTextVNode(" View all ",-1))]),_:1},8,["to"])])]))])}}});exports.default=z;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("vue"),l=require("lucide-vue-next"),A={class:"w-full"},$={key:0,class:"flex items-center gap-2 py-3"},C={key:1,class:"text-xs text-destructive py-2"},L={key:2,class:"rounded-xl border bg-background p-4 text-center space-y-2"},z={key:3,class:"rounded-xl border bg-background overflow-hidden"},T={class:"px-3 py-2 border-b bg-muted/40 flex items-center justify-between"},F={class:"flex items-center gap-2"},U={class:"text-[10px] text-muted-foreground"},I={class:"divide-y"},M={class:"flex items-center gap-2 mb-1.5"},j={class:"text-sm shrink-0"},P={class:"text-xs font-medium truncate flex-1"},R={class:"text-[10px] text-muted-foreground"},G={class:"ml-7 space-y-1.5"},O={class:"h-1.5 rounded-full bg-muted overflow-hidden"},q={class:"flex items-center gap-3 text-[10px] text-muted-foreground"},K={class:"flex items-center gap-1"},H={class:"flex items-center gap-1"},J={class:"px-3 py-2 border-t bg-muted/20 flex items-center justify-between"},Z={class:"text-[10px] text-muted-foreground"},Q=e.defineComponent({__name:"CountryBreakdownCard",props:{toolName:{},instanceId:{},instanceName:{},moduleType:{},resolvedArgs:{},status:{}},emits:["submit"],setup(p,{emit:x}){const{$useRoute:y,$useModuleOverlay:W}=useNuxtApp(),i=p,h=x,v=y(),N=e.computed(()=>v.params.slug),_=$useModuleApi(i.instanceId),d=e.ref(!0),c=e.ref(null),o=e.ref([]),u=e.ref(null),V=t=>({"United States":"🇺🇸","United Kingdom":"🇬🇧",Germany:"🇩🇪",France:"🇫🇷",Netherlands:"🇳🇱",Belgium:"🇧🇪",Canada:"🇨🇦",Australia:"🇦🇺",India:"🇮🇳",Brazil:"🇧🇷",Spain:"🇪🇸",Italy:"🇮🇹",Japan:"🇯🇵",China:"🇨🇳","South Korea":"🇰🇷",Mexico:"🇲🇽",Russia:"🇷🇺",Sweden:"🇸🇪",Norway:"🇳🇴",Denmark:"🇩🇰",Finland:"🇫🇮",Poland:"🇵🇱",Switzerland:"🇨🇭",Austria:"🇦🇹",Portugal:"🇵🇹",Ireland:"🇮🇪","New Zealand":"🇳🇿",Singapore:"🇸🇬","South Africa":"🇿🇦",Turkey:"🇹🇷",Indonesia:"🇮🇩",Thailand:"🇹🇭",Philippines:"🇵🇭",Vietnam:"🇻🇳",Argentina:"🇦🇷",Colombia:"🇨🇴",Israel:"🇮🇱",UAE:"🇦🇪","United Arab Emirates":"🇦🇪","Czech Republic":"🇨🇿",Czechia:"🇨🇿",Romania:"🇷🇴",Hungary:"🇭🇺",Ukraine:"🇺🇦",Greece:"🇬🇷",Luxembourg:"🇱🇺"})[t]||"🌍";function b(){const t=i.resolvedArgs?._cachedData;return t?(o.value=(t.countries||[]).map(s=>({country:s.country,sessions:s.sessions,totalUsers:s.users})),u.value=i.resolvedArgs._fetchedAt||null,d.value=!1,!0):!1}async function k(){const{startDate:t,endDate:s}=i.resolvedArgs||{};d.value=!0,c.value=null;try{const n=new URLSearchParams;t&&n.set("startDate",t),s&&n.set("endDate",s);const r=await _.get(`/countries?${n.toString()}`);o.value=r.rows||[],u.value=new Date().toISOString();const m=o.value.reduce((a,w)=>a+(w.sessions||0),0);f({count:o.value.length,countries:o.value.map(a=>({country:a.country,sessions:a.sessions,users:a.totalUsers,share:`${(a.sessions/m*100).toFixed(1)}%`})),suggestion:o.value.length===0?"No geographic data found for this period.":`Top countries by traffic: ${o.value.slice(0,5).map(a=>`${a.country} (${(a.sessions/m*100).toFixed(0)}%)`).join(", ")}.`})}catch(n){c.value=n?.data?.statusMessage||n?.message||"Failed to load country data",f(`Error loading country data: ${c.value}`)}finally{d.value=!1}}e.onMounted(()=>{i.status==="completed"&&b()||k()});function f(t){i.status!=="completed"&&h("submit",t)}const g=t=>t==null?"0":Math.round(t).toLocaleString(),E=t=>t?new Date(t).toLocaleString(void 0,{month:"short",day:"numeric",hour:"2-digit",minute:"2-digit"}):"",S=e.computed(()=>o.value.reduce((t,s)=>t+(s.sessions||0),0)||1),D=e.computed(()=>Math.max(...o.value.map(t=>t.sessions||0),1)),B=e.computed(()=>{const{startDate:t,endDate:s}=i.resolvedArgs||{};if(!t&&!s)return"Last 30 days";const n=t||"30daysAgo",r=n.match(/^(\d+)daysAgo$/);return r?`Last ${r[1]} days`:`${n} → ${s||"today"}`});return(t,s)=>{const n=e.resolveComponent("NuxtLink");return e.openBlock(),e.createElementBlock("div",A,[e.unref(d)?(e.openBlock(),e.createElementBlock("div",$,[e.createVNode(e.unref(l.Loader2),{class:"size-4 animate-spin text-muted-foreground"}),s[0]||(s[0]=e.createElementVNode("span",{class:"text-xs text-muted-foreground"},"Loading country data…",-1))])):e.unref(c)?(e.openBlock(),e.createElementBlock("div",C,e.toDisplayString(e.unref(c)),1)):e.unref(o).length===0?(e.openBlock(),e.createElementBlock("div",L,[e.createVNode(e.unref(l.Globe),{class:"size-8 text-muted-foreground mx-auto"}),s[1]||(s[1]=e.createElementVNode("p",{class:"text-sm text-muted-foreground"},"No geographic data found for this period.",-1))])):(e.openBlock(),e.createElementBlock("div",z,[e.createElementVNode("div",T,[e.createElementVNode("div",F,[e.createVNode(e.unref(l.Globe),{class:"size-3.5 text-primary"}),s[2]||(s[2]=e.createElementVNode("span",{class:"text-xs font-medium"},"Visitors by Country",-1))]),e.createElementVNode("span",U,e.toDisplayString(e.unref(B)),1)]),e.createElementVNode("div",I,[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(e.unref(o),(r,m)=>(e.openBlock(),e.createElementBlock("div",{key:m,class:"px-3 py-2.5 hover:bg-muted/30 transition-colors"},[e.createElementVNode("div",M,[e.createElementVNode("span",j,e.toDisplayString(V(r.country)),1),e.createElementVNode("span",P,e.toDisplayString(r.country),1),e.createElementVNode("span",R,e.toDisplayString((r.sessions/e.unref(S)*100).toFixed(1))+"%",1)]),e.createElementVNode("div",G,[e.createElementVNode("div",O,[e.createElementVNode("div",{class:"h-full rounded-full bg-blue-500/70 transition-all",style:e.normalizeStyle({width:`${r.sessions/e.unref(D)*100}%`})},null,4)]),e.createElementVNode("div",q,[e.createElementVNode("span",K,[e.createVNode(e.unref(l.MousePointerClick),{class:"size-2.5"}),e.createTextVNode(" "+e.toDisplayString(g(r.sessions))+" sessions ",1)]),e.createElementVNode("span",H,[e.createVNode(e.unref(l.Users),{class:"size-2.5"}),e.createTextVNode(" "+e.toDisplayString(g(r.totalUsers))+" users ",1)])])])]))),128))]),e.createElementVNode("div",J,[e.createElementVNode("span",Z,[e.createTextVNode(e.toDisplayString(e.unref(o).length)+" countr"+e.toDisplayString(e.unref(o).length===1?"y":"ies")+" ",1),e.unref(u)?(e.openBlock(),e.createElementBlock(e.Fragment,{key:0},[e.createTextVNode(" · fetched "+e.toDisplayString(E(e.unref(u))),1)],64)):e.createCommentVNode("",!0)]),e.createVNode(n,{to:`/projects/${e.unref(N)}/modules/${p.instanceId}`,class:"inline-flex items-center gap-1.5 text-xs text-primary hover:underline"},{default:e.withCtx(()=>[e.createVNode(e.unref(l.ExternalLink),{class:"size-3"}),s[3]||(s[3]=e.createTextVNode(" View full report ",-1))]),_:1},8,["to"])])]))])}}});exports.default=Q;
|
|
@@ -1,19 +1,18 @@
|
|
|
1
|
-
import { defineComponent as
|
|
2
|
-
import { Loader2 as H, Globe as w, MousePointerClick as J, Users as
|
|
3
|
-
|
|
4
|
-
const W = { class: "w-full" }, X = {
|
|
1
|
+
import { defineComponent as j, computed as y, ref as v, onMounted as B, resolveComponent as P, openBlock as l, createElementBlock as u, unref as s, createVNode as m, createElementVNode as o, toDisplayString as i, Fragment as k, renderList as R, normalizeStyle as G, createTextVNode as f, createCommentVNode as K, withCtx as O } from "vue";
|
|
2
|
+
import { Loader2 as H, Globe as w, MousePointerClick as J, Users as Z, ExternalLink as q } from "lucide-vue-next";
|
|
3
|
+
const Q = { class: "w-full" }, W = {
|
|
5
4
|
key: 0,
|
|
6
5
|
class: "flex items-center gap-2 py-3"
|
|
7
|
-
},
|
|
6
|
+
}, X = {
|
|
8
7
|
key: 1,
|
|
9
8
|
class: "text-xs text-destructive py-2"
|
|
10
|
-
},
|
|
9
|
+
}, Y = {
|
|
11
10
|
key: 2,
|
|
12
11
|
class: "rounded-xl border bg-background p-4 text-center space-y-2"
|
|
13
|
-
},
|
|
12
|
+
}, ee = {
|
|
14
13
|
key: 3,
|
|
15
14
|
class: "rounded-xl border bg-background overflow-hidden"
|
|
16
|
-
},
|
|
15
|
+
}, te = { class: "px-3 py-2 border-b bg-muted/40 flex items-center justify-between" }, se = { class: "flex items-center gap-2" }, oe = { class: "text-[10px] text-muted-foreground" }, ne = { class: "divide-y" }, ae = { class: "flex items-center gap-2 mb-1.5" }, re = { class: "text-sm shrink-0" }, ie = { class: "text-xs font-medium truncate flex-1" }, de = { class: "text-[10px] text-muted-foreground" }, le = { class: "ml-7 space-y-1.5" }, ue = { class: "h-1.5 rounded-full bg-muted overflow-hidden" }, ce = { class: "flex items-center gap-3 text-[10px] text-muted-foreground" }, me = { class: "flex items-center gap-1" }, pe = { class: "flex items-center gap-1" }, fe = { class: "px-3 py-2 border-t bg-muted/20 flex items-center justify-between" }, ge = { class: "text-[10px] text-muted-foreground" }, ve = /* @__PURE__ */ j({
|
|
17
16
|
__name: "CountryBreakdownCard",
|
|
18
17
|
props: {
|
|
19
18
|
toolName: {},
|
|
@@ -25,7 +24,7 @@ const W = { class: "w-full" }, X = {
|
|
|
25
24
|
},
|
|
26
25
|
emits: ["submit"],
|
|
27
26
|
setup(_, { emit: A }) {
|
|
28
|
-
const c = _, C = A, N =
|
|
27
|
+
const { $useRoute: $, $useModuleOverlay: xe } = useNuxtApp(), c = _, C = A, N = $(), L = y(() => N.params.slug), z = $useModuleApi(c.instanceId), g = v(!0), p = v(null), n = v([]), x = v(null), D = (e) => ({
|
|
29
28
|
"United States": "🇺🇸",
|
|
30
29
|
"United Kingdom": "🇬🇧",
|
|
31
30
|
Germany: "🇩🇪",
|
|
@@ -73,7 +72,7 @@ const W = { class: "w-full" }, X = {
|
|
|
73
72
|
Greece: "🇬🇷",
|
|
74
73
|
Luxembourg: "🇱🇺"
|
|
75
74
|
})[e] || "🌍";
|
|
76
|
-
function
|
|
75
|
+
function U() {
|
|
77
76
|
const e = c.resolvedArgs?._cachedData;
|
|
78
77
|
return e ? (n.value = (e.countries || []).map((t) => ({
|
|
79
78
|
country: t.country,
|
|
@@ -81,15 +80,15 @@ const W = { class: "w-full" }, X = {
|
|
|
81
80
|
totalUsers: t.users
|
|
82
81
|
})), x.value = c.resolvedArgs._fetchedAt || null, g.value = !1, !0) : !1;
|
|
83
82
|
}
|
|
84
|
-
async function
|
|
83
|
+
async function F() {
|
|
85
84
|
const { startDate: e, endDate: t } = c.resolvedArgs || {};
|
|
86
85
|
g.value = !0, p.value = null;
|
|
87
86
|
try {
|
|
88
87
|
const a = new URLSearchParams();
|
|
89
88
|
e && a.set("startDate", e), t && a.set("endDate", t);
|
|
90
|
-
const r = await
|
|
89
|
+
const r = await z.get(`/countries?${a.toString()}`);
|
|
91
90
|
n.value = r.rows || [], x.value = (/* @__PURE__ */ new Date()).toISOString();
|
|
92
|
-
const h = n.value.reduce((d,
|
|
91
|
+
const h = n.value.reduce((d, T) => d + (T.sessions || 0), 0);
|
|
93
92
|
b({
|
|
94
93
|
count: n.value.length,
|
|
95
94
|
countries: n.value.map((d) => ({
|
|
@@ -106,82 +105,82 @@ const W = { class: "w-full" }, X = {
|
|
|
106
105
|
g.value = !1;
|
|
107
106
|
}
|
|
108
107
|
}
|
|
109
|
-
|
|
110
|
-
c.status === "completed" &&
|
|
108
|
+
B(() => {
|
|
109
|
+
c.status === "completed" && U() || F();
|
|
111
110
|
});
|
|
112
111
|
function b(e) {
|
|
113
112
|
c.status !== "completed" && C("submit", e);
|
|
114
113
|
}
|
|
115
|
-
const S = (e) => e == null ? "0" : Math.round(e).toLocaleString(),
|
|
114
|
+
const S = (e) => e == null ? "0" : Math.round(e).toLocaleString(), I = (e) => e ? new Date(e).toLocaleString(void 0, { month: "short", day: "numeric", hour: "2-digit", minute: "2-digit" }) : "", M = y(
|
|
116
115
|
() => n.value.reduce((e, t) => e + (t.sessions || 0), 0) || 1
|
|
117
|
-
),
|
|
116
|
+
), V = y(
|
|
118
117
|
() => Math.max(...n.value.map((e) => e.sessions || 0), 1)
|
|
119
|
-
),
|
|
118
|
+
), E = y(() => {
|
|
120
119
|
const { startDate: e, endDate: t } = c.resolvedArgs || {};
|
|
121
120
|
if (!e && !t) return "Last 30 days";
|
|
122
121
|
const a = e || "30daysAgo", r = a.match(/^(\d+)daysAgo$/);
|
|
123
122
|
return r ? `Last ${r[1]} days` : `${a} → ${t || "today"}`;
|
|
124
123
|
});
|
|
125
124
|
return (e, t) => {
|
|
126
|
-
const a =
|
|
127
|
-
return l(), u("div",
|
|
128
|
-
s(g) ? (l(), u("div",
|
|
125
|
+
const a = P("NuxtLink");
|
|
126
|
+
return l(), u("div", Q, [
|
|
127
|
+
s(g) ? (l(), u("div", W, [
|
|
129
128
|
m(s(H), { class: "size-4 animate-spin text-muted-foreground" }),
|
|
130
129
|
t[0] || (t[0] = o("span", { class: "text-xs text-muted-foreground" }, "Loading country data…", -1))
|
|
131
|
-
])) : s(p) ? (l(), u("div",
|
|
130
|
+
])) : s(p) ? (l(), u("div", X, i(s(p)), 1)) : s(n).length === 0 ? (l(), u("div", Y, [
|
|
132
131
|
m(s(w), { class: "size-8 text-muted-foreground mx-auto" }),
|
|
133
132
|
t[1] || (t[1] = o("p", { class: "text-sm text-muted-foreground" }, "No geographic data found for this period.", -1))
|
|
134
|
-
])) : (l(), u("div",
|
|
135
|
-
o("div",
|
|
136
|
-
o("div",
|
|
133
|
+
])) : (l(), u("div", ee, [
|
|
134
|
+
o("div", te, [
|
|
135
|
+
o("div", se, [
|
|
137
136
|
m(s(w), { class: "size-3.5 text-primary" }),
|
|
138
137
|
t[2] || (t[2] = o("span", { class: "text-xs font-medium" }, "Visitors by Country", -1))
|
|
139
138
|
]),
|
|
140
|
-
o("span",
|
|
139
|
+
o("span", oe, i(s(E)), 1)
|
|
141
140
|
]),
|
|
142
|
-
o("div",
|
|
143
|
-
(l(!0), u(k, null,
|
|
141
|
+
o("div", ne, [
|
|
142
|
+
(l(!0), u(k, null, R(s(n), (r, h) => (l(), u("div", {
|
|
144
143
|
key: h,
|
|
145
144
|
class: "px-3 py-2.5 hover:bg-muted/30 transition-colors"
|
|
146
145
|
}, [
|
|
147
|
-
o("div",
|
|
148
|
-
o("span",
|
|
149
|
-
o("span",
|
|
150
|
-
o("span",
|
|
146
|
+
o("div", ae, [
|
|
147
|
+
o("span", re, i(D(r.country)), 1),
|
|
148
|
+
o("span", ie, i(r.country), 1),
|
|
149
|
+
o("span", de, i((r.sessions / s(M) * 100).toFixed(1)) + "%", 1)
|
|
151
150
|
]),
|
|
152
|
-
o("div",
|
|
153
|
-
o("div",
|
|
151
|
+
o("div", le, [
|
|
152
|
+
o("div", ue, [
|
|
154
153
|
o("div", {
|
|
155
154
|
class: "h-full rounded-full bg-blue-500/70 transition-all",
|
|
156
|
-
style:
|
|
155
|
+
style: G({ width: `${r.sessions / s(V) * 100}%` })
|
|
157
156
|
}, null, 4)
|
|
158
157
|
]),
|
|
159
|
-
o("div",
|
|
160
|
-
o("span",
|
|
158
|
+
o("div", ce, [
|
|
159
|
+
o("span", me, [
|
|
161
160
|
m(s(J), { class: "size-2.5" }),
|
|
162
161
|
f(" " + i(S(r.sessions)) + " sessions ", 1)
|
|
163
162
|
]),
|
|
164
|
-
o("span",
|
|
165
|
-
m(s(
|
|
163
|
+
o("span", pe, [
|
|
164
|
+
m(s(Z), { class: "size-2.5" }),
|
|
166
165
|
f(" " + i(S(r.totalUsers)) + " users ", 1)
|
|
167
166
|
])
|
|
168
167
|
])
|
|
169
168
|
])
|
|
170
169
|
]))), 128))
|
|
171
170
|
]),
|
|
172
|
-
o("div",
|
|
173
|
-
o("span",
|
|
171
|
+
o("div", fe, [
|
|
172
|
+
o("span", ge, [
|
|
174
173
|
f(i(s(n).length) + " countr" + i(s(n).length === 1 ? "y" : "ies") + " ", 1),
|
|
175
174
|
s(x) ? (l(), u(k, { key: 0 }, [
|
|
176
|
-
f(" · fetched " + i(
|
|
177
|
-
], 64)) :
|
|
175
|
+
f(" · fetched " + i(I(s(x))), 1)
|
|
176
|
+
], 64)) : K("", !0)
|
|
178
177
|
]),
|
|
179
178
|
m(a, {
|
|
180
179
|
to: `/projects/${s(L)}/modules/${_.instanceId}`,
|
|
181
180
|
class: "inline-flex items-center gap-1.5 text-xs text-primary hover:underline"
|
|
182
181
|
}, {
|
|
183
|
-
default:
|
|
184
|
-
m(s(
|
|
182
|
+
default: O(() => [
|
|
183
|
+
m(s(q), { class: "size-3" }),
|
|
185
184
|
t[3] || (t[3] = f(" View full report ", -1))
|
|
186
185
|
]),
|
|
187
186
|
_: 1
|
|
@@ -193,5 +192,5 @@ const W = { class: "w-full" }, X = {
|
|
|
193
192
|
}
|
|
194
193
|
});
|
|
195
194
|
export {
|
|
196
|
-
|
|
195
|
+
ve as default
|
|
197
196
|
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("vue"),l=require("lucide-vue-next"),L={class:"w-full"},$={key:0,class:"flex items-center gap-2 py-3"},z={key:1,class:"text-xs text-destructive py-2"},A={key:2,class:"rounded-xl border bg-background p-4 text-center space-y-2"},M={key:3,class:"rounded-xl border bg-background overflow-hidden"},T={class:"px-3 py-2 border-b bg-muted/40 flex items-center justify-between"},F={class:"flex items-center gap-2"},j={class:"text-[10px] text-muted-foreground"},I={class:"px-3 pt-3 pb-1"},U={class:"flex h-3 rounded-full overflow-hidden"},O={class:"divide-y"},P={class:"flex items-center gap-2"},q={class:"text-xs font-medium capitalize flex-1"},R={class:"text-sm font-semibold tabular-nums"},G={class:"ml-6 mt-1 flex items-center gap-3 text-[10px] text-muted-foreground"},H={class:"flex items-center gap-1"},J={class:"flex items-center gap-1"},K={class:"px-3 py-2 border-t bg-muted/20 flex items-center justify-between"},Q={class:"text-[10px] text-muted-foreground"},W=e.defineComponent({__name:"DeviceBreakdownCard",props:{toolName:{},instanceId:{},instanceName:{},moduleType:{},resolvedArgs:{},status:{}},emits:["submit"],setup(v,{emit:x}){const{$useRoute:y,$useModuleOverlay:X}=useNuxtApp(),i=v,h=x,b=y(),k=e.computed(()=>b.params.slug),N=$useModuleApi(i.instanceId),u=e.ref(!0),d=e.ref(null),r=e.ref([]),m=e.ref(null),_=s=>{const t=(s||"").toLowerCase();return t==="mobile"||t==="smartphone"?l.Smartphone:t==="tablet"?l.Tablet:l.Monitor},V=s=>{const t=(s||"").toLowerCase();return t==="desktop"?"bg-blue-500":t==="mobile"||t==="smartphone"?"bg-emerald-500":t==="tablet"?"bg-amber-500":"bg-violet-500"},E=s=>{const t=(s||"").toLowerCase();return t==="desktop"?"text-blue-500":t==="mobile"||t==="smartphone"?"text-emerald-500":t==="tablet"?"text-amber-500":"text-violet-500"};function B(){const s=i.resolvedArgs?._cachedData;return s?(r.value=(s.devices||[]).map(t=>({deviceCategory:t.device,sessions:t.sessions,totalUsers:t.users})),m.value=i.resolvedArgs._fetchedAt||null,u.value=!1,!0):!1}async function w(){const{startDate:s,endDate:t}=i.resolvedArgs||{};u.value=!0,d.value=null;try{const n=new URLSearchParams;s&&n.set("startDate",s),t&&n.set("endDate",t);const o=await N.get(`/devices?${n.toString()}`);r.value=o.rows||[],m.value=new Date().toISOString();const c=r.value.reduce((a,S)=>a+(S.sessions||0),0);g({count:r.value.length,devices:r.value.map(a=>({device:a.deviceCategory,sessions:a.sessions,users:a.totalUsers,share:`${(a.sessions/c*100).toFixed(1)}%`})),suggestion:r.value.length===0?"No device data found for this period.":`Device breakdown: ${r.value.map(a=>`${a.deviceCategory} ${(a.sessions/c*100).toFixed(0)}%`).join(", ")}.`})}catch(n){d.value=n?.data?.statusMessage||n?.message||"Failed to load device data",g(`Error loading device data: ${d.value}`)}finally{u.value=!1}}e.onMounted(()=>{i.status==="completed"&&B()||w()});function g(s){i.status!=="completed"&&h("submit",s)}const f=s=>s==null?"0":Math.round(s).toLocaleString(),C=s=>s?new Date(s).toLocaleString(void 0,{month:"short",day:"numeric",hour:"2-digit",minute:"2-digit"}):"",p=e.computed(()=>r.value.reduce((s,t)=>s+(t.sessions||0),0)||1),D=e.computed(()=>{const{startDate:s,endDate:t}=i.resolvedArgs||{};if(!s&&!t)return"Last 30 days";const n=s||"30daysAgo",o=n.match(/^(\d+)daysAgo$/);return o?`Last ${o[1]} days`:`${n} → ${t||"today"}`});return(s,t)=>{const n=e.resolveComponent("NuxtLink");return e.openBlock(),e.createElementBlock("div",L,[e.unref(u)?(e.openBlock(),e.createElementBlock("div",$,[e.createVNode(e.unref(l.Loader2),{class:"size-4 animate-spin text-muted-foreground"}),t[0]||(t[0]=e.createElementVNode("span",{class:"text-xs text-muted-foreground"},"Loading device data…",-1))])):e.unref(d)?(e.openBlock(),e.createElementBlock("div",z,e.toDisplayString(e.unref(d)),1)):e.unref(r).length===0?(e.openBlock(),e.createElementBlock("div",A,[e.createVNode(e.unref(l.Monitor),{class:"size-8 text-muted-foreground mx-auto"}),t[1]||(t[1]=e.createElementVNode("p",{class:"text-sm text-muted-foreground"},"No device data found for this period.",-1))])):(e.openBlock(),e.createElementBlock("div",M,[e.createElementVNode("div",T,[e.createElementVNode("div",F,[e.createVNode(e.unref(l.Monitor),{class:"size-3.5 text-primary"}),t[2]||(t[2]=e.createElementVNode("span",{class:"text-xs font-medium"},"Device Breakdown",-1))]),e.createElementVNode("span",j,e.toDisplayString(e.unref(D)),1)]),e.createElementVNode("div",I,[e.createElementVNode("div",U,[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(e.unref(r),(o,c)=>(e.openBlock(),e.createElementBlock("div",{key:c,class:e.normalizeClass([V(o.deviceCategory),"transition-all first:rounded-l-full last:rounded-r-full"]),style:e.normalizeStyle({width:`${o.sessions/e.unref(p)*100}%`})},null,6))),128))])]),e.createElementVNode("div",O,[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(e.unref(r),(o,c)=>(e.openBlock(),e.createElementBlock("div",{key:c,class:"px-3 py-2.5 hover:bg-muted/30 transition-colors"},[e.createElementVNode("div",P,[(e.openBlock(),e.createBlock(e.resolveDynamicComponent(_(o.deviceCategory)),{class:e.normalizeClass(["size-4 shrink-0",E(o.deviceCategory)])},null,8,["class"])),e.createElementVNode("span",q,e.toDisplayString(o.deviceCategory),1),e.createElementVNode("span",R,e.toDisplayString((o.sessions/e.unref(p)*100).toFixed(1))+"% ",1)]),e.createElementVNode("div",G,[e.createElementVNode("span",H,[e.createVNode(e.unref(l.MousePointerClick),{class:"size-2.5"}),e.createTextVNode(" "+e.toDisplayString(f(o.sessions))+" sessions ",1)]),e.createElementVNode("span",J,[e.createVNode(e.unref(l.Users),{class:"size-2.5"}),e.createTextVNode(" "+e.toDisplayString(f(o.totalUsers))+" users ",1)])])]))),128))]),e.createElementVNode("div",K,[e.createElementVNode("span",Q,[e.createTextVNode(e.toDisplayString(f(e.unref(p)))+" total sessions ",1),e.unref(m)?(e.openBlock(),e.createElementBlock(e.Fragment,{key:0},[e.createTextVNode(" · fetched "+e.toDisplayString(C(e.unref(m))),1)],64)):e.createCommentVNode("",!0)]),e.createVNode(n,{to:`/projects/${e.unref(k)}/modules/${v.instanceId}`,class:"inline-flex items-center gap-1.5 text-xs text-primary hover:underline"},{default:e.withCtx(()=>[e.createVNode(e.unref(l.ExternalLink),{class:"size-3"}),t[3]||(t[3]=e.createTextVNode(" View full report ",-1))]),_:1},8,["to"])])]))])}}});exports.default=W;
|