import React, { useEffect, useState } from 'react'; import axios from 'axios'; import './Dashboard.css'; const apiUrl = process.env.REACT_APP_API_URL || ''; // ✅ Load API URL directly export function CareerSuggestions({ careerSuggestions = [], userState, areaTitle, onCareerClick }) { const [updatedCareers, setUpdatedCareers] = useState([]); const [loading, setLoading] = useState(true); const [progress, setProgress] = useState(0); useEffect(() => { if (!careerSuggestions || careerSuggestions.length === 0) { setLoading(false); return; } const token = localStorage.getItem('token'); // Get auth token const checkCareerDataAvailability = async () => { setLoading(true); setProgress(0); const totalSteps = careerSuggestions.length * 4; // Each career has 4 API checks let completedSteps = 0; const updateProgress = () => { completedSteps += 1; setProgress((completedSteps / totalSteps) * 100); }; const careerPromises = careerSuggestions.map(async (career) => { try { console.log(`Checking data for: ${career.title} (${career.code})`); const headers = { Authorization: `Bearer ${token}`, Accept: 'application/json', }; const fetchJSON = async (url) => { try { const response = await axios.get(url, { headers }); updateProgress(); // ✅ Update progress on success return response.data; } catch (error) { console.warn(`⚠️ Error fetching ${url}:`, error.response?.status); updateProgress(); // ✅ Update progress even if failed return null; } }; // Step 1: Fetch CIP Code const cipData = await fetchJSON(`${apiUrl}/cip/${career.code}`); const isCipMissing = !cipData || Object.keys(cipData).length === 0; // Step 2: Fetch Job Description & Tasks const jobDetailsData = await fetchJSON(`${apiUrl}/onet/career-description/${career.code}`); const isJobDetailsMissing = !jobDetailsData || Object.keys(jobDetailsData).length === 0; // Step 3: Fetch Salary & Economic Projections in Parallel const [economicData, salaryResponse] = await Promise.all([ fetchJSON(`${apiUrl}/projections/${career.code.split('.')[0]}`), axios.get(`${apiUrl}/salary`, { params: { socCode: career.code.split('.')[0], area: areaTitle }, headers, }).then((res) => { updateProgress(); return res.data; }).catch((error) => { updateProgress(); return error.response?.status === 404 ? null : error.response; }), ]); const isEconomicMissing = !economicData || Object.keys(economicData).length === 0; const isSalaryMissing = !salaryResponse; const isLimitedData = isCipMissing || isJobDetailsMissing || isEconomicMissing || isSalaryMissing; return { ...career, limitedData: isLimitedData }; } catch (error) { console.error(`Error checking API response for ${career.title}:`, error); return { ...career, limitedData: true }; } }); const updatedCareerList = await Promise.all(careerPromises); setUpdatedCareers(updatedCareerList); setLoading(false); }; checkCareerDataAvailability(); }, [careerSuggestions, apiUrl, userState, areaTitle]); return (
Loading Career Suggestions...