import React, { useEffect, useState } from 'react'; import axios from 'axios'; import './Dashboard.css'; // or replace with Tailwind classes if desired const apiUrl = process.env.REACT_APP_API_URL || ''; export function CareerSuggestions({ careerSuggestions = [], userState, areaTitle, setLoading, setProgress, onCareerClick, }) { const [updatedCareers, setUpdatedCareers] = useState([]); useEffect(() => { // If no careers provided, stop any loading state if (!careerSuggestions || careerSuggestions.length === 0) { setLoading(false); return; } const token = localStorage.getItem('token'); const checkCareerDataAvailability = async () => { setLoading(true); setProgress(0); // Each career has 4 external calls const totalSteps = careerSuggestions.length * 4; let completedSteps = 0; // Helper function to increment the global progress const updateProgress = () => { completedSteps += 1; const percent = Math.round((completedSteps / totalSteps) * 100); setProgress(percent); }; // Universal fetch helper const fetchJSON = async (url, params) => { try { const response = await axios.get(url, { headers: { Authorization: `Bearer ${token}`, Accept: 'application/json', }, params: params || {}, }); updateProgress(); // increment if success return response.data; } catch (error) { updateProgress(); // increment even on failure return null; } }; // Map over careerSuggestions to fetch CIP, job details, economic, salary data in parallel const careerPromises = careerSuggestions.map(async (career) => { try { // e.g. "15-1199.00" => "15-1199" const strippedSoc = career.code.split('.')[0]; const [cipData, jobDetailsData, economicData, salaryData] = await Promise.all([ fetchJSON(`${apiUrl}/cip/${career.code}`), fetchJSON(`${apiUrl}/onet/career-description/${career.code}`), fetchJSON(`${apiUrl}/projections/${strippedSoc}`), fetchJSON(`${apiUrl}/salary`, { socCode: strippedSoc, area: areaTitle, }), ]); // Evaluate if any data is missing const isCipMissing = !cipData || Object.keys(cipData).length === 0; const isJobDetailsMissing = !jobDetailsData || Object.keys(jobDetailsData).length === 0; const isEconomicMissing = !economicData || Object.values(economicData).every((val) => val === 'N/A' || val === '*'); const isSalaryMissing = !salaryData; const isLimitedData = isCipMissing || isJobDetailsMissing || isEconomicMissing || isSalaryMissing; return { ...career, limitedData: isLimitedData, }; } catch (err) { // If any errors occur mid-logic, mark it limited return { ...career, limitedData: true }; } }); try { const updatedCareerList = await Promise.all(careerPromises); setUpdatedCareers(updatedCareerList); } finally { setLoading(false); } }; checkCareerDataAvailability(); }, [careerSuggestions, userState, areaTitle, setLoading, setProgress]); return (
{updatedCareers.map((career) => ( ))}
); } export default CareerSuggestions;