diff --git a/src/components/LoanRepayment.js b/src/components/LoanRepayment.js
index 575f875..e6482aa 100644
--- a/src/components/LoanRepayment.js
+++ b/src/components/LoanRepayment.js
@@ -7,7 +7,7 @@ function LoanRepayment({
setResults,
setLoading,
}) {
- const [expectedSalary, setExpectedSalary] = useState('');
+ const [expectedSalary, setExpectedSalary] = useState(0);
const [tuitionType, setTuitionType] = useState('inState'); // Tuition type: inState or outOfState
const [interestRate, setInterestRate] = useState(5.5); // Interest rate
const [loanTerm, setLoanTerm] = useState(10); // Loan term in years
@@ -86,8 +86,8 @@ function LoanRepayment({
const totalLoanCost = extraMonthlyPayment * monthsWithExtra;
let salary = Number(expectedSalary) || 0;
- let netGain = 'N/A';
- let monthlySalary = 'N/A';
+ let netGain = 0;
+ let monthlySalary = 0;
if (salary > 0) {
const totalSalary = salary * loanTerm;
@@ -150,7 +150,8 @@ function LoanRepayment({
setCurrentSalary(e.target.value)}
- placeholder="Enter your current salary" />
+ placeholder="Enter your current salary"
+ />
diff --git a/src/components/PopoutPanel.css b/src/components/PopoutPanel.css
index 637c98e..b6f1899 100644
--- a/src/components/PopoutPanel.css
+++ b/src/components/PopoutPanel.css
@@ -100,40 +100,10 @@
color: #666;
}
-/* 🔹 Filter Section Styling */
-.filter-section {
- background: #f8f8f8;
- padding: 10px;
- border-radius: 5px;
- margin-bottom: 15px;
-}
-
-.filter-section h3 {
- margin-bottom: 10px;
- font-size: 16px;
-}
-
-.filter-section label {
- display: block;
- font-size: 14px;
- margin-bottom: 5px;
- font-weight: bold;
-}
-
-.filter-section input {
- width: 100%;
- padding: 5px;
- margin-bottom: 10px;
- border: 1px solid #ccc;
- border-radius: 4px;
-}
-
-.filter-section select {
- width: 100%;
- padding: 5px;
- margin-bottom: 10px;
- border: 1px solid #ccc;
- border-radius: 4px;
+.filter-controls {
+ display: flex;
+ align-items: center;
+ gap: 20px;
}
/* Schools section: Grid layout with clear separation */
diff --git a/src/components/PopoutPanel.js b/src/components/PopoutPanel.js
index 726af67..fe12602 100644
--- a/src/components/PopoutPanel.js
+++ b/src/components/PopoutPanel.js
@@ -1,5 +1,6 @@
import { ClipLoader } from 'react-spinners';
import LoanRepayment from './LoanRepayment.js';
+import SchoolFilters from './SchoolFilters';
import './PopoutPanel.css';
import { useState, useEffect } from 'react';
@@ -15,21 +16,23 @@ function PopoutPanel({
const [results, setResults] = useState([]); // Store loan repayment calculation results
const [loadingCalculation, setLoadingCalculation] = useState(false);
const [persistedROI, setPersistedROI] = useState({});
+ const [sortBy, setSortBy] = useState('tuition'); // Default sorting
+ const [tuitionRange, setTuitionRange] = useState([0, 50000]);
+ const [distanceRange, setDistanceRange] = useState([0, 200]);
const {
jobDescription = null,
tasks = null,
title = 'Career Details',
- economicProjections = {},
+ economicProjections = {},
salaryData = [],
- schools = [],
+ schools = [],
} = data || {};
useEffect(() => {
-
setResults([]);
setIsCalculated(false);
- }, [schools]);
+ }, [sortBy, tuitionRange, distanceRange]);
if (!isVisible) return null;
@@ -59,6 +62,31 @@ function PopoutPanel({
closePanel(); // Maintain existing close behavior
}
+
+ /** 🔹 Apply Sorting & Filtering Directly at Render Time **/
+ const filteredAndSortedSchools = [...schools]
+ .filter(school => {
+ // Convert tuition to a number
+ const inStateCost = parseFloat(school['In_state cost']);
+
+ // Remove " mi" from distance and convert it to a number
+ const distance = parseFloat(school['distance'].replace(' mi', ''));
+
+ console.log(`Filtering School: ${school['INSTNM']} | Tuition: ${inStateCost} | Distance: ${distance}`);
+
+ return (
+ inStateCost >= tuitionRange[0] &&
+ inStateCost <= tuitionRange[1] &&
+ distance >= distanceRange[0] &&
+ distance <= distanceRange[1]
+ );
+ })
+ .sort((a, b) => {
+ if (sortBy === 'tuition') return a['In_state cost'] - b['In_state cost'];
+ if (sortBy === 'distance') return a['distance'] - b['distance'];
+ return 0;
+ });
+
return (
@@ -124,16 +152,74 @@ function PopoutPanel({
)}
+ {/* Sorting & Filtering UI */}
+
+
+
{/* Schools Offering Programs Section */}
Schools Offering Programs
- {schools.length > 0 ? (
- schools.map((school, index) => (
+ {filteredAndSortedSchools.length > 0 ? (
+ filteredAndSortedSchools.map((school, index) => (
{school['INSTNM']}
-
Degree Type: {school['CREDDESC'] || 'Degree type information is not available for this program'}
-
In-State Tuition: ${school['In_state cost'] || 'Tuition information is not available for this school'}
-
Out-of-State Tuition: ${school['Out_state cost'] || 'Tuition information is not available for this school'}
+
Degree Type: {school['CREDDESC'] || 'Degree type not available for this program'}
+
In-State Tuition: ${school['In_state cost'] || 'Tuition not available for this school'}
+
Out-of-State Tuition: ${school['Out_state cost'] || 'Tuition not available for this school'}
Distance: {school['distance'] || 'Distance to school not available'}
Website:
{school['Website']}
@@ -148,7 +234,7 @@ function PopoutPanel({
{/* Loan Repayment Analysis */}
Loan Repayment Analysis
({
+ schools={filteredAndSortedSchools.map(school => ({
schoolName: school['INSTNM'],
inState: parseFloat(school['In_state cost']) || 0,
outOfState: parseFloat(school['Out_state cost']) || 0,
diff --git a/src/components/SchoolFilters b/src/components/SchoolFilters
new file mode 100644
index 0000000..e409bb4
--- /dev/null
+++ b/src/components/SchoolFilters
@@ -0,0 +1,115 @@
+import React, { useState } from 'react';
+import './SchoolFilters.css';
+
+function SchoolFilters({ schools, setFilteredSchools }) {
+ const [sortBy, setSortBy] = useState('tuition'); // Default: Sort by Tuition
+ const [tuitionRange, setTuitionRange] = useState([0, 50000]); // Example range
+ const [distanceRange, setDistanceRange] = useState([0, 200]); // Example range
+
+ // Sorting function
+ const sortSchools = (schools) => {
+ return [...schools].sort((a, b) => {
+ if (sortBy === 'tuition') return a.inState - b.inState;
+ if (sortBy === 'distance') return a.distance - b.distance;
+ return 0;
+ });
+ };
+
+ // Filtering function
+ const filterSchools = (schools) => {
+ return schools.filter((school) =>
+ school.inState >= tuitionRange[0] &&
+ school.inState <= tuitionRange[1] &&
+ school.distance >= distanceRange[0] &&
+ school.distance <= distanceRange[1]
+ );
+ };
+
+ // Apply sorting & filtering when values change
+ const updateFilteredSchools = () => {
+ let updatedSchools = sortSchools(schools);
+ updatedSchools = filterSchools(updatedSchools);
+ setFilteredSchools(updatedSchools);
+ };
+
+ // Effect to update results on change
+ React.useEffect(() => {
+ updateFilteredSchools();
+ }, [sortBy, tuitionRange, distanceRange, schools]);
+
+ return (
+
+ );
+}
+
+export default SchoolFilters;