import React, { useState, useEffect } from 'react'; import { useNavigate } from 'react-router-dom'; import { ClipLoader } from 'react-spinners'; import authFetch from '../utils/authFetch.js'; const InterestInventory = () => { const [questions, setQuestions] = useState([]); const [responses, setResponses] = useState({}); const [currentPage, setCurrentPage] = useState(1); const [isSubmitting, setIsSubmitting] = useState(false); const [loading, setLoading] = useState(false); const [error, setError] = useState(null); const [userProfile, setUserProfile] = useState(null); const navigate = useNavigate(); const questionsPerPage = 6; const totalPages = Math.ceil(questions.length / questionsPerPage) || 1; useEffect(() => { fetchQuestions(); fetchUserProfile(); }, []); const fetchQuestions = async () => { setLoading(true); setError(null); try { const response = await authFetch('/api/onet/questions?start=1&end=60', { method: 'GET', headers: { Accept: 'application/json' }, }); if (!response.ok) { throw new Error(`Failed to fetch questions: ${response.statusText}`); } const data = await response.json(); if (data && Array.isArray(data.questions)) { setQuestions(data.questions); } else { throw new Error('Invalid question format.'); } } catch (err) { setError(err.message); console.error('Error fetching questions:', err.message); } finally { setLoading(false); } }; 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); } }; // Restore previously saved answers if available useEffect(() => { const storedAnswers = userProfile?.interest_inventory_answers; if (questions.length === 60 && storedAnswers?.length === 60) { const restored = {}; storedAnswers.split('').forEach((val, index) => { restored[index + 1] = val; }); setResponses(restored); } }, [questions, userProfile]); const handleResponseChange = (questionIndex, value) => { setResponses((prev) => ({ ...prev, [questionIndex]: value, })); }; const validateCurrentPage = () => { const start = (currentPage - 1) * questionsPerPage; const end = currentPage * questionsPerPage; const currentQuestions = questions.slice(start, end); const unanswered = currentQuestions.filter( (q) => !responses[q.index] || responses[q.index] === '0' ); if (unanswered.length > 0) { alert('Please answer all questions before proceeding.'); return false; } return true; }; const handleNextPage = () => { if (!validateCurrentPage()) return; setCurrentPage((prev) => prev + 1); }; const handlePreviousPage = () => { if (currentPage > 1) { setCurrentPage((prev) => prev - 1); } }; const randomizeAnswers = () => { const randomized = {}; questions.forEach((question) => { randomized[question.index] = Math.floor(Math.random() * 5) + 1; // 1–5 }); setResponses(randomized); }; const handleSubmit = async () => { if (!validateCurrentPage()) return; // Combine answers into a 60-char string const answers = Array.from({ length: 60 }, (_, i) => responses[i + 1] || '0').join(''); // First save the answers to user profile try { await authFetch('/api/user-profile', { method: 'POST', headers: { 'Content-Type': 'application/json' }, 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, }), }); } catch (err) { console.error('Error saving answers to user profile:', err.message); } // Then submit to the O*Net logic try { setIsSubmitting(true); setError(null); const response = await authFetch(`${process.env.REACT_APP_API_URL}/onet/submit_answers`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ answers }), }); if (!response.ok) { throw new Error(`Failed to submit answers: ${response.statusText}`); } const data = await response.json(); const { careers: careerSuggestions, riaSecScores } = data; if (Array.isArray(careerSuggestions) && Array.isArray(riaSecScores)) { navigate('/dashboard', { state: { careerSuggestions, riaSecScores } }); } else { throw new Error('Invalid data format from the server.'); } } catch (error) { console.error('Error submitting answers:', error.message); alert('Failed to submit answers. Please try again later.'); } finally { setIsSubmitting(false); } }; // Compute which questions to show const start = (currentPage - 1) * questionsPerPage; const end = currentPage * questionsPerPage; const currentQuestions = questions.slice(start, end); // Calculate progress for the bar const totalQuestions = 60; const answeredCount = Object.keys(responses).filter((key) => responses[key] !== '0').length; const progressPercent = Math.round((answeredCount / totalQuestions) * 100); return (
{error}
)} {/* Progress Bar & Page Indicator */}Page {currentPage} of {totalPages}
{answeredCount} / {totalQuestions} answered