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