From dd1d6bec889ebb71f3319a3a72b5061b8ec0f7b8 Mon Sep 17 00:00:00 2001 From: Josh Date: Tue, 25 Mar 2025 15:55:30 +0000 Subject: [PATCH] Added data flow fixes for Confirm Career Selection button and rendering logic fix --- src/components/CareerSearch.js | 40 +++++++++++++-- src/components/GettingStarted.js | 2 +- src/components/MilestoneTracker.js | 77 +++++++++++++++-------------- user_profile.db | Bin 53248 -> 53248 bytes 4 files changed, 78 insertions(+), 41 deletions(-) diff --git a/src/components/CareerSearch.js b/src/components/CareerSearch.js index b14b715..ec8eb3c 100644 --- a/src/components/CareerSearch.js +++ b/src/components/CareerSearch.js @@ -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 (
{/* Career Cluster Selection */} @@ -118,9 +125,36 @@ const CareerSearch = ({ onSelectCareer, initialCareer }) => {
)} - {/* Display selected career */} - {selectedCareer &&
Selected Career: {selectedCareer}
} + {/* Display selected career */} + {selectedCareer && ( +
+
Selected Career: {selectedCareer}
+ {!hasCareerPath && ( + + )} +
+ )} + {hasCareerPath && ( +

This career already has a career path. Do you want to reload it or create a new one?

+ )} + {isCurrentCareer && ( +

You are already on this career path.

+ )} + ); }; diff --git a/src/components/GettingStarted.js b/src/components/GettingStarted.js index 1dcffca..6eca2f5 100644 --- a/src/components/GettingStarted.js +++ b/src/components/GettingStarted.js @@ -38,7 +38,7 @@ function GettingStarted() {

Already know your path?

You can skip ahead and begin planning your milestones now.

-
diff --git a/src/components/MilestoneTracker.js b/src/components/MilestoneTracker.js index d5d12f8..f745d7c 100644 --- a/src/components/MilestoneTracker.js +++ b/src/components/MilestoneTracker.js @@ -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,22 +45,27 @@ 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(); @@ -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 { @@ -558,18 +559,20 @@ const MilestoneTracker = ({ selectedCareer: initialCareer, careerClusters }) =>

Not sure about this career path? Choose a different one here.

- {selectedCareer && !careerPathId && ( + {selectedCareer && ( <> + {selectedCareer !== selectedCareer?.career_name && ( - + )} {showModal && (
diff --git a/user_profile.db b/user_profile.db index 7f48a8f0f8b32723efe7eb46248eb5cd82bb3854..ac1c9fcc83064503d4c313058ed927dc778963cb 100644 GIT binary patch delta 940 zcmZozz}&Ead4e>f(?l6(MyHJl+4hVQo6p!=1W0i4Ol9C-$sfee%Xfk=m5+&cKCcjV+9g zj1xJPoO1G$vy(FtGxHQ&^U^c(Qd5hH9g|Bk%TkRDj7)V6jCGAnH@}!8!_2|Om(IX9 zfiHbC*Mexi$rIMGs1joX*X9Z9N(3diSX3DJ7V{qFS<4;5Uc#}D%ZV+3)rLg{=w=QU zfhJK2eg-DVRK-w+RB47r&&h?wN>12ZW@KP&ple_VM8w!VdBGludThoN