@feedmepos/mf-connect 0.1.98-beta.47 → 0.1.98-beta.49

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 (121) hide show
  1. package/dist/{App-JFPlzU0L.js → App-DpEetYST.js} +8 -8
  2. package/dist/{AuditLogs-Bk6QCZgp.js → AuditLogs-Cmo803hX.js} +10 -10
  3. package/dist/{Bin-CHi79olc.js → Bin-DJfXzuaK.js} +8 -8
  4. package/dist/{Broadcast-DSicPemE.js → Broadcast-CNgV44yY.js} +11 -11
  5. package/dist/{CampaignAnalytic-B3czdnvb.js → CampaignAnalytic-B2Rn2EJg.js} +6 -6
  6. package/dist/{CampaignTypeDialog.vue_vue_type_script_setup_true_lang-CkC0A-ix.js → CampaignTypeDialog.vue_vue_type_script_setup_true_lang-Bns7bxjM.js} +7 -7
  7. package/dist/{Card-Begf7uD_.js → Card-B2VUzTu-.js} +20 -20
  8. package/dist/{Collections-BSmTzG4a.js → Collections-CND1NP87.js} +8 -8
  9. package/dist/{Credit-BqZ9lr6S.js → Credit-DVwWQVhX.js} +12 -12
  10. package/dist/{EditCampaignSheet.vue_vue_type_script_setup_true_lang-qMqks3fR.js → EditCampaignSheet.vue_vue_type_script_setup_true_lang-BAkLmXrV.js} +34 -35
  11. package/dist/{EffectSheet.vue_vue_type_style_index_0_lang-Ck2PxSye.js → EffectSheet.vue_vue_type_style_index_0_lang-C_iJZVqp.js} +16 -16
  12. package/dist/{Experience-i0bu7uAI.js → Experience-byIWULhh.js} +12 -12
  13. package/dist/{FileSaver.min-Ck6lXfKM.js → FileSaver.min-CaXtjHRv.js} +1 -1
  14. package/dist/{Game-Be02GnjR.js → Game-tzliFFnf.js} +13 -13
  15. package/dist/{GiftCardSetup-DPN3NhND.js → GiftCardSetup-CUZn8cQ_.js} +9 -9
  16. package/dist/{Grab-BKIYI2d-.js → Grab-Bj955oc2.js} +9 -9
  17. package/dist/{ImageInput.vue_vue_type_script_setup_true_lang-BqylTCHX.js → ImageInput.vue_vue_type_script_setup_true_lang-DM6s0VaT.js} +1 -1
  18. package/dist/{Index-BD_l8T_M.js → Index-qie7NJrQ.js} +10 -10
  19. package/dist/{LocationPicker.vue_vue_type_script_setup_true_lang-Cch5RizQ.js → LocationPicker.vue_vue_type_script_setup_true_lang-DN_0AboA.js} +1 -1
  20. package/dist/{LottieAnimation.vue_vue_type_script_setup_true_lang-D3psJutm.js → LottieAnimation.vue_vue_type_script_setup_true_lang-CrDegDYa.js} +1 -1
  21. package/dist/LoyaltyDashboard-D_SjNwRv.js +2218 -0
  22. package/dist/{MainLayout-C96xSNND.js → MainLayout-B4LQ7fj3.js} +3 -3
  23. package/dist/{Marketing-Bg6DFKg5.js → Marketing-BP2jjkGw.js} +4 -4
  24. package/dist/{MarketingMaterialEdit-BYbWgB2R.js → MarketingMaterialEdit-BDP-tlCV.js} +6 -6
  25. package/dist/Member-BIT0lu05.js +642 -0
  26. package/dist/MemberDetailSheet.vue_vue_type_script_setup_true_lang-CmR5L_FZ.js +1287 -0
  27. package/dist/{MemberImportHistory-Bw-M3Zx-.js → MemberImportHistory-CXq5k3za.js} +26 -24
  28. package/dist/MemberList-DgQrAUhF.js +336 -0
  29. package/dist/{MemberTransactions-DEzFrc9e.js → MemberTransactions-SD0EK9MQ.js} +1 -1
  30. package/dist/{MessageInput.vue_vue_type_script_setup_true_lang-CFpMazFG.js → MessageInput.vue_vue_type_script_setup_true_lang-B_P--gRo.js} +10 -10
  31. package/dist/{Mission-CWeWfTdC.js → Mission-Dcc8TywU.js} +13 -13
  32. package/dist/{Overview-CPMN5kuM.js → Overview-2n-3zYgT.js} +3 -3
  33. package/dist/{Overview-De06lJt0.js → Overview-ClsCoDwC.js} +19 -19
  34. package/dist/{Point-XfVYDIbj.js → Point-yoPNIfen.js} +12 -12
  35. package/dist/{Promotion-Q646p6RE.js → Promotion-Bo8fwRxo.js} +13 -13
  36. package/dist/{Queue-BNfc0ySV.js → Queue-DOMCJIfy.js} +11 -11
  37. package/dist/{Record-Dx5pZmpm.js → Record-B_GFsmRS.js} +9 -9
  38. package/dist/{Review-BX5Z5ivr.js → Review-D-UnLgKx.js} +2 -2
  39. package/dist/{ReviewFacebookCallback-B6GFP04-.js → ReviewFacebookCallback-CSkzBR52.js} +5 -5
  40. package/dist/{ReviewGoogleCallback-BWgxTbuf.js → ReviewGoogleCallback-DXW6TAxP.js} +5 -5
  41. package/dist/{Reward-DOImZVUL.js → Reward-CqNDQ5fM.js} +16 -16
  42. package/dist/{RewardGroup.vue_vue_type_script_setup_true_lang-8fuZmrBK.js → RewardGroup.vue_vue_type_script_setup_true_lang-CZPtIroB.js} +12 -12
  43. package/dist/{RuleGroup.vue_vue_type_script_setup_true_lang-C9kWB5Zw.js → RuleGroup.vue_vue_type_script_setup_true_lang-xzJ738TT.js} +15 -15
  44. package/dist/{Segment-BndDCfLd.js → Segment-B3keIMfg.js} +33 -34
  45. package/dist/{SelectItems.vue_vue_type_script_setup_true_lang-DV1X7e-_.js → SelectItems.vue_vue_type_script_setup_true_lang-B1IbP3lO.js} +2 -2
  46. package/dist/{SendCollectionSheet.vue_vue_type_script_setup_true_lang-O9ohGQxg.js → SendCollectionSheet.vue_vue_type_script_setup_true_lang-BvrNFNDo.js} +13 -13
  47. package/dist/{SendVoucherSheet.vue_vue_type_script_setup_true_lang-D2knZbHq.js → SendVoucherSheet.vue_vue_type_script_setup_true_lang-BtJyfV2S.js} +4 -4
  48. package/dist/{Setting-DPm0lJmq.js → Setting-CUf7r25C.js} +14 -14
  49. package/dist/{SettingAdvertisements-DdPGyRNI.js → SettingAdvertisements-BnfH2GWe.js} +12 -12
  50. package/dist/{Settings-BQPDUWyz.js → Settings-CVyEvBdL.js} +5 -5
  51. package/dist/{Store-Cw-c2Wgl.js → Store-yJsGBJjp.js} +24 -24
  52. package/dist/{StoreRewards-CYkHL-h6.js → StoreRewards-E009h_Ki.js} +15 -15
  53. package/dist/{StoreTransactions.vue_vue_type_script_setup_true_lang-DClGeare.js → StoreTransactions.vue_vue_type_script_setup_true_lang-dFIK3_9i.js} +22 -22
  54. package/dist/{TargetLocationInput.vue_vue_type_script_setup_true_lang-DekQ8_F8.js → TargetLocationInput.vue_vue_type_script_setup_true_lang-BWytuBNh.js} +2 -2
  55. package/dist/{Tier-B7QmbFn8.js → Tier-D6l8QcgM.js} +25 -25
  56. package/dist/{Title-CRM_l4YE.js → Title-CKdZ_ulb.js} +22 -22
  57. package/dist/{Transaction-C1jXS8Le.js → Transaction-CHzWDrMp.js} +2 -2
  58. package/dist/{UserRuleGroup.vue_vue_type_script_setup_true_lang-yPF04Hth.js → UserRuleGroup.vue_vue_type_script_setup_true_lang-D5-CNeZh.js} +6 -6
  59. package/dist/{Voucher-Cfh_Wudx.js → Voucher-g84i_O99.js} +14 -14
  60. package/dist/{VoucherEditor.vue_vue_type_script_setup_true_lang-BkiXzbFh.js → VoucherEditor.vue_vue_type_script_setup_true_lang-HofDeLRx.js} +12 -12
  61. package/dist/{ZodTextField.vue_vue_type_script_setup_true_lang-BEFynSZm.js → ZodTextField.vue_vue_type_script_setup_true_lang-B2QIFX1P.js} +2 -2
  62. package/dist/{app-CEWVaJEZ.js → app-CVfoAVMp.js} +238 -238
  63. package/dist/app.js +1 -1
  64. package/dist/{business-DWLMb2lG.js → business-DZUUnIjL.js} +1 -1
  65. package/dist/{campaign-DwYJGuSz.js → campaign-BIbDOJuM.js} +8 -8
  66. package/dist/{campaign-DRJO5ydK.js → campaign-CI_rZpSy.js} +2 -2
  67. package/dist/{campaign.enum-Dx-Zo68Q.js → campaign.enum-BBJZPv79.js} +1 -1
  68. package/dist/{campaign.fn-CPfN51jT.js → campaign.fn-BSKTKKn_.js} +57 -57
  69. package/dist/{collectible.enum-Liy2wH3s.js → collectible.enum-Bpd7su_n.js} +1 -1
  70. package/dist/{collection.fn-j4_hDjjy.js → collection.fn-CGLzb4iJ.js} +2 -2
  71. package/dist/{duplicateCampaign-CQ-yfh9b.js → duplicateCampaign-DvYTuIU-.js} +2 -2
  72. package/dist/{effect-DU8lcl8m.js → effect-DeuwDSDb.js} +1 -1
  73. package/dist/{email-addresses-DUpMDrGS.js → email-addresses-CXSJ6d0R.js} +2 -2
  74. package/dist/{export-BFMh5l4w.js → export-DMrK_zVs.js} +3 -3
  75. package/dist/{helper-DSvUKuiG.js → helper-CuwR4Iok.js} +1 -1
  76. package/dist/{index-JlyOHqyG.js → index-BGM2LdBN.js} +3 -3
  77. package/dist/{index-CWbvBvE3.js → index-BIE7IDVs.js} +2 -2
  78. package/dist/{index-DD3Jlx01.js → index-BnF40VHU.js} +1 -1
  79. package/dist/{index-rZdY3BW8.js → index-Br-IwWs2.js} +7 -7
  80. package/dist/{index-C69TnizM.js → index-BsGpbfSM.js} +1 -1
  81. package/dist/{index-CDyGueuB.js → index-BsL2fRDR.js} +82 -83
  82. package/dist/{index-D8_jwrSU.js → index-BtCff_X4.js} +1 -1
  83. package/dist/{index--mkEqsYz.js → index-CVshuS9x.js} +2 -2
  84. package/dist/{index-CrKfbYDf.js → index-CmXN0dX2.js} +281 -283
  85. package/dist/{index-CvVrgPmm.js → index-CsKzQMVH.js} +10766 -8027
  86. package/dist/{index-CuyxKvmh.js → index-D0RwTeSK.js} +7 -8
  87. package/dist/{index-CvaF2wtX.js → index-Di34zXvz.js} +1 -1
  88. package/dist/{index-DCbCuJXP.js → index-DtlEsLvC.js} +1 -1
  89. package/dist/{index-B-tBxRw2.js → index-KJ9fWfKI.js} +2 -2
  90. package/dist/{index-DLZ_cPwd.js → index-Z1kANjy2.js} +1 -1
  91. package/dist/{index-D-swy6qD.js → index-mkULcMHp.js} +1 -1
  92. package/dist/{index-CWEtTfxy.js → index-ux77Q19k.js} +24 -25
  93. package/dist/{index-BVWwOMHO.js → index-v0Wp7wZh.js} +11 -12
  94. package/dist/{index.esm2017-B2wpsz6n.js → index.esm2017-7ccdC84w.js} +132 -132
  95. package/dist/{loading-BHHf9MeD.js → loading-CRmkbq3n.js} +1 -1
  96. package/dist/{lodash-zHycpMIs.js → lodash-Bc-ryXNQ.js} +1 -1
  97. package/dist/{member-import-MTwvl8TG.js → member-import-DlkhFBuH.js} +8 -8
  98. package/dist/{membership-Ctqa96gd.js → membership-B26RzkXD.js} +3 -3
  99. package/dist/{money-C9m7TfMA.js → money-DQctndhn.js} +1 -1
  100. package/dist/{number-ng88zCwj.js → number-Bf6ikkos.js} +1 -1
  101. package/dist/objectid-rBYoX-d0.js +145 -0
  102. package/dist/{plugins-MY2whJpz.js → plugins-C67nSbj6.js} +3 -3
  103. package/dist/{reward-DiiV8MQE.js → reward-C43tP4ms.js} +1 -1
  104. package/dist/{rule-builder-BVEerrEc.js → rule-builder-C8VKx9qo.js} +1 -1
  105. package/dist/{rule-C31n55fZ.js → rule-ferkW3Tn.js} +3 -3
  106. package/dist/{template-CtcRYRZb.js → template-6TQsSBnV.js} +6 -6
  107. package/dist/{timezone-Ck4iMIrt.js → timezone-CHLqfxGX.js} +1 -1
  108. package/dist/{transaction.fn-BI0-LgQG.js → transaction.fn-Ck4GNkX8.js} +1 -1
  109. package/dist/{trigger-_5hAtyky.js → trigger-DW-HI3-m.js} +5 -5
  110. package/dist/{useMarketingMaterialActions-CX9qJp_O.js → useMarketingMaterialActions-DgjXENGq.js} +3 -3
  111. package/dist/{usePagination-DZKDMzEh.js → usePagination-DK5YxY0V.js} +1 -1
  112. package/dist/{user-C-Db5JiY.js → user-CEgC8bHe.js} +1 -1
  113. package/dist/{vue-i18n-BbF7bmsx.js → vue-i18n-CVwaGWN7.js} +237 -237
  114. package/dist/{xlsx-CzpvTfCU.js → xlsx-BjSGml1D.js} +440 -440
  115. package/dist/{zod-HtL78lno.js → zod-CIM7JLfN.js} +1 -1
  116. package/package.json +3 -1
  117. package/dist/LoyaltyDashboard-D0eq0Gaw.js +0 -1345
  118. package/dist/Member-B4NAFx8G.js +0 -573
  119. package/dist/MemberList-DXpa6_Rb.js +0 -1603
  120. package/dist/index-C_H8jFYf.js +0 -2743
  121. package/dist/objectid-BTsufz4u.js +0 -145
@@ -0,0 +1,2218 @@
1
+ import { defineComponent as H, resolveComponent as _, openBlock as l, createBlock as O, withCtx as L, createElementVNode as t, createVNode as p, unref as n, createTextVNode as j, createElementBlock as c, Fragment as D, renderList as V, normalizeClass as z, toDisplayString as d, createCommentVNode as q, normalizeStyle as ct, mergeModels as ut, useModel as pt, ref as h, computed as M, watch as Ae, onBeforeUnmount as ft, isRef as Ye, withKeys as Xe, withModifiers as Ze, nextTick as rt, onMounted as yt } from "vue";
2
+ import { h as Ee } from "./moment-D7p2TMB-.js";
3
+ import { g as P, S as bt, b as vt, c as gt } from "./index-CVshuS9x.js";
4
+ import { RouterLink as ot, useRouter as ht } from "vue-router";
5
+ import { c as xt } from "./index-KJ9fWfKI.js";
6
+ import { _ as ue } from "./MetricInfoTooltip.vue_vue_type_script_setup_true_lang-Bg_0YlwG.js";
7
+ import { m as _t } from "./index-BIE7IDVs.js";
8
+ import { _ as st } from "./FilterChip.vue_vue_type_script_setup_true_lang-DaU-9GzO.js";
9
+ import { _ as je } from "./DateRangeChip.vue_vue_type_script_setup_true_lang-eIoPtgO5.js";
10
+ import { _ as wt } from "./MemberDetailSheet.vue_vue_type_script_setup_true_lang-CmR5L_FZ.js";
11
+ import { c as Rt } from "./plugins-C67nSbj6.js";
12
+ import { m as Se } from "./index-Di34zXvz.js";
13
+ import { t as St } from "./money-DQctndhn.js";
14
+ import { u as Mt } from "./loading-CRmkbq3n.js";
15
+ import { u as $t } from "./business-DZUUnIjL.js";
16
+ import { C as et } from "./timezone-CHLqfxGX.js";
17
+ import { useCoreStore as Ct } from "@feedmepos/mf-common";
18
+ const At = { class: "flex items-center mb-14" }, Dt = {
19
+ key: 0,
20
+ class: "fm-typo-en-body-sm-400 text-fm-color-typo-secondary py-10"
21
+ }, Ft = {
22
+ key: 1,
23
+ class: "fm-typo-en-body-sm-400 text-fm-color-typo-secondary py-10"
24
+ }, It = {
25
+ key: 2,
26
+ class: "flex flex-col"
27
+ }, kt = { class: "flex-1 min-w-0" }, Lt = { class: "fm-typo-en-body-sm-600 whitespace-nowrap overflow-hidden text-ellipsis" }, Et = { class: "fm-typo-en-body-sm-400 text-fm-color-typo-tertiary mt-2" }, Pt = { class: "text-right flex-shrink-0" }, Tt = { class: "fm-typo-en-body-lg-600" }, Nt = { class: "fm-typo-en-body-sm-400 text-fm-color-typo-tertiary mt-2" }, Ot = {
28
+ key: 3,
29
+ class: "fm-typo-en-body-sm-400 text-fm-color-typo-secondary py-10"
30
+ }, Bt = /* @__PURE__ */ H({
31
+ __name: "CampaignActivityList",
32
+ props: {
33
+ campaigns: {},
34
+ loading: { type: Boolean },
35
+ error: { type: Boolean }
36
+ },
37
+ setup(e) {
38
+ return (o, r) => {
39
+ const i = _("FmCard");
40
+ return l(), O(i, {
41
+ variant: "outlined",
42
+ class: "p-24"
43
+ }, {
44
+ default: L(() => [
45
+ t("div", At, [
46
+ r[1] || (r[1] = t("div", { class: "flex-1 fm-typo-en-body-md-600" }, "Recent campaigns", -1)),
47
+ p(n(ot), {
48
+ to: "/campaign",
49
+ class: "fm-typo-en-body-sm-600 text-fm-color-primary no-underline"
50
+ }, {
51
+ default: L(() => [...r[0] || (r[0] = [
52
+ j(" All campaigns ", -1)
53
+ ])]),
54
+ _: 1
55
+ })
56
+ ]),
57
+ e.loading ? (l(), c("div", Dt, " Loading campaigns. ")) : e.error ? (l(), c("div", Ft, " Unable to load campaigns. ")) : e.campaigns.length ? (l(), c("div", It, [
58
+ (l(!0), c(D, null, V(e.campaigns, (s) => (l(), c("div", {
59
+ key: s.id,
60
+ class: "flex items-start gap-10 py-10 border-b border-fm-color-neutral-gray-100 last:border-b-0"
61
+ }, [
62
+ t("div", {
63
+ class: z(["w-7 h-7 rounded-full bg-current flex-shrink-0 mt-5", s.statusClass])
64
+ }, null, 2),
65
+ t("div", kt, [
66
+ t("div", Lt, d(s.name), 1),
67
+ t("div", Et, d(s.type), 1)
68
+ ]),
69
+ t("div", Pt, [
70
+ t("div", Tt, d(s.metric), 1),
71
+ t("div", Nt, d(s.metricLabel), 1)
72
+ ])
73
+ ]))), 128))
74
+ ])) : (l(), c("div", Ot, " No campaigns are available for this location. "))
75
+ ]),
76
+ _: 1
77
+ });
78
+ };
79
+ }
80
+ }), Ut = { class: "flex items-center gap-8" }, zt = { class: "w-[30px] h-[30px] bg-fm-color-primary-oats flex items-center justify-center flex-shrink-0 fm-corner-radius-md" }, Vt = { class: "bg-fm-color-primary-oats p-14 fm-corner-radius-md" }, Yt = { class: "fm-typo-en-body-md-600 mb-6" }, jt = { class: "fm-typo-en-body-sm-400 text-fm-color-typo-secondary" }, qt = { class: "flex flex-col gap-6" }, Wt = { class: "border-t border-fm-color-neutral-gray-100 pt-12 flex flex-col gap-3" }, Ht = { class: "fm-typo-en-body-sm-400 text-fm-color-typo-secondary" }, Gt = {
81
+ key: 1,
82
+ class: "bg-fm-color-neutral-gray-100 rounded-10 p-14 fm-typo-en-body-sm-400 text-fm-color-typo-secondary"
83
+ }, Kt = /* @__PURE__ */ H({
84
+ __name: "InsightPanel",
85
+ props: {
86
+ insight: {}
87
+ },
88
+ emits: ["navigate"],
89
+ setup(e, { emit: o }) {
90
+ const r = o;
91
+ return (i, s) => {
92
+ const m = _("FmIcon"), y = _("FmButton"), v = _("FmCard");
93
+ return l(), O(v, {
94
+ variant: "outlined",
95
+ class: "p-24 flex flex-col gap-14"
96
+ }, {
97
+ default: L(() => [
98
+ t("div", Ut, [
99
+ t("div", zt, [
100
+ p(m, {
101
+ name: "info",
102
+ outline: "",
103
+ size: "sm",
104
+ class: "!text-fm-color-primary"
105
+ })
106
+ ]),
107
+ s[1] || (s[1] = t("div", { class: "fm-typo-en-body-md-600" }, "Action insight", -1))
108
+ ]),
109
+ e.insight ? (l(), c(D, { key: 0 }, [
110
+ t("div", Vt, [
111
+ t("div", Yt, d(e.insight.title), 1),
112
+ t("div", jt, d(e.insight.body), 1)
113
+ ]),
114
+ t("div", qt, [
115
+ s[2] || (s[2] = t("div", { class: "fm-typo-en-body-sm-600 text-fm-color-typo-tertiary uppercase tracking-wide mb-1" }, " Suggested action ", -1)),
116
+ p(y, {
117
+ label: e.insight.action.label,
118
+ "append-icon": "arrow_forward",
119
+ class: "!justify-between",
120
+ onClick: s[0] || (s[0] = (g) => r("navigate", e.insight.action.path))
121
+ }, null, 8, ["label"])
122
+ ]),
123
+ t("div", Wt, [
124
+ s[3] || (s[3] = t("div", { class: "fm-typo-en-body-sm-600 text-fm-color-typo-tertiary uppercase tracking-wide mb-1" }, " Supporting signal ", -1)),
125
+ (l(!0), c(D, null, V(e.insight.signals, (g) => (l(), c("li", {
126
+ key: g.text,
127
+ class: "flex items-start gap-7"
128
+ }, [
129
+ t("ul", Ht, d(g.text), 1)
130
+ ]))), 128))
131
+ ])
132
+ ], 64)) : (l(), c("div", Gt, " More member activity is needed before a clear action can be suggested. "))
133
+ ]),
134
+ _: 1
135
+ });
136
+ };
137
+ }
138
+ }), Jt = { class: "grid grid-cols-5 xs:grid-cols-2 gap-12" }, Qt = { class: "flex items-center gap-8" }, Xt = { class: "w-[30px] h-[30px] rounded-8 bg-[#FFF6EE] flex items-center justify-center flex-shrink-0" }, Zt = { class: "fm-typo-en-body-sm-600 text-fm-color-typo-secondary flex-1 min-w-0" }, er = { class: "fm-typo-en-title-sm-800 text-fm-color-typo-primary whitespace-nowrap overflow-hidden text-ellipsis" }, tr = {
139
+ key: 0,
140
+ class: "text-fm-color-typo-success fm-typo-en-body-sm-600 -mt-4"
141
+ }, rr = { class: "flex items-center gap-4 flex-wrap" }, or = /* @__PURE__ */ H({
142
+ __name: "KpiStrip",
143
+ props: {
144
+ kpis: {}
145
+ },
146
+ setup(e) {
147
+ return (o, r) => {
148
+ const i = _("FmIcon"), s = _("FmCard");
149
+ return l(), c("section", Jt, [
150
+ (l(!0), c(D, null, V(e.kpis, (m) => (l(), O(s, {
151
+ key: m.label,
152
+ variant: "outlined",
153
+ class: "flex flex-col gap-8 p-16 min-w-0 overflow-hidden"
154
+ }, {
155
+ default: L(() => [
156
+ t("div", Qt, [
157
+ t("div", Xt, [
158
+ p(i, {
159
+ name: m.icon,
160
+ outline: "",
161
+ size: "sm",
162
+ class: "!text-fm-color-primary"
163
+ }, null, 8, ["name"])
164
+ ]),
165
+ t("span", Zt, d(m.label), 1),
166
+ p(ue, {
167
+ description: m.description
168
+ }, null, 8, ["description"])
169
+ ]),
170
+ t("div", er, d(m.value), 1),
171
+ m.sub ? (l(), c("div", tr, d(m.sub), 1)) : q("", !0),
172
+ t("div", rr, [
173
+ m.delta !== "0%" && m.delta !== "0pp" ? (l(), O(i, {
174
+ key: 0,
175
+ name: m.trendUp ? "trending_up" : "trending_down",
176
+ size: "xs",
177
+ class: z(m.deltaClass)
178
+ }, null, 8, ["name", "class"])) : q("", !0),
179
+ t("span", {
180
+ class: z(["fm-typo-en-body-sm-600", m.deltaClass])
181
+ }, d(m.delta), 3),
182
+ r[0] || (r[0] = t("span", { class: "fm-typo-en-body-sm-400 text-fm-color-typo-tertiary" }, "vs prev", -1))
183
+ ])
184
+ ]),
185
+ _: 2
186
+ }, 1024))), 128))
187
+ ]);
188
+ };
189
+ }
190
+ }), sr = { class: "flex flex-col gap-4" }, ar = ["onClick"], nr = { class: "fm-typo-en-body-sm-600" }, lr = { class: "fm-typo-en-body-md-600 min-w-[38px] text-right" }, ir = { class: "fm-typo-en-body-sm-400 text-fm-color-typo-tertiary min-w-[34px] text-right" }, dr = { class: "mt-14 pt-12 border-t border-fm-color-neutral-gray-100 fm-typo-en-body-sm-400 text-fm-color-typo-secondary" }, mr = /* @__PURE__ */ H({
191
+ __name: "LifecycleSegments",
192
+ props: {
193
+ segments: {},
194
+ summary: {},
195
+ interactive: { type: Boolean, default: !0 }
196
+ },
197
+ emits: ["select"],
198
+ setup(e, { emit: o }) {
199
+ const r = e, i = o;
200
+ return (s, m) => {
201
+ const y = _("FmProgressBar"), v = _("FmCard");
202
+ return l(), O(v, {
203
+ variant: "outlined",
204
+ class: "p-24"
205
+ }, {
206
+ default: L(() => [
207
+ m[0] || (m[0] = t("div", { class: "flex items-center mb-16" }, [
208
+ t("div", { class: "flex-1 fm-typo-en-body-md-600" }, "Member lifecycle")
209
+ ], -1)),
210
+ t("div", sr, [
211
+ (l(!0), c(D, null, V(r.segments, (g) => (l(), c("div", {
212
+ key: g.id,
213
+ class: z([
214
+ "flex items-center gap-9 px-6 py-3 -mx-6 rounded-8",
215
+ r.interactive ? "cursor-pointer hover:bg-fm-color-neutral-gray-100/50" : "cursor-default"
216
+ ]),
217
+ onClick: (x) => r.interactive && i("select", g.id)
218
+ }, [
219
+ t("div", {
220
+ class: z(["flex w-[90px] flex-shrink-0 items-center gap-3", g.labelClass])
221
+ }, [
222
+ t("span", nr, d(g.label), 1),
223
+ p(ue, {
224
+ description: g.description
225
+ }, null, 8, ["description"])
226
+ ], 2),
227
+ p(y, {
228
+ class: "flex-1",
229
+ value: g.barPct,
230
+ color: g.barColor,
231
+ size: "lg"
232
+ }, null, 8, ["value", "color"]),
233
+ t("span", lr, d(g.countStr), 1),
234
+ t("span", ir, d(g.pctStr), 1)
235
+ ], 10, ar))), 128))
236
+ ]),
237
+ t("div", dr, d(r.summary), 1)
238
+ ]),
239
+ _: 1
240
+ });
241
+ };
242
+ }
243
+ }), cr = { class: "flex items-start gap-8 mb-12" }, ur = { class: "flex-1" }, pr = { class: "fm-typo-en-body-sm-400 text-fm-color-typo-tertiary mt-4" }, fr = {
244
+ key: 0,
245
+ class: "flex items-start pl-[152px] xs:pl-0 xs:justify-center"
246
+ }, yr = { class: "flex flex-col items-start" }, br = { class: "flex items-center gap-8" }, vr = {
247
+ key: 0,
248
+ class: "fm-typo-en-body-sm-600 text-fm-color-typo-warning bg-fm-color-system-warning-100 px-8 py-[2px] rounded-xxxl whitespace-nowrap"
249
+ }, gr = ["onClick"], hr = { class: "min-w-0" }, xr = { class: "flex items-center gap-3 fm-typo-en-body-sm-600" }, _r = { class: "fm-typo-en-body-sm-400 text-fm-color-typo-secondary mt-4" }, wr = { class: "min-w-0 text-right" }, Rr = { class: "fm-typo-en-body-lg-600" }, Sr = {
250
+ key: 0,
251
+ class: "fm-typo-en-body-sm-400 text-fm-color-typo-tertiary"
252
+ }, Mr = { class: "mt-12 pt-12 border-t border-fm-color-neutral-gray-100" }, $r = { class: "fm-typo-en-body-sm-400 text-fm-color-typo-tertiary text-right" }, Cr = /* @__PURE__ */ H({
253
+ __name: "MemberFunnel",
254
+ props: {
255
+ stages: {},
256
+ footnote: {},
257
+ interactive: { type: Boolean, default: !0 }
258
+ },
259
+ emits: ["select"],
260
+ setup(e, { emit: o }) {
261
+ const r = e, i = o;
262
+ function s(m) {
263
+ r.interactive && i("select", m);
264
+ }
265
+ return (m, y) => {
266
+ const v = _("FmProgressBar"), g = _("FmCard");
267
+ return l(), O(g, {
268
+ variant: "outlined",
269
+ class: "p-24"
270
+ }, {
271
+ default: L(() => [
272
+ t("div", cr, [
273
+ t("div", ur, [
274
+ y[0] || (y[0] = t("div", { class: "fm-typo-en-body-md-600" }, "Member funnel", -1)),
275
+ t("div", pr, d(r.interactive ? "Strict member-only · visitors excluded · click any stage to drill down" : "Strict member-only · visitors excluded"), 1)
276
+ ])
277
+ ]),
278
+ (l(!0), c(D, null, V(e.stages, (x, $) => (l(), c("div", {
279
+ key: x.id
280
+ }, [
281
+ x.hasDropLine ? (l(), c("div", fr, [
282
+ t("div", yr, [
283
+ y[1] || (y[1] = t("div", { class: "w-[1px] h-[4px] bg-fm-color-neutral-gray-100 ml-[9px]" }, null, -1)),
284
+ t("div", br, [
285
+ t("span", {
286
+ class: z(["fm-typo-en-body-sm-600 px-8 py-[2px] rounded-xxxl whitespace-nowrap", x.dropClass])
287
+ }, d(x.conversionStr), 3),
288
+ x.isBiggestDrop ? (l(), c("span", vr, " biggest drop ")) : q("", !0)
289
+ ]),
290
+ y[2] || (y[2] = t("div", { class: "w-[1px] h-[4px] bg-fm-color-neutral-gray-100 ml-[9px]" }, null, -1))
291
+ ])
292
+ ])) : q("", !0),
293
+ t("div", {
294
+ class: z([
295
+ "grid grid-cols-[140px_minmax(0,1fr)_72px] xs:grid-cols-[minmax(0,1fr)_auto] items-center gap-x-12 gap-y-8 py-4 px-8 -mx-8 rounded-md",
296
+ r.interactive ? "cursor-pointer hover:bg-fm-color-neutral-gray-100/50" : ""
297
+ ]),
298
+ onClick: (F) => s(x.id)
299
+ }, [
300
+ t("div", hr, [
301
+ t("div", xr, [
302
+ t("span", null, d(x.label), 1),
303
+ p(ue, {
304
+ description: x.description
305
+ }, null, 8, ["description"])
306
+ ]),
307
+ t("div", _r, d(x.desc), 1)
308
+ ]),
309
+ p(v, {
310
+ class: "min-w-0 xs:col-span-2 xs:row-start-2",
311
+ value: x.barWidthPct,
312
+ color: x.barColor,
313
+ size: "lg"
314
+ }, null, 8, ["value", "color"]),
315
+ t("div", wr, [
316
+ t("div", Rr, d(x.countStr), 1),
317
+ x.hasConvRate ? (l(), c("div", Sr, d(x.convRateLabel), 1)) : q("", !0)
318
+ ])
319
+ ], 10, gr)
320
+ ]))), 128)),
321
+ t("div", Mr, [
322
+ t("div", $r, d(e.footnote), 1)
323
+ ])
324
+ ]),
325
+ _: 1
326
+ });
327
+ };
328
+ }
329
+ }), Ar = { class: "flex items-center gap-3 fm-typo-en-body-md-600 mb-4" }, Dr = { class: "fm-typo-en-body-sm-400 text-fm-color-typo-tertiary mb-16" }, Fr = { class: "grid grid-cols-2 xs:grid-cols-1 gap-16" }, Ir = { class: "fm-typo-en-title-sm-800" }, kr = { class: "fm-typo-en-body-sm-400 text-fm-color-typo-tertiary mt-4" }, Lr = { class: "fm-typo-en-title-sm-800" }, Er = { class: "fm-typo-en-body-sm-400 text-fm-color-typo-tertiary mt-4" }, Pr = { class: "fm-typo-en-body-sm-400 text-fm-color-typo-tertiary mt-8" }, Tr = { class: "mt-16 pt-12 border-t border-fm-color-neutral-gray-100 fm-typo-en-body-sm-400" }, Nr = /* @__PURE__ */ H({
330
+ __name: "MemberSpendComparison",
331
+ props: {
332
+ spend: {}
333
+ },
334
+ setup(e) {
335
+ return (o, r) => {
336
+ const i = _("FmProgressBar"), s = _("FmCard");
337
+ return l(), O(s, {
338
+ variant: "outlined",
339
+ class: "p-24"
340
+ }, {
341
+ default: L(() => [
342
+ t("div", Ar, [
343
+ r[0] || (r[0] = t("span", null, "Member vs. non-member spend", -1)),
344
+ p(ue, {
345
+ description: e.spend.description
346
+ }, null, 8, ["description"])
347
+ ]),
348
+ t("div", Dr, d(e.spend.description), 1),
349
+ t("div", Fr, [
350
+ t("div", null, [
351
+ r[1] || (r[1] = t("div", { class: "flex items-center gap-8 mb-8" }, [
352
+ t("div", { class: "w-8 h-8 rounded-sm bg-fm-color-primary" }),
353
+ t("span", { class: "fm-typo-en-body-sm-400 text-fm-color-typo-secondary" }, "Member sales")
354
+ ], -1)),
355
+ t("div", Ir, d(e.spend.memberSalesFmt), 1),
356
+ t("div", kr, " avg " + d(e.spend.avgMemberSaleFmt) + " / order ", 1)
357
+ ]),
358
+ t("div", null, [
359
+ r[2] || (r[2] = t("div", { class: "flex items-center gap-8 mb-8" }, [
360
+ t("div", { class: "w-8 h-8 rounded-sm bg-fm-color-neutral-gray-200" }),
361
+ t("span", { class: "fm-typo-en-body-sm-400 text-fm-color-typo-secondary" }, "Non-member sales")
362
+ ], -1)),
363
+ t("div", Lr, d(e.spend.nonMemberSalesFmt), 1),
364
+ t("div", Er, " avg " + d(e.spend.avgNonMemberSaleFmt) + " / order ", 1)
365
+ ])
366
+ ]),
367
+ p(i, {
368
+ class: "mt-16",
369
+ value: e.spend.memberSharePct,
370
+ color: "primary",
371
+ size: "md"
372
+ }, null, 8, ["value"]),
373
+ t("div", Pr, " Members drive " + d(e.spend.memberSharePct) + "% of tracked sales ", 1),
374
+ t("div", Tr, d(e.spend.summary), 1)
375
+ ]),
376
+ _: 1
377
+ });
378
+ };
379
+ }
380
+ }), Or = { class: "flex items-center mb-16" }, Br = {
381
+ key: 0,
382
+ class: "fm-typo-en-body-sm-400 text-fm-color-typo-secondary"
383
+ }, Ur = {
384
+ key: 1,
385
+ class: "fm-typo-en-body-sm-400 text-fm-color-typo-secondary"
386
+ }, zr = { class: "grid grid-cols-3 gap-10 mb-16" }, Vr = { class: "fm-typo-en-body-sm-400 text-fm-color-typo-secondary mb-4 flex items-center gap-3" }, Yr = { class: "fm-typo-en-title-sm-800" }, jr = { class: "flex flex-col gap-9" }, qr = { class: "flex-1 fm-typo-en-body-sm-400 whitespace-nowrap overflow-hidden text-ellipsis" }, Wr = { class: "flex flex-shrink-0 items-center gap-3 fm-typo-en-body-sm-600 text-fm-color-typo-secondary" }, Hr = { class: "w-[48px] h-4 bg-fm-color-neutral-gray-100 rounded-2 overflow-hidden flex-shrink-0" }, Gr = {
387
+ key: 3,
388
+ class: "fm-typo-en-body-sm-400 text-fm-color-typo-secondary"
389
+ }, Kr = /* @__PURE__ */ H({
390
+ __name: "RewardPerformance",
391
+ props: {
392
+ kpis: {},
393
+ topRewards: {},
394
+ hasData: { type: Boolean },
395
+ loading: { type: Boolean },
396
+ error: { type: Boolean }
397
+ },
398
+ setup(e) {
399
+ return (o, r) => {
400
+ const i = _("FmCard");
401
+ return l(), O(i, {
402
+ variant: "outlined",
403
+ class: "p-24"
404
+ }, {
405
+ default: L(() => [
406
+ t("div", Or, [
407
+ r[1] || (r[1] = t("div", { class: "flex-1 fm-typo-en-body-md-600" }, "Reward usage health", -1)),
408
+ p(n(ot), {
409
+ to: "/reward",
410
+ class: "fm-typo-en-body-sm-600 text-fm-color-primary no-underline"
411
+ }, {
412
+ default: L(() => [...r[0] || (r[0] = [
413
+ j(" All rewards ", -1)
414
+ ])]),
415
+ _: 1
416
+ })
417
+ ]),
418
+ e.loading ? (l(), c("div", Br, " Loading reward usage data. ")) : e.error ? (l(), c("div", Ur, " Unable to load reward usage data. ")) : e.hasData ? (l(), c(D, { key: 2 }, [
419
+ t("div", zr, [
420
+ (l(!0), c(D, null, V(e.kpis, (s) => (l(), c("div", {
421
+ key: s.label,
422
+ class: "bg-[#FAFAFA] rounded-10 p-12"
423
+ }, [
424
+ t("div", Vr, [
425
+ t("span", null, d(s.label), 1),
426
+ p(ue, {
427
+ description: s.description
428
+ }, null, 8, ["description"])
429
+ ]),
430
+ t("div", Yr, d(s.value), 1),
431
+ s.delta ? (l(), c("div", {
432
+ key: 0,
433
+ class: z(["fm-typo-en-body-sm-600 mt-3", s.deltaClass])
434
+ }, d(s.delta), 3)) : q("", !0)
435
+ ]))), 128))
436
+ ]),
437
+ r[3] || (r[3] = t("div", { class: "fm-typo-en-body-sm-600 text-fm-color-typo-tertiary uppercase tracking-wide mb-10" }, " Top used rewards ", -1)),
438
+ t("div", jr, [
439
+ (l(!0), c(D, null, V(e.topRewards, (s) => (l(), c("div", {
440
+ key: s.name,
441
+ class: "flex items-center gap-9"
442
+ }, [
443
+ r[2] || (r[2] = t("div", { class: "w-6 h-6 rounded-2 bg-fm-color-primary flex-shrink-0" }, null, -1)),
444
+ t("span", qr, d(s.name), 1),
445
+ t("span", Wr, [
446
+ j(d(s.count) + " ", 1),
447
+ p(ue, {
448
+ description: s.description
449
+ }, null, 8, ["description"])
450
+ ]),
451
+ t("div", Hr, [
452
+ t("div", {
453
+ class: "h-full bg-fm-color-primary rounded-2",
454
+ style: ct({ width: s.barPct + "%" })
455
+ }, null, 4)
456
+ ])
457
+ ]))), 128))
458
+ ])
459
+ ], 64)) : (l(), c("div", Gr, " No reward usage data is available for this period. "))
460
+ ]),
461
+ _: 1
462
+ });
463
+ };
464
+ }
465
+ }), T = () => {
466
+ const e = bt.getBusinessId();
467
+ if (!e) throw new Error("Invalid business ID");
468
+ return vt(`businesses/${e}/loyalty-dashboard`, {
469
+ noIdRequired: !0
470
+ });
471
+ }, U = {
472
+ async readTotalMembers(e) {
473
+ return P(
474
+ await T().post(
475
+ "metrics/total-members",
476
+ e
477
+ )
478
+ );
479
+ },
480
+ async readActiveMembers(e) {
481
+ return P(
482
+ await T().post(
483
+ "metrics/active-members",
484
+ e
485
+ )
486
+ );
487
+ },
488
+ async readMemberSales(e) {
489
+ return P(
490
+ await T().post(
491
+ "metrics/member-sales",
492
+ e
493
+ )
494
+ );
495
+ },
496
+ async readMemberSpendComparison(e) {
497
+ return P(
498
+ await T().post(
499
+ "metrics/member-spend-comparison",
500
+ e
501
+ )
502
+ );
503
+ },
504
+ async readMemberSalesTrend(e) {
505
+ return P(
506
+ await T().post(
507
+ "metrics/member-sales-trend",
508
+ e
509
+ )
510
+ );
511
+ },
512
+ async readRepeatRate(e) {
513
+ return P(
514
+ await T().post(
515
+ "metrics/repeat-rate",
516
+ e
517
+ )
518
+ );
519
+ },
520
+ async readVoucherRedemptionRate(e) {
521
+ return P(
522
+ await T().post(
523
+ "metrics/voucher-redemption-rate",
524
+ e
525
+ )
526
+ );
527
+ },
528
+ async readMemberFunnel(e) {
529
+ return P(
530
+ await T().post(
531
+ "metrics/member-funnel",
532
+ e
533
+ )
534
+ );
535
+ },
536
+ async readMemberLifecycle(e) {
537
+ return P(
538
+ await T().post(
539
+ "metrics/member-lifecycle",
540
+ e
541
+ )
542
+ );
543
+ },
544
+ async readRewardUsageHealth(e) {
545
+ return P(
546
+ await T().post(
547
+ "metrics/reward-usage-health",
548
+ e
549
+ )
550
+ );
551
+ },
552
+ async readSameDayBillAnomalies(e) {
553
+ return P(
554
+ await T().post(
555
+ "metrics/same-day-bill-anomalies",
556
+ e
557
+ )
558
+ );
559
+ },
560
+ async readDuplicateRewardEarnings(e) {
561
+ return P(
562
+ await T().post(
563
+ "metrics/duplicate-reward-earnings",
564
+ e
565
+ )
566
+ );
567
+ },
568
+ async readRewardEarningOutliers(e) {
569
+ return P(
570
+ await T().post(
571
+ "metrics/reward-earning-outliers",
572
+ e
573
+ )
574
+ );
575
+ },
576
+ async readRewardMaximizers(e) {
577
+ return P(
578
+ await T().post(
579
+ "metrics/reward-maximizers",
580
+ e
581
+ )
582
+ );
583
+ },
584
+ async readRewardAbuseSummary(e) {
585
+ return P(
586
+ await T().post(
587
+ "reward-abuse/summary",
588
+ e
589
+ )
590
+ );
591
+ },
592
+ async readRewardAbuseFindings(e) {
593
+ return P(
594
+ await T().post(
595
+ "reward-abuse/findings",
596
+ e
597
+ )
598
+ );
599
+ }
600
+ }, k = {
601
+ totalMembers: "Distinct members recorded through the end of the selected period; the start date does not reduce this total.",
602
+ activeMembers: "Distinct members with a completed member purchase or voucher redemption during the selected period.",
603
+ memberSales: "Sum of nettTotal from member-linked bills included in the selected period.",
604
+ repeatRate: "Repeat members divided by purchase members. Repeat members have purchase history before the selected period.",
605
+ voucherRedemptionRate: "Repeat members who redeemed a voucher divided by repeat members.",
606
+ purchasingMembers: "Distinct members with at least one completed member bill in the selected period.",
607
+ repeatMembers: "Purchase members who also had purchase history before the selected period.",
608
+ funnelRewardRedeemers: "Repeat members with counted reward activity in the selected period.",
609
+ newlyJoined: "Members whose join date falls within the selected period.",
610
+ frequent: "Existing members with repeated completed member bills in the selected period.",
611
+ infrequent: "Existing members with limited completed member bills in the selected period.",
612
+ atRisk: "Existing members with no selected-period purchase but a recent completed purchase.",
613
+ dormant: "Existing members with no selected-period purchase and no recent completed purchase.",
614
+ memberSalesTrend: "Daily member nett sales for the selected period compared with the selected comparison period.",
615
+ rewardRedeemers: "Distinct members who used a counted VOUCHER, CREDIT, or POINT reward during the selected period; anonymous usage is excluded from the member count.",
616
+ redemptionRate: "Reward redeemers divided by active members, where active members are members with purchase or reward activity during the selected period.",
617
+ averageRewardUses: "Counted reward-use transactions divided by distinct reward redeemers.",
618
+ memberSpendComparison: "Shows the value members bring — use it to make the case for growing membership"
619
+ }, W = {
620
+ SAME_DAY_BILL_ANOMALY: "same-day-bill-anomaly",
621
+ DUPLICATE_REWARD_EARNING: "duplicate-reward-earning",
622
+ REWARD_EARNING_OUTLIER: "reward-earning-outlier"
623
+ }, Ve = [
624
+ W.SAME_DAY_BILL_ANOMALY,
625
+ W.DUPLICATE_REWARD_EARNING,
626
+ W.REWARD_EARNING_OUTLIER
627
+ ], Jr = {
628
+ [W.SAME_DAY_BILL_ANOMALY]: "Same-day bill anomaly",
629
+ [W.DUPLICATE_REWARD_EARNING]: "Duplicate reward earning",
630
+ [W.REWARD_EARNING_OUTLIER]: "Reward earning outlier"
631
+ }, Qr = {
632
+ [W.SAME_DAY_BILL_ANOMALY]: "Members attached to at least three distinct completed, positive-value bills in one business day.",
633
+ [W.DUPLICATE_REWARD_EARNING]: "The same collectible was distributed more than once for one member and bill or reference.",
634
+ [W.REWARD_EARNING_OUTLIER]: "Daily reward earning is above the merchant-relative threshold for its reward type."
635
+ }, Xr = {
636
+ [W.SAME_DAY_BILL_ANOMALY]: "Threshold: 3 completed bills in one business day.",
637
+ [W.DUPLICATE_REWARD_EARNING]: "Threshold: more than 1 distribution for the same bill or reference.",
638
+ [W.REWARD_EARNING_OUTLIER]: "Threshold: the greater of the prior-90-day P99 or median + 5 MAD, per reward type."
639
+ }, Zr = {
640
+ VOUCHER: "Voucher",
641
+ CREDIT: "Credit",
642
+ COIN: "Point/spendable points",
643
+ POINT: "Experience"
644
+ };
645
+ function eo(e) {
646
+ return {
647
+ dateRange: e.dateRange,
648
+ businessRestaurantIds: [...e.businessRestaurantIds],
649
+ selectedRestaurantIds: [...e.selectedRestaurantIds],
650
+ timezone: e.timezone
651
+ };
652
+ }
653
+ function to(e, o) {
654
+ return {
655
+ ...e,
656
+ dateRange: o
657
+ };
658
+ }
659
+ function Le(e) {
660
+ return Jr[e];
661
+ }
662
+ function at(e) {
663
+ return Zr[e];
664
+ }
665
+ const ro = 15 * 60 * 1e3;
666
+ function oo(e, o = /* @__PURE__ */ new Date(), r = ro) {
667
+ const i = Date.parse(e), s = new Date(o).getTime();
668
+ return Number.isFinite(i) && Number.isFinite(s) && s - i > r;
669
+ }
670
+ function so(e, o = {}) {
671
+ const r = o.loading === !0, i = o.error === !0, s = e ? oo(e.updatedAt, o.now) : !1, m = !e || e.status === "unavailable", y = (e == null ? void 0 : e.status) === "available" && e.flaggedMembers === 0 && e.totalFindings === 0, v = r ? "loading" : m ? "unavailable" : s ? "stale" : e.status === "partial" ? "partial" : y ? "empty" : "available", g = {
672
+ loading: "Loading report data...",
673
+ available: "These are unusual activity findings from report data and require verification.",
674
+ partial: "Some report signals are unavailable. Available findings remain reviewable.",
675
+ unavailable: i ? "The report could not be loaded for this period." : "Report data is unavailable for this period.",
676
+ empty: "No unusual activity detected for the selected period.",
677
+ stale: "The report data may be stale. Verify findings against source records."
678
+ };
679
+ return {
680
+ status: v,
681
+ availability: (e == null ? void 0 : e.status) ?? "unavailable",
682
+ flaggedMembers: (e == null ? void 0 : e.flaggedMembers) ?? null,
683
+ totalFindings: (e == null ? void 0 : e.totalFindings) ?? null,
684
+ updatedAt: (e == null ? void 0 : e.updatedAt) ?? null,
685
+ stale: s,
686
+ error: i,
687
+ message: g[v],
688
+ bySignal: ((e == null ? void 0 : e.bySignal) ?? []).map((x) => ({
689
+ ...x,
690
+ label: Le(x.signal),
691
+ description: Qr[x.signal],
692
+ threshold: Xr[x.signal]
693
+ }))
694
+ };
695
+ }
696
+ function ao(e, o, r = /* @__PURE__ */ new Date()) {
697
+ const i = Se.tz(r, o).endOf("day"), s = i.clone().startOf("day");
698
+ return s.startOf("month"), [s.toISOString(), i.toISOString()];
699
+ }
700
+ function no(e, o) {
701
+ return e.length ? e : o;
702
+ }
703
+ function lo(e) {
704
+ return {
705
+ dateRange: e.dateRange,
706
+ compareDateRange: e.compareDateRange,
707
+ restaurantIds: no(
708
+ e.selectedLocationIds,
709
+ e.locationIds
710
+ ),
711
+ timezone: e.timezone
712
+ };
713
+ }
714
+ function tt(e) {
715
+ const [o, r] = e, i = Se(r).diff(Se(o)), s = Se(o).subtract(1, "millisecond");
716
+ return [s.clone().subtract(i, "milliseconds").toISOString(), s.toISOString()];
717
+ }
718
+ const ke = (e) => ({
719
+ total: 0,
720
+ totalNew: 0,
721
+ totalPrev: 0,
722
+ active: 0,
723
+ activePrev: 0,
724
+ purchasing: 0,
725
+ purchasingPrev: 0,
726
+ repeat: 0,
727
+ repeatPrev: 0,
728
+ redeemers: 0,
729
+ redeemersPrev: 0,
730
+ memberSales: 0,
731
+ memberSalesPrev: 0,
732
+ series: Array(e).fill(0),
733
+ prev: Array(e).fill(0)
734
+ });
735
+ ke(20), ke(7), ke(30), ke(12);
736
+ const qe = (e, o) => o ? Math.round(e / o * 1e3) / 10 : 0, io = (e, o) => o ? Math.round((e - o) / o * 1e3) / 10 : 0, Me = (e) => e >= 1e3 ? (e / 1e3).toFixed(1).replace(/\.0$/, "") + "k" : String(e), ce = (e, o) => St(e).set({ currency: o }).toFormat(!0), mo = [
737
+ "neutral-black",
738
+ "primary",
739
+ "#FF9C52",
740
+ "#FFB577",
741
+ "#FFD0A3"
742
+ ], We = {
743
+ text: "text-fm-color-typo-success",
744
+ bg: "bg-fm-color-system-success-100"
745
+ }, nt = {
746
+ text: "text-fm-color-typo-error",
747
+ bg: "bg-fm-color-system-error-100"
748
+ }, He = {
749
+ text: "text-fm-color-typo-warning",
750
+ bg: "bg-fm-color-system-warning-100"
751
+ };
752
+ function co(e) {
753
+ return e === 0 ? "text-fm-color-typo-secondary" : e > 0 ? We.text : nt.text;
754
+ }
755
+ function uo(e) {
756
+ const o = [
757
+ {
758
+ id: "total",
759
+ label: "Total members",
760
+ count: e.totalMembers,
761
+ desc: "All members through period end",
762
+ description: k.totalMembers,
763
+ denom: null
764
+ },
765
+ {
766
+ id: "active",
767
+ label: "Active members",
768
+ count: e.activeMembers,
769
+ desc: "Purchase or reward activity",
770
+ description: k.activeMembers,
771
+ denom: e.totalMembers
772
+ },
773
+ {
774
+ id: "purchasing",
775
+ label: "Purchase members",
776
+ count: e.purchasingMembers,
777
+ desc: "At least 1 completed order",
778
+ description: k.purchasingMembers,
779
+ denom: e.activeMembers
780
+ },
781
+ {
782
+ id: "repeat",
783
+ label: "Repeat members",
784
+ count: e.repeatMembers,
785
+ desc: "Had prior order history",
786
+ description: k.repeatMembers,
787
+ denom: e.purchasingMembers
788
+ },
789
+ {
790
+ id: "redeemers",
791
+ label: "Reward redeemers",
792
+ count: e.rewardRedeemers,
793
+ desc: "Repeat member used reward",
794
+ description: k.funnelRewardRedeemers,
795
+ denom: e.repeatMembers
796
+ }
797
+ ], r = o.map(
798
+ (y, v) => v === 0 || !y.denom ? null : qe(y.count, y.denom)
799
+ );
800
+ let i = null, s = 100;
801
+ return e.totalMembers > 0 && r.forEach((y, v) => {
802
+ v > 0 && y !== null && y < s && (s = y, i = v);
803
+ }), {
804
+ funnelStages: o.map((y, v) => {
805
+ const g = r[v], x = v === i;
806
+ return {
807
+ id: y.id,
808
+ label: y.label,
809
+ desc: y.desc,
810
+ description: y.description,
811
+ countStr: Me(y.count),
812
+ conversionStr: g != null ? `${g}% convert` : "",
813
+ convRateLabel: g != null ? `${g}% of prev` : "",
814
+ hasConvRate: v > 0,
815
+ hasDropLine: v > 0,
816
+ isBiggestDrop: x,
817
+ barColor: mo[v] ?? "#FFD0A3",
818
+ barWidthPct: e.totalMembers > 0 && y.count > 0 ? Math.max(qe(y.count, e.totalMembers), 1) : 0,
819
+ dropClass: x ? `${He.text} bg-[#FFF0E2]` : "text-fm-color-typo-secondary bg-fm-color-neutral-gray-100"
820
+ };
821
+ }),
822
+ funnelFootnote: `${e.totalMembers.toLocaleString()} total members`,
823
+ convRates: r,
824
+ biggestDropIdx: i
825
+ };
826
+ }
827
+ function po(e) {
828
+ const { funnelStages: o, funnelFootnote: r } = uo(e);
829
+ return { funnelStages: o, funnelFootnote: r };
830
+ }
831
+ const fo = 10;
832
+ function yo(e) {
833
+ const o = [
834
+ {
835
+ source: e.totalMembers,
836
+ target: e.activeMembers,
837
+ title: "Many members are not active",
838
+ body: "Members who joined may benefit from a reactivation campaign.",
839
+ action: {
840
+ label: "Create reactivation campaign",
841
+ path: "/campaign/promotion"
842
+ }
843
+ },
844
+ {
845
+ source: e.activeMembers,
846
+ target: e.purchasingMembers,
847
+ title: "Active members are not purchasing",
848
+ body: "Active members may benefit from a review of purchase incentives.",
849
+ action: {
850
+ label: "Review purchase incentives",
851
+ path: "/campaign/promotion"
852
+ }
853
+ },
854
+ {
855
+ source: e.purchasingMembers,
856
+ target: e.repeatMembers,
857
+ title: "Members are not returning after a purchase",
858
+ body: "Members who purchase once may benefit from a retention campaign.",
859
+ action: {
860
+ label: "Create retention campaign",
861
+ path: "/campaign/promotion"
862
+ }
863
+ },
864
+ {
865
+ source: e.repeatMembers,
866
+ target: e.rewardRedeemers,
867
+ title: "Repeat members are not using rewards",
868
+ body: "Repeat members may benefit from a review of reward setup.",
869
+ action: {
870
+ label: "Review reward setup",
871
+ path: "/reward"
872
+ }
873
+ }
874
+ ];
875
+ let r = null;
876
+ for (const s of o)
877
+ s.source < fo || s.target >= s.source || (!r || s.target / s.source < r.target / r.source) && (r = s);
878
+ if (!r) return null;
879
+ const i = Math.round(r.target / r.source * 1e3) / 10;
880
+ return {
881
+ title: r.title,
882
+ body: `${i}% of this stage progressed in the selected period. ${r.body}`,
883
+ action: r.action,
884
+ signals: [
885
+ {
886
+ text: `${r.target.toLocaleString()} of ${r.source.toLocaleString()} members progressed`
887
+ }
888
+ ]
889
+ };
890
+ }
891
+ const bo = {
892
+ VOUCHER: "Voucher",
893
+ PROMOTION: "Promotion",
894
+ POINT: "Experience",
895
+ CREDIT: "Credit",
896
+ BROADCAST: "Broadcast",
897
+ COIN: "Point",
898
+ REWARD_POOL: "Reward pool",
899
+ GAME: "Game",
900
+ MISSION: "Mission"
901
+ }, vo = {
902
+ active: { label: "Active", class: We.text },
903
+ expired: { label: "Ended", class: "text-fm-color-typo-tertiary" },
904
+ upcoming: { label: "Upcoming", class: He.text }
905
+ };
906
+ function go(e) {
907
+ return e.type !== "MEMBERSHIP";
908
+ }
909
+ function ho(e, o) {
910
+ var r;
911
+ return !o.length || !((r = e.targetLocation) != null && r.length) ? !0 : e.targetLocation.some(
912
+ (i) => o.includes(i.toString())
913
+ );
914
+ }
915
+ function xo(e) {
916
+ var o;
917
+ if (((o = e.timeframeOptions) == null ? void 0 : o.type) === "timeframe") {
918
+ const r = Se();
919
+ return r.isBetween(
920
+ e.timeframeOptions.start ?? r.clone().subtract(1, "d"),
921
+ e.timeframeOptions.end ?? r.clone().add(1, "d")
922
+ ) ? "active" : r.isAfter(e.timeframeOptions.end) ? "expired" : "upcoming";
923
+ }
924
+ return "active";
925
+ }
926
+ function _o(e, o) {
927
+ return e.filter(go).filter(
928
+ (r) => ho(r, o)
929
+ ).map((r) => {
930
+ const i = xo(r), s = vo[i], m = r.type === "BROADCAST";
931
+ return {
932
+ id: r._id.toString(),
933
+ name: r.name,
934
+ type: bo[r.type] ?? r.type,
935
+ status: s.label,
936
+ metric: m ? String(r.currentReceive ?? 0) : s.label,
937
+ metricLabel: m ? "Messages sent" : "Status",
938
+ statusClass: s.class
939
+ };
940
+ }).sort(
941
+ (r, i) => +(i.status === "Active") - +(r.status === "Active")
942
+ ).slice(0, 4);
943
+ }
944
+ function wo(e, o) {
945
+ return {
946
+ categories: e.categories,
947
+ prevCategories: e.prevCategories,
948
+ comparisonCategories: e.categories.map(
949
+ (r, i) => [r, e.prevCategories[i]].filter(Boolean).map((s) => Se(s).format("DD/MM/YYYY")).join(" vs ")
950
+ ),
951
+ series: e.series,
952
+ prevSeries: e.prevSeries,
953
+ description: k.memberSalesTrend,
954
+ totalFmt: ce(e.memberSales, o),
955
+ deltaStr: `${e.deltaPct > 0 ? "+" : ""}${e.deltaPct}%`,
956
+ deltaClass: co(e.deltaPct)
957
+ };
958
+ }
959
+ function Ro(e, o, r, i) {
960
+ return !e.memberOrders && !e.nonMemberOrders ? "No completed orders were recorded in this period." : r === 0 && o > 0 ? "Members account for all tracked spend in this period." : o === 0 && r > 0 ? "Non-members account for all tracked spend in this period." : i > 0 ? `Members spend ${i}% more per order than non-members. Converting more walk-ins to members is a direct lever on sales.` : i < 0 ? `Non-members spend ${Math.abs(
961
+ i
962
+ )}% more per order than members. Converting more walk-ins to members can increase member-linked sales.` : "Members and non-members have the same average order value in this period.";
963
+ }
964
+ function So(e, o) {
965
+ const r = e.memberOrders ? e.memberSales / e.memberOrders : 0, i = e.nonMemberOrders ? e.nonMemberSales / e.nonMemberOrders : 0, s = e.memberSales + e.nonMemberSales, m = io(r, i);
966
+ return {
967
+ description: k.memberSpendComparison,
968
+ memberSalesFmt: ce(e.memberSales, o),
969
+ nonMemberSalesFmt: ce(e.nonMemberSales, o),
970
+ avgMemberSaleFmt: ce(r, o),
971
+ avgNonMemberSaleFmt: ce(i, o),
972
+ memberSharePct: qe(e.memberSales, s),
973
+ avgGapPct: m,
974
+ summary: Ro(
975
+ e,
976
+ r,
977
+ i,
978
+ m
979
+ )
980
+ };
981
+ }
982
+ function Mo(e) {
983
+ const o = e.criteria ? {
984
+ ...k,
985
+ frequent: `Existing members with at least ${e.criteria.frequentMinBills} completed member bills in the selected period.`,
986
+ infrequent: `Existing members with 1 to ${e.criteria.frequentMinBills - 1} completed member bills in the selected period.`,
987
+ atRisk: `Existing members with no selected-period purchase but a completed purchase in the prior ${e.criteria.atRiskLookbackDays} calendar days.`,
988
+ dormant: `Existing members with no selected-period purchase and no completed purchase in the prior ${e.criteria.atRiskLookbackDays} calendar days.`
989
+ } : k, r = [
990
+ {
991
+ id: "new",
992
+ label: "Newly joined",
993
+ count: e.newlyJoined,
994
+ description: k.newlyJoined,
995
+ labelClass: We.text,
996
+ barColor: "typo-success"
997
+ },
998
+ {
999
+ id: "frequent",
1000
+ label: "Frequent",
1001
+ count: e.frequent,
1002
+ description: o.frequent,
1003
+ labelClass: "text-fm-color-primary",
1004
+ barColor: "primary"
1005
+ },
1006
+ {
1007
+ id: "infrequent",
1008
+ label: "Infrequent",
1009
+ count: e.infrequent,
1010
+ description: o.infrequent,
1011
+ labelClass: "text-fm-color-typo-secondary",
1012
+ barColor: "neutral-gray-300"
1013
+ },
1014
+ {
1015
+ id: "at-risk",
1016
+ label: "At-risk",
1017
+ count: e.atRisk,
1018
+ description: o.atRisk,
1019
+ labelClass: He.text,
1020
+ barColor: "#FFC746"
1021
+ },
1022
+ {
1023
+ id: "dormant",
1024
+ label: "Dormant",
1025
+ count: e.dormant,
1026
+ description: o.dormant,
1027
+ labelClass: nt.text,
1028
+ barColor: "#FFCFCC"
1029
+ }
1030
+ ], i = Math.max(...r.map((m) => m.count), 1);
1031
+ return {
1032
+ lifecycleSegs: r.map((m) => ({
1033
+ ...m,
1034
+ barPct: Math.round(m.count / i * 100),
1035
+ pctStr: `${e.totalMembers ? Math.round(m.count / e.totalMembers * 100) : 0}%`,
1036
+ countStr: Me(m.count)
1037
+ })),
1038
+ lifecycleSummary: `${Me(
1039
+ e.atRisk + e.dormant
1040
+ )} members are at-risk or dormant`
1041
+ };
1042
+ }
1043
+ function $o(e) {
1044
+ return Mo(e);
1045
+ }
1046
+ function Co(e, o) {
1047
+ return e.displayUnit === "uses" ? `${Me(e.displayValue)} ${e.displayValue === 1 ? "use" : "uses"}` : e.type === "COIN" ? `${Me(e.displayValue)} pts` : ce(e.displayValue, o);
1048
+ }
1049
+ function Ao(e) {
1050
+ return e.displayUnit === "uses" ? "Counted voucher-use transactions for this reward during the selected period." : `Total ${e.type === "COIN" ? "point" : e.type.toLowerCase()} amount used for this reward during the selected period.`;
1051
+ }
1052
+ function Do(e, o) {
1053
+ const r = Math.max(
1054
+ ...e.topRewards.map((i) => i.usageCount),
1055
+ 1
1056
+ );
1057
+ return {
1058
+ rewardKpis: [
1059
+ {
1060
+ label: "Reward redeemers",
1061
+ value: Me(e.rewardRedeemers),
1062
+ description: k.rewardRedeemers
1063
+ },
1064
+ {
1065
+ label: "Redemption rate",
1066
+ value: `${e.redemptionRatePct}%`,
1067
+ description: k.redemptionRate
1068
+ },
1069
+ {
1070
+ label: "Avg reward uses",
1071
+ value: `${e.averageRewardUsesPerRedeemer}x`,
1072
+ description: k.averageRewardUses
1073
+ }
1074
+ ],
1075
+ topRewards: e.topRewards.map((i) => ({
1076
+ name: i.name,
1077
+ count: Co(i, o),
1078
+ description: Ao(i),
1079
+ barPct: i.usageCount ? Math.round(i.usageCount / r * 100) : 0
1080
+ }))
1081
+ };
1082
+ }
1083
+ const Fo = { class: "flex flex-col gap-16 min-h-full" }, Io = {
1084
+ key: 0,
1085
+ class: "fm-typo-en-body-sm-400 text-fm-color-typo-error p-12 rounded-sm border border-fm-color-system-error-200 bg-fm-color-system-error-100"
1086
+ }, ko = { class: "grid grid-cols-2 md:grid-cols-4 gap-8 items-end" }, Lo = { class: "flex items-center justify-between gap-12 flex-wrap" }, Eo = { class: "fm-typo-en-body-sm-600 text-fm-color-typo-primary" }, Po = {
1087
+ key: 0,
1088
+ class: "fm-typo-en-body-sm-400 text-fm-color-typo-secondary"
1089
+ }, To = { class: "flex items-center gap-8" }, No = {
1090
+ key: 1,
1091
+ class: "flex items-center justify-center min-h-[180px]"
1092
+ }, Oo = {
1093
+ key: 2,
1094
+ class: "flex flex-col items-center justify-center gap-8 min-h-[180px] text-center"
1095
+ }, Bo = {
1096
+ key: 3,
1097
+ class: "flex flex-col items-center justify-center gap-8 min-h-[180px] text-center"
1098
+ }, Uo = {
1099
+ key: 4,
1100
+ class: "flex flex-col gap-8"
1101
+ }, zo = { class: "flex items-stretch gap-8 p-12" }, Vo = ["aria-expanded", "onClick", "onKeydown"], Yo = { class: "flex-1 min-w-0" }, jo = { class: "fm-typo-en-body-md-600 text-fm-color-typo-primary truncate" }, qo = { class: "fm-typo-en-body-sm-400 text-fm-color-typo-secondary truncate" }, Wo = { class: "hidden md:flex flex-col justify-center min-w-[150px]" }, Ho = { class: "fm-typo-en-body-sm-600 text-fm-color-typo-primary" }, Go = { class: "hidden lg:flex flex-wrap items-center gap-4 max-w-[260px]" }, Ko = {
1102
+ key: 0,
1103
+ class: "border-t border-fm-color-neutral-gray-100 bg-fm-color-neutral-gray-100 p-16"
1104
+ }, Jo = { class: "grid grid-cols-1 md:grid-cols-2 gap-16 mb-16" }, Qo = { class: "fm-typo-en-body-sm-600 text-fm-color-typo-primary" }, Xo = { class: "fm-typo-en-body-sm-600 text-fm-color-typo-primary" }, Zo = { class: "flex flex-col gap-8" }, es = { class: "flex items-start justify-between gap-12" }, ts = { class: "fm-typo-en-body-sm-600 text-fm-color-typo-primary" }, rs = { class: "fm-typo-en-body-sm-400 text-fm-color-typo-tertiary whitespace-nowrap" }, os = { class: "grid grid-cols-1 md:grid-cols-2 gap-x-16 gap-y-8 mt-8" }, ss = { class: "fm-typo-en-body-sm-400 text-fm-color-typo-secondary" }, as = { class: "fm-typo-en-body-sm-600 text-fm-color-typo-primary" }, ns = { class: "fm-typo-en-body-sm-400 text-fm-color-typo-secondary" }, ls = { class: "fm-typo-en-body-sm-600 text-fm-color-typo-primary" }, is = { class: "fm-typo-en-body-sm-400 text-fm-color-typo-secondary" }, ds = { class: "fm-typo-en-body-sm-600 text-fm-color-typo-primary" }, ms = { class: "fm-typo-en-body-sm-400 text-fm-color-typo-secondary" }, cs = {
1105
+ key: 0,
1106
+ class: "mt-4 flex max-w-full flex-wrap gap-4"
1107
+ }, us = {
1108
+ key: 1,
1109
+ class: "fm-typo-en-body-sm-600 text-fm-color-typo-primary"
1110
+ }, ps = { class: "fm-typo-en-body-sm-400 text-fm-color-typo-secondary md:col-span-2" }, fs = { class: "fm-typo-en-body-sm-600 text-fm-color-typo-primary break-words" }, ys = {
1111
+ key: 5,
1112
+ class: "flex items-center justify-between gap-12 pt-8 border-t border-fm-color-neutral-gray-100"
1113
+ }, bs = { class: "fm-typo-en-body-sm-400 text-fm-color-typo-secondary" }, vs = { class: "flex items-center gap-4" }, gs = /* @__PURE__ */ H({
1114
+ __name: "RewardAbuseFindingsSheet",
1115
+ props: /* @__PURE__ */ ut({
1116
+ payload: {},
1117
+ locations: {}
1118
+ }, {
1119
+ modelValue: { type: Boolean, default: !1 },
1120
+ modelModifiers: {}
1121
+ }),
1122
+ emits: ["update:modelValue"],
1123
+ setup(e) {
1124
+ const o = e, r = pt(e, "modelValue"), i = h(Ve[0]), s = h([]), m = h(""), y = h({
1125
+ startDate: void 0,
1126
+ endDate: void 0
1127
+ }), v = h(10), g = h(0), x = h("latestOccurredOn"), $ = h([]), F = h(0), w = h(0), C = h(!1), se = h(!1), te = h(!1), Y = h({}), Q = h(null), de = h(null);
1128
+ let E = 0, X = "", N;
1129
+ const pe = M(
1130
+ () => Ve.map((b) => ({
1131
+ label: Le(b),
1132
+ value: b
1133
+ }))
1134
+ ), fe = [
1135
+ { label: "Latest flagged first", value: "latestOccurredOn" },
1136
+ { label: "Highest observed value", value: "observedValue" }
1137
+ ], $e = [
1138
+ { label: "10", value: 10 },
1139
+ { label: "20", value: 20 },
1140
+ { label: "50", value: 50 }
1141
+ ], ae = M(
1142
+ () => w.value ? Math.ceil(w.value / v.value) : 0
1143
+ ), Ce = M(() => g.value + 1), ye = M(
1144
+ () => Object.fromEntries(
1145
+ o.locations.map((b) => [b.value, b.label])
1146
+ )
1147
+ ), be = M(
1148
+ () => `${y.value.startDate}-${y.value.endDate}`
1149
+ );
1150
+ function ne(b) {
1151
+ const u = Ee(b);
1152
+ return u.isValid() ? u.format("D MMM YYYY, h:mm A") : "--";
1153
+ }
1154
+ function ve(b) {
1155
+ return b.length ? b.join(", ") : "--";
1156
+ }
1157
+ function ge(b) {
1158
+ return Rt(b, { successMessage: "Bill ID copied" });
1159
+ }
1160
+ function me(b) {
1161
+ return b.member.name || "Member";
1162
+ }
1163
+ function he(b) {
1164
+ return ye.value[b] ?? b;
1165
+ }
1166
+ function le(b) {
1167
+ var u, Z, K;
1168
+ return b.member.id ?? `anonymous-${b.latestOccurredOn}-${(u = b.findings[0]) == null ? void 0 : u.billIds.join(
1169
+ "-"
1170
+ )}-${(Z = b.findings[0]) == null ? void 0 : Z.referenceIds.join("-")}-${(K = b.findings[0]) == null ? void 0 : K.observedValue}`;
1171
+ }
1172
+ function xe(b) {
1173
+ const u = le(b);
1174
+ Y.value[u] = !Y.value[u];
1175
+ }
1176
+ function De(b) {
1177
+ b.startDate && b.endDate && (y.value = b);
1178
+ }
1179
+ function Fe() {
1180
+ const b = o.payload;
1181
+ b && (i.value = Ve[0], s.value = [...b.selectedRestaurantIds], y.value = {
1182
+ startDate: b.dateRange[0],
1183
+ endDate: b.dateRange[1]
1184
+ }, m.value = "", v.value = 10, g.value = 0, x.value = "latestOccurredOn", Y.value = {}, te.value = !1);
1185
+ }
1186
+ function Pe() {
1187
+ return !y.value.startDate || !y.value.endDate ? null : [y.value.startDate, y.value.endDate];
1188
+ }
1189
+ async function G(b = !1) {
1190
+ if (!r.value || !o.payload) return;
1191
+ const u = Pe();
1192
+ if (!u) return;
1193
+ const K = {
1194
+ ...to(
1195
+ o.payload,
1196
+ u
1197
+ ),
1198
+ selectedRestaurantIds: [...s.value],
1199
+ signal: i.value,
1200
+ search: m.value.trim(),
1201
+ page: g.value + 1,
1202
+ pageSize: v.value,
1203
+ sortBy: x.value,
1204
+ sortDirection: "desc"
1205
+ }, _e = JSON.stringify(K);
1206
+ if (!b && _e === X) return;
1207
+ X = _e;
1208
+ const ee = ++E;
1209
+ C.value = !0, se.value = !1;
1210
+ try {
1211
+ const J = await U.readRewardAbuseFindings(K);
1212
+ if (ee !== E) return;
1213
+ $.value = J.members, F.value = J.totalMembers, w.value = J.totalRows, Y.value = {};
1214
+ } catch {
1215
+ if (ee !== E) return;
1216
+ se.value = !0, $.value = [], F.value = 0, w.value = 0;
1217
+ } finally {
1218
+ ee === E && (C.value = !1);
1219
+ }
1220
+ }
1221
+ function Te() {
1222
+ r.value && (g.value = 0, N && clearTimeout(N), N = setTimeout(() => {
1223
+ G();
1224
+ }, 250));
1225
+ }
1226
+ function Ne() {
1227
+ g.value < ae.value - 1 && (g.value += 1, G());
1228
+ }
1229
+ function Oe() {
1230
+ g.value > 0 && (g.value -= 1, G());
1231
+ }
1232
+ function Ie(b) {
1233
+ v.value = b, g.value = 0, G();
1234
+ }
1235
+ async function Be(b) {
1236
+ var u;
1237
+ if (b.member.id) {
1238
+ te.value = !1;
1239
+ try {
1240
+ const Z = await _t.readById(b.member.id);
1241
+ Q.value = Z, await rt(), (u = de.value) == null || u.showSheet();
1242
+ } catch {
1243
+ te.value = !0;
1244
+ }
1245
+ }
1246
+ }
1247
+ return Ae(r, (b) => {
1248
+ b && (X = "", Fe(), G(!0));
1249
+ }), Ae(
1250
+ [i, s, m, y, x],
1251
+ Te,
1252
+ { deep: !0 }
1253
+ ), Ae(
1254
+ () => o.payload,
1255
+ () => {
1256
+ r.value && (X = "", Fe(), G(!0));
1257
+ },
1258
+ { deep: !0 }
1259
+ ), ft(() => {
1260
+ N && clearTimeout(N);
1261
+ }), (b, u) => {
1262
+ const Z = _("FmSearch"), K = _("FmSelect"), _e = _("FmCircularProgress"), ee = _("FmIcon"), J = _("FmButton"), Ue = _("FmAvatar"), ze = _("FmChip"), I = _("FmTooltip"), ie = _("FmSideSheet");
1263
+ return l(), O(ie, {
1264
+ modelValue: r.value,
1265
+ "onUpdate:modelValue": u[5] || (u[5] = (R) => r.value = R),
1266
+ header: "Members requiring review",
1267
+ "dismiss-away": "",
1268
+ "max-width": 1100
1269
+ }, {
1270
+ default: L(() => [
1271
+ t("div", Fo, [
1272
+ u[19] || (u[19] = t("div", { class: "fm-typo-en-body-sm-400 text-fm-color-typo-secondary" }, " One row represents one member for the selected anomaly signal. Findings are recomputed for the selected filters and remain read-only. ", -1)),
1273
+ n(te) ? (l(), c("div", Io, " Member details could not be loaded. ")) : q("", !0),
1274
+ t("div", ko, [
1275
+ p(Z, {
1276
+ modelValue: n(m),
1277
+ "onUpdate:modelValue": u[0] || (u[0] = (R) => Ye(m) ? m.value = R : null),
1278
+ placeholder: "Search member ID",
1279
+ class: "col-span-2 md:col-span-1"
1280
+ }, null, 8, ["modelValue"]),
1281
+ p(K, {
1282
+ modelValue: n(i),
1283
+ "onUpdate:modelValue": u[1] || (u[1] = (R) => Ye(i) ? i.value = R : null),
1284
+ items: n(pe),
1285
+ label: "Signal",
1286
+ class: "col-span-1"
1287
+ }, null, 8, ["modelValue", "items"]),
1288
+ p(st, {
1289
+ label: "Location: ",
1290
+ icon: "storefront",
1291
+ "right-icon": "keyboard_arrow_down",
1292
+ "model-value": n(s),
1293
+ items: e.locations,
1294
+ "show-item-label": !0,
1295
+ class: "col-span-1",
1296
+ "onUpdate:modelValue": u[2] || (u[2] = (R) => s.value = R)
1297
+ }, null, 8, ["model-value", "items"]),
1298
+ (l(), O(je, {
1299
+ key: n(be),
1300
+ "model-value": n(y),
1301
+ "onUpdate:modelValue": De
1302
+ }, null, 8, ["model-value"]))
1303
+ ]),
1304
+ t("div", Lo, [
1305
+ t("div", Eo, [
1306
+ j(d(n(F).toLocaleString()) + " members ", 1),
1307
+ n(w) !== n(F) ? (l(), c("span", Po, " · " + d(n(w).toLocaleString()) + " evidence rows ", 1)) : q("", !0)
1308
+ ]),
1309
+ t("div", To, [
1310
+ u[6] || (u[6] = t("span", { class: "fm-typo-en-body-sm-400 text-fm-color-typo-secondary" }, "Sort", -1)),
1311
+ p(K, {
1312
+ "model-value": n(x),
1313
+ items: fe,
1314
+ searchable: !1,
1315
+ "onUpdate:modelValue": u[3] || (u[3] = (R) => x.value = R)
1316
+ }, null, 8, ["model-value"]),
1317
+ p(K, {
1318
+ "model-value": n(v),
1319
+ items: $e,
1320
+ searchable: !1,
1321
+ "onUpdate:modelValue": Ie
1322
+ }, null, 8, ["model-value"])
1323
+ ])
1324
+ ]),
1325
+ n(C) ? (l(), c("div", No, [
1326
+ p(_e, { size: "lg" })
1327
+ ])) : n(se) ? (l(), c("div", Oo, [
1328
+ p(ee, {
1329
+ name: "error_outline",
1330
+ outline: "",
1331
+ size: "lg",
1332
+ class: "text-fm-color-typo-error"
1333
+ }),
1334
+ u[7] || (u[7] = t("div", { class: "fm-typo-en-body-md-600 text-fm-color-typo-primary" }, " Findings are unavailable ", -1)),
1335
+ u[8] || (u[8] = t("div", { class: "fm-typo-en-body-sm-400 text-fm-color-typo-secondary" }, " No member data was changed. Try the filters again. ", -1)),
1336
+ p(J, {
1337
+ label: "Retry",
1338
+ icon: "refresh",
1339
+ variant: "tertiary",
1340
+ onClick: u[4] || (u[4] = (R) => G(!0))
1341
+ })
1342
+ ])) : n($).length ? (l(), c("div", Uo, [
1343
+ (l(!0), c(D, null, V(n($), (R) => (l(), c("div", {
1344
+ key: le(R),
1345
+ class: "border border-fm-color-neutral-gray-100 rounded-sm overflow-hidden"
1346
+ }, [
1347
+ t("div", zo, [
1348
+ t("button", {
1349
+ type: "button",
1350
+ class: "flex items-center gap-12 flex-1 min-w-0 text-left",
1351
+ "aria-expanded": n(Y)[le(R)] === !0,
1352
+ onClick: (A) => xe(R),
1353
+ onKeydown: [
1354
+ Xe(Ze((A) => xe(R), ["prevent"]), ["enter"]),
1355
+ Xe(Ze((A) => xe(R), ["prevent"]), ["space"])
1356
+ ]
1357
+ }, [
1358
+ p(ee, {
1359
+ name: n(Y)[le(R)] ? "expand_less" : "expand_more",
1360
+ outline: "",
1361
+ size: "md",
1362
+ class: "text-fm-color-typo-tertiary"
1363
+ }, null, 8, ["name"]),
1364
+ p(Ue, {
1365
+ name: me(R),
1366
+ size: "md"
1367
+ }, null, 8, ["name"]),
1368
+ t("div", Yo, [
1369
+ t("div", jo, d(me(R)), 1),
1370
+ t("div", qo, d(R.member.phoneNumber || R.member.cardNo || R.member.id || "Anonymous evidence"), 1)
1371
+ ])
1372
+ ], 40, Vo),
1373
+ t("div", Wo, [
1374
+ u[11] || (u[11] = t("div", { class: "fm-typo-en-body-sm-400 text-fm-color-typo-tertiary" }, " Latest flagged ", -1)),
1375
+ t("div", Ho, d(ne(R.latestOccurredOn)), 1)
1376
+ ]),
1377
+ t("div", Go, [
1378
+ (l(!0), c(D, null, V(R.signals, (A) => (l(), c("span", {
1379
+ key: A,
1380
+ class: "fm-typo-en-body-sm-400 px-8 py-4 rounded-sm bg-fm-color-neutral-gray-100 text-fm-color-typo-secondary"
1381
+ }, d(n(Le)(A)), 1))), 128))
1382
+ ]),
1383
+ p(J, {
1384
+ label: "View member",
1385
+ icon: "person",
1386
+ variant: "tertiary",
1387
+ disabled: !R.member.id,
1388
+ onClick: (A) => Be(R)
1389
+ }, null, 8, ["disabled", "onClick"])
1390
+ ]),
1391
+ n(Y)[le(R)] ? (l(), c("div", Ko, [
1392
+ t("div", Jo, [
1393
+ t("div", null, [
1394
+ u[12] || (u[12] = t("div", { class: "fm-typo-en-body-sm-400 text-fm-color-typo-tertiary" }, " Latest flagged ", -1)),
1395
+ t("div", Qo, d(ne(R.latestOccurredOn)), 1)
1396
+ ]),
1397
+ t("div", null, [
1398
+ u[13] || (u[13] = t("div", { class: "fm-typo-en-body-sm-400 text-fm-color-typo-tertiary" }, " Locations ", -1)),
1399
+ t("div", Xo, d(R.locationIds.length ? R.locationIds.map(he).join(", ") : "--"), 1)
1400
+ ])
1401
+ ]),
1402
+ t("div", Zo, [
1403
+ (l(!0), c(D, null, V(R.findings, (A) => (l(), c("div", {
1404
+ key: `${A.signal}-${A.occurredOn}-${A.billIds.join("-")}-${A.referenceIds.join(
1405
+ "-"
1406
+ )}`,
1407
+ class: "border border-fm-color-neutral-gray-200 rounded-sm bg-fm-color-neutral-white p-12"
1408
+ }, [
1409
+ t("div", es, [
1410
+ t("div", ts, d(n(Le)(A.signal)), 1),
1411
+ t("div", rs, d(ne(A.occurredOn)), 1)
1412
+ ]),
1413
+ t("div", os, [
1414
+ t("div", ss, [
1415
+ u[14] || (u[14] = j(" Observed value: ", -1)),
1416
+ t("span", as, d(A.observedValue.toLocaleString()), 1)
1417
+ ]),
1418
+ t("div", ns, [
1419
+ u[15] || (u[15] = j(" Threshold: ", -1)),
1420
+ t("span", ls, d(A.thresholdValue === null ? "--" : A.thresholdValue.toLocaleString()), 1)
1421
+ ]),
1422
+ t("div", is, [
1423
+ u[16] || (u[16] = j(" Reward type: ", -1)),
1424
+ t("span", ds, d(A.rewardType ? n(at)(A.rewardType) : "--"), 1)
1425
+ ]),
1426
+ t("div", ms, [
1427
+ u[17] || (u[17] = t("div", null, "Bill IDs:", -1)),
1428
+ A.billIds.length ? (l(), c("div", cs, [
1429
+ (l(!0), c(D, null, V(A.billIds, (we) => (l(), O(I, {
1430
+ key: we,
1431
+ content: "Copy bill ID",
1432
+ placement: "top"
1433
+ }, {
1434
+ default: L(() => [
1435
+ p(ze, {
1436
+ label: we,
1437
+ "aria-label": `Copy bill ID ${we}`,
1438
+ "right-icon": "content_copy",
1439
+ variant: "plain",
1440
+ compact: "",
1441
+ class: "max-w-full cursor-pointer",
1442
+ onClick: (Ge) => ge(we)
1443
+ }, null, 8, ["label", "aria-label", "onClick"])
1444
+ ]),
1445
+ _: 2
1446
+ }, 1024))), 128))
1447
+ ])) : (l(), c("span", us, " -- "))
1448
+ ]),
1449
+ t("div", ps, [
1450
+ u[18] || (u[18] = j(" Reference IDs: ", -1)),
1451
+ t("span", fs, d(ve(A.referenceIds)), 1)
1452
+ ])
1453
+ ])
1454
+ ]))), 128))
1455
+ ])
1456
+ ])) : q("", !0)
1457
+ ]))), 128))
1458
+ ])) : (l(), c("div", Bo, [
1459
+ p(ee, {
1460
+ name: "fact_check",
1461
+ outline: "",
1462
+ size: "lg",
1463
+ class: "text-fm-color-typo-tertiary"
1464
+ }),
1465
+ u[9] || (u[9] = t("div", { class: "fm-typo-en-body-md-600 text-fm-color-typo-primary" }, " No findings match these filters ", -1)),
1466
+ u[10] || (u[10] = t("div", { class: "fm-typo-en-body-sm-400 text-fm-color-typo-secondary" }, " Try a wider date range, another signal, or all locations. ", -1))
1467
+ ])),
1468
+ n(ae) > 1 ? (l(), c("div", ys, [
1469
+ t("div", bs, " Page " + d(n(Ce)) + " of " + d(n(ae)), 1),
1470
+ t("div", vs, [
1471
+ p(I, { content: "Previous page" }, {
1472
+ default: L(() => [
1473
+ p(J, {
1474
+ icon: "chevron_left",
1475
+ variant: "tertiary",
1476
+ disabled: n(g) === 0 || n(C),
1477
+ onClick: Oe
1478
+ }, null, 8, ["disabled"])
1479
+ ]),
1480
+ _: 1
1481
+ }),
1482
+ p(I, { content: "Next page" }, {
1483
+ default: L(() => [
1484
+ p(J, {
1485
+ icon: "chevron_right",
1486
+ variant: "tertiary",
1487
+ disabled: n(g) >= n(ae) - 1 || n(C),
1488
+ onClick: Ne
1489
+ }, null, 8, ["disabled"])
1490
+ ]),
1491
+ _: 1
1492
+ })
1493
+ ])
1494
+ ])) : q("", !0)
1495
+ ]),
1496
+ n(Q) ? (l(), O(wt, {
1497
+ key: 0,
1498
+ ref_key: "detailSheetRef",
1499
+ ref: de,
1500
+ member: n(Q)
1501
+ }, null, 8, ["member"])) : q("", !0)
1502
+ ]),
1503
+ _: 1
1504
+ }, 8, ["modelValue"]);
1505
+ };
1506
+ }
1507
+ }), hs = { class: "flex items-start gap-12" }, xs = { class: "flex-1 min-w-0" }, _s = { class: "flex items-center gap-8" }, ws = {
1508
+ key: 0,
1509
+ class: "flex items-center justify-center min-h-[120px]"
1510
+ }, Rs = {
1511
+ key: 1,
1512
+ class: "mt-24"
1513
+ }, Ss = { class: "grid grid-cols-2 gap-16" }, Ms = { class: "border border-fm-color-neutral-gray-100 rounded-sm p-16" }, $s = { class: "fm-typo-en-title-lg-800 text-fm-color-typo-primary" }, Cs = { class: "border border-fm-color-neutral-gray-100 rounded-sm p-16" }, As = { class: "fm-typo-en-title-lg-800 text-fm-color-typo-primary" }, Ds = /* @__PURE__ */ H({
1514
+ __name: "RewardAbuseMaximizers",
1515
+ props: {
1516
+ metric: {},
1517
+ loading: { type: Boolean },
1518
+ error: { type: Boolean }
1519
+ },
1520
+ setup(e) {
1521
+ const o = e, r = M(() => o.loading ? "Loading" : o.error || !o.metric ? "Unavailable" : o.metric.status === "insufficient-baseline" ? "Insufficient baseline" : o.metric.maximizerMembers === 0 ? "No members" : "Available"), i = M(() => r.value === "Available" || r.value === "No members" ? "text-fm-color-typo-success bg-fm-color-system-success-100" : r.value === "Insufficient baseline" ? "text-fm-color-typo-warning bg-fm-color-system-warning-100" : "text-fm-color-typo-error bg-fm-color-system-error-100"), s = M(() => o.metric ? o.metric.maximizerMembers.toLocaleString() : "--"), m = M(() => !o.metric || o.metric.thresholdPct === null ? "--" : `${o.metric.thresholdPct}%`);
1522
+ return (y, v) => {
1523
+ const g = _("FmIcon"), x = _("FmTooltip"), $ = _("FmCircularProgress"), F = _("FmCard");
1524
+ return l(), O(F, {
1525
+ variant: "outlined",
1526
+ class: "p-24 h-full"
1527
+ }, {
1528
+ default: L(() => [
1529
+ t("div", hs, [
1530
+ t("div", xs, [
1531
+ t("div", _s, [
1532
+ v[0] || (v[0] = t("div", { class: "fm-typo-en-body-lg-600 text-fm-color-typo-primary" }, " Reward Maximizers ", -1)),
1533
+ p(x, { content: "A neutral optimization cohort of frequent purchasers with high bill-linked reward use. It is separate from anomaly findings." }, {
1534
+ default: L(() => [
1535
+ p(g, {
1536
+ name: "info",
1537
+ outline: "",
1538
+ size: "sm",
1539
+ class: "text-fm-color-typo-tertiary"
1540
+ })
1541
+ ]),
1542
+ _: 1
1543
+ })
1544
+ ]),
1545
+ v[1] || (v[1] = t("div", { class: "fm-typo-en-body-sm-400 text-fm-color-typo-tertiary mt-4" }, " Frequent purchasers with above-benchmark reward use ", -1))
1546
+ ]),
1547
+ t("span", {
1548
+ class: z(["fm-typo-en-body-sm-600 px-8 py-4 rounded-sm whitespace-nowrap", n(i)])
1549
+ }, d(n(r)), 3)
1550
+ ]),
1551
+ e.loading ? (l(), c("div", ws, [
1552
+ p($, { size: "lg" })
1553
+ ])) : (l(), c("div", Rs, [
1554
+ t("div", Ss, [
1555
+ t("div", Ms, [
1556
+ t("div", $s, d(n(s)), 1),
1557
+ v[2] || (v[2] = t("div", { class: "fm-typo-en-body-sm-400 text-fm-color-typo-secondary mt-4" }, " Members in cohort ", -1))
1558
+ ]),
1559
+ t("div", Cs, [
1560
+ t("div", As, d(n(m)), 1),
1561
+ v[3] || (v[3] = t("div", { class: "fm-typo-en-body-sm-400 text-fm-color-typo-secondary mt-4" }, " Prior-90-day P95 ratio ", -1))
1562
+ ])
1563
+ ]),
1564
+ t("div", {
1565
+ class: z([
1566
+ "fm-typo-en-body-sm-400 mt-16 p-12 rounded-sm border",
1567
+ n(r) === "Available" || n(r) === "No members" ? "text-fm-color-typo-secondary border-fm-color-neutral-gray-100 bg-fm-color-neutral-gray-100" : n(r) === "Insufficient baseline" ? "text-fm-color-typo-warning border-fm-color-system-warning-200 bg-fm-color-system-warning-100" : "text-fm-color-typo-error border-fm-color-system-error-200 bg-fm-color-system-error-100"
1568
+ ])
1569
+ }, [
1570
+ e.error || !e.metric ? (l(), c(D, { key: 0 }, [
1571
+ j(" The cohort could not be loaded for this period. ")
1572
+ ], 64)) : e.metric.status === "insufficient-baseline" ? (l(), c(D, { key: 1 }, [
1573
+ j(" The prior-90-day baseline is too small to show a stable cohort. ")
1574
+ ], 64)) : e.metric.maximizerMembers === 0 ? (l(), c(D, { key: 2 }, [
1575
+ j(" No members meet the cohort criteria for the selected period. ")
1576
+ ], 64)) : (l(), c(D, { key: 3 }, [
1577
+ j(" Members have at least five completed, positive-value bills and above-benchmark bill-linked use of Voucher, Credit, or Point/spendable points rewards. This cohort does not affect review counts. ")
1578
+ ], 64))
1579
+ ], 2),
1580
+ v[4] || (v[4] = t("div", { class: "fm-typo-en-body-sm-400 text-fm-color-typo-tertiary mt-16" }, " Experience is evaluated separately from spendable points when reward earning outliers are calculated. ", -1))
1581
+ ]))
1582
+ ]),
1583
+ _: 1
1584
+ });
1585
+ };
1586
+ }
1587
+ }), Fs = { class: "flex items-start gap-12" }, Is = { class: "flex-1 min-w-0" }, ks = { class: "flex items-center gap-8" }, Ls = {
1588
+ key: 0,
1589
+ class: "flex items-center justify-center min-h-[120px]"
1590
+ }, Es = { class: "grid grid-cols-2 gap-16 mt-24" }, Ps = { class: "border border-fm-color-neutral-gray-100 rounded-sm p-16" }, Ts = { class: "fm-typo-en-title-lg-800 text-fm-color-typo-primary" }, Ns = { class: "border border-fm-color-neutral-gray-100 rounded-sm p-16" }, Os = { class: "fm-typo-en-title-lg-800 text-fm-color-typo-primary" }, Bs = { class: "mt-20" }, Us = {
1591
+ key: 0,
1592
+ class: "divide-y divide-fm-color-neutral-gray-100"
1593
+ }, zs = { class: "flex items-center gap-8" }, Vs = { class: "flex-1 fm-typo-en-body-sm-600 text-fm-color-typo-primary" }, Ys = { class: "fm-typo-en-body-sm-400 text-fm-color-typo-secondary mt-4" }, js = { class: "flex items-start justify-between gap-12 mt-8" }, qs = { class: "fm-typo-en-body-sm-400 text-fm-color-typo-tertiary" }, Ws = { class: "fm-typo-en-body-sm-600 text-fm-color-typo-primary whitespace-nowrap" }, Hs = {
1594
+ key: 0,
1595
+ class: "mt-8 pl-12 border-l-2 border-fm-color-neutral-gray-100 space-y-4"
1596
+ }, Gs = {
1597
+ key: 1,
1598
+ class: "fm-typo-en-body-sm-400 text-fm-color-typo-tertiary"
1599
+ }, Ks = { class: "flex items-center justify-between gap-12 mt-20 pt-16 border-t border-fm-color-neutral-gray-100 xs:flex-col xs:items-start" }, Js = { class: "fm-typo-en-body-sm-400 text-fm-color-typo-tertiary" }, Qs = /* @__PURE__ */ H({
1600
+ __name: "RewardAbuseSummary",
1601
+ props: {
1602
+ summary: {},
1603
+ outlierMetric: {}
1604
+ },
1605
+ emits: ["review"],
1606
+ setup(e, { emit: o }) {
1607
+ const r = e, i = o, s = M(
1608
+ () => r.summary.flaggedMembers !== null && r.summary.flaggedMembers > 0 && r.summary.status !== "unavailable" && r.summary.status !== "loading"
1609
+ ), m = {
1610
+ loading: "Loading",
1611
+ available: "Available",
1612
+ partial: "Partial data",
1613
+ unavailable: "Unavailable",
1614
+ empty: "No findings",
1615
+ stale: "Stale data"
1616
+ };
1617
+ function y(w) {
1618
+ return w ? Ee(w).format("D MMM YYYY, h:mm A") : "--";
1619
+ }
1620
+ function v(w) {
1621
+ return w === "available" || w === "empty" ? "text-fm-color-typo-success bg-fm-color-system-success-100" : w === "partial" || w === "stale" ? "text-fm-color-typo-warning bg-fm-color-system-warning-100" : "text-fm-color-typo-error bg-fm-color-system-error-100";
1622
+ }
1623
+ function g(w) {
1624
+ return w === "available" ? "Available" : w === "insufficient-baseline" ? "Insufficient baseline" : "Unavailable";
1625
+ }
1626
+ function x(w) {
1627
+ return w === "available" ? "text-fm-color-typo-success" : w === "insufficient-baseline" ? "text-fm-color-typo-warning" : "text-fm-color-typo-error";
1628
+ }
1629
+ function $(w) {
1630
+ return w === null ? "--" : w.toLocaleString();
1631
+ }
1632
+ function F(w) {
1633
+ return w === null ? "--" : w.toLocaleString();
1634
+ }
1635
+ return (w, C) => {
1636
+ const se = _("FmIcon"), te = _("FmTooltip"), Y = _("FmCircularProgress"), Q = _("FmButton"), de = _("FmCard");
1637
+ return l(), O(de, {
1638
+ variant: "outlined",
1639
+ class: "p-24 h-full"
1640
+ }, {
1641
+ default: L(() => [
1642
+ t("div", Fs, [
1643
+ t("div", Is, [
1644
+ t("div", ks, [
1645
+ C[1] || (C[1] = t("div", { class: "fm-typo-en-body-lg-600 text-fm-color-typo-primary" }, " Members requiring review ", -1)),
1646
+ p(te, { content: "A member is counted once across the available anomaly signals. This is a review queue, not a fraud verdict." }, {
1647
+ default: L(() => [
1648
+ p(se, {
1649
+ name: "info",
1650
+ outline: "",
1651
+ size: "sm",
1652
+ class: "text-fm-color-typo-tertiary"
1653
+ })
1654
+ ]),
1655
+ _: 1
1656
+ })
1657
+ ]),
1658
+ C[2] || (C[2] = t("div", { class: "fm-typo-en-body-sm-400 text-fm-color-typo-tertiary mt-4" }, " Selected period · business-wide thresholds · selected locations shown ", -1))
1659
+ ]),
1660
+ t("span", {
1661
+ class: z(["fm-typo-en-body-sm-600 px-8 py-4 rounded-sm whitespace-nowrap", v(e.summary.status)])
1662
+ }, d(m[e.summary.status]), 3)
1663
+ ]),
1664
+ e.summary.status === "loading" ? (l(), c("div", Ls, [
1665
+ p(Y, { size: "lg" })
1666
+ ])) : (l(), c(D, { key: 1 }, [
1667
+ t("div", Es, [
1668
+ t("div", Ps, [
1669
+ t("div", Ts, d($(e.summary.flaggedMembers)), 1),
1670
+ C[3] || (C[3] = t("div", { class: "fm-typo-en-body-sm-400 text-fm-color-typo-secondary mt-4" }, " Unique members ", -1))
1671
+ ]),
1672
+ t("div", Ns, [
1673
+ t("div", Os, d($(e.summary.totalFindings)), 1),
1674
+ C[4] || (C[4] = t("div", { class: "fm-typo-en-body-sm-400 text-fm-color-typo-secondary mt-4" }, " Total findings ", -1))
1675
+ ])
1676
+ ]),
1677
+ t("div", {
1678
+ class: z([
1679
+ "fm-typo-en-body-sm-400 mt-16 p-12 rounded-sm border",
1680
+ e.summary.status === "available" || e.summary.status === "empty" ? "text-fm-color-typo-secondary border-fm-color-neutral-gray-100 bg-fm-color-neutral-gray-100" : e.summary.status === "partial" || e.summary.status === "stale" ? "text-fm-color-typo-warning border-fm-color-system-warning-200 bg-fm-color-system-warning-100" : "text-fm-color-typo-error border-fm-color-system-error-200 bg-fm-color-system-error-100"
1681
+ ])
1682
+ }, d(e.summary.message), 3),
1683
+ t("div", Bs, [
1684
+ C[5] || (C[5] = t("div", { class: "fm-typo-en-body-md-600 text-fm-color-typo-primary mb-8" }, " Signal breakdown ", -1)),
1685
+ e.summary.bySignal.length ? (l(), c("div", Us, [
1686
+ (l(!0), c(D, null, V(e.summary.bySignal, (E) => {
1687
+ var X;
1688
+ return l(), c("div", {
1689
+ key: E.signal,
1690
+ class: "py-12"
1691
+ }, [
1692
+ t("div", zs, [
1693
+ t("div", Vs, d(E.label), 1),
1694
+ t("div", {
1695
+ class: z(["fm-typo-en-body-sm-600", x(E.status)])
1696
+ }, d(g(E.status)), 3)
1697
+ ]),
1698
+ t("div", Ys, d(E.description), 1),
1699
+ t("div", js, [
1700
+ t("div", qs, d(E.threshold), 1),
1701
+ t("div", Ws, d($(E.flaggedMembers)) + " members · " + d($(E.findings)) + " findings ", 1)
1702
+ ]),
1703
+ E.signal === "reward-earning-outlier" && ((X = e.outlierMetric) != null && X.byType.length) ? (l(), c("div", Hs, [
1704
+ (l(!0), c(D, null, V(e.outlierMetric.byType, (N) => (l(), c("div", {
1705
+ key: N.type,
1706
+ class: "fm-typo-en-body-sm-400 text-fm-color-typo-tertiary"
1707
+ }, d(n(at)(N.type)) + ": " + d(N.status === "available" ? `${F(
1708
+ N.threshold
1709
+ )} threshold · ${N.baselineMembers.toLocaleString()} baseline members` : "Insufficient baseline"), 1))), 128))
1710
+ ])) : q("", !0)
1711
+ ]);
1712
+ }), 128))
1713
+ ])) : (l(), c("div", Gs, " Signal breakdown is unavailable for this response. "))
1714
+ ]),
1715
+ t("div", Ks, [
1716
+ t("div", Js, d(e.summary.updatedAt ? `Report data updated ${y(e.summary.updatedAt)}.` : "Report timestamp unavailable."), 1),
1717
+ p(Q, {
1718
+ label: "Review members",
1719
+ icon: "search",
1720
+ variant: "primary",
1721
+ disabled: !n(s),
1722
+ onClick: C[0] || (C[0] = (E) => i("review"))
1723
+ }, null, 8, ["disabled"])
1724
+ ])
1725
+ ], 64))
1726
+ ]),
1727
+ _: 1
1728
+ });
1729
+ };
1730
+ }
1731
+ }), Xs = { class: "mb-6 flex items-center gap-3 fm-typo-en-body-md-600" }, Zs = { class: "flex items-baseline gap-10 mb-14 flex-wrap" }, ea = { class: "fm-typo-en-title-lg-800" }, ta = /* @__PURE__ */ H({
1732
+ __name: "SalesTrendChart",
1733
+ props: {
1734
+ sales: {}
1735
+ },
1736
+ setup(e) {
1737
+ const o = e, r = M(() => [
1738
+ {
1739
+ label: "This period",
1740
+ data: o.sales.series,
1741
+ color: "#FF7823",
1742
+ fill: !0
1743
+ },
1744
+ {
1745
+ label: "Prev. period",
1746
+ data: o.sales.prevSeries,
1747
+ color: "#B2B3B6",
1748
+ dash: !0
1749
+ }
1750
+ ]), i = { display: !1 };
1751
+ return (s, m) => {
1752
+ const y = _("FmLineChart"), v = _("FmCard");
1753
+ return l(), O(v, {
1754
+ variant: "outlined",
1755
+ class: "p-24"
1756
+ }, {
1757
+ default: L(() => [
1758
+ t("div", Xs, [
1759
+ m[0] || (m[0] = t("span", null, "Member sales trend", -1)),
1760
+ p(ue, {
1761
+ description: e.sales.description
1762
+ }, null, 8, ["description"])
1763
+ ]),
1764
+ t("div", Zs, [
1765
+ t("span", ea, d(e.sales.totalFmt), 1),
1766
+ t("span", {
1767
+ class: z(["fm-typo-en-body-sm-600 px-9 py-3 rounded-full whitespace-nowrap", e.sales.deltaClass])
1768
+ }, d(e.sales.deltaStr), 3),
1769
+ m[1] || (m[1] = t("span", { class: "fm-typo-en-body-sm-400 text-fm-color-typo-tertiary" }, "vs prev. period", -1))
1770
+ ]),
1771
+ p(y, {
1772
+ datasets: n(r),
1773
+ "x-axis": { categories: e.sales.comparisonCategories },
1774
+ "x-cfg": i,
1775
+ "y-cfg": i,
1776
+ legend: { display: !1 },
1777
+ height: "80px"
1778
+ }, null, 8, ["datasets", "x-axis"]),
1779
+ m[2] || (m[2] = t("div", { class: "flex items-center gap-14 mt-10" }, [
1780
+ t("div", { class: "flex items-center gap-5" }, [
1781
+ t("div", { class: "w-14 h-2 bg-fm-color-primary rounded-1" }),
1782
+ t("span", { class: "fm-typo-en-body-sm-400 text-fm-color-typo-secondary" }, "This period")
1783
+ ]),
1784
+ t("div", { class: "flex items-center gap-5" }, [
1785
+ t("div", { class: "w-14 border-t-[1.5px] border-dashed border-fm-color-neutral-gray-200" }),
1786
+ t("span", { class: "fm-typo-en-body-sm-400 text-fm-color-typo-secondary" }, "Prev. period")
1787
+ ])
1788
+ ], -1))
1789
+ ]),
1790
+ _: 1
1791
+ });
1792
+ };
1793
+ }
1794
+ }), ra = { class: "flex items-center gap-8" }, oa = { class: "px-24 flex flex-col gap-16 pb-24" }, sa = { class: "flex items-center justify-between gap-8 flex-wrap" }, aa = { class: "flex items-center gap-8 flex-wrap" }, na = { class: "fm-typo-en-body-sm-400 text-fm-color-typo-tertiary -mt-8 text-right" }, la = { class: "grid grid-cols-2 xs:grid-cols-1 gap-16" }, ia = { class: "grid grid-cols-[3fr_2fr] xs:grid-cols-1 gap-16 items-start" }, da = { class: "grid grid-cols-2 xs:grid-cols-1 gap-16" }, Ca = /* @__PURE__ */ H({
1795
+ __name: "LoyaltyDashboard",
1796
+ setup(e) {
1797
+ const o = $t(), r = Ct(), i = ht(), { global: s, minor: m } = Mt, y = M(
1798
+ () => et[r.currentCountry.value || "MY"] ?? et.MY
1799
+ ), v = M(
1800
+ () => gt.Country.getCountry(r.currentCountry.value || "MY").currency.code
1801
+ ), [g, x] = ao(
1802
+ "this-month",
1803
+ y.value
1804
+ ), $ = h({
1805
+ startDate: g,
1806
+ endDate: x
1807
+ }), F = h(
1808
+ le(tt([g, x]))
1809
+ ), w = h({ location: [] }), C = h(o.locations.length > 0), se = h(!1), te = h(0), Y = h({}), Q = h(null), de = h(null), E = h(null), X = h(
1810
+ null
1811
+ ), N = h(null), pe = h(!1), fe = h(!1), $e = h([]), ae = h(!1), Ce = h(!1), ye = h({
1812
+ outlier: { loading: !1, error: !1 },
1813
+ maximizers: { loading: !1, error: !1 }
1814
+ }), be = h(null), ne = h(!1), ve = h(!1), ge = h(null), me = h(null), he = h(!1);
1815
+ function le([a, f]) {
1816
+ return { startDate: a, endDate: f };
1817
+ }
1818
+ Ae($, (a) => {
1819
+ a.startDate && a.endDate && (F.value = le(
1820
+ tt([a.startDate, a.endDate])
1821
+ ));
1822
+ });
1823
+ const xe = M(
1824
+ () => po(
1825
+ Q.value ?? {
1826
+ totalMembers: 0,
1827
+ activeMembers: 0,
1828
+ purchasingMembers: 0,
1829
+ repeatMembers: 0,
1830
+ rewardRedeemers: 0
1831
+ }
1832
+ )
1833
+ ), De = M(
1834
+ () => $o(
1835
+ de.value ?? {
1836
+ totalMembers: 0,
1837
+ newlyJoined: 0,
1838
+ frequent: 0,
1839
+ infrequent: 0,
1840
+ atRisk: 0,
1841
+ dormant: 0
1842
+ }
1843
+ )
1844
+ ), Fe = M(
1845
+ () => wo(
1846
+ E.value ?? {
1847
+ categories: [""],
1848
+ prevCategories: [""],
1849
+ series: [0],
1850
+ prevSeries: [0],
1851
+ description: k.memberSalesTrend,
1852
+ memberSales: 0,
1853
+ deltaPct: 0
1854
+ },
1855
+ v.value
1856
+ )
1857
+ ), Pe = M(
1858
+ () => Q.value ? yo(Q.value) : null
1859
+ ), G = M(
1860
+ () => N.value ? Do(N.value, v.value) : null
1861
+ ), Te = M(
1862
+ () => So(
1863
+ X.value ?? {
1864
+ memberSales: 0,
1865
+ memberOrders: 0,
1866
+ nonMemberSales: 0,
1867
+ nonMemberOrders: 0
1868
+ },
1869
+ v.value
1870
+ )
1871
+ ), Ne = M(
1872
+ () => _o($e.value, w.value.location)
1873
+ ), Oe = M(() => {
1874
+ const a = Y.value;
1875
+ return [
1876
+ {
1877
+ label: "Total members",
1878
+ value: ee(a.totalMembers ?? 0),
1879
+ description: k.totalMembers,
1880
+ icon: "group",
1881
+ delta: "0%"
1882
+ },
1883
+ {
1884
+ label: "Active members",
1885
+ value: ee(a.activeMembers ?? 0),
1886
+ description: k.activeMembers,
1887
+ icon: "bolt",
1888
+ delta: "0%"
1889
+ },
1890
+ {
1891
+ label: "Member sales",
1892
+ value: ce(a.memberSales ?? 0, v.value),
1893
+ description: k.memberSales,
1894
+ icon: "payments",
1895
+ delta: "0%"
1896
+ },
1897
+ {
1898
+ label: "Repeat rate",
1899
+ value: J(a.repeatRatePct ?? 0),
1900
+ description: k.repeatRate,
1901
+ icon: "repeat",
1902
+ delta: "0pp"
1903
+ },
1904
+ {
1905
+ label: "Voucher redemption rate",
1906
+ value: J(a.voucherRedemptionRatePct ?? 0),
1907
+ description: k.voucherRedemptionRate,
1908
+ icon: "redeem",
1909
+ delta: "0pp"
1910
+ }
1911
+ ].map(
1912
+ (S) => ({
1913
+ ...S,
1914
+ sub: null,
1915
+ deltaClass: "text-fm-color-typo-secondary",
1916
+ trendUp: !0
1917
+ })
1918
+ );
1919
+ }), Ie = M(
1920
+ () => o.locations.map((a) => a._id.toString())
1921
+ ), Be = M(
1922
+ () => o.locations.map((a) => ({
1923
+ label: `${a.code ? `${a.code} - ` : ""}${a.name}`,
1924
+ value: a._id.toString()
1925
+ }))
1926
+ ), b = M(
1927
+ () => !$.value.startDate || !$.value.endDate || !C.value ? null : eo({
1928
+ dateRange: [$.value.startDate, $.value.endDate],
1929
+ businessRestaurantIds: Ie.value,
1930
+ selectedRestaurantIds: w.value.location,
1931
+ timezone: y.value
1932
+ })
1933
+ ), u = M(
1934
+ () => so(be.value, {
1935
+ loading: ne.value,
1936
+ error: ve.value
1937
+ })
1938
+ );
1939
+ function Z(a) {
1940
+ return !a.startDate || !a.endDate ? "" : `${Ee(a.startDate).format("D MMM")} – ${Ee(
1941
+ a.endDate
1942
+ ).format("D MMM YYYY")}`;
1943
+ }
1944
+ const K = M(() => Z($.value)), _e = M(
1945
+ () => Z(F.value)
1946
+ );
1947
+ function ee(a) {
1948
+ return a >= 1e3 ? `${(a / 1e3).toFixed(1).replace(/\.0$/, "")}k` : String(a);
1949
+ }
1950
+ function J(a) {
1951
+ return `${Math.round(a * 10) / 10}%`;
1952
+ }
1953
+ function Ue(a) {
1954
+ if (a && typeof a == "object" && "value" in a && Number.isFinite(Number(a.value)))
1955
+ return Number(a.value);
1956
+ }
1957
+ function ze() {
1958
+ return !$.value.startDate || !$.value.endDate || !F.value.startDate || !F.value.endDate || !C.value ? null : lo({
1959
+ dateRange: [$.value.startDate, $.value.endDate],
1960
+ compareDateRange: [
1961
+ F.value.startDate,
1962
+ F.value.endDate
1963
+ ],
1964
+ selectedLocationIds: w.value.location,
1965
+ locationIds: Ie.value,
1966
+ timezone: y.value
1967
+ });
1968
+ }
1969
+ function I(a) {
1970
+ return a === te.value;
1971
+ }
1972
+ async function ie(a, f, S) {
1973
+ try {
1974
+ await a(f, S);
1975
+ } catch (re) {
1976
+ if (I(S)) throw re;
1977
+ }
1978
+ }
1979
+ async function R(a, f) {
1980
+ const [
1981
+ S,
1982
+ re,
1983
+ Re,
1984
+ oe,
1985
+ B
1986
+ ] = await Promise.all([
1987
+ U.readTotalMembers(a),
1988
+ U.readActiveMembers(a),
1989
+ U.readMemberSales(a),
1990
+ U.readRepeatRate(a),
1991
+ U.readVoucherRedemptionRate(a)
1992
+ ]);
1993
+ I(f) && (Y.value = {
1994
+ totalMembers: Ue(S),
1995
+ activeMembers: re.activeMembers,
1996
+ memberSales: Re.memberSales,
1997
+ repeatRatePct: oe.repeatRatePct,
1998
+ voucherRedemptionRatePct: B.voucherRedemptionRatePct
1999
+ });
2000
+ }
2001
+ async function A(a, f) {
2002
+ const S = await U.readMemberFunnel(a);
2003
+ I(f) && (Q.value = S);
2004
+ }
2005
+ async function we(a, f) {
2006
+ const S = await U.readMemberLifecycle(a);
2007
+ I(f) && (de.value = S);
2008
+ }
2009
+ async function Ge(a, f) {
2010
+ const S = await U.readMemberSalesTrend(a);
2011
+ I(f) && (E.value = S);
2012
+ }
2013
+ async function lt(a, f) {
2014
+ const S = await U.readMemberSpendComparison(a);
2015
+ I(f) && (X.value = S);
2016
+ }
2017
+ async function it(a, f) {
2018
+ pe.value = !0, fe.value = !1;
2019
+ try {
2020
+ const S = await U.readRewardUsageHealth(a);
2021
+ if (!I(f)) return;
2022
+ N.value = S;
2023
+ } catch (S) {
2024
+ throw I(f) && (fe.value = !0), S;
2025
+ } finally {
2026
+ I(f) && (pe.value = !1);
2027
+ }
2028
+ }
2029
+ function Ke() {
2030
+ be.value = null, ne.value = !1, ve.value = !1, ge.value = null, me.value = null, Object.values(ye.value).forEach((a) => {
2031
+ a.loading = !1, a.error = !1;
2032
+ });
2033
+ }
2034
+ function Je(a, f, S, re, Re) {
2035
+ const oe = ye.value[a];
2036
+ oe.loading = !0, oe.error = !1, f(S).then((B) => {
2037
+ I(re) && Re(B);
2038
+ }).catch(() => {
2039
+ I(re) && (oe.error = !0);
2040
+ }).finally(() => {
2041
+ I(re) && (oe.loading = !1);
2042
+ });
2043
+ }
2044
+ function dt(a, f) {
2045
+ be.value = null, ne.value = !0, ve.value = !1, ge.value = null, me.value = null, Je(
2046
+ "outlier",
2047
+ U.readRewardEarningOutliers,
2048
+ a,
2049
+ f,
2050
+ (S) => {
2051
+ ge.value = S;
2052
+ }
2053
+ ), Je(
2054
+ "maximizers",
2055
+ U.readRewardMaximizers,
2056
+ a,
2057
+ f,
2058
+ (S) => {
2059
+ me.value = S;
2060
+ }
2061
+ ), U.readRewardAbuseSummary(a).then((S) => {
2062
+ I(f) && (be.value = S);
2063
+ }).catch(() => {
2064
+ I(f) && (ve.value = !0);
2065
+ }).finally(() => {
2066
+ I(f) && (ne.value = !1);
2067
+ });
2068
+ }
2069
+ async function mt() {
2070
+ ae.value = !0, Ce.value = !1;
2071
+ try {
2072
+ const { resources: a } = await xt.readAll({
2073
+ limit: 1e3,
2074
+ skip: 0,
2075
+ sortBy: "_id",
2076
+ descending: !0
2077
+ });
2078
+ $e.value = a;
2079
+ } catch (a) {
2080
+ throw Ce.value = !0, a;
2081
+ } finally {
2082
+ ae.value = !1;
2083
+ }
2084
+ }
2085
+ function Qe() {
2086
+ const a = ++te.value, f = ze();
2087
+ if (!f) {
2088
+ pe.value = !1, fe.value = !1, Ke();
2089
+ return;
2090
+ }
2091
+ b.value ? dt(b.value, a) : Ke(), m(
2092
+ () => ie(R, f, a)
2093
+ ).catch(() => {
2094
+ }), m(
2095
+ () => ie(A, f, a)
2096
+ ).catch(() => {
2097
+ }), m(
2098
+ () => ie(we, f, a)
2099
+ ).catch(() => {
2100
+ }), m(
2101
+ () => ie(Ge, f, a)
2102
+ ).catch(() => {
2103
+ }), m(
2104
+ () => ie(
2105
+ lt,
2106
+ f,
2107
+ a
2108
+ )
2109
+ ).catch(() => {
2110
+ }), m(
2111
+ () => ie(it, f, a)
2112
+ ).catch(() => {
2113
+ });
2114
+ }
2115
+ return Ae([$, F, () => w.value.location], () => {
2116
+ se.value && Qe();
2117
+ }), yt(async () => {
2118
+ await s(async () => {
2119
+ C.value || await o.readLocations(), C.value = !0;
2120
+ }), await rt(), se.value = !0, Qe(), mt().catch(() => {
2121
+ $e.value = [];
2122
+ });
2123
+ }), (a, f) => {
2124
+ var Re, oe;
2125
+ const S = _("FmPill"), re = _("FmPageHead");
2126
+ return l(), c(D, null, [
2127
+ p(re, { title: "Analytic" }, {
2128
+ title: L(() => [
2129
+ t("div", ra, [
2130
+ f[6] || (f[6] = t("span", { class: "fm-typo-en-title-md-600 fm-step-title line-clamp-2" }, " Analytic ", -1)),
2131
+ p(S, { variant: "beta" })
2132
+ ])
2133
+ ]),
2134
+ _: 1
2135
+ }),
2136
+ t("div", oa, [
2137
+ t("div", sa, [
2138
+ p(st, {
2139
+ label: "Location: ",
2140
+ "right-icon": "keyboard_arrow_down",
2141
+ modelValue: n(w).location,
2142
+ "onUpdate:modelValue": f[0] || (f[0] = (B) => n(w).location = B),
2143
+ icon: "storefront",
2144
+ "show-item-label": !0,
2145
+ items: n(o).locationOptions
2146
+ }, null, 8, ["modelValue", "items"]),
2147
+ t("div", aa, [
2148
+ p(je, {
2149
+ "model-value": n($),
2150
+ "onUpdate:modelValue": f[1] || (f[1] = (B) => $.value = B)
2151
+ }, null, 8, ["model-value"]),
2152
+ f[7] || (f[7] = t("span", { class: "fm-typo-en-body-sm-600 text-fm-color-typo-tertiary" }, "vs", -1)),
2153
+ p(je, {
2154
+ "model-value": n(F),
2155
+ "onUpdate:modelValue": f[2] || (f[2] = (B) => F.value = B)
2156
+ }, null, 8, ["model-value"])
2157
+ ])
2158
+ ]),
2159
+ t("div", na, d(n(K)) + " · vs. " + d(n(_e)), 1),
2160
+ p(or, { kpis: n(Oe) }, null, 8, ["kpis"]),
2161
+ t("section", la, [
2162
+ p(Qs, {
2163
+ summary: n(u),
2164
+ "outlier-metric": n(ge),
2165
+ onReview: f[3] || (f[3] = (B) => he.value = !0)
2166
+ }, null, 8, ["summary", "outlier-metric"]),
2167
+ p(Ds, {
2168
+ metric: n(me),
2169
+ loading: n(ye).maximizers.loading,
2170
+ error: n(ye).maximizers.error
2171
+ }, null, 8, ["metric", "loading", "error"])
2172
+ ]),
2173
+ t("section", ia, [
2174
+ p(Cr, {
2175
+ stages: n(xe).funnelStages,
2176
+ footnote: n(xe).funnelFootnote,
2177
+ interactive: !1
2178
+ }, null, 8, ["stages", "footnote"]),
2179
+ p(Kt, {
2180
+ insight: n(Pe),
2181
+ onNavigate: f[4] || (f[4] = (B) => n(i).push(B))
2182
+ }, null, 8, ["insight"])
2183
+ ]),
2184
+ t("section", da, [
2185
+ p(mr, {
2186
+ segments: n(De).lifecycleSegs,
2187
+ summary: n(De).lifecycleSummary,
2188
+ interactive: !1
2189
+ }, null, 8, ["segments", "summary"]),
2190
+ p(ta, { sales: n(Fe) }, null, 8, ["sales"]),
2191
+ p(Nr, { spend: n(Te) }, null, 8, ["spend"]),
2192
+ p(Kr, {
2193
+ kpis: ((Re = n(G)) == null ? void 0 : Re.rewardKpis) ?? [],
2194
+ "top-rewards": ((oe = n(G)) == null ? void 0 : oe.topRewards) ?? [],
2195
+ "has-data": !!n(G),
2196
+ loading: n(pe),
2197
+ error: n(fe)
2198
+ }, null, 8, ["kpis", "top-rewards", "has-data", "loading", "error"]),
2199
+ p(Bt, {
2200
+ campaigns: n(Ne),
2201
+ loading: n(ae),
2202
+ error: n(Ce)
2203
+ }, null, 8, ["campaigns", "loading", "error"])
2204
+ ]),
2205
+ p(gs, {
2206
+ modelValue: n(he),
2207
+ "onUpdate:modelValue": f[5] || (f[5] = (B) => Ye(he) ? he.value = B : null),
2208
+ payload: n(b),
2209
+ locations: n(Be)
2210
+ }, null, 8, ["modelValue", "payload", "locations"])
2211
+ ])
2212
+ ], 64);
2213
+ };
2214
+ }
2215
+ });
2216
+ export {
2217
+ Ca as default
2218
+ };