250 lines
10 KiB
TypeScript
250 lines
10 KiB
TypeScript
import React, { ReactElement, useEffect, useState, useRef, useCallback} from 'react';
|
|
import { Box, Typography, Container, Paper } from '@mui/material';
|
|
import { Route, Routes, useLocation, useNavigate } from 'react-router-dom';
|
|
import DashboardIcon from '@mui/icons-material/Dashboard';
|
|
import PersonIcon from '@mui/icons-material/Person';
|
|
import ChatIcon from '@mui/icons-material/Chat';
|
|
import HistoryIcon from '@mui/icons-material/History';
|
|
import DescriptionIcon from '@mui/icons-material/Description';
|
|
import QuestionAnswerIcon from '@mui/icons-material/QuestionAnswer';
|
|
import BarChartIcon from '@mui/icons-material/BarChart';
|
|
import SettingsIcon from '@mui/icons-material/Settings';
|
|
import SearchIcon from '@mui/icons-material/Search';
|
|
import BookmarkIcon from '@mui/icons-material/Bookmark';
|
|
import WorkIcon from '@mui/icons-material/Work';
|
|
import InfoIcon from '@mui/icons-material/Info';
|
|
import BusinessIcon from '@mui/icons-material/Business';
|
|
import { SxProps, Theme } from '@mui/material';
|
|
import { ThemeProvider } from '@mui/material/styles';
|
|
|
|
import {Header} from './Components/Header';
|
|
import { Scrollable } from '../Components/Scrollable';
|
|
import { Footer } from './Components/Footer';
|
|
import { HomePage } from './Pages/HomePage';
|
|
// import { BackstoryThemeVisualizer } from './BackstoryThemeVisualizer';
|
|
import { HomePage as ChatPage } from '../Pages/HomePage';
|
|
import { ResumeBuilderPage } from '../Pages/ResumeBuilderPage';
|
|
import { Snack, SeverityType } from '../Components/Snack';
|
|
import { Query } from '../Components/ChatQuery';
|
|
import { ConversationHandle } from '../Components/Conversation';
|
|
import { AboutPage } from './Pages/AboutPage';
|
|
import { backstoryTheme } from '../BackstoryTheme';
|
|
|
|
import '@fontsource/roboto/300.css';
|
|
import '@fontsource/roboto/400.css';
|
|
import '@fontsource/roboto/500.css';
|
|
import '@fontsource/roboto/700.css';
|
|
import { VectorVisualizerPage } from 'Pages/VectorVisualizerPage';
|
|
|
|
type NavigationLinkType = {
|
|
name: string;
|
|
path: string;
|
|
icon?: ReactElement<any>;
|
|
label?: ReactElement<any>;
|
|
};
|
|
|
|
const DefaultNavItems : NavigationLinkType[] = [
|
|
{ name: 'Chat', path: '/chat', icon: <ChatIcon /> },
|
|
{ name: 'Resume Builder', path: '/resume-builder', icon: <WorkIcon /> },
|
|
{ name: 'RAG Visualizer', path: '/rag-visualizer', icon: <WorkIcon /> },
|
|
{ name: 'About', path: '/about', icon: <InfoIcon /> },
|
|
// { name: 'How It Works', path: '/how-it-works', icon: <InfoIcon/> },
|
|
// { name: 'For Candidates', path: '/for-candidates', icon: <PersonIcon/> },
|
|
// { name: 'For Employers', path: '/for-employers', icon: <BusinessIcon/> },
|
|
// { name: 'Pricing', path: '/pricing', icon: <AttachMoneyIcon/> },
|
|
];
|
|
|
|
const CandidateNavItems : NavigationLinkType[]= [
|
|
{ name: 'Dashboard', icon: <DashboardIcon />, path: '/dashboard' },
|
|
{ name: 'Profile', icon: <PersonIcon />, path: '/profile' },
|
|
{ name: 'Backstory', icon: <HistoryIcon />, path: '/backstory' },
|
|
{ name: 'Resumes', icon: <DescriptionIcon />, path: '/resumes' },
|
|
{ name: 'Q&A Setup', icon: <QuestionAnswerIcon />, path: '/qa-setup' },
|
|
{ name: 'Analytics', icon: <BarChartIcon />, path: '/analytics' },
|
|
{ name: 'Settings', icon: <SettingsIcon />, path: '/settings' },
|
|
];
|
|
|
|
const EmployerNavItems: NavigationLinkType[] = [
|
|
{ name: 'Dashboard', icon: <DashboardIcon />, path: '/dashboard' },
|
|
{ name: 'Search', icon: <SearchIcon />, path: '/search' },
|
|
{ name: 'Saved', icon: <BookmarkIcon />, path: '/saved' },
|
|
{ name: 'Jobs', icon: <WorkIcon />, path: '/jobs' },
|
|
{ name: 'Company', icon: <BusinessIcon />, path: '/company' },
|
|
{ name: 'Analytics', icon: <BarChartIcon />, path: '/analytics' },
|
|
{ name: 'Settings', icon: <SettingsIcon />, path: '/settings' },
|
|
];
|
|
|
|
// Navigation links based on user type
|
|
const getNavigationLinks = (userType: string, isLoggedIn: boolean) : NavigationLinkType[] => {
|
|
if (!isLoggedIn) {
|
|
return DefaultNavItems;
|
|
}
|
|
|
|
if (userType === 'candidate') {
|
|
return CandidateNavItems;
|
|
}
|
|
|
|
// Employer navigation
|
|
return EmployerNavItems;
|
|
};
|
|
|
|
// Placeholder for page components
|
|
const DashboardPage = () => <Box p={3}><Typography variant="h4">Dashboard</Typography></Box>;
|
|
const ProfilePage = () => <Box p={3}><Typography variant="h4">Profile</Typography></Box>;
|
|
const BackstoryPage = () => <Box p={3}><Typography variant="h4">Backstory</Typography></Box>;
|
|
const ResumesPage = () => <Box p={3}><Typography variant="h4">Resumes</Typography></Box>;
|
|
const QASetupPage = () => <Box p={3}><Typography variant="h4">Q&A Setup</Typography></Box>;
|
|
const AnalyticsPage = () => <Box p={3}><Typography variant="h4">Analytics</Typography></Box>;
|
|
const SettingsPage = () => <Box p={3}><Typography variant="h4">Settings</Typography></Box>;
|
|
const SearchPage = () => <Box p={3}><Typography variant="h4">Search</Typography></Box>;
|
|
const SavedPage = () => <Box p={3}><Typography variant="h4">Saved</Typography></Box>;
|
|
const JobsPage = () => <Box p={3}><Typography variant="h4">Jobs</Typography></Box>;
|
|
const CompanyPage = () => <Box p={3}><Typography variant="h4">Company</Typography></Box>;
|
|
|
|
// This is a placeholder for your actual user context
|
|
type UserContext = {
|
|
user: {
|
|
type: string;
|
|
name: string;
|
|
avatar?: any;
|
|
};
|
|
isAuthenticated: boolean;
|
|
logout: () => void;
|
|
};
|
|
|
|
const useUserContext = () : UserContext => {
|
|
return {
|
|
user: {
|
|
type: 'candidate', // or 'employer'
|
|
name: 'John Doe',
|
|
avatar: null,
|
|
},
|
|
isAuthenticated: false,
|
|
logout: () => console.log('Logging out'),
|
|
};
|
|
};
|
|
|
|
interface BackstoryPageContainerProps {
|
|
children?: React.ReactNode;
|
|
sx?: SxProps<Theme>;
|
|
userContext: UserContext;
|
|
};
|
|
|
|
const BackstoryPageContainer = (props : BackstoryPageContainerProps) => {
|
|
const { children, sx } = props;
|
|
return (
|
|
<Container maxWidth="xl" sx={{ mt: 2, mb: 2, height: "calc(1024px - 72px)", ...sx }}>
|
|
<Paper
|
|
elevation={2}
|
|
sx={{
|
|
p: 3,
|
|
backgroundColor: 'background.paper',
|
|
borderRadius: 2,
|
|
minHeight: '80vh',
|
|
}}
|
|
>
|
|
<Scrollable>
|
|
{children}
|
|
</Scrollable>
|
|
</Paper>
|
|
</Container>
|
|
);
|
|
}
|
|
const BackstoryApp = () => {
|
|
const navigate = useNavigate();
|
|
const location = useLocation();
|
|
const userContext : UserContext = useUserContext();
|
|
const { user, isAuthenticated } = userContext;
|
|
const [navigationLinks, setNavigationLinks] = useState<NavigationLinkType[]>([]);
|
|
const snackRef = useRef<any>(null);
|
|
const chatRef = useRef<ConversationHandle>(null);
|
|
const setSnack = useCallback((message: string, severity?: SeverityType) => {
|
|
snackRef.current?.setSnack(message, severity);
|
|
}, [snackRef]);
|
|
const submitQuery = (query: Query) => {
|
|
console.log(`handleSubmitChatQuery:`, query, chatRef.current ? ' sending' : 'no handler');
|
|
chatRef.current?.submitQuery(query);
|
|
navigate('/chat');
|
|
};
|
|
const [page, setPage] = useState<string>("");
|
|
|
|
useEffect(() => {
|
|
const currentRoute = location.pathname.split("/")[1] ? `/${location.pathname.split("/")[1]}` : "/";
|
|
setPage(currentRoute);
|
|
}, [location.pathname]);
|
|
|
|
useEffect(() => {
|
|
setNavigationLinks(getNavigationLinks(user.type, isAuthenticated));
|
|
}, [user.type, isAuthenticated]);
|
|
|
|
// Render appropriate routes based on user type
|
|
return (
|
|
<ThemeProvider theme={backstoryTheme}>
|
|
<Header currentPath={page} navigate={navigate} navigationLinks={navigationLinks} showLogin={false}/>
|
|
<Box sx={{ display: "flex", minHeight: "72px", height: "72px" }}/>
|
|
<Scrollable sx={{
|
|
display: 'flex',
|
|
flexDirection: 'column',
|
|
backgroundColor: 'background.default',
|
|
maxHeight: "calc(100vh - 72px)",
|
|
}}>
|
|
<BackstoryPageContainer userContext={userContext}>
|
|
<Routes>
|
|
<Route path="/chat" element={<ChatPage ref={chatRef} setSnack={setSnack} sessionId={"684a0c7e-e638-4db7-b00d-0558bfefb710"} submitQuery={submitQuery}/>} />
|
|
<Route path="/about" element={<AboutPage setSnack={setSnack} sessionId={"684a0c7e-e638-4db7-b00d-0558bfefb710"} submitQuery={submitQuery}/>} />
|
|
<Route path="/about/:subPage" element={<AboutPage setSnack={setSnack} sessionId={"684a0c7e-e638-4db7-b00d-0558bfefb710"} submitQuery={submitQuery}/>} />
|
|
<Route path="/resume-builder" element={<ResumeBuilderPage setSnack={setSnack} sessionId={"684a0c7e-e638-4db7-b00d-0558bfefb710"} submitQuery={submitQuery}/>} />
|
|
<Route path="/rag-visualizer" element={<VectorVisualizerPage setSnack={setSnack} sessionId={"684a0c7e-e638-4db7-b00d-0558bfefb710"} submitQuery={submitQuery} />} />
|
|
<Route path="/dashboard" element={<DashboardPage />} />
|
|
<Route path="/" element={<HomePage/>}/>
|
|
{/* Candidate-specific routes */}
|
|
{user.type === 'candidate' && (
|
|
<>
|
|
<Route path="/profile" element={<ProfilePage />} />
|
|
<Route path="/backstory" element={<BackstoryPage />} />
|
|
<Route path="/resumes" element={<ResumesPage />} />
|
|
<Route path="/qa-setup" element={<QASetupPage />} />
|
|
</>
|
|
)}
|
|
|
|
{/* Employer-specific routes */}
|
|
{user.type === 'employer' && (
|
|
<>
|
|
<Route path="/search" element={<SearchPage />} />
|
|
<Route path="/saved" element={<SavedPage />} />
|
|
<Route path="/jobs" element={<JobsPage />} />
|
|
<Route path="/company" element={<CompanyPage />} />
|
|
</>
|
|
)}
|
|
|
|
{/* Common routes */}
|
|
<Route path="/analytics" element={<AnalyticsPage />} />
|
|
<Route path="/settings" element={<SettingsPage />} />
|
|
|
|
{/* Redirect to dashboard by default */}
|
|
<Route path="*" element={<HomePage />} />
|
|
</Routes>
|
|
</BackstoryPageContainer>
|
|
{ location.pathname === "/" && <Footer /> }
|
|
</Scrollable>
|
|
<Snack ref={snackRef}/>
|
|
</ThemeProvider>
|
|
);
|
|
|
|
};
|
|
|
|
const App = () => {
|
|
return (
|
|
<BackstoryApp />
|
|
);
|
|
};
|
|
|
|
|
|
export type {
|
|
UserContext,
|
|
NavigationLinkType
|
|
};
|
|
|
|
export {
|
|
BackstoryApp
|
|
}; |