Fixed staging handlecareerclick. .pems are in this one
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
This commit is contained in:
parent
d5d3c6d63b
commit
1e039bf454
0
client-cert.pem
Normal file
0
client-cert.pem
Normal file
0
client-key.pem
Normal file
0
client-key.pem
Normal file
@ -339,59 +339,69 @@ function CareerExplorer() {
|
|||||||
}
|
}
|
||||||
}, [location.state, userProfile, fetchSuggestions, navigate]);
|
}, [location.state, userProfile, fetchSuggestions, navigate]);
|
||||||
|
|
||||||
/* ------------------------------------------------------
|
// ------------------------------------------------------
|
||||||
handleCareerClick – fetches all details for one career
|
// handleCareerClick – fetch & build data for one career
|
||||||
---------------------------------------------------- */
|
// ------------------------------------------------------
|
||||||
const handleCareerClick = useCallback(
|
const handleCareerClick = useCallback(
|
||||||
async (career) => {
|
async (career) => {
|
||||||
const socCode = career.code;
|
const socCode = career.code;
|
||||||
if (!socCode) return;
|
if (!socCode) return;
|
||||||
|
|
||||||
|
/* Reset modal state & show spinner */
|
||||||
setSelectedCareer(career);
|
setSelectedCareer(career);
|
||||||
setCareerDetails(null); // reset any previous modal
|
setCareerDetails(null);
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
/* ---------- 1. CIP lookup ---------- */
|
/* ---------- 1. CIP lookup ---------- */
|
||||||
let cipCode = null;
|
let cipCode = null;
|
||||||
const cipRes = await fetch(`/api/cip/${socCode}`);
|
try {
|
||||||
if (cipRes.ok) {
|
const cipRes = await fetch(`/api/cip/${socCode}`);
|
||||||
cipCode = (await cipRes.json()).cipCode ?? null;
|
if (cipRes.ok) {
|
||||||
}
|
cipCode = (await cipRes.json()).cipCode ?? null;
|
||||||
|
}
|
||||||
|
} catch { /* swallow */ }
|
||||||
|
|
||||||
/* ---------- 2. Job description & tasks ---------- */
|
/* ---------- 2. Job description & tasks ---------- */
|
||||||
let description = '';
|
let description = '';
|
||||||
let tasks = [];
|
let tasks = [];
|
||||||
const jobRes = await fetch(`/api/onet/career-description/${socCode}`);
|
try {
|
||||||
if (jobRes.ok) {
|
const jobRes = await fetch(`/api/onet/career-description/${socCode}`);
|
||||||
const jd = await jobRes.json();
|
if (jobRes.ok) {
|
||||||
description = jd.description ?? '';
|
const jd = await jobRes.json();
|
||||||
tasks = jd.tasks ?? [];
|
description = jd.description ?? '';
|
||||||
}
|
tasks = jd.tasks ?? [];
|
||||||
|
}
|
||||||
|
} catch { /* swallow */ }
|
||||||
|
|
||||||
/* ---------- 3. Salary data ---------- */
|
/* ---------- 3. Salary data ---------- */
|
||||||
const salaryRes = await axios.get('/api/salary', {
|
const salaryRes = await axios
|
||||||
params: { socCode: socCode.split('.')[0], area: areaTitle },
|
.get('/api/salary', {
|
||||||
}).catch(() => ({ data: {} }));
|
params: { socCode: socCode.split('.')[0], area: areaTitle },
|
||||||
|
})
|
||||||
|
.catch(() => ({ data: {} }));
|
||||||
|
|
||||||
const s = salaryRes.data;
|
const s = salaryRes.data;
|
||||||
const salaryDataPoints = s && Object.keys(s).length > 0 ? [
|
const salaryData = s && Object.keys(s).length
|
||||||
{ percentile: '10th Percentile', regionalSalary: +s.regional?.regional_PCT10 || 0, nationalSalary: +s.national?.national_PCT10 || 0 },
|
? [
|
||||||
{ percentile: '25th Percentile', regionalSalary: +s.regional?.regional_PCT25 || 0, nationalSalary: +s.national?.national_PCT25 || 0 },
|
{ percentile: '10th Percentile', regionalSalary: +s.regional?.regional_PCT10 || 0, nationalSalary: +s.national?.national_PCT10 || 0 },
|
||||||
{ percentile: 'Median', regionalSalary: +s.regional?.regional_MEDIAN || 0, nationalSalary: +s.national?.national_MEDIAN || 0 },
|
{ percentile: '25th Percentile', regionalSalary: +s.regional?.regional_PCT25 || 0, nationalSalary: +s.national?.national_PCT25 || 0 },
|
||||||
{ percentile: '75th Percentile', regionalSalary: +s.regional?.regional_PCT75 || 0, nationalSalary: +s.national?.national_PCT75 || 0 },
|
{ percentile: 'Median', regionalSalary: +s.regional?.regional_MEDIAN || 0, nationalSalary: +s.national?.national_MEDIAN || 0 },
|
||||||
{ percentile: '90th Percentile', regionalSalary: +s.regional?.regional_PCT90 || 0, nationalSalary: +s.national?.national_PCT90 || 0 },
|
{ percentile: '75th Percentile', regionalSalary: +s.regional?.regional_PCT75 || 0, nationalSalary: +s.national?.national_PCT75 || 0 },
|
||||||
] : [];
|
{ percentile: '90th Percentile', regionalSalary: +s.regional?.regional_PCT90 || 0, nationalSalary: +s.national?.national_PCT90 || 0 },
|
||||||
|
]
|
||||||
|
: [];
|
||||||
|
|
||||||
/* ---------- 4. Economic projections ---------- */
|
/* ---------- 4. Economic projections ---------- */
|
||||||
const fullStateName = getFullStateName(userState);
|
const fullStateName = getFullStateName(userState);
|
||||||
const projRes = await axios.get(
|
const projRes = await axios
|
||||||
`/api/projections/${socCode.split('.')[0]}`,
|
.get(`/api/projections/${socCode.split('.')[0]}`, {
|
||||||
{ params: { state: fullStateName } }
|
params: { state: fullStateName },
|
||||||
).catch(() => ({ data: {} }));
|
})
|
||||||
|
.catch(() => ({ data: {} }));
|
||||||
|
|
||||||
/* ---------- 5. Decide if we actually have data ---------- */
|
/* ---------- 5. Do we have *anything* useful? ---------- */
|
||||||
const haveSalary = salaryDataPoints.length > 0;
|
const haveSalary = salaryData.length > 0;
|
||||||
const haveProj = !!(projRes.data.state || projRes.data.national);
|
const haveProj = !!(projRes.data.state || projRes.data.national);
|
||||||
const haveJobInfo = description || tasks.length > 0;
|
const haveJobInfo = description || tasks.length > 0;
|
||||||
|
|
||||||
@ -399,43 +409,43 @@ const handleCareerClick = useCallback(
|
|||||||
setCareerDetails({
|
setCareerDetails({
|
||||||
error: `We're sorry, but detailed info for "${career.title}" isn't available right now.`,
|
error: `We're sorry, but detailed info for "${career.title}" isn't available right now.`,
|
||||||
});
|
});
|
||||||
return; // stops here – nothing useful to show
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ---------- 6. AI‑risk (only if job details exist) ---------- */
|
/* ---------- 6. AI‑risk (only if job‑info exists) ---------- */
|
||||||
let aiRisk = null;
|
let aiRisk = null;
|
||||||
if (haveJobInfo) {
|
if (haveJobInfo) {
|
||||||
try {
|
try {
|
||||||
aiRisk = (await axios.get(`/api/ai-risk/${socCode}`)).data;
|
aiRisk = (await axios.get(`/api/ai-risk/${socCode}`)).data;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
if (err.response?.status === 404) {
|
if (err.response?.status === 404) {
|
||||||
const aiRes = await axios.post('/api/public/ai-risk-analysis', {
|
try {
|
||||||
socCode,
|
const aiRes = await axios.post('/api/public/ai-risk-analysis', {
|
||||||
careerName : career.title,
|
socCode,
|
||||||
jobDescription : description,
|
careerName: career.title,
|
||||||
tasks,
|
jobDescription: description,
|
||||||
});
|
tasks,
|
||||||
aiRisk = aiRes.data;
|
});
|
||||||
// store for next time (best‑effort)
|
aiRisk = aiRes.data;
|
||||||
axios.post('/api/ai-risk', aiRisk).catch(() => {});
|
// cache for next time (best‑effort)
|
||||||
|
axios.post('/api/ai-risk', aiRisk).catch(() => {});
|
||||||
|
} catch { /* GPT fallback failed – ignore */ }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ---------- 7. Build the final object & show modal ---------- */
|
/* ---------- 7. Build & show modal ---------- */
|
||||||
const updatedCareerDetails = {
|
setCareerDetails({
|
||||||
...career,
|
...career,
|
||||||
cipCode, // may be null – EducationalPrograms handles it
|
cipCode, // may be null – downstream handles it
|
||||||
jobDescription: description,
|
jobDescription: description,
|
||||||
tasks,
|
tasks,
|
||||||
salaryData: salaryDataPoints,
|
salaryData,
|
||||||
economicProjections: projRes.data ?? {},
|
economicProjections: projRes.data ?? {},
|
||||||
aiRisk,
|
aiRisk, // can be null
|
||||||
};
|
});
|
||||||
|
} catch (fatal) {
|
||||||
setCareerDetails(updatedCareerDetails);
|
console.error('[handleCareerClick] fatal:', fatal);
|
||||||
} catch (e) {
|
|
||||||
console.error('[handleCareerClick] fatal:', e);
|
|
||||||
setCareerDetails({
|
setCareerDetails({
|
||||||
error: `We're sorry, but detailed info for "${career.title}" isn't available right now.`,
|
error: `We're sorry, but detailed info for "${career.title}" isn't available right now.`,
|
||||||
});
|
});
|
||||||
@ -446,7 +456,6 @@ const handleCareerClick = useCallback(
|
|||||||
[areaTitle, userState]
|
[areaTitle, userState]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------
|
// ------------------------------------------------------
|
||||||
// handleCareerFromSearch
|
// handleCareerFromSearch
|
||||||
// ------------------------------------------------------
|
// ------------------------------------------------------
|
||||||
|
Loading…
Reference in New Issue
Block a user