@oneclick.dev/cms-core-modules 0.0.79 → 0.0.81
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-Bu9VzIRx.mjs → AppointmentDetailsCard-33WpATpV.mjs} +43 -43
- package/dist/AppointmentDetailsCard-DpLM5IrB.js +1 -0
- package/dist/AppointmentListTable-CQ0WIXtj.js +1 -0
- package/dist/{AppointmentListTable-B8YLwOfT.mjs → AppointmentListTable-aV_UJd6j.mjs} +42 -42
- package/dist/CountryBreakdownCard-D7BK3nRD.js +1 -0
- package/dist/{CountryBreakdownCard-oDzmpvAd.mjs → CountryBreakdownCard-DVxNz2DJ.mjs} +48 -48
- package/dist/DeviceBreakdownCard-DRhQ9ufG.js +1 -0
- package/dist/{DeviceBreakdownCard-Oh_yzipG.mjs → DeviceBreakdownCard-W1frLe0L.mjs} +58 -58
- package/dist/{PeakHoursCard-DzNo4SNo.mjs → PeakHoursCard-9-EZFZLR.mjs} +55 -55
- package/dist/PeakHoursCard-BR5zmta4.js +1 -0
- package/dist/ProductDetailsCard-6nHikw4V.mjs +121 -0
- package/dist/ProductDetailsCard-Bn7qrgmc.js +1 -0
- package/dist/RealtimeCard--APfRNc8.js +1 -0
- package/dist/{RealtimeCard-tNUSIw6B.mjs → RealtimeCard-fvQlJcM7.mjs} +41 -41
- package/dist/SearchTermsCard-BsB-63aH.js +1 -0
- package/dist/{SearchTermsCard-BVHFHWUZ.mjs → SearchTermsCard-BzVrHKqQ.mjs} +57 -57
- package/dist/TopPagesCard-BDeA997A.js +1 -0
- package/dist/{TopPagesCard-CRIa3rSZ.mjs → TopPagesCard-CTozhOr_.mjs} +48 -48
- package/dist/{TrafficSourcesCard-Ct20QYax.mjs → TrafficSourcesCard-BxtCKsqx.mjs} +65 -65
- package/dist/TrafficSourcesCard-C3ziDTUL.js +1 -0
- package/dist/VisitorStatsCard-BmByE_Hi.js +1 -0
- package/dist/{VisitorStatsCard-DMULybKV.mjs → VisitorStatsCard-CXizEbVK.mjs} +55 -55
- package/dist/index.cjs.js +1 -1
- package/dist/index.mjs +11 -11
- package/package.json +2 -2
- package/dist/AppointmentDetailsCard-LL-6PARb.js +0 -1
- package/dist/AppointmentListTable-DNvvb4sz.js +0 -1
- package/dist/CountryBreakdownCard-BpDXbxwZ.js +0 -1
- package/dist/DeviceBreakdownCard-OXiU9Cf0.js +0 -1
- package/dist/PeakHoursCard-OkgI1vnd.js +0 -1
- package/dist/ProductDetailsCard-BBOorNmB.js +0 -1
- package/dist/ProductDetailsCard-CYK9Mtt4.mjs +0 -121
- package/dist/RealtimeCard-DESm9Fs_.js +0 -1
- package/dist/SearchTermsCard-DmyhGQVM.js +0 -1
- package/dist/TopPagesCard-CgtNyhwY.js +0 -1
- package/dist/TrafficSourcesCard-CPAxaQTi.js +0 -1
- package/dist/VisitorStatsCard-Cs6jPehw.js +0 -1
|
@@ -1,18 +1,18 @@
|
|
|
1
|
-
import { defineComponent as
|
|
2
|
-
import { Loader2 as
|
|
3
|
-
const
|
|
1
|
+
import { defineComponent as O, computed as _, ref as h, onMounted as q, resolveComponent as G, openBlock as i, createElementBlock as l, unref as s, createVNode as m, createElementVNode as o, toDisplayString as c, Fragment as k, renderList as L, normalizeStyle as H, normalizeClass as $, createBlock as J, resolveDynamicComponent as K, createTextVNode as v, createCommentVNode as Q, withCtx as W } from "vue";
|
|
2
|
+
import { Loader2 as X, Monitor as w, MousePointerClick as Y, Users as Z, ExternalLink as ee, Smartphone as te, Tablet as se } from "lucide-vue-next";
|
|
3
|
+
const oe = { class: "w-full" }, ne = {
|
|
4
4
|
key: 0,
|
|
5
5
|
class: "flex items-center gap-2 py-3"
|
|
6
|
-
},
|
|
6
|
+
}, re = {
|
|
7
7
|
key: 1,
|
|
8
8
|
class: "text-xs text-destructive py-2"
|
|
9
|
-
},
|
|
9
|
+
}, ae = {
|
|
10
10
|
key: 2,
|
|
11
11
|
class: "rounded-xl border bg-background p-4 text-center space-y-2"
|
|
12
|
-
},
|
|
12
|
+
}, ie = {
|
|
13
13
|
key: 3,
|
|
14
14
|
class: "rounded-xl border bg-background overflow-hidden"
|
|
15
|
-
},
|
|
15
|
+
}, le = { class: "px-3 py-2 border-b bg-muted/40 flex items-center justify-between" }, de = { class: "flex items-center gap-2" }, ce = { class: "text-[10px] text-muted-foreground" }, ue = { class: "px-3 pt-3 pb-1" }, me = { class: "flex h-3 rounded-full overflow-hidden" }, pe = { class: "divide-y" }, fe = { class: "flex items-center gap-2" }, ve = { class: "text-xs font-medium capitalize flex-1" }, xe = { class: "text-sm font-semibold tabular-nums" }, ge = { class: "ml-6 mt-1 flex items-center gap-3 text-[10px] text-muted-foreground" }, he = { class: "flex items-center gap-1" }, ye = { class: "flex items-center gap-1" }, be = { class: "px-3 py-2 border-t bg-muted/20 flex items-center justify-between" }, _e = { class: "text-[10px] text-muted-foreground" }, Ce = /* @__PURE__ */ O({
|
|
16
16
|
__name: "DeviceBreakdownCard",
|
|
17
17
|
props: {
|
|
18
18
|
toolName: {},
|
|
@@ -24,17 +24,17 @@ const se = { class: "w-full" }, oe = {
|
|
|
24
24
|
},
|
|
25
25
|
emits: ["submit"],
|
|
26
26
|
setup(C, { emit: S }) {
|
|
27
|
-
const { $useRoute: N, $
|
|
27
|
+
const { $useRoute: N, $useModuleApi: A } = useNuxtApp(), u = C, z = S, F = N(), M = _(() => F.params.slug), j = A(u.instanceId), x = h(!0), f = h(null), r = h([]), g = h(null), B = (t) => {
|
|
28
28
|
const e = (t || "").toLowerCase();
|
|
29
|
-
return e === "mobile" || e === "smartphone" ?
|
|
30
|
-
},
|
|
29
|
+
return e === "mobile" || e === "smartphone" ? te : e === "tablet" ? se : w;
|
|
30
|
+
}, I = (t) => {
|
|
31
31
|
const e = (t || "").toLowerCase();
|
|
32
32
|
return e === "desktop" ? "bg-blue-500" : e === "mobile" || e === "smartphone" ? "bg-emerald-500" : e === "tablet" ? "bg-amber-500" : "bg-violet-500";
|
|
33
|
-
},
|
|
33
|
+
}, T = (t) => {
|
|
34
34
|
const e = (t || "").toLowerCase();
|
|
35
35
|
return e === "desktop" ? "text-blue-500" : e === "mobile" || e === "smartphone" ? "text-emerald-500" : e === "tablet" ? "text-amber-500" : "text-violet-500";
|
|
36
36
|
};
|
|
37
|
-
function
|
|
37
|
+
function U() {
|
|
38
38
|
const t = u.resolvedArgs?._cachedData;
|
|
39
39
|
return t ? (r.value = (t.devices || []).map((e) => ({
|
|
40
40
|
deviceCategory: e.device,
|
|
@@ -42,16 +42,16 @@ const se = { class: "w-full" }, oe = {
|
|
|
42
42
|
totalUsers: e.users
|
|
43
43
|
})), g.value = u.resolvedArgs._fetchedAt || null, x.value = !1, !0) : !1;
|
|
44
44
|
}
|
|
45
|
-
async function
|
|
45
|
+
async function V() {
|
|
46
46
|
const { startDate: t, endDate: e } = u.resolvedArgs || {};
|
|
47
|
-
x.value = !0,
|
|
47
|
+
x.value = !0, f.value = null;
|
|
48
48
|
try {
|
|
49
49
|
const a = new URLSearchParams();
|
|
50
50
|
t && a.set("startDate", t), e && a.set("endDate", e);
|
|
51
|
-
const n = await
|
|
51
|
+
const n = await j.get(`/devices?${a.toString()}`);
|
|
52
52
|
r.value = n.rows || [], g.value = (/* @__PURE__ */ new Date()).toISOString();
|
|
53
|
-
const p = r.value.reduce((d,
|
|
54
|
-
|
|
53
|
+
const p = r.value.reduce((d, R) => d + (R.sessions || 0), 0);
|
|
54
|
+
D({
|
|
55
55
|
count: r.value.length,
|
|
56
56
|
devices: r.value.map((d) => ({
|
|
57
57
|
device: d.deviceCategory,
|
|
@@ -62,89 +62,89 @@ const se = { class: "w-full" }, oe = {
|
|
|
62
62
|
suggestion: r.value.length === 0 ? "No device data found for this period." : `Device breakdown: ${r.value.map((d) => `${d.deviceCategory} ${(d.sessions / p * 100).toFixed(0)}%`).join(", ")}.`
|
|
63
63
|
});
|
|
64
64
|
} catch (a) {
|
|
65
|
-
|
|
65
|
+
f.value = a?.data?.statusMessage || a?.message || "Failed to load device data", D(`Error loading device data: ${f.value}`);
|
|
66
66
|
} finally {
|
|
67
67
|
x.value = !1;
|
|
68
68
|
}
|
|
69
69
|
}
|
|
70
|
-
|
|
71
|
-
u.status === "completed" &&
|
|
70
|
+
q(() => {
|
|
71
|
+
u.status === "completed" && U() || V();
|
|
72
72
|
});
|
|
73
|
-
function
|
|
74
|
-
u.status !== "completed" &&
|
|
73
|
+
function D(t) {
|
|
74
|
+
u.status !== "completed" && z("submit", t);
|
|
75
75
|
}
|
|
76
|
-
const y = (t) => t == null ? "0" : Math.round(t).toLocaleString(),
|
|
76
|
+
const y = (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" }) : "", b = _(
|
|
77
77
|
() => r.value.reduce((t, e) => t + (e.sessions || 0), 0) || 1
|
|
78
|
-
),
|
|
78
|
+
), P = _(() => {
|
|
79
79
|
const { startDate: t, endDate: e } = u.resolvedArgs || {};
|
|
80
80
|
if (!t && !e) return "Last 30 days";
|
|
81
81
|
const a = t || "30daysAgo", n = a.match(/^(\d+)daysAgo$/);
|
|
82
82
|
return n ? `Last ${n[1]} days` : `${a} → ${e || "today"}`;
|
|
83
83
|
});
|
|
84
84
|
return (t, e) => {
|
|
85
|
-
const a =
|
|
86
|
-
return i(), l("div",
|
|
87
|
-
s(x) ? (i(), l("div",
|
|
88
|
-
m(s(
|
|
85
|
+
const a = G("NuxtLink");
|
|
86
|
+
return i(), l("div", oe, [
|
|
87
|
+
s(x) ? (i(), l("div", ne, [
|
|
88
|
+
m(s(X), { class: "size-4 animate-spin text-muted-foreground" }),
|
|
89
89
|
e[0] || (e[0] = o("span", { class: "text-xs text-muted-foreground" }, "Loading device data…", -1))
|
|
90
|
-
])) : s(
|
|
90
|
+
])) : s(f) ? (i(), l("div", re, c(s(f)), 1)) : s(r).length === 0 ? (i(), l("div", ae, [
|
|
91
91
|
m(s(w), { class: "size-8 text-muted-foreground mx-auto" }),
|
|
92
92
|
e[1] || (e[1] = o("p", { class: "text-sm text-muted-foreground" }, "No device data found for this period.", -1))
|
|
93
|
-
])) : (i(), l("div",
|
|
94
|
-
o("div",
|
|
95
|
-
o("div",
|
|
93
|
+
])) : (i(), l("div", ie, [
|
|
94
|
+
o("div", le, [
|
|
95
|
+
o("div", de, [
|
|
96
96
|
m(s(w), { class: "size-3.5 text-primary" }),
|
|
97
97
|
e[2] || (e[2] = o("span", { class: "text-xs font-medium" }, "Device Breakdown", -1))
|
|
98
98
|
]),
|
|
99
|
-
o("span",
|
|
99
|
+
o("span", ce, c(s(P)), 1)
|
|
100
100
|
]),
|
|
101
|
-
o("div",
|
|
102
|
-
o("div",
|
|
103
|
-
(i(!0), l(k, null,
|
|
101
|
+
o("div", ue, [
|
|
102
|
+
o("div", me, [
|
|
103
|
+
(i(!0), l(k, null, L(s(r), (n, p) => (i(), l("div", {
|
|
104
104
|
key: p,
|
|
105
|
-
class:
|
|
106
|
-
style:
|
|
105
|
+
class: $([I(n.deviceCategory), "transition-all first:rounded-l-full last:rounded-r-full"]),
|
|
106
|
+
style: H({ width: `${n.sessions / s(b) * 100}%` })
|
|
107
107
|
}, null, 6))), 128))
|
|
108
108
|
])
|
|
109
109
|
]),
|
|
110
|
-
o("div",
|
|
111
|
-
(i(!0), l(k, null,
|
|
110
|
+
o("div", pe, [
|
|
111
|
+
(i(!0), l(k, null, L(s(r), (n, p) => (i(), l("div", {
|
|
112
112
|
key: p,
|
|
113
113
|
class: "px-3 py-2.5 hover:bg-muted/30 transition-colors"
|
|
114
114
|
}, [
|
|
115
|
-
o("div",
|
|
116
|
-
(i(),
|
|
117
|
-
class:
|
|
115
|
+
o("div", fe, [
|
|
116
|
+
(i(), J(K(B(n.deviceCategory)), {
|
|
117
|
+
class: $(["size-4 shrink-0", T(n.deviceCategory)])
|
|
118
118
|
}, null, 8, ["class"])),
|
|
119
119
|
o("span", ve, c(n.deviceCategory), 1),
|
|
120
|
-
o("span",
|
|
120
|
+
o("span", xe, c((n.sessions / s(b) * 100).toFixed(1)) + "% ", 1)
|
|
121
121
|
]),
|
|
122
|
-
o("div",
|
|
123
|
-
o("span", ge, [
|
|
124
|
-
m(s(X), { class: "size-2.5" }),
|
|
125
|
-
f(" " + c(y(n.sessions)) + " sessions ", 1)
|
|
126
|
-
]),
|
|
122
|
+
o("div", ge, [
|
|
127
123
|
o("span", he, [
|
|
128
124
|
m(s(Y), { class: "size-2.5" }),
|
|
129
|
-
|
|
125
|
+
v(" " + c(y(n.sessions)) + " sessions ", 1)
|
|
126
|
+
]),
|
|
127
|
+
o("span", ye, [
|
|
128
|
+
m(s(Z), { class: "size-2.5" }),
|
|
129
|
+
v(" " + c(y(n.totalUsers)) + " users ", 1)
|
|
130
130
|
])
|
|
131
131
|
])
|
|
132
132
|
]))), 128))
|
|
133
133
|
]),
|
|
134
|
-
o("div",
|
|
135
|
-
o("span",
|
|
136
|
-
|
|
134
|
+
o("div", be, [
|
|
135
|
+
o("span", _e, [
|
|
136
|
+
v(c(y(s(b))) + " total sessions ", 1),
|
|
137
137
|
s(g) ? (i(), l(k, { key: 0 }, [
|
|
138
|
-
|
|
139
|
-
], 64)) :
|
|
138
|
+
v(" · fetched " + c(E(s(g))), 1)
|
|
139
|
+
], 64)) : Q("", !0)
|
|
140
140
|
]),
|
|
141
141
|
m(a, {
|
|
142
142
|
to: `/projects/${s(M)}/modules/${C.instanceId}`,
|
|
143
143
|
class: "inline-flex items-center gap-1.5 text-xs text-primary hover:underline"
|
|
144
144
|
}, {
|
|
145
|
-
default:
|
|
146
|
-
m(s(
|
|
147
|
-
e[3] || (e[3] =
|
|
145
|
+
default: W(() => [
|
|
146
|
+
m(s(ee), { class: "size-3" }),
|
|
147
|
+
e[3] || (e[3] = v(" View full report ", -1))
|
|
148
148
|
]),
|
|
149
149
|
_: 1
|
|
150
150
|
}, 8, ["to"])
|
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
import { defineComponent as
|
|
2
|
-
import { Loader2 as
|
|
3
|
-
const
|
|
1
|
+
import { defineComponent as Z, computed as g, ref as f, onMounted as ee, resolveComponent as te, openBlock as r, createElementBlock as l, unref as a, createVNode as $, createElementVNode as o, toDisplayString as y, createCommentVNode as L, Fragment as A, renderList as N, normalizeStyle as se, normalizeClass as F, createStaticVNode as oe, createTextVNode as I, withCtx as ae } from "vue";
|
|
2
|
+
import { Loader2 as ne, Clock as re, ExternalLink as le } from "lucide-vue-next";
|
|
3
|
+
const ue = { class: "w-full" }, ie = {
|
|
4
4
|
key: 0,
|
|
5
5
|
class: "flex items-center gap-2 py-3"
|
|
6
|
-
},
|
|
6
|
+
}, de = {
|
|
7
7
|
key: 1,
|
|
8
8
|
class: "text-xs text-destructive py-2"
|
|
9
|
-
},
|
|
9
|
+
}, ce = {
|
|
10
10
|
key: 2,
|
|
11
11
|
class: "rounded-xl border bg-background overflow-hidden"
|
|
12
|
-
},
|
|
12
|
+
}, pe = { class: "px-3 py-2 border-b bg-muted/40 flex items-center justify-between" }, fe = { class: "flex items-center gap-2" }, me = { class: "text-[10px] text-muted-foreground" }, xe = {
|
|
13
13
|
key: 0,
|
|
14
14
|
class: "px-3 pt-3 pb-1"
|
|
15
|
-
},
|
|
15
|
+
}, ge = { class: "flex items-center gap-2 text-xs" }, ye = { class: "inline-flex items-center gap-1 px-2 py-0.5 rounded-full bg-blue-500/10 text-blue-600 dark:text-blue-400 font-medium" }, he = { class: "px-3 py-3" }, be = { class: "flex items-end gap-[2px] h-16" }, ve = ["title"], ke = {
|
|
16
16
|
key: 1,
|
|
17
17
|
class: "px-3 pb-3"
|
|
18
|
-
},
|
|
18
|
+
}, _e = { class: "space-y-[2px]" }, Se = { class: "text-[8px] text-muted-foreground w-6 shrink-0 text-right" }, Me = { class: "flex gap-[2px] flex-1" }, $e = ["title"], Ae = { class: "px-3 py-2 border-t bg-muted/20 flex items-center justify-between" }, De = { class: "text-[10px] text-muted-foreground" }, Ne = /* @__PURE__ */ Z({
|
|
19
19
|
__name: "PeakHoursCard",
|
|
20
20
|
props: {
|
|
21
21
|
toolName: {},
|
|
@@ -26,8 +26,8 @@ const le = { class: "w-full" }, ue = {
|
|
|
26
26
|
status: {}
|
|
27
27
|
},
|
|
28
28
|
emits: ["submit"],
|
|
29
|
-
setup(P, { emit:
|
|
30
|
-
const { $useRoute: V, $
|
|
29
|
+
setup(P, { emit: O }) {
|
|
30
|
+
const { $useRoute: V, $useModuleApi: j } = useNuxtApp(), c = P, z = O, E = V(), B = g(() => E.params.slug), R = j(c.instanceId), h = f(!0), m = f(null), b = f([]), x = f(null), v = f(null), U = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"], H = {
|
|
31
31
|
Sunday: "Sun",
|
|
32
32
|
Monday: "Mon",
|
|
33
33
|
Tuesday: "Tue",
|
|
@@ -35,22 +35,22 @@ const le = { class: "w-full" }, ue = {
|
|
|
35
35
|
Thursday: "Thu",
|
|
36
36
|
Friday: "Fri",
|
|
37
37
|
Saturday: "Sat"
|
|
38
|
-
}, p = f([]),
|
|
39
|
-
function
|
|
40
|
-
const t = e /
|
|
38
|
+
}, p = f([]), q = g(() => Math.max(...p.value.map((e) => e.sessions), 1));
|
|
39
|
+
function G(e) {
|
|
40
|
+
const t = e / q.value;
|
|
41
41
|
return t === 0 ? "bg-muted/40" : t < 0.2 ? "bg-blue-100 dark:bg-blue-950" : t < 0.4 ? "bg-blue-200 dark:bg-blue-900" : t < 0.6 ? "bg-blue-300 dark:bg-blue-700" : t < 0.8 ? "bg-blue-400 dark:bg-blue-600" : "bg-blue-500 dark:bg-blue-500";
|
|
42
42
|
}
|
|
43
|
-
function
|
|
43
|
+
function J() {
|
|
44
44
|
const e = c.resolvedArgs?._cachedData;
|
|
45
45
|
return e ? (b.value = e.hourly || [], x.value = e.peakHour ?? null, p.value = e.heatmap || [], v.value = c.resolvedArgs._fetchedAt || null, h.value = !1, !0) : !1;
|
|
46
46
|
}
|
|
47
|
-
async function
|
|
47
|
+
async function K() {
|
|
48
48
|
const { startDate: e, endDate: t } = c.resolvedArgs || {};
|
|
49
49
|
h.value = !0, m.value = null;
|
|
50
50
|
try {
|
|
51
51
|
const u = new URLSearchParams();
|
|
52
52
|
e && u.set("startDate", e), t && u.set("endDate", t);
|
|
53
|
-
const d = (await
|
|
53
|
+
const d = (await R.get(`/audience/hours?${u.toString()}`)).rows || [];
|
|
54
54
|
p.value = d.map((s) => ({
|
|
55
55
|
day: s.dayOfWeekName,
|
|
56
56
|
hour: parseInt(s.hour, 10),
|
|
@@ -72,13 +72,13 @@ const le = { class: "w-full" }, ue = {
|
|
|
72
72
|
const w = {};
|
|
73
73
|
for (const s of d)
|
|
74
74
|
w[s.dayOfWeekName] = (w[s.dayOfWeekName] || 0) + (s.sessions || 0);
|
|
75
|
-
const
|
|
75
|
+
const W = Object.entries(w).sort((s, M) => M[1] - s[1])[0]?.[0] || "—";
|
|
76
76
|
T({
|
|
77
77
|
peakHour: S,
|
|
78
|
-
peakDay:
|
|
78
|
+
peakDay: W,
|
|
79
79
|
hourly: _,
|
|
80
80
|
heatmap: p.value,
|
|
81
|
-
suggestion: `Peak traffic hour is ${k(S)} with ${D.toLocaleString()} sessions. The busiest day is ${
|
|
81
|
+
suggestion: `Peak traffic hour is ${k(S)} with ${D.toLocaleString()} sessions. The busiest day is ${W}.`
|
|
82
82
|
});
|
|
83
83
|
} catch (u) {
|
|
84
84
|
m.value = u?.data?.statusMessage || u?.message || "Failed to load peak hours data", T(`Error loading peak hours data: ${m.value}`);
|
|
@@ -86,66 +86,66 @@ const le = { class: "w-full" }, ue = {
|
|
|
86
86
|
h.value = !1;
|
|
87
87
|
}
|
|
88
88
|
}
|
|
89
|
-
|
|
90
|
-
c.status === "completed" &&
|
|
89
|
+
ee(() => {
|
|
90
|
+
c.status === "completed" && J() || K();
|
|
91
91
|
});
|
|
92
92
|
function T(e) {
|
|
93
|
-
c.status !== "completed" &&
|
|
93
|
+
c.status !== "completed" && z("submit", e);
|
|
94
94
|
}
|
|
95
95
|
function k(e) {
|
|
96
96
|
return e === 0 ? "12 AM" : e < 12 ? `${e} AM` : e === 12 ? "12 PM" : `${e - 12} PM`;
|
|
97
97
|
}
|
|
98
|
-
const
|
|
98
|
+
const Q = (e) => e ? new Date(e).toLocaleString(void 0, { month: "short", day: "numeric", hour: "2-digit", minute: "2-digit" }) : "", X = g(() => Math.max(...b.value.map((e) => e.sessions), 1)), Y = g(() => {
|
|
99
99
|
const { startDate: e, endDate: t } = c.resolvedArgs || {};
|
|
100
100
|
if (!e && !t) return "Last 30 days";
|
|
101
101
|
const u = e || "30daysAgo", n = u.match(/^(\d+)daysAgo$/);
|
|
102
102
|
return n ? `Last ${n[1]} days` : `${u} → ${t || "today"}`;
|
|
103
|
-
}), C = g(() =>
|
|
103
|
+
}), C = g(() => U.filter((e) => p.value.some((t) => t.day === e)));
|
|
104
104
|
return (e, t) => {
|
|
105
|
-
const u =
|
|
106
|
-
return r(), l("div",
|
|
107
|
-
a(h) ? (r(), l("div",
|
|
108
|
-
$(a(
|
|
105
|
+
const u = te("NuxtLink");
|
|
106
|
+
return r(), l("div", ue, [
|
|
107
|
+
a(h) ? (r(), l("div", ie, [
|
|
108
|
+
$(a(ne), { class: "size-4 animate-spin text-muted-foreground" }),
|
|
109
109
|
t[0] || (t[0] = o("span", { class: "text-xs text-muted-foreground" }, "Loading peak hours data…", -1))
|
|
110
|
-
])) : a(m) ? (r(), l("div",
|
|
111
|
-
o("div",
|
|
112
|
-
o("div",
|
|
113
|
-
$(a(
|
|
110
|
+
])) : a(m) ? (r(), l("div", de, y(a(m)), 1)) : (r(), l("div", ce, [
|
|
111
|
+
o("div", pe, [
|
|
112
|
+
o("div", fe, [
|
|
113
|
+
$(a(re), { class: "size-3.5 text-primary" }),
|
|
114
114
|
t[1] || (t[1] = o("span", { class: "text-xs font-medium" }, "Peak Traffic Hours", -1))
|
|
115
115
|
]),
|
|
116
|
-
o("span",
|
|
116
|
+
o("span", me, y(a(Y)), 1)
|
|
117
117
|
]),
|
|
118
|
-
a(x) !== null ? (r(), l("div",
|
|
119
|
-
o("div",
|
|
120
|
-
o("span",
|
|
118
|
+
a(x) !== null ? (r(), l("div", xe, [
|
|
119
|
+
o("div", ge, [
|
|
120
|
+
o("span", ye, " 🔥 " + y(k(a(x))), 1),
|
|
121
121
|
t[2] || (t[2] = o("span", { class: "text-muted-foreground" }, "is the busiest hour", -1))
|
|
122
122
|
])
|
|
123
123
|
])) : L("", !0),
|
|
124
|
-
o("div",
|
|
125
|
-
o("div",
|
|
124
|
+
o("div", he, [
|
|
125
|
+
o("div", be, [
|
|
126
126
|
(r(!0), l(A, null, N(a(b), (n) => (r(), l("div", {
|
|
127
127
|
key: n.hour,
|
|
128
|
-
class:
|
|
129
|
-
style:
|
|
128
|
+
class: F(["flex-1 rounded-t transition-all hover:opacity-80 group relative", n.hour === a(x) ? "bg-blue-500" : "bg-blue-300/60 dark:bg-blue-700/60"]),
|
|
129
|
+
style: se({ height: `${Math.max(n.sessions / a(X) * 100, 2)}%` }),
|
|
130
130
|
title: `${k(n.hour)}: ${n.sessions.toLocaleString()} sessions`
|
|
131
|
-
}, null, 14,
|
|
131
|
+
}, null, 14, ve))), 128))
|
|
132
132
|
]),
|
|
133
|
-
t[3] || (t[3] =
|
|
133
|
+
t[3] || (t[3] = oe('<div class="flex mt-1 text-[8px] text-muted-foreground"><span class="flex-1 text-left">12AM</span><span class="flex-1 text-center">6AM</span><span class="flex-1 text-center">12PM</span><span class="flex-1 text-center">6PM</span><span class="flex-1 text-right">11PM</span></div>', 1))
|
|
134
134
|
]),
|
|
135
|
-
a(C).length > 0 ? (r(), l("div",
|
|
135
|
+
a(C).length > 0 ? (r(), l("div", ke, [
|
|
136
136
|
t[4] || (t[4] = o("p", { class: "text-[10px] text-muted-foreground mb-1.5 font-medium" }, "Weekly Heatmap", -1)),
|
|
137
|
-
o("div",
|
|
137
|
+
o("div", _e, [
|
|
138
138
|
(r(!0), l(A, null, N(a(C), (n) => (r(), l("div", {
|
|
139
139
|
key: n,
|
|
140
140
|
class: "flex items-center gap-1"
|
|
141
141
|
}, [
|
|
142
|
-
o("span",
|
|
143
|
-
o("div",
|
|
142
|
+
o("span", Se, y(H[n]), 1),
|
|
143
|
+
o("div", Me, [
|
|
144
144
|
(r(), l(A, null, N(24, (d) => o("div", {
|
|
145
145
|
key: d,
|
|
146
|
-
class:
|
|
146
|
+
class: F(["flex-1 h-2.5 rounded-[2px] transition-colors", G(a(p).find((i) => i.day === n && i.hour === d - 1)?.sessions || 0)]),
|
|
147
147
|
title: `${H[n]} ${k(d - 1)}: ${(a(p).find((i) => i.day === n && i.hour === d - 1)?.sessions || 0).toLocaleString()} sessions`
|
|
148
|
-
}, null, 10,
|
|
148
|
+
}, null, 10, $e)), 64))
|
|
149
149
|
])
|
|
150
150
|
]))), 128))
|
|
151
151
|
]),
|
|
@@ -155,19 +155,19 @@ const le = { class: "w-full" }, ue = {
|
|
|
155
155
|
o("span", { class: "flex-1 text-right" }, "11PM")
|
|
156
156
|
], -1))
|
|
157
157
|
])) : L("", !0),
|
|
158
|
-
o("div",
|
|
159
|
-
o("span",
|
|
158
|
+
o("div", Ae, [
|
|
159
|
+
o("span", De, [
|
|
160
160
|
a(v) ? (r(), l(A, { key: 0 }, [
|
|
161
|
-
|
|
161
|
+
I("fetched " + y(Q(a(v))), 1)
|
|
162
162
|
], 64)) : L("", !0)
|
|
163
163
|
]),
|
|
164
164
|
$(u, {
|
|
165
|
-
to: `/projects/${a(
|
|
165
|
+
to: `/projects/${a(B)}/modules/${P.instanceId}/audience`,
|
|
166
166
|
class: "inline-flex items-center gap-1.5 text-xs text-primary hover:underline"
|
|
167
167
|
}, {
|
|
168
|
-
default:
|
|
169
|
-
$(a(
|
|
170
|
-
t[6] || (t[6] =
|
|
168
|
+
default: ae(() => [
|
|
169
|
+
$(a(le), { class: "size-3" }),
|
|
170
|
+
t[6] || (t[6] = I(" View full report ", -1))
|
|
171
171
|
]),
|
|
172
172
|
_: 1
|
|
173
173
|
}, 8, ["to"])
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("vue"),v=require("lucide-vue-next"),z={class:"w-full"},I={key:0,class:"flex items-center gap-2 py-3"},q={key:1,class:"text-xs text-destructive py-2"},R={key:2,class:"rounded-xl border bg-background overflow-hidden"},U={class:"px-3 py-2 border-b bg-muted/40 flex items-center justify-between"},G={class:"flex items-center gap-2"},J={class:"text-[10px] text-muted-foreground"},K={key:0,class:"px-3 pt-3 pb-1"},Q={class:"flex items-center gap-2 text-xs"},X={class:"inline-flex items-center gap-1 px-2 py-0.5 rounded-full bg-blue-500/10 text-blue-600 dark:text-blue-400 font-medium"},Y={class:"px-3 py-3"},Z={class:"flex items-end gap-[2px] h-16"},ee=["title"],te={key:1,class:"px-3 pb-3"},se={class:"space-y-[2px]"},oe={class:"text-[8px] text-muted-foreground w-6 shrink-0 text-right"},ne={class:"flex gap-[2px] flex-1"},re=["title"],ae={class:"px-3 py-2 border-t bg-muted/20 flex items-center justify-between"},le={class:"text-[10px] text-muted-foreground"},ue=e.defineComponent({__name:"PeakHoursCard",props:{toolName:{},instanceId:{},instanceName:{},moduleType:{},resolvedArgs:{},status:{}},emits:["submit"],setup(N,{emit:B}){const{$useRoute:M,$useModuleApi:$}=useNuxtApp(),u=N,D=B,A=M(),L=e.computed(()=>A.params.slug),w=$(u.instanceId),m=e.ref(!0),c=e.ref(null),f=e.ref([]),i=e.ref(null),p=e.ref(null),P=["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],E={Sunday:"Sun",Monday:"Mon",Tuesday:"Tue",Wednesday:"Wed",Thursday:"Thu",Friday:"Fri",Saturday:"Sat"},d=e.ref([]),T=e.computed(()=>Math.max(...d.value.map(t=>t.sessions),1));function C(t){const s=t/T.value;return s===0?"bg-muted/40":s<.2?"bg-blue-100 dark:bg-blue-950":s<.4?"bg-blue-200 dark:bg-blue-900":s<.6?"bg-blue-300 dark:bg-blue-700":s<.8?"bg-blue-400 dark:bg-blue-600":"bg-blue-500 dark:bg-blue-500"}function H(){const t=u.resolvedArgs?._cachedData;return t?(f.value=t.hourly||[],i.value=t.peakHour??null,d.value=t.heatmap||[],p.value=u.resolvedArgs._fetchedAt||null,m.value=!1,!0):!1}async function F(){const{startDate:t,endDate:s}=u.resolvedArgs||{};m.value=!0,c.value=null;try{const r=new URLSearchParams;t&&r.set("startDate",t),s&&r.set("endDate",s);const l=(await w.get(`/audience/hours?${r.toString()}`)).rows||[];d.value=l.map(o=>({day:o.dayOfWeekName,hour:parseInt(o.hour,10),sessions:o.sessions||0}));const a={};for(const o of l){const k=parseInt(o.hour,10);a[k]=(a[k]||0)+(o.sessions||0)}const g=[];for(let o=0;o<24;o++)g.push({hour:o,sessions:a[o]||0});f.value=g;let y=0,h=0;for(const o of g)o.sessions>h&&(y=o.hour,h=o.sessions);i.value=y,p.value=new Date().toISOString();const b={};for(const o of l)b[o.dayOfWeekName]=(b[o.dayOfWeekName]||0)+(o.sessions||0);const S=Object.entries(b).sort((o,k)=>k[1]-o[1])[0]?.[0]||"—";_({peakHour:y,peakDay:S,hourly:g,heatmap:d.value,suggestion:`Peak traffic hour is ${x(y)} with ${h.toLocaleString()} sessions. The busiest day is ${S}.`})}catch(r){c.value=r?.data?.statusMessage||r?.message||"Failed to load peak hours data",_(`Error loading peak hours data: ${c.value}`)}finally{m.value=!1}}e.onMounted(()=>{u.status==="completed"&&H()||F()});function _(t){u.status!=="completed"&&D("submit",t)}function x(t){return t===0?"12 AM":t<12?`${t} AM`:t===12?"12 PM":`${t-12} PM`}const O=t=>t?new Date(t).toLocaleString(void 0,{month:"short",day:"numeric",hour:"2-digit",minute:"2-digit"}):"",W=e.computed(()=>Math.max(...f.value.map(t=>t.sessions),1)),j=e.computed(()=>{const{startDate:t,endDate:s}=u.resolvedArgs||{};if(!t&&!s)return"Last 30 days";const r=t||"30daysAgo",n=r.match(/^(\d+)daysAgo$/);return n?`Last ${n[1]} days`:`${r} → ${s||"today"}`}),V=e.computed(()=>P.filter(t=>d.value.some(s=>s.day===t)));return(t,s)=>{const r=e.resolveComponent("NuxtLink");return e.openBlock(),e.createElementBlock("div",z,[e.unref(m)?(e.openBlock(),e.createElementBlock("div",I,[e.createVNode(e.unref(v.Loader2),{class:"size-4 animate-spin text-muted-foreground"}),s[0]||(s[0]=e.createElementVNode("span",{class:"text-xs text-muted-foreground"},"Loading peak hours data…",-1))])):e.unref(c)?(e.openBlock(),e.createElementBlock("div",q,e.toDisplayString(e.unref(c)),1)):(e.openBlock(),e.createElementBlock("div",R,[e.createElementVNode("div",U,[e.createElementVNode("div",G,[e.createVNode(e.unref(v.Clock),{class:"size-3.5 text-primary"}),s[1]||(s[1]=e.createElementVNode("span",{class:"text-xs font-medium"},"Peak Traffic Hours",-1))]),e.createElementVNode("span",J,e.toDisplayString(e.unref(j)),1)]),e.unref(i)!==null?(e.openBlock(),e.createElementBlock("div",K,[e.createElementVNode("div",Q,[e.createElementVNode("span",X," 🔥 "+e.toDisplayString(x(e.unref(i))),1),s[2]||(s[2]=e.createElementVNode("span",{class:"text-muted-foreground"},"is the busiest hour",-1))])])):e.createCommentVNode("",!0),e.createElementVNode("div",Y,[e.createElementVNode("div",Z,[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(e.unref(f),n=>(e.openBlock(),e.createElementBlock("div",{key:n.hour,class:e.normalizeClass(["flex-1 rounded-t transition-all hover:opacity-80 group relative",n.hour===e.unref(i)?"bg-blue-500":"bg-blue-300/60 dark:bg-blue-700/60"]),style:e.normalizeStyle({height:`${Math.max(n.sessions/e.unref(W)*100,2)}%`}),title:`${x(n.hour)}: ${n.sessions.toLocaleString()} sessions`},null,14,ee))),128))]),s[3]||(s[3]=e.createStaticVNode('<div class="flex mt-1 text-[8px] text-muted-foreground"><span class="flex-1 text-left">12AM</span><span class="flex-1 text-center">6AM</span><span class="flex-1 text-center">12PM</span><span class="flex-1 text-center">6PM</span><span class="flex-1 text-right">11PM</span></div>',1))]),e.unref(V).length>0?(e.openBlock(),e.createElementBlock("div",te,[s[4]||(s[4]=e.createElementVNode("p",{class:"text-[10px] text-muted-foreground mb-1.5 font-medium"},"Weekly Heatmap",-1)),e.createElementVNode("div",se,[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(e.unref(V),n=>(e.openBlock(),e.createElementBlock("div",{key:n,class:"flex items-center gap-1"},[e.createElementVNode("span",oe,e.toDisplayString(E[n]),1),e.createElementVNode("div",ne,[(e.openBlock(),e.createElementBlock(e.Fragment,null,e.renderList(24,l=>e.createElementVNode("div",{key:l,class:e.normalizeClass(["flex-1 h-2.5 rounded-[2px] transition-colors",C(e.unref(d).find(a=>a.day===n&&a.hour===l-1)?.sessions||0)]),title:`${E[n]} ${x(l-1)}: ${(e.unref(d).find(a=>a.day===n&&a.hour===l-1)?.sessions||0).toLocaleString()} sessions`},null,10,re)),64))])]))),128))]),s[5]||(s[5]=e.createElementVNode("div",{class:"flex mt-1 ml-7 text-[8px] text-muted-foreground"},[e.createElementVNode("span",{class:"flex-1 text-left"},"12AM"),e.createElementVNode("span",{class:"flex-1 text-center"},"12PM"),e.createElementVNode("span",{class:"flex-1 text-right"},"11PM")],-1))])):e.createCommentVNode("",!0),e.createElementVNode("div",ae,[e.createElementVNode("span",le,[e.unref(p)?(e.openBlock(),e.createElementBlock(e.Fragment,{key:0},[e.createTextVNode("fetched "+e.toDisplayString(O(e.unref(p))),1)],64)):e.createCommentVNode("",!0)]),e.createVNode(r,{to:`/projects/${e.unref(L)}/modules/${N.instanceId}/audience`,class:"inline-flex items-center gap-1.5 text-xs text-primary hover:underline"},{default:e.withCtx(()=>[e.createVNode(e.unref(v.ExternalLink),{class:"size-3"}),s[6]||(s[6]=e.createTextVNode(" View full report ",-1))]),_:1},8,["to"])])]))])}}});exports.default=ue;
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import { defineComponent as z, computed as i, ref as m, onMounted as E, resolveComponent as L, openBlock as a, createElementBlock as n, unref as t, createVNode as p, createElementVNode as r, toDisplayString as c, createBlock as M, normalizeClass as V, createCommentVNode as g, withCtx as j, createTextVNode as A } from "vue";
|
|
2
|
+
import { Loader2 as P, Package as S, ExternalLink as B } from "lucide-vue-next";
|
|
3
|
+
const D = { class: "w-full" }, F = {
|
|
4
|
+
key: 0,
|
|
5
|
+
class: "flex items-center gap-2 py-3"
|
|
6
|
+
}, R = {
|
|
7
|
+
key: 1,
|
|
8
|
+
class: "text-xs text-destructive py-2"
|
|
9
|
+
}, T = {
|
|
10
|
+
key: 2,
|
|
11
|
+
class: "rounded-xl border bg-background p-3 space-y-3"
|
|
12
|
+
}, U = { class: "flex items-start gap-3" }, q = { class: "shrink-0 size-16 rounded-lg bg-muted overflow-hidden flex items-center justify-center" }, G = ["src", "alt"], H = { class: "flex-1 min-w-0" }, J = { class: "text-sm font-semibold truncate" }, K = { class: "text-lg font-bold mt-0.5" }, O = { class: "flex items-center gap-2 mt-1" }, Q = { class: "text-xs text-muted-foreground" }, W = {
|
|
13
|
+
key: 0,
|
|
14
|
+
class: "text-xs text-muted-foreground line-clamp-2"
|
|
15
|
+
}, Z = /* @__PURE__ */ z({
|
|
16
|
+
__name: "ProductDetailsCard",
|
|
17
|
+
props: {
|
|
18
|
+
toolName: {},
|
|
19
|
+
instanceId: {},
|
|
20
|
+
instanceName: {},
|
|
21
|
+
moduleType: {},
|
|
22
|
+
resolvedArgs: {},
|
|
23
|
+
status: {}
|
|
24
|
+
},
|
|
25
|
+
emits: ["submit"],
|
|
26
|
+
setup(f, { emit: v }) {
|
|
27
|
+
const { $useRoute: _, $useModuleApi: y } = useNuxtApp(), u = f, b = v, k = _(), h = i(() => k.params.slug), N = y(u.instanceId), d = m(!0), o = m(null), e = m(null);
|
|
28
|
+
async function w() {
|
|
29
|
+
const l = u.resolvedArgs?.productId;
|
|
30
|
+
if (!l) {
|
|
31
|
+
o.value = "No product ID provided", d.value = !1;
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
d.value = !0, o.value = null;
|
|
35
|
+
try {
|
|
36
|
+
const s = await N.get(`/products/${l}`);
|
|
37
|
+
e.value = s, x({
|
|
38
|
+
productId: e.value.id,
|
|
39
|
+
title: e.value.title,
|
|
40
|
+
price: e.value.price,
|
|
41
|
+
currency: e.value.currency,
|
|
42
|
+
stock: e.value.stock,
|
|
43
|
+
status: e.value.status,
|
|
44
|
+
available: e.value.available
|
|
45
|
+
});
|
|
46
|
+
} catch (s) {
|
|
47
|
+
o.value = s?.data?.statusMessage || s?.message || "Failed to load product", x(`Error fetching product: ${o.value}`);
|
|
48
|
+
} finally {
|
|
49
|
+
d.value = !1;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
E(() => {
|
|
53
|
+
w();
|
|
54
|
+
});
|
|
55
|
+
function x(l) {
|
|
56
|
+
u.status !== "completed" && b("submit", l);
|
|
57
|
+
}
|
|
58
|
+
const I = i(() => e.value ? new Intl.NumberFormat(void 0, {
|
|
59
|
+
style: "currency",
|
|
60
|
+
currency: e.value.currency || "EUR"
|
|
61
|
+
}).format(e.value.price) : ""), C = i(() => {
|
|
62
|
+
switch (e.value?.status) {
|
|
63
|
+
case "published":
|
|
64
|
+
return "text-emerald-600 dark:text-emerald-400 bg-emerald-50 dark:bg-emerald-900/20";
|
|
65
|
+
case "draft":
|
|
66
|
+
return "text-amber-600 dark:text-amber-400 bg-amber-50 dark:bg-amber-900/20";
|
|
67
|
+
case "archived":
|
|
68
|
+
return "text-gray-600 dark:text-gray-400 bg-gray-100 dark:bg-gray-800";
|
|
69
|
+
default:
|
|
70
|
+
return "text-muted-foreground bg-muted";
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
return (l, s) => {
|
|
74
|
+
const $ = L("NuxtLink");
|
|
75
|
+
return a(), n("div", D, [
|
|
76
|
+
t(d) ? (a(), n("div", F, [
|
|
77
|
+
p(t(P), { class: "size-4 animate-spin text-muted-foreground" }),
|
|
78
|
+
s[0] || (s[0] = r("span", { class: "text-xs text-muted-foreground" }, "Loading product…", -1))
|
|
79
|
+
])) : t(o) ? (a(), n("div", R, c(t(o)), 1)) : t(e) ? (a(), n("div", T, [
|
|
80
|
+
r("div", U, [
|
|
81
|
+
r("div", q, [
|
|
82
|
+
t(e).featuredMedia ? (a(), n("img", {
|
|
83
|
+
key: 0,
|
|
84
|
+
src: t(e).featuredMedia,
|
|
85
|
+
alt: t(e).title,
|
|
86
|
+
class: "size-full object-cover"
|
|
87
|
+
}, null, 8, G)) : (a(), M(t(S), {
|
|
88
|
+
key: 1,
|
|
89
|
+
class: "size-6 text-muted-foreground"
|
|
90
|
+
}))
|
|
91
|
+
]),
|
|
92
|
+
r("div", H, [
|
|
93
|
+
r("p", J, c(t(e).title), 1),
|
|
94
|
+
r("p", K, c(t(I)), 1),
|
|
95
|
+
r("div", O, [
|
|
96
|
+
r("span", {
|
|
97
|
+
class: V(["text-[10px] font-medium px-1.5 py-0.5 rounded-full uppercase", t(C)])
|
|
98
|
+
}, c(t(e).status), 3),
|
|
99
|
+
r("span", Q, " Stock: " + c(t(e).stock ?? "—"), 1)
|
|
100
|
+
])
|
|
101
|
+
])
|
|
102
|
+
]),
|
|
103
|
+
t(e).description ? (a(), n("p", W, c(t(e).description), 1)) : g("", !0),
|
|
104
|
+
p($, {
|
|
105
|
+
to: `/projects/${t(h)}/modules/${f.instanceId}/${t(e).id}`,
|
|
106
|
+
class: "inline-flex items-center gap-1.5 text-xs text-primary hover:underline"
|
|
107
|
+
}, {
|
|
108
|
+
default: j(() => [
|
|
109
|
+
p(t(B), { class: "size-3" }),
|
|
110
|
+
s[1] || (s[1] = A(" View full details ", -1))
|
|
111
|
+
]),
|
|
112
|
+
_: 1
|
|
113
|
+
}, 8, ["to"])
|
|
114
|
+
])) : g("", !0)
|
|
115
|
+
]);
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
});
|
|
119
|
+
export {
|
|
120
|
+
Z as default
|
|
121
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("vue"),c=require("lucide-vue-next"),b={class:"w-full"},N={key:0,class:"flex items-center gap-2 py-3"},h={key:1,class:"text-xs text-destructive py-2"},E={key:2,class:"rounded-xl border bg-background p-3 space-y-3"},V={class:"flex items-start gap-3"},B={class:"shrink-0 size-16 rounded-lg bg-muted overflow-hidden flex items-center justify-center"},S=["src","alt"],w={class:"flex-1 min-w-0"},C={class:"text-sm font-semibold truncate"},D={class:"text-lg font-bold mt-0.5"},I={class:"flex items-center gap-2 mt-1"},$={class:"text-xs text-muted-foreground"},z={key:0,class:"text-xs text-muted-foreground line-clamp-2"},M=e.defineComponent({__name:"ProductDetailsCard",props:{toolName:{},instanceId:{},instanceName:{},moduleType:{},resolvedArgs:{},status:{}},emits:["submit"],setup(l,{emit:d}){const{$useRoute:i,$useModuleApi:m}=useNuxtApp(),n=l,p=d,f=i(),g=e.computed(()=>f.params.slug),x=m(n.instanceId),a=e.ref(!0),o=e.ref(null),t=e.ref(null);async function v(){const s=n.resolvedArgs?.productId;if(!s){o.value="No product ID provided",a.value=!1;return}a.value=!0,o.value=null;try{const r=await x.get(`/products/${s}`);t.value=r,u({productId:t.value.id,title:t.value.title,price:t.value.price,currency:t.value.currency,stock:t.value.stock,status:t.value.status,available:t.value.available})}catch(r){o.value=r?.data?.statusMessage||r?.message||"Failed to load product",u(`Error fetching product: ${o.value}`)}finally{a.value=!1}}e.onMounted(()=>{v()});function u(s){n.status!=="completed"&&p("submit",s)}const k=e.computed(()=>t.value?new Intl.NumberFormat(void 0,{style:"currency",currency:t.value.currency||"EUR"}).format(t.value.price):""),y=e.computed(()=>{switch(t.value?.status){case"published":return"text-emerald-600 dark:text-emerald-400 bg-emerald-50 dark:bg-emerald-900/20";case"draft":return"text-amber-600 dark:text-amber-400 bg-amber-50 dark:bg-amber-900/20";case"archived":return"text-gray-600 dark:text-gray-400 bg-gray-100 dark:bg-gray-800";default:return"text-muted-foreground bg-muted"}});return(s,r)=>{const _=e.resolveComponent("NuxtLink");return e.openBlock(),e.createElementBlock("div",b,[e.unref(a)?(e.openBlock(),e.createElementBlock("div",N,[e.createVNode(e.unref(c.Loader2),{class:"size-4 animate-spin text-muted-foreground"}),r[0]||(r[0]=e.createElementVNode("span",{class:"text-xs text-muted-foreground"},"Loading product…",-1))])):e.unref(o)?(e.openBlock(),e.createElementBlock("div",h,e.toDisplayString(e.unref(o)),1)):e.unref(t)?(e.openBlock(),e.createElementBlock("div",E,[e.createElementVNode("div",V,[e.createElementVNode("div",B,[e.unref(t).featuredMedia?(e.openBlock(),e.createElementBlock("img",{key:0,src:e.unref(t).featuredMedia,alt:e.unref(t).title,class:"size-full object-cover"},null,8,S)):(e.openBlock(),e.createBlock(e.unref(c.Package),{key:1,class:"size-6 text-muted-foreground"}))]),e.createElementVNode("div",w,[e.createElementVNode("p",C,e.toDisplayString(e.unref(t).title),1),e.createElementVNode("p",D,e.toDisplayString(e.unref(k)),1),e.createElementVNode("div",I,[e.createElementVNode("span",{class:e.normalizeClass(["text-[10px] font-medium px-1.5 py-0.5 rounded-full uppercase",e.unref(y)])},e.toDisplayString(e.unref(t).status),3),e.createElementVNode("span",$," Stock: "+e.toDisplayString(e.unref(t).stock??"—"),1)])])]),e.unref(t).description?(e.openBlock(),e.createElementBlock("p",z,e.toDisplayString(e.unref(t).description),1)):e.createCommentVNode("",!0),e.createVNode(_,{to:`/projects/${e.unref(g)}/modules/${l.instanceId}/${e.unref(t).id}`,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"}),r[1]||(r[1]=e.createTextVNode(" View full details ",-1))]),_:1},8,["to"])])):e.createCommentVNode("",!0)])}}});exports.default=M;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("vue"),l=require("lucide-vue-next"),E={class:"w-full"},b={key:0,class:"flex items-center gap-2 py-3"},B={key:1,class:"text-xs text-destructive py-2"},w={key:2,class:"rounded-xl border bg-background overflow-hidden"},S={class:"px-3 py-2 border-b bg-muted/40 flex items-center justify-between"},U={class:"flex items-center gap-2"},A={class:"px-3 py-4 text-center"},D={class:"flex items-center justify-center gap-2 mb-1"},j={class:"text-3xl font-bold"},z={class:"text-xs text-muted-foreground"},C={key:0,class:"border-t"},L={class:"divide-y"},R=["title"],P={class:"flex items-center gap-1 text-[10px] text-muted-foreground shrink-0 ml-2"},$={class:"font-medium"},F={class:"px-3 py-2 border-t bg-muted/20 flex items-center justify-between"},I={key:0,class:"text-[10px] text-muted-foreground"},M=e.defineComponent({__name:"RealtimeCard",props:{toolName:{},instanceId:{},instanceName:{},moduleType:{},resolvedArgs:{},status:{}},emits:["submit"],setup(u,{emit:p}){const{$useRoute:f,$useModuleApi:g}=useNuxtApp(),n=u,v=p,x=f(),y=e.computed(()=>x.params.slug),N=g(n.instanceId),i=e.ref(!0),o=e.ref(null),a=e.ref(0),r=e.ref([]),c=e.ref(null);function _(){const s=n.resolvedArgs?._cachedData;return s?(a.value=s.activeUsersRightNow||0,r.value=(s.topActivePages||[]).map(t=>({page:t.page,activeUsers:t.activeUsers})),c.value=n.resolvedArgs._fetchedAt||null,i.value=!1,!0):!1}async function h(){i.value=!0,o.value=null;try{const s=await N.get("/realtime");a.value=s.activeUsers||0,r.value=s.activePages||[],c.value=new Date().toISOString(),m({activeUsersRightNow:a.value,topActivePages:r.value.map(t=>({page:t.page,activeUsers:t.activeUsers}))})}catch(s){o.value=s?.data?.statusMessage||s?.message||"Failed to load realtime data",m(`Error loading realtime data: ${o.value}`)}finally{i.value=!1}}e.onMounted(()=>{n.status==="completed"&&_()||h()});function m(s){n.status!=="completed"&&v("submit",s)}const V=s=>s?new Date(s).toLocaleString(void 0,{month:"short",day:"numeric",hour:"2-digit",minute:"2-digit"}):"";return(s,t)=>{const k=e.resolveComponent("NuxtLink");return e.openBlock(),e.createElementBlock("div",E,[e.unref(i)?(e.openBlock(),e.createElementBlock("div",b,[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 realtime data…",-1))])):e.unref(o)?(e.openBlock(),e.createElementBlock("div",B,e.toDisplayString(e.unref(o)),1)):(e.openBlock(),e.createElementBlock("div",w,[e.createElementVNode("div",S,[e.createElementVNode("div",U,[e.createVNode(e.unref(l.Radio),{class:"size-3.5 text-emerald-500"}),t[1]||(t[1]=e.createElementVNode("span",{class:"text-xs font-medium"},"Realtime",-1))]),t[2]||(t[2]=e.createElementVNode("span",{class:"relative flex size-2"},[e.createElementVNode("span",{class:"animate-ping absolute inline-flex h-full w-full rounded-full bg-emerald-400 opacity-75"}),e.createElementVNode("span",{class:"relative inline-flex rounded-full size-2 bg-emerald-500"})],-1))]),e.createElementVNode("div",A,[e.createElementVNode("div",D,[e.createVNode(e.unref(l.Users),{class:"size-5 text-primary"}),e.createElementVNode("span",j,e.toDisplayString(e.unref(a)),1)]),e.createElementVNode("p",z,"active "+e.toDisplayString(e.unref(a)===1?"user":"users")+" right now",1)]),e.unref(r).length>0?(e.openBlock(),e.createElementBlock("div",C,[t[3]||(t[3]=e.createElementVNode("div",{class:"px-3 py-1.5 bg-muted/20"},[e.createElementVNode("span",{class:"text-[10px] font-medium text-muted-foreground uppercase tracking-wide"},"Active Pages")],-1)),e.createElementVNode("div",L,[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(e.unref(r),d=>(e.openBlock(),e.createElementBlock("div",{key:d.page,class:"px-3 py-2 flex items-center justify-between hover:bg-muted/30 transition-colors"},[e.createElementVNode("span",{class:"text-xs truncate flex-1",title:d.page},e.toDisplayString(d.page),9,R),e.createElementVNode("div",P,[e.createVNode(e.unref(l.Users),{class:"size-2.5"}),e.createElementVNode("span",$,e.toDisplayString(d.activeUsers),1)])]))),128))])])):e.createCommentVNode("",!0),e.createElementVNode("div",F,[e.unref(c)?(e.openBlock(),e.createElementBlock("span",I," Fetched "+e.toDisplayString(V(e.unref(c))),1)):e.createCommentVNode("",!0),e.createVNode(k,{to:`/projects/${e.unref(y)}/modules/${u.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[4]||(t[4]=e.createTextVNode(" View full report ",-1))]),_:1},8,["to"])])]))])}}});exports.default=M;
|