import { ClipLoader } from 'react-spinners'; import LoanRepayment from './LoanRepayment.js'; import SchoolFilters from './SchoolFilters'; import './PopoutPanel.css'; import { useState, useEffect } from 'react'; function PopoutPanel({ isVisible, data = {}, userState = 'N/A', // Passed explicitly from Dashboard loading = false, error = null, closePanel, updateChatbotContext, }) { const [isCalculated, setIsCalculated] = useState(false); const [results, setResults] = useState([]); // Store loan repayment calculation results const [loadingCalculation, setLoadingCalculation] = useState(false); const [persistedROI, setPersistedROI] = useState({}); const [programLengths, setProgramLengths] = useState([]); const [sortBy, setSortBy] = useState('tuition'); // Default sorting const [maxTuition, setMaxTuition] = useState(50000); // Set default max tuition value const [maxDistance, setMaxDistance] = useState(200); // Set default max distance value const { jobDescription = null, tasks = null, title = 'Career Details', economicProjections = {}, salaryData = [], schools = [], } = data || {}; useEffect(() => { setResults([]); setIsCalculated(false); }, [sortBy, maxTuition, maxDistance]); // Ensure no other dependencies! useEffect(() => { setProgramLengths(schools.map(school => getProgramLength(school['CREDDESC']))); }, [schools]); useEffect(() => { console.log("📩 Updating Chatbot Context from PopoutPanel:", data); if (data && Object.keys(data).length > 0) { updateChatbotContext({ careerDetails: data, schools, salaryData, economicProjections, results, persistedROI, // ✅ Make sure ROI is included! }); } else { console.log("⚠️ No valid PopoutPanel data to update chatbot context."); } }, [data, schools, salaryData, economicProjections, results, persistedROI, updateChatbotContext]); if (!isVisible) return null; if (loading || loadingCalculation) { return (

Loading Career Details...

); } // Get program length for calculating tuition const getProgramLength = (degreeType) => { if (degreeType?.includes("Associate")) return 2; if (degreeType?.includes("Bachelor")) return 4; if (degreeType?.includes("Master")) return 6; if (degreeType?.includes("Doctoral") || degreeType?.includes("First Professional")) return 8; if (degreeType?.includes("Certificate")) return 1; return 4; // Default to 4 years if unspecified }; function handleClosePanel() { setResults([]); // Clear only LoanRepayment results setIsCalculated(false); // Reset calculation state closePanel(); // Maintain existing close behavior } /** 🔹 Apply Sorting & Filtering Directly at Render Time **/ const filteredAndSortedSchools = [...schools] .filter(school => { const inStateCost = parseFloat(school['In_state cost']); const distance = parseFloat(school['distance'].replace(' mi', '')); return ( inStateCost <= maxTuition && distance <= maxDistance ); }) .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 (
{/* Header with Close & Plan My Path Buttons */}

{title}

{/* Job Description and Tasks */}

Job Description

{jobDescription || 'No description available'}

Expected Tasks

{tasks && tasks.length > 0 ? ( ) : (

No tasks available for this career path.

)}
{/* Economic Projections */}

Economic Projections for {userState}

{economicProjections && typeof economicProjections === 'object' ? ( ) : (

No economic projections available for this career path.

)}
{/* Salary Data Points */}

Salary Data

{salaryData.length > 0 ? ( {salaryData.map((point, index) => ( ))}
Percentile Regional Salary US Salary
{point.percentile} {point.regionalSalary > 0 ? `$${parseInt(point.regionalSalary, 10).toLocaleString()}` : 'N/A'} {point.nationalSalary > 0 ? `$${parseInt(point.nationalSalary, 10).toLocaleString()}` : 'N/A'}
) : (

Salary data is not available.

)}
{/* Schools Offering Programs Section */}

Schools Offering Programs

{/* Header and Filters - Not part of grid */}
{filteredAndSortedSchools.length > 0 ? ( filteredAndSortedSchools.map((school, index) => (
{school['INSTNM']}
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']}
)) ) : (

No schools of higher education are available in your state for this career path.

)}
{/* Loan Repayment Analysis */}

Loan Repayment Analysis

({ schoolName: school['INSTNM'], inState: parseFloat(school['In_state cost']) || 0, outOfState: parseFloat(school['Out_state cost']) || 0, inStateGraduate: parseFloat(school['In State Graduate']) || parseFloat(school['In_state cost']) || 0, outStateGraduate: parseFloat(school['Out State Graduate']) || parseFloat(school['Out_state cost']) || 0, degreeType: school['CREDDESC'], programLength: programLengths[index], }))} salaryData={salaryData} setResults={setResults} setLoading={setLoadingCalculation} setPersistedROI={setPersistedROI} // ✅ Store ROI after calculation /> {/* Results Display */} {results.length > 0 && (

Comparisons by School over the life of the loan

{results.map((result, index) => (

{result.schoolName} - {result.degreeType || 'Degree type not available'}

Total Tuition: ${result.totalTuition}

Monthly Payment: ${result.monthlyPayment}

Total Monthly Payment (with extra): ${result.totalMonthlyPayment}

Total Loan Cost: ${result.totalLoanCost}

Net Gain: ${result.netGain}

Monthly Salary (Gross): ${result.monthlySalary}

))}
)}
); } export default PopoutPanel;