From 856ebd0e626a793a0f39a497b496271808de0941 Mon Sep 17 00:00:00 2001 From: Josh Date: Thu, 8 May 2025 12:22:53 +0000 Subject: [PATCH] Fixed refresh in MilestoneTracker.js to keep the last scenario edited in local. --- .env.production | 1 + backend/server.js | 79 ++++++++++++++++++++++++----- src/components/MilestoneTracker.js | 30 ++++++++--- src/components/PopoutPanel.js | 2 +- user_profile.db | Bin 106496 -> 106496 bytes 5 files changed, 92 insertions(+), 20 deletions(-) diff --git a/.env.production b/.env.production index 012edd7..8177dc9 100644 --- a/.env.production +++ b/.env.production @@ -9,3 +9,4 @@ COLLEGE_SCORECARD_KEY = BlZ0tIdmXVGI4G8NxJ9e6dXEiGUfAfnQJyw8bumj REACT_APP_API_URL=https://dev1.aptivaai.com/api REACT_APP_ENV=production REACT_APP_OPENAI_API_KEY=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 +GCP_CLOUD_SQL_PASSWORD=q2O}1PU-R:|l57S0 diff --git a/backend/server.js b/backend/server.js index 66fd620..e579444 100755 --- a/backend/server.js +++ b/backend/server.js @@ -134,52 +134,107 @@ app.post('/api/user-profile', (req, res) => { return res.status(401).json({ error: 'Invalid or expired token' }); } - const { firstName, lastName, email, zipCode, state, area, careerSituation, interest_inventory_answers } = req.body; + const { + firstName, + lastName, + email, + zipCode, + state, + area, + careerSituation, + interest_inventory_answers, + } = req.body; if (!firstName || !lastName || !email || !zipCode || !state || !area) { - return res.status(400).json({ error: 'All fields are required' }); + return res.status(400).json({ error: 'All fields are required (except IIA)' }); } - const checkQuery = `SELECT id FROM user_profile WHERE user_id = ?`; - db.get(checkQuery, [userId], (err, row) => { + // 1) Check if we have an existing user_profile row for this userId + const checkQuery = `SELECT * FROM user_profile WHERE user_id = ?`; + db.get(checkQuery, [userId], (err, existingRow) => { if (err) { console.error('Error checking profile:', err.message); return res.status(500).json({ error: 'Database error' }); } - const params = [firstName, lastName, email, zipCode, state, area, careerSituation || null, interest_inventory_answers, userId]; + // 2) If interest_inventory_answers was omitted in the request, + // keep the old value from existingRow. + let finalAnswers; + if (existingRow) { + // If the row exists, keep or replace answers: + finalAnswers = + interest_inventory_answers === undefined + ? existingRow.interest_inventory_answers + : interest_inventory_answers; + } else { + // If no row yet, use whatever is passed or null + finalAnswers = interest_inventory_answers || null; + } - if (row) { - // Profile exists → UPDATE + if (existingRow) { + // 3) Update const updateQuery = ` UPDATE user_profile - SET firstname = ?, lastname = ?, email = ?, zipcode = ?, state = ?, area = ?, career_situation = ?, interest_inventory_answers = ? + SET firstname = ?, + lastname = ?, + email = ?, + zipcode = ?, + state = ?, + area = ?, + career_situation = ?, + interest_inventory_answers = ? WHERE user_id = ? `; + const params = [ + firstName, + lastName, + email, + zipCode, + state, + area, + careerSituation || null, + finalAnswers, + userId, + ]; db.run(updateQuery, params, function (err) { if (err) { console.error('Error updating profile:', err.message); return res.status(500).json({ error: 'Failed to update user profile' }); } - res.status(200).json({ message: 'User profile updated successfully' }); + return res.status(200).json({ message: 'User profile updated successfully' }); }); } else { - // Profile doesn't exist → INSERT + // 4) Insert new const insertQuery = ` - INSERT INTO user_profile (firstname, lastname, email, zipcode, state, area, career_situation, interest_inventory_answers, user_id) + INSERT INTO user_profile + (firstname, lastname, email, zipcode, state, area, career_situation, interest_inventory_answers, user_id) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?) `; + const params = [ + firstName, + lastName, + email, + zipCode, + state, + area, + careerSituation || null, + finalAnswers, + userId, + ]; db.run(insertQuery, params, function (err) { if (err) { console.error('Error inserting profile:', err.message); return res.status(500).json({ error: 'Failed to create user profile' }); } - res.status(201).json({ message: 'User profile created successfully', id: this.lastID }); + return res + .status(201) + .json({ message: 'User profile created successfully', id: this.lastID }); }); } }); }); + // Route for login app.post('/api/login', (req, res) => { const { username, password } = req.body; diff --git a/src/components/MilestoneTracker.js b/src/components/MilestoneTracker.js index 50943f0..bade554 100644 --- a/src/components/MilestoneTracker.js +++ b/src/components/MilestoneTracker.js @@ -79,14 +79,23 @@ const MilestoneTracker = ({ selectedCareer: initialCareer }) => { if (!res || !res.ok) return; const data = await res.json(); setExistingCareerPaths(data.careerPaths); - - // If user came from a different route passing in a selected scenario: + const fromPopout = location.state?.selectedCareer; if (fromPopout) { setSelectedCareer(fromPopout); setCareerPathId(fromPopout.career_path_id); - } else if (!selectedCareer) { - // fallback: fetch the 'latest' scenario + } else { + const storedCareerPathId = localStorage.getItem('lastSelectedCareerPathId'); + if (storedCareerPathId) { + const matchingCareer = data.careerPaths.find(p => p.id === storedCareerPathId); + if (matchingCareer) { + setSelectedCareer(matchingCareer); + setCareerPathId(storedCareerPathId); + return; + } + } + + // fallback to latest scenario if no stored ID or not found const latest = await authFetch(`${apiURL}/premium/career-profile/latest`); if (latest && latest.ok) { const latestData = await latest.json(); @@ -97,7 +106,7 @@ const MilestoneTracker = ({ selectedCareer: initialCareer }) => { } } }; - + const fetchFinancialProfile = async () => { const res = await authFetch(`${apiURL}/premium/financial-profile`); if (res?.ok) { @@ -105,10 +114,11 @@ const MilestoneTracker = ({ selectedCareer: initialCareer }) => { setFinancialProfile(data); } }; - + fetchCareerPaths(); fetchFinancialProfile(); - }, [apiURL, location.state, selectedCareer]); + }, [apiURL, location.state]); + // -------------------------------------------------- // 2) When careerPathId changes => fetch scenarioRow + collegeProfile @@ -148,6 +158,12 @@ const MilestoneTracker = ({ selectedCareer: initialCareer }) => { fetchCollege(); }, [careerPathId, apiURL]); + useEffect(() => { + if (careerPathId) { + localStorage.setItem('lastSelectedCareerPathId', careerPathId); + } + }, [careerPathId]); + // -------------------------------------------------- // 3) Once scenarioRow + collegeProfile + financialProfile => run simulation // + fetch milestones for annotation lines diff --git a/src/components/PopoutPanel.js b/src/components/PopoutPanel.js index f389364..efc52cc 100644 --- a/src/components/PopoutPanel.js +++ b/src/components/PopoutPanel.js @@ -22,7 +22,7 @@ function PopoutPanel({ const [programLengths, setProgramLengths] = useState([]); const [sortBy, setSortBy] = useState("tuition"); const [maxTuition, setMaxTuition] = useState(50000); - const [maxDistance, setMaxDistance] = useState(200); + const [maxDistance, setMaxDistance] = useState(100); const token = localStorage.getItem("token"); const navigate = useNavigate(); diff --git a/user_profile.db b/user_profile.db index 06342c9073281e832aae0ac48f525410993f5374..66213cf3ce8b9dac4874262703357efe44746df5 100644 GIT binary patch delta 142 zcmZoTz}9epZGtqT-b5K^M!k&*I`T{g#*_Qx&1?)!j0_EpjSWo(vK+n?Dc=M0^?{E1m d6rf^;O^i%3(;4F#MW^${GO}%#h+}-=2ms~kBnbcj delta 142 zcmZoTz}9epZGtqT(nJ|&Mx~7jI`T}$hLii`&1{TKj7