@oneclick.dev/cms-core-modules 0.0.78 → 0.0.80
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-33WpATpV.mjs} +42 -43
- package/dist/AppointmentDetailsCard-DpLM5IrB.js +1 -0
- package/dist/AppointmentListTable-CQ0WIXtj.js +1 -0
- package/dist/{AppointmentListTable-vMSMt0M5.mjs → AppointmentListTable-aV_UJd6j.mjs} +24 -25
- package/dist/CountryBreakdownCard-D7BK3nRD.js +1 -0
- package/dist/{CountryBreakdownCard-B_VhBsm8.mjs → CountryBreakdownCard-DVxNz2DJ.mjs} +29 -30
- package/dist/DeviceBreakdownCard-DRhQ9ufG.js +1 -0
- package/dist/{DeviceBreakdownCard-CQR65Zr_.mjs → DeviceBreakdownCard-W1frLe0L.mjs} +57 -58
- package/dist/{PeakHoursCard-_1JS0tpZ.mjs → PeakHoursCard-9-EZFZLR.mjs} +27 -28
- package/dist/PeakHoursCard-BR5zmta4.js +1 -0
- package/dist/{ProductDetailsCard-C5gqBJag.mjs → ProductDetailsCard-6nHikw4V.mjs} +22 -23
- package/dist/ProductDetailsCard-Bn7qrgmc.js +1 -0
- package/dist/RealtimeCard--APfRNc8.js +1 -0
- package/dist/{RealtimeCard-CtX6Yyk-.mjs → RealtimeCard-fvQlJcM7.mjs} +35 -36
- package/dist/SearchTermsCard-BsB-63aH.js +1 -0
- package/dist/{SearchTermsCard-DzSu9jzo.mjs → SearchTermsCard-BzVrHKqQ.mjs} +51 -52
- package/dist/TopPagesCard-BDeA997A.js +1 -0
- package/dist/{TopPagesCard-D7lH_QYV.mjs → TopPagesCard-CTozhOr_.mjs} +38 -39
- package/dist/{TrafficSourcesCard-Fng3fVh7.mjs → TrafficSourcesCard-BxtCKsqx.mjs} +57 -58
- package/dist/TrafficSourcesCard-C3ziDTUL.js +1 -0
- package/dist/VisitorStatsCard-BmByE_Hi.js +1 -0
- package/dist/{VisitorStatsCard-CuXXnMBc.mjs → VisitorStatsCard-CXizEbVK.mjs} +37 -38
- 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-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,6 +1,5 @@
|
|
|
1
|
-
import { defineComponent as
|
|
2
|
-
import { Loader2 as
|
|
3
|
-
import { useRoute as T, useModuleApi as $ } from "@oneclick.dev/cms-kit";
|
|
1
|
+
import { defineComponent as C, computed as S, ref as m, onMounted as P, resolveComponent as V, openBlock as n, createElementBlock as o, unref as a, createVNode as i, createElementVNode as e, toDisplayString as r, Fragment as $, renderList as D, createCommentVNode as _, withCtx as E, createTextVNode as F } from "vue";
|
|
2
|
+
import { Loader2 as I, Radio as M, Users as h, ExternalLink as T } from "lucide-vue-next";
|
|
4
3
|
const B = { class: "w-full" }, O = {
|
|
5
4
|
key: 0,
|
|
6
5
|
class: "flex items-center gap-2 py-3"
|
|
@@ -13,10 +12,10 @@ const B = { class: "w-full" }, O = {
|
|
|
13
12
|
}, H = { class: "px-3 py-2 border-b bg-muted/40 flex items-center justify-between" }, J = { class: "flex items-center gap-2" }, K = { class: "px-3 py-4 text-center" }, Q = { class: "flex items-center justify-center gap-2 mb-1" }, W = { class: "text-3xl font-bold" }, X = { class: "text-xs text-muted-foreground" }, Y = {
|
|
14
13
|
key: 0,
|
|
15
14
|
class: "border-t"
|
|
16
|
-
}, Z = { class: "divide-y" }, ee = ["title"], te = { class: "flex items-center gap-1 text-[10px] text-muted-foreground shrink-0 ml-2" }, se = { class: "font-medium" }, ae = { class: "px-3 py-2 border-t bg-muted/20 flex items-center justify-between" },
|
|
15
|
+
}, Z = { class: "divide-y" }, ee = ["title"], te = { class: "flex items-center gap-1 text-[10px] text-muted-foreground shrink-0 ml-2" }, se = { class: "font-medium" }, ae = { class: "px-3 py-2 border-t bg-muted/20 flex items-center justify-between" }, ne = {
|
|
17
16
|
key: 0,
|
|
18
17
|
class: "text-[10px] text-muted-foreground"
|
|
19
|
-
},
|
|
18
|
+
}, re = /* @__PURE__ */ C({
|
|
20
19
|
__name: "RealtimeCard",
|
|
21
20
|
props: {
|
|
22
21
|
toolName: {},
|
|
@@ -28,19 +27,19 @@ const B = { class: "w-full" }, O = {
|
|
|
28
27
|
},
|
|
29
28
|
emits: ["submit"],
|
|
30
29
|
setup(v, { emit: y }) {
|
|
31
|
-
const l = v,
|
|
32
|
-
function
|
|
30
|
+
const { $useRoute: b, $useModuleApi: w } = useNuxtApp(), l = v, k = y, N = b(), A = S(() => N.params.slug), U = w(l.instanceId), p = m(!0), d = m(null), c = m(0), u = m([]), x = m(null);
|
|
31
|
+
function z() {
|
|
33
32
|
const s = l.resolvedArgs?._cachedData;
|
|
34
33
|
return s ? (c.value = s.activeUsersRightNow || 0, u.value = (s.topActivePages || []).map((t) => ({
|
|
35
34
|
page: t.page,
|
|
36
35
|
activeUsers: t.activeUsers
|
|
37
|
-
})),
|
|
36
|
+
})), x.value = l.resolvedArgs._fetchedAt || null, p.value = !1, !0) : !1;
|
|
38
37
|
}
|
|
39
|
-
async function
|
|
38
|
+
async function L() {
|
|
40
39
|
p.value = !0, d.value = null;
|
|
41
40
|
try {
|
|
42
|
-
const s = await
|
|
43
|
-
c.value = s.activeUsers || 0, u.value = s.activePages || [],
|
|
41
|
+
const s = await U.get("/realtime");
|
|
42
|
+
c.value = s.activeUsers || 0, u.value = s.activePages || [], x.value = (/* @__PURE__ */ new Date()).toISOString(), g({
|
|
44
43
|
activeUsersRightNow: c.value,
|
|
45
44
|
topActivePages: u.value.map((t) => ({
|
|
46
45
|
page: t.page,
|
|
@@ -53,23 +52,23 @@ const B = { class: "w-full" }, O = {
|
|
|
53
52
|
p.value = !1;
|
|
54
53
|
}
|
|
55
54
|
}
|
|
56
|
-
|
|
57
|
-
l.status === "completed" &&
|
|
55
|
+
P(() => {
|
|
56
|
+
l.status === "completed" && z() || L();
|
|
58
57
|
});
|
|
59
58
|
function g(s) {
|
|
60
|
-
l.status !== "completed" &&
|
|
59
|
+
l.status !== "completed" && k("submit", s);
|
|
61
60
|
}
|
|
62
|
-
const
|
|
61
|
+
const R = (s) => s ? new Date(s).toLocaleString(void 0, { month: "short", day: "numeric", hour: "2-digit", minute: "2-digit" }) : "";
|
|
63
62
|
return (s, t) => {
|
|
64
|
-
const
|
|
65
|
-
return
|
|
66
|
-
a(p) ? (
|
|
67
|
-
|
|
63
|
+
const j = V("NuxtLink");
|
|
64
|
+
return n(), o("div", B, [
|
|
65
|
+
a(p) ? (n(), o("div", O, [
|
|
66
|
+
i(a(I), { class: "size-4 animate-spin text-muted-foreground" }),
|
|
68
67
|
t[0] || (t[0] = e("span", { class: "text-xs text-muted-foreground" }, "Loading realtime data…", -1))
|
|
69
|
-
])) : a(d) ? (
|
|
68
|
+
])) : a(d) ? (n(), o("div", q, r(a(d)), 1)) : (n(), o("div", G, [
|
|
70
69
|
e("div", H, [
|
|
71
70
|
e("div", J, [
|
|
72
|
-
|
|
71
|
+
i(a(M), { class: "size-3.5 text-emerald-500" }),
|
|
73
72
|
t[1] || (t[1] = e("span", { class: "text-xs font-medium" }, "Realtime", -1))
|
|
74
73
|
]),
|
|
75
74
|
t[2] || (t[2] = e("span", { class: "relative flex size-2" }, [
|
|
@@ -79,40 +78,40 @@ const B = { class: "w-full" }, O = {
|
|
|
79
78
|
]),
|
|
80
79
|
e("div", K, [
|
|
81
80
|
e("div", Q, [
|
|
82
|
-
|
|
81
|
+
i(a(h), { class: "size-5 text-primary" }),
|
|
83
82
|
e("span", W, r(a(c)), 1)
|
|
84
83
|
]),
|
|
85
84
|
e("p", X, "active " + r(a(c) === 1 ? "user" : "users") + " right now", 1)
|
|
86
85
|
]),
|
|
87
|
-
a(u).length > 0 ? (
|
|
86
|
+
a(u).length > 0 ? (n(), o("div", Y, [
|
|
88
87
|
t[3] || (t[3] = e("div", { class: "px-3 py-1.5 bg-muted/20" }, [
|
|
89
88
|
e("span", { class: "text-[10px] font-medium text-muted-foreground uppercase tracking-wide" }, "Active Pages")
|
|
90
89
|
], -1)),
|
|
91
90
|
e("div", Z, [
|
|
92
|
-
(
|
|
93
|
-
key:
|
|
91
|
+
(n(!0), o($, null, D(a(u), (f) => (n(), o("div", {
|
|
92
|
+
key: f.page,
|
|
94
93
|
class: "px-3 py-2 flex items-center justify-between hover:bg-muted/30 transition-colors"
|
|
95
94
|
}, [
|
|
96
95
|
e("span", {
|
|
97
96
|
class: "text-xs truncate flex-1",
|
|
98
|
-
title:
|
|
99
|
-
}, r(
|
|
97
|
+
title: f.page
|
|
98
|
+
}, r(f.page), 9, ee),
|
|
100
99
|
e("div", te, [
|
|
101
|
-
|
|
102
|
-
e("span", se, r(
|
|
100
|
+
i(a(h), { class: "size-2.5" }),
|
|
101
|
+
e("span", se, r(f.activeUsers), 1)
|
|
103
102
|
])
|
|
104
103
|
]))), 128))
|
|
105
104
|
])
|
|
106
105
|
])) : _("", !0),
|
|
107
106
|
e("div", ae, [
|
|
108
|
-
a(
|
|
109
|
-
|
|
110
|
-
to: `/projects/${a(
|
|
107
|
+
a(x) ? (n(), o("span", ne, " Fetched " + r(R(a(x))), 1)) : _("", !0),
|
|
108
|
+
i(j, {
|
|
109
|
+
to: `/projects/${a(A)}/modules/${v.instanceId}`,
|
|
111
110
|
class: "inline-flex items-center gap-1.5 text-xs text-primary hover:underline"
|
|
112
111
|
}, {
|
|
113
|
-
default:
|
|
114
|
-
|
|
115
|
-
t[4] || (t[4] =
|
|
112
|
+
default: E(() => [
|
|
113
|
+
i(a(T), { class: "size-3" }),
|
|
114
|
+
t[4] || (t[4] = F(" View full report ", -1))
|
|
116
115
|
]),
|
|
117
116
|
_: 1
|
|
118
117
|
}, 8, ["to"])
|
|
@@ -123,5 +122,5 @@ const B = { class: "w-full" }, O = {
|
|
|
123
122
|
}
|
|
124
123
|
});
|
|
125
124
|
export {
|
|
126
|
-
|
|
125
|
+
re as default
|
|
127
126
|
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("vue"),c=require("lucide-vue-next"),M={class:"w-full"},R={key:0,class:"flex items-center gap-2 py-3"},U={key:1,class:"text-xs text-destructive py-2"},j={key:2,class:"rounded-xl border bg-background p-4 text-center space-y-2"},q={key:3,class:"rounded-xl border bg-background overflow-hidden"},G={class:"px-3 py-2 border-b bg-muted/40 flex items-center justify-between"},I={class:"flex items-center gap-2"},Q={class:"text-xs font-medium"},K={class:"text-[10px] text-muted-foreground"},O={class:"divide-y"},H={class:"flex items-center gap-2 mb-1.5"},J={class:"text-[10px] font-medium text-muted-foreground w-5 text-right shrink-0"},W={class:"text-xs font-medium truncate flex-1"},X={class:"ml-7 space-y-1.5"},Y={class:"h-1.5 rounded-full bg-muted overflow-hidden"},Z={key:0,class:"flex items-center gap-3 text-[10px] text-muted-foreground"},ee={class:"flex items-center gap-1"},te={class:"flex items-center gap-1"},se={class:"flex items-center gap-1"},oe={class:"flex items-center gap-1"},ne={key:1,class:"flex items-center gap-3 text-[10px] text-muted-foreground"},re={class:"flex items-center gap-1"},ae={class:"flex items-center gap-1"},ce={class:"flex items-center gap-1"},le={class:"px-3 py-2 border-t bg-muted/20 flex items-center justify-between"},ie={class:"text-[10px] text-muted-foreground"},de=e.defineComponent({__name:"SearchTermsCard",props:{toolName:{},instanceId:{},instanceName:{},moduleType:{},resolvedArgs:{},status:{}},emits:["submit"],setup(x,{emit:N}){const{$useRoute:V,$useModuleApi:k}=useNuxtApp(),i=x,S=N,b=V(),E=e.computed(()=>b.params.slug),T=k(i.instanceId),m=e.ref(!0),d=e.ref(null),o=e.ref([]),_=e.ref(0),g=e.ref(null),u=e.ref("google_ads"),D=t=>t.label||t.query||t.sessionGoogleAdsQuery||t.landingPagePlusQueryString||"—";function B(){const t=i.resolvedArgs?._cachedData;return t?(u.value=t.source||"google_ads",t.source==="search_console"?o.value=(t.searchTerms||[]).map(s=>({label:s.term,clicks:s.clicks,impressions:s.impressions,ctr:s.ctr,position:s.position})):o.value=(t.searchTerms||[]).map(s=>({label:s.term,sessions:s.sessions,totalUsers:s.users,engagementRate:parseFloat(s.engagementRate)/100})),_.value=t.count||o.value.length,g.value=i.resolvedArgs._fetchedAt||null,m.value=!1,!0):!1}async function $(){const{startDate:t,endDate:s}=i.resolvedArgs||{};m.value=!0,d.value=null;try{const a=new URLSearchParams;t&&a.set("startDate",t),s&&a.set("endDate",s);const n=await T.get(`/content/search-terms?${a.toString()}`),l=n.source||"google_ads";if(u.value=l,l==="search_console")o.value=(n.rows||[]).map(r=>({...r,label:r.query}));else{const r=l==="organic_landing_pages"?"landingPagePlusQueryString":"sessionGoogleAdsQuery";o.value=(n.rows||[]).map(f=>({...f,label:f[r]}))}_.value=n.rowCount||o.value.length,g.value=new Date().toISOString();const F=()=>{if(o.value.length===0)return"No search data found for this period.";const r=o.value.slice(0,5).map(f=>f.label).join(", ");return l==="search_console"?`Found ${o.value.length} search queries from Google Search Console. The top keywords are: ${r}.`:l==="organic_landing_pages"?`Found ${o.value.length} pages receiving organic search traffic. The top organic landing pages are: ${r}.`:`Found ${o.value.length} search terms. The top keywords driving traffic are: ${r}.`},P=o.value.map(r=>l==="search_console"?{term:r.label,clicks:r.clicks,impressions:r.impressions,ctr:r.ctr,position:r.position}:{term:r.label,sessions:r.sessions,users:r.totalUsers,engagementRate:`${(r.engagementRate*100).toFixed(1)}%`});v({count:o.value.length,source:l,searchTerms:P,suggestion:F()})}catch(a){d.value=a?.data?.statusMessage||a?.message||"Failed to load search data",v(`Error loading search data: ${d.value}`)}finally{m.value=!1}}e.onMounted(()=>{i.status==="completed"&&B()||$()});function v(t){i.status!=="completed"&&S("submit",t)}const p=t=>t==null?"0":Math.round(t).toLocaleString(),y=t=>t==null?"0%":`${(t*100).toFixed(1)}%`,w=t=>t==null?"—":t.toFixed(1),C=t=>t?new Date(t).toLocaleString(void 0,{month:"short",day:"numeric",hour:"2-digit",minute:"2-digit"}):"",h=e.computed(()=>u.value==="search_console"),L=e.computed(()=>o.value.length===0?1:h.value?Math.max(...o.value.map(t=>t.clicks||0)):Math.max(...o.value.map(t=>t.sessions||0))),A=e.computed(()=>u.value==="search_console"?"Search Keywords (Search Console)":u.value==="organic_landing_pages"?"Top Organic Landing Pages":"Search Terms & Keywords"),z=e.computed(()=>{const{startDate:t,endDate:s}=i.resolvedArgs||{};if(!t&&!s)return"Last 30 days";const a=t||"30daysAgo",n=a.match(/^(\d+)daysAgo$/);return n?`Last ${n[1]} days`:`${a} → ${s||"today"}`});return(t,s)=>{const a=e.resolveComponent("NuxtLink");return e.openBlock(),e.createElementBlock("div",M,[e.unref(m)?(e.openBlock(),e.createElementBlock("div",R,[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 search data…",-1))])):e.unref(d)?(e.openBlock(),e.createElementBlock("div",U,e.toDisplayString(e.unref(d)),1)):e.unref(o).length===0?(e.openBlock(),e.createElementBlock("div",j,[e.createVNode(e.unref(c.Search),{class:"size-8 text-muted-foreground mx-auto"}),s[1]||(s[1]=e.createElementVNode("p",{class:"text-sm text-muted-foreground"},"No search data found for this period.",-1))])):(e.openBlock(),e.createElementBlock("div",q,[e.createElementVNode("div",G,[e.createElementVNode("div",I,[e.createVNode(e.unref(c.Search),{class:"size-3.5 text-primary"}),e.createElementVNode("span",Q,e.toDisplayString(e.unref(A)),1)]),e.createElementVNode("span",K,e.toDisplayString(e.unref(z)),1)]),e.createElementVNode("div",O,[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(e.unref(o),(n,l)=>(e.openBlock(),e.createElementBlock("div",{key:l,class:"px-3 py-2.5 hover:bg-muted/30 transition-colors"},[e.createElementVNode("div",H,[e.createElementVNode("span",J,e.toDisplayString(l+1)+".",1),e.createElementVNode("span",W,e.toDisplayString(D(n)),1)]),e.createElementVNode("div",X,[e.createElementVNode("div",Y,[e.createElementVNode("div",{class:"h-full rounded-full bg-amber-500/70 transition-all",style:e.normalizeStyle({width:`${((e.unref(h)?n.clicks:n.sessions)||0)/e.unref(L)*100}%`})},null,4)]),e.unref(h)?(e.openBlock(),e.createElementBlock("div",Z,[e.createElementVNode("span",ee,[e.createVNode(e.unref(c.MousePointerClick),{class:"size-2.5"}),e.createTextVNode(" "+e.toDisplayString(p(n.clicks))+" clicks ",1)]),e.createElementVNode("span",te,[e.createVNode(e.unref(c.Eye),{class:"size-2.5"}),e.createTextVNode(" "+e.toDisplayString(p(n.impressions))+" impr. ",1)]),e.createElementVNode("span",se,[e.createVNode(e.unref(c.TrendingUp),{class:"size-2.5"}),e.createTextVNode(" "+e.toDisplayString(y(n.ctr))+" CTR ",1)]),e.createElementVNode("span",oe,[e.createVNode(e.unref(c.Hash),{class:"size-2.5"}),e.createTextVNode(" pos "+e.toDisplayString(w(n.position)),1)])])):(e.openBlock(),e.createElementBlock("div",ne,[e.createElementVNode("span",re,[e.createVNode(e.unref(c.MousePointerClick),{class:"size-2.5"}),e.createTextVNode(" "+e.toDisplayString(p(n.sessions))+" sessions ",1)]),e.createElementVNode("span",ae,[e.createVNode(e.unref(c.Users),{class:"size-2.5"}),e.createTextVNode(" "+e.toDisplayString(p(n.totalUsers))+" users ",1)]),e.createElementVNode("span",ce,[e.createVNode(e.unref(c.TrendingUp),{class:"size-2.5"}),e.createTextVNode(" "+e.toDisplayString(y(n.engagementRate))+" engaged ",1)])]))])]))),128))]),e.createElementVNode("div",le,[e.createElementVNode("span",ie,[e.createTextVNode(e.toDisplayString(e.unref(o).length)+" result"+e.toDisplayString(e.unref(o).length===1?"":"s")+" ",1),e.unref(g)?(e.openBlock(),e.createElementBlock(e.Fragment,{key:0},[e.createTextVNode(" · fetched "+e.toDisplayString(C(e.unref(g))),1)],64)):e.createCommentVNode("",!0)]),e.createVNode(a,{to:`/projects/${e.unref(E)}/modules/${x.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[2]||(s[2]=e.createTextVNode(" View full report ",-1))]),_:1},8,["to"])])]))])}}});exports.default=de;
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import { defineComponent as
|
|
2
|
-
import { Loader2 as
|
|
3
|
-
import { useRoute as ae, useModuleApi as re } from "@oneclick.dev/cms-kit";
|
|
1
|
+
import { defineComponent as J, computed as _, ref as h, onMounted as W, resolveComponent as X, openBlock as u, createElementBlock as m, unref as s, createVNode as l, createElementVNode as o, toDisplayString as i, Fragment as A, renderList as Y, normalizeStyle as Z, createTextVNode as g, createCommentVNode as ee, withCtx as se } from "vue";
|
|
2
|
+
import { Loader2 as te, Search as C, MousePointerClick as z, Eye as oe, TrendingUp as N, Hash as ne, Users as ae, ExternalLink as re } from "lucide-vue-next";
|
|
4
3
|
const ie = { class: "w-full" }, le = {
|
|
5
4
|
key: 0,
|
|
6
5
|
class: "flex items-center gap-2 py-3"
|
|
@@ -13,13 +12,13 @@ const ie = { class: "w-full" }, le = {
|
|
|
13
12
|
}, ue = {
|
|
14
13
|
key: 3,
|
|
15
14
|
class: "rounded-xl border bg-background overflow-hidden"
|
|
16
|
-
}, me = { class: "px-3 py-2 border-b bg-muted/40 flex items-center justify-between" }, ge = { class: "flex items-center gap-2" }, pe = { class: "text-xs font-medium" },
|
|
15
|
+
}, me = { class: "px-3 py-2 border-b bg-muted/40 flex items-center justify-between" }, ge = { class: "flex items-center gap-2" }, pe = { class: "text-xs font-medium" }, he = { class: "text-[10px] text-muted-foreground" }, fe = { class: "divide-y" }, xe = { class: "flex items-center gap-2 mb-1.5" }, _e = { class: "text-[10px] font-medium text-muted-foreground w-5 text-right shrink-0" }, ve = { class: "text-xs font-medium truncate flex-1" }, ye = { class: "ml-7 space-y-1.5" }, be = { class: "h-1.5 rounded-full bg-muted overflow-hidden" }, ke = {
|
|
17
16
|
key: 0,
|
|
18
17
|
class: "flex items-center gap-3 text-[10px] text-muted-foreground"
|
|
19
|
-
}, Se = { class: "flex items-center gap-1" },
|
|
18
|
+
}, Se = { class: "flex items-center gap-1" }, $e = { class: "flex items-center gap-1" }, Te = { class: "flex items-center gap-1" }, we = { class: "flex items-center gap-1" }, Le = {
|
|
20
19
|
key: 1,
|
|
21
20
|
class: "flex items-center gap-3 text-[10px] text-muted-foreground"
|
|
22
|
-
},
|
|
21
|
+
}, Ae = { class: "flex items-center gap-1" }, Ce = { class: "flex items-center gap-1" }, ze = { class: "flex items-center gap-1" }, Ne = { class: "px-3 py-2 border-t bg-muted/20 flex items-center justify-between" }, De = { class: "text-[10px] text-muted-foreground" }, Me = /* @__PURE__ */ J({
|
|
23
22
|
__name: "SearchTermsCard",
|
|
24
23
|
props: {
|
|
25
24
|
toolName: {},
|
|
@@ -30,9 +29,9 @@ const ie = { class: "w-full" }, le = {
|
|
|
30
29
|
status: {}
|
|
31
30
|
},
|
|
32
31
|
emits: ["submit"],
|
|
33
|
-
setup(
|
|
34
|
-
const
|
|
35
|
-
function
|
|
32
|
+
setup($, { emit: D }) {
|
|
33
|
+
const { $useRoute: F, $useModuleApi: P } = useNuxtApp(), p = $, M = D, R = F(), U = _(() => R.params.slug), j = P(p.instanceId), v = h(!0), f = h(null), n = h([]), T = h(0), y = h(null), x = h("google_ads"), E = (e) => e.label || e.query || e.sessionGoogleAdsQuery || e.landingPagePlusQueryString || "—";
|
|
34
|
+
function V() {
|
|
36
35
|
const e = p.resolvedArgs?._cachedData;
|
|
37
36
|
return e ? (x.value = e.source || "google_ads", e.source === "search_console" ? n.value = (e.searchTerms || []).map((t) => ({
|
|
38
37
|
label: t.term,
|
|
@@ -45,15 +44,15 @@ const ie = { class: "w-full" }, le = {
|
|
|
45
44
|
sessions: t.sessions,
|
|
46
45
|
totalUsers: t.users,
|
|
47
46
|
engagementRate: parseFloat(t.engagementRate) / 100
|
|
48
|
-
})),
|
|
47
|
+
})), T.value = e.count || n.value.length, y.value = p.resolvedArgs._fetchedAt || null, v.value = !1, !0) : !1;
|
|
49
48
|
}
|
|
50
|
-
async function
|
|
49
|
+
async function G() {
|
|
51
50
|
const { startDate: e, endDate: t } = p.resolvedArgs || {};
|
|
52
|
-
v.value = !0,
|
|
51
|
+
v.value = !0, f.value = null;
|
|
53
52
|
try {
|
|
54
53
|
const c = new URLSearchParams();
|
|
55
54
|
e && c.set("startDate", e), t && c.set("endDate", t);
|
|
56
|
-
const a = await
|
|
55
|
+
const a = await j.get(`/content/search-terms?${c.toString()}`), d = a.source || "google_ads";
|
|
57
56
|
if (x.value = d, d === "search_console")
|
|
58
57
|
n.value = (a.rows || []).map((r) => ({
|
|
59
58
|
...r,
|
|
@@ -66,12 +65,12 @@ const ie = { class: "w-full" }, le = {
|
|
|
66
65
|
label: k[r]
|
|
67
66
|
}));
|
|
68
67
|
}
|
|
69
|
-
|
|
70
|
-
const
|
|
68
|
+
T.value = a.rowCount || n.value.length, y.value = (/* @__PURE__ */ new Date()).toISOString();
|
|
69
|
+
const O = () => {
|
|
71
70
|
if (n.value.length === 0) return "No search data found for this period.";
|
|
72
71
|
const r = n.value.slice(0, 5).map((k) => k.label).join(", ");
|
|
73
72
|
return d === "search_console" ? `Found ${n.value.length} search queries from Google Search Console. The top keywords are: ${r}.` : d === "organic_landing_pages" ? `Found ${n.value.length} pages receiving organic search traffic. The top organic landing pages are: ${r}.` : `Found ${n.value.length} search terms. The top keywords driving traffic are: ${r}.`;
|
|
74
|
-
},
|
|
73
|
+
}, H = n.value.map((r) => d === "search_console" ? {
|
|
75
74
|
term: r.label,
|
|
76
75
|
clicks: r.clicks,
|
|
77
76
|
impressions: r.impressions,
|
|
@@ -86,87 +85,87 @@ const ie = { class: "w-full" }, le = {
|
|
|
86
85
|
w({
|
|
87
86
|
count: n.value.length,
|
|
88
87
|
source: d,
|
|
89
|
-
searchTerms:
|
|
90
|
-
suggestion:
|
|
88
|
+
searchTerms: H,
|
|
89
|
+
suggestion: O()
|
|
91
90
|
});
|
|
92
91
|
} catch (c) {
|
|
93
|
-
|
|
92
|
+
f.value = c?.data?.statusMessage || c?.message || "Failed to load search data", w(`Error loading search data: ${f.value}`);
|
|
94
93
|
} finally {
|
|
95
94
|
v.value = !1;
|
|
96
95
|
}
|
|
97
96
|
}
|
|
98
|
-
|
|
99
|
-
p.status === "completed" &&
|
|
97
|
+
W(() => {
|
|
98
|
+
p.status === "completed" && V() || G();
|
|
100
99
|
});
|
|
101
100
|
function w(e) {
|
|
102
|
-
p.status !== "completed" &&
|
|
101
|
+
p.status !== "completed" && M("submit", e);
|
|
103
102
|
}
|
|
104
|
-
const b = (e) => e == null ? "0" : Math.round(e).toLocaleString(), L = (e) => e == null ? "0%" : `${(e * 100).toFixed(1)}%`,
|
|
103
|
+
const b = (e) => e == null ? "0" : Math.round(e).toLocaleString(), L = (e) => e == null ? "0%" : `${(e * 100).toFixed(1)}%`, I = (e) => e == null ? "—" : e.toFixed(1), Q = (e) => e ? new Date(e).toLocaleString(void 0, { month: "short", day: "numeric", hour: "2-digit", minute: "2-digit" }) : "", S = _(() => x.value === "search_console"), q = _(() => n.value.length === 0 ? 1 : S.value ? Math.max(...n.value.map((e) => e.clicks || 0)) : Math.max(...n.value.map((e) => e.sessions || 0))), K = _(() => x.value === "search_console" ? "Search Keywords (Search Console)" : x.value === "organic_landing_pages" ? "Top Organic Landing Pages" : "Search Terms & Keywords"), B = _(() => {
|
|
105
104
|
const { startDate: e, endDate: t } = p.resolvedArgs || {};
|
|
106
105
|
if (!e && !t) return "Last 30 days";
|
|
107
106
|
const c = e || "30daysAgo", a = c.match(/^(\d+)daysAgo$/);
|
|
108
107
|
return a ? `Last ${a[1]} days` : `${c} → ${t || "today"}`;
|
|
109
108
|
});
|
|
110
109
|
return (e, t) => {
|
|
111
|
-
const c =
|
|
110
|
+
const c = X("NuxtLink");
|
|
112
111
|
return u(), m("div", ie, [
|
|
113
112
|
s(v) ? (u(), m("div", le, [
|
|
114
|
-
l(s(
|
|
113
|
+
l(s(te), { class: "size-4 animate-spin text-muted-foreground" }),
|
|
115
114
|
t[0] || (t[0] = o("span", { class: "text-xs text-muted-foreground" }, "Loading search data…", -1))
|
|
116
|
-
])) : s(
|
|
117
|
-
l(s(
|
|
115
|
+
])) : s(f) ? (u(), m("div", ce, i(s(f)), 1)) : s(n).length === 0 ? (u(), m("div", de, [
|
|
116
|
+
l(s(C), { class: "size-8 text-muted-foreground mx-auto" }),
|
|
118
117
|
t[1] || (t[1] = o("p", { class: "text-sm text-muted-foreground" }, "No search data found for this period.", -1))
|
|
119
118
|
])) : (u(), m("div", ue, [
|
|
120
119
|
o("div", me, [
|
|
121
120
|
o("div", ge, [
|
|
122
|
-
l(s(
|
|
123
|
-
o("span", pe, i(s(
|
|
121
|
+
l(s(C), { class: "size-3.5 text-primary" }),
|
|
122
|
+
o("span", pe, i(s(K)), 1)
|
|
124
123
|
]),
|
|
125
|
-
o("span",
|
|
124
|
+
o("span", he, i(s(B)), 1)
|
|
126
125
|
]),
|
|
127
|
-
o("div",
|
|
128
|
-
(u(!0), m(
|
|
126
|
+
o("div", fe, [
|
|
127
|
+
(u(!0), m(A, null, Y(s(n), (a, d) => (u(), m("div", {
|
|
129
128
|
key: d,
|
|
130
129
|
class: "px-3 py-2.5 hover:bg-muted/30 transition-colors"
|
|
131
130
|
}, [
|
|
132
131
|
o("div", xe, [
|
|
133
132
|
o("span", _e, i(d + 1) + ".", 1),
|
|
134
|
-
o("span", ve, i(
|
|
133
|
+
o("span", ve, i(E(a)), 1)
|
|
135
134
|
]),
|
|
136
135
|
o("div", ye, [
|
|
137
136
|
o("div", be, [
|
|
138
137
|
o("div", {
|
|
139
138
|
class: "h-full rounded-full bg-amber-500/70 transition-all",
|
|
140
|
-
style:
|
|
139
|
+
style: Z({ width: `${((s(S) ? a.clicks : a.sessions) || 0) / s(q) * 100}%` })
|
|
141
140
|
}, null, 4)
|
|
142
141
|
]),
|
|
143
142
|
s(S) ? (u(), m("div", ke, [
|
|
144
143
|
o("span", Se, [
|
|
145
|
-
l(s(
|
|
144
|
+
l(s(z), { class: "size-2.5" }),
|
|
146
145
|
g(" " + i(b(a.clicks)) + " clicks ", 1)
|
|
147
146
|
]),
|
|
148
|
-
o("span",
|
|
149
|
-
l(s(
|
|
147
|
+
o("span", $e, [
|
|
148
|
+
l(s(oe), { class: "size-2.5" }),
|
|
150
149
|
g(" " + i(b(a.impressions)) + " impr. ", 1)
|
|
151
150
|
]),
|
|
152
|
-
o("span",
|
|
151
|
+
o("span", Te, [
|
|
153
152
|
l(s(N), { class: "size-2.5" }),
|
|
154
153
|
g(" " + i(L(a.ctr)) + " CTR ", 1)
|
|
155
154
|
]),
|
|
156
155
|
o("span", we, [
|
|
157
|
-
l(s(
|
|
158
|
-
g(" pos " + i(
|
|
156
|
+
l(s(ne), { class: "size-2.5" }),
|
|
157
|
+
g(" pos " + i(I(a.position)), 1)
|
|
159
158
|
])
|
|
160
159
|
])) : (u(), m("div", Le, [
|
|
161
|
-
o("span",
|
|
162
|
-
l(s(
|
|
160
|
+
o("span", Ae, [
|
|
161
|
+
l(s(z), { class: "size-2.5" }),
|
|
163
162
|
g(" " + i(b(a.sessions)) + " sessions ", 1)
|
|
164
163
|
]),
|
|
165
|
-
o("span",
|
|
166
|
-
l(s(
|
|
164
|
+
o("span", Ce, [
|
|
165
|
+
l(s(ae), { class: "size-2.5" }),
|
|
167
166
|
g(" " + i(b(a.totalUsers)) + " users ", 1)
|
|
168
167
|
]),
|
|
169
|
-
o("span",
|
|
168
|
+
o("span", ze, [
|
|
170
169
|
l(s(N), { class: "size-2.5" }),
|
|
171
170
|
g(" " + i(L(a.engagementRate)) + " engaged ", 1)
|
|
172
171
|
])
|
|
@@ -177,16 +176,16 @@ const ie = { class: "w-full" }, le = {
|
|
|
177
176
|
o("div", Ne, [
|
|
178
177
|
o("span", De, [
|
|
179
178
|
g(i(s(n).length) + " result" + i(s(n).length === 1 ? "" : "s") + " ", 1),
|
|
180
|
-
s(y) ? (u(), m(
|
|
181
|
-
g(" · fetched " + i(
|
|
182
|
-
], 64)) :
|
|
179
|
+
s(y) ? (u(), m(A, { key: 0 }, [
|
|
180
|
+
g(" · fetched " + i(Q(s(y))), 1)
|
|
181
|
+
], 64)) : ee("", !0)
|
|
183
182
|
]),
|
|
184
183
|
l(c, {
|
|
185
|
-
to: `/projects/${s(
|
|
184
|
+
to: `/projects/${s(U)}/modules/${$.instanceId}`,
|
|
186
185
|
class: "inline-flex items-center gap-1.5 text-xs text-primary hover:underline"
|
|
187
186
|
}, {
|
|
188
|
-
default:
|
|
189
|
-
l(s(
|
|
187
|
+
default: se(() => [
|
|
188
|
+
l(s(re), { class: "size-3" }),
|
|
190
189
|
t[2] || (t[2] = g(" View full report ", -1))
|
|
191
190
|
]),
|
|
192
191
|
_: 1
|
|
@@ -198,5 +197,5 @@ const ie = { class: "w-full" }, le = {
|
|
|
198
197
|
}
|
|
199
198
|
});
|
|
200
199
|
export {
|
|
201
|
-
|
|
200
|
+
Me as default
|
|
202
201
|
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("vue"),c=require("lucide-vue-next"),T={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"},M={key:3,class:"rounded-xl border bg-background overflow-hidden"},C={class:"px-3 py-2 border-b bg-muted/40 flex items-center justify-between"},z={class:"flex items-center gap-2"},F={class:"text-[10px] text-muted-foreground"},I={class:"divide-y"},j={class:"flex items-center gap-2 mb-1.5"},U={class:"text-[10px] font-medium text-muted-foreground w-5 text-right shrink-0"},q=["title"],O={class:"ml-7 space-y-1.5"},R={class:"h-1.5 rounded-full bg-muted overflow-hidden"},G={class:"flex items-center gap-3 text-[10px] text-muted-foreground"},H={class:"flex items-center gap-1"},J={class:"flex items-center gap-1"},K={class:"flex items-center gap-1"},Q={class:"px-3 py-2 border-t bg-muted/20 flex items-center justify-between"},W={class:"text-[10px] text-muted-foreground"},X=e.defineComponent({__name:"TopPagesCard",props:{toolName:{},instanceId:{},instanceName:{},moduleType:{},resolvedArgs:{},status:{}},emits:["submit"],setup(f,{emit:h}){const{$useRoute:y,$useModuleApi:N}=useNuxtApp(),l=f,V=h,_=y(),k=e.computed(()=>_.params.slug),E=N(l.instanceId),d=e.ref(!0),i=e.ref(null),a=e.ref([]),u=e.ref(0),m=e.ref(null);function b(){const t=l.resolvedArgs?._cachedData;return t?(a.value=t.pages?.map(s=>({pagePath:s.page,screenPageViews:s.views,totalUsers:s.users,averageSessionDuration:D(s.avgDuration)}))||[],u.value=t.totalPagesTracked||a.value.length,m.value=l.resolvedArgs._fetchedAt||null,d.value=!1,!0):!1}function D(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 w(){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 E.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"&&b()||w()});function x(t){l.status!=="completed"&&V("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(),S=t=>t?new Date(t).toLocaleString(void 0,{month:"short",day:"numeric",hour:"2-digit",minute:"2-digit"}):"",P=e.computed(()=>a.value.length===0?1:Math.max(...a.value.map(t=>t.screenPageViews||0))),B=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",T,[e.unref(d)?(e.openBlock(),e.createElementBlock("div",$,[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",L,e.toDisplayString(e.unref(i)),1)):e.unref(a).length===0?(e.openBlock(),e.createElementBlock("div",A,[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",M,[e.createElementVNode("div",C,[e.createElementVNode("div",z,[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",F,e.toDisplayString(e.unref(B)),1)]),e.createElementVNode("div",I,[(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",j,[e.createElementVNode("span",U,e.toDisplayString(r+1)+".",1),e.createElementVNode("span",{class:"text-xs font-medium truncate flex-1",title:o.pagePath},e.toDisplayString(o.pagePath),9,q)]),e.createElementVNode("div",O,[e.createElementVNode("div",R,[e.createElementVNode("div",{class:"h-full rounded-full bg-primary/70 transition-all",style:e.normalizeStyle({width:`${(o.screenPageViews||0)/e.unref(P)*100}%`})},null,4)]),e.createElementVNode("div",G,[e.createElementVNode("span",H,[e.createVNode(e.unref(c.Eye),{class:"size-2.5"}),e.createTextVNode(" "+e.toDisplayString(g(o.screenPageViews))+" views ",1)]),e.createElementVNode("span",J,[e.createVNode(e.unref(c.Users),{class:"size-2.5"}),e.createTextVNode(" "+e.toDisplayString(g(o.totalUsers))+" users ",1)]),e.createElementVNode("span",K,[e.createVNode(e.unref(c.Clock),{class:"size-2.5"}),e.createTextVNode(" "+e.toDisplayString(v(o.averageSessionDuration)),1)])])])]))),128))]),e.createElementVNode("div",Q,[e.createElementVNode("span",W,[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(S(e.unref(m))),1)],64)):e.createCommentVNode("",!0)]),e.createVNode(n,{to:`/projects/${e.unref(k)}/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=X;
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import { defineComponent as
|
|
2
|
-
import { Loader2 as
|
|
3
|
-
import { useRoute as W, useModuleApi as X } from "@oneclick.dev/cms-kit";
|
|
1
|
+
import { defineComponent as F, computed as w, ref as f, onMounted as B, resolveComponent as R, 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 q, createTextVNode as g, createCommentVNode as G, withCtx as H } from "vue";
|
|
2
|
+
import { Loader2 as J, FileText as S, Eye as K, Users as Q, Clock as W, ExternalLink as X } from "lucide-vue-next";
|
|
4
3
|
const Y = { class: "w-full" }, Z = {
|
|
5
4
|
key: 0,
|
|
6
5
|
class: "flex items-center gap-2 py-3"
|
|
@@ -13,7 +12,7 @@ const Y = { class: "w-full" }, Z = {
|
|
|
13
12
|
}, se = {
|
|
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"],
|
|
15
|
+
}, 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"], ue = { class: "ml-7 space-y-1.5" }, ce = { 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" }, ye = /* @__PURE__ */ F({
|
|
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,
|
|
29
|
-
function
|
|
26
|
+
setup(b, { emit: $ }) {
|
|
27
|
+
const { $useRoute: L, $useModuleApi: A } = useNuxtApp(), m = b, N = $, V = L(), C = w(() => V.params.slug), M = A(m.instanceId), x = f(!0), p = f(null), r = f([]), v = f(0), h = f(null);
|
|
28
|
+
function T() {
|
|
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: z(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 z(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 I() {
|
|
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,41 +62,41 @@ const Y = { class: "w-full" }, Z = {
|
|
|
63
62
|
x.value = !1;
|
|
64
63
|
}
|
|
65
64
|
}
|
|
66
|
-
|
|
67
|
-
m.status === "completed" &&
|
|
65
|
+
B(() => {
|
|
66
|
+
m.status === "completed" && T() || I();
|
|
68
67
|
});
|
|
69
68
|
function k(e) {
|
|
70
|
-
m.status !== "completed" &&
|
|
69
|
+
m.status !== "completed" && N("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(), E = (e) => e ? new Date(e).toLocaleString(void 0, { month: "short", day: "numeric", hour: "2-digit", minute: "2-digit" }) : "", U = w(() => r.value.length === 0 ? 1 : Math.max(...r.value.map((e) => e.screenPageViews || 0))), j = 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 = R("NuxtLink");
|
|
83
|
+
return d(), u("div", Y, [
|
|
84
|
+
s(x) ? (d(), u("div", Z, [
|
|
85
|
+
c(s(J), { 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", ee, i(s(p)), 1)) : s(r).length === 0 ? (d(), u("div", te, [
|
|
88
|
+
c(s(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(),
|
|
90
|
+
])) : (d(), u("div", se, [
|
|
92
91
|
a("div", ae, [
|
|
93
92
|
a("div", oe, [
|
|
94
|
-
|
|
93
|
+
c(s(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(
|
|
96
|
+
a("span", ne, i(s(j)), 1)
|
|
98
97
|
]),
|
|
99
98
|
a("div", re, [
|
|
100
|
-
(d(!0),
|
|
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
|
}, [
|
|
@@ -108,24 +107,24 @@ const Y = { class: "w-full" }, Z = {
|
|
|
108
107
|
title: o.pagePath
|
|
109
108
|
}, i(o.pagePath), 9, de)
|
|
110
109
|
]),
|
|
111
|
-
a("div",
|
|
112
|
-
a("div",
|
|
110
|
+
a("div", ue, [
|
|
111
|
+
a("div", ce, [
|
|
113
112
|
a("div", {
|
|
114
113
|
class: "h-full rounded-full bg-primary/70 transition-all",
|
|
115
|
-
style:
|
|
114
|
+
style: q({ width: `${(o.screenPageViews || 0) / s(U) * 100}%` })
|
|
116
115
|
}, null, 4)
|
|
117
116
|
]),
|
|
118
117
|
a("div", me, [
|
|
119
118
|
a("span", ge, [
|
|
120
|
-
|
|
119
|
+
c(s(K), { class: "size-2.5" }),
|
|
121
120
|
g(" " + i(y(o.screenPageViews)) + " views ", 1)
|
|
122
121
|
]),
|
|
123
122
|
a("span", pe, [
|
|
124
|
-
|
|
123
|
+
c(s(Q), { class: "size-2.5" }),
|
|
125
124
|
g(" " + i(y(o.totalUsers)) + " users ", 1)
|
|
126
125
|
]),
|
|
127
126
|
a("span", fe, [
|
|
128
|
-
|
|
127
|
+
c(s(W), { class: "size-2.5" }),
|
|
129
128
|
g(" " + i(D(o.averageSessionDuration)), 1)
|
|
130
129
|
])
|
|
131
130
|
])
|
|
@@ -135,16 +134,16 @@ const Y = { class: "w-full" }, Z = {
|
|
|
135
134
|
a("div", xe, [
|
|
136
135
|
a("span", ve, [
|
|
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(E(s(h))), 1)
|
|
139
|
+
], 64)) : G("", !0)
|
|
141
140
|
]),
|
|
142
|
-
|
|
143
|
-
to: `/projects/${s(
|
|
141
|
+
c(n, {
|
|
142
|
+
to: `/projects/${s(C)}/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: H(() => [
|
|
146
|
+
c(s(X), { 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
|
};
|