244 lines
8.1 KiB
TypeScript
244 lines
8.1 KiB
TypeScript
import { useMemo, useState } from 'react';
|
|
import { localStorageService } from './mvvm/services/local-storage.service';
|
|
import { AuthPage } from './presentation/auth/pages/AuthPage';
|
|
import { AiAgentPage } from './presentation/ai-agent/pages/AiAgentPage';
|
|
import { CareerAgentPage } from './presentation/ai-agent/pages/CareerAgentPage';
|
|
import { CvPage } from './presentation/cv/pages/CvPage';
|
|
import type { DashboardNavKey } from './presentation/dashboard/components/DashboardSidebar';
|
|
import { DashboardPage } from './presentation/dashboard/pages/DashboardPage';
|
|
import { HomePage } from './presentation/home/pages/HomePage';
|
|
import { JobDetailPage } from './presentation/jobs/pages/JobDetailPage';
|
|
import { JobsPage } from './presentation/jobs/pages/JobsPage';
|
|
import { MessagesPage } from './presentation/messages/pages/MessagesPage';
|
|
import { PricingPage } from './presentation/pricing/pages/PricingPage';
|
|
import { JobordbogenPage } from './presentation/jobordbogen/pages/JobordbogenPage';
|
|
import { JobordbogenEntryPage } from './presentation/jobordbogen/pages/JobordbogenEntryPage';
|
|
import { StoriesPage } from './presentation/stories/pages/StoriesPage';
|
|
import { NewsletterPage } from './presentation/newsletter/pages/NewsletterPage';
|
|
import { ForVirksomhederPage } from './presentation/companies/pages/ForVirksomhederPage';
|
|
import { JobSearchersPage } from './presentation/jobseekers/pages/JobSearchersPage';
|
|
import { ContactPage } from './presentation/contact/pages/ContactPage';
|
|
import {
|
|
SimulatorPage,
|
|
type SimulatorEvaluationSelection,
|
|
} from './presentation/simulator/pages/SimulatorPage';
|
|
import { SimulatorEvaluationPage } from './presentation/simulator/pages/SimulatorEvaluationPage';
|
|
import { SubscriptionPage } from './presentation/subscription/pages/SubscriptionPage';
|
|
|
|
type AppPage = DashboardNavKey | 'job-detail' | 'simulator-evaluation';
|
|
|
|
interface JobDetailSelection {
|
|
id: string;
|
|
fromJobnet: boolean;
|
|
returnPage: DashboardNavKey;
|
|
}
|
|
|
|
function App() {
|
|
const isHomeRoute = useMemo(() => window.location.pathname === '/home', []);
|
|
const isPricingRoute = useMemo(() => window.location.pathname === '/pricing' || window.location.pathname === '/priser', []);
|
|
const isStoriesRoute = useMemo(() => window.location.pathname === '/stories', []);
|
|
const isNewsletterRoute = useMemo(() => window.location.pathname === '/newsletter', []);
|
|
const isCompaniesRoute = useMemo(() => window.location.pathname === '/for-virksomheder' || window.location.pathname === '/virksomheder', []);
|
|
const isJobseekersRoute = useMemo(() => window.location.pathname === '/for-jobsogere' || window.location.pathname === '/jobsearchers', []);
|
|
const isContactRoute = useMemo(() => window.location.pathname === '/kontakt' || window.location.pathname === '/contact', []);
|
|
const isJobordbogenEntryRoute = useMemo(() => window.location.pathname.startsWith('/jobordbogen/') && window.location.pathname !== '/jobordbogen/', []);
|
|
const isJobordbogenRoute = useMemo(() => window.location.pathname === '/jobordbogen' || window.location.pathname === '/academy', []);
|
|
const initialAuthenticated = useMemo(() => Boolean(window.localStorage.getItem('token')), []);
|
|
const initialTheme = useMemo<'light' | 'dark'>(() => {
|
|
const stored = window.localStorage.getItem('theme');
|
|
return stored === 'dark' ? 'dark' : 'light';
|
|
}, []);
|
|
const [isAuthenticated, setIsAuthenticated] = useState(initialAuthenticated);
|
|
const [theme, setTheme] = useState<'light' | 'dark'>(initialTheme);
|
|
const [activePage, setActivePage] = useState<AppPage>('dashboard');
|
|
const [jobDetailSelection, setJobDetailSelection] = useState<JobDetailSelection | null>(null);
|
|
const [evaluationSelection, setEvaluationSelection] = useState<SimulatorEvaluationSelection | null>(null);
|
|
|
|
function handleNavigate(target: DashboardNavKey) {
|
|
if (
|
|
target === 'dashboard'
|
|
|| target === 'jobs'
|
|
|| target === 'cv'
|
|
|| target === 'messages'
|
|
|| target === 'agents'
|
|
|| target === 'ai-agent'
|
|
|| target === 'simulator'
|
|
|| target === 'subscription'
|
|
) {
|
|
setActivePage(target);
|
|
}
|
|
}
|
|
|
|
function handleOpenJobDetail(id: string, fromJobnet: boolean, returnPage: DashboardNavKey = 'jobs') {
|
|
setJobDetailSelection({ id, fromJobnet, returnPage });
|
|
setActivePage('job-detail');
|
|
}
|
|
|
|
function handleBackFromJobDetail() {
|
|
setActivePage(jobDetailSelection?.returnPage ?? 'jobs');
|
|
}
|
|
|
|
function handleOpenSimulatorEvaluation(selection: SimulatorEvaluationSelection) {
|
|
setEvaluationSelection(selection);
|
|
setActivePage('simulator-evaluation');
|
|
}
|
|
|
|
function handleBackFromSimulatorEvaluation() {
|
|
setActivePage('simulator');
|
|
}
|
|
|
|
async function handleLogout() {
|
|
await localStorageService.clearCredentials();
|
|
setActivePage('dashboard');
|
|
setJobDetailSelection(null);
|
|
setEvaluationSelection(null);
|
|
setIsAuthenticated(false);
|
|
}
|
|
|
|
function handleToggleTheme() {
|
|
setTheme((current) => {
|
|
const next = current === 'light' ? 'dark' : 'light';
|
|
window.localStorage.setItem('theme', next);
|
|
return next;
|
|
});
|
|
}
|
|
|
|
if (isHomeRoute) {
|
|
return <HomePage />;
|
|
}
|
|
|
|
if (isPricingRoute) {
|
|
return <PricingPage />;
|
|
}
|
|
|
|
if (isStoriesRoute) {
|
|
return <StoriesPage />;
|
|
}
|
|
|
|
if (isNewsletterRoute) {
|
|
return <NewsletterPage />;
|
|
}
|
|
|
|
if (isCompaniesRoute) {
|
|
return <ForVirksomhederPage />;
|
|
}
|
|
|
|
if (isJobseekersRoute) {
|
|
return <JobSearchersPage />;
|
|
}
|
|
|
|
if (isContactRoute) {
|
|
return <ContactPage />;
|
|
}
|
|
|
|
if (isJobordbogenEntryRoute) {
|
|
return <JobordbogenEntryPage />;
|
|
}
|
|
|
|
if (isJobordbogenRoute) {
|
|
return <JobordbogenPage />;
|
|
}
|
|
|
|
if (!isAuthenticated) {
|
|
return <AuthPage onAuthenticated={() => setIsAuthenticated(true)} />;
|
|
}
|
|
|
|
if (activePage === 'jobs') {
|
|
return (
|
|
<JobsPage
|
|
onLogout={handleLogout}
|
|
onNavigate={handleNavigate}
|
|
onOpenJobDetail={handleOpenJobDetail}
|
|
theme={theme}
|
|
onToggleTheme={handleToggleTheme}
|
|
/>
|
|
);
|
|
}
|
|
|
|
if (activePage === 'cv') {
|
|
return <CvPage onLogout={handleLogout} onNavigate={handleNavigate} theme={theme} onToggleTheme={handleToggleTheme} />;
|
|
}
|
|
|
|
if (activePage === 'messages') {
|
|
return <MessagesPage onLogout={handleLogout} onNavigate={handleNavigate} theme={theme} onToggleTheme={handleToggleTheme} />;
|
|
}
|
|
|
|
if (activePage === 'agents') {
|
|
return (
|
|
<AiAgentPage
|
|
onLogout={handleLogout}
|
|
onNavigate={handleNavigate}
|
|
onOpenJobDetail={handleOpenJobDetail}
|
|
theme={theme}
|
|
onToggleTheme={handleToggleTheme}
|
|
/>
|
|
);
|
|
}
|
|
|
|
if (activePage === 'ai-agent') {
|
|
return (
|
|
<CareerAgentPage
|
|
onLogout={handleLogout}
|
|
onNavigate={handleNavigate}
|
|
theme={theme}
|
|
onToggleTheme={handleToggleTheme}
|
|
/>
|
|
);
|
|
}
|
|
|
|
if (activePage === 'simulator') {
|
|
return (
|
|
<SimulatorPage
|
|
onLogout={handleLogout}
|
|
onNavigate={handleNavigate}
|
|
onOpenEvaluation={handleOpenSimulatorEvaluation}
|
|
theme={theme}
|
|
onToggleTheme={handleToggleTheme}
|
|
/>
|
|
);
|
|
}
|
|
|
|
if (activePage === 'simulator-evaluation' && evaluationSelection) {
|
|
return (
|
|
<SimulatorEvaluationPage
|
|
interviewSelection={evaluationSelection}
|
|
onBack={handleBackFromSimulatorEvaluation}
|
|
onLogout={handleLogout}
|
|
onNavigate={handleNavigate}
|
|
theme={theme}
|
|
onToggleTheme={handleToggleTheme}
|
|
/>
|
|
);
|
|
}
|
|
|
|
if (activePage === 'subscription') {
|
|
return <SubscriptionPage onLogout={handleLogout} onNavigate={handleNavigate} theme={theme} onToggleTheme={handleToggleTheme} />;
|
|
}
|
|
|
|
if (activePage === 'job-detail' && jobDetailSelection) {
|
|
return (
|
|
<JobDetailPage
|
|
jobId={jobDetailSelection.id}
|
|
fromJobnet={jobDetailSelection.fromJobnet}
|
|
onBack={handleBackFromJobDetail}
|
|
onLogout={handleLogout}
|
|
onNavigate={handleNavigate}
|
|
theme={theme}
|
|
onToggleTheme={handleToggleTheme}
|
|
/>
|
|
);
|
|
}
|
|
|
|
return (
|
|
<DashboardPage
|
|
onLogout={handleLogout}
|
|
onNavigate={handleNavigate}
|
|
onOpenJobDetail={handleOpenJobDetail}
|
|
theme={theme}
|
|
onToggleTheme={handleToggleTheme}
|
|
/>
|
|
);
|
|
}
|
|
|
|
export default App;
|