Tuition calculation fixed for suggested calculated with manual override.

This commit is contained in:
Josh 2025-04-04 13:25:48 +00:00
parent 5a5f2068d9
commit 8acd60c57b
3 changed files with 3940 additions and 10 deletions

3826
public/ic2023_ay.csv Normal file

File diff suppressed because it is too large Load Diff

View File

@ -26,6 +26,7 @@ function FinancialProfileForm() {
const [creditHoursPerYear, setCreditHoursPerYear] = useState("");
const [programType, setProgramType] = useState("");
const [isFullyOnline, setIsFullyOnline] = useState(false);
const [isInState, setIsInState] = useState(true);
const [selectedSchool, setSelectedSchool] = useState("");
const [selectedProgram, setSelectedProgram] = useState("");
const [manualTuition, setManualTuition] = useState("");
@ -34,7 +35,82 @@ function FinancialProfileForm() {
const [schoolSuggestions, setSchoolSuggestions] = useState([]);
const [programSuggestions, setProgramSuggestions] = useState([]);
const [availableProgramTypes, setAvailableProgramTypes] = useState([]);
const [icTuitionData, setIcTuitionData] = useState([]);
const [calculatedTuition, setCalculatedTuition] = useState(0);
const [selectedSchoolUnitId, setSelectedSchoolUnitId] = useState(null);
useEffect(() => {
async function fetchRawTuitionData() {
const res = await fetch("/ic2023_ay.csv");
const text = await res.text();
const rows = text.split("\n").map(line => line.split(','));
const headers = rows[0];
const data = rows.slice(1).map(row => Object.fromEntries(row.map((val, idx) => [headers[idx], val])));
setIcTuitionData(data);
}
fetchRawTuitionData();
}, []);
useEffect(() => {
if (selectedSchool && schoolData.length > 0) {
const school = schoolData.find(school => school.INSTNM.toLowerCase() === selectedSchool.toLowerCase());
if (school) {
setSelectedSchoolUnitId(school.UNITID); // Set UNITID for the school
}
}
}, [selectedSchool, schoolData]);
useEffect(() => {
async function fetchRawTuitionData() {
const res = await fetch("/ic2023_ay.csv");
const text = await res.text();
const rows = text.split("\n").map(line => line.split(','));
const headers = rows[0];
const data = rows.slice(1).map(row => Object.fromEntries(row.map((val, idx) => [headers[idx], val])));
setIcTuitionData(data);
}
fetchRawTuitionData();
}, []);
useEffect(() => {
if (selectedSchool && programType && creditHoursPerYear && icTuitionData.length > 0) {
// Find the selected school from tuition data
const schoolMatch = icTuitionData.find(row => row.UNITID === selectedSchoolUnitId); // Use UNITID for matching
if (!schoolMatch) return;
// Set tuition based on the users in-state vs out-of-state status
const partTimeRate = isInState
? parseFloat(schoolMatch.HRCHG1 || 0) // Use HRCHG1 for in-state part-time tuition
: parseFloat(schoolMatch.HRCHG2 || 0); // HRCHG2 for out-of-state part-time tuition
const fullTimeTuition = isInState
? parseFloat(schoolMatch.TUITION2 || 0) // Use TUITION2 for in-state full-time tuition
: parseFloat(schoolMatch.TUITION3 || 0); // TUITION3 for out-of-state full-time tuition
const hours = parseFloat(creditHoursPerYear);
let estimate = 0;
// Apply the logic to calculate tuition based on credit hours
if (hours && hours < 24 && partTimeRate) {
estimate = partTimeRate * hours; // Part-time tuition based on credit hours
} else {
estimate = fullTimeTuition; // Full-time tuition
}
// Set the calculated tuition
setCalculatedTuition(Math.round(estimate));
}
}, [selectedSchoolUnitId, programType, creditHoursPerYear, icTuitionData, isInState]);
// Manual override tuition
useEffect(() => {
if (manualTuition !== "") {
setCalculatedTuition(parseFloat(manualTuition)); // Override with user input
}
}, [manualTuition]);
useEffect(() => {
async function fetchSchoolData() {
@ -82,6 +158,7 @@ function FinancialProfileForm() {
setIsFullyOnline(!!data.is_fully_online);
setSelectedSchool(data.selected_school || "");
setSelectedProgram(data.selected_program || "");
}
}
} catch (err) {
@ -171,6 +248,10 @@ function FinancialProfileForm() {
setProgramType(e.target.value);
};
const handleTuitionInput = (e) => {
setManualTuition(e.target.value);
};
const handleSubmit = async (e) => {
e.preventDefault();
const formData = {
@ -191,7 +272,10 @@ function FinancialProfileForm() {
programType,
isFullyOnline,
selectedSchool,
selectedProgram
selectedProgram,
calculatedTuition,
manualTuition,
finalTuition: manualTuition || calculatedTuition
};
try {
@ -316,15 +400,35 @@ function FinancialProfileForm() {
</>
)}
<>
<label className="block font-medium">Estimated Tuition (Override if needed)</label>
<input
type="number"
value={manualTuition || calculatedTuition}
onChange={handleInput(setManualTuition)}
className="w-full border rounded p-2"
placeholder="Override tuition amount"
/>
</>
<div className="flex items-center space-x-2">
<input id="isInState" type="checkbox" checked={isInState} onChange={(e) => setIsInState(e.target.checked)} />
<label htmlFor="isInState" className="font-medium">In-State Tuition</label>
</div>
<div className="flex items-center space-x-2">
<input id="isFullyOnline" type="checkbox" checked={isFullyOnline} onChange={(e) => setIsFullyOnline(e.target.checked)} />
<label htmlFor="isFullyOnline" className="font-medium">Program is Fully Online</label>
</div>
<label className="block font-medium">Credit Hours Per Year</label>
<input
type="number"
value={creditHoursPerYear}
onChange={(e) => setCreditHoursPerYear(e.target.value)}
className="w-full border rounded p-2"
placeholder="e.g. 30"
/>
<label className="block font-medium">Calculated Yearly Tuition (override if needed)</label>
<input
type="number"
value={manualTuition || calculatedTuition}
onChange={handleTuitionInput}
className="w-full border rounded p-2"
placeholder="Override tuition amount"
/>
</>
<div className="pt-4">
<button type="submit" className="bg-blue-600 text-white px-4 py-2 rounded hover:bg-blue-700">

Binary file not shown.