@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
@@ -1,19 +1,18 @@
1
- import { defineComponent as U, computed as w, ref as f, onMounted as j, resolveComponent as F, openBlock as d, createElementBlock as c, unref as s, createVNode as u, createElementVNode as a, toDisplayString as i, Fragment as P, renderList as B, normalizeStyle as R, createTextVNode as g, createCommentVNode as O, withCtx as q } from "vue";
2
- import { Loader2 as G, FileText as S, Eye as H, Users as J, Clock as K, ExternalLink as Q } from "lucide-vue-next";
3
- import { useRoute as W, useModuleApi as X } from "@oneclick.dev/cms-kit";
4
- const Y = { class: "w-full" }, Z = {
1
+ import { defineComponent as j, computed as w, ref as f, onMounted as F, resolveComponent as B, openBlock as d, createElementBlock as u, unref as s, createVNode as c, createElementVNode as a, toDisplayString as i, Fragment as P, renderList as O, normalizeStyle as R, createTextVNode as g, createCommentVNode as q, withCtx as G } from "vue";
2
+ import { Loader2 as H, FileText as $, Eye as J, Users as K, Clock as Q, ExternalLink as W } from "lucide-vue-next";
3
+ const X = { class: "w-full" }, Y = {
5
4
  key: 0,
6
5
  class: "flex items-center gap-2 py-3"
7
- }, ee = {
6
+ }, Z = {
8
7
  key: 1,
9
8
  class: "text-xs text-destructive py-2"
10
- }, te = {
9
+ }, ee = {
11
10
  key: 2,
12
11
  class: "rounded-xl border bg-background p-4 text-center"
13
- }, se = {
12
+ }, te = {
14
13
  key: 3,
15
14
  class: "rounded-xl border bg-background overflow-hidden"
16
- }, ae = { class: "px-3 py-2 border-b bg-muted/40 flex items-center justify-between" }, oe = { class: "flex items-center gap-2" }, ne = { class: "text-[10px] text-muted-foreground" }, re = { class: "divide-y" }, ie = { class: "flex items-center gap-2 mb-1.5" }, le = { class: "text-[10px] font-medium text-muted-foreground w-5 text-right shrink-0" }, de = ["title"], ce = { class: "ml-7 space-y-1.5" }, ue = { class: "h-1.5 rounded-full bg-muted overflow-hidden" }, me = { class: "flex items-center gap-3 text-[10px] text-muted-foreground" }, ge = { class: "flex items-center gap-1" }, pe = { class: "flex items-center gap-1" }, fe = { class: "flex items-center gap-1" }, xe = { class: "px-3 py-2 border-t bg-muted/20 flex items-center justify-between" }, ve = { class: "text-[10px] text-muted-foreground" }, we = /* @__PURE__ */ U({
15
+ }, se = { class: "px-3 py-2 border-b bg-muted/40 flex items-center justify-between" }, ae = { class: "flex items-center gap-2" }, oe = { class: "text-[10px] text-muted-foreground" }, ne = { class: "divide-y" }, re = { class: "flex items-center gap-2 mb-1.5" }, ie = { class: "text-[10px] font-medium text-muted-foreground w-5 text-right shrink-0" }, le = ["title"], de = { class: "ml-7 space-y-1.5" }, ue = { class: "h-1.5 rounded-full bg-muted overflow-hidden" }, ce = { class: "flex items-center gap-3 text-[10px] text-muted-foreground" }, me = { class: "flex items-center gap-1" }, ge = { class: "flex items-center gap-1" }, pe = { class: "flex items-center gap-1" }, fe = { class: "px-3 py-2 border-t bg-muted/20 flex items-center justify-between" }, xe = { class: "text-[10px] text-muted-foreground" }, ye = /* @__PURE__ */ j({
17
16
  __name: "TopPagesCard",
18
17
  props: {
19
18
  toolName: {},
@@ -24,29 +23,29 @@ const Y = { class: "w-full" }, Z = {
24
23
  status: {}
25
24
  },
26
25
  emits: ["submit"],
27
- setup(b, { emit: L }) {
28
- const m = b, $ = L, V = W(), A = w(() => V.params.slug), N = X(m.instanceId), x = f(!0), p = f(null), r = f([]), v = f(0), h = f(null);
26
+ setup(b, { emit: S }) {
27
+ const { $useRoute: L, $useModuleOverlay: ve } = useNuxtApp(), m = b, A = S, N = L(), V = w(() => N.params.slug), M = $useModuleApi(m.instanceId), x = f(!0), p = f(null), r = f([]), v = f(0), h = f(null);
29
28
  function C() {
30
29
  const e = m.resolvedArgs?._cachedData;
31
30
  return e ? (r.value = e.pages?.map((t) => ({
32
31
  pagePath: t.page,
33
32
  screenPageViews: t.views,
34
33
  totalUsers: t.users,
35
- averageSessionDuration: M(t.avgDuration)
34
+ averageSessionDuration: T(t.avgDuration)
36
35
  })) || [], v.value = e.totalPagesTracked || r.value.length, h.value = m.resolvedArgs._fetchedAt || null, x.value = !1, !0) : !1;
37
36
  }
38
- function M(e) {
37
+ function T(e) {
39
38
  if (!e) return 0;
40
39
  const t = e.match(/(\d+)m/), n = e.match(/(\d+)s/);
41
40
  return (t ? parseInt(t[1]) * 60 : 0) + (n ? parseInt(n[1]) : 0);
42
41
  }
43
- async function T() {
42
+ async function z() {
44
43
  const { startDate: e, endDate: t, limit: n } = m.resolvedArgs || {};
45
44
  x.value = !0, p.value = null;
46
45
  try {
47
46
  const o = new URLSearchParams();
48
47
  e && o.set("startDate", e), t && o.set("endDate", t), n && o.set("limit", String(n));
49
- const l = await N.get(`/top-pages?${o.toString()}`);
48
+ const l = await M.get(`/top-pages?${o.toString()}`);
50
49
  r.value = l.rows || [], v.value = l.rowCount || r.value.length, h.value = (/* @__PURE__ */ new Date()).toISOString(), k({
51
50
  count: r.value.length,
52
51
  totalPagesTracked: v.value,
@@ -63,88 +62,88 @@ const Y = { class: "w-full" }, Z = {
63
62
  x.value = !1;
64
63
  }
65
64
  }
66
- j(() => {
67
- m.status === "completed" && C() || T();
65
+ F(() => {
66
+ m.status === "completed" && C() || z();
68
67
  });
69
68
  function k(e) {
70
- m.status !== "completed" && $("submit", e);
69
+ m.status !== "completed" && A("submit", e);
71
70
  }
72
71
  const D = (e) => {
73
72
  if (!e) return "0s";
74
73
  const t = Math.floor(e / 60), n = Math.round(e % 60);
75
74
  return t > 0 ? `${t}m ${n}s` : `${n}s`;
76
- }, y = (e) => e == null ? "0" : e.toLocaleString(), z = (e) => e ? new Date(e).toLocaleString(void 0, { month: "short", day: "numeric", hour: "2-digit", minute: "2-digit" }) : "", I = w(() => r.value.length === 0 ? 1 : Math.max(...r.value.map((e) => e.screenPageViews || 0))), E = w(() => {
75
+ }, y = (e) => e == null ? "0" : e.toLocaleString(), I = (e) => e ? new Date(e).toLocaleString(void 0, { month: "short", day: "numeric", hour: "2-digit", minute: "2-digit" }) : "", E = w(() => r.value.length === 0 ? 1 : Math.max(...r.value.map((e) => e.screenPageViews || 0))), U = w(() => {
77
76
  const { startDate: e, endDate: t } = m.resolvedArgs || {};
78
77
  if (!e && !t) return "Last 30 days";
79
78
  const n = e || "30daysAgo", o = t || "today", l = n.match(/^(\d+)daysAgo$/);
80
79
  return l ? `Last ${l[1]} days` : `${n} → ${o}`;
81
80
  });
82
81
  return (e, t) => {
83
- const n = F("NuxtLink");
84
- return d(), c("div", Y, [
85
- s(x) ? (d(), c("div", Z, [
86
- u(s(G), { class: "size-4 animate-spin text-muted-foreground" }),
82
+ const n = B("NuxtLink");
83
+ return d(), u("div", X, [
84
+ s(x) ? (d(), u("div", Y, [
85
+ c(s(H), { class: "size-4 animate-spin text-muted-foreground" }),
87
86
  t[0] || (t[0] = a("span", { class: "text-xs text-muted-foreground" }, "Loading top pages…", -1))
88
- ])) : s(p) ? (d(), c("div", ee, i(s(p)), 1)) : s(r).length === 0 ? (d(), c("div", te, [
89
- u(s(S), { class: "size-8 text-muted-foreground mx-auto mb-2" }),
87
+ ])) : s(p) ? (d(), u("div", Z, i(s(p)), 1)) : s(r).length === 0 ? (d(), u("div", ee, [
88
+ c(s($), { class: "size-8 text-muted-foreground mx-auto mb-2" }),
90
89
  t[1] || (t[1] = a("p", { class: "text-sm text-muted-foreground" }, "No page data found for this period.", -1))
91
- ])) : (d(), c("div", se, [
92
- a("div", ae, [
93
- a("div", oe, [
94
- u(s(S), { class: "size-3.5 text-primary" }),
90
+ ])) : (d(), u("div", te, [
91
+ a("div", se, [
92
+ a("div", ae, [
93
+ c(s($), { class: "size-3.5 text-primary" }),
95
94
  t[2] || (t[2] = a("span", { class: "text-xs font-medium" }, "Most Popular Pages", -1))
96
95
  ]),
97
- a("span", ne, i(s(E)), 1)
96
+ a("span", oe, i(s(U)), 1)
98
97
  ]),
99
- a("div", re, [
100
- (d(!0), c(P, null, B(s(r), (o, l) => (d(), c("div", {
98
+ a("div", ne, [
99
+ (d(!0), u(P, null, O(s(r), (o, l) => (d(), u("div", {
101
100
  key: l,
102
101
  class: "px-3 py-2.5 hover:bg-muted/30 transition-colors"
103
102
  }, [
104
- a("div", ie, [
105
- a("span", le, i(l + 1) + ".", 1),
103
+ a("div", re, [
104
+ a("span", ie, i(l + 1) + ".", 1),
106
105
  a("span", {
107
106
  class: "text-xs font-medium truncate flex-1",
108
107
  title: o.pagePath
109
- }, i(o.pagePath), 9, de)
108
+ }, i(o.pagePath), 9, le)
110
109
  ]),
111
- a("div", ce, [
110
+ a("div", de, [
112
111
  a("div", ue, [
113
112
  a("div", {
114
113
  class: "h-full rounded-full bg-primary/70 transition-all",
115
- style: R({ width: `${(o.screenPageViews || 0) / s(I) * 100}%` })
114
+ style: R({ width: `${(o.screenPageViews || 0) / s(E) * 100}%` })
116
115
  }, null, 4)
117
116
  ]),
118
- a("div", me, [
119
- a("span", ge, [
120
- u(s(H), { class: "size-2.5" }),
117
+ a("div", ce, [
118
+ a("span", me, [
119
+ c(s(J), { class: "size-2.5" }),
121
120
  g(" " + i(y(o.screenPageViews)) + " views ", 1)
122
121
  ]),
123
- a("span", pe, [
124
- u(s(J), { class: "size-2.5" }),
122
+ a("span", ge, [
123
+ c(s(K), { class: "size-2.5" }),
125
124
  g(" " + i(y(o.totalUsers)) + " users ", 1)
126
125
  ]),
127
- a("span", fe, [
128
- u(s(K), { class: "size-2.5" }),
126
+ a("span", pe, [
127
+ c(s(Q), { class: "size-2.5" }),
129
128
  g(" " + i(D(o.averageSessionDuration)), 1)
130
129
  ])
131
130
  ])
132
131
  ])
133
132
  ]))), 128))
134
133
  ]),
135
- a("div", xe, [
136
- a("span", ve, [
134
+ a("div", fe, [
135
+ a("span", xe, [
137
136
  g(" Top " + i(s(r).length) + " of " + i(y(s(v))) + " pages ", 1),
138
- s(h) ? (d(), c(P, { key: 0 }, [
139
- g(" · fetched " + i(z(s(h))), 1)
140
- ], 64)) : O("", !0)
137
+ s(h) ? (d(), u(P, { key: 0 }, [
138
+ g(" · fetched " + i(I(s(h))), 1)
139
+ ], 64)) : q("", !0)
141
140
  ]),
142
- u(n, {
143
- to: `/projects/${s(A)}/modules/${b.instanceId}`,
141
+ c(n, {
142
+ to: `/projects/${s(V)}/modules/${b.instanceId}`,
144
143
  class: "inline-flex items-center gap-1.5 text-xs text-primary hover:underline"
145
144
  }, {
146
- default: q(() => [
147
- u(s(Q), { class: "size-3" }),
145
+ default: G(() => [
146
+ c(s(W), { class: "size-3" }),
148
147
  t[3] || (t[3] = g(" View full report ", -1))
149
148
  ]),
150
149
  _: 1
@@ -156,5 +155,5 @@ const Y = { class: "w-full" }, Z = {
156
155
  }
157
156
  });
158
157
  export {
159
- we as default
158
+ ye as default
160
159
  };
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("vue"),c=require("lucide-vue-next"),B={class:"w-full"},T={key:0,class:"flex items-center gap-2 py-3"},$={key:1,class:"text-xs text-destructive py-2"},L={key:2,class:"rounded-xl border bg-background p-4 text-center"},A={key:3,class:"rounded-xl border bg-background overflow-hidden"},M={class:"px-3 py-2 border-b bg-muted/40 flex items-center justify-between"},C={class:"flex items-center gap-2"},z={class:"text-[10px] text-muted-foreground"},F={class:"divide-y"},I={class:"flex items-center gap-2 mb-1.5"},j={class:"text-[10px] font-medium text-muted-foreground w-5 text-right shrink-0"},U=["title"],O={class:"ml-7 space-y-1.5"},q={class:"h-1.5 rounded-full bg-muted overflow-hidden"},R={class:"flex items-center gap-3 text-[10px] text-muted-foreground"},G={class:"flex items-center gap-1"},H={class:"flex items-center gap-1"},J={class:"flex items-center gap-1"},K={class:"px-3 py-2 border-t bg-muted/20 flex items-center justify-between"},Q={class:"text-[10px] text-muted-foreground"},W=e.defineComponent({__name:"TopPagesCard",props:{toolName:{},instanceId:{},instanceName:{},moduleType:{},resolvedArgs:{},status:{}},emits:["submit"],setup(f,{emit:h}){const{$useRoute:y,$useModuleOverlay:X}=useNuxtApp(),l=f,N=h,V=y(),_=e.computed(()=>V.params.slug),k=$useModuleApi(l.instanceId),d=e.ref(!0),i=e.ref(null),a=e.ref([]),u=e.ref(0),m=e.ref(null);function E(){const t=l.resolvedArgs?._cachedData;return t?(a.value=t.pages?.map(s=>({pagePath:s.page,screenPageViews:s.views,totalUsers:s.users,averageSessionDuration:b(s.avgDuration)}))||[],u.value=t.totalPagesTracked||a.value.length,m.value=l.resolvedArgs._fetchedAt||null,d.value=!1,!0):!1}function b(t){if(!t)return 0;const s=t.match(/(\d+)m/),n=t.match(/(\d+)s/);return(s?parseInt(s[1])*60:0)+(n?parseInt(n[1]):0)}async function D(){const{startDate:t,endDate:s,limit:n}=l.resolvedArgs||{};d.value=!0,i.value=null;try{const o=new URLSearchParams;t&&o.set("startDate",t),s&&o.set("endDate",s),n&&o.set("limit",String(n));const r=await k.get(`/top-pages?${o.toString()}`);a.value=r.rows||[],u.value=r.rowCount||a.value.length,m.value=new Date().toISOString(),x({count:a.value.length,totalPagesTracked:u.value,pages:a.value.map(p=>({page:p.pagePath,views:p.screenPageViews,users:p.totalUsers,avgDuration:v(p.averageSessionDuration)}))})}catch(o){i.value=o?.data?.statusMessage||o?.message||"Failed to load top pages",x(`Error loading top pages: ${i.value}`)}finally{d.value=!1}}e.onMounted(()=>{l.status==="completed"&&E()||D()});function x(t){l.status!=="completed"&&N("submit",t)}const v=t=>{if(!t)return"0s";const s=Math.floor(t/60),n=Math.round(t%60);return s>0?`${s}m ${n}s`:`${n}s`},g=t=>t==null?"0":t.toLocaleString(),w=t=>t?new Date(t).toLocaleString(void 0,{month:"short",day:"numeric",hour:"2-digit",minute:"2-digit"}):"",S=e.computed(()=>a.value.length===0?1:Math.max(...a.value.map(t=>t.screenPageViews||0))),P=e.computed(()=>{const{startDate:t,endDate:s}=l.resolvedArgs||{};if(!t&&!s)return"Last 30 days";const n=t||"30daysAgo",o=s||"today",r=n.match(/^(\d+)daysAgo$/);return r?`Last ${r[1]} days`:`${n} → ${o}`});return(t,s)=>{const n=e.resolveComponent("NuxtLink");return e.openBlock(),e.createElementBlock("div",B,[e.unref(d)?(e.openBlock(),e.createElementBlock("div",T,[e.createVNode(e.unref(c.Loader2),{class:"size-4 animate-spin text-muted-foreground"}),s[0]||(s[0]=e.createElementVNode("span",{class:"text-xs text-muted-foreground"},"Loading top pages…",-1))])):e.unref(i)?(e.openBlock(),e.createElementBlock("div",$,e.toDisplayString(e.unref(i)),1)):e.unref(a).length===0?(e.openBlock(),e.createElementBlock("div",L,[e.createVNode(e.unref(c.FileText),{class:"size-8 text-muted-foreground mx-auto mb-2"}),s[1]||(s[1]=e.createElementVNode("p",{class:"text-sm text-muted-foreground"},"No page data found for this period.",-1))])):(e.openBlock(),e.createElementBlock("div",A,[e.createElementVNode("div",M,[e.createElementVNode("div",C,[e.createVNode(e.unref(c.FileText),{class:"size-3.5 text-primary"}),s[2]||(s[2]=e.createElementVNode("span",{class:"text-xs font-medium"},"Most Popular Pages",-1))]),e.createElementVNode("span",z,e.toDisplayString(e.unref(P)),1)]),e.createElementVNode("div",F,[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(e.unref(a),(o,r)=>(e.openBlock(),e.createElementBlock("div",{key:r,class:"px-3 py-2.5 hover:bg-muted/30 transition-colors"},[e.createElementVNode("div",I,[e.createElementVNode("span",j,e.toDisplayString(r+1)+".",1),e.createElementVNode("span",{class:"text-xs font-medium truncate flex-1",title:o.pagePath},e.toDisplayString(o.pagePath),9,U)]),e.createElementVNode("div",O,[e.createElementVNode("div",q,[e.createElementVNode("div",{class:"h-full rounded-full bg-primary/70 transition-all",style:e.normalizeStyle({width:`${(o.screenPageViews||0)/e.unref(S)*100}%`})},null,4)]),e.createElementVNode("div",R,[e.createElementVNode("span",G,[e.createVNode(e.unref(c.Eye),{class:"size-2.5"}),e.createTextVNode(" "+e.toDisplayString(g(o.screenPageViews))+" views ",1)]),e.createElementVNode("span",H,[e.createVNode(e.unref(c.Users),{class:"size-2.5"}),e.createTextVNode(" "+e.toDisplayString(g(o.totalUsers))+" users ",1)]),e.createElementVNode("span",J,[e.createVNode(e.unref(c.Clock),{class:"size-2.5"}),e.createTextVNode(" "+e.toDisplayString(v(o.averageSessionDuration)),1)])])])]))),128))]),e.createElementVNode("div",K,[e.createElementVNode("span",Q,[e.createTextVNode(" Top "+e.toDisplayString(e.unref(a).length)+" of "+e.toDisplayString(g(e.unref(u)))+" pages ",1),e.unref(m)?(e.openBlock(),e.createElementBlock(e.Fragment,{key:0},[e.createTextVNode(" · fetched "+e.toDisplayString(w(e.unref(m))),1)],64)):e.createCommentVNode("",!0)]),e.createVNode(n,{to:`/projects/${e.unref(_)}/modules/${f.instanceId}`,class:"inline-flex items-center gap-1.5 text-xs text-primary hover:underline"},{default:e.withCtx(()=>[e.createVNode(e.unref(c.ExternalLink),{class:"size-3"}),s[3]||(s[3]=e.createTextVNode(" View full report ",-1))]),_:1},8,["to"])])]))])}}});exports.default=W;
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("vue"),i=require("lucide-vue-next"),C={class:"w-full"},$={key:0,class:"flex items-center gap-2 py-3"},L={key:1,class:"text-xs text-destructive py-2"},A={key:2,class:"rounded-xl border bg-background p-4 text-center"},U={key:3,class:"rounded-xl border bg-background overflow-hidden"},z={class:"px-3 py-2 border-b bg-muted/40 flex items-center justify-between"},T={class:"flex items-center gap-2"},F={class:"text-[10px] text-muted-foreground"},G={key:0,class:"px-3 pt-3 pb-2"},M={class:"h-3 rounded-full bg-muted overflow-hidden flex"},j=["title"],R={class:"flex flex-wrap gap-x-3 gap-y-1 mt-2"},I={class:"text-[10px] text-muted-foreground"},P={class:"text-[10px] font-medium"},q={key:1,class:"border-t"},O={class:"divide-y"},H={class:"text-xs font-medium truncate flex-1"},J={class:"flex items-center gap-3 text-[10px] text-muted-foreground shrink-0"},K={class:"flex items-center gap-1"},Q={class:"flex items-center gap-1"},W={class:"px-3 py-2 border-t bg-muted/20 flex items-center justify-between"},X={key:0,class:"text-[10px] text-muted-foreground"},Y=e.defineComponent({__name:"TrafficSourcesCard",props:{toolName:{},instanceId:{},instanceName:{},moduleType:{},resolvedArgs:{},status:{}},emits:["submit"],setup(g,{emit:k}){const{$useRoute:_,$useModuleOverlay:Z}=useNuxtApp(),l=g,N=k,E=_(),V=e.computed(()=>E.params.slug),x=$useModuleApi(l.instanceId),m=e.ref(!0),u=e.ref(null),c=e.ref([]),a=e.ref([]),p=e.ref(null);function S(){const s=l.resolvedArgs?._cachedData;return s?(a.value=(s.topChannels||[]).map(t=>({sessionDefaultChannelGroup:t.channel,sessions:t.sessions,totalUsers:t.users,newUsers:t.newUsers,engagementRate:parseFloat(t.engagementRate)/100})),c.value=(s.topSources||[]).map(t=>({sessionSource:t.source,sessions:t.sessions,totalUsers:t.users})),p.value=l.resolvedArgs._fetchedAt||null,m.value=!1,!0):!1}async function B(){const{startDate:s,endDate:t}=l.resolvedArgs||{};m.value=!0,u.value=null;try{const o=new URLSearchParams;s&&o.set("startDate",s),t&&o.set("endDate",t);const[n,d]=await Promise.all([x.get(`/top-sources?${o.toString()}`),x.get(`/acquisition/channels?${o.toString()}`)]);c.value=n.rows||[],a.value=d.rows||[],p.value=new Date().toISOString(),h({topChannels:a.value.map(r=>({channel:r.sessionDefaultChannelGroup,sessions:r.sessions,users:r.totalUsers,newUsers:r.newUsers,engagementRate:`${(r.engagementRate*100).toFixed(1)}%`})),topSources:c.value.map(r=>({source:r.sessionSource,sessions:r.sessions,users:r.totalUsers}))})}catch(o){u.value=o?.data?.statusMessage||o?.message||"Failed to load traffic sources",h(`Error loading traffic sources: ${u.value}`)}finally{m.value=!1}}e.onMounted(()=>{l.status==="completed"&&S()||B()});function h(s){l.status!=="completed"&&N("submit",s)}const f=s=>s==null?"0":Math.round(s).toLocaleString(),D=s=>s?new Date(s).toLocaleString(void 0,{month:"short",day:"numeric",hour:"2-digit",minute:"2-digit"}):"",b=e.computed(()=>a.value.reduce((s,t)=>s+(t.sessions||0),0)),y=["bg-primary/70","bg-blue-500/70","bg-emerald-500/70","bg-amber-500/70","bg-purple-500/70","bg-pink-500/70","bg-cyan-500/70","bg-orange-500/70","bg-indigo-500/70","bg-rose-500/70"],v=["bg-primary","bg-blue-500","bg-emerald-500","bg-amber-500","bg-purple-500","bg-pink-500","bg-cyan-500","bg-orange-500","bg-indigo-500","bg-rose-500"],w=e.computed(()=>{const{startDate:s,endDate:t}=l.resolvedArgs||{};if(!s&&!t)return"Last 30 days";const o=s||"30daysAgo",n=o.match(/^(\d+)daysAgo$/);return n?`Last ${n[1]} days`:`${o} → ${t||"today"}`});return(s,t)=>{const o=e.resolveComponent("NuxtLink");return e.openBlock(),e.createElementBlock("div",C,[e.unref(m)?(e.openBlock(),e.createElementBlock("div",$,[e.createVNode(e.unref(i.Loader2),{class:"size-4 animate-spin text-muted-foreground"}),t[0]||(t[0]=e.createElementVNode("span",{class:"text-xs text-muted-foreground"},"Loading traffic sources…",-1))])):e.unref(u)?(e.openBlock(),e.createElementBlock("div",L,e.toDisplayString(e.unref(u)),1)):e.unref(a).length===0&&e.unref(c).length===0?(e.openBlock(),e.createElementBlock("div",A,[e.createVNode(e.unref(i.Globe),{class:"size-8 text-muted-foreground mx-auto mb-2"}),t[1]||(t[1]=e.createElementVNode("p",{class:"text-sm text-muted-foreground"},"No traffic source data found for this period.",-1))])):(e.openBlock(),e.createElementBlock("div",U,[e.createElementVNode("div",z,[e.createElementVNode("div",T,[e.createVNode(e.unref(i.Globe),{class:"size-3.5 text-primary"}),t[2]||(t[2]=e.createElementVNode("span",{class:"text-xs font-medium"},"Traffic Sources",-1))]),e.createElementVNode("span",F,e.toDisplayString(e.unref(w)),1)]),e.unref(a).length>0?(e.openBlock(),e.createElementBlock("div",G,[e.createElementVNode("div",M,[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(e.unref(a),(n,d)=>(e.openBlock(),e.createElementBlock("div",{key:n.sessionDefaultChannelGroup,class:e.normalizeClass(["h-full first:rounded-l-full last:rounded-r-full",y[d%y.length]]),style:e.normalizeStyle({width:`${e.unref(b)>0?(n.sessions||0)/e.unref(b)*100:0}%`}),title:`${n.sessionDefaultChannelGroup}: ${f(n.sessions)} sessions`},null,14,j))),128))]),e.createElementVNode("div",R,[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(e.unref(a).slice(0,6),(n,d)=>(e.openBlock(),e.createElementBlock("div",{key:n.sessionDefaultChannelGroup,class:"flex items-center gap-1.5"},[e.createElementVNode("span",{class:e.normalizeClass(["size-2 rounded-full shrink-0",v[d%v.length]])},null,2),e.createElementVNode("span",I,e.toDisplayString(n.sessionDefaultChannelGroup),1),e.createElementVNode("span",P,e.toDisplayString(f(n.sessions)),1)]))),128))])])):e.createCommentVNode("",!0),e.unref(c).length>0?(e.openBlock(),e.createElementBlock("div",q,[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"},"Top Sources")],-1)),e.createElementVNode("div",O,[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(e.unref(c),n=>(e.openBlock(),e.createElementBlock("div",{key:n.sessionSource,class:"px-3 py-2 flex items-center justify-between hover:bg-muted/30 transition-colors"},[e.createElementVNode("span",H,e.toDisplayString(n.sessionSource),1),e.createElementVNode("div",J,[e.createElementVNode("span",K,[e.createVNode(e.unref(i.MousePointerClick),{class:"size-2.5"}),e.createTextVNode(" "+e.toDisplayString(f(n.sessions)),1)]),e.createElementVNode("span",Q,[e.createVNode(e.unref(i.Users),{class:"size-2.5"}),e.createTextVNode(" "+e.toDisplayString(f(n.totalUsers)),1)])])]))),128))])])):e.createCommentVNode("",!0),e.createElementVNode("div",W,[e.unref(p)?(e.openBlock(),e.createElementBlock("span",X," Fetched "+e.toDisplayString(D(e.unref(p))),1)):e.createCommentVNode("",!0),e.createVNode(o,{to:`/projects/${e.unref(V)}/modules/${g.instanceId}`,class:"inline-flex items-center gap-1.5 text-xs text-primary hover:underline"},{default:e.withCtx(()=>[e.createVNode(e.unref(i.ExternalLink),{class:"size-3"}),t[4]||(t[4]=e.createTextVNode(" View full report ",-1))]),_:1},8,["to"])])]))])}}});exports.default=Y;
@@ -1,28 +1,27 @@
1
- import { defineComponent as I, computed as _, ref as x, onMounted as P, resolveComponent as B, openBlock as r, createElementBlock as a, unref as s, createVNode as m, createElementVNode as o, toDisplayString as d, Fragment as y, renderList as k, normalizeStyle as q, normalizeClass as N, createCommentVNode as S, createTextVNode as w, withCtx as O } from "vue";
2
- import { Loader2 as H, Globe as z, MousePointerClick as J, Users as K, ExternalLink as Q } from "lucide-vue-next";
3
- import { useRoute as W, useModuleApi as X } from "@oneclick.dev/cms-kit";
4
- const Y = { class: "w-full" }, Z = {
1
+ import { defineComponent as P, computed as _, ref as x, onMounted as B, resolveComponent as O, openBlock as r, createElementBlock as a, unref as s, createVNode as m, createElementVNode as o, toDisplayString as d, Fragment as y, renderList as k, normalizeStyle as q, normalizeClass as U, createCommentVNode as S, createTextVNode as w, withCtx as H } from "vue";
2
+ import { Loader2 as J, Globe as z, MousePointerClick as K, Users as Q, ExternalLink as W } from "lucide-vue-next";
3
+ const X = { class: "w-full" }, Y = {
5
4
  key: 0,
6
5
  class: "flex items-center gap-2 py-3"
7
- }, ee = {
6
+ }, Z = {
8
7
  key: 1,
9
8
  class: "text-xs text-destructive py-2"
10
- }, se = {
9
+ }, ee = {
11
10
  key: 2,
12
11
  class: "rounded-xl border bg-background p-4 text-center"
13
- }, te = {
12
+ }, se = {
14
13
  key: 3,
15
14
  class: "rounded-xl border bg-background overflow-hidden"
16
- }, oe = { class: "px-3 py-2 border-b bg-muted/40 flex items-center justify-between" }, ne = { class: "flex items-center gap-2" }, re = { class: "text-[10px] text-muted-foreground" }, ae = {
15
+ }, te = { class: "px-3 py-2 border-b bg-muted/40 flex items-center justify-between" }, oe = { class: "flex items-center gap-2" }, ne = { class: "text-[10px] text-muted-foreground" }, re = {
17
16
  key: 0,
18
17
  class: "px-3 pt-3 pb-2"
19
- }, le = { class: "h-3 rounded-full bg-muted overflow-hidden flex" }, ie = ["title"], ue = { class: "flex flex-wrap gap-x-3 gap-y-1 mt-2" }, de = { class: "text-[10px] text-muted-foreground" }, ce = { class: "text-[10px] font-medium" }, me = {
18
+ }, ae = { class: "h-3 rounded-full bg-muted overflow-hidden flex" }, le = ["title"], ie = { class: "flex flex-wrap gap-x-3 gap-y-1 mt-2" }, ue = { class: "text-[10px] text-muted-foreground" }, de = { class: "text-[10px] font-medium" }, ce = {
20
19
  key: 1,
21
20
  class: "border-t"
22
- }, pe = { class: "divide-y" }, ge = { class: "text-xs font-medium truncate flex-1" }, fe = { class: "flex items-center gap-3 text-[10px] text-muted-foreground shrink-0" }, xe = { class: "flex items-center gap-1" }, he = { class: "flex items-center gap-1" }, be = { class: "px-3 py-2 border-t bg-muted/20 flex items-center justify-between" }, ve = {
21
+ }, me = { class: "divide-y" }, pe = { class: "text-xs font-medium truncate flex-1" }, ge = { class: "flex items-center gap-3 text-[10px] text-muted-foreground shrink-0" }, fe = { class: "flex items-center gap-1" }, xe = { class: "flex items-center gap-1" }, he = { class: "px-3 py-2 border-t bg-muted/20 flex items-center justify-between" }, be = {
23
22
  key: 0,
24
23
  class: "text-[10px] text-muted-foreground"
25
- }, Se = /* @__PURE__ */ I({
24
+ }, ke = /* @__PURE__ */ P({
26
25
  __name: "TrafficSourcesCard",
27
26
  props: {
28
27
  toolName: {},
@@ -34,7 +33,7 @@ const Y = { class: "w-full" }, Z = {
34
33
  },
35
34
  emits: ["submit"],
36
35
  setup(D, { emit: G }) {
37
- const c = D, F = G, R = W(), T = _(() => R.params.slug), C = X(c.instanceId), h = x(!0), g = x(null), p = x([]), u = x([]), b = x(null);
36
+ const { $useRoute: F, $useModuleOverlay: ve } = useNuxtApp(), c = D, M = G, R = F(), T = _(() => R.params.slug), C = $useModuleApi(c.instanceId), h = x(!0), g = x(null), p = x([]), u = x([]), b = x(null);
38
37
  function j() {
39
38
  const t = c.resolvedArgs?._cachedData;
40
39
  return t ? (u.value = (t.topChannels || []).map((e) => ({
@@ -49,7 +48,7 @@ const Y = { class: "w-full" }, Z = {
49
48
  totalUsers: e.users
50
49
  })), b.value = c.resolvedArgs._fetchedAt || null, h.value = !1, !0) : !1;
51
50
  }
52
- async function M() {
51
+ async function V() {
53
52
  const { startDate: t, endDate: e } = c.resolvedArgs || {};
54
53
  h.value = !0, g.value = null;
55
54
  try {
@@ -79,13 +78,13 @@ const Y = { class: "w-full" }, Z = {
79
78
  h.value = !1;
80
79
  }
81
80
  }
82
- P(() => {
83
- c.status === "completed" && j() || M();
81
+ B(() => {
82
+ c.status === "completed" && j() || V();
84
83
  });
85
84
  function $(t) {
86
- c.status !== "completed" && F("submit", t);
85
+ c.status !== "completed" && M("submit", t);
87
86
  }
88
- const v = (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" }) : "", L = _(() => u.value.reduce((t, e) => t + (e.sessions || 0), 0)), U = [
87
+ const v = (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" }) : "", L = _(() => u.value.reduce((t, e) => t + (e.sessions || 0), 0)), A = [
89
88
  "bg-primary/70",
90
89
  "bg-blue-500/70",
91
90
  "bg-emerald-500/70",
@@ -96,7 +95,7 @@ const Y = { class: "w-full" }, Z = {
96
95
  "bg-orange-500/70",
97
96
  "bg-indigo-500/70",
98
97
  "bg-rose-500/70"
99
- ], A = [
98
+ ], N = [
100
99
  "bg-primary",
101
100
  "bg-blue-500",
102
101
  "bg-emerald-500",
@@ -107,82 +106,82 @@ const Y = { class: "w-full" }, Z = {
107
106
  "bg-orange-500",
108
107
  "bg-indigo-500",
109
108
  "bg-rose-500"
110
- ], E = _(() => {
109
+ ], I = _(() => {
111
110
  const { startDate: t, endDate: e } = c.resolvedArgs || {};
112
111
  if (!t && !e) return "Last 30 days";
113
112
  const l = t || "30daysAgo", n = l.match(/^(\d+)daysAgo$/);
114
113
  return n ? `Last ${n[1]} days` : `${l} → ${e || "today"}`;
115
114
  });
116
115
  return (t, e) => {
117
- const l = B("NuxtLink");
118
- return r(), a("div", Y, [
119
- s(h) ? (r(), a("div", Z, [
120
- m(s(H), { class: "size-4 animate-spin text-muted-foreground" }),
116
+ const l = O("NuxtLink");
117
+ return r(), a("div", X, [
118
+ s(h) ? (r(), a("div", Y, [
119
+ m(s(J), { class: "size-4 animate-spin text-muted-foreground" }),
121
120
  e[0] || (e[0] = o("span", { class: "text-xs text-muted-foreground" }, "Loading traffic sources…", -1))
122
- ])) : s(g) ? (r(), a("div", ee, d(s(g)), 1)) : s(u).length === 0 && s(p).length === 0 ? (r(), a("div", se, [
121
+ ])) : s(g) ? (r(), a("div", Z, d(s(g)), 1)) : s(u).length === 0 && s(p).length === 0 ? (r(), a("div", ee, [
123
122
  m(s(z), { class: "size-8 text-muted-foreground mx-auto mb-2" }),
124
123
  e[1] || (e[1] = o("p", { class: "text-sm text-muted-foreground" }, "No traffic source data found for this period.", -1))
125
- ])) : (r(), a("div", te, [
126
- o("div", oe, [
127
- o("div", ne, [
124
+ ])) : (r(), a("div", se, [
125
+ o("div", te, [
126
+ o("div", oe, [
128
127
  m(s(z), { class: "size-3.5 text-primary" }),
129
128
  e[2] || (e[2] = o("span", { class: "text-xs font-medium" }, "Traffic Sources", -1))
130
129
  ]),
131
- o("span", re, d(s(E)), 1)
130
+ o("span", ne, d(s(I)), 1)
132
131
  ]),
133
- s(u).length > 0 ? (r(), a("div", ae, [
134
- o("div", le, [
132
+ s(u).length > 0 ? (r(), a("div", re, [
133
+ o("div", ae, [
135
134
  (r(!0), a(y, null, k(s(u), (n, f) => (r(), a("div", {
136
135
  key: n.sessionDefaultChannelGroup,
137
- class: N(["h-full first:rounded-l-full last:rounded-r-full", U[f % U.length]]),
136
+ class: U(["h-full first:rounded-l-full last:rounded-r-full", A[f % A.length]]),
138
137
  style: q({ width: `${s(L) > 0 ? (n.sessions || 0) / s(L) * 100 : 0}%` }),
139
138
  title: `${n.sessionDefaultChannelGroup}: ${v(n.sessions)} sessions`
140
- }, null, 14, ie))), 128))
139
+ }, null, 14, le))), 128))
141
140
  ]),
142
- o("div", ue, [
141
+ o("div", ie, [
143
142
  (r(!0), a(y, null, k(s(u).slice(0, 6), (n, f) => (r(), a("div", {
144
143
  key: n.sessionDefaultChannelGroup,
145
144
  class: "flex items-center gap-1.5"
146
145
  }, [
147
146
  o("span", {
148
- class: N(["size-2 rounded-full shrink-0", A[f % A.length]])
147
+ class: U(["size-2 rounded-full shrink-0", N[f % N.length]])
149
148
  }, null, 2),
150
- o("span", de, d(n.sessionDefaultChannelGroup), 1),
151
- o("span", ce, d(v(n.sessions)), 1)
149
+ o("span", ue, d(n.sessionDefaultChannelGroup), 1),
150
+ o("span", de, d(v(n.sessions)), 1)
152
151
  ]))), 128))
153
152
  ])
154
153
  ])) : S("", !0),
155
- s(p).length > 0 ? (r(), a("div", me, [
154
+ s(p).length > 0 ? (r(), a("div", ce, [
156
155
  e[3] || (e[3] = o("div", { class: "px-3 py-1.5 bg-muted/20" }, [
157
156
  o("span", { class: "text-[10px] font-medium text-muted-foreground uppercase tracking-wide" }, "Top Sources")
158
157
  ], -1)),
159
- o("div", pe, [
158
+ o("div", me, [
160
159
  (r(!0), a(y, null, k(s(p), (n) => (r(), a("div", {
161
160
  key: n.sessionSource,
162
161
  class: "px-3 py-2 flex items-center justify-between hover:bg-muted/30 transition-colors"
163
162
  }, [
164
- o("span", ge, d(n.sessionSource), 1),
165
- o("div", fe, [
166
- o("span", xe, [
167
- m(s(J), { class: "size-2.5" }),
163
+ o("span", pe, d(n.sessionSource), 1),
164
+ o("div", ge, [
165
+ o("span", fe, [
166
+ m(s(K), { class: "size-2.5" }),
168
167
  w(" " + d(v(n.sessions)), 1)
169
168
  ]),
170
- o("span", he, [
171
- m(s(K), { class: "size-2.5" }),
169
+ o("span", xe, [
170
+ m(s(Q), { class: "size-2.5" }),
172
171
  w(" " + d(v(n.totalUsers)), 1)
173
172
  ])
174
173
  ])
175
174
  ]))), 128))
176
175
  ])
177
176
  ])) : S("", !0),
178
- o("div", be, [
179
- s(b) ? (r(), a("span", ve, " Fetched " + d(V(s(b))), 1)) : S("", !0),
177
+ o("div", he, [
178
+ s(b) ? (r(), a("span", be, " Fetched " + d(E(s(b))), 1)) : S("", !0),
180
179
  m(l, {
181
180
  to: `/projects/${s(T)}/modules/${D.instanceId}`,
182
181
  class: "inline-flex items-center gap-1.5 text-xs text-primary hover:underline"
183
182
  }, {
184
- default: O(() => [
185
- m(s(Q), { class: "size-3" }),
183
+ default: H(() => [
184
+ m(s(W), { class: "size-3" }),
186
185
  e[4] || (e[4] = w(" View full report ", -1))
187
186
  ]),
188
187
  _: 1
@@ -194,5 +193,5 @@ const Y = { class: "w-full" }, Z = {
194
193
  }
195
194
  });
196
195
  export {
197
- Se as default
196
+ ke as default
198
197
  };
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("vue"),o=require("lucide-vue-next"),C={class:"w-full"},M={key:0,class:"flex items-center gap-2 py-3"},F={key:1,class:"text-xs text-destructive py-2"},L={key:2,class:"rounded-xl border bg-background overflow-hidden"},z={class:"px-3 py-2 border-b bg-muted/40 flex items-center justify-between"},j={class:"flex items-center gap-2"},O={class:"text-[10px] text-muted-foreground"},T={class:"grid grid-cols-2 sm:grid-cols-4 divide-x divide-y"},I={class:"flex items-center gap-1.5"},q={class:"text-[10px] text-muted-foreground uppercase tracking-wide"},Y={class:"text-sm font-semibold"},G={key:0,class:"flex items-center gap-0.5"},H={class:"px-3 py-2 border-t bg-muted/20 flex items-center justify-between"},J={key:0,class:"text-[10px] text-muted-foreground"},K=e.defineComponent({__name:"VisitorStatsCard",props:{toolName:{},instanceId:{},instanceName:{},moduleType:{},resolvedArgs:{},status:{}},emits:["submit"],setup(f,{emit:w}){const{$useRoute:S,$useModuleOverlay:Q}=useNuxtApp(),i=f,V=w,_=S(),N=e.computed(()=>_.params.slug),D=$useModuleApi(i.instanceId),u=e.ref(!0),c=e.ref(null),r=e.ref({}),l=e.ref({}),d=e.ref(null);function B(){const t=i.resolvedArgs?._cachedData;return t?(r.value={totalUsers:t.totalUsers||0,sessions:t.sessions||0,screenPageViews:t.pageViews||0,newUsers:t.newUsers||0,bounceRate:v(t.bounceRate),averageSessionDuration:E(t.avgSessionDuration),engagementRate:v(t.engagementRate),screenPageViewsPerSession:parseFloat(t.pagesPerSession)||0},l.value=Object.fromEntries(Object.entries(t.changes||{}).map(([s,n])=>[s,P(n)])),d.value=i.resolvedArgs._fetchedAt||null,u.value=!1,!0):!1}function v(t){return t?parseFloat(t)/100:0}function E(t){if(!t)return 0;const s=t.match(/(\d+)m/),n=t.match(/(\d+)s/);return(s?parseInt(s[1])*60:0)+(n?parseInt(n[1]):0)}function P(t){return!t||t==="N/A"?null:parseFloat(t.replace("+",""))}async function $(){const{startDate:t,endDate:s}=i.resolvedArgs||{};u.value=!0,c.value=null;try{const n=new URLSearchParams;t&&n.set("startDate",t),s&&n.set("endDate",s);const a=await D.get(`/report?${n.toString()}`);r.value=a.totals||{},l.value=a.changes||{},d.value=new Date().toISOString(),h({period:x.value,totalUsers:Math.round(r.value.totalUsers||0),sessions:Math.round(r.value.sessions||0),pageViews:Math.round(r.value.screenPageViews||0),newUsers:Math.round(r.value.newUsers||0),bounceRate:`${(r.value.bounceRate*100).toFixed(1)}%`,avgSessionDuration:y(r.value.averageSessionDuration),engagementRate:`${(r.value.engagementRate*100).toFixed(1)}%`,pagesPerSession:(r.value.screenPageViewsPerSession||0).toFixed(1),changes:Object.fromEntries(Object.entries(l.value).map(([A,p])=>[A,p!==null?`${p>0?"+":""}${p.toFixed(1)}%`:"N/A"]))})}catch(n){c.value=n?.data?.statusMessage||n?.message||"Failed to load visitor stats",h(`Error loading visitor stats: ${c.value}`)}finally{u.value=!1}}e.onMounted(()=>{i.status==="completed"&&B()||$()});function h(t){i.status!=="completed"&&V("submit",t)}const x=e.computed(()=>{const{startDate:t,endDate:s}=i.resolvedArgs||{};if(!t&&!s)return"Last 30 days";const n=t||"30daysAgo",a=n.match(/^(\d+)daysAgo$/);return n==="yesterday"&&(!s||s==="yesterday")?"Yesterday":a?`Last ${a[1]} days`:`${n} → ${s||"today"}`}),y=t=>{if(!t)return"0s";const s=Math.floor(t/60),n=Math.round(t%60);return s>0?`${s}m ${n}s`:`${n}s`},m=t=>t==null?"0":Math.round(t).toLocaleString(),k=t=>t==null?"0%":`${(t*100).toFixed(1)}%`,R=t=>t?new Date(t).toLocaleString(void 0,{month:"short",day:"numeric",hour:"2-digit",minute:"2-digit"}):"",g=(t,s=!1)=>{if(t==null)return"text-muted-foreground";const n=s?t<0:t>0,a=s?t>0:t<0;return n?"text-emerald-600 dark:text-emerald-400":a?"text-red-600 dark:text-red-400":"text-muted-foreground"},b=t=>t==null?null:`${t>0?"+":""}${t.toFixed(1)}%`,U=e.computed(()=>[{label:"Users",value:m(r.value.totalUsers),change:l.value.totalUsers,icon:o.Users},{label:"Sessions",value:m(r.value.sessions),change:l.value.sessions,icon:o.MousePointerClick},{label:"Page Views",value:m(r.value.screenPageViews),change:l.value.screenPageViews,icon:o.Eye},{label:"New Users",value:m(r.value.newUsers),change:l.value.newUsers,icon:o.Users},{label:"Bounce Rate",value:k(r.value.bounceRate),change:l.value.bounceRate,inverted:!0,icon:o.ArrowDownRight},{label:"Engagement",value:k(r.value.engagementRate),change:l.value.engagementRate,icon:o.Timer},{label:"Avg Duration",value:y(r.value.averageSessionDuration),change:l.value.averageSessionDuration,icon:o.Timer},{label:"Pages/Session",value:(r.value.screenPageViewsPerSession||0).toFixed(1),change:l.value.screenPageViewsPerSession,icon:o.Eye}]);return(t,s)=>{const n=e.resolveComponent("NuxtLink");return e.openBlock(),e.createElementBlock("div",C,[e.unref(u)?(e.openBlock(),e.createElementBlock("div",M,[e.createVNode(e.unref(o.Loader2),{class:"size-4 animate-spin text-muted-foreground"}),s[0]||(s[0]=e.createElementVNode("span",{class:"text-xs text-muted-foreground"},"Loading visitor statistics…",-1))])):e.unref(c)?(e.openBlock(),e.createElementBlock("div",F,e.toDisplayString(e.unref(c)),1)):(e.openBlock(),e.createElementBlock("div",L,[e.createElementVNode("div",z,[e.createElementVNode("div",j,[e.createVNode(e.unref(o.BarChart3),{class:"size-3.5 text-primary"}),s[1]||(s[1]=e.createElementVNode("span",{class:"text-xs font-medium"},"Visitor Statistics",-1))]),e.createElementVNode("span",O,e.toDisplayString(e.unref(x)),1)]),e.createElementVNode("div",T,[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(e.unref(U),a=>(e.openBlock(),e.createElementBlock("div",{key:a.label,class:"px-3 py-3 space-y-1"},[e.createElementVNode("div",I,[(e.openBlock(),e.createBlock(e.resolveDynamicComponent(a.icon),{class:"size-3 text-muted-foreground"})),e.createElementVNode("span",q,e.toDisplayString(a.label),1)]),e.createElementVNode("p",Y,e.toDisplayString(a.value),1),b(a.change)?(e.openBlock(),e.createElementBlock("div",G,[(a.change??0)>0?(e.openBlock(),e.createBlock(e.unref(o.ArrowUpRight),{key:0,class:e.normalizeClass(["size-2.5",g(a.change,a.inverted)])},null,8,["class"])):(a.change??0)<0?(e.openBlock(),e.createBlock(e.unref(o.ArrowDownRight),{key:1,class:e.normalizeClass(["size-2.5",g(a.change,a.inverted)])},null,8,["class"])):(e.openBlock(),e.createBlock(e.unref(o.Minus),{key:2,class:"size-2.5 text-muted-foreground"})),e.createElementVNode("span",{class:e.normalizeClass(["text-[10px] font-medium",g(a.change,a.inverted)])},e.toDisplayString(b(a.change)),3)])):e.createCommentVNode("",!0)]))),128))]),e.createElementVNode("div",H,[e.unref(d)?(e.openBlock(),e.createElementBlock("span",J," Fetched "+e.toDisplayString(R(e.unref(d))),1)):e.createCommentVNode("",!0),e.createVNode(n,{to:`/projects/${e.unref(N)}/modules/${f.instanceId}`,class:"inline-flex items-center gap-1.5 text-xs text-primary hover:underline"},{default:e.withCtx(()=>[e.createVNode(e.unref(o.ExternalLink),{class:"size-3"}),s[2]||(s[2]=e.createTextVNode(" View full report ",-1))]),_:1},8,["to"])])]))])}}});exports.default=K;