@ammarkhalidfarooq/dashboard-package 0.5.16 → 0.5.18

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