import React, { useState, useEffect } from 'react'; import axios from 'axios'; import { fetchSchools, clientGeocodeZip, haversineDistance} from '../utils/apiUtils.js'; const apiUrl = process.env.REACT_APP_API_URL; const STATES = [ { name: 'Alabama', code: 'AL' }, { name: 'Alaska', code: 'AK' }, { name: 'Arizona', code: 'AZ' }, { name: 'Arkansas', code: 'AR' }, { name: 'California', code: 'CA' }, { name: 'Colorado', code: 'CO' }, { name: 'Connecticut', code: 'CT' }, { name: 'Delaware', code: 'DE' }, { name: 'District of Columbia', code: 'DC' }, { name: 'Florida', code: 'FL' }, { name: 'Georgia', code: 'GA' }, { name: 'Hawaii', code: 'HI' }, { name: 'Idaho', code: 'ID' }, { name: 'Illinois', code: 'IL' }, { name: 'Indiana', code: 'IN' }, { name: 'Iowa', code: 'IA' }, { name: 'Kansas', code: 'KS' }, { name: 'Kentucky', code: 'KY' }, { name: 'Louisiana', code: 'LA' }, { name: 'Maine', code: 'ME' }, { name: 'Maryland', code: 'MD' }, { name: 'Massachusetts', code: 'MA' }, { name: 'Michigan', code: 'MI' }, { name: 'Minnesota', code: 'MN' }, { name: 'Mississippi', code: 'MS' }, { name: 'Missouri', code: 'MO' }, { name: 'Montana', code: 'MT' }, { name: 'Nebraska', code: 'NE' }, { name: 'Nevada', code: 'NV' }, { name: 'New Hampshire', code: 'NH' }, { name: 'New Jersey', code: 'NJ' }, { name: 'New Mexico', code: 'NM' }, { name: 'New York', code: 'NY' }, { name: 'North Carolina', code: 'NC' }, { name: 'North Dakota', code: 'ND' }, { name: 'Ohio', code: 'OH' }, { name: 'Oklahoma', code: 'OK' }, { name: 'Oregon', code: 'OR' }, { name: 'Pennsylvania', code: 'PA' }, { name: 'Rhode Island', code: 'RI' }, { name: 'South Carolina', code: 'SC' }, { name: 'South Dakota', code: 'SD' }, { name: 'Tennessee', code: 'TN' }, { name: 'Texas', code: 'TX' }, { name: 'Utah', code: 'UT' }, { name: 'Vermont', code: 'VT' }, { name: 'Virginia', code: 'VA' }, { name: 'Washington', code: 'WA' }, { name: 'West Virginia', code: 'WV' }, { name: 'Wisconsin', code: 'WI' }, { name: 'Wyoming', code: 'WY' }, ]; // 2) Helper to convert state code => full name function getFullStateName(code) { const found = STATES.find((s) => s.code === code?.toUpperCase()); return found ? found.name : ''; } function CareerModal({ career, userState, areaTitle, userZipcode, closeModal, addCareerToList }) { const [careerDetails, setCareerDetails] = useState(null); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); useEffect(() => { const handleCareerClick = async () => { const socCode = career.code; setLoading(true); setError(null); try { const cipResponse = await fetch(`${apiUrl}/cip/${socCode}`); if (!cipResponse.ok) throw new Error('Failed to fetch CIP Code'); const { cipCode } = await cipResponse.json(); const cleanedCipCode = cipCode.replace('.', '').slice(0, 4); const jobDetailsResponse = await fetch(`${apiUrl}/onet/career-description/${socCode}`); if (!jobDetailsResponse.ok) throw new Error('Failed to fetch job description'); const { description, tasks } = await jobDetailsResponse.json(); const salaryResponse = await axios.get(`${apiUrl}/salary`, { params: { socCode: socCode.split('.')[0], area: areaTitle }, }).catch(() => ({ data: {} })); const economicResponse = await axios.get(`${apiUrl}/projections/${socCode.split('.')[0]}`, { params: { state: getFullStateName(userState) }, }).catch(() => ({ data: {} })); const sData = salaryResponse.data || {}; const salaryDataPoints = sData && Object.keys(sData).length > 0 ? [ { percentile: '10th', regionalSalary: sData.regional?.regional_PCT10 || 0, nationalSalary: sData.national?.national_PCT10 || 0 }, { percentile: '25th', regionalSalary: sData.regional?.regional_PCT25 || 0, nationalSalary: sData.national?.national_PCT25 || 0 }, { percentile: 'Median', regionalSalary: sData.regional?.regional_MEDIAN || 0, nationalSalary: sData.national?.national_MEDIAN || 0 }, { percentile: '75th', regionalSalary: sData.regional?.regional_PCT75 || 0, nationalSalary: sData.national?.national_PCT75 || 0 }, { percentile: '90th', regionalSalary: sData.regional?.regional_PCT90 || 0, nationalSalary: sData.national?.national_PCT90 || 0 }, ] : []; setCareerDetails({ ...career, jobDescription: description, tasks, economicProjections: economicResponse.data || {}, salaryData: salaryDataPoints, }); } catch (error) { console.error(error); setError('Failed to load career details.'); } finally { setLoading(false); } }; handleCareerClick(); }, [career, userState, areaTitle, userZipcode]); if (loading) return
{careerDetails.jobDescription}
Percentile | Regional Salary | National Salary |
---|---|---|
{s.percentile} | ${s.regionalSalary.toLocaleString()} | ${s.nationalSalary.toLocaleString()} |
Region | Current Jobs | Jobs in 10 yrs | Growth % | Annual Openings |
---|---|---|---|---|
{careerDetails.economicProjections.state.area} | {careerDetails.economicProjections.state.base.toLocaleString()} | {careerDetails.economicProjections.state.projection.toLocaleString()} | {careerDetails.economicProjections.state.percentChange}% | {careerDetails.economicProjections.state.annualOpenings.toLocaleString()} |
National | {careerDetails.economicProjections.national.base.toLocaleString()} | {careerDetails.economicProjections.national.projection.toLocaleString()} | {careerDetails.economicProjections.national.percentChange}% | {careerDetails.economicProjections.national.annualOpenings.toLocaleString()} |