Added AI Risk to MilestoneTracker.js
This commit is contained in:
parent
7a31b722c5
commit
1e84c8b38a
@ -276,6 +276,9 @@ export default function MilestoneTracker({ selectedCareer: initialCareer }) {
|
|||||||
const [selectedCareer, setSelectedCareer] = useState(initialCareer || null);
|
const [selectedCareer, setSelectedCareer] = useState(initialCareer || null);
|
||||||
const [careerProfileId, setCareerProfileId] = useState(null);
|
const [careerProfileId, setCareerProfileId] = useState(null);
|
||||||
const [scenarioRow, setScenarioRow] = useState(null);
|
const [scenarioRow, setScenarioRow] = useState(null);
|
||||||
|
const [aiRisk, setAiRisk] = useState(null);
|
||||||
|
const [aiRiskLoading, setAiRiskLoading] = useState(false);
|
||||||
|
const [aiRiskError, setAiRiskError] = useState(null);
|
||||||
const [collegeProfile, setCollegeProfile] = useState(null);
|
const [collegeProfile, setCollegeProfile] = useState(null);
|
||||||
|
|
||||||
const [strippedSocCode, setStrippedSocCode] = useState(null);
|
const [strippedSocCode, setStrippedSocCode] = useState(null);
|
||||||
@ -455,6 +458,81 @@ export default function MilestoneTracker({ selectedCareer: initialCareer }) {
|
|||||||
setStrippedSocCode(stripSocCode(found.soc_code));
|
setStrippedSocCode(stripSocCode(found.soc_code));
|
||||||
}, [scenarioRow, masterCareerRatings]);
|
}, [scenarioRow, masterCareerRatings]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
// If we have no SOC code or scenarioRow is missing, reset
|
||||||
|
if (!strippedSocCode || !scenarioRow?.career_name) {
|
||||||
|
setAiRisk(null);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function fetchAiRisk() {
|
||||||
|
setAiRiskLoading(true);
|
||||||
|
setAiRiskError(null);
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 1) Attempt local DB first
|
||||||
|
const localRes = await fetch(`${apiURL}/ai-risk/${strippedSocCode}`);
|
||||||
|
if (localRes.ok) {
|
||||||
|
const localData = await localRes.json();
|
||||||
|
setAiRisk(localData);
|
||||||
|
} else if (localRes.status === 404) {
|
||||||
|
// 2) If not found => call GPT route
|
||||||
|
// We'll pass minimal data if we don't have job description or tasks
|
||||||
|
const chatPayload = {
|
||||||
|
socCode: strippedSocCode,
|
||||||
|
careerName: scenarioRow.career_name,
|
||||||
|
jobDescription: '', // or optionally fetch from O*NET / tasks
|
||||||
|
tasks: []
|
||||||
|
};
|
||||||
|
|
||||||
|
// POST to your server3 public route
|
||||||
|
const gptRes = await fetch(`${apiURL}/public/ai-risk-analysis`, {
|
||||||
|
method: 'POST',
|
||||||
|
headers: { 'Content-Type': 'application/json' },
|
||||||
|
body: JSON.stringify(chatPayload),
|
||||||
|
});
|
||||||
|
if (!gptRes.ok) {
|
||||||
|
throw new Error('GPT call failed');
|
||||||
|
}
|
||||||
|
const gptData = await gptRes.json();
|
||||||
|
|
||||||
|
// 3) Store in server2 so we skip GPT next time
|
||||||
|
await fetch(`${apiURL}/ai-risk`, {
|
||||||
|
method: 'POST',
|
||||||
|
headers: { 'Content-Type': 'application/json' },
|
||||||
|
body: JSON.stringify({
|
||||||
|
socCode: strippedSocCode,
|
||||||
|
careerName: gptData.careerName,
|
||||||
|
jobDescription: gptData.jobDescription,
|
||||||
|
tasks: gptData.tasks,
|
||||||
|
riskLevel: gptData.riskLevel,
|
||||||
|
reasoning: gptData.reasoning,
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
// 4) Set it in state
|
||||||
|
setAiRisk({
|
||||||
|
socCode: strippedSocCode,
|
||||||
|
careerName: scenarioRow.career_name,
|
||||||
|
riskLevel: gptData.riskLevel,
|
||||||
|
reasoning: gptData.reasoning
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// Some other error code
|
||||||
|
throw new Error(`AI Risk fetch error: ${localRes.status}`);
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.error('Error fetching AI risk =>', err);
|
||||||
|
setAiRiskError('Failed to load AI risk data.');
|
||||||
|
setAiRisk(null);
|
||||||
|
} finally {
|
||||||
|
setAiRiskLoading(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fetchAiRisk();
|
||||||
|
}, [strippedSocCode, scenarioRow?.career_name, apiURL]);
|
||||||
|
|
||||||
// 6) Salary
|
// 6) Salary
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!strippedSocCode) {
|
if (!strippedSocCode) {
|
||||||
@ -887,18 +965,34 @@ if (aiLoading || clickCount >= DAILY_CLICK_LIMIT) {
|
|||||||
<h2 className="text-2xl font-bold mb-4">Where Am I Now?</h2>
|
<h2 className="text-2xl font-bold mb-4">Where Am I Now?</h2>
|
||||||
|
|
||||||
{/* 1) Career */}
|
{/* 1) Career */}
|
||||||
<div className="bg-white p-4 rounded shadow mb-4 flex flex-col justify-center items-center min-h-[80px]">
|
<div className="bg-white p-4 rounded shadow mb-4 flex flex-col justify-center items-center min-h-[80px]">
|
||||||
<p>
|
|
||||||
<strong>Current Career:</strong>{' '}
|
|
||||||
{scenarioRow?.career_name || '(Select a career)'}
|
|
||||||
</p>
|
|
||||||
{yearsInCareer && (
|
|
||||||
<p>
|
<p>
|
||||||
<strong>Time in this career:</strong> {yearsInCareer}{' '}
|
<strong>Current Career:</strong>{' '}
|
||||||
{yearsInCareer === '<1' ? 'year' : 'years'}
|
{scenarioRow?.career_name || '(Select a career)'}
|
||||||
</p>
|
</p>
|
||||||
)}
|
{yearsInCareer && (
|
||||||
</div>
|
<p>
|
||||||
|
<strong>Time in this career:</strong> {yearsInCareer}{' '}
|
||||||
|
{yearsInCareer === '<1' ? 'year' : 'years'}
|
||||||
|
</p>
|
||||||
|
)}
|
||||||
|
|
||||||
|
<div className="mt-2">
|
||||||
|
{aiRiskLoading ? (
|
||||||
|
<p className="text-sm text-gray-500">Loading AI risk...</p>
|
||||||
|
) : aiRiskError ? (
|
||||||
|
<p className="text-sm text-red-500">{aiRiskError}</p>
|
||||||
|
) : aiRisk ? (
|
||||||
|
<div className="text-sm text-gray-700">
|
||||||
|
<strong>AI Risk Level:</strong> {aiRisk.riskLevel}
|
||||||
|
<br />
|
||||||
|
<em>{aiRisk.reasoning}</em>
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<p className="text-sm text-gray-500">No AI risk data available</p>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
{/* 2) Salary Benchmarks */}
|
{/* 2) Salary Benchmarks */}
|
||||||
<div className="flex flex-col md:flex-row gap-4">
|
<div className="flex flex-col md:flex-row gap-4">
|
||||||
|
BIN
user_profile.db
BIN
user_profile.db
Binary file not shown.
Loading…
Reference in New Issue
Block a user