Added data flow fixes for Confirm Career Selection button and rendering logic fix
This commit is contained in:
parent
b3ff06c0fc
commit
dd1d6bec88
@ -1,13 +1,14 @@
|
||||
import React, { useState, useEffect } from "react";
|
||||
import { Input } from "./ui/input.js"; // Assuming Input is a basic text input component
|
||||
|
||||
const CareerSearch = ({ onSelectCareer, initialCareer }) => {
|
||||
const CareerSearch = ({ onSelectCareer, existingCareerPaths }) => {
|
||||
const [careerClusters, setCareerClusters] = useState({});
|
||||
const [selectedCluster, setSelectedCluster] = useState("");
|
||||
const [selectedSubdivision, setSelectedSubdivision] = useState("");
|
||||
const [selectedCareer, setSelectedCareer] = useState("");
|
||||
const [careerSearch, setCareerSearch] = useState("");
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
const fetchCareerClusters = async () => {
|
||||
try {
|
||||
@ -62,6 +63,12 @@ const CareerSearch = ({ onSelectCareer, initialCareer }) => {
|
||||
// Get careers based on selected subdivision
|
||||
const careers = selectedSubdivision ? careerClusters[selectedCluster]?.[selectedSubdivision] || [] : [];
|
||||
|
||||
// Check if the selected career already has an existing career path
|
||||
const hasCareerPath = existingCareerPaths.some(career => career.title === selectedCareer);
|
||||
|
||||
// Check if the selected career is the current one
|
||||
const isCurrentCareer = selectedCareer === selectedCareer?.career_name;
|
||||
|
||||
return (
|
||||
<div>
|
||||
{/* Career Cluster Selection */}
|
||||
@ -119,8 +126,35 @@ const CareerSearch = ({ onSelectCareer, initialCareer }) => {
|
||||
)}
|
||||
|
||||
{/* Display selected career */}
|
||||
{selectedCareer && <div>Selected Career: {selectedCareer}</div>}
|
||||
{selectedCareer && (
|
||||
<div style={{ marginTop: '10px' }}>
|
||||
<div>Selected Career: {selectedCareer}</div>
|
||||
{!hasCareerPath && (
|
||||
<button
|
||||
onClick={() => {
|
||||
const matchedCareer = careers.find(
|
||||
(c) => c.title.toLowerCase() === selectedCareer.toLowerCase()
|
||||
);
|
||||
if (matchedCareer) {
|
||||
onSelectCareer(matchedCareer.title, matchedCareer.soc); // 🔥 this triggers the update upstream
|
||||
} else {
|
||||
alert("Please select a valid career from the list.");
|
||||
}
|
||||
}}
|
||||
>
|
||||
Confirm Career Selection
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
{hasCareerPath && (
|
||||
<p>This career already has a career path. Do you want to reload it or create a new one?</p>
|
||||
)}
|
||||
{isCurrentCareer && (
|
||||
<p>You are already on this career path.</p>
|
||||
)}
|
||||
</div>
|
||||
|
||||
);
|
||||
};
|
||||
|
||||
|
@ -38,7 +38,7 @@ function GettingStarted() {
|
||||
<div className="premium-access">
|
||||
<h3>Already know your path?</h3>
|
||||
<p>You can skip ahead and begin planning your milestones now.</p>
|
||||
<button className="premium-button" onClick={() => navigate('/milestone-tracker')}>
|
||||
<button className="premium-button" onClick={() => navigate('/milestone-tracker', { state: { fromGettingStarted: true } })}>
|
||||
Access Milestone Tracker <span className="premium-label">(Premium)</span>
|
||||
</button>
|
||||
</div>
|
||||
|
@ -31,6 +31,9 @@ const MilestoneTracker = ({ selectedCareer: initialCareer, careerClusters }) =>
|
||||
const [careerSubdivision, setCareerSubdivision] = useState('');
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [sessionHandled, setSessionHandled] = useState(false);
|
||||
const [hasHandledCareerPath, setHasHandledCareerPath] = useState(false);
|
||||
const [existingCareerPaths, setExistingCareerPaths] = useState([]); // To store existing career paths
|
||||
|
||||
|
||||
|
||||
const handleUnauthorized = () => {
|
||||
@ -42,23 +45,28 @@ const MilestoneTracker = ({ selectedCareer: initialCareer, careerClusters }) =>
|
||||
const apiURL = process.env.REACT_APP_API_URL;
|
||||
|
||||
useEffect(() => {
|
||||
if (selectedCareer) {
|
||||
// First check when user navigates to this page
|
||||
handleCareerPathDecision(selectedCareer);
|
||||
}
|
||||
}, [selectedCareer]);
|
||||
const fetchExistingPaths = async () => {
|
||||
const response = await fetch('/api/career-paths'); // Replace with the actual API endpoint
|
||||
const data = await response.json();
|
||||
setExistingCareerPaths(data);
|
||||
};
|
||||
|
||||
fetchExistingPaths();
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (location.state?.selectedCareer) {
|
||||
setSelectedCareer(location.state.selectedCareer);
|
||||
setCareerPathId(location.state.selectedCareer.career_path_id);
|
||||
loadMilestonesFromServer(location.state.selectedCareer.career_path_id);
|
||||
} else {
|
||||
console.warn('No career selected; prompting user to select one.');
|
||||
setCareerPathId(null);
|
||||
const fromState = location.state?.selectedCareer;
|
||||
|
||||
if (fromState && !hasHandledCareerPath) {
|
||||
setSelectedCareer(fromState);
|
||||
setCareerPathId(fromState.career_path_id);
|
||||
loadMilestonesFromServer(fromState.career_path_id);
|
||||
handleCareerPathDecision(fromState.career_name);
|
||||
setHasHandledCareerPath(true);
|
||||
}
|
||||
}, [location.state]);
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
loadMilestonesFromServer();
|
||||
}, [selectedCareer]);
|
||||
@ -85,17 +93,19 @@ const MilestoneTracker = ({ selectedCareer: initialCareer, careerClusters }) =>
|
||||
})
|
||||
|
||||
.then(data => {
|
||||
if (data && data.id) {
|
||||
if (!location.state?.selectedCareer && data && data.id) {
|
||||
setCareerPathId(data.id);
|
||||
} else {
|
||||
setCareerPathId(null); // No existing career path for new user
|
||||
setSelectedCareer({
|
||||
career_name: data.career_name,
|
||||
career_path_id: data.id,
|
||||
});
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error("Could not fetch latest career path:", error);
|
||||
setCareerPathId(null);
|
||||
});
|
||||
}, []);
|
||||
}, []);
|
||||
|
||||
const authFetch = async (url, options = {}) => {
|
||||
const token = localStorage.getItem("token");
|
||||
@ -129,8 +139,11 @@ const MilestoneTracker = ({ selectedCareer: initialCareer, careerClusters }) =>
|
||||
};
|
||||
|
||||
const handleCareerPathDecision = async (careerName) => {
|
||||
if (hasHandledCareerPath || !careerName || careerName === 'Not Selected') return; // ✅ already processed, do nothing
|
||||
setHasHandledCareerPath(true); // ✅ prevent duplicate handling
|
||||
setLoading(true);
|
||||
const token = localStorage.getItem('token');
|
||||
|
||||
const response = await authFetch('/api/premium/planned-path', {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({ career_name: careerName }),
|
||||
@ -142,6 +155,8 @@ const MilestoneTracker = ({ selectedCareer: initialCareer, careerClusters }) =>
|
||||
const data = await response.json();
|
||||
setLoading(false);
|
||||
|
||||
const fromGettingStarted = location?.state?.fromGettingStarted;
|
||||
|
||||
if (data.action_required === 'reload_or_create') {
|
||||
const decision = window.confirm( `A career path for "${data.title}" already exists.\n\nClick OK to RELOAD the existing path.\nClick Cancel to CREATE a new one.`);
|
||||
|
||||
@ -153,8 +168,12 @@ const MilestoneTracker = ({ selectedCareer: initialCareer, careerClusters }) =>
|
||||
} else if (data.action_required === 'new_created') {
|
||||
setCareerPathId(data.career_path_id);
|
||||
}
|
||||
if (fromGettingStarted) {
|
||||
navigate(location.pathname, { replace: true, state: {} }); // clear state
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
const reloadExistingCareerPath = (careerPathId) => {
|
||||
console.log('Reloading career path with ID:', careerPathId);
|
||||
setCareerPathId(careerPathId);
|
||||
@ -217,26 +236,9 @@ const MilestoneTracker = ({ selectedCareer: initialCareer, careerClusters }) =>
|
||||
useEffect(() => {
|
||||
if (selectedCareer) {
|
||||
fetchAISuggestedMilestones(selectedCareer?.career_name);
|
||||
prepopulateCareerFields(selectedCareer?.career_name);
|
||||
|
||||
}
|
||||
}, [selectedCareer]);
|
||||
|
||||
const prepopulateCareerFields = (career) => {
|
||||
if (!careerClusters) return;
|
||||
for (const cluster in careerClusters) {
|
||||
for (const subdivision in careerClusters[cluster]) {
|
||||
if (careerClusters[cluster][subdivision].some(job => job.title === career)) {
|
||||
setCareerCluster(cluster);
|
||||
setCareerSubdivision(subdivision);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
setCareerCluster('');
|
||||
setCareerSubdivision('');
|
||||
};
|
||||
|
||||
const handleAddMilestone = async () => {
|
||||
if (!careerPathId) {
|
||||
console.error('No career_path_id available for milestone.');
|
||||
@ -328,7 +330,6 @@ const MilestoneTracker = ({ selectedCareer: initialCareer, careerClusters }) =>
|
||||
const handleCareerSelection = async (career, socCode) => {
|
||||
setSelectedCareer(career);
|
||||
setSelectedSocCode(socCode);
|
||||
prepopulateCareerFields(career);
|
||||
|
||||
const token = localStorage.getItem('token');
|
||||
try {
|
||||
@ -559,17 +560,19 @@ const MilestoneTracker = ({ selectedCareer: initialCareer, careerClusters }) =>
|
||||
<p>Not sure about this career path? Choose a different one here.</p>
|
||||
<CareerSearch
|
||||
onSelectCareer={handleCareerSelection}
|
||||
existingCareerPaths={existingCareerPaths}
|
||||
initialCareer={selectedCareer}
|
||||
cluster={careerCluster}
|
||||
subdivision={careerSubdivision}
|
||||
/>
|
||||
|
||||
{selectedCareer && !careerPathId && (
|
||||
{selectedCareer && (
|
||||
<>
|
||||
{selectedCareer !== selectedCareer?.career_name && (
|
||||
<button onClick={() => setShowModal(true)} style={{ marginTop: '10px' }}>
|
||||
Confirm Career Selection
|
||||
</button>
|
||||
|
||||
)}
|
||||
{showModal && (
|
||||
<div className="modal-overlay">
|
||||
<div className="modal">
|
||||
|
BIN
user_profile.db
BIN
user_profile.db
Binary file not shown.
Loading…
Reference in New Issue
Block a user