Added RIASEC to user_profile
This commit is contained in:
parent
87effa1a86
commit
112d6eec56
@ -337,7 +337,7 @@ app.get('/api/check-username/:username', (req, res) => {
|
||||
/**
|
||||
* POST /api/user-profile
|
||||
* Headers: { Authorization: Bearer <token> }
|
||||
* Body: { firstName, lastName, email, zipCode, state, area, ... }
|
||||
* Body: { userName, firstName, lastName, email, zipCode, state, area, ... }
|
||||
*
|
||||
* If user_profile row exists (id = token.id), update
|
||||
* else insert
|
||||
@ -358,6 +358,7 @@ app.post('/api/user-profile', (req, res) => {
|
||||
}
|
||||
|
||||
const {
|
||||
userName,
|
||||
firstName,
|
||||
lastName,
|
||||
email,
|
||||
@ -366,13 +367,14 @@ app.post('/api/user-profile', (req, res) => {
|
||||
area,
|
||||
careerSituation,
|
||||
interest_inventory_answers,
|
||||
riasec_scores, // new JSON with { R:15, I:22, A:..., S:..., E:..., C:... }
|
||||
career_priorities,
|
||||
career_list,
|
||||
} = req.body;
|
||||
|
||||
// Check if profile row exists
|
||||
pool.query(
|
||||
`SELECT * FROM user_profile WHERE id = ?`,
|
||||
'SELECT * FROM user_profile WHERE id = ?',
|
||||
[profileId],
|
||||
(err, results) => {
|
||||
if (err) {
|
||||
@ -391,31 +393,66 @@ app.post('/api/user-profile', (req, res) => {
|
||||
.json({ error: 'All fields are required for initial profile creation.' });
|
||||
}
|
||||
|
||||
// Final handling of interest inventory answers
|
||||
const finalAnswers =
|
||||
interest_inventory_answers !== undefined
|
||||
? interest_inventory_answers
|
||||
: existingRow?.interest_inventory_answers || null;
|
||||
|
||||
// final career priorities
|
||||
const finalCareerPriorities =
|
||||
career_priorities !== undefined
|
||||
? career_priorities
|
||||
: existingRow?.career_priorities || null;
|
||||
|
||||
// final career list
|
||||
const finalCareerList =
|
||||
career_list !== undefined
|
||||
? career_list
|
||||
: existingRow?.career_list || null;
|
||||
|
||||
// final userName
|
||||
const finalUserName =
|
||||
userName !== undefined
|
||||
? userName
|
||||
: existingRow?.username || null;
|
||||
|
||||
// final RIASEC JSON
|
||||
// If you passed something in "riasec_scores", store as JSON
|
||||
// If none passed, keep existing or null
|
||||
let finalRiasecScores;
|
||||
if (riasec_scores !== undefined) {
|
||||
if (riasec_scores) {
|
||||
finalRiasecScores = JSON.stringify(riasec_scores);
|
||||
} else {
|
||||
// if it's empty or falsey, set to null or keep existing
|
||||
finalRiasecScores = null;
|
||||
}
|
||||
} else {
|
||||
finalRiasecScores = existingRow?.riasec_scores || null;
|
||||
}
|
||||
|
||||
if (existingRow) {
|
||||
// Update the existing user_profile
|
||||
// Update existing row
|
||||
const updateQuery = `
|
||||
UPDATE user_profile
|
||||
SET firstname = ?, lastname = ?, email = ?, zipcode = ?, state = ?, area = ?,
|
||||
career_situation = ?, interest_inventory_answers = ?, career_priorities = ?,
|
||||
career_list = ?
|
||||
SET
|
||||
username = ?,
|
||||
firstname = ?,
|
||||
lastname = ?,
|
||||
email = ?,
|
||||
zipcode = ?,
|
||||
state = ?,
|
||||
area = ?,
|
||||
career_situation = ?,
|
||||
interest_inventory_answers = ?,
|
||||
riasec_scores = ?, -- new field
|
||||
career_priorities = ?,
|
||||
career_list = ?
|
||||
WHERE id = ?
|
||||
`;
|
||||
const params = [
|
||||
finalUserName,
|
||||
firstName || existingRow.firstname,
|
||||
lastName || existingRow.lastname,
|
||||
email || existingRow.email,
|
||||
@ -424,9 +461,10 @@ app.post('/api/user-profile', (req, res) => {
|
||||
area || existingRow.area,
|
||||
careerSituation || existingRow.career_situation,
|
||||
finalAnswers,
|
||||
finalRiasecScores, // JSON string
|
||||
finalCareerPriorities,
|
||||
finalCareerList,
|
||||
profileId,
|
||||
profileId
|
||||
];
|
||||
|
||||
pool.query(updateQuery, params, (err2) => {
|
||||
@ -436,20 +474,20 @@ app.post('/api/user-profile', (req, res) => {
|
||||
.status(500)
|
||||
.json({ error: 'Failed to update user profile' });
|
||||
}
|
||||
return res
|
||||
.status(200)
|
||||
.json({ message: 'User profile updated successfully' });
|
||||
return res.status(200).json({ message: 'User profile updated successfully' });
|
||||
});
|
||||
} else {
|
||||
// Insert a new profile (the user_auth record exists, but the user_profile row is missing)
|
||||
// Insert a new profile
|
||||
const insertQuery = `
|
||||
INSERT INTO user_profile
|
||||
(id, firstname, lastname, email, zipcode, state, area, career_situation,
|
||||
interest_inventory_answers, career_priorities, career_list)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
||||
(id, username, firstname, lastname, email, zipcode, state, area,
|
||||
career_situation, interest_inventory_answers, riasec_scores,
|
||||
career_priorities, career_list)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
||||
`;
|
||||
const params = [
|
||||
profileId, // Force the row's primary key to match the existing user ID
|
||||
profileId,
|
||||
finalUserName,
|
||||
firstName,
|
||||
lastName,
|
||||
email,
|
||||
@ -458,6 +496,7 @@ app.post('/api/user-profile', (req, res) => {
|
||||
area,
|
||||
careerSituation || null,
|
||||
finalAnswers,
|
||||
finalRiasecScores, // JSON string or null
|
||||
finalCareerPriorities,
|
||||
finalCareerList,
|
||||
];
|
||||
@ -469,15 +508,17 @@ app.post('/api/user-profile', (req, res) => {
|
||||
.status(500)
|
||||
.json({ error: 'Failed to create user profile' });
|
||||
}
|
||||
return res
|
||||
.status(201)
|
||||
.json({ message: 'User profile created successfully', id: profileId });
|
||||
return res.status(201).json({
|
||||
message: 'User profile created successfully',
|
||||
id: profileId
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------
|
||||
FETCH USER PROFILE (MySQL)
|
||||
------------------------------------------------------------------ */
|
||||
|
@ -349,6 +349,24 @@ app.post('/api/onet/submit_answers', async (req, res) => {
|
||||
// filter out lower ed
|
||||
const filtered = filterHigherEducationCareers(careerSuggestions);
|
||||
|
||||
const riasecCode = convertToRiasecCode(riaSecScores);
|
||||
|
||||
const token = req.headers.authorization?.split(' ')[1];
|
||||
if (token) {
|
||||
try {
|
||||
await axios.post(`${process.env.MAIN_API_URL}/api/user-profile`,
|
||||
{
|
||||
interest_inventory_answers: answers,
|
||||
riasec: riasecCode
|
||||
},
|
||||
{ headers: { Authorization: `Bearer ${token}` } }
|
||||
);
|
||||
} catch (err) {
|
||||
console.error('Error storing RIASEC in user_profile =>', err.response?.data || err.message);
|
||||
// fallback if needed
|
||||
}
|
||||
}
|
||||
|
||||
res.status(200).json({
|
||||
careers: filtered,
|
||||
riaSecScores,
|
||||
@ -379,6 +397,25 @@ function filterHigherEducationCareers(careers) {
|
||||
.filter(Boolean);
|
||||
}
|
||||
|
||||
function convertToRiasecCode(riaSecScores) {
|
||||
// We assume each item has { area, score, description }
|
||||
// Sort them by area in R, I, A, S, E, C order or by highest score, whichever you prefer:
|
||||
|
||||
// Sort by standard R -> I -> A -> S -> E -> C ordering:
|
||||
const order = { Realistic: 0, Investigative: 1, Artistic: 2, Social: 3, Enterprising: 4, Conventional: 5 };
|
||||
// or you can sort by descending score:
|
||||
// const sorted = [...riaSecScores].sort((a, b) => b.score - a.score);
|
||||
|
||||
// For this example, let's do the standard R -> I -> A -> S -> E -> C
|
||||
const sorted = [...riaSecScores].sort((a, b) => order[a.area] - order[b.area]);
|
||||
|
||||
// Now build the 6-letter code
|
||||
// e.g. "RI" + "A" + ...
|
||||
// If you want to show tie-breaking or real logic, you can do so
|
||||
return sorted.map(item => item.area[0].toUpperCase()).join('');
|
||||
// e.g. "RIASEC"
|
||||
}
|
||||
|
||||
// ONet career details
|
||||
app.get('/api/onet/career-details/:socCode', async (req, res) => {
|
||||
const { socCode } = req.params;
|
||||
|
@ -3,6 +3,18 @@ import { useNavigate } from 'react-router-dom';
|
||||
import { ClipLoader } from 'react-spinners';
|
||||
import authFetch from '../utils/authFetch.js';
|
||||
|
||||
|
||||
function mapScores(riaSecScores) {
|
||||
const map = {};
|
||||
// e.g. area = "Realistic" => letter "R"
|
||||
riaSecScores.forEach(obj => {
|
||||
const letter = obj.area[0].toUpperCase(); // 'R', 'I', 'A', 'S', 'E', 'C'
|
||||
map[letter] = obj.score;
|
||||
});
|
||||
return map; // e.g. { R:15, I:22, A:20, S:30, E:25, C:24 }
|
||||
}
|
||||
|
||||
|
||||
const InterestInventory = () => {
|
||||
const [questions, setQuestions] = useState([]);
|
||||
const [responses, setResponses] = useState({});
|
||||
@ -156,6 +168,16 @@ const InterestInventory = () => {
|
||||
const { careers: careerSuggestions, riaSecScores } = data;
|
||||
|
||||
if (Array.isArray(careerSuggestions) && Array.isArray(riaSecScores)) {
|
||||
// 4) Convert those scores to a short code
|
||||
const scoresMap = mapScores(riaSecScores); // { R:15, I:22, ... }
|
||||
await authFetch('/api/user-profile', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({
|
||||
riasec_scores: scoresMap // store in DB as a JSON string
|
||||
}),
|
||||
});
|
||||
|
||||
navigate('/career-explorer', { state: { careerSuggestions, riaSecScores, fromInterestInventory: true } });
|
||||
} else {
|
||||
throw new Error('Invalid data format from the server.');
|
||||
|
Loading…
Reference in New Issue
Block a user