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