@oneclick.dev/cms-core-modules 0.0.79 → 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 (37) hide show
  1. package/dist/{AppointmentDetailsCard-Bu9VzIRx.mjs → AppointmentDetailsCard-33WpATpV.mjs} +43 -43
  2. package/dist/AppointmentDetailsCard-DpLM5IrB.js +1 -0
  3. package/dist/AppointmentListTable-CQ0WIXtj.js +1 -0
  4. package/dist/{AppointmentListTable-B8YLwOfT.mjs → AppointmentListTable-aV_UJd6j.mjs} +42 -42
  5. package/dist/CountryBreakdownCard-D7BK3nRD.js +1 -0
  6. package/dist/{CountryBreakdownCard-oDzmpvAd.mjs → CountryBreakdownCard-DVxNz2DJ.mjs} +48 -48
  7. package/dist/DeviceBreakdownCard-DRhQ9ufG.js +1 -0
  8. package/dist/{DeviceBreakdownCard-Oh_yzipG.mjs → DeviceBreakdownCard-W1frLe0L.mjs} +58 -58
  9. package/dist/{PeakHoursCard-DzNo4SNo.mjs → PeakHoursCard-9-EZFZLR.mjs} +55 -55
  10. package/dist/PeakHoursCard-BR5zmta4.js +1 -0
  11. package/dist/ProductDetailsCard-6nHikw4V.mjs +121 -0
  12. package/dist/ProductDetailsCard-Bn7qrgmc.js +1 -0
  13. package/dist/RealtimeCard--APfRNc8.js +1 -0
  14. package/dist/{RealtimeCard-tNUSIw6B.mjs → RealtimeCard-fvQlJcM7.mjs} +41 -41
  15. package/dist/SearchTermsCard-BsB-63aH.js +1 -0
  16. package/dist/{SearchTermsCard-BVHFHWUZ.mjs → SearchTermsCard-BzVrHKqQ.mjs} +57 -57
  17. package/dist/TopPagesCard-BDeA997A.js +1 -0
  18. package/dist/{TopPagesCard-CRIa3rSZ.mjs → TopPagesCard-CTozhOr_.mjs} +48 -48
  19. package/dist/{TrafficSourcesCard-Ct20QYax.mjs → TrafficSourcesCard-BxtCKsqx.mjs} +65 -65
  20. package/dist/TrafficSourcesCard-C3ziDTUL.js +1 -0
  21. package/dist/VisitorStatsCard-BmByE_Hi.js +1 -0
  22. package/dist/{VisitorStatsCard-DMULybKV.mjs → VisitorStatsCard-CXizEbVK.mjs} +55 -55
  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-LL-6PARb.js +0 -1
  27. package/dist/AppointmentListTable-DNvvb4sz.js +0 -1
  28. package/dist/CountryBreakdownCard-BpDXbxwZ.js +0 -1
  29. package/dist/DeviceBreakdownCard-OXiU9Cf0.js +0 -1
  30. package/dist/PeakHoursCard-OkgI1vnd.js +0 -1
  31. package/dist/ProductDetailsCard-BBOorNmB.js +0 -1
  32. package/dist/ProductDetailsCard-CYK9Mtt4.mjs +0 -121
  33. package/dist/RealtimeCard-DESm9Fs_.js +0 -1
  34. package/dist/SearchTermsCard-DmyhGQVM.js +0 -1
  35. package/dist/TopPagesCard-CgtNyhwY.js +0 -1
  36. package/dist/TrafficSourcesCard-CPAxaQTi.js +0 -1
  37. package/dist/VisitorStatsCard-Cs6jPehw.js +0 -1
@@ -1,21 +1,21 @@
1
- import { defineComponent as A, computed as T, ref as x, onMounted as L, resolveComponent as j, openBlock as d, createElementBlock as l, unref as r, createVNode as i, createElementVNode as t, toDisplayString as a, Fragment as P, renderList as M, normalizeClass as E, createCommentVNode as V, withCtx as D, createTextVNode as F } from "vue";
2
- import { Loader2 as R, CalendarDays as g, Mail as B, Clock as O, Users as U, ExternalLink as q } from "lucide-vue-next";
3
- const G = { class: "w-full" }, H = {
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";
3
+ const H = { class: "w-full" }, J = {
4
4
  key: 0,
5
5
  class: "flex items-center gap-2 py-3"
6
- }, J = {
6
+ }, K = {
7
7
  key: 1,
8
8
  class: "text-xs text-destructive py-2"
9
- }, K = {
9
+ }, Q = {
10
10
  key: 2,
11
11
  class: "rounded-xl border bg-background p-4 text-center"
12
- }, Q = {
12
+ }, W = {
13
13
  key: 3,
14
14
  class: "space-y-3"
15
- }, W = { class: "flex items-start gap-3" }, X = { class: "shrink-0 size-10 rounded-lg bg-primary/10 flex items-center justify-center" }, Y = { class: "flex-1 min-w-0" }, Z = { class: "text-sm font-semibold truncate" }, ee = { class: "flex items-center gap-2 mt-1 flex-wrap" }, te = {
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 = {
16
16
  key: 0,
17
17
  class: "text-xs font-medium"
18
- }, se = { class: "grid grid-cols-2 gap-2 text-xs text-muted-foreground" }, re = { class: "flex items-center gap-1.5" }, ne = { class: "truncate" }, ae = { class: "flex items-center gap-1.5" }, oe = { class: "flex items-center gap-1.5" }, ie = { class: "flex items-center gap-1.5" }, ue = /* @__PURE__ */ A({
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({
19
19
  __name: "AppointmentDetailsCard",
20
20
  props: {
21
21
  toolName: {},
@@ -27,8 +27,8 @@ const G = { class: "w-full" }, H = {
27
27
  },
28
28
  emits: ["submit"],
29
29
  setup(v, { emit: b }) {
30
- const { $useRoute: h, $useModuleOverlay: de } = useNuxtApp(), f = v, k = b, y = h(), N = T(() => y.params.slug), I = $useModuleApi(f.instanceId), p = x(!0), c = x(null), u = x([]);
31
- async function C() {
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
32
  const { name: s, email: o, date: m } = f.resolvedArgs || {};
33
33
  if (!m) {
34
34
  c.value = "No date provided", p.value = !1;
@@ -38,8 +38,8 @@ const G = { class: "w-full" }, H = {
38
38
  try {
39
39
  const e = new URLSearchParams();
40
40
  s && e.set("name", s), o && e.set("email", o), m && e.set("date", m);
41
- const w = await I.get(`/appointments/find?${e.toString()}`);
42
- u.value = w.appointments || [], _({
41
+ const A = await C.get(`/appointments/find?${e.toString()}`);
42
+ u.value = A.appointments || [], _({
43
43
  count: u.value.length,
44
44
  appointments: u.value.map((n) => ({
45
45
  orderId: n.orderId,
@@ -60,13 +60,13 @@ const G = { class: "w-full" }, H = {
60
60
  p.value = !1;
61
61
  }
62
62
  }
63
- L(() => {
64
- C();
63
+ j(() => {
64
+ z();
65
65
  });
66
66
  function _(s) {
67
- f.status !== "completed" && k("submit", s);
67
+ f.status !== "completed" && y("submit", s);
68
68
  }
69
- const z = (s) => {
69
+ const S = (s) => {
70
70
  switch (s) {
71
71
  case "approved":
72
72
  return "text-emerald-600 dark:text-emerald-400 bg-emerald-50 dark:bg-emerald-900/20";
@@ -93,60 +93,60 @@ const G = { class: "w-full" }, H = {
93
93
  default:
94
94
  return s || "Pending";
95
95
  }
96
- }, S = (s) => s == null ? "" : `€${s.toFixed(2)}`;
96
+ }, w = (s) => s == null ? "" : `€${s.toFixed(2)}`;
97
97
  return (s, o) => {
98
- const m = j("NuxtLink");
99
- return d(), l("div", G, [
100
- r(p) ? (d(), l("div", H, [
101
- i(r(R), { class: "size-4 animate-spin text-muted-foreground" }),
98
+ const m = P("NuxtLink");
99
+ return d(), l("div", H, [
100
+ r(p) ? (d(), l("div", J, [
101
+ i(r(B), { class: "size-4 animate-spin text-muted-foreground" }),
102
102
  o[0] || (o[0] = t("span", { class: "text-xs text-muted-foreground" }, "Searching appointments…", -1))
103
- ])) : r(c) ? (d(), l("div", J, a(r(c)), 1)) : r(u).length === 0 ? (d(), l("div", K, [
103
+ ])) : r(c) ? (d(), l("div", K, a(r(c)), 1)) : r(u).length === 0 ? (d(), l("div", Q, [
104
104
  i(r(g), { class: "size-8 text-muted-foreground mx-auto mb-2" }),
105
105
  o[1] || (o[1] = t("p", { class: "text-sm text-muted-foreground" }, "No appointments found for the given criteria.", -1))
106
- ])) : (d(), l("div", Q, [
107
- (d(!0), l(P, null, M(r(u), (e) => (d(), l("div", {
106
+ ])) : (d(), l("div", W, [
107
+ (d(!0), l(E, null, M(r(u), (e) => (d(), l("div", {
108
108
  key: e.reservationId || e.orderId,
109
109
  class: "rounded-xl border bg-background p-3 space-y-3"
110
110
  }, [
111
- t("div", W, [
112
- t("div", X, [
111
+ t("div", X, [
112
+ t("div", Y, [
113
113
  i(r(g), { class: "size-5 text-primary" })
114
114
  ]),
115
- t("div", Y, [
116
- t("p", Z, a(e.customerInfo?.firstName) + " " + a(e.customerInfo?.lastName), 1),
117
- t("div", ee, [
115
+ t("div", Z, [
116
+ t("p", ee, a(e.customerInfo?.firstName) + " " + a(e.customerInfo?.lastName), 1),
117
+ t("div", te, [
118
118
  t("span", {
119
- class: E(["text-[10px] font-medium px-1.5 py-0.5 rounded-full uppercase", z(e.reservationStatus || e.status)])
119
+ class: V(["text-[10px] font-medium px-1.5 py-0.5 rounded-full uppercase", S(e.reservationStatus || e.status)])
120
120
  }, a($(e.reservationStatus || e.status)), 3),
121
- e.reservationPrice != null ? (d(), l("span", te, a(S(e.reservationPrice)), 1)) : V("", !0)
121
+ e.reservationPrice != null ? (d(), l("span", se, a(w(e.reservationPrice)), 1)) : D("", !0)
122
122
  ])
123
123
  ])
124
124
  ]),
125
- t("div", se, [
126
- t("div", re, [
127
- i(r(B), { class: "size-3" }),
128
- t("span", ne, a(e.customerInfo?.email || "—"), 1)
125
+ t("div", re, [
126
+ t("div", ne, [
127
+ i(r(U), { class: "size-3" }),
128
+ t("span", ae, a(e.customerInfo?.email || "—"), 1)
129
129
  ]),
130
- t("div", ae, [
130
+ t("div", oe, [
131
131
  i(r(g), { class: "size-3" }),
132
132
  t("span", null, a(e.date), 1)
133
133
  ]),
134
- t("div", oe, [
134
+ t("div", ie, [
135
135
  i(r(O), { class: "size-3" }),
136
136
  t("span", null, a(e.startTime) + " – " + a(e.endTime), 1)
137
137
  ]),
138
- t("div", ie, [
139
- i(r(U), { class: "size-3" }),
138
+ t("div", de, [
139
+ i(r(q), { class: "size-3" }),
140
140
  t("span", null, a(e.spots || 1) + " " + a((e.spots || 1) === 1 ? "spot" : "spots"), 1)
141
141
  ])
142
142
  ]),
143
143
  i(m, {
144
- to: `/projects/${r(N)}/modules/${v.instanceId}`,
144
+ to: `/projects/${r(I)}/modules/${v.instanceId}`,
145
145
  class: "inline-flex items-center gap-1.5 text-xs text-primary hover:underline"
146
146
  }, {
147
- default: D(() => [
148
- i(r(q), { class: "size-3" }),
149
- o[2] || (o[2] = F(" Open in agenda ", -1))
147
+ default: F(() => [
148
+ i(r(G), { class: "size-3" }),
149
+ o[2] || (o[2] = R(" Open in agenda ", -1))
150
150
  ]),
151
151
  _: 1
152
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,18 +1,18 @@
1
- import { defineComponent as C, computed as L, ref as x, onMounted as A, resolveComponent as S, openBlock as i, createElementBlock as u, unref as a, createVNode as c, createElementVNode as e, toDisplayString as n, Fragment as j, renderList as D, normalizeClass as P, withCtx as z, createTextVNode as E } from "vue";
2
- import { Loader2 as M, CalendarDays as V, ExternalLink as q } from "lucide-vue-next";
3
- const F = { class: "w-full" }, B = {
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";
3
+ const B = { class: "w-full" }, R = {
4
4
  key: 0,
5
5
  class: "flex items-center gap-2 py-3"
6
- }, R = {
6
+ }, U = {
7
7
  key: 1,
8
8
  class: "text-xs text-destructive py-2"
9
- }, O = {
9
+ }, G = {
10
10
  key: 2,
11
11
  class: "rounded-xl border bg-background p-4 text-center"
12
- }, U = {
12
+ }, H = {
13
13
  key: 3,
14
14
  class: "rounded-xl border bg-background overflow-hidden"
15
- }, G = { class: "overflow-x-auto" }, H = { class: "w-full text-xs" }, J = { class: "px-3 py-2" }, K = { class: "font-medium truncate max-w-[160px]" }, Q = { class: "text-muted-foreground truncate max-w-[160px]" }, W = { class: "px-3 py-2 whitespace-nowrap" }, X = { class: "px-3 py-2 whitespace-nowrap" }, Y = { class: "px-3 py-2 text-center" }, Z = { class: "px-3 py-2" }, ee = { class: "px-3 py-2 text-right font-medium whitespace-nowrap" }, te = { class: "px-3 py-2 border-t bg-muted/20 flex items-center justify-between" }, se = { class: "text-xs text-muted-foreground" }, ae = /* @__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__ */ $({
16
16
  __name: "AppointmentListTable",
17
17
  props: {
18
18
  toolName: {},
@@ -24,12 +24,12 @@ const F = { class: "w-full" }, B = {
24
24
  },
25
25
  emits: ["submit"],
26
26
  setup(f, { emit: b }) {
27
- const { $useRoute: h, $useModuleOverlay: oe } = useNuxtApp(), m = f, v = b, y = h(), _ = L(() => y.params.slug), k = $useModuleApi(m.instanceId), p = x(!0), l = x(null), d = x([]);
28
- async function w() {
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() {
29
29
  const t = m.resolvedArgs?.quantity || 20;
30
30
  p.value = !0, l.value = null;
31
31
  try {
32
- const s = await k.get(`/appointments?quantity=${t}`);
32
+ const s = await w.get(`/appointments?quantity=${t}`);
33
33
  d.value = s.appointments || [], g({
34
34
  count: d.value.length,
35
35
  appointments: d.value.map((o) => ({
@@ -51,13 +51,13 @@ const F = { class: "w-full" }, B = {
51
51
  p.value = !1;
52
52
  }
53
53
  }
54
- A(() => {
55
- w();
54
+ S(() => {
55
+ I();
56
56
  });
57
57
  function g(t) {
58
- m.status !== "completed" && v("submit", t);
58
+ m.status !== "completed" && y("submit", t);
59
59
  }
60
- const I = (t) => {
60
+ const N = (t) => {
61
61
  switch (t) {
62
62
  case "approved":
63
63
  return "text-emerald-600 dark:text-emerald-400 bg-emerald-50 dark:bg-emerald-900/20";
@@ -69,7 +69,7 @@ const F = { class: "w-full" }, B = {
69
69
  default:
70
70
  return "text-amber-600 dark:text-amber-400 bg-amber-50 dark:bg-amber-900/20";
71
71
  }
72
- }, N = (t) => {
72
+ }, T = (t) => {
73
73
  switch (t) {
74
74
  case "approved":
75
75
  return "Approved";
@@ -84,7 +84,7 @@ const F = { class: "w-full" }, B = {
84
84
  default:
85
85
  return t || "Pending";
86
86
  }
87
- }, T = (t) => t == null ? "—" : `€${t.toFixed(2)}`, $ = (t) => {
87
+ }, C = (t) => t == null ? "—" : `€${t.toFixed(2)}`, L = (t) => {
88
88
  if (!t) return "—";
89
89
  try {
90
90
  return new Date(t).toLocaleDateString("en-US", { weekday: "short", month: "short", day: "numeric" });
@@ -93,17 +93,17 @@ const F = { class: "w-full" }, B = {
93
93
  }
94
94
  };
95
95
  return (t, s) => {
96
- const o = S("NuxtLink");
97
- return i(), u("div", F, [
98
- a(p) ? (i(), u("div", B, [
99
- c(a(M), { class: "size-4 animate-spin text-muted-foreground" }),
96
+ const o = j("NuxtLink");
97
+ return i(), u("div", B, [
98
+ a(p) ? (i(), u("div", R, [
99
+ c(a(q), { class: "size-4 animate-spin text-muted-foreground" }),
100
100
  s[0] || (s[0] = e("span", { class: "text-xs text-muted-foreground" }, "Loading appointments…", -1))
101
- ])) : a(l) ? (i(), u("div", R, n(a(l)), 1)) : a(d).length === 0 ? (i(), u("div", O, [
102
- c(a(V), { class: "size-8 text-muted-foreground mx-auto mb-2" }),
101
+ ])) : a(l) ? (i(), u("div", U, n(a(l)), 1)) : a(d).length === 0 ? (i(), u("div", G, [
102
+ c(a(F), { class: "size-8 text-muted-foreground mx-auto mb-2" }),
103
103
  s[1] || (s[1] = e("p", { class: "text-sm text-muted-foreground" }, "No recent appointments found.", -1))
104
- ])) : (i(), u("div", U, [
105
- e("div", G, [
106
- e("table", H, [
104
+ ])) : (i(), u("div", H, [
105
+ e("div", J, [
106
+ e("table", K, [
107
107
  s[2] || (s[2] = e("thead", null, [
108
108
  e("tr", { class: "border-b bg-muted/40" }, [
109
109
  e("th", { class: "text-left px-3 py-2 font-medium text-muted-foreground" }, "Customer"),
@@ -115,36 +115,36 @@ const F = { class: "w-full" }, B = {
115
115
  ])
116
116
  ], -1)),
117
117
  e("tbody", null, [
118
- (i(!0), u(j, null, D(a(d), (r) => (i(), u("tr", {
118
+ (i(!0), u(D, null, P(a(d), (r) => (i(), u("tr", {
119
119
  key: r.reservationId || r.orderId,
120
120
  class: "border-b last:border-b-0 hover:bg-muted/30 transition-colors"
121
121
  }, [
122
- e("td", J, [
123
- e("div", K, n(r.customerInfo?.firstName) + " " + n(r.customerInfo?.lastName), 1),
124
- e("div", Q, n(r.customerInfo?.email), 1)
122
+ e("td", O, [
123
+ e("div", Q, n(r.customerInfo?.firstName) + " " + n(r.customerInfo?.lastName), 1),
124
+ e("div", W, n(r.customerInfo?.email), 1)
125
125
  ]),
126
- e("td", W, n($(r.date)), 1),
127
- e("td", X, n(r.startTime) + " – " + n(r.endTime), 1),
128
- e("td", Y, n(r.spots || 1), 1),
129
- e("td", Z, [
126
+ e("td", X, n(L(r.date)), 1),
127
+ e("td", Y, n(r.startTime) + " – " + n(r.endTime), 1),
128
+ e("td", Z, n(r.spots || 1), 1),
129
+ e("td", ee, [
130
130
  e("span", {
131
- class: P(["inline-block text-[10px] font-medium px-1.5 py-0.5 rounded-full uppercase whitespace-nowrap", I(r.reservationStatus || r.status)])
132
- }, n(N(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)
133
133
  ]),
134
- e("td", ee, n(T(r.reservationPrice)), 1)
134
+ e("td", te, n(C(r.reservationPrice)), 1)
135
135
  ]))), 128))
136
136
  ])
137
137
  ])
138
138
  ]),
139
- e("div", te, [
140
- e("span", se, n(a(d).length) + " appointment" + n(a(d).length === 1 ? "" : "s"), 1),
139
+ e("div", se, [
140
+ e("span", oe, n(a(d).length) + " appointment" + n(a(d).length === 1 ? "" : "s"), 1),
141
141
  c(o, {
142
- to: `/projects/${a(_)}/modules/${f.instanceId}`,
142
+ to: `/projects/${a(k)}/modules/${f.instanceId}`,
143
143
  class: "inline-flex items-center gap-1.5 text-xs text-primary hover:underline"
144
144
  }, {
145
- default: z(() => [
146
- c(a(q), { class: "size-3" }),
147
- s[3] || (s[3] = E(" View all ", -1))
145
+ default: E(() => [
146
+ c(a(M), { class: "size-3" }),
147
+ s[3] || (s[3] = V(" View all ", -1))
148
148
  ]),
149
149
  _: 1
150
150
  }, 8, ["to"])
@@ -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,18 +1,18 @@
1
- import { defineComponent as j, computed as y, ref as v, onMounted as B, resolveComponent as P, openBlock as l, createElementBlock as u, unref as s, createVNode as m, createElementVNode as o, toDisplayString as i, Fragment as k, renderList as R, normalizeStyle as G, createTextVNode as f, createCommentVNode as K, withCtx as O } from "vue";
2
- import { Loader2 as H, Globe as w, MousePointerClick as J, Users as Z, ExternalLink as q } from "lucide-vue-next";
3
- const Q = { class: "w-full" }, W = {
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";
3
+ const W = { class: "w-full" }, X = {
4
4
  key: 0,
5
5
  class: "flex items-center gap-2 py-3"
6
- }, X = {
6
+ }, Y = {
7
7
  key: 1,
8
8
  class: "text-xs text-destructive py-2"
9
- }, Y = {
9
+ }, ee = {
10
10
  key: 2,
11
11
  class: "rounded-xl border bg-background p-4 text-center space-y-2"
12
- }, ee = {
12
+ }, te = {
13
13
  key: 3,
14
14
  class: "rounded-xl border bg-background overflow-hidden"
15
- }, te = { class: "px-3 py-2 border-b bg-muted/40 flex items-center justify-between" }, se = { class: "flex items-center gap-2" }, oe = { class: "text-[10px] text-muted-foreground" }, ne = { class: "divide-y" }, ae = { class: "flex items-center gap-2 mb-1.5" }, re = { class: "text-sm shrink-0" }, ie = { class: "text-xs font-medium truncate flex-1" }, de = { class: "text-[10px] text-muted-foreground" }, le = { class: "ml-7 space-y-1.5" }, ue = { class: "h-1.5 rounded-full bg-muted overflow-hidden" }, ce = { class: "flex items-center gap-3 text-[10px] text-muted-foreground" }, me = { class: "flex items-center gap-1" }, pe = { class: "flex items-center gap-1" }, fe = { class: "px-3 py-2 border-t bg-muted/20 flex items-center justify-between" }, ge = { class: "text-[10px] text-muted-foreground" }, ve = /* @__PURE__ */ j({
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({
16
16
  __name: "CountryBreakdownCard",
17
17
  props: {
18
18
  toolName: {},
@@ -24,7 +24,7 @@ const Q = { class: "w-full" }, W = {
24
24
  },
25
25
  emits: ["submit"],
26
26
  setup(_, { emit: A }) {
27
- const { $useRoute: $, $useModuleOverlay: xe } = useNuxtApp(), c = _, C = A, N = $(), L = y(() => N.params.slug), z = $useModuleApi(c.instanceId), g = v(!0), p = v(null), n = v([]), x = v(null), D = (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) => ({
28
28
  "United States": "🇺🇸",
29
29
  "United Kingdom": "🇬🇧",
30
30
  Germany: "🇩🇪",
@@ -72,7 +72,7 @@ const Q = { class: "w-full" }, W = {
72
72
  Greece: "🇬🇷",
73
73
  Luxembourg: "🇱🇺"
74
74
  })[e] || "🌍";
75
- function U() {
75
+ function F() {
76
76
  const e = c.resolvedArgs?._cachedData;
77
77
  return e ? (n.value = (e.countries || []).map((t) => ({
78
78
  country: t.country,
@@ -80,15 +80,15 @@ const Q = { class: "w-full" }, W = {
80
80
  totalUsers: t.users
81
81
  })), x.value = c.resolvedArgs._fetchedAt || null, g.value = !1, !0) : !1;
82
82
  }
83
- async function F() {
83
+ async function I() {
84
84
  const { startDate: e, endDate: t } = c.resolvedArgs || {};
85
85
  g.value = !0, p.value = null;
86
86
  try {
87
87
  const a = new URLSearchParams();
88
88
  e && a.set("startDate", e), t && a.set("endDate", t);
89
- const r = await z.get(`/countries?${a.toString()}`);
89
+ const r = await D.get(`/countries?${a.toString()}`);
90
90
  n.value = r.rows || [], x.value = (/* @__PURE__ */ new Date()).toISOString();
91
- const h = n.value.reduce((d, T) => d + (T.sessions || 0), 0);
91
+ const h = n.value.reduce((d, j) => d + (j.sessions || 0), 0);
92
92
  b({
93
93
  count: n.value.length,
94
94
  countries: n.value.map((d) => ({
@@ -105,82 +105,82 @@ const Q = { class: "w-full" }, W = {
105
105
  g.value = !1;
106
106
  }
107
107
  }
108
- B(() => {
109
- c.status === "completed" && U() || F();
108
+ P(() => {
109
+ c.status === "completed" && F() || I();
110
110
  });
111
111
  function b(e) {
112
- c.status !== "completed" && C("submit", e);
112
+ c.status !== "completed" && $("submit", e);
113
113
  }
114
- const S = (e) => e == null ? "0" : Math.round(e).toLocaleString(), I = (e) => e ? new Date(e).toLocaleString(void 0, { month: "short", day: "numeric", hour: "2-digit", minute: "2-digit" }) : "", M = 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(
115
115
  () => n.value.reduce((e, t) => e + (t.sessions || 0), 0) || 1
116
- ), V = y(
116
+ ), E = y(
117
117
  () => Math.max(...n.value.map((e) => e.sessions || 0), 1)
118
- ), E = y(() => {
118
+ ), T = y(() => {
119
119
  const { startDate: e, endDate: t } = c.resolvedArgs || {};
120
120
  if (!e && !t) return "Last 30 days";
121
121
  const a = e || "30daysAgo", r = a.match(/^(\d+)daysAgo$/);
122
122
  return r ? `Last ${r[1]} days` : `${a} → ${t || "today"}`;
123
123
  });
124
124
  return (e, t) => {
125
- const a = P("NuxtLink");
126
- return l(), u("div", Q, [
127
- s(g) ? (l(), u("div", W, [
128
- m(s(H), { class: "size-4 animate-spin text-muted-foreground" }),
125
+ const a = R("NuxtLink");
126
+ return l(), u("div", W, [
127
+ s(g) ? (l(), u("div", X, [
128
+ m(s(O), { class: "size-4 animate-spin text-muted-foreground" }),
129
129
  t[0] || (t[0] = o("span", { class: "text-xs text-muted-foreground" }, "Loading country data…", -1))
130
- ])) : s(p) ? (l(), u("div", X, i(s(p)), 1)) : s(n).length === 0 ? (l(), u("div", Y, [
130
+ ])) : s(p) ? (l(), u("div", Y, i(s(p)), 1)) : s(n).length === 0 ? (l(), u("div", ee, [
131
131
  m(s(w), { class: "size-8 text-muted-foreground mx-auto" }),
132
132
  t[1] || (t[1] = o("p", { class: "text-sm text-muted-foreground" }, "No geographic data found for this period.", -1))
133
- ])) : (l(), u("div", ee, [
134
- o("div", te, [
135
- o("div", se, [
133
+ ])) : (l(), u("div", te, [
134
+ o("div", se, [
135
+ o("div", oe, [
136
136
  m(s(w), { class: "size-3.5 text-primary" }),
137
137
  t[2] || (t[2] = o("span", { class: "text-xs font-medium" }, "Visitors by Country", -1))
138
138
  ]),
139
- o("span", oe, i(s(E)), 1)
139
+ o("span", ne, i(s(T)), 1)
140
140
  ]),
141
- o("div", ne, [
142
- (l(!0), u(k, null, R(s(n), (r, h) => (l(), u("div", {
141
+ o("div", ae, [
142
+ (l(!0), u(k, null, G(s(n), (r, h) => (l(), u("div", {
143
143
  key: h,
144
144
  class: "px-3 py-2.5 hover:bg-muted/30 transition-colors"
145
145
  }, [
146
- o("div", ae, [
147
- o("span", re, i(D(r.country)), 1),
148
- o("span", ie, i(r.country), 1),
149
- o("span", de, i((r.sessions / s(M) * 100).toFixed(1)) + "%", 1)
146
+ o("div", re, [
147
+ o("span", ie, i(U(r.country)), 1),
148
+ o("span", de, i(r.country), 1),
149
+ o("span", le, i((r.sessions / s(V) * 100).toFixed(1)) + "%", 1)
150
150
  ]),
151
- o("div", le, [
152
- o("div", ue, [
151
+ o("div", ue, [
152
+ o("div", ce, [
153
153
  o("div", {
154
154
  class: "h-full rounded-full bg-blue-500/70 transition-all",
155
- style: G({ width: `${r.sessions / s(V) * 100}%` })
155
+ style: K({ width: `${r.sessions / s(E) * 100}%` })
156
156
  }, null, 4)
157
157
  ]),
158
- o("div", ce, [
159
- o("span", me, [
160
- m(s(J), { class: "size-2.5" }),
161
- f(" " + i(S(r.sessions)) + " sessions ", 1)
162
- ]),
158
+ o("div", me, [
163
159
  o("span", pe, [
164
160
  m(s(Z), { class: "size-2.5" }),
161
+ f(" " + i(S(r.sessions)) + " sessions ", 1)
162
+ ]),
163
+ o("span", fe, [
164
+ m(s(q), { class: "size-2.5" }),
165
165
  f(" " + i(S(r.totalUsers)) + " users ", 1)
166
166
  ])
167
167
  ])
168
168
  ])
169
169
  ]))), 128))
170
170
  ]),
171
- o("div", fe, [
172
- o("span", ge, [
171
+ o("div", ge, [
172
+ o("span", xe, [
173
173
  f(i(s(n).length) + " countr" + i(s(n).length === 1 ? "y" : "ies") + " ", 1),
174
174
  s(x) ? (l(), u(k, { key: 0 }, [
175
- f(" · fetched " + i(I(s(x))), 1)
176
- ], 64)) : K("", !0)
175
+ f(" · fetched " + i(M(s(x))), 1)
176
+ ], 64)) : H("", !0)
177
177
  ]),
178
178
  m(a, {
179
- to: `/projects/${s(L)}/modules/${_.instanceId}`,
179
+ to: `/projects/${s(z)}/modules/${_.instanceId}`,
180
180
  class: "inline-flex items-center gap-1.5 text-xs text-primary hover:underline"
181
181
  }, {
182
- default: O(() => [
183
- m(s(q), { class: "size-3" }),
182
+ default: J(() => [
183
+ m(s(Q), { class: "size-3" }),
184
184
  t[3] || (t[3] = f(" View full report ", -1))
185
185
  ]),
186
186
  _: 1
@@ -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;