diff --git a/backend/server.js b/backend/server.js
index 6128d9b..82273d2 100755
--- a/backend/server.js
+++ b/backend/server.js
@@ -134,7 +134,7 @@ 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 } = 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' });
@@ -147,13 +147,13 @@ app.post('/api/user-profile', (req, res) => {
return res.status(500).json({ error: 'Database error' });
}
- const params = [firstName, lastName, email, zipCode, state, area, careerSituation || null, userId];
+ const params = [firstName, lastName, email, zipCode, state, area, careerSituation || null, interest_inventory_answers, userId];
if (row) {
// Profile exists → UPDATE
const updateQuery = `
UPDATE user_profile
- SET firstname = ?, lastname = ?, email = ?, zipcode = ?, state = ?, area = ?, career_situation = ?
+ SET firstname = ?, lastname = ?, email = ?, zipcode = ?, state = ?, area = ?, career_situation = ?, interest_inventory_answers = ?
WHERE user_id = ?
`;
db.run(updateQuery, params, function (err) {
@@ -166,8 +166,8 @@ app.post('/api/user-profile', (req, res) => {
} else {
// Profile doesn't exist → INSERT
const insertQuery = `
- INSERT INTO user_profile (firstname, lastname, email, zipcode, state, area, career_situation, user_id)
- VALUES (?, ?, ?, ?, ?, ?, ?, ?)
+ INSERT INTO user_profile (firstname, lastname, email, zipcode, state, area, career_situation, interest_inventory_answers, user_id)
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
`;
db.run(insertQuery, params, function (err) {
if (err) {
@@ -180,8 +180,6 @@ app.post('/api/user-profile', (req, res) => {
});
});
-
-
// Route for login
app.post('/api/login', (req, res) => {
const { username, password } = req.body;
diff --git a/src/App.js b/src/App.js
index 3184757..b2eaef0 100644
--- a/src/App.js
+++ b/src/App.js
@@ -1,5 +1,6 @@
import React, { useState} from 'react';
import { Routes, Route, Navigate } from 'react-router-dom';
+import SessionExpiredHandler from './components/SessionExpiredHandler.js';
import GettingStarted from './components/GettingStarted.js';
import SignIn from './components/SignIn.js';
import SignUp from './components/SignUp.js';
@@ -10,7 +11,7 @@ import MilestoneTracker from "./components/MilestoneTracker.js";
import './App.css';
function App() {
- console.log("App.js is rendering!");
+
const [isAuthenticated, setIsAuthenticated] = useState(() => {
return !!localStorage.getItem('token'); // Check localStorage
});
@@ -50,7 +51,9 @@ function App() {
{/* Catch-all for unknown routes */}
} />
+
+
);
}
diff --git a/src/components/InterestInventory.js b/src/components/InterestInventory.js
index 773151a..5e04892 100644
--- a/src/components/InterestInventory.js
+++ b/src/components/InterestInventory.js
@@ -1,6 +1,7 @@
import React, { useState, useEffect } from 'react';
import { useNavigate } from 'react-router-dom';
import { ClipLoader } from 'react-spinners';
+import authFetch from '../utils/authFetch.js';
import './InterestInventory.css';
const InterestInventory = () => {
@@ -12,7 +13,10 @@ const InterestInventory = () => {
const navigate = useNavigate();
const [loading, setLoading] = useState(false);
const [error, setError] = useState(null);
+ const [userProfile, setUserProfile] = useState(null);
+ const userId = localStorage.getItem('userId');
+ const apiUrl = process.env.REACT_APP_API_URL || '';
const fetchQuestions = async () => {
setLoading(true); // Start loading
@@ -20,7 +24,7 @@ const InterestInventory = () => {
const url = '/api/onet/questions?start=1&end=60';
try {
- const response = await fetch(url, {
+ const response = await authFetch(url, {
method: 'GET',
headers: { Accept: 'application/json' },
});
@@ -47,8 +51,38 @@ const InterestInventory = () => {
useEffect(() => {
fetchQuestions();
+ fetchUserProfile();
}, []);
+ const fetchUserProfile = async () => {
+ try {
+ const res = await authFetch('/api/user-profile', {
+ method: 'GET',
+ });
+
+ if (!res || !res.ok) throw new Error('Failed to fetch user profile');
+
+ const data = await res.json();
+ setUserProfile(data);
+ } catch (err) {
+ console.error('Error fetching user profile:', err.message);
+ }
+ };
+
+
+
+ useEffect(() => {
+ const storedAnswers = userProfile?.interest_inventory_answers;
+ if (questions.length === 60 && storedAnswers && storedAnswers.length === 60) {
+ const restored = {};
+ storedAnswers.split('').forEach((val, index) => {
+ restored[index + 1] = val;
+ });
+ setResponses(restored);
+ }
+ }, [questions, userProfile]);
+
+
const handleResponseChange = (questionIndex, value) => {
setResponses((prevResponses) => ({
...prevResponses,
@@ -95,12 +129,28 @@ const InterestInventory = () => {
if (!validateCurrentPage()) return;
const answers = Array.from({ length: 60 }, (_, i) => responses[i + 1] || '0').join('');
-
+
+ await authFetch(`${apiUrl}/user-profile`, {
+ method: 'POST',
+ body: JSON.stringify({
+ firstName: userProfile?.firstname,
+ lastName: userProfile?.lastname,
+ email: userProfile?.email,
+ zipCode: userProfile?.zipcode,
+ state: userProfile?.state,
+ area: userProfile?.area,
+ careerSituation: userProfile?.career_situation || null,
+ interest_inventory_answers: answers,
+ }),
+ });
+
+
+
try {
setIsSubmitting(true);
setError(null); // Clear previous errors
const url = `${process.env.REACT_APP_API_URL}/onet/submit_answers`;
- const response = await fetch(url, {
+ const response = await authFetch(url, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ answers }),
diff --git a/src/components/SessionExpiredHandler.js b/src/components/SessionExpiredHandler.js
new file mode 100644
index 0000000..9a3dfc6
--- /dev/null
+++ b/src/components/SessionExpiredHandler.js
@@ -0,0 +1,34 @@
+import React, { useState, useEffect } from 'react';
+import { useNavigate } from 'react-router-dom';
+import { setSessionExpiredCallback } from '../utils/authFetch.js';
+
+const SessionExpiredHandler = () => {
+ const [showModal, setShowModal] = useState(false);
+ const navigate = useNavigate();
+
+ useEffect(() => {
+ setSessionExpiredCallback(() => {
+ setShowModal(true);
+ });
+ }, []);
+
+ if (!showModal) return null;
+
+ return (
+
+
+
Session Expired
+
+
+
+ );
+};
+
+export default SessionExpiredHandler;
diff --git a/src/components/UserProfile.js b/src/components/UserProfile.js
index 2e1e3cc..39a3893 100644
--- a/src/components/UserProfile.js
+++ b/src/components/UserProfile.js
@@ -119,7 +119,6 @@ function UserProfile() {
if (!response.ok) {
throw new Error('Failed to save profile');
}
- console.warn('Profile saved successfully');
console.log('Profile saved successfully');
} catch (error) {
console.error('Error saving profile:', error);
diff --git a/src/utils/authFetch.js b/src/utils/authFetch.js
index 505b5f4..1b2a658 100644
--- a/src/utils/authFetch.js
+++ b/src/utils/authFetch.js
@@ -1,38 +1,32 @@
-// src/utils/authFetch.js
+let onSessionExpiredCallback = null;
-export const authFetch = async (url, options = {}, onUnauthorized) => {
- const token = localStorage.getItem("token");
-
- console.log("Token:", token); // Log token value
-
- if (!token) {
- console.log("Token is missing, triggering onUnauthorized");
- if (typeof onUnauthorized === 'function') onUnauthorized();
- return null;
- }
-
- const finalOptions = {
- ...options,
- headers: {
- ...(options.headers || {}),
- Authorization: `Bearer ${token}`,
- },
- };
-
- try {
- const res = await fetch(url, finalOptions);
-
- console.log("Response Status:", res.status); // Log response status
-
- if (res.status === 401 || res.status === 403) {
- console.log("Unauthorized response received, triggering onUnauthorized");
- if (typeof onUnauthorized === 'function') onUnauthorized();
- return null;
- }
-
- return res;
- } catch (err) {
- console.error("Fetch error:", err);
- return null;
- }
+export const setSessionExpiredCallback = (callback) => {
+ onSessionExpiredCallback = callback;
};
+
+const authFetch = async (url, options = {}) => {
+ const token = localStorage.getItem('token');
+
+ if (!token) {
+ onSessionExpiredCallback?.();
+ return null;
+ }
+
+ const res = await fetch(url, {
+ ...options,
+ headers: {
+ Authorization: `Bearer ${token}`,
+ 'Content-Type': 'application/json',
+ ...options.headers,
+ },
+ });
+
+ if ([401, 403].includes(res.status)) {
+ onSessionExpiredCallback?.();
+ return null;
+ }
+
+ return res;
+};
+
+export default authFetch;
diff --git a/user_profile.db b/user_profile.db
index ec9e0ad..0148c9d 100644
Binary files a/user_profile.db and b/user_profile.db differ