@oneclick.dev/cms-core-modules 0.0.78 → 0.0.79
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{AppointmentDetailsCard-SMNXi117.mjs → AppointmentDetailsCard-Bu9VzIRx.mjs} +54 -55
- package/dist/AppointmentDetailsCard-LL-6PARb.js +1 -0
- package/dist/{AppointmentListTable-vMSMt0M5.mjs → AppointmentListTable-B8YLwOfT.mjs} +41 -42
- package/dist/AppointmentListTable-DNvvb4sz.js +1 -0
- package/dist/CountryBreakdownCard-BpDXbxwZ.js +1 -0
- package/dist/{CountryBreakdownCard-B_VhBsm8.mjs → CountryBreakdownCard-oDzmpvAd.mjs} +45 -46
- package/dist/DeviceBreakdownCard-OXiU9Cf0.js +1 -0
- package/dist/DeviceBreakdownCard-Oh_yzipG.mjs +159 -0
- package/dist/{PeakHoursCard-_1JS0tpZ.mjs → PeakHoursCard-DzNo4SNo.mjs} +56 -57
- package/dist/PeakHoursCard-OkgI1vnd.js +1 -0
- package/dist/ProductDetailsCard-BBOorNmB.js +1 -0
- package/dist/{ProductDetailsCard-C5gqBJag.mjs → ProductDetailsCard-CYK9Mtt4.mjs} +44 -45
- package/dist/RealtimeCard-DESm9Fs_.js +1 -0
- package/dist/{RealtimeCard-CtX6Yyk-.mjs → RealtimeCard-tNUSIw6B.mjs} +44 -45
- package/dist/{SearchTermsCard-DzSu9jzo.mjs → SearchTermsCard-BVHFHWUZ.mjs} +66 -67
- package/dist/SearchTermsCard-DmyhGQVM.js +1 -0
- package/dist/{TopPagesCard-D7lH_QYV.mjs → TopPagesCard-CRIa3rSZ.mjs} +52 -53
- package/dist/TopPagesCard-CgtNyhwY.js +1 -0
- package/dist/TrafficSourcesCard-CPAxaQTi.js +1 -0
- package/dist/{TrafficSourcesCard-Fng3fVh7.mjs → TrafficSourcesCard-Ct20QYax.mjs} +48 -49
- package/dist/VisitorStatsCard-Cs6jPehw.js +1 -0
- package/dist/{VisitorStatsCard-CuXXnMBc.mjs → VisitorStatsCard-DMULybKV.mjs} +57 -58
- package/dist/index.cjs.js +1 -1
- package/dist/index.mjs +11 -11
- package/package.json +2 -2
- package/dist/AppointmentDetailsCard-BfBwWxTU.js +0 -1
- package/dist/AppointmentListTable-Dk-CnNR6.js +0 -1
- package/dist/CountryBreakdownCard-Ghg0Wz-h.js +0 -1
- package/dist/DeviceBreakdownCard-CQR65Zr_.mjs +0 -160
- package/dist/DeviceBreakdownCard-Cpcj75Rv.js +0 -1
- package/dist/PeakHoursCard-CFIg8dys.js +0 -1
- package/dist/ProductDetailsCard-Ce11f_9r.js +0 -1
- package/dist/RealtimeCard-CatAzdxv.js +0 -1
- package/dist/SearchTermsCard-BPAdRL-r.js +0 -1
- package/dist/TopPagesCard-BA9Are_Z.js +0 -1
- package/dist/TrafficSourcesCard-DV13ZOBq.js +0 -1
- package/dist/VisitorStatsCard-CAzAZtKD.js +0 -1
|
@@ -1,19 +1,18 @@
|
|
|
1
|
-
import { defineComponent as
|
|
2
|
-
import { Loader2 as
|
|
3
|
-
|
|
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
|
-
},
|
|
6
|
+
}, Z = {
|
|
8
7
|
key: 1,
|
|
9
8
|
class: "text-xs text-destructive py-2"
|
|
10
|
-
},
|
|
9
|
+
}, ee = {
|
|
11
10
|
key: 2,
|
|
12
11
|
class: "rounded-xl border bg-background p-4 text-center"
|
|
13
|
-
},
|
|
12
|
+
}, te = {
|
|
14
13
|
key: 3,
|
|
15
14
|
class: "rounded-xl border bg-background overflow-hidden"
|
|
16
|
-
},
|
|
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:
|
|
28
|
-
const m = b,
|
|
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:
|
|
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
|
|
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
|
|
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
|
|
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
|
-
|
|
67
|
-
m.status === "completed" && C() ||
|
|
65
|
+
F(() => {
|
|
66
|
+
m.status === "completed" && C() || z();
|
|
68
67
|
});
|
|
69
68
|
function k(e) {
|
|
70
|
-
m.status !== "completed" &&
|
|
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(),
|
|
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 =
|
|
84
|
-
return d(),
|
|
85
|
-
s(x) ? (d(),
|
|
86
|
-
|
|
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(),
|
|
89
|
-
|
|
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(),
|
|
92
|
-
a("div",
|
|
93
|
-
a("div",
|
|
94
|
-
|
|
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",
|
|
96
|
+
a("span", oe, i(s(U)), 1)
|
|
98
97
|
]),
|
|
99
|
-
a("div",
|
|
100
|
-
(d(!0),
|
|
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",
|
|
105
|
-
a("span",
|
|
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,
|
|
108
|
+
}, i(o.pagePath), 9, le)
|
|
110
109
|
]),
|
|
111
|
-
a("div",
|
|
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(
|
|
114
|
+
style: R({ width: `${(o.screenPageViews || 0) / s(E) * 100}%` })
|
|
116
115
|
}, null, 4)
|
|
117
116
|
]),
|
|
118
|
-
a("div",
|
|
119
|
-
a("span",
|
|
120
|
-
|
|
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",
|
|
124
|
-
|
|
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",
|
|
128
|
-
|
|
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",
|
|
136
|
-
a("span",
|
|
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(),
|
|
139
|
-
g(" · fetched " + i(
|
|
140
|
-
], 64)) :
|
|
137
|
+
s(h) ? (d(), u(P, { key: 0 }, [
|
|
138
|
+
g(" · fetched " + i(I(s(h))), 1)
|
|
139
|
+
], 64)) : q("", !0)
|
|
141
140
|
]),
|
|
142
|
-
|
|
143
|
-
to: `/projects/${s(
|
|
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:
|
|
147
|
-
|
|
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
|
-
|
|
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
|
|
2
|
-
import { Loader2 as
|
|
3
|
-
|
|
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
|
-
},
|
|
6
|
+
}, Z = {
|
|
8
7
|
key: 1,
|
|
9
8
|
class: "text-xs text-destructive py-2"
|
|
10
|
-
},
|
|
9
|
+
}, ee = {
|
|
11
10
|
key: 2,
|
|
12
11
|
class: "rounded-xl border bg-background p-4 text-center"
|
|
13
|
-
},
|
|
12
|
+
}, se = {
|
|
14
13
|
key: 3,
|
|
15
14
|
class: "rounded-xl border bg-background overflow-hidden"
|
|
16
|
-
},
|
|
15
|
+
}, te = { class: "px-3 py-2 border-b bg-muted/40 flex items-center justify-between" }, 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
|
-
},
|
|
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
|
-
},
|
|
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
|
-
},
|
|
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,
|
|
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
|
|
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
|
-
|
|
83
|
-
c.status === "completed" && j() ||
|
|
81
|
+
B(() => {
|
|
82
|
+
c.status === "completed" && j() || V();
|
|
84
83
|
});
|
|
85
84
|
function $(t) {
|
|
86
|
-
c.status !== "completed" &&
|
|
85
|
+
c.status !== "completed" && M("submit", t);
|
|
87
86
|
}
|
|
88
|
-
const v = (t) => t == null ? "0" : Math.round(t).toLocaleString(),
|
|
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
|
-
],
|
|
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
|
-
],
|
|
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 =
|
|
118
|
-
return r(), a("div",
|
|
119
|
-
s(h) ? (r(), a("div",
|
|
120
|
-
m(s(
|
|
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",
|
|
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",
|
|
126
|
-
o("div",
|
|
127
|
-
o("div",
|
|
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",
|
|
130
|
+
o("span", ne, d(s(I)), 1)
|
|
132
131
|
]),
|
|
133
|
-
s(u).length > 0 ? (r(), a("div",
|
|
134
|
-
o("div",
|
|
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:
|
|
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,
|
|
139
|
+
}, null, 14, le))), 128))
|
|
141
140
|
]),
|
|
142
|
-
o("div",
|
|
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:
|
|
147
|
+
class: U(["size-2 rounded-full shrink-0", N[f % N.length]])
|
|
149
148
|
}, null, 2),
|
|
150
|
-
o("span",
|
|
151
|
-
o("span",
|
|
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",
|
|
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",
|
|
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",
|
|
165
|
-
o("div",
|
|
166
|
-
o("span",
|
|
167
|
-
m(s(
|
|
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",
|
|
171
|
-
m(s(
|
|
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",
|
|
179
|
-
s(b) ? (r(), a("span",
|
|
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:
|
|
185
|
-
m(s(
|
|
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
|
-
|
|
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;
|