@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.
Files changed (36) hide show
  1. package/dist/{AppointmentDetailsCard-SMNXi117.mjs → AppointmentDetailsCard-33WpATpV.mjs} +42 -43
  2. package/dist/AppointmentDetailsCard-DpLM5IrB.js +1 -0
  3. package/dist/AppointmentListTable-CQ0WIXtj.js +1 -0
  4. package/dist/{AppointmentListTable-vMSMt0M5.mjs → AppointmentListTable-aV_UJd6j.mjs} +24 -25
  5. package/dist/CountryBreakdownCard-D7BK3nRD.js +1 -0
  6. package/dist/{CountryBreakdownCard-B_VhBsm8.mjs → CountryBreakdownCard-DVxNz2DJ.mjs} +29 -30
  7. package/dist/DeviceBreakdownCard-DRhQ9ufG.js +1 -0
  8. package/dist/{DeviceBreakdownCard-CQR65Zr_.mjs → DeviceBreakdownCard-W1frLe0L.mjs} +57 -58
  9. package/dist/{PeakHoursCard-_1JS0tpZ.mjs → PeakHoursCard-9-EZFZLR.mjs} +27 -28
  10. package/dist/PeakHoursCard-BR5zmta4.js +1 -0
  11. package/dist/{ProductDetailsCard-C5gqBJag.mjs → ProductDetailsCard-6nHikw4V.mjs} +22 -23
  12. package/dist/ProductDetailsCard-Bn7qrgmc.js +1 -0
  13. package/dist/RealtimeCard--APfRNc8.js +1 -0
  14. package/dist/{RealtimeCard-CtX6Yyk-.mjs → RealtimeCard-fvQlJcM7.mjs} +35 -36
  15. package/dist/SearchTermsCard-BsB-63aH.js +1 -0
  16. package/dist/{SearchTermsCard-DzSu9jzo.mjs → SearchTermsCard-BzVrHKqQ.mjs} +51 -52
  17. package/dist/TopPagesCard-BDeA997A.js +1 -0
  18. package/dist/{TopPagesCard-D7lH_QYV.mjs → TopPagesCard-CTozhOr_.mjs} +38 -39
  19. package/dist/{TrafficSourcesCard-Fng3fVh7.mjs → TrafficSourcesCard-BxtCKsqx.mjs} +57 -58
  20. package/dist/TrafficSourcesCard-C3ziDTUL.js +1 -0
  21. package/dist/VisitorStatsCard-BmByE_Hi.js +1 -0
  22. package/dist/{VisitorStatsCard-CuXXnMBc.mjs → VisitorStatsCard-CXizEbVK.mjs} +37 -38
  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-Cpcj75Rv.js +0 -1
  30. package/dist/PeakHoursCard-CFIg8dys.js +0 -1
  31. package/dist/ProductDetailsCard-Ce11f_9r.js +0 -1
  32. package/dist/RealtimeCard-CatAzdxv.js +0 -1
  33. package/dist/SearchTermsCard-BPAdRL-r.js +0 -1
  34. package/dist/TopPagesCard-BA9Are_Z.js +0 -1
  35. package/dist/TrafficSourcesCard-DV13ZOBq.js +0 -1
  36. package/dist/VisitorStatsCard-CAzAZtKD.js +0 -1
@@ -1,6 +1,5 @@
1
- import { defineComponent as T, computed as A, ref as x, onMounted as L, resolveComponent as $, openBlock as d, createElementBlock as l, unref as r, createVNode as i, createElementVNode as t, toDisplayString as o, Fragment as j, renderList as P, normalizeClass as E, createCommentVNode as M, withCtx as V, createTextVNode as D } from "vue";
2
- import { Loader2 as F, CalendarDays as g, Mail as R, Clock as B, Users as U, ExternalLink as O } from "lucide-vue-next";
3
- import { useRoute as q, useModuleApi as G } from "@oneclick.dev/cms-kit";
1
+ import { defineComponent as T, computed as L, ref as x, onMounted as j, resolveComponent as P, openBlock as d, createElementBlock as l, unref as r, createVNode as i, createElementVNode as t, toDisplayString as a, Fragment as E, renderList as M, normalizeClass as V, createCommentVNode as D, withCtx as F, createTextVNode as R } from "vue";
2
+ import { Loader2 as B, CalendarDays as g, Mail as U, Clock as O, Users as q, ExternalLink as G } from "lucide-vue-next";
4
3
  const H = { class: "w-full" }, J = {
5
4
  key: 0,
6
5
  class: "flex items-center gap-2 py-3"
@@ -16,7 +15,7 @@ const H = { class: "w-full" }, J = {
16
15
  }, X = { class: "flex items-start gap-3" }, Y = { class: "shrink-0 size-10 rounded-lg bg-primary/10 flex items-center justify-center" }, Z = { class: "flex-1 min-w-0" }, ee = { class: "text-sm font-semibold truncate" }, te = { class: "flex items-center gap-2 mt-1 flex-wrap" }, se = {
17
16
  key: 0,
18
17
  class: "text-xs font-medium"
19
- }, re = { class: "grid grid-cols-2 gap-2 text-xs text-muted-foreground" }, ne = { class: "flex items-center gap-1.5" }, oe = { class: "truncate" }, ae = { class: "flex items-center gap-1.5" }, ie = { class: "flex items-center gap-1.5" }, de = { class: "flex items-center gap-1.5" }, ue = /* @__PURE__ */ T({
18
+ }, re = { class: "grid grid-cols-2 gap-2 text-xs text-muted-foreground" }, ne = { class: "flex items-center gap-1.5" }, ae = { class: "truncate" }, oe = { class: "flex items-center gap-1.5" }, ie = { class: "flex items-center gap-1.5" }, de = { class: "flex items-center gap-1.5" }, ue = /* @__PURE__ */ T({
20
19
  __name: "AppointmentDetailsCard",
21
20
  props: {
22
21
  toolName: {},
@@ -28,21 +27,21 @@ const H = { class: "w-full" }, J = {
28
27
  },
29
28
  emits: ["submit"],
30
29
  setup(v, { emit: b }) {
31
- const f = v, h = b, k = q(), y = A(() => k.params.slug), N = G(f.instanceId), p = x(!0), c = x(null), m = x([]);
32
- async function I() {
33
- const { name: s, email: a, date: u } = f.resolvedArgs || {};
34
- if (!u) {
30
+ const { $useRoute: h, $useModuleApi: k } = useNuxtApp(), f = v, y = b, N = h(), I = L(() => N.params.slug), C = k(f.instanceId), p = x(!0), c = x(null), u = x([]);
31
+ async function z() {
32
+ const { name: s, email: o, date: m } = f.resolvedArgs || {};
33
+ if (!m) {
35
34
  c.value = "No date provided", p.value = !1;
36
35
  return;
37
36
  }
38
37
  p.value = !0, c.value = null;
39
38
  try {
40
39
  const e = new URLSearchParams();
41
- s && e.set("name", s), a && e.set("email", a), u && e.set("date", u);
42
- const w = await N.get(`/appointments/find?${e.toString()}`);
43
- m.value = w.appointments || [], _({
44
- count: m.value.length,
45
- appointments: m.value.map((n) => ({
40
+ s && e.set("name", s), o && e.set("email", o), m && e.set("date", m);
41
+ const A = await C.get(`/appointments/find?${e.toString()}`);
42
+ u.value = A.appointments || [], _({
43
+ count: u.value.length,
44
+ appointments: u.value.map((n) => ({
46
45
  orderId: n.orderId,
47
46
  reservationId: n.reservationId,
48
47
  customerName: `${n.customerInfo?.firstName || ""} ${n.customerInfo?.lastName || ""}`.trim(),
@@ -61,13 +60,13 @@ const H = { class: "w-full" }, J = {
61
60
  p.value = !1;
62
61
  }
63
62
  }
64
- L(() => {
65
- I();
63
+ j(() => {
64
+ z();
66
65
  });
67
66
  function _(s) {
68
- f.status !== "completed" && h("submit", s);
67
+ f.status !== "completed" && y("submit", s);
69
68
  }
70
- const C = (s) => {
69
+ const S = (s) => {
71
70
  switch (s) {
72
71
  case "approved":
73
72
  return "text-emerald-600 dark:text-emerald-400 bg-emerald-50 dark:bg-emerald-900/20";
@@ -79,7 +78,7 @@ const H = { class: "w-full" }, J = {
79
78
  default:
80
79
  return "text-amber-600 dark:text-amber-400 bg-amber-50 dark:bg-amber-900/20";
81
80
  }
82
- }, z = (s) => {
81
+ }, $ = (s) => {
83
82
  switch (s) {
84
83
  case "approved":
85
84
  return "Approved";
@@ -94,18 +93,18 @@ const H = { class: "w-full" }, J = {
94
93
  default:
95
94
  return s || "Pending";
96
95
  }
97
- }, S = (s) => s == null ? "" : `€${s.toFixed(2)}`;
98
- return (s, a) => {
99
- const u = $("NuxtLink");
96
+ }, w = (s) => s == null ? "" : `€${s.toFixed(2)}`;
97
+ return (s, o) => {
98
+ const m = P("NuxtLink");
100
99
  return d(), l("div", H, [
101
100
  r(p) ? (d(), l("div", J, [
102
- i(r(F), { class: "size-4 animate-spin text-muted-foreground" }),
103
- a[0] || (a[0] = t("span", { class: "text-xs text-muted-foreground" }, "Searching appointments…", -1))
104
- ])) : r(c) ? (d(), l("div", K, o(r(c)), 1)) : r(m).length === 0 ? (d(), l("div", Q, [
101
+ i(r(B), { class: "size-4 animate-spin text-muted-foreground" }),
102
+ o[0] || (o[0] = t("span", { class: "text-xs text-muted-foreground" }, "Searching appointments…", -1))
103
+ ])) : r(c) ? (d(), l("div", K, a(r(c)), 1)) : r(u).length === 0 ? (d(), l("div", Q, [
105
104
  i(r(g), { class: "size-8 text-muted-foreground mx-auto mb-2" }),
106
- a[1] || (a[1] = t("p", { class: "text-sm text-muted-foreground" }, "No appointments found for the given criteria.", -1))
105
+ o[1] || (o[1] = t("p", { class: "text-sm text-muted-foreground" }, "No appointments found for the given criteria.", -1))
107
106
  ])) : (d(), l("div", W, [
108
- (d(!0), l(j, null, P(r(m), (e) => (d(), l("div", {
107
+ (d(!0), l(E, null, M(r(u), (e) => (d(), l("div", {
109
108
  key: e.reservationId || e.orderId,
110
109
  class: "rounded-xl border bg-background p-3 space-y-3"
111
110
  }, [
@@ -114,40 +113,40 @@ const H = { class: "w-full" }, J = {
114
113
  i(r(g), { class: "size-5 text-primary" })
115
114
  ]),
116
115
  t("div", Z, [
117
- t("p", ee, o(e.customerInfo?.firstName) + " " + o(e.customerInfo?.lastName), 1),
116
+ t("p", ee, a(e.customerInfo?.firstName) + " " + a(e.customerInfo?.lastName), 1),
118
117
  t("div", te, [
119
118
  t("span", {
120
- class: E(["text-[10px] font-medium px-1.5 py-0.5 rounded-full uppercase", C(e.reservationStatus || e.status)])
121
- }, o(z(e.reservationStatus || e.status)), 3),
122
- e.reservationPrice != null ? (d(), l("span", se, o(S(e.reservationPrice)), 1)) : M("", !0)
119
+ class: V(["text-[10px] font-medium px-1.5 py-0.5 rounded-full uppercase", S(e.reservationStatus || e.status)])
120
+ }, a($(e.reservationStatus || e.status)), 3),
121
+ e.reservationPrice != null ? (d(), l("span", se, a(w(e.reservationPrice)), 1)) : D("", !0)
123
122
  ])
124
123
  ])
125
124
  ]),
126
125
  t("div", re, [
127
126
  t("div", ne, [
128
- i(r(R), { class: "size-3" }),
129
- t("span", oe, o(e.customerInfo?.email || "—"), 1)
127
+ i(r(U), { class: "size-3" }),
128
+ t("span", ae, a(e.customerInfo?.email || "—"), 1)
130
129
  ]),
131
- t("div", ae, [
130
+ t("div", oe, [
132
131
  i(r(g), { class: "size-3" }),
133
- t("span", null, o(e.date), 1)
132
+ t("span", null, a(e.date), 1)
134
133
  ]),
135
134
  t("div", ie, [
136
- i(r(B), { class: "size-3" }),
137
- t("span", null, o(e.startTime) + " – " + o(e.endTime), 1)
135
+ i(r(O), { class: "size-3" }),
136
+ t("span", null, a(e.startTime) + " – " + a(e.endTime), 1)
138
137
  ]),
139
138
  t("div", de, [
140
- i(r(U), { class: "size-3" }),
141
- t("span", null, o(e.spots || 1) + " " + o((e.spots || 1) === 1 ? "spot" : "spots"), 1)
139
+ i(r(q), { class: "size-3" }),
140
+ t("span", null, a(e.spots || 1) + " " + a((e.spots || 1) === 1 ? "spot" : "spots"), 1)
142
141
  ])
143
142
  ]),
144
- i(u, {
145
- to: `/projects/${r(y)}/modules/${v.instanceId}`,
143
+ i(m, {
144
+ to: `/projects/${r(I)}/modules/${v.instanceId}`,
146
145
  class: "inline-flex items-center gap-1.5 text-xs text-primary hover:underline"
147
146
  }, {
148
- default: V(() => [
149
- i(r(O), { class: "size-3" }),
150
- a[2] || (a[2] = D(" Open in agenda ", -1))
147
+ default: F(() => [
148
+ i(r(G), { class: "size-3" }),
149
+ o[2] || (o[2] = R(" Open in agenda ", -1))
151
150
  ]),
152
151
  _: 1
153
152
  }, 8, ["to"])
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("vue"),o=require("lucide-vue-next"),h={class:"w-full"},S={key:0,class:"flex items-center gap-2 py-3"},B={key:1,class:"text-xs text-destructive py-2"},D={key:2,class:"rounded-xl border bg-background p-4 text-center"},I={key:3,class:"space-y-3"},C={class:"flex items-start gap-3"},z={class:"shrink-0 size-10 rounded-lg bg-primary/10 flex items-center justify-center"},T={class:"flex-1 min-w-0"},$={class:"text-sm font-semibold truncate"},w={class:"flex items-center gap-2 mt-1 flex-wrap"},A={key:0,class:"text-xs font-medium"},j={class:"grid grid-cols-2 gap-2 text-xs text-muted-foreground"},L={class:"flex items-center gap-1.5"},P={class:"truncate"},M={class:"flex items-center gap-1.5"},F={class:"flex items-center gap-1.5"},R={class:"flex items-center gap-1.5"},q=e.defineComponent({__name:"AppointmentDetailsCard",props:{toolName:{},instanceId:{},instanceName:{},moduleType:{},resolvedArgs:{},status:{}},emits:["submit"],setup(u,{emit:p}){const{$useRoute:f,$useModuleApi:g}=useNuxtApp(),d=u,x=p,v=f(),N=e.computed(()=>v.params.slug),k=g(d.instanceId),c=e.ref(!0),a=e.ref(null),l=e.ref([]);async function _(){const{name:s,email:n,date:i}=d.resolvedArgs||{};if(!i){a.value="No date provided",c.value=!1;return}c.value=!0,a.value=null;try{const t=new URLSearchParams;s&&t.set("name",s),n&&t.set("email",n),i&&t.set("date",i);const E=await k.get(`/appointments/find?${t.toString()}`);l.value=E.appointments||[],m({count:l.value.length,appointments:l.value.map(r=>({orderId:r.orderId,reservationId:r.reservationId,customerName:`${r.customerInfo?.firstName||""} ${r.customerInfo?.lastName||""}`.trim(),email:r.customerInfo?.email,date:r.date,startTime:r.startTime,endTime:r.endTime,spots:r.spots,status:r.reservationStatus||r.status,price:r.reservationPrice}))})}catch(t){a.value=t?.data?.statusMessage||t?.message||"Failed to find appointment",m(`Error finding appointment: ${a.value}`)}finally{c.value=!1}}e.onMounted(()=>{_()});function m(s){d.status!=="completed"&&x("submit",s)}const y=s=>{switch(s){case"approved":return"text-emerald-600 dark:text-emerald-400 bg-emerald-50 dark:bg-emerald-900/20";case"needs_approval":return"text-blue-600 dark:text-blue-400 bg-blue-50 dark:bg-blue-900/20";case"rejected":case"cancelled":return"text-red-600 dark:text-red-400 bg-red-50 dark:bg-red-900/20";default:return"text-amber-600 dark:text-amber-400 bg-amber-50 dark:bg-amber-900/20"}},b=s=>{switch(s){case"approved":return"Approved";case"needs_approval":return"Needs Approval";case"rejected":return"Rejected";case"cancelled":return"Cancelled";case"confirmed":return"Confirmed";default:return s||"Pending"}},V=s=>s==null?"":`€${s.toFixed(2)}`;return(s,n)=>{const i=e.resolveComponent("NuxtLink");return e.openBlock(),e.createElementBlock("div",h,[e.unref(c)?(e.openBlock(),e.createElementBlock("div",S,[e.createVNode(e.unref(o.Loader2),{class:"size-4 animate-spin text-muted-foreground"}),n[0]||(n[0]=e.createElementVNode("span",{class:"text-xs text-muted-foreground"},"Searching appointments…",-1))])):e.unref(a)?(e.openBlock(),e.createElementBlock("div",B,e.toDisplayString(e.unref(a)),1)):e.unref(l).length===0?(e.openBlock(),e.createElementBlock("div",D,[e.createVNode(e.unref(o.CalendarDays),{class:"size-8 text-muted-foreground mx-auto mb-2"}),n[1]||(n[1]=e.createElementVNode("p",{class:"text-sm text-muted-foreground"},"No appointments found for the given criteria.",-1))])):(e.openBlock(),e.createElementBlock("div",I,[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(e.unref(l),t=>(e.openBlock(),e.createElementBlock("div",{key:t.reservationId||t.orderId,class:"rounded-xl border bg-background p-3 space-y-3"},[e.createElementVNode("div",C,[e.createElementVNode("div",z,[e.createVNode(e.unref(o.CalendarDays),{class:"size-5 text-primary"})]),e.createElementVNode("div",T,[e.createElementVNode("p",$,e.toDisplayString(t.customerInfo?.firstName)+" "+e.toDisplayString(t.customerInfo?.lastName),1),e.createElementVNode("div",w,[e.createElementVNode("span",{class:e.normalizeClass(["text-[10px] font-medium px-1.5 py-0.5 rounded-full uppercase",y(t.reservationStatus||t.status)])},e.toDisplayString(b(t.reservationStatus||t.status)),3),t.reservationPrice!=null?(e.openBlock(),e.createElementBlock("span",A,e.toDisplayString(V(t.reservationPrice)),1)):e.createCommentVNode("",!0)])])]),e.createElementVNode("div",j,[e.createElementVNode("div",L,[e.createVNode(e.unref(o.Mail),{class:"size-3"}),e.createElementVNode("span",P,e.toDisplayString(t.customerInfo?.email||"—"),1)]),e.createElementVNode("div",M,[e.createVNode(e.unref(o.CalendarDays),{class:"size-3"}),e.createElementVNode("span",null,e.toDisplayString(t.date),1)]),e.createElementVNode("div",F,[e.createVNode(e.unref(o.Clock),{class:"size-3"}),e.createElementVNode("span",null,e.toDisplayString(t.startTime)+" – "+e.toDisplayString(t.endTime),1)]),e.createElementVNode("div",R,[e.createVNode(e.unref(o.Users),{class:"size-3"}),e.createElementVNode("span",null,e.toDisplayString(t.spots||1)+" "+e.toDisplayString((t.spots||1)===1?"spot":"spots"),1)])]),e.createVNode(i,{to:`/projects/${e.unref(N)}/modules/${u.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"}),n[2]||(n[2]=e.createTextVNode(" Open in agenda ",-1))]),_:1},8,["to"])]))),128))]))])}}});exports.default=q;
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("vue"),c=require("lucide-vue-next"),E={class:"w-full"},V={key:0,class:"flex items-center gap-2 py-3"},w={key:1,class:"text-xs text-destructive py-2"},S={key:2,class:"rounded-xl border bg-background p-4 text-center"},D={key:3,class:"rounded-xl border bg-background overflow-hidden"},I={class:"overflow-x-auto"},B={class:"w-full text-xs"},T={class:"px-3 py-2"},C={class:"font-medium truncate max-w-[160px]"},L={class:"text-muted-foreground truncate max-w-[160px]"},$={class:"px-3 py-2 whitespace-nowrap"},A={class:"px-3 py-2 whitespace-nowrap"},j={class:"px-3 py-2 text-center"},P={class:"px-3 py-2"},q={class:"px-3 py-2 text-right font-medium whitespace-nowrap"},z={class:"px-3 py-2 border-t bg-muted/20 flex items-center justify-between"},M={class:"text-xs text-muted-foreground"},F=e.defineComponent({__name:"AppointmentListTable",props:{toolName:{},instanceId:{},instanceName:{},moduleType:{},resolvedArgs:{},status:{}},emits:["submit"],setup(i,{emit:m}){const{$useRoute:p,$useModuleApi:x}=useNuxtApp(),d=i,f=m,g=p(),y=e.computed(()=>g.params.slug),b=x(d.instanceId),l=e.ref(!0),a=e.ref(null),s=e.ref([]);async function N(){const t=d.resolvedArgs?.quantity||20;l.value=!0,a.value=null;try{const o=await b.get(`/appointments?quantity=${t}`);s.value=o.appointments||[],u({count:s.value.length,appointments:s.value.map(r=>({orderId:r.orderId,reservationId:r.reservationId,customerName:`${r.customerInfo?.firstName||""} ${r.customerInfo?.lastName||""}`.trim(),email:r.customerInfo?.email,date:r.date,startTime:r.startTime,endTime:r.endTime,spots:r.spots,status:r.reservationStatus||r.status,price:r.reservationPrice}))})}catch(o){a.value=o?.data?.statusMessage||o?.message||"Failed to load appointments",u(`Error loading appointments: ${a.value}`)}finally{l.value=!1}}e.onMounted(()=>{N()});function u(t){d.status!=="completed"&&f("submit",t)}const v=t=>{switch(t){case"approved":return"text-emerald-600 dark:text-emerald-400 bg-emerald-50 dark:bg-emerald-900/20";case"needs_approval":return"text-blue-600 dark:text-blue-400 bg-blue-50 dark:bg-blue-900/20";case"rejected":case"cancelled":return"text-red-600 dark:text-red-400 bg-red-50 dark:bg-red-900/20";default:return"text-amber-600 dark:text-amber-400 bg-amber-50 dark:bg-amber-900/20"}},h=t=>{switch(t){case"approved":return"Approved";case"needs_approval":return"Needs Approval";case"rejected":return"Rejected";case"cancelled":return"Cancelled";case"confirmed":return"Confirmed";default:return t||"Pending"}},_=t=>t==null?"—":`€${t.toFixed(2)}`,k=t=>{if(!t)return"—";try{return new Date(t).toLocaleDateString("en-US",{weekday:"short",month:"short",day:"numeric"})}catch{return t}};return(t,o)=>{const r=e.resolveComponent("NuxtLink");return e.openBlock(),e.createElementBlock("div",E,[e.unref(l)?(e.openBlock(),e.createElementBlock("div",V,[e.createVNode(e.unref(c.Loader2),{class:"size-4 animate-spin text-muted-foreground"}),o[0]||(o[0]=e.createElementVNode("span",{class:"text-xs text-muted-foreground"},"Loading appointments…",-1))])):e.unref(a)?(e.openBlock(),e.createElementBlock("div",w,e.toDisplayString(e.unref(a)),1)):e.unref(s).length===0?(e.openBlock(),e.createElementBlock("div",S,[e.createVNode(e.unref(c.CalendarDays),{class:"size-8 text-muted-foreground mx-auto mb-2"}),o[1]||(o[1]=e.createElementVNode("p",{class:"text-sm text-muted-foreground"},"No recent appointments found.",-1))])):(e.openBlock(),e.createElementBlock("div",D,[e.createElementVNode("div",I,[e.createElementVNode("table",B,[o[2]||(o[2]=e.createElementVNode("thead",null,[e.createElementVNode("tr",{class:"border-b bg-muted/40"},[e.createElementVNode("th",{class:"text-left px-3 py-2 font-medium text-muted-foreground"},"Customer"),e.createElementVNode("th",{class:"text-left px-3 py-2 font-medium text-muted-foreground"},"Date"),e.createElementVNode("th",{class:"text-left px-3 py-2 font-medium text-muted-foreground"},"Time"),e.createElementVNode("th",{class:"text-center px-3 py-2 font-medium text-muted-foreground"},"Spots"),e.createElementVNode("th",{class:"text-left px-3 py-2 font-medium text-muted-foreground"},"Status"),e.createElementVNode("th",{class:"text-right px-3 py-2 font-medium text-muted-foreground"},"Price")])],-1)),e.createElementVNode("tbody",null,[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(e.unref(s),n=>(e.openBlock(),e.createElementBlock("tr",{key:n.reservationId||n.orderId,class:"border-b last:border-b-0 hover:bg-muted/30 transition-colors"},[e.createElementVNode("td",T,[e.createElementVNode("div",C,e.toDisplayString(n.customerInfo?.firstName)+" "+e.toDisplayString(n.customerInfo?.lastName),1),e.createElementVNode("div",L,e.toDisplayString(n.customerInfo?.email),1)]),e.createElementVNode("td",$,e.toDisplayString(k(n.date)),1),e.createElementVNode("td",A,e.toDisplayString(n.startTime)+" – "+e.toDisplayString(n.endTime),1),e.createElementVNode("td",j,e.toDisplayString(n.spots||1),1),e.createElementVNode("td",P,[e.createElementVNode("span",{class:e.normalizeClass(["inline-block text-[10px] font-medium px-1.5 py-0.5 rounded-full uppercase whitespace-nowrap",v(n.reservationStatus||n.status)])},e.toDisplayString(h(n.reservationStatus||n.status)),3)]),e.createElementVNode("td",q,e.toDisplayString(_(n.reservationPrice)),1)]))),128))])])]),e.createElementVNode("div",z,[e.createElementVNode("span",M,e.toDisplayString(e.unref(s).length)+" appointment"+e.toDisplayString(e.unref(s).length===1?"":"s"),1),e.createVNode(r,{to:`/projects/${e.unref(y)}/modules/${i.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"}),o[3]||(o[3]=e.createTextVNode(" View all ",-1))]),_:1},8,["to"])])]))])}}});exports.default=F;
@@ -1,6 +1,5 @@
1
- import { defineComponent as C, computed as L, ref as x, onMounted as S, resolveComponent as A, openBlock as i, createElementBlock as u, unref as a, createVNode as c, createElementVNode as e, toDisplayString as n, Fragment as $, renderList as j, normalizeClass as D, withCtx as P, createTextVNode as z } from "vue";
2
- import { Loader2 as E, CalendarDays as V, ExternalLink as q } from "lucide-vue-next";
3
- import { useRoute as F, useModuleApi as M } from "@oneclick.dev/cms-kit";
1
+ import { defineComponent as $, computed as A, ref as x, onMounted as S, resolveComponent as j, openBlock as i, createElementBlock as u, unref as a, createVNode as c, createElementVNode as e, toDisplayString as n, Fragment as D, renderList as P, normalizeClass as z, withCtx as E, createTextVNode as V } from "vue";
2
+ import { Loader2 as q, CalendarDays as F, ExternalLink as M } from "lucide-vue-next";
4
3
  const B = { class: "w-full" }, R = {
5
4
  key: 0,
6
5
  class: "flex items-center gap-2 py-3"
@@ -13,7 +12,7 @@ const B = { class: "w-full" }, R = {
13
12
  }, H = {
14
13
  key: 3,
15
14
  class: "rounded-xl border bg-background overflow-hidden"
16
- }, J = { class: "overflow-x-auto" }, K = { class: "w-full text-xs" }, O = { class: "px-3 py-2" }, Q = { class: "font-medium truncate max-w-[160px]" }, W = { class: "text-muted-foreground truncate max-w-[160px]" }, X = { class: "px-3 py-2 whitespace-nowrap" }, Y = { class: "px-3 py-2 whitespace-nowrap" }, Z = { class: "px-3 py-2 text-center" }, ee = { class: "px-3 py-2" }, te = { class: "px-3 py-2 text-right font-medium whitespace-nowrap" }, se = { class: "px-3 py-2 border-t bg-muted/20 flex items-center justify-between" }, oe = { class: "text-xs text-muted-foreground" }, de = /* @__PURE__ */ C({
15
+ }, J = { class: "overflow-x-auto" }, K = { class: "w-full text-xs" }, O = { class: "px-3 py-2" }, Q = { class: "font-medium truncate max-w-[160px]" }, W = { class: "text-muted-foreground truncate max-w-[160px]" }, X = { class: "px-3 py-2 whitespace-nowrap" }, Y = { class: "px-3 py-2 whitespace-nowrap" }, Z = { class: "px-3 py-2 text-center" }, ee = { class: "px-3 py-2" }, te = { class: "px-3 py-2 text-right font-medium whitespace-nowrap" }, se = { class: "px-3 py-2 border-t bg-muted/20 flex items-center justify-between" }, oe = { class: "text-xs text-muted-foreground" }, ae = /* @__PURE__ */ $({
17
16
  __name: "AppointmentListTable",
18
17
  props: {
19
18
  toolName: {},
@@ -25,12 +24,12 @@ const B = { class: "w-full" }, R = {
25
24
  },
26
25
  emits: ["submit"],
27
26
  setup(f, { emit: b }) {
28
- const m = f, h = b, v = F(), y = L(() => v.params.slug), _ = M(m.instanceId), p = x(!0), l = x(null), d = x([]);
29
- async function k() {
27
+ const { $useRoute: h, $useModuleApi: v } = useNuxtApp(), m = f, y = b, _ = h(), k = A(() => _.params.slug), w = v(m.instanceId), p = x(!0), l = x(null), d = x([]);
28
+ async function I() {
30
29
  const t = m.resolvedArgs?.quantity || 20;
31
30
  p.value = !0, l.value = null;
32
31
  try {
33
- const s = await _.get(`/appointments?quantity=${t}`);
32
+ const s = await w.get(`/appointments?quantity=${t}`);
34
33
  d.value = s.appointments || [], g({
35
34
  count: d.value.length,
36
35
  appointments: d.value.map((o) => ({
@@ -53,12 +52,12 @@ const B = { class: "w-full" }, R = {
53
52
  }
54
53
  }
55
54
  S(() => {
56
- k();
55
+ I();
57
56
  });
58
57
  function g(t) {
59
- m.status !== "completed" && h("submit", t);
58
+ m.status !== "completed" && y("submit", t);
60
59
  }
61
- const w = (t) => {
60
+ const N = (t) => {
62
61
  switch (t) {
63
62
  case "approved":
64
63
  return "text-emerald-600 dark:text-emerald-400 bg-emerald-50 dark:bg-emerald-900/20";
@@ -70,7 +69,7 @@ const B = { class: "w-full" }, R = {
70
69
  default:
71
70
  return "text-amber-600 dark:text-amber-400 bg-amber-50 dark:bg-amber-900/20";
72
71
  }
73
- }, I = (t) => {
72
+ }, T = (t) => {
74
73
  switch (t) {
75
74
  case "approved":
76
75
  return "Approved";
@@ -85,7 +84,7 @@ const B = { class: "w-full" }, R = {
85
84
  default:
86
85
  return t || "Pending";
87
86
  }
88
- }, N = (t) => t == null ? "—" : `€${t.toFixed(2)}`, T = (t) => {
87
+ }, C = (t) => t == null ? "—" : `€${t.toFixed(2)}`, L = (t) => {
89
88
  if (!t) return "—";
90
89
  try {
91
90
  return new Date(t).toLocaleDateString("en-US", { weekday: "short", month: "short", day: "numeric" });
@@ -94,13 +93,13 @@ const B = { class: "w-full" }, R = {
94
93
  }
95
94
  };
96
95
  return (t, s) => {
97
- const o = A("NuxtLink");
96
+ const o = j("NuxtLink");
98
97
  return i(), u("div", B, [
99
98
  a(p) ? (i(), u("div", R, [
100
- c(a(E), { class: "size-4 animate-spin text-muted-foreground" }),
99
+ c(a(q), { class: "size-4 animate-spin text-muted-foreground" }),
101
100
  s[0] || (s[0] = e("span", { class: "text-xs text-muted-foreground" }, "Loading appointments…", -1))
102
101
  ])) : a(l) ? (i(), u("div", U, n(a(l)), 1)) : a(d).length === 0 ? (i(), u("div", G, [
103
- c(a(V), { class: "size-8 text-muted-foreground mx-auto mb-2" }),
102
+ c(a(F), { class: "size-8 text-muted-foreground mx-auto mb-2" }),
104
103
  s[1] || (s[1] = e("p", { class: "text-sm text-muted-foreground" }, "No recent appointments found.", -1))
105
104
  ])) : (i(), u("div", H, [
106
105
  e("div", J, [
@@ -116,7 +115,7 @@ const B = { class: "w-full" }, R = {
116
115
  ])
117
116
  ], -1)),
118
117
  e("tbody", null, [
119
- (i(!0), u($, null, j(a(d), (r) => (i(), u("tr", {
118
+ (i(!0), u(D, null, P(a(d), (r) => (i(), u("tr", {
120
119
  key: r.reservationId || r.orderId,
121
120
  class: "border-b last:border-b-0 hover:bg-muted/30 transition-colors"
122
121
  }, [
@@ -124,15 +123,15 @@ const B = { class: "w-full" }, R = {
124
123
  e("div", Q, n(r.customerInfo?.firstName) + " " + n(r.customerInfo?.lastName), 1),
125
124
  e("div", W, n(r.customerInfo?.email), 1)
126
125
  ]),
127
- e("td", X, n(T(r.date)), 1),
126
+ e("td", X, n(L(r.date)), 1),
128
127
  e("td", Y, n(r.startTime) + " – " + n(r.endTime), 1),
129
128
  e("td", Z, n(r.spots || 1), 1),
130
129
  e("td", ee, [
131
130
  e("span", {
132
- class: D(["inline-block text-[10px] font-medium px-1.5 py-0.5 rounded-full uppercase whitespace-nowrap", w(r.reservationStatus || r.status)])
133
- }, n(I(r.reservationStatus || r.status)), 3)
131
+ class: z(["inline-block text-[10px] font-medium px-1.5 py-0.5 rounded-full uppercase whitespace-nowrap", N(r.reservationStatus || r.status)])
132
+ }, n(T(r.reservationStatus || r.status)), 3)
134
133
  ]),
135
- e("td", te, n(N(r.reservationPrice)), 1)
134
+ e("td", te, n(C(r.reservationPrice)), 1)
136
135
  ]))), 128))
137
136
  ])
138
137
  ])
@@ -140,12 +139,12 @@ const B = { class: "w-full" }, R = {
140
139
  e("div", se, [
141
140
  e("span", oe, n(a(d).length) + " appointment" + n(a(d).length === 1 ? "" : "s"), 1),
142
141
  c(o, {
143
- to: `/projects/${a(y)}/modules/${f.instanceId}`,
142
+ to: `/projects/${a(k)}/modules/${f.instanceId}`,
144
143
  class: "inline-flex items-center gap-1.5 text-xs text-primary hover:underline"
145
144
  }, {
146
- default: P(() => [
147
- c(a(q), { class: "size-3" }),
148
- s[3] || (s[3] = z(" View all ", -1))
145
+ default: E(() => [
146
+ c(a(M), { class: "size-3" }),
147
+ s[3] || (s[3] = V(" View all ", -1))
149
148
  ]),
150
149
  _: 1
151
150
  }, 8, ["to"])
@@ -156,5 +155,5 @@ const B = { class: "w-full" }, R = {
156
155
  }
157
156
  });
158
157
  export {
159
- de as default
158
+ ae as default
160
159
  };
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("vue"),l=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"},z={key:2,class:"rounded-xl border bg-background p-4 text-center space-y-2"},T={key:3,class:"rounded-xl border bg-background overflow-hidden"},F={class:"px-3 py-2 border-b bg-muted/40 flex items-center justify-between"},U={class:"flex items-center gap-2"},I={class:"text-[10px] text-muted-foreground"},M={class:"divide-y"},j={class:"flex items-center gap-2 mb-1.5"},P={class:"text-sm shrink-0"},R={class:"text-xs font-medium truncate flex-1"},G={class:"text-[10px] text-muted-foreground"},q={class:"ml-7 space-y-1.5"},K={class:"h-1.5 rounded-full bg-muted overflow-hidden"},O={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"},Z={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:"CountryBreakdownCard",props:{toolName:{},instanceId:{},instanceName:{},moduleType:{},resolvedArgs:{},status:{}},emits:["submit"],setup(p,{emit:x}){const{$useRoute:y,$useModuleApi:h}=useNuxtApp(),i=p,v=x,N=y(),_=e.computed(()=>N.params.slug),V=h(i.instanceId),d=e.ref(!0),c=e.ref(null),o=e.ref([]),u=e.ref(null),b=t=>({"United States":"🇺🇸","United Kingdom":"🇬🇧",Germany:"🇩🇪",France:"🇫🇷",Netherlands:"🇳🇱",Belgium:"🇧🇪",Canada:"🇨🇦",Australia:"🇦🇺",India:"🇮🇳",Brazil:"🇧🇷",Spain:"🇪🇸",Italy:"🇮🇹",Japan:"🇯🇵",China:"🇨🇳","South Korea":"🇰🇷",Mexico:"🇲🇽",Russia:"🇷🇺",Sweden:"🇸🇪",Norway:"🇳🇴",Denmark:"🇩🇰",Finland:"🇫🇮",Poland:"🇵🇱",Switzerland:"🇨🇭",Austria:"🇦🇹",Portugal:"🇵🇹",Ireland:"🇮🇪","New Zealand":"🇳🇿",Singapore:"🇸🇬","South Africa":"🇿🇦",Turkey:"🇹🇷",Indonesia:"🇮🇩",Thailand:"🇹🇭",Philippines:"🇵🇭",Vietnam:"🇻🇳",Argentina:"🇦🇷",Colombia:"🇨🇴",Israel:"🇮🇱",UAE:"🇦🇪","United Arab Emirates":"🇦🇪","Czech Republic":"🇨🇿",Czechia:"🇨🇿",Romania:"🇷🇴",Hungary:"🇭🇺",Ukraine:"🇺🇦",Greece:"🇬🇷",Luxembourg:"🇱🇺"})[t]||"🌍";function k(){const t=i.resolvedArgs?._cachedData;return t?(o.value=(t.countries||[]).map(s=>({country:s.country,sessions:s.sessions,totalUsers:s.users})),u.value=i.resolvedArgs._fetchedAt||null,d.value=!1,!0):!1}async function E(){const{startDate:t,endDate:s}=i.resolvedArgs||{};d.value=!0,c.value=null;try{const n=new URLSearchParams;t&&n.set("startDate",t),s&&n.set("endDate",s);const r=await V.get(`/countries?${n.toString()}`);o.value=r.rows||[],u.value=new Date().toISOString();const m=o.value.reduce((a,A)=>a+(A.sessions||0),0);f({count:o.value.length,countries:o.value.map(a=>({country:a.country,sessions:a.sessions,users:a.totalUsers,share:`${(a.sessions/m*100).toFixed(1)}%`})),suggestion:o.value.length===0?"No geographic data found for this period.":`Top countries by traffic: ${o.value.slice(0,5).map(a=>`${a.country} (${(a.sessions/m*100).toFixed(0)}%)`).join(", ")}.`})}catch(n){c.value=n?.data?.statusMessage||n?.message||"Failed to load country data",f(`Error loading country data: ${c.value}`)}finally{d.value=!1}}e.onMounted(()=>{i.status==="completed"&&k()||E()});function f(t){i.status!=="completed"&&v("submit",t)}const g=t=>t==null?"0":Math.round(t).toLocaleString(),S=t=>t?new Date(t).toLocaleString(void 0,{month:"short",day:"numeric",hour:"2-digit",minute:"2-digit"}):"",D=e.computed(()=>o.value.reduce((t,s)=>t+(s.sessions||0),0)||1),B=e.computed(()=>Math.max(...o.value.map(t=>t.sessions||0),1)),w=e.computed(()=>{const{startDate:t,endDate:s}=i.resolvedArgs||{};if(!t&&!s)return"Last 30 days";const n=t||"30daysAgo",r=n.match(/^(\d+)daysAgo$/);return r?`Last ${r[1]} days`:`${n} → ${s||"today"}`});return(t,s)=>{const n=e.resolveComponent("NuxtLink");return e.openBlock(),e.createElementBlock("div",C,[e.unref(d)?(e.openBlock(),e.createElementBlock("div",$,[e.createVNode(e.unref(l.Loader2),{class:"size-4 animate-spin text-muted-foreground"}),s[0]||(s[0]=e.createElementVNode("span",{class:"text-xs text-muted-foreground"},"Loading country data…",-1))])):e.unref(c)?(e.openBlock(),e.createElementBlock("div",L,e.toDisplayString(e.unref(c)),1)):e.unref(o).length===0?(e.openBlock(),e.createElementBlock("div",z,[e.createVNode(e.unref(l.Globe),{class:"size-8 text-muted-foreground mx-auto"}),s[1]||(s[1]=e.createElementVNode("p",{class:"text-sm text-muted-foreground"},"No geographic data found for this period.",-1))])):(e.openBlock(),e.createElementBlock("div",T,[e.createElementVNode("div",F,[e.createElementVNode("div",U,[e.createVNode(e.unref(l.Globe),{class:"size-3.5 text-primary"}),s[2]||(s[2]=e.createElementVNode("span",{class:"text-xs font-medium"},"Visitors by Country",-1))]),e.createElementVNode("span",I,e.toDisplayString(e.unref(w)),1)]),e.createElementVNode("div",M,[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(e.unref(o),(r,m)=>(e.openBlock(),e.createElementBlock("div",{key:m,class:"px-3 py-2.5 hover:bg-muted/30 transition-colors"},[e.createElementVNode("div",j,[e.createElementVNode("span",P,e.toDisplayString(b(r.country)),1),e.createElementVNode("span",R,e.toDisplayString(r.country),1),e.createElementVNode("span",G,e.toDisplayString((r.sessions/e.unref(D)*100).toFixed(1))+"%",1)]),e.createElementVNode("div",q,[e.createElementVNode("div",K,[e.createElementVNode("div",{class:"h-full rounded-full bg-blue-500/70 transition-all",style:e.normalizeStyle({width:`${r.sessions/e.unref(B)*100}%`})},null,4)]),e.createElementVNode("div",O,[e.createElementVNode("span",H,[e.createVNode(e.unref(l.MousePointerClick),{class:"size-2.5"}),e.createTextVNode(" "+e.toDisplayString(g(r.sessions))+" sessions ",1)]),e.createElementVNode("span",J,[e.createVNode(e.unref(l.Users),{class:"size-2.5"}),e.createTextVNode(" "+e.toDisplayString(g(r.totalUsers))+" users ",1)])])])]))),128))]),e.createElementVNode("div",Z,[e.createElementVNode("span",Q,[e.createTextVNode(e.toDisplayString(e.unref(o).length)+" countr"+e.toDisplayString(e.unref(o).length===1?"y":"ies")+" ",1),e.unref(u)?(e.openBlock(),e.createElementBlock(e.Fragment,{key:0},[e.createTextVNode(" · fetched "+e.toDisplayString(S(e.unref(u))),1)],64)):e.createCommentVNode("",!0)]),e.createVNode(n,{to:`/projects/${e.unref(_)}/modules/${p.instanceId}`,class:"inline-flex items-center gap-1.5 text-xs text-primary hover:underline"},{default:e.withCtx(()=>[e.createVNode(e.unref(l.ExternalLink),{class:"size-3"}),s[3]||(s[3]=e.createTextVNode(" View full report ",-1))]),_:1},8,["to"])])]))])}}});exports.default=W;
@@ -1,6 +1,5 @@
1
- import { defineComponent as T, computed as y, ref as v, onMounted as j, resolveComponent as B, openBlock as l, createElementBlock as u, unref as s, createVNode as m, createElementVNode as o, toDisplayString as i, Fragment as k, renderList as P, normalizeStyle as R, createTextVNode as f, createCommentVNode as G, withCtx as K } from "vue";
2
- import { Loader2 as H, Globe as w, MousePointerClick as J, Users as O, ExternalLink as Z } from "lucide-vue-next";
3
- import { useRoute as q, useModuleApi as Q } from "@oneclick.dev/cms-kit";
1
+ import { defineComponent as B, computed as y, ref as v, onMounted as P, resolveComponent as R, openBlock as l, createElementBlock as u, unref as s, createVNode as m, createElementVNode as o, toDisplayString as i, Fragment as k, renderList as G, normalizeStyle as K, createTextVNode as f, createCommentVNode as H, withCtx as J } from "vue";
2
+ import { Loader2 as O, Globe as w, MousePointerClick as Z, Users as q, ExternalLink as Q } from "lucide-vue-next";
4
3
  const W = { class: "w-full" }, X = {
5
4
  key: 0,
6
5
  class: "flex items-center gap-2 py-3"
@@ -13,7 +12,7 @@ const W = { class: "w-full" }, X = {
13
12
  }, te = {
14
13
  key: 3,
15
14
  class: "rounded-xl border bg-background overflow-hidden"
16
- }, se = { 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" }, ae = { class: "divide-y" }, re = { class: "flex items-center gap-2 mb-1.5" }, ie = { class: "text-sm shrink-0" }, de = { class: "text-xs font-medium truncate flex-1" }, le = { class: "text-[10px] text-muted-foreground" }, 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" }, pe = { class: "flex items-center gap-1" }, fe = { class: "flex items-center gap-1" }, ge = { class: "px-3 py-2 border-t bg-muted/20 flex items-center justify-between" }, xe = { class: "text-[10px] text-muted-foreground" }, _e = /* @__PURE__ */ T({
15
+ }, se = { 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" }, ae = { class: "divide-y" }, re = { class: "flex items-center gap-2 mb-1.5" }, ie = { class: "text-sm shrink-0" }, de = { class: "text-xs font-medium truncate flex-1" }, le = { class: "text-[10px] text-muted-foreground" }, 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" }, pe = { class: "flex items-center gap-1" }, fe = { class: "flex items-center gap-1" }, ge = { class: "px-3 py-2 border-t bg-muted/20 flex items-center justify-between" }, xe = { class: "text-[10px] text-muted-foreground" }, ve = /* @__PURE__ */ B({
17
16
  __name: "CountryBreakdownCard",
18
17
  props: {
19
18
  toolName: {},
@@ -25,7 +24,7 @@ const W = { class: "w-full" }, X = {
25
24
  },
26
25
  emits: ["submit"],
27
26
  setup(_, { emit: A }) {
28
- const c = _, C = A, N = q(), L = y(() => N.params.slug), $ = Q(c.instanceId), g = v(!0), p = v(null), n = v([]), x = v(null), z = (e) => ({
27
+ const { $useRoute: C, $useModuleApi: N } = useNuxtApp(), c = _, $ = A, L = C(), z = y(() => L.params.slug), D = N(c.instanceId), g = v(!0), p = v(null), n = v([]), x = v(null), U = (e) => ({
29
28
  "United States": "🇺🇸",
30
29
  "United Kingdom": "🇬🇧",
31
30
  Germany: "🇩🇪",
@@ -73,7 +72,7 @@ const W = { class: "w-full" }, X = {
73
72
  Greece: "🇬🇷",
74
73
  Luxembourg: "🇱🇺"
75
74
  })[e] || "🌍";
76
- function D() {
75
+ function F() {
77
76
  const e = c.resolvedArgs?._cachedData;
78
77
  return e ? (n.value = (e.countries || []).map((t) => ({
79
78
  country: t.country,
@@ -81,15 +80,15 @@ const W = { class: "w-full" }, X = {
81
80
  totalUsers: t.users
82
81
  })), x.value = c.resolvedArgs._fetchedAt || null, g.value = !1, !0) : !1;
83
82
  }
84
- async function U() {
83
+ async function I() {
85
84
  const { startDate: e, endDate: t } = c.resolvedArgs || {};
86
85
  g.value = !0, p.value = null;
87
86
  try {
88
87
  const a = new URLSearchParams();
89
88
  e && a.set("startDate", e), t && a.set("endDate", t);
90
- const r = await $.get(`/countries?${a.toString()}`);
89
+ const r = await D.get(`/countries?${a.toString()}`);
91
90
  n.value = r.rows || [], x.value = (/* @__PURE__ */ new Date()).toISOString();
92
- const h = n.value.reduce((d, E) => d + (E.sessions || 0), 0);
91
+ const h = n.value.reduce((d, j) => d + (j.sessions || 0), 0);
93
92
  b({
94
93
  count: n.value.length,
95
94
  countries: n.value.map((d) => ({
@@ -106,27 +105,27 @@ const W = { class: "w-full" }, X = {
106
105
  g.value = !1;
107
106
  }
108
107
  }
109
- j(() => {
110
- c.status === "completed" && D() || U();
108
+ P(() => {
109
+ c.status === "completed" && F() || I();
111
110
  });
112
111
  function b(e) {
113
- c.status !== "completed" && C("submit", e);
112
+ c.status !== "completed" && $("submit", e);
114
113
  }
115
- const S = (e) => e == null ? "0" : Math.round(e).toLocaleString(), F = (e) => e ? new Date(e).toLocaleString(void 0, { month: "short", day: "numeric", hour: "2-digit", minute: "2-digit" }) : "", I = y(
114
+ const S = (e) => e == null ? "0" : Math.round(e).toLocaleString(), M = (e) => e ? new Date(e).toLocaleString(void 0, { month: "short", day: "numeric", hour: "2-digit", minute: "2-digit" }) : "", V = y(
116
115
  () => n.value.reduce((e, t) => e + (t.sessions || 0), 0) || 1
117
- ), M = y(
116
+ ), E = y(
118
117
  () => Math.max(...n.value.map((e) => e.sessions || 0), 1)
119
- ), V = y(() => {
118
+ ), T = y(() => {
120
119
  const { startDate: e, endDate: t } = c.resolvedArgs || {};
121
120
  if (!e && !t) return "Last 30 days";
122
121
  const a = e || "30daysAgo", r = a.match(/^(\d+)daysAgo$/);
123
122
  return r ? `Last ${r[1]} days` : `${a} → ${t || "today"}`;
124
123
  });
125
124
  return (e, t) => {
126
- const a = B("NuxtLink");
125
+ const a = R("NuxtLink");
127
126
  return l(), u("div", W, [
128
127
  s(g) ? (l(), u("div", X, [
129
- m(s(H), { class: "size-4 animate-spin text-muted-foreground" }),
128
+ m(s(O), { class: "size-4 animate-spin text-muted-foreground" }),
130
129
  t[0] || (t[0] = o("span", { class: "text-xs text-muted-foreground" }, "Loading country data…", -1))
131
130
  ])) : s(p) ? (l(), u("div", Y, i(s(p)), 1)) : s(n).length === 0 ? (l(), u("div", ee, [
132
131
  m(s(w), { class: "size-8 text-muted-foreground mx-auto" }),
@@ -137,32 +136,32 @@ const W = { class: "w-full" }, X = {
137
136
  m(s(w), { class: "size-3.5 text-primary" }),
138
137
  t[2] || (t[2] = o("span", { class: "text-xs font-medium" }, "Visitors by Country", -1))
139
138
  ]),
140
- o("span", ne, i(s(V)), 1)
139
+ o("span", ne, i(s(T)), 1)
141
140
  ]),
142
141
  o("div", ae, [
143
- (l(!0), u(k, null, P(s(n), (r, h) => (l(), u("div", {
142
+ (l(!0), u(k, null, G(s(n), (r, h) => (l(), u("div", {
144
143
  key: h,
145
144
  class: "px-3 py-2.5 hover:bg-muted/30 transition-colors"
146
145
  }, [
147
146
  o("div", re, [
148
- o("span", ie, i(z(r.country)), 1),
147
+ o("span", ie, i(U(r.country)), 1),
149
148
  o("span", de, i(r.country), 1),
150
- o("span", le, i((r.sessions / s(I) * 100).toFixed(1)) + "%", 1)
149
+ o("span", le, i((r.sessions / s(V) * 100).toFixed(1)) + "%", 1)
151
150
  ]),
152
151
  o("div", ue, [
153
152
  o("div", ce, [
154
153
  o("div", {
155
154
  class: "h-full rounded-full bg-blue-500/70 transition-all",
156
- style: R({ width: `${r.sessions / s(M) * 100}%` })
155
+ style: K({ width: `${r.sessions / s(E) * 100}%` })
157
156
  }, null, 4)
158
157
  ]),
159
158
  o("div", me, [
160
159
  o("span", pe, [
161
- m(s(J), { class: "size-2.5" }),
160
+ m(s(Z), { class: "size-2.5" }),
162
161
  f(" " + i(S(r.sessions)) + " sessions ", 1)
163
162
  ]),
164
163
  o("span", fe, [
165
- m(s(O), { class: "size-2.5" }),
164
+ m(s(q), { class: "size-2.5" }),
166
165
  f(" " + i(S(r.totalUsers)) + " users ", 1)
167
166
  ])
168
167
  ])
@@ -173,15 +172,15 @@ const W = { class: "w-full" }, X = {
173
172
  o("span", xe, [
174
173
  f(i(s(n).length) + " countr" + i(s(n).length === 1 ? "y" : "ies") + " ", 1),
175
174
  s(x) ? (l(), u(k, { key: 0 }, [
176
- f(" · fetched " + i(F(s(x))), 1)
177
- ], 64)) : G("", !0)
175
+ f(" · fetched " + i(M(s(x))), 1)
176
+ ], 64)) : H("", !0)
178
177
  ]),
179
178
  m(a, {
180
- to: `/projects/${s(L)}/modules/${_.instanceId}`,
179
+ to: `/projects/${s(z)}/modules/${_.instanceId}`,
181
180
  class: "inline-flex items-center gap-1.5 text-xs text-primary hover:underline"
182
181
  }, {
183
- default: K(() => [
184
- m(s(Z), { class: "size-3" }),
182
+ default: J(() => [
183
+ m(s(Q), { class: "size-3" }),
185
184
  t[3] || (t[3] = f(" View full report ", -1))
186
185
  ]),
187
186
  _: 1
@@ -193,5 +192,5 @@ const W = { class: "w-full" }, X = {
193
192
  }
194
193
  });
195
194
  export {
196
- _e as default
195
+ ve as default
197
196
  };
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("vue"),l=require("lucide-vue-next"),$={class:"w-full"},z={key:0,class:"flex items-center gap-2 py-3"},A={key:1,class:"text-xs text-destructive py-2"},T={key:2,class:"rounded-xl border bg-background p-4 text-center space-y-2"},M={key:3,class:"rounded-xl border bg-background overflow-hidden"},F={class:"px-3 py-2 border-b bg-muted/40 flex items-center justify-between"},j={class:"flex items-center gap-2"},I={class:"text-[10px] text-muted-foreground"},U={class:"px-3 pt-3 pb-1"},P={class:"flex h-3 rounded-full overflow-hidden"},q={class:"divide-y"},O={class:"flex items-center gap-2"},R={class:"text-xs font-medium capitalize flex-1"},G={class:"text-sm font-semibold tabular-nums"},H={class:"ml-6 mt-1 flex items-center gap-3 text-[10px] text-muted-foreground"},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:"DeviceBreakdownCard",props:{toolName:{},instanceId:{},instanceName:{},moduleType:{},resolvedArgs:{},status:{}},emits:["submit"],setup(v,{emit:x}){const{$useRoute:y,$useModuleApi:h}=useNuxtApp(),i=v,b=x,k=y(),N=e.computed(()=>k.params.slug),_=h(i.instanceId),u=e.ref(!0),d=e.ref(null),r=e.ref([]),m=e.ref(null),V=s=>{const t=(s||"").toLowerCase();return t==="mobile"||t==="smartphone"?l.Smartphone:t==="tablet"?l.Tablet:l.Monitor},E=s=>{const t=(s||"").toLowerCase();return t==="desktop"?"bg-blue-500":t==="mobile"||t==="smartphone"?"bg-emerald-500":t==="tablet"?"bg-amber-500":"bg-violet-500"},B=s=>{const t=(s||"").toLowerCase();return t==="desktop"?"text-blue-500":t==="mobile"||t==="smartphone"?"text-emerald-500":t==="tablet"?"text-amber-500":"text-violet-500"};function w(){const s=i.resolvedArgs?._cachedData;return s?(r.value=(s.devices||[]).map(t=>({deviceCategory:t.device,sessions:t.sessions,totalUsers:t.users})),m.value=i.resolvedArgs._fetchedAt||null,u.value=!1,!0):!1}async function C(){const{startDate:s,endDate:t}=i.resolvedArgs||{};u.value=!0,d.value=null;try{const n=new URLSearchParams;s&&n.set("startDate",s),t&&n.set("endDate",t);const o=await _.get(`/devices?${n.toString()}`);r.value=o.rows||[],m.value=new Date().toISOString();const c=r.value.reduce((a,L)=>a+(L.sessions||0),0);g({count:r.value.length,devices:r.value.map(a=>({device:a.deviceCategory,sessions:a.sessions,users:a.totalUsers,share:`${(a.sessions/c*100).toFixed(1)}%`})),suggestion:r.value.length===0?"No device data found for this period.":`Device breakdown: ${r.value.map(a=>`${a.deviceCategory} ${(a.sessions/c*100).toFixed(0)}%`).join(", ")}.`})}catch(n){d.value=n?.data?.statusMessage||n?.message||"Failed to load device data",g(`Error loading device data: ${d.value}`)}finally{u.value=!1}}e.onMounted(()=>{i.status==="completed"&&w()||C()});function g(s){i.status!=="completed"&&b("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"}):"",p=e.computed(()=>r.value.reduce((s,t)=>s+(t.sessions||0),0)||1),S=e.computed(()=>{const{startDate:s,endDate:t}=i.resolvedArgs||{};if(!s&&!t)return"Last 30 days";const n=s||"30daysAgo",o=n.match(/^(\d+)daysAgo$/);return o?`Last ${o[1]} days`:`${n} → ${t||"today"}`});return(s,t)=>{const n=e.resolveComponent("NuxtLink");return e.openBlock(),e.createElementBlock("div",$,[e.unref(u)?(e.openBlock(),e.createElementBlock("div",z,[e.createVNode(e.unref(l.Loader2),{class:"size-4 animate-spin text-muted-foreground"}),t[0]||(t[0]=e.createElementVNode("span",{class:"text-xs text-muted-foreground"},"Loading device data…",-1))])):e.unref(d)?(e.openBlock(),e.createElementBlock("div",A,e.toDisplayString(e.unref(d)),1)):e.unref(r).length===0?(e.openBlock(),e.createElementBlock("div",T,[e.createVNode(e.unref(l.Monitor),{class:"size-8 text-muted-foreground mx-auto"}),t[1]||(t[1]=e.createElementVNode("p",{class:"text-sm text-muted-foreground"},"No device data found for this period.",-1))])):(e.openBlock(),e.createElementBlock("div",M,[e.createElementVNode("div",F,[e.createElementVNode("div",j,[e.createVNode(e.unref(l.Monitor),{class:"size-3.5 text-primary"}),t[2]||(t[2]=e.createElementVNode("span",{class:"text-xs font-medium"},"Device Breakdown",-1))]),e.createElementVNode("span",I,e.toDisplayString(e.unref(S)),1)]),e.createElementVNode("div",U,[e.createElementVNode("div",P,[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(e.unref(r),(o,c)=>(e.openBlock(),e.createElementBlock("div",{key:c,class:e.normalizeClass([E(o.deviceCategory),"transition-all first:rounded-l-full last:rounded-r-full"]),style:e.normalizeStyle({width:`${o.sessions/e.unref(p)*100}%`})},null,6))),128))])]),e.createElementVNode("div",q,[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(e.unref(r),(o,c)=>(e.openBlock(),e.createElementBlock("div",{key:c,class:"px-3 py-2.5 hover:bg-muted/30 transition-colors"},[e.createElementVNode("div",O,[(e.openBlock(),e.createBlock(e.resolveDynamicComponent(V(o.deviceCategory)),{class:e.normalizeClass(["size-4 shrink-0",B(o.deviceCategory)])},null,8,["class"])),e.createElementVNode("span",R,e.toDisplayString(o.deviceCategory),1),e.createElementVNode("span",G,e.toDisplayString((o.sessions/e.unref(p)*100).toFixed(1))+"% ",1)]),e.createElementVNode("div",H,[e.createElementVNode("span",J,[e.createVNode(e.unref(l.MousePointerClick),{class:"size-2.5"}),e.createTextVNode(" "+e.toDisplayString(f(o.sessions))+" sessions ",1)]),e.createElementVNode("span",K,[e.createVNode(e.unref(l.Users),{class:"size-2.5"}),e.createTextVNode(" "+e.toDisplayString(f(o.totalUsers))+" users ",1)])])]))),128))]),e.createElementVNode("div",Q,[e.createElementVNode("span",W,[e.createTextVNode(e.toDisplayString(f(e.unref(p)))+" total sessions ",1),e.unref(m)?(e.openBlock(),e.createElementBlock(e.Fragment,{key:0},[e.createTextVNode(" · fetched "+e.toDisplayString(D(e.unref(m))),1)],64)):e.createCommentVNode("",!0)]),e.createVNode(n,{to:`/projects/${e.unref(N)}/modules/${v.instanceId}`,class:"inline-flex items-center gap-1.5 text-xs text-primary hover:underline"},{default:e.withCtx(()=>[e.createVNode(e.unref(l.ExternalLink),{class:"size-3"}),t[3]||(t[3]=e.createTextVNode(" View full report ",-1))]),_:1},8,["to"])])]))])}}});exports.default=X;