diff --git a/backend/server3.js b/backend/server3.js index 72b64ac..1ecc3e5 100644 --- a/backend/server3.js +++ b/backend/server3.js @@ -259,6 +259,19 @@ app.post('/api/premium/career-profile', authenticatePremiumUser, async (req, res } }); +// server3.js (add near the other career-profile routes) +app.put('/api/premium/career-profile/:id/goals', authenticatePremiumUser, async (req, res) => { + const { id } = req.params; + const { career_goals } = req.body; + + // simple ownership check + const [rows] = await pool.query('SELECT user_id FROM career_profiles WHERE id=?', [id]); + if (!rows[0] || rows[0].user_id !== req.id) { + return res.status(403).json({ error: 'Not your profile.' }); + } + await pool.query('UPDATE career_profiles SET career_goals=? WHERE id=?', [career_goals, id]); + res.json({ career_goals }); +}); // DELETE a career profile (scenario) by ID app.delete('/api/premium/career-profile/:careerProfileId', authenticatePremiumUser, async (req, res) => { @@ -2473,6 +2486,40 @@ app.delete('/api/premium/tasks/:taskId', authenticatePremiumUser, async (req, re } }); +app.get('/api/premium/tasks', authenticatePremiumUser, async (req, res) => { + try { + const { career_path_id, status = 'all' } = req.query; + const args = [req.id]; // << first placeholder = user_id + + let sql = ` + SELECT + t.id, t.milestone_id, t.title, t.description, + t.due_date, t.status, + t.created_at, t.updated_at, + + m.title AS milestone_title, + m.date AS milestone_date, + cp.id AS career_path_id, + cp.career_name + FROM tasks t + JOIN milestones m ON m.id = t.milestone_id + JOIN career_paths cp ON cp.id = m.career_path_id + WHERE cp.user_id = ? + `; + + if (career_path_id) { sql += ' AND cp.id = ?'; args.push(career_path_id); } + if (status !== 'all') { sql += ' AND t.status = ?'; args.push(status); } + + sql += ' ORDER BY COALESCE(t.due_date, m.date) ASC'; + + const [rows] = await pool.query(sql, args); + return res.json(rows); + } catch (err) { + console.error('Error fetching tasks:', err); + return res.status(500).json({ error: 'Failed to fetch tasks.' }); + } +}); + /* ------------------------------------------------------------------ MILESTONE IMPACTS ENDPOINTS ------------------------------------------------------------------ */ @@ -2664,6 +2711,10 @@ app.delete('/api/premium/milestone-impacts/:impactId', authenticatePremiumUser, } }); +/* ------------------------------------------------------------------ + O*NET KSA DATA + ------------------------------------------------------------------ */ + let onetKsaData = []; // entire array from ksa_data.json let allKsaNames = []; // an array of unique KSA names (for fuzzy matching) diff --git a/src/components/CareerCoach.js b/src/components/CareerCoach.js index 4124e0a..d2393a1 100644 --- a/src/components/CareerCoach.js +++ b/src/components/CareerCoach.js @@ -73,6 +73,8 @@ export default function CareerCoach({ userProfile, financialProfile, scenarioRow, + setScenarioRow, + careerProfileId, collegeProfile, onMilestonesCreated, onAiRiskFetched @@ -83,6 +85,9 @@ export default function CareerCoach({ const [loading, setLoading] = useState(false); const [aiRisk, setAiRisk] = useState(null); const chatRef = useRef(null); + const [showGoals , setShowGoals ] = useState(false); + const [draftGoals, setDraftGoals] = useState(scenarioRow?.career_goals || ""); + const [saving , setSaving ] = useState(false); /* -------------- scroll --------------- */ useEffect(() => { @@ -248,7 +253,7 @@ I'm here to support you with personalized coaching. What would you like to focus

Career Coach

{/* Quick-action bar */} -
+
-
+ {/* pushes Edit Goals to the far right */} +
+ + +
+ {/* Chat area */}
+ + {showGoals && ( +
+
+

Edit Your Career Goals

+ +