// FinancialProfileForm.js import React, { useEffect, useState } from 'react'; import { useNavigate } from 'react-router-dom'; import authFetch from '../utils/authFetch.js'; import Modal from './ui/modal.js'; import ExpensesWizard from './ExpensesWizard.js'; // same wizard you use in onboarding import { Button } from './ui/button.js'; // Tailwind‑based button (optional) /* helper – clamp 0‑100 */ const pct = v => Math.min(Math.max(parseFloat(v) || 0, 0), 100); export default function FinancialProfileForm() { const nav = useNavigate(); /* ─────────────── local state ─────────────── */ const [currentSalary, setCurrentSalary] = useState(''); const [additionalIncome, setAdditionalIncome] = useState(''); const [monthlyExpenses, setMonthlyExpenses] = useState(''); const [monthlyDebtPayments, setMonthlyDebtPayments] = useState(''); const [retirementSavings, setRetirementSavings] = useState(''); const [emergencyFund, setEmergencyFund] = useState(''); const [retirementContribution, setRetirementContribution] = useState(''); const [emergencyContribution, setEmergencyContribution] = useState(''); const [extraCashEmergencyPct, setExtraCashEmergencyPct] = useState('50'); const [extraCashRetirementPct, setExtraCashRetirementPct] = useState('50'); /* wizard modal */ const [showExpensesWizard, setShowExpensesWizard] = useState(false); const openWizard = () => setShowExpensesWizard(true); const closeWizard = () => setShowExpensesWizard(false); /* ───────────── preload existing row ───────── */ useEffect(() => { (async () => { try { const res = await authFetch('/api/premium/financial-profile'); if (!res.ok) return; const d = await res.json(); setCurrentSalary (d.current_salary ?? ''); setAdditionalIncome (d.additional_income ?? ''); setMonthlyExpenses (d.monthly_expenses ?? ''); setMonthlyDebtPayments (d.monthly_debt_payments ?? ''); setRetirementSavings (d.retirement_savings ?? ''); setEmergencyFund (d.emergency_fund ?? ''); setRetirementContribution (d.retirement_contribution ?? ''); setEmergencyContribution (d.emergency_contribution ?? ''); setExtraCashEmergencyPct (d.extra_cash_emergency_pct ?? ''); setExtraCashRetirementPct (d.extra_cash_retirement_pct ?? ''); } catch (err) { console.error(err); } })(); }, []); /* ----------------------------------------------------------- * keep the two % inputs complementary (must add to 100) * --------------------------------------------------------- */ function handleChange(e) { const { name, value } = e.target; const pct = Math.max(0, Math.min(100, Number(value) || 0)); // clamp 0‑100 if (name === 'extraCashEmergencyPct') { setExtraCashEmergencyPct(String(pct)); setExtraCashRetirementPct(String(100 - pct)); } else if (name === 'extraCashRetirementPct') { setExtraCashRetirementPct(String(pct)); setExtraCashEmergencyPct(String(100 - pct)); } else { // all other numeric fields: // allow empty string so users can clear then re‑type const update = valSetter => valSetter(value === '' ? '' : Number(value)); switch (name) { case 'currentSalary': update(setCurrentSalary); break; case 'additionalIncome': update(setAdditionalIncome); break; case 'monthlyExpenses': update(setMonthlyExpenses); break; case 'monthlyDebtPayments': update(setMonthlyDebtPayments); break; case 'retirementSavings': update(setRetirementSavings); break; case 'emergencyFund': update(setEmergencyFund); break; case 'retirementContribution': update(setRetirementContribution); break; case 'emergencyContribution': update(setEmergencyContribution); break; default: break; } } } /* ───────────── submit ─────────────────────── */ async function handleSubmit(e) { e.preventDefault(); const body = { current_salary: parseFloat(currentSalary) || 0, additional_income: parseFloat(additionalIncome) || 0, monthly_expenses: parseFloat(monthlyExpenses) || 0, monthly_debt_payments: parseFloat(monthlyDebtPayments) || 0, retirement_savings: parseFloat(retirementSavings) || 0, emergency_fund: parseFloat(emergencyFund) || 0, retirement_contribution: parseFloat(retirementContribution) || 0, emergency_contribution: parseFloat(emergencyContribution) || 0, extra_cash_emergency_pct: pct(extraCashEmergencyPct), extra_cash_retirement_pct: pct(extraCashRetirementPct) }; try { const res = await authFetch('/api/premium/financial-profile', { method : 'POST', headers: { 'Content-Type':'application/json' }, body : JSON.stringify(body) }); if (!res.ok) throw new Error(await res.text()); alert('Financial profile saved.'); nav(-1); } catch (err) { console.error(err); alert('Failed to save financial profile.'); } } /* ───────────── view ───────────────────────── */ return ( <>

Edit Your Financial Profile

{/* salary / income */} {/* expenses with wizard */}
setMonthlyExpenses(e.target.value)} />
{/* rest of the numeric fields */} {/* allocation – kept in sync */}

Extra Monthly Cash Allocation (must total 100%)

{/* action buttons */}
{/* wizard modal */} {showExpensesWizard && ( { setMonthlyExpenses(total); closeWizard(); }} /> )} ); }