+
Career Details
-
- Are you currently working or earning any income (even part-time)?
-
-
setCurrentlyWorking(e.target.value)}
- className="w-full border rounded p-2"
- >
- Select one
- Yes
- No
-
+
+
+ Are you currently working or earning any income (even part-time)?
+
+ setCurrentlyWorking(e.target.value)}
+ className="w-full border rounded p-2"
+ >
+ Select one
+ Yes
+ No
+
+
-
-
Search for Career
+
+
Search for Career
{careers.map((career, index) => (
@@ -143,38 +142,79 @@ const CareerOnboarding = ({ nextStep, prevStep, data, setData }) => {
- {selectedCareer &&
Selected Career: {selectedCareer}
}
+ {selectedCareer && (
+
+ Selected Career: {selectedCareer}
+
+ )}
-
Status:
-
- Select Status
- Planned
- Current
- Exploring
-
+
+ Status:
+
+ Select Status
+ Planned
+ Current
+ Exploring
+
+
-
Career Start Date:
-
+
+ Career Start Date:
+
+
-
Projected End Date (optional):
-
+
+ Projected End Date (optional):
+
+
-
- Are you currently enrolled in college or planning to enroll?
-
-
setCollegeEnrollmentStatus(e.target.value)}
- className="w-full border rounded p-2"
- >
- Select one
- Not Enrolled / Not Planning
- Currently Enrolled
- Planning to Enroll (Prospective Student)
-
+
+
+ Are you currently enrolled in college or planning to enroll?
+
+ setCollegeEnrollmentStatus(e.target.value)}
+ className="w-full border rounded p-2"
+ >
+ Select one
+ Not Enrolled / Not Planning
+ Currently Enrolled
+ Planning to Enroll (Prospective Student)
+
+
-
Back
-
Financial →
+
+
+ Back
+
+
+ Financial →
+
+
);
};
diff --git a/src/components/PremiumOnboarding/CollegeOnboarding.js b/src/components/PremiumOnboarding/CollegeOnboarding.js
index c1a015a..9575068 100644
--- a/src/components/PremiumOnboarding/CollegeOnboarding.js
+++ b/src/components/PremiumOnboarding/CollegeOnboarding.js
@@ -1,7 +1,7 @@
+// CollegeOnboarding.js
import React, { useState, useEffect } from 'react';
import authFetch from '../../utils/authFetch.js';
-
function CollegeOnboarding({ nextStep, prevStep, data, setData, careerPathId }) {
// CIP / iPEDS local states (purely for CIP data and suggestions)
const [schoolData, setSchoolData] = useState([]);
@@ -11,8 +11,6 @@ function CollegeOnboarding({ nextStep, prevStep, data, setData, careerPathId })
const [availableProgramTypes, setAvailableProgramTypes] = useState([]);
// ---- DESCTRUCTURE PARENT DATA FOR ALL FIELDS EXCEPT TUITION/PROGRAM_LENGTH ----
- // We'll store user "typed" values for tuition/program_length in local states,
- // but everything else comes directly from `data`.
const {
college_enrollment_status = '',
selected_school = '',
@@ -34,59 +32,42 @@ function CollegeOnboarding({ nextStep, prevStep, data, setData, careerPathId })
hours_completed = '',
credit_hours_required = '',
tuition_paid = '',
- // We do NOT consume data.tuition or data.program_length directly here
- // because we store them in local states (manualTuition, manualProgramLength).
} = data;
// ---- 1. LOCAL STATES for auto/manual logic on TWO fields ----
- // manualTuition: user typed override
- // autoTuition: iPEDS calculation
- const [manualTuition, setManualTuition] = useState(''); // '' means no manual override
+ const [manualTuition, setManualTuition] = useState('');
const [autoTuition, setAutoTuition] = useState(0);
- // same approach for program_length
const [manualProgramLength, setManualProgramLength] = useState('');
const [autoProgramLength, setAutoProgramLength] = useState('0.00');
- // ------------------------------------------
- // Universal handleChange for all parent fields
- // ------------------------------------------
+ // -- universal handleChange for all parent fields except tuition/program_length
const handleParentFieldChange = (e) => {
const { name, value, type, checked } = e.target;
let val = value;
if (type === 'checkbox') {
val = checked;
}
- // parse numeric fields that are NOT tuition or program_length
if (['interest_rate','loan_term','extra_payment','expected_salary'].includes(name)) {
val = parseFloat(val) || 0;
} else if (
['annual_financial_aid','existing_college_debt','credit_hours_per_year',
- 'hours_completed','credit_hours_required','tuition_paid']
- .includes(name)
+ 'hours_completed','credit_hours_required','tuition_paid'].includes(name)
) {
val = val === '' ? '' : parseFloat(val);
}
-
setData(prev => ({ ...prev, [name]: val }));
};
- // ------------------------------------------
- // handleManualTuition, handleManualProgramLength
- // for local fields
- // ------------------------------------------
const handleManualTuitionChange = (e) => {
- // user typed something => override
- setManualTuition(e.target.value); // store as string for partial typing
+ setManualTuition(e.target.value);
};
const handleManualProgramLengthChange = (e) => {
setManualProgramLength(e.target.value);
};
- // ------------------------------------------
- // CIP Data fetch once
- // ------------------------------------------
+ // CIP fetch
useEffect(() => {
async function fetchCipData() {
try {
@@ -104,9 +85,7 @@ function CollegeOnboarding({ nextStep, prevStep, data, setData, careerPathId })
fetchCipData();
}, []);
- // ------------------------------------------
- // iPEDS Data fetch once
- // ------------------------------------------
+ // iPEDS fetch
useEffect(() => {
async function fetchIpedsData() {
try {
@@ -125,9 +104,7 @@ function CollegeOnboarding({ nextStep, prevStep, data, setData, careerPathId })
fetchIpedsData();
}, []);
- // ------------------------------------------
- // handleSchoolChange, handleProgramChange, etc. => update parent fields
- // ------------------------------------------
+ // handleSchoolChange
const handleSchoolChange = (e) => {
const value = e.target.value;
setData(prev => ({
@@ -137,7 +114,6 @@ function CollegeOnboarding({ nextStep, prevStep, data, setData, careerPathId })
program_type: '',
credit_hours_required: '',
}));
- // CIP suggestions
const filtered = schoolData.filter(s =>
s.INSTNM.toLowerCase().includes(value.toLowerCase())
);
@@ -163,7 +139,6 @@ function CollegeOnboarding({ nextStep, prevStep, data, setData, careerPathId })
const handleProgramChange = (e) => {
const value = e.target.value;
setData(prev => ({ ...prev, selected_program: value }));
-
if (!value) {
setProgramSuggestions([]);
return;
@@ -188,11 +163,11 @@ function CollegeOnboarding({ nextStep, prevStep, data, setData, careerPathId })
program_type: val,
credit_hours_required: '',
}));
- setManualProgramLength(''); // reset manual override
+ setManualProgramLength('');
setAutoProgramLength('0.00');
};
- // Once we have school+program, load possible program types
+ // once we have school+program, load possible program types
useEffect(() => {
if (!selected_program || !selected_school || !schoolData.length) return;
const possibleTypes = schoolData
@@ -204,15 +179,11 @@ function CollegeOnboarding({ nextStep, prevStep, data, setData, careerPathId })
setAvailableProgramTypes([...new Set(possibleTypes)]);
}, [selected_program, selected_school, schoolData]);
- // ------------------------------------------
- // Auto-calc Tuition => store in local autoTuition
- // ------------------------------------------
+ // auto-calc tuition
useEffect(() => {
- // do we have enough to calc?
if (!icTuitionData.length) return;
if (!selected_school || !program_type || !credit_hours_per_year) return;
- // find row
const found = schoolData.find(s => s.INSTNM.toLowerCase() === selected_school.toLowerCase());
if (!found) return;
const unitId = found.UNITID;
@@ -221,7 +192,6 @@ function CollegeOnboarding({ nextStep, prevStep, data, setData, careerPathId })
const match = icTuitionData.find(row => row.UNITID === unitId);
if (!match) return;
- // grad or undergrad
const isGradOrProf = [
"Master's Degree",
"Doctoral Degree",
@@ -258,7 +228,6 @@ function CollegeOnboarding({ nextStep, prevStep, data, setData, careerPathId })
const chpy = parseFloat(credit_hours_per_year) || 0;
let estimate = 0;
- // threshold
if (chpy < 24 && partTimeRate) {
estimate = partTimeRate * chpy;
} else {
@@ -266,15 +235,12 @@ function CollegeOnboarding({ nextStep, prevStep, data, setData, careerPathId })
}
setAutoTuition(Math.round(estimate));
-
}, [
icTuitionData, selected_school, program_type,
credit_hours_per_year, is_in_state, is_in_district, schoolData
]);
- // ------------------------------------------
- // Auto-calc Program Length => store in local autoProgramLength
- // ------------------------------------------
+ // auto-calc program length
useEffect(() => {
if (!program_type) return;
if (!hours_completed || !credit_hours_per_year) return;
@@ -299,264 +265,315 @@ function CollegeOnboarding({ nextStep, prevStep, data, setData, careerPathId })
setAutoProgramLength(calcLength);
}, [program_type, hours_completed, credit_hours_per_year, credit_hours_required]);
- // ------------------------------------------
- // handleSubmit => merges final chosen values
- // ------------------------------------------
+ // final handleSubmit
const handleSubmit = () => {
- const chosenTuition = manualTuition.trim() === ''
- ? autoTuition
+ const chosenTuition = manualTuition.trim() === ''
+ ? autoTuition
: parseFloat(manualTuition);
const chosenProgramLength = manualProgramLength.trim() === ''
? autoProgramLength
: manualProgramLength;
- // Update parent’s data (collegeData)
setData(prev => ({
...prev,
- tuition: chosenTuition, // match name used by parent or server
- program_length: chosenProgramLength // match name used by parent
+ tuition: chosenTuition,
+ program_length: chosenProgramLength
}));
- // Then go to the next step in the parent’s wizard
nextStep();
};
- // The displayed tuition => (manualTuition !== '' ? manualTuition : autoTuition)
const displayedTuition = (manualTuition.trim() === '' ? autoTuition : manualTuition);
-
- // The displayed program length => (manualProgramLength !== '' ? manualProgramLength : autoProgramLength)
const displayedProgramLength = (manualProgramLength.trim() === '' ? autoProgramLength : manualProgramLength);
-
return (
-
-
College Details
+
+
College Details
{(college_enrollment_status === 'currently_enrolled' ||
college_enrollment_status === 'prospective_student') ? (
- <>
-
+
) : (
Not currently enrolled or prospective student. Skipping college onboarding.
)}
- ← Previous
- Finish Onboarding
+
+
+ ← Previous
+
+
+ Finish Onboarding
+
+
);
}
diff --git a/src/components/PremiumOnboarding/FinancialOnboarding.js b/src/components/PremiumOnboarding/FinancialOnboarding.js
index 6d6da21..295f8cf 100644
--- a/src/components/PremiumOnboarding/FinancialOnboarding.js
+++ b/src/components/PremiumOnboarding/FinancialOnboarding.js
@@ -1,3 +1,4 @@
+// FinancialOnboarding.js
import React from 'react';
const FinancialOnboarding = ({ nextStep, prevStep, data, setData, isEditMode = false }) => {
@@ -13,7 +14,6 @@ const FinancialOnboarding = ({ nextStep, prevStep, data, setData, isEditMode = f
emergency_contribution = 0,
extra_cash_emergency_pct = "",
extra_cash_retirement_pct = "",
-
planned_monthly_expenses = '',
planned_monthly_debt_payments = '',
planned_monthly_retirement_contribution = '',
@@ -22,7 +22,7 @@ const FinancialOnboarding = ({ nextStep, prevStep, data, setData, isEditMode = f
planned_surplus_retirement_pct = '',
planned_additional_income = ''
} = data;
-
+
const handleChange = (e) => {
const { name, value } = e.target;
let val = parseFloat(value) || 0;
@@ -42,172 +42,250 @@ const FinancialOnboarding = ({ nextStep, prevStep, data, setData, isEditMode = f
extra_cash_emergency_pct: 100 - val
}));
} else {
- setData(prevData => ({
- ...prevData,
- [name]: val
- }));
+ setData(prevData => ({ ...prevData, [name]: val }));
}
};
return (
-
-
Financial Details
+
+
Financial Details
{currently_working === 'yes' && (
- <>
-
+
)}
-
-
-
-
-
-
-
-
-
-
-
-
-
Extra Monthly Cash Allocation
-
If you have extra money left each month after expenses, how would you like to allocate it? (Must add to 100%)
-
-
Extra Monthly Cash to Emergency Fund (%)
-
-
-
Extra Monthly Cash to Retirement Fund (%)
-
-
-{/* Only show the planned overrides if isEditMode is true */}
-{isEditMode && (
- <>
-
-
Planned Scenario Overrides
-
These fields let you override your real finances for this scenario.
-
-
Planned Monthly Expenses
+
+
+ Monthly Expenses
+
-
Planned Monthly Debt Payments
+
+ Monthly Debt Payments (optional)
+
-
Planned Monthly Retirement Contribution
+
+ Retirement Savings
+
-
Planned Monthly Emergency Contribution
+
+ Monthly Retirement Contribution
+
-
Planned Surplus % to Emergency
+
+ Emergency Fund Savings
+
-
Planned Surplus % to Retirement
+
+ Monthly Emergency Fund Contribution
+
+
-
Planned Additional Annual Income
+
+
Extra Monthly Cash Allocation
+
+ If you have extra money left each month after expenses, how would you like to allocate it?
+ (Must add to 100%)
+
+
+
+ Extra Monthly Cash to Emergency Fund (%)
- >
+
+
+
+ Extra Monthly Cash to Retirement Fund (%)
+
+
+
+
+ {/* Only show the planned overrides if isEditMode is true */}
+ {isEditMode && (
+
)}
-
← Previous: Career
-
Next: College →
+
+
+
+ ← Previous: Career
+
+
+ Next: College →
+
+
);
};
diff --git a/src/components/PremiumOnboarding/PremiumWelcome.js b/src/components/PremiumOnboarding/PremiumWelcome.js
index c5fdbc6..98a7f8d 100644
--- a/src/components/PremiumOnboarding/PremiumWelcome.js
+++ b/src/components/PremiumOnboarding/PremiumWelcome.js
@@ -2,12 +2,17 @@
import React from 'react';
const PremiumWelcome = ({ nextStep }) => (
-
-
Welcome to AptivaAI Premium!
-
+
+
Welcome to AptivaAI Premium!
+
Let's get started by gathering some quick information to personalize your experience.
-
Get Started
+
+ Get Started
+
);