@ammarkhalidfarooq/dashboard-package 0.5.16 → 0.5.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs.js CHANGED
@@ -887,6 +887,1454 @@ var Dashboard = function Dashboard(_ref) {
887
887
  });
888
888
  };
889
889
 
890
+ function formatNumber(num) {
891
+ if (num >= 1000000000) {
892
+ return (num / 1000000000).toFixed(1).replace(/\.0$/, "") + "B";
893
+ }
894
+ if (num >= 1000000) {
895
+ return (num / 1000000).toFixed(1).replace(/\.0$/, "") + "M";
896
+ }
897
+ if (num >= 1000) {
898
+ return (num / 1000).toFixed(1).replace(/\.0$/, "") + "K";
899
+ }
900
+ return (num !== null && num !== void 0 ? num : 0).toString();
901
+ }
902
+
903
+ var W = 794;
904
+ var H = 1123;
905
+ var MX = 32; // horizontal margin
906
+ var CW = W - MX * 2; // 730 px usable width
907
+
908
+ // ─── Number helpers ───────────────────────────────────────────────────────────
909
+ var d$ = function d$(v) {
910
+ return "$".concat(formatNumber(Number(v !== null && v !== void 0 ? v : 0)));
911
+ };
912
+ var pct = function pct(v) {
913
+ var dp = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 2;
914
+ return "".concat(Number(v !== null && v !== void 0 ? v : 0).toFixed(dp), "%");
915
+ };
916
+ var signed = function signed(v) {
917
+ var suffix = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : "%";
918
+ var n = Number(v !== null && v !== void 0 ? v : 0);
919
+ return "".concat(n >= 0 ? "+" : "").concat(n.toFixed(2)).concat(suffix);
920
+ };
921
+
922
+ // ─── SVG line sparkline ───────────────────────────────────────────────────────
923
+ var Sparkline = function Sparkline(_ref) {
924
+ var _ref$data = _ref.data,
925
+ data = _ref$data === void 0 ? [] : _ref$data,
926
+ _ref$color = _ref.color,
927
+ color = _ref$color === void 0 ? "#6366F1" : _ref$color,
928
+ _ref$width = _ref.width,
929
+ width = _ref$width === void 0 ? 120 : _ref$width,
930
+ _ref$height = _ref.height,
931
+ height = _ref$height === void 0 ? 40 : _ref$height;
932
+ var vals = data.length >= 2 ? data : [0, 0];
933
+ var max = Math.max.apply(Math, _toConsumableArray(vals).concat([0]));
934
+ var min = Math.min.apply(Math, _toConsumableArray(vals).concat([0]));
935
+ var range = max - min || 1;
936
+ var pad = 3;
937
+ var pts = vals.map(function (v, i) {
938
+ return [pad + i / (vals.length - 1) * (width - pad * 2), pad + (height - pad * 2) - (v - min) / range * (height - pad * 2)];
939
+ });
940
+ var d = pts.map(function (p, i) {
941
+ return "".concat(i === 0 ? "M" : "L").concat(p[0].toFixed(1), ",").concat(p[1].toFixed(1));
942
+ }).join(" ");
943
+ var area = "".concat(d, " L").concat((width - pad).toFixed(1), ",").concat(height, " L").concat(pad, ",").concat(height, " Z");
944
+ var gradId = "sp-".concat(color.replace(/[^a-z0-9]/gi, ""));
945
+ return /*#__PURE__*/jsxRuntime.jsxs("svg", {
946
+ width: width,
947
+ height: height,
948
+ style: {
949
+ display: "block",
950
+ overflow: "visible"
951
+ },
952
+ children: [/*#__PURE__*/jsxRuntime.jsx("defs", {
953
+ children: /*#__PURE__*/jsxRuntime.jsxs("linearGradient", {
954
+ id: gradId,
955
+ x1: "0",
956
+ y1: "0",
957
+ x2: "0",
958
+ y2: "1",
959
+ children: [/*#__PURE__*/jsxRuntime.jsx("stop", {
960
+ offset: "0%",
961
+ stopColor: color,
962
+ stopOpacity: "0.15"
963
+ }), /*#__PURE__*/jsxRuntime.jsx("stop", {
964
+ offset: "100%",
965
+ stopColor: color,
966
+ stopOpacity: "0"
967
+ })]
968
+ })
969
+ }), /*#__PURE__*/jsxRuntime.jsx("path", {
970
+ d: area,
971
+ fill: "url(#".concat(gradId, ")")
972
+ }), /*#__PURE__*/jsxRuntime.jsx("path", {
973
+ d: d,
974
+ fill: "none",
975
+ stroke: color,
976
+ strokeWidth: 2,
977
+ strokeLinecap: "round",
978
+ strokeLinejoin: "round"
979
+ })]
980
+ });
981
+ };
982
+
983
+ // ─── SVG multi-series line chart ──────────────────────────────────────────────
984
+ var LineChart = function LineChart(_ref2) {
985
+ var _ref2$series = _ref2.series,
986
+ series = _ref2$series === void 0 ? [] : _ref2$series,
987
+ _ref2$categories = _ref2.categories,
988
+ categories = _ref2$categories === void 0 ? [] : _ref2$categories,
989
+ _ref2$width = _ref2.width,
990
+ width = _ref2$width === void 0 ? CW : _ref2$width,
991
+ _ref2$height = _ref2.height,
992
+ height = _ref2$height === void 0 ? 180 : _ref2$height;
993
+ var allVals = series.flatMap(function (s) {
994
+ return s.data || [];
995
+ });
996
+ if (!allVals.length) {
997
+ return /*#__PURE__*/jsxRuntime.jsx("div", {
998
+ style: {
999
+ height: height,
1000
+ background: "#F9FAFB",
1001
+ borderRadius: 6
1002
+ }
1003
+ });
1004
+ }
1005
+ var COLORS = ["#6366F1", "#10B981", "#06B6D4"];
1006
+ var PL = 46,
1007
+ PR = 8,
1008
+ PT = 8,
1009
+ PB = 22;
1010
+ var IW = width - PL - PR;
1011
+ var IH = height - PT - PB;
1012
+ var max = Math.max.apply(Math, _toConsumableArray(allVals).concat([0]));
1013
+ var min = 0;
1014
+ var range = max - min || 1;
1015
+ var xp = function xp(i, n) {
1016
+ return PL + i / Math.max(n - 1, 1) * IW;
1017
+ };
1018
+ var yp = function yp(v) {
1019
+ return PT + IH - (v - min) / range * IH;
1020
+ };
1021
+ var yTicks = [0, 0.25, 0.5, 0.75, 1].map(function (t) {
1022
+ return min + t * range;
1023
+ });
1024
+ var step = Math.max(1, Math.floor(categories.length / 6));
1025
+ var shownCats = categories.filter(function (_, i) {
1026
+ return i % step === 0 || i === categories.length - 1;
1027
+ });
1028
+ return /*#__PURE__*/jsxRuntime.jsxs("svg", {
1029
+ width: width,
1030
+ height: height,
1031
+ style: {
1032
+ display: "block"
1033
+ },
1034
+ children: [yTicks.map(function (v, i) {
1035
+ var y = yp(v);
1036
+ var label = v >= 10000 ? "$".concat((v / 1000).toFixed(0), "K") : v >= 1000 ? "$".concat((v / 1000).toFixed(1), "K") : "$".concat(v.toFixed(0));
1037
+ return /*#__PURE__*/jsxRuntime.jsxs("g", {
1038
+ children: [/*#__PURE__*/jsxRuntime.jsx("line", {
1039
+ x1: PL,
1040
+ y1: y,
1041
+ x2: width - PR,
1042
+ y2: y,
1043
+ stroke: "#F3F4F6",
1044
+ strokeWidth: 1
1045
+ }), /*#__PURE__*/jsxRuntime.jsx("text", {
1046
+ x: PL - 4,
1047
+ y: y + 3.5,
1048
+ textAnchor: "end",
1049
+ fontSize: 9,
1050
+ fill: "#9CA3AF",
1051
+ children: label
1052
+ })]
1053
+ }, i);
1054
+ }), series.map(function (s, si) {
1055
+ var data = s.data || [];
1056
+ if (!data.length) return null;
1057
+ var pathD = data.map(function (v, i) {
1058
+ return "".concat(i === 0 ? "M" : "L").concat(xp(i, data.length).toFixed(1), ",").concat(yp(v).toFixed(1));
1059
+ }).join(" ");
1060
+ return /*#__PURE__*/jsxRuntime.jsx("path", {
1061
+ d: pathD,
1062
+ fill: "none",
1063
+ stroke: COLORS[si % COLORS.length],
1064
+ strokeWidth: 2,
1065
+ strokeLinecap: "round",
1066
+ strokeLinejoin: "round"
1067
+ }, si);
1068
+ }), shownCats.map(function (label, i) {
1069
+ var origIdx = categories.indexOf(label);
1070
+ var x = xp(origIdx < 0 ? i * step : origIdx, categories.length);
1071
+ return /*#__PURE__*/jsxRuntime.jsx("text", {
1072
+ x: x,
1073
+ y: height - 5,
1074
+ textAnchor: "middle",
1075
+ fontSize: 9,
1076
+ fill: "#9CA3AF",
1077
+ children: label
1078
+ }, i);
1079
+ })]
1080
+ });
1081
+ };
1082
+
1083
+ // ─── SVG donut ────────────────────────────────────────────────────────────────
1084
+ var Donut = function Donut(_ref3) {
1085
+ var _ref3$segments = _ref3.segments,
1086
+ segments = _ref3$segments === void 0 ? [] : _ref3$segments,
1087
+ _ref3$size = _ref3.size,
1088
+ size = _ref3$size === void 0 ? 88 : _ref3$size,
1089
+ centerVal = _ref3.centerVal,
1090
+ centerLabel = _ref3.centerLabel;
1091
+ var total = segments.reduce(function (s, g) {
1092
+ return s + (g.value || 0);
1093
+ }, 0) || 1;
1094
+ var r = (size - 18) / 2;
1095
+ var cx = size / 2;
1096
+ var cy = size / 2;
1097
+ var circ = 2 * Math.PI * r;
1098
+ var cumulDash = 0;
1099
+ return /*#__PURE__*/jsxRuntime.jsxs("svg", {
1100
+ width: size,
1101
+ height: size,
1102
+ style: {
1103
+ display: "block"
1104
+ },
1105
+ children: [/*#__PURE__*/jsxRuntime.jsx("circle", {
1106
+ cx: cx,
1107
+ cy: cy,
1108
+ r: r,
1109
+ fill: "none",
1110
+ stroke: "#E5E7EB",
1111
+ strokeWidth: 12
1112
+ }), segments.map(function (seg, i) {
1113
+ var dash = seg.value / total * circ;
1114
+ var el = /*#__PURE__*/jsxRuntime.jsx("circle", {
1115
+ cx: cx,
1116
+ cy: cy,
1117
+ r: r,
1118
+ fill: "none",
1119
+ stroke: seg.color || "#6366F1",
1120
+ strokeWidth: 12,
1121
+ strokeDasharray: "".concat(dash, " ").concat(circ),
1122
+ strokeDashoffset: -cumulDash,
1123
+ strokeLinecap: "butt",
1124
+ transform: "rotate(-90 ".concat(cx, " ").concat(cy, ")")
1125
+ }, i);
1126
+ cumulDash += dash;
1127
+ return el;
1128
+ }), centerVal && /*#__PURE__*/jsxRuntime.jsx("text", {
1129
+ x: cx,
1130
+ y: cy - (centerLabel ? 5 : 0),
1131
+ textAnchor: "middle",
1132
+ fontSize: 14,
1133
+ fontWeight: "bold",
1134
+ fill: "#111827",
1135
+ children: centerVal
1136
+ }), centerLabel && /*#__PURE__*/jsxRuntime.jsx("text", {
1137
+ x: cx,
1138
+ y: cy + 13,
1139
+ textAnchor: "middle",
1140
+ fontSize: 9,
1141
+ fill: "#6B7280",
1142
+ children: centerLabel
1143
+ })]
1144
+ });
1145
+ };
1146
+
1147
+ // ─── Shared primitives ────────────────────────────────────────────────────────
1148
+ var Divider = function Divider(_ref4) {
1149
+ var _ref4$mt = _ref4.mt,
1150
+ mt = _ref4$mt === void 0 ? 0 : _ref4$mt,
1151
+ _ref4$mb = _ref4.mb,
1152
+ mb = _ref4$mb === void 0 ? 0 : _ref4$mb;
1153
+ return /*#__PURE__*/jsxRuntime.jsx("div", {
1154
+ style: {
1155
+ borderTop: "1px solid #E5E7EB",
1156
+ marginTop: mt,
1157
+ marginBottom: mb
1158
+ }
1159
+ });
1160
+ };
1161
+ var Panel = function Panel(_ref5) {
1162
+ var children = _ref5.children,
1163
+ title = _ref5.title,
1164
+ subtitle = _ref5.subtitle,
1165
+ action = _ref5.action,
1166
+ _ref5$style = _ref5.style,
1167
+ style = _ref5$style === void 0 ? {} : _ref5$style;
1168
+ return /*#__PURE__*/jsxRuntime.jsxs("div", {
1169
+ style: _objectSpread2({
1170
+ border: "1px solid #E5E7EB",
1171
+ borderRadius: 8,
1172
+ background: "#fff",
1173
+ padding: 12,
1174
+ display: "flex",
1175
+ flexDirection: "column",
1176
+ boxSizing: "border-box"
1177
+ }, style),
1178
+ children: [(title || subtitle || action) && /*#__PURE__*/jsxRuntime.jsxs("div", {
1179
+ style: {
1180
+ display: "flex",
1181
+ justifyContent: "space-between",
1182
+ alignItems: "flex-start",
1183
+ marginBottom: 8,
1184
+ flexShrink: 0
1185
+ },
1186
+ children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
1187
+ children: [title && /*#__PURE__*/jsxRuntime.jsx("div", {
1188
+ style: {
1189
+ fontSize: 12,
1190
+ fontWeight: 700,
1191
+ color: "#111827",
1192
+ lineHeight: 1.2
1193
+ },
1194
+ children: title
1195
+ }), subtitle && /*#__PURE__*/jsxRuntime.jsx("div", {
1196
+ style: {
1197
+ fontSize: 9.5,
1198
+ color: "#9CA3AF",
1199
+ marginTop: 2
1200
+ },
1201
+ children: subtitle
1202
+ })]
1203
+ }), action && /*#__PURE__*/jsxRuntime.jsx("div", {
1204
+ style: {
1205
+ fontSize: 9.5,
1206
+ color: "#6366F1",
1207
+ fontWeight: 500,
1208
+ flexShrink: 0
1209
+ },
1210
+ children: action
1211
+ })]
1212
+ }), children]
1213
+ });
1214
+ };
1215
+ var MiniTable = function MiniTable(_ref6) {
1216
+ var _ref6$head = _ref6.head,
1217
+ head = _ref6$head === void 0 ? [] : _ref6$head,
1218
+ _ref6$rows = _ref6.rows,
1219
+ rows = _ref6$rows === void 0 ? [] : _ref6$rows;
1220
+ return /*#__PURE__*/jsxRuntime.jsxs("table", {
1221
+ style: {
1222
+ width: "100%",
1223
+ borderCollapse: "collapse",
1224
+ fontSize: 9.5,
1225
+ tableLayout: "fixed"
1226
+ },
1227
+ children: [/*#__PURE__*/jsxRuntime.jsx("thead", {
1228
+ children: /*#__PURE__*/jsxRuntime.jsx("tr", {
1229
+ style: {
1230
+ background: "#F9FAFB"
1231
+ },
1232
+ children: head.map(function (h, i) {
1233
+ return /*#__PURE__*/jsxRuntime.jsx("th", {
1234
+ style: {
1235
+ padding: "4px 6px",
1236
+ textAlign: i === 0 ? "left" : "right",
1237
+ fontWeight: 700,
1238
+ fontSize: 8.5,
1239
+ letterSpacing: "0.3px",
1240
+ color: "#6B7280",
1241
+ borderBottom: "1px solid #E5E7EB"
1242
+ },
1243
+ children: h
1244
+ }, i);
1245
+ })
1246
+ })
1247
+ }), /*#__PURE__*/jsxRuntime.jsx("tbody", {
1248
+ children: rows.map(function (row, ri) {
1249
+ return /*#__PURE__*/jsxRuntime.jsx("tr", {
1250
+ style: {
1251
+ background: ri % 2 === 1 ? "#F9FAFB" : "#fff"
1252
+ },
1253
+ children: row.map(function (cell, ci) {
1254
+ return /*#__PURE__*/jsxRuntime.jsx("td", {
1255
+ style: {
1256
+ padding: "4px 6px",
1257
+ textAlign: ci === 0 ? "left" : "right",
1258
+ color: "#374151",
1259
+ borderBottom: ri < rows.length - 1 ? "1px solid #F3F4F6" : "none"
1260
+ },
1261
+ children: cell
1262
+ }, ci);
1263
+ })
1264
+ }, ri);
1265
+ })
1266
+ })]
1267
+ });
1268
+ };
1269
+ var KpiCard = function KpiCard(_ref7) {
1270
+ var title = _ref7.title,
1271
+ value = _ref7.value,
1272
+ trend = _ref7.trend,
1273
+ detail = _ref7.detail;
1274
+ var neg = "".concat(trend).trim().startsWith("-");
1275
+ return /*#__PURE__*/jsxRuntime.jsxs("div", {
1276
+ style: {
1277
+ border: "1px solid #E5E7EB",
1278
+ borderRadius: 8,
1279
+ padding: "10px 12px 9px",
1280
+ background: "#fff",
1281
+ flex: 1,
1282
+ minWidth: 0,
1283
+ boxSizing: "border-box",
1284
+ display: "flex",
1285
+ flexDirection: "column",
1286
+ gap: 2
1287
+ },
1288
+ children: [/*#__PURE__*/jsxRuntime.jsx("div", {
1289
+ style: {
1290
+ fontSize: 8,
1291
+ fontWeight: 700,
1292
+ letterSpacing: "0.7px",
1293
+ color: "#6B7280",
1294
+ textTransform: "uppercase"
1295
+ },
1296
+ children: title
1297
+ }), /*#__PURE__*/jsxRuntime.jsx("div", {
1298
+ style: {
1299
+ fontSize: 17,
1300
+ fontWeight: 800,
1301
+ color: "#111827",
1302
+ lineHeight: 1.1,
1303
+ marginTop: 2
1304
+ },
1305
+ children: value
1306
+ }), /*#__PURE__*/jsxRuntime.jsx("div", {
1307
+ style: {
1308
+ fontSize: 10.5,
1309
+ fontWeight: 600,
1310
+ color: neg ? "#DC2626" : "#16A34A"
1311
+ },
1312
+ children: trend
1313
+ }), /*#__PURE__*/jsxRuntime.jsx("div", {
1314
+ style: {
1315
+ fontSize: 8.5,
1316
+ color: "#9CA3AF",
1317
+ lineHeight: 1.4
1318
+ },
1319
+ children: detail
1320
+ })]
1321
+ });
1322
+ };
1323
+ var StatPair = function StatPair(_ref8) {
1324
+ var label = _ref8.label,
1325
+ val = _ref8.val,
1326
+ trend = _ref8.trend;
1327
+ var neg = "".concat(trend).trim().startsWith("-");
1328
+ return /*#__PURE__*/jsxRuntime.jsxs("div", {
1329
+ style: {
1330
+ marginBottom: 6
1331
+ },
1332
+ children: [/*#__PURE__*/jsxRuntime.jsx("div", {
1333
+ style: {
1334
+ fontSize: 8.5,
1335
+ color: "#9CA3AF",
1336
+ marginBottom: 1
1337
+ },
1338
+ children: label
1339
+ }), /*#__PURE__*/jsxRuntime.jsxs("div", {
1340
+ style: {
1341
+ display: "flex",
1342
+ alignItems: "baseline",
1343
+ gap: 4
1344
+ },
1345
+ children: [/*#__PURE__*/jsxRuntime.jsx("span", {
1346
+ style: {
1347
+ fontSize: 13,
1348
+ fontWeight: 700,
1349
+ color: "#111827"
1350
+ },
1351
+ children: val
1352
+ }), trend && /*#__PURE__*/jsxRuntime.jsx("span", {
1353
+ style: {
1354
+ fontSize: 9.5,
1355
+ fontWeight: 600,
1356
+ color: neg ? "#DC2626" : "#16A34A"
1357
+ },
1358
+ children: trend
1359
+ })]
1360
+ })]
1361
+ });
1362
+ };
1363
+ var PageHeader = function PageHeader(_ref9) {
1364
+ var dateLabel = _ref9.dateLabel,
1365
+ generatedLabel = _ref9.generatedLabel,
1366
+ activeFilters = _ref9.activeFilters,
1367
+ page = _ref9.page;
1368
+ return /*#__PURE__*/jsxRuntime.jsxs("div", {
1369
+ style: {
1370
+ padding: "22px ".concat(MX, "px 12px"),
1371
+ borderBottom: "1px solid #E5E7EB",
1372
+ flexShrink: 0
1373
+ },
1374
+ children: [/*#__PURE__*/jsxRuntime.jsx("div", {
1375
+ style: {
1376
+ display: "flex",
1377
+ justifyContent: "space-between",
1378
+ alignItems: "center"
1379
+ },
1380
+ children: /*#__PURE__*/jsxRuntime.jsxs("div", {
1381
+ style: {
1382
+ display: "flex",
1383
+ alignItems: "baseline",
1384
+ gap: 10
1385
+ },
1386
+ children: [/*#__PURE__*/jsxRuntime.jsx("span", {
1387
+ style: {
1388
+ fontSize: 20,
1389
+ fontWeight: 800,
1390
+ color: "#111827",
1391
+ letterSpacing: "-0.5px"
1392
+ },
1393
+ children: "Madinah"
1394
+ }), /*#__PURE__*/jsxRuntime.jsx("span", {
1395
+ style: {
1396
+ fontSize: 8.5,
1397
+ fontWeight: 700,
1398
+ letterSpacing: "1.5px",
1399
+ color: "#9CA3AF",
1400
+ textTransform: "uppercase"
1401
+ },
1402
+ children: "PERFORMANCE REPORT"
1403
+ })]
1404
+ })
1405
+ }), /*#__PURE__*/jsxRuntime.jsx("div", {
1406
+ style: {
1407
+ marginTop: 8,
1408
+ fontSize: 13.5,
1409
+ fontWeight: 700,
1410
+ color: "#111827"
1411
+ },
1412
+ children: "Dashboard overview \u2014 Overall"
1413
+ }), /*#__PURE__*/jsxRuntime.jsxs("div", {
1414
+ style: {
1415
+ display: "flex",
1416
+ justifyContent: "space-between",
1417
+ marginTop: 2
1418
+ },
1419
+ children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
1420
+ children: [/*#__PURE__*/jsxRuntime.jsx("div", {
1421
+ style: {
1422
+ fontSize: 10.5,
1423
+ color: "#374151"
1424
+ },
1425
+ children: dateLabel
1426
+ }), /*#__PURE__*/jsxRuntime.jsxs("div", {
1427
+ style: {
1428
+ fontSize: 9.5,
1429
+ color: "#9CA3AF",
1430
+ marginTop: 1
1431
+ },
1432
+ children: ["30-day window \xB7 Generated ", generatedLabel]
1433
+ })]
1434
+ }), /*#__PURE__*/jsxRuntime.jsxs("div", {
1435
+ style: {
1436
+ fontSize: 9,
1437
+ color: "#9CA3AF",
1438
+ textAlign: "right",
1439
+ alignSelf: "flex-end"
1440
+ },
1441
+ children: ["Page ", page, " of 2"]
1442
+ })]
1443
+ }), activeFilters && /*#__PURE__*/jsxRuntime.jsxs("div", {
1444
+ style: {
1445
+ marginTop: 7,
1446
+ display: "inline-flex",
1447
+ gap: 5,
1448
+ background: "#F9FAFB",
1449
+ border: "1px solid #E5E7EB",
1450
+ borderRadius: 4,
1451
+ padding: "3px 9px",
1452
+ fontSize: 8.5
1453
+ },
1454
+ children: [/*#__PURE__*/jsxRuntime.jsx("span", {
1455
+ style: {
1456
+ fontWeight: 700,
1457
+ color: "#374151",
1458
+ letterSpacing: "0.4px"
1459
+ },
1460
+ children: "ACTIVE FILTERS"
1461
+ }), /*#__PURE__*/jsxRuntime.jsx("span", {
1462
+ style: {
1463
+ color: "#6B7280"
1464
+ },
1465
+ children: activeFilters
1466
+ })]
1467
+ })]
1468
+ });
1469
+ };
1470
+ var PageFooter = function PageFooter(_ref0) {
1471
+ var generatedLabel = _ref0.generatedLabel,
1472
+ page = _ref0.page;
1473
+ return /*#__PURE__*/jsxRuntime.jsx("div", {
1474
+ style: {
1475
+ padding: "7px ".concat(MX, "px"),
1476
+ borderTop: "1px solid #E5E7EB",
1477
+ marginTop: "auto",
1478
+ flexShrink: 0
1479
+ },
1480
+ children: /*#__PURE__*/jsxRuntime.jsxs("span", {
1481
+ style: {
1482
+ fontSize: 8,
1483
+ color: "#9CA3AF"
1484
+ },
1485
+ children: ["Confidential \xB7 Generated by Dashboard \xB7 ", generatedLabel, " \xA0\xA0 Page ", page, " of 2 \xB7 madinah.com"]
1486
+ })
1487
+ });
1488
+ };
1489
+
1490
+ // ─── Main component ───────────────────────────────────────────────────────────
1491
+ var ExportPdfLayout = /*#__PURE__*/React.forwardRef(function (_ref1, ref) {
1492
+ var _apiData$overviewStat, _apiData$trafficSourc, _apiData$trafficSourc2, _apiData$overviewStat2, _apiData$roasCard, _ob$peakDay;
1493
+ var _ref1$apiData = _ref1.apiData,
1494
+ apiData = _ref1$apiData === void 0 ? {} : _ref1$apiData,
1495
+ _ref1$dateName = _ref1.dateName,
1496
+ dateName = _ref1$dateName === void 0 ? "Last Period" : _ref1$dateName;
1497
+ var now = new Date();
1498
+ var generatedLabel = now.toLocaleDateString("en-US", {
1499
+ month: "short",
1500
+ day: "numeric",
1501
+ year: "numeric"
1502
+ }) + " · " + now.toLocaleTimeString("en-US", {
1503
+ hour: "2-digit",
1504
+ minute: "2-digit"
1505
+ }) + " GMT";
1506
+ var dateLabel = dateName;
1507
+ var activeFilters = (apiData === null || apiData === void 0 ? void 0 : apiData.activeFilters) || "";
1508
+
1509
+ // ── data ──────────────────────────────────────────────────────────────────
1510
+ var overview = (apiData === null || apiData === void 0 || (_apiData$overviewStat = apiData.overviewStats) === null || _apiData$overviewStat === void 0 ? void 0 : _apiData$overviewStat.overview) || {};
1511
+ var growth = (overview === null || overview === void 0 ? void 0 : overview.growthPercentage) || {};
1512
+ var totalRaised = Number((overview === null || overview === void 0 ? void 0 : overview.totalRevenue) || 0);
1513
+ var netRaised = Number((overview === null || overview === void 0 ? void 0 : overview.netRevenue) || 0);
1514
+ var totalDonors = Number((overview === null || overview === void 0 ? void 0 : overview.totalDonations) || 0);
1515
+ var avgDonation = Number((overview === null || overview === void 0 ? void 0 : overview.overallAVGDonations) || 0);
1516
+ var convRate = Number((overview === null || overview === void 0 ? void 0 : overview.conversionRate) || 0);
1517
+ var totalVisits = Number((apiData === null || apiData === void 0 ? void 0 : apiData.totalVisits) || 0);
1518
+ var passThrough = totalRaised > 0 ? "".concat((netRaised / totalRaised * 100).toFixed(1), "% pass-through") : "–";
1519
+ var refundsRaw = (apiData === null || apiData === void 0 ? void 0 : apiData.refundAndChargeBacks) || {};
1520
+ var refundRate = Number((refundsRaw === null || refundsRaw === void 0 ? void 0 : refundsRaw.refundRate) || 0);
1521
+ var chargebackRate = Number((refundsRaw === null || refundsRaw === void 0 ? void 0 : refundsRaw.chargebackRate) || 0);
1522
+
1523
+ // donor mix
1524
+ var donorMixRaw = apiData === null || apiData === void 0 ? void 0 : apiData.donorPieChartData;
1525
+ var newDonors = 0,
1526
+ returningDonors = 0,
1527
+ mixAvgGift = avgDonation;
1528
+ if (Array.isArray(donorMixRaw)) {
1529
+ var nd = donorMixRaw.find(function (d) {
1530
+ return /new/i.test(d.type);
1531
+ }) || {};
1532
+ var rd = donorMixRaw.find(function (d) {
1533
+ return /returning/i.test(d.type);
1534
+ }) || {};
1535
+ newDonors = nd.totalDonations || 0;
1536
+ returningDonors = rd.totalDonations || 0;
1537
+ var totAmt = (nd.totalAmount || 0) + (rd.totalAmount || 0);
1538
+ var totCnt = newDonors + returningDonors;
1539
+ mixAvgGift = totCnt > 0 ? totAmt / totCnt : avgDonation;
1540
+ } else if (donorMixRaw) {
1541
+ newDonors = donorMixRaw.newDonors || 0;
1542
+ returningDonors = donorMixRaw.returningDonors || 0;
1543
+ mixAvgGift = donorMixRaw.avgGift || avgDonation;
1544
+ }
1545
+ var totalMix = newDonors + returningDonors || 1;
1546
+ var newPct = Math.round(newDonors / totalMix * 100);
1547
+ var retPct = 100 - newPct;
1548
+
1549
+ // recurring / one-time
1550
+ var recData = Array.isArray(apiData === null || apiData === void 0 ? void 0 : apiData.recurringBarChartData) ? apiData.recurringBarChartData : [];
1551
+ var recurringTotal = recData.reduce(function (s, i) {
1552
+ return s + Number(i.recurring || i.recurringAmount || 0);
1553
+ }, 0);
1554
+ var oneTimeTotal = recData.reduce(function (s, i) {
1555
+ return s + Number(i.oneTime || i.oneTimeAmount || 0);
1556
+ }, 0);
1557
+
1558
+ // donor geography
1559
+ var geoRaw = apiData === null || apiData === void 0 ? void 0 : apiData.donorGeography;
1560
+ var geoList = Array.isArray(geoRaw) ? geoRaw : Array.isArray(geoRaw === null || geoRaw === void 0 ? void 0 : geoRaw.data) ? geoRaw.data : [];
1561
+
1562
+ // traffic source
1563
+ var trafficItems = Array.isArray(apiData === null || apiData === void 0 || (_apiData$trafficSourc = apiData.trafficSourceData) === null || _apiData$trafficSourc === void 0 ? void 0 : _apiData$trafficSourc.data) ? apiData.trafficSourceData.data : [];
1564
+ var trafficTotal = Number((apiData === null || apiData === void 0 || (_apiData$trafficSourc2 = apiData.trafficSourceData) === null || _apiData$trafficSourc2 === void 0 ? void 0 : _apiData$trafficSourc2.totalRevenue) || 0);
1565
+
1566
+ // revenue trend series
1567
+ var stackedTR = (apiData === null || apiData === void 0 || (_apiData$overviewStat2 = apiData.overviewStats) === null || _apiData$overviewStat2 === void 0 ? void 0 : _apiData$overviewStat2.totalRaised) || {};
1568
+ var revSeries = [{
1569
+ name: "Email",
1570
+ data: ((stackedTR === null || stackedTR === void 0 ? void 0 : stackedTR.email) || []).map(function (i) {
1571
+ return i.value || 0;
1572
+ })
1573
+ }, {
1574
+ name: "Organic",
1575
+ data: ((stackedTR === null || stackedTR === void 0 ? void 0 : stackedTR.organic) || []).map(function (i) {
1576
+ return i.value || 0;
1577
+ })
1578
+ }, {
1579
+ name: "Paid Ads",
1580
+ data: ((stackedTR === null || stackedTR === void 0 ? void 0 : stackedTR.paidAds) || []).map(function (i) {
1581
+ return i.value || 0;
1582
+ })
1583
+ }].filter(function (s) {
1584
+ return s.data.length > 0;
1585
+ });
1586
+ var revCats = ((stackedTR === null || stackedTR === void 0 ? void 0 : stackedTR.organic) || (stackedTR === null || stackedTR === void 0 ? void 0 : stackedTR.paidAds) || (stackedTR === null || stackedTR === void 0 ? void 0 : stackedTR.email) || []).map(function (i) {
1587
+ return i.date || "";
1588
+ });
1589
+
1590
+ // campaigns
1591
+ var campaigns = (apiData === null || apiData === void 0 ? void 0 : apiData.activeCampaigns) || [];
1592
+
1593
+ // order bump
1594
+ var ob = (apiData === null || apiData === void 0 ? void 0 : apiData.orderBumpDetails) || {};
1595
+ var obData = ((ob === null || ob === void 0 ? void 0 : ob.chart) || []).map(function (i) {
1596
+ return Number(i.revenue || 0);
1597
+ });
1598
+
1599
+ // upsell / downsell
1600
+ var up = (apiData === null || apiData === void 0 ? void 0 : apiData.upSellDetails) || {};
1601
+ var dn = (apiData === null || apiData === void 0 ? void 0 : apiData.downSellDetails) || {};
1602
+
1603
+ // referrals
1604
+ var refCard = (apiData === null || apiData === void 0 ? void 0 : apiData.referralDetails) || {};
1605
+ var refData = ((refCard === null || refCard === void 0 ? void 0 : refCard.chartData) || []).map(function (i) {
1606
+ return Number(i.revenue || 0);
1607
+ });
1608
+ var C = {
1609
+ indigo: "#6366F1",
1610
+ emerald: "#10B981",
1611
+ cyan: "#06B6D4"
1612
+ };
1613
+ var headerProps = {
1614
+ dateLabel: dateLabel,
1615
+ generatedLabel: generatedLabel,
1616
+ activeFilters: activeFilters
1617
+ };
1618
+ return /*#__PURE__*/jsxRuntime.jsxs("div", {
1619
+ ref: ref,
1620
+ style: {
1621
+ display: "inline-flex",
1622
+ flexDirection: "column",
1623
+ gap: 0,
1624
+ background: "#fff"
1625
+ },
1626
+ children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
1627
+ "data-export-page": "1",
1628
+ style: {
1629
+ width: W,
1630
+ height: H,
1631
+ background: "#fff",
1632
+ display: "flex",
1633
+ flexDirection: "column",
1634
+ fontFamily: "'Helvetica Neue', Helvetica, Arial, sans-serif",
1635
+ boxSizing: "border-box",
1636
+ overflow: "hidden"
1637
+ },
1638
+ children: [/*#__PURE__*/jsxRuntime.jsx(PageHeader, _objectSpread2(_objectSpread2({}, headerProps), {}, {
1639
+ page: 1
1640
+ })), /*#__PURE__*/jsxRuntime.jsxs("div", {
1641
+ style: {
1642
+ flex: 1,
1643
+ padding: "12px ".concat(MX, "px 10px"),
1644
+ display: "flex",
1645
+ flexDirection: "column",
1646
+ gap: 10,
1647
+ overflow: "hidden"
1648
+ },
1649
+ children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
1650
+ style: {
1651
+ display: "flex",
1652
+ gap: 7
1653
+ },
1654
+ children: [/*#__PURE__*/jsxRuntime.jsx(KpiCard, {
1655
+ title: "Total Raised",
1656
+ value: d$(totalRaised),
1657
+ trend: "".concat(signed(growth === null || growth === void 0 ? void 0 : growth.totalRevenue), " vs ").concat(dateLabel),
1658
+ detail: "".concat(passThrough, " \xB7 ").concat(formatNumber(totalDonors), " donors \xB7 ").concat(d$(avgDonation), " avg \xB7 ").concat(formatNumber(totalVisits), " visits")
1659
+ }), /*#__PURE__*/jsxRuntime.jsx(KpiCard, {
1660
+ title: "Net Raised",
1661
+ value: d$(netRaised),
1662
+ trend: signed(growth === null || growth === void 0 ? void 0 : growth.netRevenue),
1663
+ detail: passThrough
1664
+ }), /*#__PURE__*/jsxRuntime.jsx(KpiCard, {
1665
+ title: "Total Donors",
1666
+ value: "".concat(formatNumber(totalDonors)),
1667
+ trend: signed(growth === null || growth === void 0 ? void 0 : growth.totalDonations),
1668
+ detail: "".concat(formatNumber(newDonors), " new \xB7 ").concat(formatNumber(returningDonors), " returning")
1669
+ }), /*#__PURE__*/jsxRuntime.jsx(KpiCard, {
1670
+ title: "Avg Donation",
1671
+ value: d$(avgDonation),
1672
+ trend: signed(growth === null || growth === void 0 ? void 0 : growth.overallAVGDonations),
1673
+ detail: "Median ".concat(d$((apiData === null || apiData === void 0 ? void 0 : apiData.medianGift) || 0), " \xB7 top decile ").concat(d$((apiData === null || apiData === void 0 ? void 0 : apiData.topDecileGift) || 0))
1674
+ }), /*#__PURE__*/jsxRuntime.jsx(KpiCard, {
1675
+ title: "ROAS",
1676
+ value: "".concat(formatNumber((_apiData$roasCard = apiData === null || apiData === void 0 ? void 0 : apiData.roasCard) !== null && _apiData$roasCard !== void 0 ? _apiData$roasCard : 0), "\xD7"),
1677
+ trend: signed(apiData === null || apiData === void 0 ? void 0 : apiData.roasCardPrev, "×"),
1678
+ detail: "".concat(d$((apiData === null || apiData === void 0 ? void 0 : apiData.adSpend) || 0), " spend \xB7 ").concat(d$((apiData === null || apiData === void 0 ? void 0 : apiData.attributedRevenue) || 0), " attrib.")
1679
+ }), /*#__PURE__*/jsxRuntime.jsx(KpiCard, {
1680
+ title: "Conversion",
1681
+ value: pct(convRate, 1),
1682
+ trend: "".concat(signed(growth === null || growth === void 0 ? void 0 : growth.conversionRate, "pp")),
1683
+ detail: "".concat(formatNumber(totalDonors), " from ").concat(formatNumber(totalVisits), " visits")
1684
+ }), /*#__PURE__*/jsxRuntime.jsx(KpiCard, {
1685
+ title: "Refund Rate",
1686
+ value: pct(refundRate, 2),
1687
+ trend: "".concat(signed(refundsRaw === null || refundsRaw === void 0 ? void 0 : refundsRaw.refundRateChange, "pp")),
1688
+ detail: "".concat(formatNumber((refundsRaw === null || refundsRaw === void 0 ? void 0 : refundsRaw.refundCount) || 0), " refunds this period")
1689
+ })]
1690
+ }), /*#__PURE__*/jsxRuntime.jsxs("div", {
1691
+ style: {
1692
+ border: "1px solid #E5E7EB",
1693
+ borderRadius: 8,
1694
+ background: "#fff",
1695
+ padding: "12px 14px 10px",
1696
+ flex: 1
1697
+ },
1698
+ children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
1699
+ style: {
1700
+ display: "flex",
1701
+ justifyContent: "space-between",
1702
+ alignItems: "flex-start",
1703
+ marginBottom: 6
1704
+ },
1705
+ children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
1706
+ children: [/*#__PURE__*/jsxRuntime.jsx("div", {
1707
+ style: {
1708
+ fontSize: 13,
1709
+ fontWeight: 700,
1710
+ color: "#111827"
1711
+ },
1712
+ children: "Total revenue trend"
1713
+ }), /*#__PURE__*/jsxRuntime.jsx("div", {
1714
+ style: {
1715
+ fontSize: 9.5,
1716
+ color: "#9CA3AF",
1717
+ marginTop: 1
1718
+ },
1719
+ children: "Last 30 days \xB7 daily aggregation"
1720
+ })]
1721
+ }), /*#__PURE__*/jsxRuntime.jsxs("div", {
1722
+ style: {
1723
+ textAlign: "right"
1724
+ },
1725
+ children: [/*#__PURE__*/jsxRuntime.jsx("span", {
1726
+ style: {
1727
+ fontSize: 15,
1728
+ fontWeight: 800,
1729
+ color: "#111827"
1730
+ },
1731
+ children: d$(totalRaised)
1732
+ }), /*#__PURE__*/jsxRuntime.jsxs("span", {
1733
+ style: {
1734
+ marginLeft: 8,
1735
+ fontSize: 10.5,
1736
+ fontWeight: 600,
1737
+ color: "#16A34A"
1738
+ },
1739
+ children: [signed(growth === null || growth === void 0 ? void 0 : growth.totalRevenue), " vs ", dateLabel]
1740
+ })]
1741
+ })]
1742
+ }), /*#__PURE__*/jsxRuntime.jsx("div", {
1743
+ style: {
1744
+ display: "flex",
1745
+ gap: 14,
1746
+ marginBottom: 6
1747
+ },
1748
+ children: [["Email", C.indigo], ["Organic", C.emerald], ["Paid Ads", C.cyan]].map(function (_ref10) {
1749
+ var _ref11 = _slicedToArray(_ref10, 2),
1750
+ name = _ref11[0],
1751
+ color = _ref11[1];
1752
+ return /*#__PURE__*/jsxRuntime.jsxs("div", {
1753
+ style: {
1754
+ display: "flex",
1755
+ alignItems: "center",
1756
+ gap: 5
1757
+ },
1758
+ children: [/*#__PURE__*/jsxRuntime.jsx("div", {
1759
+ style: {
1760
+ width: 20,
1761
+ height: 2.5,
1762
+ background: color,
1763
+ borderRadius: 2
1764
+ }
1765
+ }), /*#__PURE__*/jsxRuntime.jsx("span", {
1766
+ style: {
1767
+ fontSize: 9.5,
1768
+ color: "#6B7280"
1769
+ },
1770
+ children: name
1771
+ })]
1772
+ }, name);
1773
+ })
1774
+ }), /*#__PURE__*/jsxRuntime.jsx(LineChart, {
1775
+ series: revSeries,
1776
+ categories: revCats,
1777
+ width: CW - 28,
1778
+ height: 480
1779
+ })]
1780
+ })]
1781
+ }), /*#__PURE__*/jsxRuntime.jsx(PageFooter, {
1782
+ generatedLabel: generatedLabel,
1783
+ page: 1
1784
+ })]
1785
+ }), /*#__PURE__*/jsxRuntime.jsxs("div", {
1786
+ "data-export-page": "2",
1787
+ style: {
1788
+ width: W,
1789
+ height: H,
1790
+ background: "#fff",
1791
+ display: "flex",
1792
+ flexDirection: "column",
1793
+ fontFamily: "'Helvetica Neue', Helvetica, Arial, sans-serif",
1794
+ boxSizing: "border-box",
1795
+ overflow: "hidden"
1796
+ },
1797
+ children: [/*#__PURE__*/jsxRuntime.jsx(PageHeader, _objectSpread2(_objectSpread2({}, headerProps), {}, {
1798
+ page: 2
1799
+ })), /*#__PURE__*/jsxRuntime.jsxs("div", {
1800
+ style: {
1801
+ flex: 1,
1802
+ padding: "10px ".concat(MX, "px 8px"),
1803
+ display: "flex",
1804
+ flexDirection: "column",
1805
+ gap: 8,
1806
+ overflow: "hidden"
1807
+ },
1808
+ children: [/*#__PURE__*/jsxRuntime.jsx(Panel, {
1809
+ title: "Active campaigns",
1810
+ subtitle: "Live fundraisers ranked by velocity",
1811
+ action: "View all \u2192",
1812
+ children: /*#__PURE__*/jsxRuntime.jsx(MiniTable, {
1813
+ head: ["CAMPAIGN", "RAISED", "PROGRESS", "DONORS", "AVG GIFT", "STATUS"],
1814
+ rows: campaigns.length ? campaigns.map(function (c) {
1815
+ return [c.title || "Untitled", d$(c.collectedAmount || 0), "".concat(Math.round((c.collectedAmount || 0) / (c.usdTargetAmount || 1) * 100), "%"), "".concat(formatNumber(c.uniqueDonationsCount || 0)), d$(c.avgGift || 0), c.status || "Active"];
1816
+ }) : [["-", "$0", "0%", "0", "$0", "-"]]
1817
+ })
1818
+ }), /*#__PURE__*/jsxRuntime.jsxs("div", {
1819
+ style: {
1820
+ display: "flex",
1821
+ gap: 8,
1822
+ flexShrink: 0
1823
+ },
1824
+ children: [/*#__PURE__*/jsxRuntime.jsx(Panel, {
1825
+ title: "Donor mix",
1826
+ subtitle: "Acquisition vs retention",
1827
+ style: {
1828
+ flex: 1
1829
+ },
1830
+ children: /*#__PURE__*/jsxRuntime.jsxs("div", {
1831
+ style: {
1832
+ display: "flex",
1833
+ alignItems: "center",
1834
+ gap: 14
1835
+ },
1836
+ children: [/*#__PURE__*/jsxRuntime.jsx(Donut, {
1837
+ segments: [{
1838
+ value: newDonors,
1839
+ color: C.indigo
1840
+ }, {
1841
+ value: returningDonors,
1842
+ color: C.emerald
1843
+ }],
1844
+ size: 88,
1845
+ centerVal: "".concat(formatNumber(totalMix)),
1846
+ centerLabel: "donors"
1847
+ }), /*#__PURE__*/jsxRuntime.jsxs("div", {
1848
+ style: {
1849
+ flex: 1
1850
+ },
1851
+ children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
1852
+ style: {
1853
+ display: "flex",
1854
+ alignItems: "center",
1855
+ gap: 6,
1856
+ marginBottom: 5
1857
+ },
1858
+ children: [/*#__PURE__*/jsxRuntime.jsx("div", {
1859
+ style: {
1860
+ width: 9,
1861
+ height: 9,
1862
+ borderRadius: "50%",
1863
+ background: C.indigo,
1864
+ flexShrink: 0
1865
+ }
1866
+ }), /*#__PURE__*/jsxRuntime.jsxs("span", {
1867
+ style: {
1868
+ fontSize: 10,
1869
+ color: "#374151"
1870
+ },
1871
+ children: ["New donors ", formatNumber(newDonors), " \xB7 ", newPct, "%"]
1872
+ })]
1873
+ }), /*#__PURE__*/jsxRuntime.jsxs("div", {
1874
+ style: {
1875
+ display: "flex",
1876
+ alignItems: "center",
1877
+ gap: 6,
1878
+ marginBottom: 9
1879
+ },
1880
+ children: [/*#__PURE__*/jsxRuntime.jsx("div", {
1881
+ style: {
1882
+ width: 9,
1883
+ height: 9,
1884
+ borderRadius: "50%",
1885
+ background: C.emerald,
1886
+ flexShrink: 0
1887
+ }
1888
+ }), /*#__PURE__*/jsxRuntime.jsxs("span", {
1889
+ style: {
1890
+ fontSize: 10,
1891
+ color: "#374151"
1892
+ },
1893
+ children: ["Returning ", formatNumber(returningDonors), " \xB7 ", retPct, "%"]
1894
+ })]
1895
+ }), /*#__PURE__*/jsxRuntime.jsx(Divider, {
1896
+ mb: 7
1897
+ }), /*#__PURE__*/jsxRuntime.jsx("div", {
1898
+ style: {
1899
+ fontSize: 15,
1900
+ fontWeight: 800,
1901
+ color: "#111827"
1902
+ },
1903
+ children: d$(mixAvgGift)
1904
+ }), /*#__PURE__*/jsxRuntime.jsx("div", {
1905
+ style: {
1906
+ fontSize: 8.5,
1907
+ color: "#9CA3AF"
1908
+ },
1909
+ children: "Avg gift"
1910
+ }), /*#__PURE__*/jsxRuntime.jsxs("div", {
1911
+ style: {
1912
+ fontSize: 9,
1913
+ color: "#16A34A",
1914
+ marginTop: 1
1915
+ },
1916
+ children: [signed(growth === null || growth === void 0 ? void 0 : growth.overallAVGDonations), " vs ", dateLabel]
1917
+ })]
1918
+ })]
1919
+ })
1920
+ }), /*#__PURE__*/jsxRuntime.jsx(Panel, {
1921
+ title: "Recurring vs one-time",
1922
+ subtitle: "Donation type \xB7 weekly",
1923
+ style: {
1924
+ flex: 1
1925
+ },
1926
+ children: function () {
1927
+ var tot = recurringTotal + oneTimeTotal || 1;
1928
+ var rPct = recurringTotal / tot * 100;
1929
+ var oPct = oneTimeTotal / tot * 100;
1930
+ return /*#__PURE__*/jsxRuntime.jsxs("div", {
1931
+ style: {
1932
+ display: "flex",
1933
+ flexDirection: "column",
1934
+ gap: 10,
1935
+ marginTop: 4
1936
+ },
1937
+ children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
1938
+ children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
1939
+ style: {
1940
+ display: "flex",
1941
+ justifyContent: "space-between",
1942
+ marginBottom: 3
1943
+ },
1944
+ children: [/*#__PURE__*/jsxRuntime.jsx("span", {
1945
+ style: {
1946
+ fontSize: 10,
1947
+ color: "#374151"
1948
+ },
1949
+ children: "Recurring"
1950
+ }), /*#__PURE__*/jsxRuntime.jsx("span", {
1951
+ style: {
1952
+ fontSize: 10,
1953
+ fontWeight: 700,
1954
+ color: "#111827"
1955
+ },
1956
+ children: d$(recurringTotal)
1957
+ })]
1958
+ }), /*#__PURE__*/jsxRuntime.jsx("div", {
1959
+ style: {
1960
+ height: 10,
1961
+ background: "#EEF2FF",
1962
+ borderRadius: 3
1963
+ },
1964
+ children: /*#__PURE__*/jsxRuntime.jsx("div", {
1965
+ style: {
1966
+ width: "".concat(rPct, "%"),
1967
+ height: "100%",
1968
+ background: C.indigo,
1969
+ borderRadius: 3
1970
+ }
1971
+ })
1972
+ })]
1973
+ }), /*#__PURE__*/jsxRuntime.jsxs("div", {
1974
+ children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
1975
+ style: {
1976
+ display: "flex",
1977
+ justifyContent: "space-between",
1978
+ marginBottom: 3
1979
+ },
1980
+ children: [/*#__PURE__*/jsxRuntime.jsx("span", {
1981
+ style: {
1982
+ fontSize: 10,
1983
+ color: "#374151"
1984
+ },
1985
+ children: "One-time"
1986
+ }), /*#__PURE__*/jsxRuntime.jsx("span", {
1987
+ style: {
1988
+ fontSize: 10,
1989
+ fontWeight: 700,
1990
+ color: "#111827"
1991
+ },
1992
+ children: d$(oneTimeTotal)
1993
+ })]
1994
+ }), /*#__PURE__*/jsxRuntime.jsx("div", {
1995
+ style: {
1996
+ height: 10,
1997
+ background: "#EEF2FF",
1998
+ borderRadius: 3
1999
+ },
2000
+ children: /*#__PURE__*/jsxRuntime.jsx("div", {
2001
+ style: {
2002
+ width: "".concat(oPct, "%"),
2003
+ height: "100%",
2004
+ background: "#C7D2FE",
2005
+ borderRadius: 3
2006
+ }
2007
+ })
2008
+ })]
2009
+ })]
2010
+ });
2011
+ }()
2012
+ })]
2013
+ }), /*#__PURE__*/jsxRuntime.jsxs("div", {
2014
+ style: {
2015
+ display: "flex",
2016
+ gap: 8,
2017
+ flexShrink: 0
2018
+ },
2019
+ children: [/*#__PURE__*/jsxRuntime.jsx(Panel, {
2020
+ title: "Donor geography",
2021
+ subtitle: "Top countries \xB7 ".concat(formatNumber(totalDonors), " total"),
2022
+ style: {
2023
+ flex: 1
2024
+ },
2025
+ children: (geoList.length ? geoList.slice(0, 6) : []).map(function (g, i) {
2026
+ return /*#__PURE__*/jsxRuntime.jsxs("div", {
2027
+ style: {
2028
+ display: "flex",
2029
+ justifyContent: "space-between",
2030
+ padding: "3.5px 0",
2031
+ borderBottom: i < 5 ? "1px solid #F3F4F6" : "none"
2032
+ },
2033
+ children: [/*#__PURE__*/jsxRuntime.jsx("span", {
2034
+ style: {
2035
+ fontSize: 9.5,
2036
+ color: "#374151"
2037
+ },
2038
+ children: g.country || g.name || "-"
2039
+ }), /*#__PURE__*/jsxRuntime.jsxs("span", {
2040
+ style: {
2041
+ fontSize: 9.5,
2042
+ color: "#6B7280"
2043
+ },
2044
+ children: [formatNumber(g.totalDonors || g.donors || 0), " \xB7 ", formatNumber(g.percentage || 0), "%"]
2045
+ })]
2046
+ }, i);
2047
+ })
2048
+ }), /*#__PURE__*/jsxRuntime.jsxs(Panel, {
2049
+ title: "Refunds & chargebacks",
2050
+ subtitle: "Trust health \xB7 30-day window",
2051
+ style: {
2052
+ flex: 1
2053
+ },
2054
+ children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
2055
+ style: {
2056
+ display: "flex",
2057
+ gap: 18,
2058
+ marginBottom: 8
2059
+ },
2060
+ children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
2061
+ children: [/*#__PURE__*/jsxRuntime.jsx("div", {
2062
+ style: {
2063
+ fontSize: 8,
2064
+ fontWeight: 700,
2065
+ letterSpacing: "0.5px",
2066
+ color: "#6B7280",
2067
+ marginBottom: 2
2068
+ },
2069
+ children: "REFUNDS"
2070
+ }), /*#__PURE__*/jsxRuntime.jsx("div", {
2071
+ style: {
2072
+ fontSize: 18,
2073
+ fontWeight: 800,
2074
+ color: "#111827"
2075
+ },
2076
+ children: pct(refundRate, 1)
2077
+ }), /*#__PURE__*/jsxRuntime.jsx("div", {
2078
+ style: {
2079
+ fontSize: 9.5,
2080
+ color: "#16A34A",
2081
+ fontWeight: 600
2082
+ },
2083
+ children: signed(refundsRaw === null || refundsRaw === void 0 ? void 0 : refundsRaw.refundRateChange, "pp")
2084
+ })]
2085
+ }), /*#__PURE__*/jsxRuntime.jsxs("div", {
2086
+ children: [/*#__PURE__*/jsxRuntime.jsx("div", {
2087
+ style: {
2088
+ fontSize: 8,
2089
+ fontWeight: 700,
2090
+ letterSpacing: "0.5px",
2091
+ color: "#6B7280",
2092
+ marginBottom: 2
2093
+ },
2094
+ children: "CHARGEBACKS"
2095
+ }), /*#__PURE__*/jsxRuntime.jsx("div", {
2096
+ style: {
2097
+ fontSize: 18,
2098
+ fontWeight: 800,
2099
+ color: "#111827"
2100
+ },
2101
+ children: pct(chargebackRate, 1)
2102
+ }), /*#__PURE__*/jsxRuntime.jsx("div", {
2103
+ style: {
2104
+ fontSize: 9.5,
2105
+ color: "#9CA3AF"
2106
+ },
2107
+ children: "stable"
2108
+ })]
2109
+ })]
2110
+ }), /*#__PURE__*/jsxRuntime.jsx(Divider, {
2111
+ mb: 6
2112
+ }), /*#__PURE__*/jsxRuntime.jsxs("div", {
2113
+ style: {
2114
+ fontSize: 8.5,
2115
+ color: "#6B7280",
2116
+ lineHeight: 1.5
2117
+ },
2118
+ children: [d$((refundsRaw === null || refundsRaw === void 0 ? void 0 : refundsRaw.refundAmount) || 0), " refunded \xB7 ", d$((refundsRaw === null || refundsRaw === void 0 ? void 0 : refundsRaw.disputedAmount) || 0), " disputed \xB7 ", formatNumber((refundsRaw === null || refundsRaw === void 0 ? void 0 : refundsRaw.casesLost) || 0), " cases lost"]
2119
+ })]
2120
+ }), /*#__PURE__*/jsxRuntime.jsx(Panel, {
2121
+ title: "Traffic source",
2122
+ subtitle: "Revenue by channel \xB7 30 days",
2123
+ style: {
2124
+ flex: 1
2125
+ },
2126
+ children: /*#__PURE__*/jsxRuntime.jsx(MiniTable, {
2127
+ head: ["SOURCE", "REVENUE", "SHARE"],
2128
+ rows: [].concat(_toConsumableArray(trafficItems.map(function (t) {
2129
+ return [t.source || t.name || "-", d$(t.revenue || t.raised || 0), "".concat(formatNumber(t.share || t.percentage || 0), "%")];
2130
+ })), _toConsumableArray(trafficItems.length ? [["Total", d$(trafficTotal), ""]] : []))
2131
+ })
2132
+ }), /*#__PURE__*/jsxRuntime.jsxs(Panel, {
2133
+ title: "Order Bump",
2134
+ subtitle: "Revenue trend \xB7 last 30 days",
2135
+ style: {
2136
+ flex: 1
2137
+ },
2138
+ children: [/*#__PURE__*/jsxRuntime.jsx("div", {
2139
+ style: {
2140
+ fontSize: 17,
2141
+ fontWeight: 800,
2142
+ color: "#111827"
2143
+ },
2144
+ children: d$((ob === null || ob === void 0 ? void 0 : ob.totalRevenue) || 0)
2145
+ }), /*#__PURE__*/jsxRuntime.jsxs("div", {
2146
+ style: {
2147
+ fontSize: 10,
2148
+ color: "#16A34A",
2149
+ fontWeight: 600,
2150
+ marginBottom: 5
2151
+ },
2152
+ children: [signed(ob === null || ob === void 0 ? void 0 : ob.growthPercentage), " vs ", dateLabel]
2153
+ }), /*#__PURE__*/jsxRuntime.jsx(Sparkline, {
2154
+ data: obData.length ? obData : [0, 1],
2155
+ color: C.indigo,
2156
+ width: 110,
2157
+ height: 34
2158
+ }), /*#__PURE__*/jsxRuntime.jsx(Divider, {
2159
+ mt: 8,
2160
+ mb: 7
2161
+ }), /*#__PURE__*/jsxRuntime.jsx("div", {
2162
+ style: {
2163
+ display: "flex",
2164
+ gap: 12
2165
+ },
2166
+ children: [["Avg/day", d$((ob === null || ob === void 0 ? void 0 : ob.averagePerDay) || 0)], ["Peak day", d$((ob === null || ob === void 0 || (_ob$peakDay = ob.peakDay) === null || _ob$peakDay === void 0 ? void 0 : _ob$peakDay.amount) || 0)], ["Orders", formatNumber((ob === null || ob === void 0 ? void 0 : ob.totalOrders) || 0)]].map(function (_ref12) {
2167
+ var _ref13 = _slicedToArray(_ref12, 2),
2168
+ l = _ref13[0],
2169
+ v = _ref13[1];
2170
+ return /*#__PURE__*/jsxRuntime.jsxs("div", {
2171
+ children: [/*#__PURE__*/jsxRuntime.jsx("div", {
2172
+ style: {
2173
+ fontSize: 8,
2174
+ color: "#9CA3AF"
2175
+ },
2176
+ children: l
2177
+ }), /*#__PURE__*/jsxRuntime.jsx("div", {
2178
+ style: {
2179
+ fontSize: 11.5,
2180
+ fontWeight: 700,
2181
+ color: "#111827"
2182
+ },
2183
+ children: v
2184
+ })]
2185
+ }, l);
2186
+ })
2187
+ })]
2188
+ })]
2189
+ }), /*#__PURE__*/jsxRuntime.jsxs("div", {
2190
+ style: {
2191
+ display: "flex",
2192
+ gap: 8,
2193
+ flexShrink: 0
2194
+ },
2195
+ children: [/*#__PURE__*/jsxRuntime.jsx(Panel, {
2196
+ title: "Upsell",
2197
+ subtitle: "Acceptance & raised",
2198
+ style: {
2199
+ flex: 1
2200
+ },
2201
+ children: /*#__PURE__*/jsxRuntime.jsxs("div", {
2202
+ style: {
2203
+ display: "flex",
2204
+ alignItems: "center",
2205
+ gap: 12
2206
+ },
2207
+ children: [/*#__PURE__*/jsxRuntime.jsx(Donut, {
2208
+ segments: [{
2209
+ value: (up === null || up === void 0 ? void 0 : up.acceptanceRate) || 0,
2210
+ color: C.indigo
2211
+ }, {
2212
+ value: Math.max(0, 100 - ((up === null || up === void 0 ? void 0 : up.acceptanceRate) || 0)),
2213
+ color: "#E5E7EB"
2214
+ }],
2215
+ size: 76,
2216
+ centerVal: "".concat(formatNumber((up === null || up === void 0 ? void 0 : up.acceptanceRate) || 0), "%"),
2217
+ centerLabel: "accepted"
2218
+ }), /*#__PURE__*/jsxRuntime.jsxs("div", {
2219
+ style: {
2220
+ flex: 1
2221
+ },
2222
+ children: [/*#__PURE__*/jsxRuntime.jsx(StatPair, {
2223
+ label: "Acceptance",
2224
+ val: pct((up === null || up === void 0 ? void 0 : up.acceptanceRate) || 0, 1),
2225
+ trend: signed(up === null || up === void 0 ? void 0 : up.acceptanceGrowth)
2226
+ }), /*#__PURE__*/jsxRuntime.jsx(StatPair, {
2227
+ label: "Raised",
2228
+ val: d$((up === null || up === void 0 ? void 0 : up.raised) || 0),
2229
+ trend: signed(up === null || up === void 0 ? void 0 : up.raisedGrowth)
2230
+ })]
2231
+ })]
2232
+ })
2233
+ }), /*#__PURE__*/jsxRuntime.jsx(Panel, {
2234
+ title: "Downsell",
2235
+ subtitle: "Acceptance & raised",
2236
+ style: {
2237
+ flex: 1
2238
+ },
2239
+ children: /*#__PURE__*/jsxRuntime.jsxs("div", {
2240
+ style: {
2241
+ display: "flex",
2242
+ alignItems: "center",
2243
+ gap: 12
2244
+ },
2245
+ children: [/*#__PURE__*/jsxRuntime.jsx(Donut, {
2246
+ segments: [{
2247
+ value: (dn === null || dn === void 0 ? void 0 : dn.acceptanceRate) || 0,
2248
+ color: C.cyan
2249
+ }, {
2250
+ value: Math.max(0, 100 - ((dn === null || dn === void 0 ? void 0 : dn.acceptanceRate) || 0)),
2251
+ color: "#E5E7EB"
2252
+ }],
2253
+ size: 76,
2254
+ centerVal: "".concat(formatNumber((dn === null || dn === void 0 ? void 0 : dn.acceptanceRate) || 0), "%"),
2255
+ centerLabel: "accepted"
2256
+ }), /*#__PURE__*/jsxRuntime.jsxs("div", {
2257
+ style: {
2258
+ flex: 1
2259
+ },
2260
+ children: [/*#__PURE__*/jsxRuntime.jsx(StatPair, {
2261
+ label: "Acceptance",
2262
+ val: pct((dn === null || dn === void 0 ? void 0 : dn.acceptanceRate) || 0, 1),
2263
+ trend: signed(dn === null || dn === void 0 ? void 0 : dn.acceptanceGrowth)
2264
+ }), /*#__PURE__*/jsxRuntime.jsx(StatPair, {
2265
+ label: "Raised",
2266
+ val: d$((dn === null || dn === void 0 ? void 0 : dn.raised) || 0),
2267
+ trend: signed(dn === null || dn === void 0 ? void 0 : dn.raisedGrowth)
2268
+ })]
2269
+ })]
2270
+ })
2271
+ }), /*#__PURE__*/jsxRuntime.jsxs(Panel, {
2272
+ title: "Referrals",
2273
+ subtitle: "Revenue trend \xB7 last 30 days",
2274
+ style: {
2275
+ flex: 1
2276
+ },
2277
+ children: [/*#__PURE__*/jsxRuntime.jsx("div", {
2278
+ style: {
2279
+ fontSize: 17,
2280
+ fontWeight: 800,
2281
+ color: "#111827"
2282
+ },
2283
+ children: d$((refCard === null || refCard === void 0 ? void 0 : refCard.totalRevenue) || 0)
2284
+ }), /*#__PURE__*/jsxRuntime.jsxs("div", {
2285
+ style: {
2286
+ fontSize: 10,
2287
+ color: "#16A34A",
2288
+ fontWeight: 600,
2289
+ marginBottom: 5
2290
+ },
2291
+ children: [signed(refCard === null || refCard === void 0 ? void 0 : refCard.growthPercentage), " vs ", dateLabel]
2292
+ }), /*#__PURE__*/jsxRuntime.jsx(Sparkline, {
2293
+ data: refData.length ? refData : [0, 1],
2294
+ color: C.emerald,
2295
+ width: 110,
2296
+ height: 34
2297
+ }), /*#__PURE__*/jsxRuntime.jsx(Divider, {
2298
+ mt: 8,
2299
+ mb: 7
2300
+ }), /*#__PURE__*/jsxRuntime.jsx("div", {
2301
+ style: {
2302
+ display: "flex",
2303
+ gap: 12
2304
+ },
2305
+ children: [["Referrers", formatNumber((refCard === null || refCard === void 0 ? void 0 : refCard.totalReferrers) || 0)], ["Avg gift", d$((refCard === null || refCard === void 0 ? void 0 : refCard.averageGift) || 0)], ["Conv. rate", pct((refCard === null || refCard === void 0 ? void 0 : refCard.conversionRate) || 0, 1)]].map(function (_ref14) {
2306
+ var _ref15 = _slicedToArray(_ref14, 2),
2307
+ l = _ref15[0],
2308
+ v = _ref15[1];
2309
+ return /*#__PURE__*/jsxRuntime.jsxs("div", {
2310
+ children: [/*#__PURE__*/jsxRuntime.jsx("div", {
2311
+ style: {
2312
+ fontSize: 8,
2313
+ color: "#9CA3AF"
2314
+ },
2315
+ children: l
2316
+ }), /*#__PURE__*/jsxRuntime.jsx("div", {
2317
+ style: {
2318
+ fontSize: 11.5,
2319
+ fontWeight: 700,
2320
+ color: "#111827"
2321
+ },
2322
+ children: v
2323
+ })]
2324
+ }, l);
2325
+ })
2326
+ })]
2327
+ })]
2328
+ })]
2329
+ }), /*#__PURE__*/jsxRuntime.jsx(PageFooter, {
2330
+ generatedLabel: generatedLabel,
2331
+ page: 2
2332
+ })]
2333
+ })]
2334
+ });
2335
+ });
2336
+ ExportPdfLayout.displayName = "ExportPdfLayout";
2337
+
890
2338
  var OverallSection$2 = /*#__PURE__*/React.lazy(function () {
891
2339
  return Promise.resolve().then(function () { return OverallSection$1; });
892
2340
  });
@@ -919,139 +2367,96 @@ var NewOverview = function NewOverview(_ref) {
919
2367
  _useState4 = _slicedToArray(_useState3, 2),
920
2368
  activeSection = _useState4[0],
921
2369
  setActiveSection = _useState4[1];
922
- var exportCaptureRef = React.useRef(null);
2370
+ var _useState5 = React.useState(false),
2371
+ _useState6 = _slicedToArray(_useState5, 2),
2372
+ showExportLayout = _useState6[0],
2373
+ setShowExportLayout = _useState6[1];
2374
+ var exportLayoutRef = React.useRef(null);
923
2375
  React.useEffect(function () {
924
2376
  if (activeSectionProp) {
925
2377
  var capitalized = activeSectionProp.charAt(0).toUpperCase() + activeSectionProp.slice(1).toLowerCase();
926
2378
  setActiveSection(capitalized);
927
2379
  }
928
2380
  }, [activeSectionProp]);
2381
+
2382
+ // Step 1 – mount the off-screen export layout whenever the trigger fires
929
2383
  React.useEffect(function () {
930
- if (exportTrigger <= 0) return;
931
- var buildAndDownloadPdf = /*#__PURE__*/function () {
2384
+ if (exportTrigger > 0) setShowExportLayout(true);
2385
+ }, [exportTrigger]);
2386
+
2387
+ // Step 2 – once the layout is in the DOM, capture each page and build the PDF
2388
+ React.useEffect(function () {
2389
+ if (!showExportLayout) return;
2390
+ var doPdfExport = /*#__PURE__*/function () {
932
2391
  var _ref2 = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee() {
933
- var captureNode, _yield$Promise$all, _yield$Promise$all2, jsPDF, html2canvasModule, html2canvas, dateLabel, generatedAt, generatedLabel, canvas, sectionImageWidth, sectionImageHeight, doc, pageWidth, pageHeight, marginX, contentTop, contentBottom, contentWidth, contentHeight, pxPerPt, pageSliceHeightPx, totalPages, addHeader, addFooter, i, startY, sliceHeight, pageCanvas, pageCtx, pageImage, renderHeight, safeDate, _t;
2392
+ var container, pageEls, _yield$Promise$all, _yield$Promise$all2, jsPDF, html2canvasModule, html2canvas, doc, pdfW, pdfH, i, el, cvs, safeDate, _t;
934
2393
  return _regenerator().w(function (_context) {
935
2394
  while (1) switch (_context.p = _context.n) {
936
2395
  case 0:
937
2396
  _context.p = 0;
938
- if (!(activeSection !== "Overall")) {
939
- _context.n = 1;
2397
+ _context.n = 1;
2398
+ return new Promise(function (r) {
2399
+ return requestAnimationFrame(function () {
2400
+ return requestAnimationFrame(r);
2401
+ });
2402
+ });
2403
+ case 1:
2404
+ _context.n = 2;
2405
+ return new Promise(function (r) {
2406
+ return setTimeout(r, 400);
2407
+ });
2408
+ case 2:
2409
+ container = exportLayoutRef.current;
2410
+ if (container) {
2411
+ _context.n = 3;
940
2412
  break;
941
2413
  }
942
2414
  return _context.a(2);
943
- case 1:
944
- captureNode = exportCaptureRef.current;
945
- if (captureNode) {
946
- _context.n = 2;
2415
+ case 3:
2416
+ pageEls = container.querySelectorAll("[data-export-page]");
2417
+ if (pageEls.length) {
2418
+ _context.n = 4;
947
2419
  break;
948
2420
  }
949
2421
  return _context.a(2);
950
- case 2:
951
- _context.n = 3;
2422
+ case 4:
2423
+ _context.n = 5;
952
2424
  return Promise.all([import('jspdf'), Promise.resolve().then(function () { return html2canvas_esm; })]);
953
- case 3:
2425
+ case 5:
954
2426
  _yield$Promise$all = _context.v;
955
2427
  _yield$Promise$all2 = _slicedToArray(_yield$Promise$all, 2);
956
2428
  jsPDF = _yield$Promise$all2[0].jsPDF;
957
2429
  html2canvasModule = _yield$Promise$all2[1];
958
2430
  html2canvas = html2canvasModule["default"] || html2canvasModule;
959
- dateLabel = dateName || "Last Period";
960
- generatedAt = new Date();
961
- generatedLabel = "".concat(generatedAt.toLocaleDateString(), " ").concat(generatedAt.toLocaleTimeString(), " GMT");
962
- _context.n = 4;
963
- return new Promise(function (resolve) {
964
- return setTimeout(resolve, 900);
965
- });
966
- case 4:
967
- _context.n = 5;
968
- return html2canvas(captureNode, {
969
- scale: 2,
970
- useCORS: true,
971
- backgroundColor: "#ffffff",
972
- width: captureNode.scrollWidth,
973
- height: captureNode.scrollHeight,
974
- windowWidth: captureNode.scrollWidth,
975
- windowHeight: captureNode.scrollHeight,
976
- scrollX: 0,
977
- scrollY: -window.scrollY
978
- });
979
- case 5:
980
- canvas = _context.v;
981
- sectionImageWidth = canvas.width;
982
- sectionImageHeight = canvas.height;
983
2431
  doc = new jsPDF({
984
2432
  unit: "pt",
985
2433
  format: "a4"
986
2434
  });
987
- pageWidth = doc.internal.pageSize.getWidth();
988
- pageHeight = doc.internal.pageSize.getHeight();
989
- marginX = 40;
990
- contentTop = 112;
991
- contentBottom = 40;
992
- contentWidth = pageWidth - marginX * 2;
993
- contentHeight = pageHeight - contentTop - contentBottom;
994
- pxPerPt = sectionImageWidth / contentWidth;
995
- pageSliceHeightPx = Math.max(1, Math.floor(contentHeight * pxPerPt));
996
- totalPages = Math.max(1, Math.ceil(sectionImageHeight / pageSliceHeightPx));
997
- addHeader = function addHeader() {
998
- doc.setFont("helvetica", "bold");
999
- doc.setTextColor(17, 24, 39);
1000
- doc.setFontSize(17);
1001
- doc.text("Madinah", marginX, 34);
1002
- doc.setFontSize(9.5);
1003
- doc.setTextColor(75, 85, 99);
1004
- doc.text("PERFORMANCE REPORT", marginX, 50);
1005
- doc.setTextColor(17, 24, 39);
1006
- doc.setFontSize(12);
1007
- doc.text("Dashboard overview — Overall", marginX, 72);
1008
- doc.setFont("helvetica", "normal");
1009
- doc.setFontSize(9);
1010
- doc.setTextColor(107, 114, 128);
1011
- doc.text("".concat(dateLabel), marginX, 88);
1012
- doc.text("30-day window \xB7 Generated ".concat(generatedLabel), marginX, 100);
1013
- var activeFilters = (apiData === null || apiData === void 0 ? void 0 : apiData.activeFilters) || "";
1014
- if (activeFilters) {
1015
- doc.setFontSize(8);
1016
- doc.setTextColor(55, 65, 81);
1017
- doc.text("ACTIVE FILTERS ".concat(activeFilters), marginX, 110);
1018
- }
1019
- };
1020
- addFooter = function addFooter(pageNumber, totalPages) {
1021
- doc.setFont("helvetica", "normal");
1022
- doc.setTextColor(107, 114, 128);
1023
- doc.setFontSize(8);
1024
- doc.text("Confidential \xB7 Generated by Dashboard \xB7 ".concat(generatedLabel, " \xB7 Page ").concat(pageNumber, " of ").concat(totalPages, " \xB7 madinah.com"), marginX, pageHeight - 18);
1025
- };
2435
+ pdfW = doc.internal.pageSize.getWidth();
2436
+ pdfH = doc.internal.pageSize.getHeight();
1026
2437
  i = 0;
1027
2438
  case 6:
1028
- if (!(i < totalPages)) {
2439
+ if (!(i < pageEls.length)) {
1029
2440
  _context.n = 9;
1030
2441
  break;
1031
2442
  }
1032
- if (i > 0) doc.addPage();
1033
- addHeader();
1034
- startY = i * pageSliceHeightPx;
1035
- sliceHeight = Math.min(pageSliceHeightPx, sectionImageHeight - startY);
1036
- pageCanvas = document.createElement("canvas");
1037
- pageCanvas.width = sectionImageWidth;
1038
- pageCanvas.height = sliceHeight;
1039
- pageCtx = pageCanvas.getContext("2d");
1040
- if (pageCtx) {
1041
- _context.n = 7;
1042
- break;
1043
- }
1044
- return _context.a(3, 8);
2443
+ el = pageEls[i];
2444
+ _context.n = 7;
2445
+ return html2canvas(el, {
2446
+ scale: 2,
2447
+ useCORS: true,
2448
+ backgroundColor: "#ffffff",
2449
+ width: el.offsetWidth,
2450
+ height: el.offsetHeight,
2451
+ windowWidth: el.offsetWidth,
2452
+ windowHeight: el.offsetHeight
2453
+ });
1045
2454
  case 7:
1046
- pageCtx.fillStyle = "#ffffff";
1047
- pageCtx.fillRect(0, 0, pageCanvas.width, pageCanvas.height);
1048
- pageCtx.drawImage(canvas, 0, startY, sectionImageWidth, sliceHeight, 0, 0, sectionImageWidth, sliceHeight);
1049
- pageImage = pageCanvas.toDataURL("image/png");
1050
- renderHeight = sliceHeight / pxPerPt;
1051
- doc.addImage(pageImage, "PNG", marginX, contentTop, contentWidth, renderHeight, undefined, "FAST");
1052
- addFooter(i + 1, totalPages);
2455
+ cvs = _context.v;
2456
+ if (i > 0) doc.addPage();
2457
+ doc.addImage(cvs.toDataURL("image/png"), "PNG", 0, 0, pdfW, pdfH, undefined, "FAST");
1053
2458
  case 8:
1054
- i += 1;
2459
+ i++;
1055
2460
  _context.n = 6;
1056
2461
  break;
1057
2462
  case 9:
@@ -1062,19 +2467,22 @@ var NewOverview = function NewOverview(_ref) {
1062
2467
  case 10:
1063
2468
  _context.p = 10;
1064
2469
  _t = _context.v;
1065
- // Keep console message for host app debugging when export dependency is missing.
1066
2470
  console.error("Failed to export overall dashboard PDF:", _t);
1067
2471
  case 11:
2472
+ _context.p = 11;
2473
+ setShowExportLayout(false);
2474
+ return _context.f(11);
2475
+ case 12:
1068
2476
  return _context.a(2);
1069
2477
  }
1070
- }, _callee, null, [[0, 10]]);
2478
+ }, _callee, null, [[0, 10, 11, 12]]);
1071
2479
  }));
1072
- return function buildAndDownloadPdf() {
2480
+ return function doPdfExport() {
1073
2481
  return _ref2.apply(this, arguments);
1074
2482
  };
1075
2483
  }();
1076
- buildAndDownloadPdf();
1077
- }, [exportTrigger, activeSection, apiData, dateName]);
2484
+ doPdfExport();
2485
+ }, [showExportLayout]);
1078
2486
  var currentData = metric === "Revenue" ? revenueData : donationsData;
1079
2487
  var oneTimeData = (apiData === null || apiData === void 0 ? void 0 : apiData.oneTimeDonations) || [];
1080
2488
  var oneTimeValues = oneTimeData.length > 0 ? oneTimeData.map(function (item) {
@@ -1234,15 +2642,14 @@ var NewOverview = function NewOverview(_ref) {
1234
2642
  data: [8, 9, 11, 10, 10, 12, 9, 11, 10],
1235
2643
  categories: categories
1236
2644
  }];
1237
- return /*#__PURE__*/jsxRuntime.jsx(material.Box, {
1238
- ref: exportCaptureRef,
2645
+ return /*#__PURE__*/jsxRuntime.jsxs(material.Box, {
1239
2646
  sx: {
1240
2647
  minHeight: "100vh",
1241
2648
  display: "flex",
1242
2649
  flexDirection: "column",
1243
2650
  alignItems: "stretch"
1244
2651
  },
1245
- children: /*#__PURE__*/jsxRuntime.jsxs(React.Suspense, {
2652
+ children: [/*#__PURE__*/jsxRuntime.jsxs(React.Suspense, {
1246
2653
  fallback: /*#__PURE__*/jsxRuntime.jsx(material.Box, {
1247
2654
  sx: {
1248
2655
  display: "flex",
@@ -1272,7 +2679,22 @@ var NewOverview = function NewOverview(_ref) {
1272
2679
  sx: {},
1273
2680
  children: /*#__PURE__*/jsxRuntime.jsx(EmailSection$2, {})
1274
2681
  })]
1275
- })
2682
+ }), showExportLayout && /*#__PURE__*/jsxRuntime.jsx("div", {
2683
+ "aria-hidden": "true",
2684
+ style: {
2685
+ position: "fixed",
2686
+ top: 0,
2687
+ left: "-9999px",
2688
+ zIndex: -1,
2689
+ pointerEvents: "none",
2690
+ opacity: 1
2691
+ },
2692
+ children: /*#__PURE__*/jsxRuntime.jsx(ExportPdfLayout, {
2693
+ ref: exportLayoutRef,
2694
+ apiData: apiData,
2695
+ dateName: dateName
2696
+ })
2697
+ })]
1276
2698
  });
1277
2699
  };
1278
2700
 
@@ -3313,19 +4735,6 @@ var DonorMixCard = function DonorMixCard(_ref) {
3313
4735
  });
3314
4736
  };
3315
4737
 
3316
- function formatNumber(num) {
3317
- if (num >= 1000000000) {
3318
- return (num / 1000000000).toFixed(1).replace(/\.0$/, "") + "B";
3319
- }
3320
- if (num >= 1000000) {
3321
- return (num / 1000000).toFixed(1).replace(/\.0$/, "") + "M";
3322
- }
3323
- if (num >= 1000) {
3324
- return (num / 1000).toFixed(1).replace(/\.0$/, "") + "K";
3325
- }
3326
- return (num !== null && num !== void 0 ? num : 0).toString();
3327
- }
3328
-
3329
4738
  var TrafficSourceCard = function TrafficSourceCard(_ref) {
3330
4739
  var _ref$title = _ref.title,
3331
4740
  title = _ref$title === void 0 ? "Traffic source" : _ref$title,