From 0408f7082052a2b9e27787aad8415fab79b7c37b Mon Sep 17 00:00:00 2001 From: Miguel Velasco Date: Thu, 19 Feb 2026 22:07:53 -0500 Subject: [PATCH 1/2] feat: Add functionality to export longevity analysis projection data to CSV. --- src/components/features/LongevityAnalysis.tsx | 14 +++- src/utils/exportCsv.ts | 66 +++++++++++++++++++ 2 files changed, 78 insertions(+), 2 deletions(-) create mode 100644 src/utils/exportCsv.ts diff --git a/src/components/features/LongevityAnalysis.tsx b/src/components/features/LongevityAnalysis.tsx index 19dcf03..aef1629 100644 --- a/src/components/features/LongevityAnalysis.tsx +++ b/src/components/features/LongevityAnalysis.tsx @@ -2,7 +2,8 @@ import React from 'react'; import { LongevityResult, UserProfile } from '../../types'; import { AreaChart, Area, XAxis, YAxis, CartesianGrid, Tooltip as RechartsTooltip, ResponsiveContainer, BarChart, Bar, Legend } from 'recharts'; import Tooltip from '../common/Tooltip'; -import { AlertTriangle, CheckCircle, HelpCircle } from 'lucide-react'; +import { AlertTriangle, CheckCircle, HelpCircle, Download } from 'lucide-react'; +import { exportLongevityToCsv } from '../../utils/exportCsv'; interface LongevityAnalysisProps { longevity: LongevityResult; @@ -72,7 +73,16 @@ const LongevityAnalysis: React.FC = ({ longevity, profil {/* Chart */}
-

Portfolio Balance Projection

+
+

Portfolio Balance Projection

+ +
{ + if (!projection || projection.length === 0) return; + + const headers = [ + 'Age', + 'Year', + 'Total Assets', + 'Brokerage Balance', + 'Trad IRA Balance', + 'Roth IRA Balance', + 'HSA Balance', + 'Total Withdrawal', + 'Brokerage Withdrawal', + 'Trad IRA Withdrawal', + 'Roth IRA Withdrawal', + 'HSA Withdrawal', + 'Early Withdrawal Penalty', + 'RMD Amount', + 'Social Security Income', + 'Pension Income', + 'Dividend Income', + 'Estimated Tax', + 'Effective Tax Rate (%)' + ]; + + const rows = projection.map(data => { + // Math.round to match the displayed values which are generally rounded for ease of reading + return [ + data.age, + data.year, + Math.round(data.totalAssets), + Math.round(data.brokerage), + Math.round(data.traditionalIRA), + Math.round(data.rothIRA), + Math.round(data.hsa), + Math.round(data.withdrawal), + Math.round(data.withdrawalBrokerage), + Math.round(data.withdrawalTrad), + Math.round(data.withdrawalRoth), + Math.round(data.withdrawalHSA), + Math.round(data.earlyWithdrawalPenalty || 0), + Math.round(data.rmdAmount || 0), + Math.round(data.socialSecurityIncome || 0), + Math.round(data.pensionIncome || 0), + Math.round(data.dividendIncome || 0), + Math.round(data.estimatedTax || 0), + data.effectiveTaxRate ? (data.effectiveTaxRate * 100).toFixed(2) : '0.00' + ]; + }); + + const csvContent = [ + headers.join(','), + ...rows.map(row => row.join(',')) + ].join('\n'); + + const blob = new Blob([csvContent], { type: 'text/csv;charset=utf-8;' }); + const url = URL.createObjectURL(blob); + const link = document.createElement('a'); + link.setAttribute('href', url); + link.setAttribute('download', 'fiscal_sunset_longevity_projection.csv'); + document.body.appendChild(link); + link.click(); + document.body.removeChild(link); +}; From c23eb63860571ea4860bfb590a4edab55fbe290e Mon Sep 17 00:00:00 2001 From: Miguel Velasco Date: Mon, 23 Feb 2026 20:38:43 -0500 Subject: [PATCH 2/2] feat: Add GitHub Copilot instructions to .gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index c3b9e3c..435c512 100644 --- a/.gitignore +++ b/.gitignore @@ -29,6 +29,7 @@ gcpdeploy.md deploy.sh todo.md .agent/* +.github/copilot-instructions.md .agent/*