dev1/src/components/UserProfile.js

334 lines
11 KiB
JavaScript

import React, { useState, useEffect } from 'react';
import { useNavigate } from 'react-router-dom';
function UserProfile() {
const [firstName, setFirstName] = useState('');
const [lastName, setLastName] = useState('');
const [email, setEmail] = useState('');
const [zipCode, setZipCode] = useState('');
const [selectedState, setSelectedState] = useState('');
const [areas, setAreas] = useState([]);
const [selectedArea, setSelectedArea] = useState('');
const [careerSituation, setCareerSituation] = useState('');
const [loadingAreas, setLoadingAreas] = useState(false);
const [isPremiumUser, setIsPremiumUser] = useState(false);
const navigate = useNavigate();
const authFetch = async (url, options = {}) => {
const token = localStorage.getItem('token');
if (!token) {
navigate('/signin');
return null;
}
const res = await fetch(url, {
...options,
headers: {
Authorization: `Bearer ${token}`,
'Content-Type': 'application/json',
...options.headers,
},
});
if ([401, 403].includes(res.status)) {
console.warn('Token invalid or expired. Redirecting to Sign In.');
navigate('/signin');
return null;
}
return res;
};
useEffect(() => {
const fetchProfileAndAreas = async () => {
try {
const token = localStorage.getItem('token');
if (!token) return;
const res = await authFetch('/api/user-profile', {
method: 'GET',
headers: {
Authorization: `Bearer ${token}`,
'Content-Type': 'application/json',
},
});
if (!res || !res.ok) return;
const data = await res.json();
setFirstName(data.firstname || '');
setLastName(data.lastname || '');
setEmail(data.email || '');
setZipCode(data.zipcode || '');
setSelectedState(data.state || '');
setSelectedArea(data.area || '');
setCareerSituation(data.career_situation || '');
if (data.is_premium === 1) {
setIsPremiumUser(true);
}
if (data.state) {
setLoadingAreas(true);
try {
const areaRes = await authFetch(`/api/areas?state=${data.state}`);
if (!areaRes || !areaRes.ok) {
throw new Error('Failed to fetch areas');
}
const areaData = await areaRes.json();
setAreas(areaData.areas);
} catch (areaErr) {
console.error('Error fetching areas:', areaErr);
setAreas([]);
} finally {
setLoadingAreas(false);
}
}
} catch (error) {
console.error('Error loading user profile:', error);
}
};
fetchProfileAndAreas();
}, []); // only runs once
const handleFormSubmit = async (e) => {
e.preventDefault();
const profileData = {
firstName,
lastName,
email,
zipCode,
state: selectedState,
area: selectedArea,
careerSituation,
};
try {
const response = await authFetch('/api/user-profile', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(profileData),
});
if (!response || !response.ok) {
throw new Error('Failed to save profile');
}
console.log('Profile saved successfully');
} catch (error) {
console.error('Error saving profile:', error);
}
};
// FULL list of states, including all 50 states (+ DC if desired)
const states = [
{ name: 'Alabama', code: 'AL' },
{ name: 'Alaska', code: 'AK' },
{ name: 'Arizona', code: 'AZ' },
{ name: 'Arkansas', code: 'AR' },
{ name: 'California', code: 'CA' },
{ name: 'Colorado', code: 'CO' },
{ name: 'Connecticut', code: 'CT' },
{ name: 'Delaware', code: 'DE' },
{ name: 'District of Columbia', code: 'DC' },
{ name: 'Florida', code: 'FL' },
{ name: 'Georgia', code: 'GA' },
{ name: 'Hawaii', code: 'HI' },
{ name: 'Idaho', code: 'ID' },
{ name: 'Illinois', code: 'IL' },
{ name: 'Indiana', code: 'IN' },
{ name: 'Iowa', code: 'IA' },
{ name: 'Kansas', code: 'KS' },
{ name: 'Kentucky', code: 'KY' },
{ name: 'Louisiana', code: 'LA' },
{ name: 'Maine', code: 'ME' },
{ name: 'Maryland', code: 'MD' },
{ name: 'Massachusetts', code: 'MA' },
{ name: 'Michigan', code: 'MI' },
{ name: 'Minnesota', code: 'MN' },
{ name: 'Mississippi', code: 'MS' },
{ name: 'Missouri', code: 'MO' },
{ name: 'Montana', code: 'MT' },
{ name: 'Nebraska', code: 'NE' },
{ name: 'Nevada', code: 'NV' },
{ name: 'New Hampshire', code: 'NH' },
{ name: 'New Jersey', code: 'NJ' },
{ name: 'New Mexico', code: 'NM' },
{ name: 'New York', code: 'NY' },
{ name: 'North Carolina', code: 'NC' },
{ name: 'North Dakota', code: 'ND' },
{ name: 'Ohio', code: 'OH' },
{ name: 'Oklahoma', code: 'OK' },
{ name: 'Oregon', code: 'OR' },
{ name: 'Pennsylvania', code: 'PA' },
{ name: 'Rhode Island', code: 'RI' },
{ name: 'South Carolina', code: 'SC' },
{ name: 'South Dakota', code: 'SD' },
{ name: 'Tennessee', code: 'TN' },
{ name: 'Texas', code: 'TX' },
{ name: 'Utah', code: 'UT' },
{ name: 'Vermont', code: 'VT' },
{ name: 'Virginia', code: 'VA' },
{ name: 'Washington', code: 'WA' },
{ name: 'West Virginia', code: 'WV' },
{ name: 'Wisconsin', code: 'WI' },
{ name: 'Wyoming', code: 'WY' },
];
return (
<div className="flex min-h-screen items-center justify-center bg-gray-50 p-4">
<div className="w-full max-w-lg rounded-lg bg-white p-6 shadow-md">
<h2 className="mb-4 text-center text-2xl font-semibold">User Profile</h2>
<form onSubmit={handleFormSubmit} className="space-y-4">
{/* First Name */}
<div>
<label className="mb-1 block text-sm font-medium text-gray-700">
First Name:
</label>
<input
type="text"
value={firstName}
onChange={(e) => setFirstName(e.target.value)}
required
className="w-full rounded border border-gray-300 px-3 py-2 text-sm focus:border-blue-600 focus:outline-none"
/>
</div>
{/* Last Name */}
<div>
<label className="mb-1 block text-sm font-medium text-gray-700">
Last Name:
</label>
<input
type="text"
value={lastName}
onChange={(e) => setLastName(e.target.value)}
required
className="w-full rounded border border-gray-300 px-3 py-2 text-sm focus:border-blue-600 focus:outline-none"
/>
</div>
{/* Email */}
<div>
<label className="mb-1 block text-sm font-medium text-gray-700">
Email:
</label>
<input
type="email"
value={email}
onChange={(e) => setEmail(e.target.value)}
required
className="w-full rounded border border-gray-300 px-3 py-2 text-sm focus:border-blue-600 focus:outline-none"
/>
</div>
{/* ZIP Code */}
<div>
<label className="mb-1 block text-sm font-medium text-gray-700">
ZIP Code:
</label>
<input
type="text"
value={zipCode}
onChange={(e) => setZipCode(e.target.value)}
required
className="w-full rounded border border-gray-300 px-3 py-2 text-sm focus:border-blue-600 focus:outline-none"
/>
</div>
{/* State Dropdown */}
<div>
<label className="mb-1 block text-sm font-medium text-gray-700">
State:
</label>
<select
value={selectedState}
onChange={(e) => setSelectedState(e.target.value)}
required
className="w-full rounded border border-gray-300 px-3 py-2 text-sm focus:border-blue-600 focus:outline-none"
>
<option value="">Select a State</option>
{states.map((s) => (
<option key={s.code} value={s.code}>
{s.name}
</option>
))}
</select>
</div>
{/* Areas Dropdown */}
{loadingAreas ? (
<p className="text-sm text-gray-500">Loading areas...</p>
) : (
areas.length > 0 && (
<div>
<label className="mb-1 block text-sm font-medium text-gray-700">
Area:
</label>
<select
value={selectedArea}
onChange={(e) => setSelectedArea(e.target.value)}
required
className="w-full rounded border border-gray-300 px-3 py-2 text-sm focus:border-blue-600 focus:outline-none"
>
<option value="">Select an Area</option>
{areas.map((area, index) => (
<option key={index} value={area}>
{area}
</option>
))}
</select>
</div>
)
)}
{/* Premium-Only Field */}
{isPremiumUser && (
<div>
<label className="mb-1 block text-sm font-medium text-gray-700">
What best describes your current career situation?
</label>
<select
value={careerSituation}
onChange={(e) => setCareerSituation(e.target.value)}
className="w-full rounded border border-gray-300 px-3 py-2 text-sm focus:border-blue-600 focus:outline-none"
>
<option value="">Select One</option>
<option value="highSchool">High School Student</option>
<option value="collegeStudent">College Student</option>
<option value="transitioningPro">Transitioning Professional</option>
<option value="advancingPro">Advancing Professional</option>
</select>
</div>
)}
{/* Form Buttons */}
<div className="mt-6 flex items-center justify-end space-x-3">
<button
type="submit"
className="rounded bg-blue-600 px-5 py-2 text-white transition-colors hover:bg-green-700"
>
Save Profile
</button>
<button
type="button"
onClick={() => navigate('/getting-started')}
className="rounded bg-gray-300 px-5 py-2 text-gray-700 hover:bg-gray-400"
>
Go Back
</button>
</div>
</form>
</div>
</div>
);
}
export default UserProfile;