Signin/registration fixes, added SignInLanding.js
This commit is contained in:
parent
0e62ac4708
commit
ae3bfaadd1
@ -164,7 +164,6 @@ app.post('/api/register', async (req, res) => {
|
|||||||
(firstname, lastname, email, zipcode, state, area, career_situation)
|
(firstname, lastname, email, zipcode, state, area, career_situation)
|
||||||
VALUES (?, ?, ?, ?, ?, ?, ?)
|
VALUES (?, ?, ?, ?, ?, ?, ?)
|
||||||
`;
|
`;
|
||||||
|
|
||||||
pool.query(
|
pool.query(
|
||||||
profileQuery,
|
profileQuery,
|
||||||
[firstname, lastname, email, zipcode, state, area, career_situation],
|
[firstname, lastname, email, zipcode, state, area, career_situation],
|
||||||
@ -176,17 +175,14 @@ app.post('/api/register', async (req, res) => {
|
|||||||
.json({ error: 'Failed to create user profile' });
|
.json({ error: 'Failed to create user profile' });
|
||||||
}
|
}
|
||||||
|
|
||||||
const newProfileId = resultProfile.insertId; // auto-increment PK
|
const newProfileId = resultProfile.insertId; // auto-increment PK from user_profile
|
||||||
|
|
||||||
// 2) Insert into user_auth, referencing user_profile.id
|
// 2) Insert into user_auth
|
||||||
const authQuery = `
|
const authQuery = `
|
||||||
INSERT INTO user_auth (user_id, username, hashed_password)
|
INSERT INTO user_auth (user_id, username, hashed_password)
|
||||||
VALUES (?, ?, ?)
|
VALUES (?, ?, ?)
|
||||||
`;
|
`;
|
||||||
pool.query(
|
pool.query(authQuery, [newProfileId, username, hashedPassword], async (errAuth) => {
|
||||||
authQuery,
|
|
||||||
[newProfileId, username, hashedPassword],
|
|
||||||
(errAuth) => {
|
|
||||||
if (errAuth) {
|
if (errAuth) {
|
||||||
console.error('Error inserting user_auth:', errAuth.message);
|
console.error('Error inserting user_auth:', errAuth.message);
|
||||||
if (errAuth.code === 'ER_DUP_ENTRY') {
|
if (errAuth.code === 'ER_DUP_ENTRY') {
|
||||||
@ -197,12 +193,33 @@ app.post('/api/register', async (req, res) => {
|
|||||||
return res.status(500).json({ error: 'Failed to register user' });
|
return res.status(500).json({ error: 'Failed to register user' });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NEW: Now that we have the new user_profile.id (newProfileId),
|
||||||
|
// generate a JWT to auto-sign them in.
|
||||||
|
// We'll mimic what /api/signin does:
|
||||||
|
const token = jwt.sign({ id: newProfileId }, SECRET_KEY, {
|
||||||
|
expiresIn: '2h',
|
||||||
|
});
|
||||||
|
|
||||||
|
// Optionally fetch or build a user object. We already know:
|
||||||
|
// firstname, lastname, email, etc. from the request body.
|
||||||
|
const userPayload = {
|
||||||
|
firstname,
|
||||||
|
lastname,
|
||||||
|
email,
|
||||||
|
zipcode,
|
||||||
|
state,
|
||||||
|
area,
|
||||||
|
career_situation,
|
||||||
|
// any other fields you want
|
||||||
|
};
|
||||||
|
|
||||||
return res.status(201).json({
|
return res.status(201).json({
|
||||||
message: 'User registered successfully',
|
message: 'User registered successfully',
|
||||||
profileId: newProfileId, // the user_profile.id
|
profileId: newProfileId, // the user_profile.id
|
||||||
|
token, // NEW: the signed JWT
|
||||||
|
user: userPayload // optional: user info
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
@ -295,8 +312,6 @@ app.post('/api/signin', async (req, res) => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------------
|
/* ------------------------------------------------------------------
|
||||||
CHECK USERNAME (MySQL)
|
CHECK USERNAME (MySQL)
|
||||||
------------------------------------------------------------------ */
|
------------------------------------------------------------------ */
|
||||||
|
154
src/App.js
154
src/App.js
@ -9,11 +9,10 @@ import {
|
|||||||
} from 'react-router-dom';
|
} from 'react-router-dom';
|
||||||
import { Button } from './components/ui/button.js';
|
import { Button } from './components/ui/button.js';
|
||||||
import { cn } from './utils/cn.js';
|
import { cn } from './utils/cn.js';
|
||||||
|
import PromptModal from './components/ui/PromptModal.js';
|
||||||
// Import all components
|
|
||||||
import PremiumRoute from './components/PremiumRoute.js';
|
import PremiumRoute from './components/PremiumRoute.js';
|
||||||
import SessionExpiredHandler from './components/SessionExpiredHandler.js';
|
import SessionExpiredHandler from './components/SessionExpiredHandler.js';
|
||||||
import GettingStarted from './components/GettingStarted.js';
|
import SignInLanding from './components/SignInLanding.js';
|
||||||
import SignIn from './components/SignIn.js';
|
import SignIn from './components/SignIn.js';
|
||||||
import SignUp from './components/SignUp.js';
|
import SignUp from './components/SignUp.js';
|
||||||
import PlanningLanding from './components/PlanningLanding.js';
|
import PlanningLanding from './components/PlanningLanding.js';
|
||||||
@ -30,19 +29,26 @@ import CareerRoadmap from './components/CareerRoadmap.js';
|
|||||||
import Paywall from './components/Paywall.js';
|
import Paywall from './components/Paywall.js';
|
||||||
import OnboardingContainer from './components/PremiumOnboarding/OnboardingContainer.js';
|
import OnboardingContainer from './components/PremiumOnboarding/OnboardingContainer.js';
|
||||||
import MultiScenarioView from './components/MultiScenarioView.js';
|
import MultiScenarioView from './components/MultiScenarioView.js';
|
||||||
|
import ResumeRewrite from './components/ResumeRewrite.js';
|
||||||
// Import your ResumeRewrite component
|
|
||||||
import ResumeRewrite from './components/ResumeRewrite.js'; // adjust path if needed
|
|
||||||
|
|
||||||
function App() {
|
function App() {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const location = useLocation();
|
const location = useLocation();
|
||||||
|
|
||||||
|
// Auth states
|
||||||
const [isAuthenticated, setIsAuthenticated] = useState(false);
|
const [isAuthenticated, setIsAuthenticated] = useState(false);
|
||||||
const [user, setUser] = useState(null);
|
const [user, setUser] = useState(null);
|
||||||
|
|
||||||
|
// Loading state while verifying token
|
||||||
const [isLoading, setIsLoading] = useState(true);
|
const [isLoading, setIsLoading] = useState(true);
|
||||||
|
|
||||||
// Premium paths (including /enhancing, /retirement)
|
// Logout warning modal
|
||||||
|
const [showLogoutWarning, setShowLogoutWarning] = useState(false);
|
||||||
|
|
||||||
|
// Check if user can access premium
|
||||||
|
const canAccessPremium = user?.is_premium || user?.is_pro_premium;
|
||||||
|
|
||||||
|
// List of premium paths for your CTA logic
|
||||||
const premiumPaths = [
|
const premiumPaths = [
|
||||||
'/career-roadmap',
|
'/career-roadmap',
|
||||||
'/paywall',
|
'/paywall',
|
||||||
@ -55,60 +61,92 @@ function App() {
|
|||||||
];
|
];
|
||||||
const showPremiumCTA = !premiumPaths.includes(location.pathname);
|
const showPremiumCTA = !premiumPaths.includes(location.pathname);
|
||||||
|
|
||||||
// We'll define "canAccessPremium" for user
|
// Helper to see if user is mid–premium-onboarding
|
||||||
const canAccessPremium = user?.is_premium || user?.is_pro_premium;
|
function isOnboardingInProgress() {
|
||||||
|
try {
|
||||||
|
const stored = JSON.parse(localStorage.getItem('premiumOnboardingState') || '{}');
|
||||||
|
// If step < 4 (example), user is in progress
|
||||||
|
return stored.step && stored.step < 4;
|
||||||
|
} catch (e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ====================
|
// ==============================
|
||||||
// Single Rehydrate UseEffect
|
// 1) Single Rehydrate UseEffect
|
||||||
// ====================
|
// ==============================
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const token = localStorage.getItem('token');
|
const token = localStorage.getItem('token');
|
||||||
|
|
||||||
// No token? -> not authenticated
|
|
||||||
if (!token) {
|
if (!token) {
|
||||||
|
// No token => not authenticated
|
||||||
setIsLoading(false);
|
setIsLoading(false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Token exists, let's check with the server
|
// If we have a token, validate it by fetching user
|
||||||
fetch('https://dev1.aptivaai.com/api/user-profile', {
|
fetch('https://dev1.aptivaai.com/api/user-profile', {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
if (!res.ok) {
|
if (!res.ok) throw new Error('Token invalid on server side');
|
||||||
// For example, 401 => invalid or expired token
|
|
||||||
throw new Error('Token invalid on server side');
|
|
||||||
}
|
|
||||||
return res.json();
|
return res.json();
|
||||||
})
|
})
|
||||||
.then((profile) => {
|
.then((profile) => {
|
||||||
|
// Successfully got user profile => user is authenticated
|
||||||
setUser(profile);
|
setUser(profile);
|
||||||
setIsAuthenticated(true);
|
setIsAuthenticated(true);
|
||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
console.error(err);
|
console.error(err);
|
||||||
// Server says token invalid -> remove from localStorage
|
// Invalid token => remove it, force sign in
|
||||||
localStorage.removeItem('token');
|
localStorage.removeItem('token');
|
||||||
// Force user to sign in again
|
|
||||||
navigate('/signin?session=expired');
|
navigate('/signin?session=expired');
|
||||||
})
|
})
|
||||||
.finally(() => {
|
.finally(() => {
|
||||||
|
// Either success or fail, we're done loading
|
||||||
setIsLoading(false);
|
setIsLoading(false);
|
||||||
});
|
});
|
||||||
}, [navigate]);
|
}, [navigate]);
|
||||||
|
|
||||||
// ====================
|
// ==========================
|
||||||
// Logout Handler
|
// 2) Logout Handler + Modal
|
||||||
// ====================
|
// ==========================
|
||||||
const handleLogout = () => {
|
const handleLogoutClick = () => {
|
||||||
|
if (isOnboardingInProgress()) {
|
||||||
|
// Show a modal to confirm losing onboarding data
|
||||||
|
setShowLogoutWarning(true);
|
||||||
|
} else {
|
||||||
|
// No onboarding => just logout
|
||||||
|
confirmLogout();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const confirmLogout = () => {
|
||||||
|
// Clear relevant localStorage keys
|
||||||
localStorage.removeItem('token');
|
localStorage.removeItem('token');
|
||||||
localStorage.removeItem('careerSuggestionsCache');
|
localStorage.removeItem('careerSuggestionsCache');
|
||||||
|
localStorage.removeItem('lastSelectedCareerProfileId');
|
||||||
|
localStorage.removeItem('aiClickCount');
|
||||||
|
localStorage.removeItem('aiClickDate');
|
||||||
|
localStorage.removeItem('aiRecommendations');
|
||||||
|
localStorage.removeItem('premiumOnboardingState');
|
||||||
|
|
||||||
|
// Reset auth
|
||||||
setIsAuthenticated(false);
|
setIsAuthenticated(false);
|
||||||
setUser(null);
|
setUser(null);
|
||||||
|
setShowLogoutWarning(false);
|
||||||
|
|
||||||
navigate('/signin');
|
navigate('/signin');
|
||||||
};
|
};
|
||||||
|
|
||||||
// If we're still verifying the token, show a loading indicator
|
const cancelLogout = () => {
|
||||||
|
setShowLogoutWarning(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
// ====================================
|
||||||
|
// 3) If still verifying the token, show loading
|
||||||
|
// ====================================
|
||||||
if (isLoading) {
|
if (isLoading) {
|
||||||
return (
|
return (
|
||||||
<div className="flex h-screen items-center justify-center">
|
<div className="flex h-screen items-center justify-center">
|
||||||
@ -117,9 +155,9 @@ function App() {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ====================
|
// =====================
|
||||||
// Main App Render
|
// Main Render / Layout
|
||||||
// ====================
|
// =====================
|
||||||
return (
|
return (
|
||||||
<div className="flex min-h-screen flex-col bg-gray-50 text-gray-800">
|
<div className="flex min-h-screen flex-col bg-gray-50 text-gray-800">
|
||||||
{/* Header */}
|
{/* Header */}
|
||||||
@ -132,7 +170,7 @@ function App() {
|
|||||||
<>
|
<>
|
||||||
{/* NAV MENU */}
|
{/* NAV MENU */}
|
||||||
<nav className="flex space-x-6">
|
<nav className="flex space-x-6">
|
||||||
{/* 1) Find Your Career */}
|
{/* 1) Planning */}
|
||||||
<div className="relative group">
|
<div className="relative group">
|
||||||
<Button
|
<Button
|
||||||
style={{ color: '#1f2937' }}
|
style={{ color: '#1f2937' }}
|
||||||
@ -165,7 +203,7 @@ function App() {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* 2) Prepare for Your Career */}
|
{/* 2) Preparing */}
|
||||||
<div className="relative group">
|
<div className="relative group">
|
||||||
<Button
|
<Button
|
||||||
style={{ color: '#1f2937' }}
|
style={{ color: '#1f2937' }}
|
||||||
@ -192,7 +230,7 @@ function App() {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* 3) Enhancing Your Career (Premium) */}
|
{/* 3) Enhancing (Premium) */}
|
||||||
<div className="relative group">
|
<div className="relative group">
|
||||||
<Button
|
<Button
|
||||||
style={{ color: '#1f2937' }}
|
style={{ color: '#1f2937' }}
|
||||||
@ -227,28 +265,11 @@ function App() {
|
|||||||
>
|
>
|
||||||
Optimize Resume
|
Optimize Resume
|
||||||
</Link>
|
</Link>
|
||||||
<Link
|
{/* etc. */}
|
||||||
to="/networking"
|
|
||||||
className="block px-4 py-2 hover:bg-gray-100 text-sm text-gray-700"
|
|
||||||
>
|
|
||||||
Networking
|
|
||||||
</Link>
|
|
||||||
<Link
|
|
||||||
to="/interview-help"
|
|
||||||
className="block px-4 py-2 hover:bg-gray-100 text-sm text-gray-700"
|
|
||||||
>
|
|
||||||
Interview Help
|
|
||||||
</Link>
|
|
||||||
<Link
|
|
||||||
to="/job-search"
|
|
||||||
className="block px-4 py-2 hover:bg-gray-100 text-sm text-gray-700"
|
|
||||||
>
|
|
||||||
Job Search
|
|
||||||
</Link>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* 4) Retirement Planning (Premium) */}
|
{/* 4) Retirement (Premium) */}
|
||||||
<div className="relative group">
|
<div className="relative group">
|
||||||
<Button
|
<Button
|
||||||
style={{ color: '#1f2937' }}
|
style={{ color: '#1f2937' }}
|
||||||
@ -271,7 +292,7 @@ function App() {
|
|||||||
)}
|
)}
|
||||||
</Button>
|
</Button>
|
||||||
<div className="absolute top-full left-0 hidden group-hover:block bg-white border shadow-md w-56 z-50">
|
<div className="absolute top-full left-0 hidden group-hover:block bg-white border shadow-md w-56 z-50">
|
||||||
{/* Add more retirement submenu items if needed */}
|
{/* Additional retirement menu items */}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -331,18 +352,33 @@ function App() {
|
|||||||
Upgrade to Premium
|
Upgrade to Premium
|
||||||
</Button>
|
</Button>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
{/* LOGOUT BUTTON */}
|
||||||
<button
|
<button
|
||||||
className="text-red-600 hover:text-red-800 bg-transparent border-none"
|
className="text-red-600 hover:text-red-800 bg-transparent border-none"
|
||||||
onClick={handleLogout}
|
onClick={handleLogoutClick}
|
||||||
>
|
>
|
||||||
Logout
|
Logout
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
|
{/* SHOW WARNING MODAL IF needed */}
|
||||||
|
{showLogoutWarning && (
|
||||||
|
<PromptModal
|
||||||
|
open={true}
|
||||||
|
title="End Onboarding?"
|
||||||
|
message="If you sign out now, your onboarding progress will be lost. Are you sure?"
|
||||||
|
confirmText="Sign Out"
|
||||||
|
cancelText="Nevermind"
|
||||||
|
onConfirm={confirmLogout}
|
||||||
|
onCancel={cancelLogout}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
{/* Main Content */}
|
{/* MAIN CONTENT */}
|
||||||
<main className="flex-1 p-6">
|
<main className="flex-1 p-6">
|
||||||
<Routes>
|
<Routes>
|
||||||
{/* Default to /signin */}
|
{/* Default to /signin */}
|
||||||
@ -358,22 +394,22 @@ function App() {
|
|||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
<Route path="/signup" element={<SignUp />} />
|
<Route
|
||||||
|
path="/signup"
|
||||||
|
element={<SignUp setUser={setUser} />}
|
||||||
|
/>
|
||||||
<Route path="/paywall" element={<Paywall />} />
|
<Route path="/paywall" element={<Paywall />} />
|
||||||
|
|
||||||
{/* Authenticated routes */}
|
{/* Authenticated routes */}
|
||||||
{isAuthenticated && (
|
{isAuthenticated && (
|
||||||
<>
|
<>
|
||||||
<Route path="/getting-started" element={<GettingStarted />} />
|
<Route path="/signin-landing" element={<SignInLanding user={user} />}/>
|
||||||
<Route path="/interest-inventory" element={<InterestInventory />} />
|
<Route path="/interest-inventory" element={<InterestInventory />} />
|
||||||
<Route path="/dashboard" element={<Dashboard />} />
|
<Route path="/dashboard" element={<Dashboard />} />
|
||||||
<Route path="/profile" element={<UserProfile />} />
|
<Route path="/profile" element={<UserProfile />} />
|
||||||
<Route path="/planning" element={<PlanningLanding />} />
|
<Route path="/planning" element={<PlanningLanding />} />
|
||||||
<Route path="/career-explorer" element={<CareerExplorer />} />
|
<Route path="/career-explorer" element={<CareerExplorer />} />
|
||||||
<Route
|
<Route path="/educational-programs" element={<EducationalProgramsPage />} />
|
||||||
path="/educational-programs"
|
|
||||||
element={<EducationalProgramsPage />}
|
|
||||||
/>
|
|
||||||
<Route path="/preparing" element={<PreparingLanding />} />
|
<Route path="/preparing" element={<PreparingLanding />} />
|
||||||
|
|
||||||
{/* Premium-only routes */}
|
{/* Premium-only routes */}
|
||||||
|
@ -55,21 +55,8 @@ function SignIn({ setIsAuthenticated, setUser }) {
|
|||||||
// Store the full user object in state, so we can check user.is_premium, etc.
|
// Store the full user object in state, so we can check user.is_premium, etc.
|
||||||
if (setUser && user) {
|
if (setUser && user) {
|
||||||
setUser(user);
|
setUser(user);
|
||||||
}
|
|
||||||
|
|
||||||
const userCareerSituation = user.career_situation;
|
navigate('/signin-landing'); // fallback if undefined
|
||||||
|
|
||||||
const careerSituationRouteMap = {
|
|
||||||
planning: '/planning',
|
|
||||||
preparing: '/preparing',
|
|
||||||
enhancing: '/enhancing',
|
|
||||||
retirement: '/retirement',
|
|
||||||
};
|
|
||||||
|
|
||||||
if (careerSituationRouteMap[userCareerSituation]) {
|
|
||||||
navigate(careerSituationRouteMap[userCareerSituation]);
|
|
||||||
} else {
|
|
||||||
navigate('/getting-started'); // fallback if undefined
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
43
src/components/SignInLanding.js
Normal file
43
src/components/SignInLanding.js
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
// SignInLanding.jsx
|
||||||
|
import React from 'react';
|
||||||
|
import { Link } from 'react-router-dom';
|
||||||
|
|
||||||
|
function SignInLanding({ user }) {
|
||||||
|
return (
|
||||||
|
<div className="max-w-2xl mx-auto p-4 bg-white shadow rounded">
|
||||||
|
<h2 className="text-2xl font-semibold mb-4">
|
||||||
|
Welcome to AptivaAI {user?.firstname}!
|
||||||
|
</h2>
|
||||||
|
<p className="mb-4">
|
||||||
|
At AptivaAI, we aim to arm you with all the knowledge and guidance we wish we had when making our own career decisions. Today’s workplace is changing faster than ever, driven largely by AI—but our goal is to use that same technology to empower job seekers, not replace them.
|
||||||
|
|
||||||
|
We blend data-backed insights with human-centered design, giving you practical recommendations and real-world context so you stay in the driver’s seat of your career. Whether you’re planning your first step, enhancing your current role, or ready to pivot entirely, our platform keeps you in control—helping you adapt, grow, and thrive on your own terms.
|
||||||
|
</p>
|
||||||
|
<ul className="list-disc ml-6 mb-4">
|
||||||
|
<li><strong>Planning:</strong> Just starting out? Looking for a different career that is a better fit? Explore options and figure out what careers match your interests and skills.</li>
|
||||||
|
<li><strong>Preparing:</strong> Know what you want but just not how to get there? Gain education, skills, or certifications required to start or transition.</li>
|
||||||
|
<li><strong>Enhancing:</strong> You've got some experience in your field but want to know how to get to the next level? Advance, seek promotions, or shift roles for an established professional.</li>
|
||||||
|
<li><strong>Retirement:</strong> On your happy path and want to make sure you're financially ready when the time comes? Prepare financially and strategically for retirement.</li>
|
||||||
|
</ul>
|
||||||
|
<p className="mb-4">
|
||||||
|
Where would you like to go next?
|
||||||
|
</p>
|
||||||
|
<div className="space-x-2">
|
||||||
|
<Link to="/planning" className="inline-block px-4 py-2 bg-blue-600 text-white rounded hover:bg-blue-700">
|
||||||
|
Go to Planning
|
||||||
|
</Link>
|
||||||
|
<Link to="/preparing" className="inline-block px-4 py-2 bg-blue-600 text-white rounded hover:bg-blue-700">
|
||||||
|
Go to Preparing
|
||||||
|
</Link>
|
||||||
|
<Link to="/enhancing" className="inline-block px-4 py-2 bg-blue-600 text-white rounded hover:bg-blue-700">
|
||||||
|
Go to Enhancing
|
||||||
|
</Link>
|
||||||
|
<Link to="/retirement" className="inline-block px-4 py-2 bg-blue-600 text-white rounded hover:bg-blue-700">
|
||||||
|
Go to Retirement
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default SignInLanding;
|
@ -174,14 +174,11 @@ function SignUp() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// SignUp.jsx
|
||||||
const handleSituationConfirm = async () => {
|
const handleSituationConfirm = async () => {
|
||||||
|
setShowPrompt(false);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
console.log("Payload sent to backend:", {
|
|
||||||
username, password, firstname, lastname, email, zipcode, state, area,
|
|
||||||
career_situation: selectedSituation.id
|
|
||||||
});
|
|
||||||
|
|
||||||
const response = await fetch('/api/register', {
|
const response = await fetch('/api/register', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: { 'Content-Type': 'application/json' },
|
headers: { 'Content-Type': 'application/json' },
|
||||||
@ -199,23 +196,35 @@ function SignUp() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const data = await response.json();
|
const data = await response.json();
|
||||||
|
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
setError(data.error || 'Registration failed. Please try again.');
|
setError(data.error || 'Registration failed. Please try again.');
|
||||||
setShowPrompt(false);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If the server returns a token, store it so that App.js will consider them authenticated
|
||||||
|
if (data.token) {
|
||||||
|
localStorage.setItem('token', data.token);
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the server also returned 'user', set it in the main state
|
||||||
|
// But we need a way to pass "setUser" down to SignUp or use a context
|
||||||
|
if (data.user) {
|
||||||
|
setUsername(data.user);
|
||||||
|
} else {
|
||||||
|
// Optionally, fetch user from /api/user-profile:
|
||||||
|
// This ensures your user object is set in App.js
|
||||||
|
// But if your App.js auto-fetches the user from the token, you can skip this
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now that we have a token + user, let's direct them to the route
|
||||||
navigate(selectedSituation.route);
|
navigate(selectedSituation.route);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error(err);
|
console.error('Registration error:', err);
|
||||||
setError('An unexpected error occurred. Please try again later.');
|
setError('An unexpected error occurred. Please try again later.');
|
||||||
setShowPrompt(false);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex min-h-screen items-center justify-center bg-gray-100 p-4">
|
<div className="flex min-h-screen items-center justify-center bg-gray-100 p-4">
|
||||||
{!showCareerSituations ? (
|
{!showCareerSituations ? (
|
||||||
|
Loading…
Reference in New Issue
Block a user