268 lines
9.4 KiB
JavaScript
268 lines
9.4 KiB
JavaScript
// CareerOnboarding.js
|
||
import React, { useState, useEffect } from 'react';
|
||
import { useLocation } from 'react-router-dom';
|
||
|
||
// 1) Import your CareerSearch component
|
||
import CareerSearch from '../CareerSearch.js'; // adjust path as necessary
|
||
|
||
const Req = () => <span className="text-red-600 ml-0.5">*</span>;
|
||
|
||
const CareerOnboarding = ({ nextStep, prevStep, data, setData, finishNow }) => {
|
||
// We store local state for “are you working,” “selectedCareer,” etc.
|
||
const location = useLocation();
|
||
const navCareerObj = location.state?.selectedCareer;
|
||
const [careerObj, setCareerObj] = useState(() => {
|
||
if (navCareerObj) return navCareerObj;
|
||
try {
|
||
return JSON.parse(localStorage.getItem('selectedCareer') || 'null');
|
||
} catch { return null; }
|
||
});
|
||
const [currentlyWorking, setCurrentlyWorking] = useState('');
|
||
const [collegeStatus, setCollegeStatus] = useState('');
|
||
const [showFinPrompt, setShowFinPrompt] = useState(false);
|
||
|
||
/* ── 2. derived helpers ───────────────────────────────────── */
|
||
const selectedCareerTitle = careerObj?.title || '';
|
||
const ready =
|
||
selectedCareerTitle &&
|
||
currentlyWorking &&
|
||
collegeStatus;
|
||
|
||
const inCollege = ['currently_enrolled', 'prospective_student']
|
||
.includes(collegeStatus);
|
||
const skipFin = !!data.skipFinancialStep;
|
||
// 1) Grab the location state values, if any
|
||
|
||
const {
|
||
socCode,
|
||
cipCodes,
|
||
careerTitle, // <--- we passed this from handleSelectForEducation
|
||
userZip,
|
||
userState,
|
||
} = location.state || {};
|
||
|
||
/* ── 3. side‑effects when route brings a new career object ── */
|
||
useEffect(() => {
|
||
if (!navCareerObj?.title) return;
|
||
|
||
setCareerObj(navCareerObj);
|
||
localStorage.setItem('selectedCareer', JSON.stringify(navCareerObj));
|
||
|
||
|
||
setData(prev => ({
|
||
...prev,
|
||
career_name : navCareerObj.title,
|
||
soc_code : navCareerObj.soc_code || ''
|
||
}));
|
||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||
}, [navCareerObj]); // ← run once per navigation change
|
||
|
||
|
||
// Called whenever other <inputs> change
|
||
const handleChange = (e) => {
|
||
setData(prev => ({ ...prev, [e.target.name]: e.target.value }));
|
||
};
|
||
|
||
/* ── 4. callbacks ─────────────────────────────────────────── */
|
||
function handleCareerSelected(obj) {
|
||
setCareerObj(obj);
|
||
localStorage.setItem('selectedCareer', JSON.stringify(obj));
|
||
setData(prev => ({ ...prev, career_name: obj.title, soc_code: obj.soc_code || '' }));
|
||
}
|
||
|
||
|
||
|
||
function handleSubmit() {
|
||
if (!ready) return alert('Fill all required fields.');
|
||
const inCollege = ['currently_enrolled', 'prospective_student'].includes(collegeStatus);
|
||
setData(prev => ({
|
||
...prev,
|
||
career_name : selectedCareerTitle,
|
||
college_enrollment_status : collegeStatus,
|
||
currently_working : currentlyWorking,
|
||
inCollege,
|
||
}));
|
||
/* — where do we go? — */
|
||
if (skipFin && !inCollege) {
|
||
/* user said “Skip” AND is not in college ⇒ jump to Review */
|
||
finishNow(); // ← the helper we just injected via props
|
||
} else {
|
||
nextStep(); // ordinary flow
|
||
}
|
||
}
|
||
|
||
const nextLabel = skipFin
|
||
? inCollege ? 'College →' : 'Finish →'
|
||
: inCollege ? 'College →' : 'Financial →';
|
||
|
||
|
||
return (
|
||
<div className="max-w-md mx-auto p-6 space-y-4">
|
||
<h2 className="text-2xl font-semibold">Career Details</h2>
|
||
|
||
<div className="space-y-2">
|
||
<label className="block font-medium">
|
||
Are you currently earning any income — even part-time or outside your intended career path? <Req />
|
||
</label>
|
||
<p className="text-sm text-gray-600">
|
||
(We ask this to understand your financial picture. This won’t affect how we track your progress toward your target career.)
|
||
</p>
|
||
<select
|
||
value={currentlyWorking}
|
||
onChange={(e) => {
|
||
setCurrentlyWorking(e.target.value);
|
||
setData(prev => ({ ...prev, currently_working: e.target.value }));
|
||
}}
|
||
required
|
||
className="w-full border rounded p-2"
|
||
>
|
||
<option value="">Select one</option>
|
||
<option value="yes">Yes</option>
|
||
<option value="no">No</option>
|
||
</select>
|
||
</div>
|
||
|
||
{/* 2) Replace old local “Search for Career” with <CareerSearch/> */}
|
||
<div className="space-y-2">
|
||
<h3 className="font-medium">
|
||
Target Career <Req />
|
||
</h3>
|
||
<p className="text-sm text-gray-600">
|
||
This should be the career you are <strong>striving for</strong> — whether it’s a new goal or the one you're already in.
|
||
</p>
|
||
|
||
<CareerSearch onCareerSelected={handleCareerSelected} required />
|
||
</div>
|
||
|
||
{selectedCareerTitle && (
|
||
<p className="text-gray-700">
|
||
Selected Career: <strong>{selectedCareerTitle}</strong>
|
||
</p>
|
||
)}
|
||
|
||
<div className="space-y-2">
|
||
<label className="block font-medium">Status:</label>
|
||
<select
|
||
name="status"
|
||
onChange={handleChange}
|
||
value={data.status || ''}
|
||
className="w-full border rounded p-2"
|
||
>
|
||
<option value="">Select Status</option>
|
||
<option value="planned">Planned</option>
|
||
<option value="current">Current</option>
|
||
<option value="exploring">Exploring</option>
|
||
</select>
|
||
</div>
|
||
|
||
<div className="space-y-2">
|
||
<label className="block font-medium">Career Start Date:</label>
|
||
<input
|
||
name="start_date"
|
||
type="date"
|
||
onChange={handleChange}
|
||
value={data.start_date || ''}
|
||
className="w-full border rounded p-2"
|
||
/>
|
||
</div>
|
||
|
||
<div className="space-y-2">
|
||
<label className="block font-medium">Projected End Date (optional):</label>
|
||
<input
|
||
name="projected_end_date"
|
||
type="date"
|
||
onChange={handleChange}
|
||
value={data.projected_end_date || ''}
|
||
className="w-full border rounded p-2"
|
||
/>
|
||
</div>
|
||
|
||
<div className="space-y-2">
|
||
<label className="block font-medium">
|
||
Are you currently enrolled in college or planning to enroll? <Req />
|
||
</label>
|
||
<select
|
||
value={collegeStatus}
|
||
onChange={(e) => {
|
||
setCollegeStatus(e.target.value);
|
||
setData(prev => ({ ...prev, college_enrollment_status: e.target.value }));
|
||
const needsPrompt = ['currently_enrolled', 'prospective_student'].includes(e.target.value);
|
||
setShowFinPrompt(needsPrompt);
|
||
}}
|
||
required
|
||
className="w-full border rounded p-2"
|
||
>
|
||
<option value="">Select one</option>
|
||
<option value="not_enrolled">Not Enrolled / Not Planning</option>
|
||
<option value="currently_enrolled">Currently Enrolled</option>
|
||
<option value="prospective_student">Planning to Enroll (Prospective)</option>
|
||
</select>
|
||
|
||
{showFinPrompt && (
|
||
<div className="mt-4 p-4 rounded border border-blue-300 bg-blue-50">
|
||
<p className="text-sm mb-3">
|
||
We can give you step-by-step milestones right away. <br />
|
||
If you’d also like a personal cash-flow & tuition projection,<br />
|
||
add a few financial details now—or skip and do it later.
|
||
</p>
|
||
|
||
<button
|
||
className="bg-blue-500 hover:bg-blue-600 text-white py-1 px-3 rounded mr-2"
|
||
onClick={() => {
|
||
/* open your ScenarioEditModal or a mini financial modal */
|
||
setShowFinPrompt(false);
|
||
/* maybe set a flag so CareerRoadmap opens the modal */
|
||
}}
|
||
>
|
||
Add Financial Details
|
||
</button>
|
||
|
||
<button
|
||
className="bg-gray-200 hover:bg-gray-300 text-gray-800 py-1 px-3 rounded"
|
||
onClick={() => {
|
||
/* mark intent to skip the finance step */
|
||
setData(prev => ({ ...prev, skipFinancialStep: true }));
|
||
|
||
setShowFinPrompt(false); // hide the prompt, stay on page
|
||
}}
|
||
>
|
||
Skip for Now
|
||
</button>
|
||
</div>
|
||
)}
|
||
|
||
</div>
|
||
<div className="space-y-2">
|
||
<label className="block font-medium">Career Goals</label>
|
||
<textarea
|
||
name="career_goals"
|
||
value={data.career_goals || ''}
|
||
onChange={handleChange}
|
||
className="w-full border rounded p-2"
|
||
placeholder="Tell us about your goals, aspirations, or next steps..."
|
||
/>
|
||
</div>
|
||
<div className="flex justify-between pt-4">
|
||
<button
|
||
onClick={prevStep}
|
||
className="bg-gray-200 hover:bg-gray-300 text-gray-700 font-semibold py-2 px-4 rounded"
|
||
>
|
||
Back
|
||
</button>
|
||
<button
|
||
onClick={handleSubmit}
|
||
disabled={!ready}
|
||
className={`py-2 px-4 rounded font-semibold
|
||
${ready
|
||
? 'bg-blue-500 hover:bg-blue-600 text-white'
|
||
: 'bg-gray-300 text-gray-500 cursor-not-allowed'}`}
|
||
>
|
||
{nextLabel}
|
||
</button>
|
||
</div>
|
||
</div>
|
||
);
|
||
};
|
||
|
||
export default CareerOnboarding;
|