Fixed refresh in MilestoneTracker.js to keep the last scenario edited in local.

This commit is contained in:
Josh 2025-05-08 12:22:53 +00:00
parent 299482c2d7
commit 856ebd0e62
5 changed files with 92 additions and 20 deletions

View File

@ -9,3 +9,4 @@ COLLEGE_SCORECARD_KEY = BlZ0tIdmXVGI4G8NxJ9e6dXEiGUfAfnQJyw8bumj
REACT_APP_API_URL=https://dev1.aptivaai.com/api REACT_APP_API_URL=https://dev1.aptivaai.com/api
REACT_APP_ENV=production REACT_APP_ENV=production
REACT_APP_OPENAI_API_KEY=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 REACT_APP_OPENAI_API_KEY=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
GCP_CLOUD_SQL_PASSWORD=q2O}1PU-R:|l57S0

View File

@ -134,52 +134,107 @@ app.post('/api/user-profile', (req, res) => {
return res.status(401).json({ error: 'Invalid or expired token' }); 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) { 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 = ?`; // 1) Check if we have an existing user_profile row for this userId
db.get(checkQuery, [userId], (err, row) => { const checkQuery = `SELECT * FROM user_profile WHERE user_id = ?`;
db.get(checkQuery, [userId], (err, existingRow) => {
if (err) { if (err) {
console.error('Error checking profile:', err.message); console.error('Error checking profile:', err.message);
return res.status(500).json({ error: 'Database error' }); 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) { if (existingRow) {
// Profile exists → UPDATE // 3) Update
const updateQuery = ` const updateQuery = `
UPDATE user_profile 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 = ? WHERE user_id = ?
`; `;
const params = [
firstName,
lastName,
email,
zipCode,
state,
area,
careerSituation || null,
finalAnswers,
userId,
];
db.run(updateQuery, params, function (err) { db.run(updateQuery, params, function (err) {
if (err) { if (err) {
console.error('Error updating profile:', err.message); console.error('Error updating profile:', err.message);
return res.status(500).json({ error: 'Failed to update user profile' }); 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 { } else {
// Profile doesn't exist → INSERT // 4) Insert new
const insertQuery = ` 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 (?, ?, ?, ?, ?, ?, ?, ?, ?) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
`; `;
const params = [
firstName,
lastName,
email,
zipCode,
state,
area,
careerSituation || null,
finalAnswers,
userId,
];
db.run(insertQuery, params, function (err) { db.run(insertQuery, params, function (err) {
if (err) { if (err) {
console.error('Error inserting profile:', err.message); console.error('Error inserting profile:', err.message);
return res.status(500).json({ error: 'Failed to create user profile' }); 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 // Route for login
app.post('/api/login', (req, res) => { app.post('/api/login', (req, res) => {
const { username, password } = req.body; const { username, password } = req.body;

View File

@ -80,13 +80,22 @@ const MilestoneTracker = ({ selectedCareer: initialCareer }) => {
const data = await res.json(); const data = await res.json();
setExistingCareerPaths(data.careerPaths); setExistingCareerPaths(data.careerPaths);
// If user came from a different route passing in a selected scenario:
const fromPopout = location.state?.selectedCareer; const fromPopout = location.state?.selectedCareer;
if (fromPopout) { if (fromPopout) {
setSelectedCareer(fromPopout); setSelectedCareer(fromPopout);
setCareerPathId(fromPopout.career_path_id); setCareerPathId(fromPopout.career_path_id);
} else if (!selectedCareer) { } else {
// fallback: fetch the 'latest' scenario 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`); const latest = await authFetch(`${apiURL}/premium/career-profile/latest`);
if (latest && latest.ok) { if (latest && latest.ok) {
const latestData = await latest.json(); const latestData = await latest.json();
@ -108,7 +117,8 @@ const MilestoneTracker = ({ selectedCareer: initialCareer }) => {
fetchCareerPaths(); fetchCareerPaths();
fetchFinancialProfile(); fetchFinancialProfile();
}, [apiURL, location.state, selectedCareer]); }, [apiURL, location.state]);
// -------------------------------------------------- // --------------------------------------------------
// 2) When careerPathId changes => fetch scenarioRow + collegeProfile // 2) When careerPathId changes => fetch scenarioRow + collegeProfile
@ -148,6 +158,12 @@ const MilestoneTracker = ({ selectedCareer: initialCareer }) => {
fetchCollege(); fetchCollege();
}, [careerPathId, apiURL]); }, [careerPathId, apiURL]);
useEffect(() => {
if (careerPathId) {
localStorage.setItem('lastSelectedCareerPathId', careerPathId);
}
}, [careerPathId]);
// -------------------------------------------------- // --------------------------------------------------
// 3) Once scenarioRow + collegeProfile + financialProfile => run simulation // 3) Once scenarioRow + collegeProfile + financialProfile => run simulation
// + fetch milestones for annotation lines // + fetch milestones for annotation lines

View File

@ -22,7 +22,7 @@ function PopoutPanel({
const [programLengths, setProgramLengths] = useState([]); const [programLengths, setProgramLengths] = useState([]);
const [sortBy, setSortBy] = useState("tuition"); const [sortBy, setSortBy] = useState("tuition");
const [maxTuition, setMaxTuition] = useState(50000); const [maxTuition, setMaxTuition] = useState(50000);
const [maxDistance, setMaxDistance] = useState(200); const [maxDistance, setMaxDistance] = useState(100);
const token = localStorage.getItem("token"); const token = localStorage.getItem("token");
const navigate = useNavigate(); const navigate = useNavigate();

Binary file not shown.