@threatcaptain/tc-reports 0.2.18 → 0.2.20

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 CHANGED
@@ -28765,24 +28765,24 @@ const Dashboard = ({
28765
28765
  };
28766
28766
  const getExecutiveSummaryTemplate = (industry) => {
28767
28767
  switch (industry) {
28768
- case "Healthcare":
28768
+ case "healthcare":
28769
28769
  return "Think of this like a malpractice insurance evaluation for your medical practice. Just as you wouldn't practice without malpractice coverage, you can't afford to practice without understanding your cyber risk exposure. One successful cyberattack could cost your practice more than your highest malpractice settlement.";
28770
- case "Legal":
28770
+ case "legal_services":
28771
28771
  return "Think of this like a malpractice insurance evaluation for your law firm. Just as you wouldn't practice without malpractice coverage, you can't afford to practice without understanding your cyber risk exposure. One successful cyberattack could cost your firm more than your highest case settlement.";
28772
- case "Financial Services":
28772
+ case "financial_services":
28773
28773
  return "Think of this like a regulatory compliance audit for your financial institution. Just as you wouldn't operate without proper compliance, you can't afford to operate without understanding your cyber risk exposure. One successful cyberattack could cost your institution more than your largest loan default.";
28774
- case "Education":
28774
+ case "education":
28775
28775
  return "Think of this like an accreditation review for your educational institution. Just as you wouldn't operate without proper accreditation, you can't afford to operate without understanding your cyber risk exposure. One successful cyberattack could cost your institution more than losing a major grant.";
28776
- case "Manufacturing":
28776
+ case "manufacturing":
28777
28777
  return "Think of this like a safety inspection for your manufacturing facility. Just as you wouldn't operate without proper safety protocols, you can't afford to operate without understanding your cyber risk exposure. One successful cyberattack could cost your facility more than your largest equipment failure.";
28778
- case "Retail":
28778
+ case "retail_consumer_goods":
28779
28779
  return "Think of this like a loss prevention audit for your retail business. Just as you wouldn't operate without proper inventory controls, you can't afford to operate without understanding your cyber risk exposure. One successful cyberattack could cost your business more than your highest shrinkage loss.";
28780
28780
  case "technology_software":
28781
28781
  return "Think of this like a code review for your software platform. Just as you wouldn't deploy without proper testing, you can't afford to operate without understanding your cyber risk exposure. One successful cyberattack could cost your company more than your largest system outage.";
28782
- case "Government":
28782
+ case 'government_public_sector"':
28783
28783
  return "Think of this like a security clearance review for your agency. Just as you wouldn't operate without proper clearances, you can't afford to operate without understanding your cyber risk exposure. One successful cyberattack could cost your agency more than your largest budget overrun.";
28784
28784
  default:
28785
- return "This cybersecurity financial impact analysis estimates the potential cost of a data breach for the client, using trusted, industry-standard data. Backed by sources like IBM Security and the Ponemon Institute, it provides a credible view of the financial risks organizations like yours face in today's threat landscape. Alongside relevant industry insights, this report outlines actionable considerations to support the client's cybersecurity planning, risk management, and executive decision-making—even ahead of a detailed security assessment.";
28785
+ return "Backed by sources like IBM Security and the Ponemon Institute, this analysis provides a credible view of the risks organizations like yours face in today's threat landscape. Alongside relevant industry insights, this report outlines actionable considerations to support the client's cybersecurity planning, risk management, and executive decision-making—even ahead of a detailed security assessment.";
28786
28786
  }
28787
28787
  };
28788
28788
  const formatCurrency = (value) => {
@@ -51214,7 +51214,7 @@ const getRadarData = ({ breachData }) => {
51214
51214
  }).map((phase) => {
51215
51215
  const visualCoverage = phase.coverage === 0 ? 2 : phase.coverage;
51216
51216
  return {
51217
- tactic: phase.phase.replace("TA00", "").replace("_", " ").substring(0, 8),
51217
+ tactic: phase.phase.replace("TA00", "").replace("_", " "),
51218
51218
  coverage: visualCoverage,
51219
51219
  // Use for chart rendering
51220
51220
  actualCoverage: phase.coverage,
@@ -51257,92 +51257,166 @@ const MitreAttack = ({ breachData, overallLikelihood }) => {
51257
51257
  return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
51258
51258
  /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-lg font-semibold text-gray-900", children: "MITRE ATT&CK Coverage" }),
51259
51259
  /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-gray-600", children: "14 Tactics Protection Level" }),
51260
- /* @__PURE__ */ jsxRuntime.jsx(ChartContainer, { config: chartConfig, className: "h-72 w-72", children: /* @__PURE__ */ jsxRuntime.jsxs(
51261
- RadarChart,
51260
+ /* @__PURE__ */ jsxRuntime.jsx(
51261
+ ChartContainer,
51262
51262
  {
51263
- data: radarData,
51264
- margin: { top: 20, right: 20, bottom: 20, left: 20 },
51265
- children: [
51266
- /* @__PURE__ */ jsxRuntime.jsx("defs", { children: /* @__PURE__ */ jsxRuntime.jsxs("radialGradient", { id: gradientId, cx: "50%", cy: "50%", r: "50%", children: [
51267
- /* @__PURE__ */ jsxRuntime.jsx("stop", { offset: "0%", stopColor: strokeColor, stopOpacity: 0.4 }),
51268
- /* @__PURE__ */ jsxRuntime.jsx("stop", { offset: "70%", stopColor: strokeColor, stopOpacity: 0.2 }),
51269
- /* @__PURE__ */ jsxRuntime.jsx("stop", { offset: "100%", stopColor: strokeColor, stopOpacity: 0.1 })
51270
- ] }) }),
51271
- /* @__PURE__ */ jsxRuntime.jsx(PolarGrid, { stroke: "#e5e5e5", strokeWidth: 1, radialLines: true }),
51272
- /* @__PURE__ */ jsxRuntime.jsx(
51273
- PolarAngleAxis,
51274
- {
51275
- dataKey: "tactic",
51276
- tick: { fontSize: 10, fill: "#6b7280" },
51277
- className: "text-xs"
51278
- }
51279
- ),
51280
- /* @__PURE__ */ jsxRuntime.jsx(
51281
- PolarRadiusAxis,
51282
- {
51283
- angle: 90,
51284
- domain: [0, 100],
51285
- tick: { fontSize: 8, fill: "#6b7280" },
51286
- tickCount: 6,
51287
- axisLine: false
51288
- }
51289
- ),
51290
- /* @__PURE__ */ jsxRuntime.jsx(
51291
- Radar,
51292
- {
51293
- name: "Coverage",
51294
- dataKey: "coverage",
51295
- stroke: strokeColor,
51296
- fill: `url(#${gradientId})`,
51297
- strokeWidth: 2.5,
51298
- dot: {
51299
- r: 4,
51300
- fill: strokeColor,
51301
- strokeWidth: 2,
51302
- stroke: "#ffffff"
51303
- },
51304
- activeDot: {
51305
- r: 6,
51306
- fill: strokeColor,
51307
- strokeWidth: 2,
51308
- stroke: "#ffffff"
51309
- }
51310
- }
51311
- ),
51312
- /* @__PURE__ */ jsxRuntime.jsx(
51313
- ChartTooltip,
51314
- {
51315
- content: ({ active, payload }) => {
51316
- if (active && payload && payload.length) {
51317
- const data = payload[0].payload;
51318
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-white p-3 border rounded-lg shadow-lg", children: [
51319
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "font-semibold text-gray-900", children: data.fullName }),
51320
- /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-sm text-gray-600", children: [
51321
- "Coverage: ",
51322
- data.actualCoverage,
51323
- "%"
51324
- ] }),
51325
- /* @__PURE__ */ jsxRuntime.jsxs(
51326
- "p",
51263
+ config: chartConfig,
51264
+ className: "h-[420px] w-[420px] min-h-[420px] min-w-[420px] mb-0",
51265
+ children: /* @__PURE__ */ jsxRuntime.jsxs(
51266
+ RadarChart,
51267
+ {
51268
+ data: radarData,
51269
+ margin: { top: 50, right: 80, bottom: 50, left: 80 },
51270
+ children: [
51271
+ /* @__PURE__ */ jsxRuntime.jsx("defs", { children: /* @__PURE__ */ jsxRuntime.jsxs("radialGradient", { id: gradientId, cx: "50%", cy: "50%", r: "50%", children: [
51272
+ /* @__PURE__ */ jsxRuntime.jsx("stop", { offset: "0%", stopColor: strokeColor, stopOpacity: 0.4 }),
51273
+ /* @__PURE__ */ jsxRuntime.jsx("stop", { offset: "70%", stopColor: strokeColor, stopOpacity: 0.2 }),
51274
+ /* @__PURE__ */ jsxRuntime.jsx("stop", { offset: "100%", stopColor: strokeColor, stopOpacity: 0.1 })
51275
+ ] }) }),
51276
+ /* @__PURE__ */ jsxRuntime.jsx(PolarGrid, { stroke: "#e5e5e5", strokeWidth: 1, radialLines: true }),
51277
+ /* @__PURE__ */ jsxRuntime.jsx(
51278
+ PolarAngleAxis,
51279
+ {
51280
+ dataKey: "tactic",
51281
+ tick: (props) => {
51282
+ const { payload, x: x2, y: y2, textAnchor } = props;
51283
+ const label = payload.value;
51284
+ const centerX = 210;
51285
+ const centerY = 210;
51286
+ const dx = x2 - centerX;
51287
+ const dy = y2 - centerY;
51288
+ const distance = Math.sqrt(dx * dx + dy * dy);
51289
+ const unitX = dx / distance;
51290
+ const unitY = dy / distance;
51291
+ const offset2 = 15;
51292
+ const offsetX = x2 + unitX * offset2;
51293
+ const offsetY = y2 + unitY * offset2;
51294
+ if (label.length >= 12) {
51295
+ const words = label.split(" ");
51296
+ let line1 = "";
51297
+ let line2 = "";
51298
+ let bestSplit = Math.ceil(words.length / 2);
51299
+ for (let i = 0; i < words.length; i++) {
51300
+ if (words[i].toLowerCase() === "and" && i > 0 && i < words.length - 1) {
51301
+ bestSplit = i;
51302
+ break;
51303
+ }
51304
+ }
51305
+ line1 = words.slice(0, bestSplit).join(" ");
51306
+ line2 = words.slice(bestSplit).join(" ");
51307
+ return /* @__PURE__ */ jsxRuntime.jsxs("g", { transform: `translate(${offsetX},${offsetY})`, children: [
51308
+ /* @__PURE__ */ jsxRuntime.jsx(
51309
+ "text",
51310
+ {
51311
+ x: 0,
51312
+ y: -4,
51313
+ textAnchor,
51314
+ fontSize: 10,
51315
+ fill: "#6b7280",
51316
+ className: "text-xs",
51317
+ style: { dominantBaseline: "middle" },
51318
+ children: line1
51319
+ }
51320
+ ),
51321
+ /* @__PURE__ */ jsxRuntime.jsx(
51322
+ "text",
51323
+ {
51324
+ x: 0,
51325
+ y: 8,
51326
+ textAnchor,
51327
+ fontSize: 10,
51328
+ fill: "#6b7280",
51329
+ className: "text-xs",
51330
+ style: { dominantBaseline: "middle" },
51331
+ children: line2
51332
+ }
51333
+ )
51334
+ ] });
51335
+ }
51336
+ return /* @__PURE__ */ jsxRuntime.jsx(
51337
+ "text",
51327
51338
  {
51328
- className: "text-sm",
51329
- style: { color: getRiskLevelColor(data.riskLevel) },
51330
- children: [
51331
- "Risk Level:",
51332
- " ",
51333
- data.riskLevel.charAt(0).toUpperCase() + data.riskLevel.slice(1)
51334
- ]
51339
+ x: offsetX,
51340
+ y: offsetY,
51341
+ textAnchor,
51342
+ fontSize: 10,
51343
+ fill: "#6b7280",
51344
+ className: "text-xs",
51345
+ children: label
51335
51346
  }
51336
- )
51337
- ] });
51347
+ );
51348
+ },
51349
+ className: "text-xs"
51338
51350
  }
51339
- return null;
51340
- }
51341
- }
51342
- )
51343
- ]
51351
+ ),
51352
+ /* @__PURE__ */ jsxRuntime.jsx(
51353
+ PolarRadiusAxis,
51354
+ {
51355
+ angle: 90,
51356
+ domain: [0, 100],
51357
+ tick: { fontSize: 8, fill: "#6b7280" },
51358
+ tickCount: 6,
51359
+ axisLine: false
51360
+ }
51361
+ ),
51362
+ /* @__PURE__ */ jsxRuntime.jsx(
51363
+ Radar,
51364
+ {
51365
+ name: "Coverage",
51366
+ dataKey: "coverage",
51367
+ stroke: strokeColor,
51368
+ fill: `url(#${gradientId})`,
51369
+ strokeWidth: 2.5,
51370
+ dot: {
51371
+ r: 4,
51372
+ fill: strokeColor,
51373
+ strokeWidth: 2,
51374
+ stroke: "#ffffff"
51375
+ },
51376
+ activeDot: {
51377
+ r: 6,
51378
+ fill: strokeColor,
51379
+ strokeWidth: 2,
51380
+ stroke: "#ffffff"
51381
+ }
51382
+ }
51383
+ ),
51384
+ /* @__PURE__ */ jsxRuntime.jsx(
51385
+ ChartTooltip,
51386
+ {
51387
+ content: ({ active, payload }) => {
51388
+ if (active && payload && payload.length) {
51389
+ const data = payload[0].payload;
51390
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-white p-3 border rounded-lg shadow-lg", children: [
51391
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "font-semibold text-gray-900", children: data.fullName }),
51392
+ /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-sm text-gray-600", children: [
51393
+ "Coverage: ",
51394
+ data.actualCoverage,
51395
+ "%"
51396
+ ] }),
51397
+ /* @__PURE__ */ jsxRuntime.jsxs(
51398
+ "p",
51399
+ {
51400
+ className: "text-sm",
51401
+ style: { color: getRiskLevelColor(data.riskLevel) },
51402
+ children: [
51403
+ "Risk Level:",
51404
+ " ",
51405
+ data.riskLevel.charAt(0).toUpperCase() + data.riskLevel.slice(1)
51406
+ ]
51407
+ }
51408
+ )
51409
+ ] });
51410
+ }
51411
+ return null;
51412
+ }
51413
+ }
51414
+ )
51415
+ ]
51416
+ }
51417
+ )
51344
51418
  }
51345
- ) }),
51419
+ ),
51346
51420
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-center", children: [
51347
51421
  /* @__PURE__ */ jsxRuntime.jsxs(
51348
51422
  "div",
@@ -51900,7 +51974,7 @@ const BreachLikelihood = ({ reportData }) => {
51900
51974
  overallLikelihood: attackLikelihood
51901
51975
  }
51902
51976
  ) : /* @__PURE__ */ jsxRuntime.jsx("p", { children: "Getting breach data..." }) }),
51903
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-rows-3 gap-4", children: [
51977
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col justify-center gap-4", children: [
51904
51978
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center p-4 rounded-md bg-slate-50", children: [
51905
51979
  /* @__PURE__ */ jsxRuntime.jsx(lucideReact.CheckCircle, { className: "w-6 h-6 mr-4 text-green-600" }),
51906
51980
  /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
@@ -52117,7 +52191,6 @@ const UnifiedCostBreakdownChart = ({
52117
52191
  ) }) });
52118
52192
  };
52119
52193
  const FinancialImpact = ({ reportData }) => {
52120
- var _a;
52121
52194
  const { clientData, simulationData } = reportData;
52122
52195
  const { industry } = clientData;
52123
52196
  const getIndustryRiskLevel = (industry2) => {
@@ -52328,6 +52401,7 @@ const FinancialImpact = ({ reportData }) => {
52328
52401
  };
52329
52402
  const riskLevel = getIndustryRiskLevel(industry);
52330
52403
  const dynamicCostBreakdown = createCostBreakdownFromSimulation(simulationData);
52404
+ const calculatedCost = simulationData.use_calculated_downtime === false ? simulationData.total_cost : simulationData.adjusted_total_cost;
52331
52405
  return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
52332
52406
  /* @__PURE__ */ jsxRuntime.jsx(
52333
52407
  "section",
@@ -52346,12 +52420,12 @@ const FinancialImpact = ({ reportData }) => {
52346
52420
  /* @__PURE__ */ jsxRuntime.jsx(lucideReact.DollarSign, { className: "w-8 h-8" }),
52347
52421
  /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-2xl font-bold", children: "TOTAL POTENTIAL IMPACT" })
52348
52422
  ] }),
52349
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-4xl font-bold", children: simulationData.use_calculated_downtime === false ? formatCurrency(simulationData.total_cost) : formatCurrency(simulationData.adjusted_total_cost) }),
52423
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-4xl font-bold", children: formatCurrency(calculatedCost) }),
52350
52424
  /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-sm opacity-75 mt-2", children: [
52351
- "Cost Range: ",
52352
- formatCurrency(simulationData.total_cost * 0.8),
52353
- " - ",
52354
- formatCurrency(simulationData.total_cost * 1.2)
52425
+ "Cost Range:  ",
52426
+ formatCurrency(calculatedCost * 0.8),
52427
+ " -  ",
52428
+ formatCurrency(calculatedCost * 1.2)
52355
52429
  ] })
52356
52430
  ] }),
52357
52431
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-4", children: [
@@ -52404,20 +52478,18 @@ const FinancialImpact = ({ reportData }) => {
52404
52478
  /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "text-2xl font-bold text-slate-900 mb-2", children: "Detailed Financial Breakdown" }),
52405
52479
  /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-slate-600", children: "Understanding the components of the total potential cost" })
52406
52480
  ] }),
52407
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-1 lg:grid-cols-6 gap-8", children: [
52408
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "lg:col-span-3 space-y-4", children: /* @__PURE__ */ jsxRuntime.jsx("div", { id: "impact-chart", className: "chart-container", children: /* @__PURE__ */ jsxRuntime.jsx(
52481
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-1 lg:grid-cols-6 gap-8 print:grid-cols-6", children: [
52482
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "lg:col-span-3 print:col-span-3 space-y-4", children: /* @__PURE__ */ jsxRuntime.jsx("div", { id: "impact-chart", className: "chart-container", children: /* @__PURE__ */ jsxRuntime.jsx(
52409
52483
  UnifiedCostBreakdownChart,
52410
52484
  {
52411
52485
  hard_costs: dynamicCostBreakdown.hard_costs,
52412
52486
  business_downtime: dynamicCostBreakdown.business_downtime,
52413
52487
  regulatory_fines: dynamicCostBreakdown.regulatory_fines,
52414
52488
  reputation_damage: dynamicCostBreakdown.reputation_damage,
52415
- totalCost: parseInt(
52416
- ((_a = clientData.totalEstimatedCost) == null ? void 0 : _a.replace(/,/g, "")) || "0"
52417
- ) || clientData.totalCost
52489
+ totalCost: calculatedCost
52418
52490
  }
52419
52491
  ) }) }),
52420
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "lg:col-span-3 space-y-4", children: [
52492
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "lg:col-span-3 print:col-span-3 space-y-4", children: [
52421
52493
  /* @__PURE__ */ jsxRuntime.jsx("h4", { className: "font-semibold text-slate-900", children: "Cost Categories" }),
52422
52494
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-2", children: getIndustrySpecificCosts(
52423
52495
  clientData.industry,
@@ -53007,7 +53079,7 @@ const InsuranceHealthScore = ({ reportData }) => {
53007
53079
  break;
53008
53080
  case percentage >= 60:
53009
53081
  statusClass = "bg-yellow-500";
53010
- statusLabel = "NEEDS IMPROVEMENT";
53082
+ statusLabel = "FAIR";
53011
53083
  break;
53012
53084
  case (percentage < 60 && percentage > 0):
53013
53085
  statusClass = "bg-red-500";
@@ -53058,7 +53130,7 @@ const InsuranceHealthScore = ({ reportData }) => {
53058
53130
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-slate-50 rounded-lg p-6", children: [
53059
53131
  /* @__PURE__ */ jsxRuntime.jsx("h4", { className: "font-semibold text-slate-900 mb-4", children: "How We Calculate Your Score" }),
53060
53132
  /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-slate-700 mb-4", children: "Your Insurance Health Score is calculated based on industry-standard cybersecurity frameworks and real insurance company requirements. Each category is weighted according to its importance in determining cyber insurance coverage and pricing." }),
53061
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4", children: [
53133
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 print:grid-cols-2 gap-4", children: [
53062
53134
  /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
53063
53135
  /* @__PURE__ */ jsxRuntime.jsx("h5", { className: "font-medium text-slate-900 mb-2", children: "Score Ranges:" }),
53064
53136
  /* @__PURE__ */ jsxRuntime.jsxs("ul", { className: "text-sm text-slate-700 space-y-1", children: [
@@ -53111,7 +53183,7 @@ const InsuranceHealthScore = ({ reportData }) => {
53111
53183
  ] })
53112
53184
  ] })
53113
53185
  ] }),
53114
- /* @__PURE__ */ jsxRuntime.jsx("section", { className: "report-page space-y-6 border-t border-slate-200 pt-8", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-6", children: [
53186
+ /* @__PURE__ */ jsxRuntime.jsx("section", { className: "report-page space-y-6 border-t border-slate-200 pt-8", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 print:grid-cols-2 gap-6", children: [
53115
53187
  /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
53116
53188
  /* @__PURE__ */ jsxRuntime.jsx("h4", { className: "font-semibold text-green-600 mb-3", children: "What This Report IS:" }),
53117
53189
  /* @__PURE__ */ jsxRuntime.jsxs("ul", { className: "text-slate-700 space-y-2 text-sm", children: [
@@ -53164,6 +53236,7 @@ const ReportBuilder = ({
53164
53236
  simulationData,
53165
53237
  mspInfo
53166
53238
  }) => {
53239
+ const [editExecutiveSummary, setEditExecutiveSummary] = React.useState(false);
53167
53240
  const [searchParams] = reactRouterDom.useSearchParams();
53168
53241
  const reportTemplate = searchParams.get("template");
53169
53242
  const templateArray = (reportTemplate == null ? void 0 : reportTemplate.split(",").map((item) => item.trim())) || [];
@@ -53187,43 +53260,60 @@ const ReportBuilder = ({
53187
53260
  if (items.length === 2) return `${items[0]} and ${items[1]}`;
53188
53261
  return `${items.slice(0, -1).join(", ")}, and ${items[items.length - 1]}`;
53189
53262
  };
53263
+ const onConfigChange = (key, value) => {
53264
+ console.log(`Config changed: ${key} = ${value}`);
53265
+ };
53190
53266
  return /* @__PURE__ */ jsxRuntime.jsxs(
53191
53267
  "article",
53192
53268
  {
53193
53269
  id: "print-report",
53194
- className: "report-wrapper max-w-4xl mx-auto bg-white p-8 space-y-8",
53270
+ className: "report-wrapper max-w-4xl mx-auto bg-white p-8 space-y-8 print:font-sans",
53195
53271
  children: [
53196
- /* @__PURE__ */ jsxRuntime.jsx("figure", { className: "bg-slate-200 max-w-40 flex object-contain rounded-lg items-center justify-center mx-auto", children: mspInfo.company_logo ? /* @__PURE__ */ jsxRuntime.jsx(
53197
- "img",
53198
- {
53199
- src: mspInfo.company_logo,
53200
- alt: "MSP Logo",
53201
- className: "w-full h-auto m-auto"
53202
- }
53203
- ) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Building2, { className: "w-10 h-10 text-slate-500" }) }),
53204
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "max-w-md mx-auto bg-slate-50 rounded-lg p-6 space-y-3", children: [
53205
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-between", children: [
53206
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium text-slate-700", children: "Prepared For:" }),
53207
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-slate-900", children: clientData.company_name || "Client Company" })
53208
- ] }),
53209
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-between", children: [
53210
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium text-slate-700", children: "Industry Sector:" }),
53211
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-slate-900", children: clientData.industry || "Industry" })
53212
- ] }),
53213
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-between", children: [
53214
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium text-slate-700", children: "Prepared By:" }),
53215
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-slate-900", children: mspInfo.company_name || /* @__PURE__ */ jsxRuntime.jsx("span", { style: { color: "red", fontWeight: "bold" }, children: "NEEDS ACTUAL MSP NAME" }) })
53272
+ /* @__PURE__ */ jsxRuntime.jsxs("section", { className: "report-page", children: [
53273
+ /* @__PURE__ */ jsxRuntime.jsx("figure", { className: "bg-slate-200 max-w-40 print:max-w-40 flex object-contain rounded-lg items-center justify-center mx-auto", children: mspInfo.company_logo ? /* @__PURE__ */ jsxRuntime.jsx(
53274
+ "img",
53275
+ {
53276
+ src: mspInfo.company_logo,
53277
+ alt: "MSP Logo",
53278
+ className: "w-full h-auto m-auto print:w-40 print:h-auto"
53279
+ }
53280
+ ) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Building2, { className: "w-10 h-10 text-slate-500" }) }),
53281
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "max-w-md mx-auto bg-slate-50 rounded-lg p-6 space-y-3", children: [
53282
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-between", children: [
53283
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium text-slate-700", children: "Prepared For:" }),
53284
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-slate-900", children: clientData.company_name || "Client Company" })
53285
+ ] }),
53286
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-between", children: [
53287
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium text-slate-700", children: "Industry Sector:" }),
53288
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-slate-900", children: clientData.industry || "Industry" })
53289
+ ] }),
53290
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-between", children: [
53291
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium text-slate-700", children: "Prepared By:" }),
53292
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-slate-900", children: mspInfo.company_name || /* @__PURE__ */ jsxRuntime.jsx("span", { style: { color: "red", fontWeight: "bold" }, children: "NEEDS ACTUAL MSP NAME" }) })
53293
+ ] }),
53294
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-between", children: [
53295
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium text-slate-700", children: "Assessment Date:" }),
53296
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-slate-900", children: (/* @__PURE__ */ new Date()).toLocaleDateString() })
53297
+ ] })
53216
53298
  ] }),
53217
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-between", children: [
53218
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium text-slate-700", children: "Assessment Date:" }),
53219
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-slate-900", children: (/* @__PURE__ */ new Date()).toLocaleDateString() })
53299
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "p-4 text-left space-y-2", children: [
53300
+ /* @__PURE__ */ jsxRuntime.jsx("h1", { className: "text-2xl font-bold text-slate-900 text-left", children: "Executive Summary" }),
53301
+ /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-base font-semibold text-slate-900", children: "Why This Assessment Matters" }),
53302
+ editExecutiveSummary ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
53303
+ /* @__PURE__ */ jsxRuntime.jsx(
53304
+ Textarea,
53305
+ {
53306
+ value: displayExecutiveSummary(clientData),
53307
+ onChange: (e) => onConfigChange("executiveSummary", e.target.value),
53308
+ placeholder: "Executive summary content...",
53309
+ rows: 6,
53310
+ className: "resize-none"
53311
+ }
53312
+ ),
53313
+ /* @__PURE__ */ jsxRuntime.jsx(Button$1, { onClick: () => setEditExecutiveSummary(false), children: "Save" })
53314
+ ] }) : /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-slate-700 leading-relaxed whitespace-pre-line text-sm", children: displayExecutiveSummary(clientData) }) })
53220
53315
  ] })
53221
53316
  ] }),
53222
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "p-4 text-left space-y-2", children: [
53223
- /* @__PURE__ */ jsxRuntime.jsx("h1", { className: "text-2xl font-bold text-slate-900 text-left", children: "Executive Summary" }),
53224
- /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-base font-semibold text-slate-900", children: "Why This Assessment Matters" }),
53225
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-slate-700 leading-relaxed whitespace-pre-line text-sm", children: displayExecutiveSummary(clientData) })
53226
- ] }),
53227
53317
  showFinancialImpact && /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: financialSimulationData && Object.keys(financialSimulationData).length > 0 ? /* @__PURE__ */ jsxRuntime.jsx(
53228
53318
  FinancialImpact,
53229
53319
  {