Added FinancialProfileForm with navigation from Popoutpanel
This commit is contained in:
parent
b5daa609ac
commit
5d5e5fb001
@ -7,6 +7,7 @@ import SignUp from './components/SignUp.js';
|
|||||||
import InterestInventory from './components/InterestInventory.js';
|
import InterestInventory from './components/InterestInventory.js';
|
||||||
import Dashboard from './components/Dashboard.js';
|
import Dashboard from './components/Dashboard.js';
|
||||||
import UserProfile from './components/UserProfile.js';
|
import UserProfile from './components/UserProfile.js';
|
||||||
|
import FinancialProfileForm from './components/FinancialProfileForm.js';
|
||||||
import MilestoneTracker from "./components/MilestoneTracker.js";
|
import MilestoneTracker from "./components/MilestoneTracker.js";
|
||||||
import './App.css';
|
import './App.css';
|
||||||
|
|
||||||
@ -48,6 +49,11 @@ function App() {
|
|||||||
path="/milestone-tracker"
|
path="/milestone-tracker"
|
||||||
element={isAuthenticated ? <MilestoneTracker /> : <Navigate to="/signin" />}
|
element={isAuthenticated ? <MilestoneTracker /> : <Navigate to="/signin" />}
|
||||||
/>
|
/>
|
||||||
|
<Route
|
||||||
|
path="/financial-profile"
|
||||||
|
element={isAuthenticated ? <FinancialProfileForm /> : <Navigate to="/signin" />}
|
||||||
|
/>
|
||||||
|
|
||||||
{/* Catch-all for unknown routes */}
|
{/* Catch-all for unknown routes */}
|
||||||
<Route path="*" element={<Navigate to="/signin" />} />
|
<Route path="*" element={<Navigate to="/signin" />} />
|
||||||
</Routes>
|
</Routes>
|
||||||
|
161
src/components/FinancialProfileForm.js
Normal file
161
src/components/FinancialProfileForm.js
Normal file
@ -0,0 +1,161 @@
|
|||||||
|
import React, { useState, useEffect } from "react";
|
||||||
|
import { useLocation, useNavigate } from 'react-router-dom';
|
||||||
|
|
||||||
|
export default function FinancialProfileForm() {
|
||||||
|
const location = useLocation();
|
||||||
|
const navigate = useNavigate();
|
||||||
|
console.log("🔍 FinancialProfileForm mounted");
|
||||||
|
console.log("🔍 location.state:", location.state);
|
||||||
|
const initialCareer = location?.state?.selectedCareer;
|
||||||
|
const [selectedCareer, setSelectedCareer] = useState(initialCareer || null);
|
||||||
|
const userId = localStorage.getItem("userId");
|
||||||
|
const [formData, setFormData] = useState({
|
||||||
|
currentSalary: "",
|
||||||
|
additionalIncome: "",
|
||||||
|
monthlyExpenses: "",
|
||||||
|
monthlyDebtPayments: "",
|
||||||
|
retirementSavings: "",
|
||||||
|
retirementContribution: "",
|
||||||
|
emergencyFund: "",
|
||||||
|
inCollege: false,
|
||||||
|
expectedGraduation: "",
|
||||||
|
partTimeIncome: "",
|
||||||
|
tuitionPaid: "",
|
||||||
|
collegeLoanTotal: ""
|
||||||
|
});
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
console.log("✅ selectedCareer in useEffect:", selectedCareer);
|
||||||
|
}, [selectedCareer]);
|
||||||
|
|
||||||
|
// Fetch existing data on mount
|
||||||
|
useEffect(() => {
|
||||||
|
async function fetchProfile() {
|
||||||
|
try {
|
||||||
|
const res = await fetch(`/api/premium/financial-profile?user_id=${userId}`);
|
||||||
|
if (res.ok) {
|
||||||
|
const data = await res.json();
|
||||||
|
setFormData((prev) => ({ ...prev, ...data }));
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.error("Failed to fetch financial profile", err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fetchProfile();
|
||||||
|
}, [userId]);
|
||||||
|
|
||||||
|
const handleChange = (e) => {
|
||||||
|
const { name, value, type, checked } = e.target;
|
||||||
|
setFormData((prev) => ({
|
||||||
|
...prev,
|
||||||
|
[name]: type === "checkbox" ? checked : value
|
||||||
|
}));
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleSubmit = async (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
try {
|
||||||
|
const res = await fetch("/api/premium/financial-profile", {
|
||||||
|
method: "POST",
|
||||||
|
headers: { "Content-Type": "application/json" },
|
||||||
|
body: JSON.stringify({ user_id: userId, ...formData })
|
||||||
|
});
|
||||||
|
|
||||||
|
if (res.ok) {
|
||||||
|
navigate('/milestone-tracker', {
|
||||||
|
state: { selectedCareer }
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.error("Error submitting financial profile:", err);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<form onSubmit={handleSubmit} className="max-w-2xl mx-auto p-4 space-y-4 bg-white shadow rounded">
|
||||||
|
<h2 className="text-xl font-semibold">Your Financial Profile</h2>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<label className="block font-medium">Current Salary</label>
|
||||||
|
<input name="currentSalary" type="number" value={formData.currentSalary} onChange={handleChange}
|
||||||
|
className="w-full border rounded p-2" placeholder="$" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<label className="block font-medium">Additional Monthly Income</label>
|
||||||
|
<input name="additionalIncome" type="number" value={formData.additionalIncome} onChange={handleChange}
|
||||||
|
className="w-full border rounded p-2" placeholder="$" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<label className="block font-medium">Monthly Living Expenses</label>
|
||||||
|
<input name="monthlyExpenses" type="number" value={formData.monthlyExpenses} onChange={handleChange}
|
||||||
|
className="w-full border rounded p-2" placeholder="$" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<label className="block font-medium">Monthly Debt Payments (non-student)</label>
|
||||||
|
<input name="monthlyDebtPayments" type="number" value={formData.monthlyDebtPayments} onChange={handleChange}
|
||||||
|
className="w-full border rounded p-2" placeholder="$" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<label className="block font-medium">Current Retirement Savings</label>
|
||||||
|
<input name="retirementSavings" type="number" value={formData.retirementSavings} onChange={handleChange}
|
||||||
|
className="w-full border rounded p-2" placeholder="$" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<label className="block font-medium">Monthly Retirement Contribution</label>
|
||||||
|
<input name="retirementContribution" type="number" value={formData.retirementContribution} onChange={handleChange}
|
||||||
|
className="w-full border rounded p-2" placeholder="$" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<label className="block font-medium">Emergency Fund Balance</label>
|
||||||
|
<input name="emergencyFund" type="number" value={formData.emergencyFund} onChange={handleChange}
|
||||||
|
className="w-full border rounded p-2" placeholder="$" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="flex items-center space-x-2">
|
||||||
|
<input id="inCollege" name="inCollege" type="checkbox" checked={formData.inCollege} onChange={handleChange} />
|
||||||
|
<label htmlFor="inCollege" className="font-medium">Are you currently in college?</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{formData.inCollege && (
|
||||||
|
<>
|
||||||
|
<div>
|
||||||
|
<label className="block font-medium">Expected Graduation Date</label>
|
||||||
|
<input name="expectedGraduation" type="date" value={formData.expectedGraduation} onChange={handleChange}
|
||||||
|
className="w-full border rounded p-2" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<label className="block font-medium">Part-Time Monthly Income</label>
|
||||||
|
<input name="partTimeIncome" type="number" value={formData.partTimeIncome} onChange={handleChange}
|
||||||
|
className="w-full border rounded p-2" placeholder="$" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<label className="block font-medium">Tuition Paid So Far</label>
|
||||||
|
<input name="tuitionPaid" type="number" value={formData.tuitionPaid} onChange={handleChange}
|
||||||
|
className="w-full border rounded p-2" placeholder="$" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<label className="block font-medium">Total College Loan Amount</label>
|
||||||
|
<input name="collegeLoanTotal" type="number" value={formData.collegeLoanTotal} onChange={handleChange}
|
||||||
|
className="w-full border rounded p-2" placeholder="$" />
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
|
||||||
|
<div className="pt-4">
|
||||||
|
<button type="submit" className="bg-blue-600 text-white px-4 py-2 rounded hover:bg-blue-700">
|
||||||
|
Save and Continue
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
);
|
||||||
|
}
|
@ -149,7 +149,7 @@ function PopoutPanel({
|
|||||||
|
|
||||||
|
|
||||||
if (decision) {
|
if (decision) {
|
||||||
navigate('/milestone-tracker', {
|
navigate('/financial-profile', {
|
||||||
state: { selectedCareer: { career_path_id: match.id, career_name: data.title } }
|
state: { selectedCareer: { career_path_id: match.id, career_name: data.title } }
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
@ -172,7 +172,7 @@ function PopoutPanel({
|
|||||||
|
|
||||||
if (!newResponse.ok) throw new Error('Failed to create new career path.');
|
if (!newResponse.ok) throw new Error('Failed to create new career path.');
|
||||||
|
|
||||||
navigate('/milestone-tracker', {
|
navigate('/financial-profile', {
|
||||||
state: { selectedCareer: { career_path_id: newCareerPath.career_path_id, career_name: data.title } }
|
state: { selectedCareer: { career_path_id: newCareerPath.career_path_id, career_name: data.title } }
|
||||||
});
|
});
|
||||||
|
|
||||||
|
BIN
user_profile.db
BIN
user_profile.db
Binary file not shown.
Loading…
Reference in New Issue
Block a user