@kb0912/notification-brevo 2.1.1 → 2.1.2

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.
@@ -4,147 +4,6 @@ const adminSdk = require("@medusajs/admin-sdk");
4
4
  const ui = require("@medusajs/ui");
5
5
  const icons = require("@medusajs/icons");
6
6
  const react = require("react");
7
- const EVENT_LABELS = {
8
- "order.placed": "Order Placed",
9
- "order.canceled": "Order Canceled",
10
- "order.delivered": "Order Delivered",
11
- "customer.created": "Customer Created",
12
- "promotion-new-customer": "Promotion (New Customer)",
13
- "promotion-expiry-reminder": "Promotion Expiry Reminder",
14
- "shipment.confirmed": "Shipment Confirmed",
15
- "cart.abandoned": "Abandoned Cart",
16
- "cart.abandoned.discount": "Abandoned Cart (Discount)",
17
- "review.request": "Review Request",
18
- "winback": "Win-back"
19
- };
20
- const BrevoAnalyticsPage = () => {
21
- const [data, setData] = react.useState(null);
22
- const [loading, setLoading] = react.useState(true);
23
- const [error, setError] = react.useState(null);
24
- react.useEffect(() => {
25
- fetch("/admin/brevo-plugin-settings/analytics", { credentials: "include" }).then((res) => res.json()).then((d) => {
26
- setData(d);
27
- setLoading(false);
28
- }).catch(() => {
29
- setError("Failed to load analytics. Make sure Brevo API key is configured.");
30
- setLoading(false);
31
- });
32
- }, []);
33
- if (loading) {
34
- return /* @__PURE__ */ jsxRuntime.jsx(ui.Container, { className: "divide-y p-0", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-6 py-4", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { children: "Loading analytics..." }) }) });
35
- }
36
- if (error || !(data == null ? void 0 : data.stats)) {
37
- return /* @__PURE__ */ jsxRuntime.jsx(ui.Container, { className: "divide-y p-0", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-6 py-4", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "text-ui-fg-error", children: error || (data == null ? void 0 : data.error) || "No data available" }) }) });
38
- }
39
- const { stats, perEvent } = data;
40
- const statItems = [
41
- { label: "Delivered", value: stats.delivered, color: "green" },
42
- { label: "Opened", value: stats.opened, color: "blue" },
43
- { label: "Clicked", value: stats.clicked, color: "purple" },
44
- { label: "Bounced", value: stats.bounced, color: "orange" },
45
- { label: "Blocked", value: stats.blocked, color: "red" },
46
- { label: "Unsubscribed", value: stats.unsubscribed, color: "grey" }
47
- ];
48
- const openRate = stats.delivered > 0 ? (stats.opened / stats.delivered * 100).toFixed(1) : "0";
49
- const clickRate = stats.opened > 0 ? (stats.clicked / stats.opened * 100).toFixed(1) : "0";
50
- const perEventEntries = Object.entries(perEvent || {}).sort((a, b) => b[1].delivered - a[1].delivered);
51
- return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
52
- /* @__PURE__ */ jsxRuntime.jsx(ui.Container, { className: "divide-y p-0", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "px-6 py-4", children: [
53
- /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h1", children: "Email Analytics" }),
54
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "text-ui-fg-subtle mt-1", children: "Transactional email performance from Brevo (last 30 days)" })
55
- ] }) }),
56
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-2 md:grid-cols-4 gap-4 mt-4", children: statItems.map(({ label, value, color }) => /* @__PURE__ */ jsxRuntime.jsx(ui.Container, { className: "p-0", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "px-6 py-4 text-center", children: [
57
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "text-ui-fg-subtle text-xs uppercase", children: label }),
58
- /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "mt-1", children: value.toLocaleString() }),
59
- /* @__PURE__ */ jsxRuntime.jsx(ui.Badge, { color, className: "mt-2", children: label })
60
- ] }) }, label)) }),
61
- /* @__PURE__ */ jsxRuntime.jsx(ui.Container, { className: "divide-y p-0 mt-4", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "px-6 py-4", children: [
62
- /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "mb-4", children: "Conversion Rates" }),
63
- /* @__PURE__ */ jsxRuntime.jsxs(ui.Table, { children: [
64
- /* @__PURE__ */ jsxRuntime.jsx(ui.Table.Header, { children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Table.Row, { children: [
65
- /* @__PURE__ */ jsxRuntime.jsx(ui.Table.HeaderCell, { children: "Metric" }),
66
- /* @__PURE__ */ jsxRuntime.jsx(ui.Table.HeaderCell, { children: "Rate" }),
67
- /* @__PURE__ */ jsxRuntime.jsx(ui.Table.HeaderCell, { children: "Details" })
68
- ] }) }),
69
- /* @__PURE__ */ jsxRuntime.jsxs(ui.Table.Body, { children: [
70
- /* @__PURE__ */ jsxRuntime.jsxs(ui.Table.Row, { children: [
71
- /* @__PURE__ */ jsxRuntime.jsx(ui.Table.Cell, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: "Open Rate" }) }),
72
- /* @__PURE__ */ jsxRuntime.jsx(ui.Table.Cell, { children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Badge, { color: "blue", children: [
73
- openRate,
74
- "%"
75
- ] }) }),
76
- /* @__PURE__ */ jsxRuntime.jsx(ui.Table.Cell, { children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { className: "text-ui-fg-subtle", children: [
77
- stats.opened,
78
- " / ",
79
- stats.delivered,
80
- " delivered"
81
- ] }) })
82
- ] }),
83
- /* @__PURE__ */ jsxRuntime.jsxs(ui.Table.Row, { children: [
84
- /* @__PURE__ */ jsxRuntime.jsx(ui.Table.Cell, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: "Click Rate" }) }),
85
- /* @__PURE__ */ jsxRuntime.jsx(ui.Table.Cell, { children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Badge, { color: "purple", children: [
86
- clickRate,
87
- "%"
88
- ] }) }),
89
- /* @__PURE__ */ jsxRuntime.jsx(ui.Table.Cell, { children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { className: "text-ui-fg-subtle", children: [
90
- stats.clicked,
91
- " / ",
92
- stats.opened,
93
- " opened"
94
- ] }) })
95
- ] }),
96
- /* @__PURE__ */ jsxRuntime.jsxs(ui.Table.Row, { children: [
97
- /* @__PURE__ */ jsxRuntime.jsx(ui.Table.Cell, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: "Bounce Rate" }) }),
98
- /* @__PURE__ */ jsxRuntime.jsx(ui.Table.Cell, { children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Badge, { color: "orange", children: [
99
- stats.delivered > 0 ? (stats.bounced / (stats.delivered + stats.bounced) * 100).toFixed(1) : "0",
100
- "%"
101
- ] }) }),
102
- /* @__PURE__ */ jsxRuntime.jsx(ui.Table.Cell, { children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { className: "text-ui-fg-subtle", children: [
103
- stats.bounced,
104
- " bounced"
105
- ] }) })
106
- ] })
107
- ] })
108
- ] })
109
- ] }) }),
110
- perEventEntries.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(ui.Container, { className: "divide-y p-0 mt-4", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "px-6 py-4", children: [
111
- /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "mb-2", children: "Per-Event Breakdown" }),
112
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "text-ui-fg-subtle mb-4", children: "Performance by email event type (only events with activity shown)" }),
113
- /* @__PURE__ */ jsxRuntime.jsxs(ui.Table, { children: [
114
- /* @__PURE__ */ jsxRuntime.jsx(ui.Table.Header, { children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Table.Row, { children: [
115
- /* @__PURE__ */ jsxRuntime.jsx(ui.Table.HeaderCell, { children: "Event" }),
116
- /* @__PURE__ */ jsxRuntime.jsx(ui.Table.HeaderCell, { children: "Sent" }),
117
- /* @__PURE__ */ jsxRuntime.jsx(ui.Table.HeaderCell, { children: "Opened" }),
118
- /* @__PURE__ */ jsxRuntime.jsx(ui.Table.HeaderCell, { children: "Clicked" }),
119
- /* @__PURE__ */ jsxRuntime.jsx(ui.Table.HeaderCell, { children: "Open Rate" }),
120
- /* @__PURE__ */ jsxRuntime.jsx(ui.Table.HeaderCell, { children: "Bounced" })
121
- ] }) }),
122
- /* @__PURE__ */ jsxRuntime.jsx(ui.Table.Body, { children: perEventEntries.map(([event, eventStats]) => {
123
- const evOpenRate = eventStats.delivered > 0 ? (eventStats.opened / eventStats.delivered * 100).toFixed(1) : "0";
124
- return /* @__PURE__ */ jsxRuntime.jsxs(ui.Table.Row, { children: [
125
- /* @__PURE__ */ jsxRuntime.jsx(ui.Table.Cell, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: EVENT_LABELS[event] || event }) }),
126
- /* @__PURE__ */ jsxRuntime.jsx(ui.Table.Cell, { children: eventStats.delivered.toLocaleString() }),
127
- /* @__PURE__ */ jsxRuntime.jsx(ui.Table.Cell, { children: eventStats.opened.toLocaleString() }),
128
- /* @__PURE__ */ jsxRuntime.jsx(ui.Table.Cell, { children: eventStats.clicked.toLocaleString() }),
129
- /* @__PURE__ */ jsxRuntime.jsx(ui.Table.Cell, { children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Badge, { color: "blue", children: [
130
- evOpenRate,
131
- "%"
132
- ] }) }),
133
- /* @__PURE__ */ jsxRuntime.jsx(ui.Table.Cell, { children: eventStats.bounced > 0 ? eventStats.bounced.toLocaleString() : "—" })
134
- ] }, event);
135
- }) })
136
- ] })
137
- ] }) }),
138
- perEventEntries.length === 0 && /* @__PURE__ */ jsxRuntime.jsx(ui.Container, { className: "divide-y p-0 mt-4", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "px-6 py-4", children: [
139
- /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "mb-2", children: "Per-Event Breakdown" }),
140
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "text-ui-fg-subtle", children: "No per-event data yet. Emails sent after this update will be tagged automatically and stats will appear here." })
141
- ] }) })
142
- ] });
143
- };
144
- const config$1 = adminSdk.defineRouteConfig({
145
- label: "Email Analytics",
146
- icon: icons.ChartBar
147
- });
148
7
  const BrevoSettingsPage = () => {
149
8
  const [settings, setSettings] = react.useState(null);
150
9
  const [loading, setLoading] = react.useState(true);
@@ -1040,36 +899,177 @@ const BrevoSettingsPage = () => {
1040
899
  ] }) })
1041
900
  ] });
1042
901
  };
1043
- const config = adminSdk.defineRouteConfig({
902
+ const config$1 = adminSdk.defineRouteConfig({
1044
903
  label: "Brevo",
1045
904
  icon: icons.EnvelopeSolid
1046
905
  });
906
+ const EVENT_LABELS = {
907
+ "order.placed": "Order Placed",
908
+ "order.canceled": "Order Canceled",
909
+ "order.delivered": "Order Delivered",
910
+ "customer.created": "Customer Created",
911
+ "promotion-new-customer": "Promotion (New Customer)",
912
+ "promotion-expiry-reminder": "Promotion Expiry Reminder",
913
+ "shipment.confirmed": "Shipment Confirmed",
914
+ "cart.abandoned": "Abandoned Cart",
915
+ "cart.abandoned.discount": "Abandoned Cart (Discount)",
916
+ "review.request": "Review Request",
917
+ "winback": "Win-back"
918
+ };
919
+ const BrevoAnalyticsPage = () => {
920
+ const [data, setData] = react.useState(null);
921
+ const [loading, setLoading] = react.useState(true);
922
+ const [error, setError] = react.useState(null);
923
+ react.useEffect(() => {
924
+ fetch("/admin/brevo-plugin-settings/analytics", { credentials: "include" }).then((res) => res.json()).then((d) => {
925
+ setData(d);
926
+ setLoading(false);
927
+ }).catch(() => {
928
+ setError("Failed to load analytics. Make sure Brevo API key is configured.");
929
+ setLoading(false);
930
+ });
931
+ }, []);
932
+ if (loading) {
933
+ return /* @__PURE__ */ jsxRuntime.jsx(ui.Container, { className: "divide-y p-0", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-6 py-4", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { children: "Loading analytics..." }) }) });
934
+ }
935
+ if (error || !(data == null ? void 0 : data.stats)) {
936
+ return /* @__PURE__ */ jsxRuntime.jsx(ui.Container, { className: "divide-y p-0", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-6 py-4", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "text-ui-fg-error", children: error || (data == null ? void 0 : data.error) || "No data available" }) }) });
937
+ }
938
+ const { stats, perEvent } = data;
939
+ const statItems = [
940
+ { label: "Delivered", value: stats.delivered, color: "green" },
941
+ { label: "Opened", value: stats.opened, color: "blue" },
942
+ { label: "Clicked", value: stats.clicked, color: "purple" },
943
+ { label: "Bounced", value: stats.bounced, color: "orange" },
944
+ { label: "Blocked", value: stats.blocked, color: "red" },
945
+ { label: "Unsubscribed", value: stats.unsubscribed, color: "grey" }
946
+ ];
947
+ const openRate = stats.delivered > 0 ? (stats.opened / stats.delivered * 100).toFixed(1) : "0";
948
+ const clickRate = stats.opened > 0 ? (stats.clicked / stats.opened * 100).toFixed(1) : "0";
949
+ const perEventEntries = Object.entries(perEvent || {}).sort((a, b) => b[1].delivered - a[1].delivered);
950
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
951
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Container, { className: "divide-y p-0", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "px-6 py-4", children: [
952
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h1", children: "Email Analytics" }),
953
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "text-ui-fg-subtle mt-1", children: "Transactional email performance from Brevo (last 30 days)" })
954
+ ] }) }),
955
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-2 md:grid-cols-4 gap-4 mt-4", children: statItems.map(({ label, value, color }) => /* @__PURE__ */ jsxRuntime.jsx(ui.Container, { className: "p-0", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "px-6 py-4 text-center", children: [
956
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "text-ui-fg-subtle text-xs uppercase", children: label }),
957
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "mt-1", children: value.toLocaleString() }),
958
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Badge, { color, className: "mt-2", children: label })
959
+ ] }) }, label)) }),
960
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Container, { className: "divide-y p-0 mt-4", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "px-6 py-4", children: [
961
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "mb-4", children: "Conversion Rates" }),
962
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.Table, { children: [
963
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Table.Header, { children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Table.Row, { children: [
964
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Table.HeaderCell, { children: "Metric" }),
965
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Table.HeaderCell, { children: "Rate" }),
966
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Table.HeaderCell, { children: "Details" })
967
+ ] }) }),
968
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.Table.Body, { children: [
969
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.Table.Row, { children: [
970
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Table.Cell, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: "Open Rate" }) }),
971
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Table.Cell, { children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Badge, { color: "blue", children: [
972
+ openRate,
973
+ "%"
974
+ ] }) }),
975
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Table.Cell, { children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { className: "text-ui-fg-subtle", children: [
976
+ stats.opened,
977
+ " / ",
978
+ stats.delivered,
979
+ " delivered"
980
+ ] }) })
981
+ ] }),
982
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.Table.Row, { children: [
983
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Table.Cell, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: "Click Rate" }) }),
984
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Table.Cell, { children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Badge, { color: "purple", children: [
985
+ clickRate,
986
+ "%"
987
+ ] }) }),
988
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Table.Cell, { children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { className: "text-ui-fg-subtle", children: [
989
+ stats.clicked,
990
+ " / ",
991
+ stats.opened,
992
+ " opened"
993
+ ] }) })
994
+ ] }),
995
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.Table.Row, { children: [
996
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Table.Cell, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: "Bounce Rate" }) }),
997
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Table.Cell, { children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Badge, { color: "orange", children: [
998
+ stats.delivered > 0 ? (stats.bounced / (stats.delivered + stats.bounced) * 100).toFixed(1) : "0",
999
+ "%"
1000
+ ] }) }),
1001
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Table.Cell, { children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { className: "text-ui-fg-subtle", children: [
1002
+ stats.bounced,
1003
+ " bounced"
1004
+ ] }) })
1005
+ ] })
1006
+ ] })
1007
+ ] })
1008
+ ] }) }),
1009
+ perEventEntries.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(ui.Container, { className: "divide-y p-0 mt-4", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "px-6 py-4", children: [
1010
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "mb-2", children: "Per-Event Breakdown" }),
1011
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "text-ui-fg-subtle mb-4", children: "Performance by email event type (only events with activity shown)" }),
1012
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.Table, { children: [
1013
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Table.Header, { children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Table.Row, { children: [
1014
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Table.HeaderCell, { children: "Event" }),
1015
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Table.HeaderCell, { children: "Sent" }),
1016
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Table.HeaderCell, { children: "Opened" }),
1017
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Table.HeaderCell, { children: "Clicked" }),
1018
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Table.HeaderCell, { children: "Open Rate" }),
1019
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Table.HeaderCell, { children: "Bounced" })
1020
+ ] }) }),
1021
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Table.Body, { children: perEventEntries.map(([event, eventStats]) => {
1022
+ const evOpenRate = eventStats.delivered > 0 ? (eventStats.opened / eventStats.delivered * 100).toFixed(1) : "0";
1023
+ return /* @__PURE__ */ jsxRuntime.jsxs(ui.Table.Row, { children: [
1024
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Table.Cell, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: EVENT_LABELS[event] || event }) }),
1025
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Table.Cell, { children: eventStats.delivered.toLocaleString() }),
1026
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Table.Cell, { children: eventStats.opened.toLocaleString() }),
1027
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Table.Cell, { children: eventStats.clicked.toLocaleString() }),
1028
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Table.Cell, { children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Badge, { color: "blue", children: [
1029
+ evOpenRate,
1030
+ "%"
1031
+ ] }) }),
1032
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Table.Cell, { children: eventStats.bounced > 0 ? eventStats.bounced.toLocaleString() : "—" })
1033
+ ] }, event);
1034
+ }) })
1035
+ ] })
1036
+ ] }) }),
1037
+ perEventEntries.length === 0 && /* @__PURE__ */ jsxRuntime.jsx(ui.Container, { className: "divide-y p-0 mt-4", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "px-6 py-4", children: [
1038
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "mb-2", children: "Per-Event Breakdown" }),
1039
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "text-ui-fg-subtle", children: "No per-event data yet. Emails sent after this update will be tagged automatically and stats will appear here." })
1040
+ ] }) })
1041
+ ] });
1042
+ };
1043
+ const config = adminSdk.defineRouteConfig({
1044
+ label: "Email Analytics",
1045
+ icon: icons.ChartBar
1046
+ });
1047
1047
  const widgetModule = { widgets: [] };
1048
1048
  const routeModule = {
1049
1049
  routes: [
1050
- {
1051
- Component: BrevoAnalyticsPage,
1052
- path: "/brevo-analytics"
1053
- },
1054
1050
  {
1055
1051
  Component: BrevoSettingsPage,
1056
1052
  path: "/settings/brevo"
1053
+ },
1054
+ {
1055
+ Component: BrevoAnalyticsPage,
1056
+ path: "/brevo-analytics"
1057
1057
  }
1058
1058
  ]
1059
1059
  };
1060
1060
  const menuItemModule = {
1061
1061
  menuItems: [
1062
1062
  {
1063
- label: config$1.label,
1064
- icon: config$1.icon,
1063
+ label: config.label,
1064
+ icon: config.icon,
1065
1065
  path: "/brevo-analytics",
1066
1066
  nested: void 0,
1067
1067
  rank: void 0,
1068
1068
  translationNs: void 0
1069
1069
  },
1070
1070
  {
1071
- label: config.label,
1072
- icon: config.icon,
1071
+ label: config$1.label,
1072
+ icon: config$1.icon,
1073
1073
  path: "/settings/brevo",
1074
1074
  nested: void 0,
1075
1075
  rank: void 0,
@@ -1,149 +1,8 @@
1
1
  import { jsx, jsxs, Fragment } from "react/jsx-runtime";
2
2
  import { defineRouteConfig } from "@medusajs/admin-sdk";
3
- import { Container, Text, Heading, Badge, Table, toast, Toaster, Button, Label, Input, Switch, Select, Drawer, Checkbox } from "@medusajs/ui";
4
- import { ChartBar, EnvelopeSolid } from "@medusajs/icons";
3
+ import { toast, Container, Text, Toaster, Heading, Button, Label, Input, Switch, Select, Badge, Drawer, Checkbox, Table } from "@medusajs/ui";
4
+ import { EnvelopeSolid, ChartBar } from "@medusajs/icons";
5
5
  import { useState, useEffect } from "react";
6
- const EVENT_LABELS = {
7
- "order.placed": "Order Placed",
8
- "order.canceled": "Order Canceled",
9
- "order.delivered": "Order Delivered",
10
- "customer.created": "Customer Created",
11
- "promotion-new-customer": "Promotion (New Customer)",
12
- "promotion-expiry-reminder": "Promotion Expiry Reminder",
13
- "shipment.confirmed": "Shipment Confirmed",
14
- "cart.abandoned": "Abandoned Cart",
15
- "cart.abandoned.discount": "Abandoned Cart (Discount)",
16
- "review.request": "Review Request",
17
- "winback": "Win-back"
18
- };
19
- const BrevoAnalyticsPage = () => {
20
- const [data, setData] = useState(null);
21
- const [loading, setLoading] = useState(true);
22
- const [error, setError] = useState(null);
23
- useEffect(() => {
24
- fetch("/admin/brevo-plugin-settings/analytics", { credentials: "include" }).then((res) => res.json()).then((d) => {
25
- setData(d);
26
- setLoading(false);
27
- }).catch(() => {
28
- setError("Failed to load analytics. Make sure Brevo API key is configured.");
29
- setLoading(false);
30
- });
31
- }, []);
32
- if (loading) {
33
- return /* @__PURE__ */ jsx(Container, { className: "divide-y p-0", children: /* @__PURE__ */ jsx("div", { className: "px-6 py-4", children: /* @__PURE__ */ jsx(Text, { children: "Loading analytics..." }) }) });
34
- }
35
- if (error || !(data == null ? void 0 : data.stats)) {
36
- return /* @__PURE__ */ jsx(Container, { className: "divide-y p-0", children: /* @__PURE__ */ jsx("div", { className: "px-6 py-4", children: /* @__PURE__ */ jsx(Text, { className: "text-ui-fg-error", children: error || (data == null ? void 0 : data.error) || "No data available" }) }) });
37
- }
38
- const { stats, perEvent } = data;
39
- const statItems = [
40
- { label: "Delivered", value: stats.delivered, color: "green" },
41
- { label: "Opened", value: stats.opened, color: "blue" },
42
- { label: "Clicked", value: stats.clicked, color: "purple" },
43
- { label: "Bounced", value: stats.bounced, color: "orange" },
44
- { label: "Blocked", value: stats.blocked, color: "red" },
45
- { label: "Unsubscribed", value: stats.unsubscribed, color: "grey" }
46
- ];
47
- const openRate = stats.delivered > 0 ? (stats.opened / stats.delivered * 100).toFixed(1) : "0";
48
- const clickRate = stats.opened > 0 ? (stats.clicked / stats.opened * 100).toFixed(1) : "0";
49
- const perEventEntries = Object.entries(perEvent || {}).sort((a, b) => b[1].delivered - a[1].delivered);
50
- return /* @__PURE__ */ jsxs(Fragment, { children: [
51
- /* @__PURE__ */ jsx(Container, { className: "divide-y p-0", children: /* @__PURE__ */ jsxs("div", { className: "px-6 py-4", children: [
52
- /* @__PURE__ */ jsx(Heading, { level: "h1", children: "Email Analytics" }),
53
- /* @__PURE__ */ jsx(Text, { className: "text-ui-fg-subtle mt-1", children: "Transactional email performance from Brevo (last 30 days)" })
54
- ] }) }),
55
- /* @__PURE__ */ jsx("div", { className: "grid grid-cols-2 md:grid-cols-4 gap-4 mt-4", children: statItems.map(({ label, value, color }) => /* @__PURE__ */ jsx(Container, { className: "p-0", children: /* @__PURE__ */ jsxs("div", { className: "px-6 py-4 text-center", children: [
56
- /* @__PURE__ */ jsx(Text, { className: "text-ui-fg-subtle text-xs uppercase", children: label }),
57
- /* @__PURE__ */ jsx(Heading, { level: "h2", className: "mt-1", children: value.toLocaleString() }),
58
- /* @__PURE__ */ jsx(Badge, { color, className: "mt-2", children: label })
59
- ] }) }, label)) }),
60
- /* @__PURE__ */ jsx(Container, { className: "divide-y p-0 mt-4", children: /* @__PURE__ */ jsxs("div", { className: "px-6 py-4", children: [
61
- /* @__PURE__ */ jsx(Heading, { level: "h2", className: "mb-4", children: "Conversion Rates" }),
62
- /* @__PURE__ */ jsxs(Table, { children: [
63
- /* @__PURE__ */ jsx(Table.Header, { children: /* @__PURE__ */ jsxs(Table.Row, { children: [
64
- /* @__PURE__ */ jsx(Table.HeaderCell, { children: "Metric" }),
65
- /* @__PURE__ */ jsx(Table.HeaderCell, { children: "Rate" }),
66
- /* @__PURE__ */ jsx(Table.HeaderCell, { children: "Details" })
67
- ] }) }),
68
- /* @__PURE__ */ jsxs(Table.Body, { children: [
69
- /* @__PURE__ */ jsxs(Table.Row, { children: [
70
- /* @__PURE__ */ jsx(Table.Cell, { children: /* @__PURE__ */ jsx(Text, { className: "font-medium", children: "Open Rate" }) }),
71
- /* @__PURE__ */ jsx(Table.Cell, { children: /* @__PURE__ */ jsxs(Badge, { color: "blue", children: [
72
- openRate,
73
- "%"
74
- ] }) }),
75
- /* @__PURE__ */ jsx(Table.Cell, { children: /* @__PURE__ */ jsxs(Text, { className: "text-ui-fg-subtle", children: [
76
- stats.opened,
77
- " / ",
78
- stats.delivered,
79
- " delivered"
80
- ] }) })
81
- ] }),
82
- /* @__PURE__ */ jsxs(Table.Row, { children: [
83
- /* @__PURE__ */ jsx(Table.Cell, { children: /* @__PURE__ */ jsx(Text, { className: "font-medium", children: "Click Rate" }) }),
84
- /* @__PURE__ */ jsx(Table.Cell, { children: /* @__PURE__ */ jsxs(Badge, { color: "purple", children: [
85
- clickRate,
86
- "%"
87
- ] }) }),
88
- /* @__PURE__ */ jsx(Table.Cell, { children: /* @__PURE__ */ jsxs(Text, { className: "text-ui-fg-subtle", children: [
89
- stats.clicked,
90
- " / ",
91
- stats.opened,
92
- " opened"
93
- ] }) })
94
- ] }),
95
- /* @__PURE__ */ jsxs(Table.Row, { children: [
96
- /* @__PURE__ */ jsx(Table.Cell, { children: /* @__PURE__ */ jsx(Text, { className: "font-medium", children: "Bounce Rate" }) }),
97
- /* @__PURE__ */ jsx(Table.Cell, { children: /* @__PURE__ */ jsxs(Badge, { color: "orange", children: [
98
- stats.delivered > 0 ? (stats.bounced / (stats.delivered + stats.bounced) * 100).toFixed(1) : "0",
99
- "%"
100
- ] }) }),
101
- /* @__PURE__ */ jsx(Table.Cell, { children: /* @__PURE__ */ jsxs(Text, { className: "text-ui-fg-subtle", children: [
102
- stats.bounced,
103
- " bounced"
104
- ] }) })
105
- ] })
106
- ] })
107
- ] })
108
- ] }) }),
109
- perEventEntries.length > 0 && /* @__PURE__ */ jsx(Container, { className: "divide-y p-0 mt-4", children: /* @__PURE__ */ jsxs("div", { className: "px-6 py-4", children: [
110
- /* @__PURE__ */ jsx(Heading, { level: "h2", className: "mb-2", children: "Per-Event Breakdown" }),
111
- /* @__PURE__ */ jsx(Text, { className: "text-ui-fg-subtle mb-4", children: "Performance by email event type (only events with activity shown)" }),
112
- /* @__PURE__ */ jsxs(Table, { children: [
113
- /* @__PURE__ */ jsx(Table.Header, { children: /* @__PURE__ */ jsxs(Table.Row, { children: [
114
- /* @__PURE__ */ jsx(Table.HeaderCell, { children: "Event" }),
115
- /* @__PURE__ */ jsx(Table.HeaderCell, { children: "Sent" }),
116
- /* @__PURE__ */ jsx(Table.HeaderCell, { children: "Opened" }),
117
- /* @__PURE__ */ jsx(Table.HeaderCell, { children: "Clicked" }),
118
- /* @__PURE__ */ jsx(Table.HeaderCell, { children: "Open Rate" }),
119
- /* @__PURE__ */ jsx(Table.HeaderCell, { children: "Bounced" })
120
- ] }) }),
121
- /* @__PURE__ */ jsx(Table.Body, { children: perEventEntries.map(([event, eventStats]) => {
122
- const evOpenRate = eventStats.delivered > 0 ? (eventStats.opened / eventStats.delivered * 100).toFixed(1) : "0";
123
- return /* @__PURE__ */ jsxs(Table.Row, { children: [
124
- /* @__PURE__ */ jsx(Table.Cell, { children: /* @__PURE__ */ jsx(Text, { className: "font-medium", children: EVENT_LABELS[event] || event }) }),
125
- /* @__PURE__ */ jsx(Table.Cell, { children: eventStats.delivered.toLocaleString() }),
126
- /* @__PURE__ */ jsx(Table.Cell, { children: eventStats.opened.toLocaleString() }),
127
- /* @__PURE__ */ jsx(Table.Cell, { children: eventStats.clicked.toLocaleString() }),
128
- /* @__PURE__ */ jsx(Table.Cell, { children: /* @__PURE__ */ jsxs(Badge, { color: "blue", children: [
129
- evOpenRate,
130
- "%"
131
- ] }) }),
132
- /* @__PURE__ */ jsx(Table.Cell, { children: eventStats.bounced > 0 ? eventStats.bounced.toLocaleString() : "—" })
133
- ] }, event);
134
- }) })
135
- ] })
136
- ] }) }),
137
- perEventEntries.length === 0 && /* @__PURE__ */ jsx(Container, { className: "divide-y p-0 mt-4", children: /* @__PURE__ */ jsxs("div", { className: "px-6 py-4", children: [
138
- /* @__PURE__ */ jsx(Heading, { level: "h2", className: "mb-2", children: "Per-Event Breakdown" }),
139
- /* @__PURE__ */ jsx(Text, { className: "text-ui-fg-subtle", children: "No per-event data yet. Emails sent after this update will be tagged automatically and stats will appear here." })
140
- ] }) })
141
- ] });
142
- };
143
- const config$1 = defineRouteConfig({
144
- label: "Email Analytics",
145
- icon: ChartBar
146
- });
147
6
  const BrevoSettingsPage = () => {
148
7
  const [settings, setSettings] = useState(null);
149
8
  const [loading, setLoading] = useState(true);
@@ -1039,36 +898,177 @@ const BrevoSettingsPage = () => {
1039
898
  ] }) })
1040
899
  ] });
1041
900
  };
1042
- const config = defineRouteConfig({
901
+ const config$1 = defineRouteConfig({
1043
902
  label: "Brevo",
1044
903
  icon: EnvelopeSolid
1045
904
  });
905
+ const EVENT_LABELS = {
906
+ "order.placed": "Order Placed",
907
+ "order.canceled": "Order Canceled",
908
+ "order.delivered": "Order Delivered",
909
+ "customer.created": "Customer Created",
910
+ "promotion-new-customer": "Promotion (New Customer)",
911
+ "promotion-expiry-reminder": "Promotion Expiry Reminder",
912
+ "shipment.confirmed": "Shipment Confirmed",
913
+ "cart.abandoned": "Abandoned Cart",
914
+ "cart.abandoned.discount": "Abandoned Cart (Discount)",
915
+ "review.request": "Review Request",
916
+ "winback": "Win-back"
917
+ };
918
+ const BrevoAnalyticsPage = () => {
919
+ const [data, setData] = useState(null);
920
+ const [loading, setLoading] = useState(true);
921
+ const [error, setError] = useState(null);
922
+ useEffect(() => {
923
+ fetch("/admin/brevo-plugin-settings/analytics", { credentials: "include" }).then((res) => res.json()).then((d) => {
924
+ setData(d);
925
+ setLoading(false);
926
+ }).catch(() => {
927
+ setError("Failed to load analytics. Make sure Brevo API key is configured.");
928
+ setLoading(false);
929
+ });
930
+ }, []);
931
+ if (loading) {
932
+ return /* @__PURE__ */ jsx(Container, { className: "divide-y p-0", children: /* @__PURE__ */ jsx("div", { className: "px-6 py-4", children: /* @__PURE__ */ jsx(Text, { children: "Loading analytics..." }) }) });
933
+ }
934
+ if (error || !(data == null ? void 0 : data.stats)) {
935
+ return /* @__PURE__ */ jsx(Container, { className: "divide-y p-0", children: /* @__PURE__ */ jsx("div", { className: "px-6 py-4", children: /* @__PURE__ */ jsx(Text, { className: "text-ui-fg-error", children: error || (data == null ? void 0 : data.error) || "No data available" }) }) });
936
+ }
937
+ const { stats, perEvent } = data;
938
+ const statItems = [
939
+ { label: "Delivered", value: stats.delivered, color: "green" },
940
+ { label: "Opened", value: stats.opened, color: "blue" },
941
+ { label: "Clicked", value: stats.clicked, color: "purple" },
942
+ { label: "Bounced", value: stats.bounced, color: "orange" },
943
+ { label: "Blocked", value: stats.blocked, color: "red" },
944
+ { label: "Unsubscribed", value: stats.unsubscribed, color: "grey" }
945
+ ];
946
+ const openRate = stats.delivered > 0 ? (stats.opened / stats.delivered * 100).toFixed(1) : "0";
947
+ const clickRate = stats.opened > 0 ? (stats.clicked / stats.opened * 100).toFixed(1) : "0";
948
+ const perEventEntries = Object.entries(perEvent || {}).sort((a, b) => b[1].delivered - a[1].delivered);
949
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
950
+ /* @__PURE__ */ jsx(Container, { className: "divide-y p-0", children: /* @__PURE__ */ jsxs("div", { className: "px-6 py-4", children: [
951
+ /* @__PURE__ */ jsx(Heading, { level: "h1", children: "Email Analytics" }),
952
+ /* @__PURE__ */ jsx(Text, { className: "text-ui-fg-subtle mt-1", children: "Transactional email performance from Brevo (last 30 days)" })
953
+ ] }) }),
954
+ /* @__PURE__ */ jsx("div", { className: "grid grid-cols-2 md:grid-cols-4 gap-4 mt-4", children: statItems.map(({ label, value, color }) => /* @__PURE__ */ jsx(Container, { className: "p-0", children: /* @__PURE__ */ jsxs("div", { className: "px-6 py-4 text-center", children: [
955
+ /* @__PURE__ */ jsx(Text, { className: "text-ui-fg-subtle text-xs uppercase", children: label }),
956
+ /* @__PURE__ */ jsx(Heading, { level: "h2", className: "mt-1", children: value.toLocaleString() }),
957
+ /* @__PURE__ */ jsx(Badge, { color, className: "mt-2", children: label })
958
+ ] }) }, label)) }),
959
+ /* @__PURE__ */ jsx(Container, { className: "divide-y p-0 mt-4", children: /* @__PURE__ */ jsxs("div", { className: "px-6 py-4", children: [
960
+ /* @__PURE__ */ jsx(Heading, { level: "h2", className: "mb-4", children: "Conversion Rates" }),
961
+ /* @__PURE__ */ jsxs(Table, { children: [
962
+ /* @__PURE__ */ jsx(Table.Header, { children: /* @__PURE__ */ jsxs(Table.Row, { children: [
963
+ /* @__PURE__ */ jsx(Table.HeaderCell, { children: "Metric" }),
964
+ /* @__PURE__ */ jsx(Table.HeaderCell, { children: "Rate" }),
965
+ /* @__PURE__ */ jsx(Table.HeaderCell, { children: "Details" })
966
+ ] }) }),
967
+ /* @__PURE__ */ jsxs(Table.Body, { children: [
968
+ /* @__PURE__ */ jsxs(Table.Row, { children: [
969
+ /* @__PURE__ */ jsx(Table.Cell, { children: /* @__PURE__ */ jsx(Text, { className: "font-medium", children: "Open Rate" }) }),
970
+ /* @__PURE__ */ jsx(Table.Cell, { children: /* @__PURE__ */ jsxs(Badge, { color: "blue", children: [
971
+ openRate,
972
+ "%"
973
+ ] }) }),
974
+ /* @__PURE__ */ jsx(Table.Cell, { children: /* @__PURE__ */ jsxs(Text, { className: "text-ui-fg-subtle", children: [
975
+ stats.opened,
976
+ " / ",
977
+ stats.delivered,
978
+ " delivered"
979
+ ] }) })
980
+ ] }),
981
+ /* @__PURE__ */ jsxs(Table.Row, { children: [
982
+ /* @__PURE__ */ jsx(Table.Cell, { children: /* @__PURE__ */ jsx(Text, { className: "font-medium", children: "Click Rate" }) }),
983
+ /* @__PURE__ */ jsx(Table.Cell, { children: /* @__PURE__ */ jsxs(Badge, { color: "purple", children: [
984
+ clickRate,
985
+ "%"
986
+ ] }) }),
987
+ /* @__PURE__ */ jsx(Table.Cell, { children: /* @__PURE__ */ jsxs(Text, { className: "text-ui-fg-subtle", children: [
988
+ stats.clicked,
989
+ " / ",
990
+ stats.opened,
991
+ " opened"
992
+ ] }) })
993
+ ] }),
994
+ /* @__PURE__ */ jsxs(Table.Row, { children: [
995
+ /* @__PURE__ */ jsx(Table.Cell, { children: /* @__PURE__ */ jsx(Text, { className: "font-medium", children: "Bounce Rate" }) }),
996
+ /* @__PURE__ */ jsx(Table.Cell, { children: /* @__PURE__ */ jsxs(Badge, { color: "orange", children: [
997
+ stats.delivered > 0 ? (stats.bounced / (stats.delivered + stats.bounced) * 100).toFixed(1) : "0",
998
+ "%"
999
+ ] }) }),
1000
+ /* @__PURE__ */ jsx(Table.Cell, { children: /* @__PURE__ */ jsxs(Text, { className: "text-ui-fg-subtle", children: [
1001
+ stats.bounced,
1002
+ " bounced"
1003
+ ] }) })
1004
+ ] })
1005
+ ] })
1006
+ ] })
1007
+ ] }) }),
1008
+ perEventEntries.length > 0 && /* @__PURE__ */ jsx(Container, { className: "divide-y p-0 mt-4", children: /* @__PURE__ */ jsxs("div", { className: "px-6 py-4", children: [
1009
+ /* @__PURE__ */ jsx(Heading, { level: "h2", className: "mb-2", children: "Per-Event Breakdown" }),
1010
+ /* @__PURE__ */ jsx(Text, { className: "text-ui-fg-subtle mb-4", children: "Performance by email event type (only events with activity shown)" }),
1011
+ /* @__PURE__ */ jsxs(Table, { children: [
1012
+ /* @__PURE__ */ jsx(Table.Header, { children: /* @__PURE__ */ jsxs(Table.Row, { children: [
1013
+ /* @__PURE__ */ jsx(Table.HeaderCell, { children: "Event" }),
1014
+ /* @__PURE__ */ jsx(Table.HeaderCell, { children: "Sent" }),
1015
+ /* @__PURE__ */ jsx(Table.HeaderCell, { children: "Opened" }),
1016
+ /* @__PURE__ */ jsx(Table.HeaderCell, { children: "Clicked" }),
1017
+ /* @__PURE__ */ jsx(Table.HeaderCell, { children: "Open Rate" }),
1018
+ /* @__PURE__ */ jsx(Table.HeaderCell, { children: "Bounced" })
1019
+ ] }) }),
1020
+ /* @__PURE__ */ jsx(Table.Body, { children: perEventEntries.map(([event, eventStats]) => {
1021
+ const evOpenRate = eventStats.delivered > 0 ? (eventStats.opened / eventStats.delivered * 100).toFixed(1) : "0";
1022
+ return /* @__PURE__ */ jsxs(Table.Row, { children: [
1023
+ /* @__PURE__ */ jsx(Table.Cell, { children: /* @__PURE__ */ jsx(Text, { className: "font-medium", children: EVENT_LABELS[event] || event }) }),
1024
+ /* @__PURE__ */ jsx(Table.Cell, { children: eventStats.delivered.toLocaleString() }),
1025
+ /* @__PURE__ */ jsx(Table.Cell, { children: eventStats.opened.toLocaleString() }),
1026
+ /* @__PURE__ */ jsx(Table.Cell, { children: eventStats.clicked.toLocaleString() }),
1027
+ /* @__PURE__ */ jsx(Table.Cell, { children: /* @__PURE__ */ jsxs(Badge, { color: "blue", children: [
1028
+ evOpenRate,
1029
+ "%"
1030
+ ] }) }),
1031
+ /* @__PURE__ */ jsx(Table.Cell, { children: eventStats.bounced > 0 ? eventStats.bounced.toLocaleString() : "—" })
1032
+ ] }, event);
1033
+ }) })
1034
+ ] })
1035
+ ] }) }),
1036
+ perEventEntries.length === 0 && /* @__PURE__ */ jsx(Container, { className: "divide-y p-0 mt-4", children: /* @__PURE__ */ jsxs("div", { className: "px-6 py-4", children: [
1037
+ /* @__PURE__ */ jsx(Heading, { level: "h2", className: "mb-2", children: "Per-Event Breakdown" }),
1038
+ /* @__PURE__ */ jsx(Text, { className: "text-ui-fg-subtle", children: "No per-event data yet. Emails sent after this update will be tagged automatically and stats will appear here." })
1039
+ ] }) })
1040
+ ] });
1041
+ };
1042
+ const config = defineRouteConfig({
1043
+ label: "Email Analytics",
1044
+ icon: ChartBar
1045
+ });
1046
1046
  const widgetModule = { widgets: [] };
1047
1047
  const routeModule = {
1048
1048
  routes: [
1049
- {
1050
- Component: BrevoAnalyticsPage,
1051
- path: "/brevo-analytics"
1052
- },
1053
1049
  {
1054
1050
  Component: BrevoSettingsPage,
1055
1051
  path: "/settings/brevo"
1052
+ },
1053
+ {
1054
+ Component: BrevoAnalyticsPage,
1055
+ path: "/brevo-analytics"
1056
1056
  }
1057
1057
  ]
1058
1058
  };
1059
1059
  const menuItemModule = {
1060
1060
  menuItems: [
1061
1061
  {
1062
- label: config$1.label,
1063
- icon: config$1.icon,
1062
+ label: config.label,
1063
+ icon: config.icon,
1064
1064
  path: "/brevo-analytics",
1065
1065
  nested: void 0,
1066
1066
  rank: void 0,
1067
1067
  translationNs: void 0
1068
1068
  },
1069
1069
  {
1070
- label: config.label,
1071
- icon: config.icon,
1070
+ label: config$1.label,
1071
+ icon: config$1.icon,
1072
1072
  path: "/settings/brevo",
1073
1073
  nested: void 0,
1074
1074
  rank: void 0,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kb0912/notification-brevo",
3
- "version": "2.1.1",
3
+ "version": "2.1.2",
4
4
  "description": "Sending email notification using Brevo.",
5
5
  "author": "KB (https://medusajs.com)",
6
6
  "license": "MIT",
@@ -36,13 +36,13 @@
36
36
  "prepublishOnly": "medusa plugin:build"
37
37
  },
38
38
  "devDependencies": {
39
- "@medusajs/admin-sdk": "^2.13.3",
40
- "@medusajs/cli": "^2.13.3",
41
- "@medusajs/framework": "^2.13.3",
42
- "@medusajs/icons": "^2.13.3",
43
- "@medusajs/medusa": "^2.13.3",
44
- "@medusajs/test-utils": "^2.13.3",
45
- "@medusajs/ui": "^4.1.3",
39
+ "@medusajs/admin-sdk": "^2.15.5",
40
+ "@medusajs/cli": "^2.15.5",
41
+ "@medusajs/framework": "^2.15.5",
42
+ "@medusajs/icons": "^2.15.5",
43
+ "@medusajs/medusa": "^2.15.5",
44
+ "@medusajs/test-utils": "^2.15.5",
45
+ "@medusajs/ui": "^4.1.15",
46
46
  "@swc/core": "1.5.7",
47
47
  "@types/node": "^20.0.0",
48
48
  "@types/react": "^18.3.2",
@@ -81,4 +81,4 @@
81
81
  "@getbrevo/brevo": "^4.0.1"
82
82
  },
83
83
  "main": "index.js"
84
- }
84
+ }