Restructured for menus
This commit is contained in:
parent
38635f0fd4
commit
43b332bd47
@ -89,7 +89,7 @@ const BackstoryLayout: React.FC<BackstoryLayoutProps> = (props: BackstoryLayoutP
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const userType = user?.userType || null;
|
const userType = user?.userType || null;
|
||||||
setNavigationItems(getMainNavigationItems(userType));
|
setNavigationItems(getMainNavigationItems(userType, user?.isAdmin ? true : false));
|
||||||
}, [user]);
|
}, [user]);
|
||||||
|
|
||||||
// Generate dynamic routes from navigation config
|
// Generate dynamic routes from navigation config
|
||||||
@ -97,7 +97,10 @@ const BackstoryLayout: React.FC<BackstoryLayoutProps> = (props: BackstoryLayoutP
|
|||||||
if (!guest) return null;
|
if (!guest) return null;
|
||||||
|
|
||||||
const userType = user?.userType || null;
|
const userType = user?.userType || null;
|
||||||
const routes = getAllRoutes(userType);
|
const isAdmin = user?.isAdmin ? true : false;
|
||||||
|
|
||||||
|
// Get all routes from navigation config
|
||||||
|
const routes = getAllRoutes(userType, isAdmin);
|
||||||
|
|
||||||
return routes.map((route, index) => {
|
return routes.map((route, index) => {
|
||||||
if (!route.path || !route.component) return null;
|
if (!route.path || !route.component) return null;
|
||||||
|
@ -17,9 +17,10 @@ interface BackstoryDynamicRoutesProps extends BackstoryPageProps {
|
|||||||
const getBackstoryDynamicRoutes = (props: BackstoryDynamicRoutesProps): ReactNode => {
|
const getBackstoryDynamicRoutes = (props: BackstoryDynamicRoutesProps): ReactNode => {
|
||||||
const { user, chatRef } = props;
|
const { user, chatRef } = props;
|
||||||
const userType = user?.userType || null;
|
const userType = user?.userType || null;
|
||||||
|
const isAdmin = user?.isAdmin ? true : false;
|
||||||
|
|
||||||
// Get all routes from navigation config
|
// Get all routes from navigation config
|
||||||
const routes = getAllRoutes(userType);
|
const routes = getAllRoutes(userType, isAdmin);
|
||||||
|
|
||||||
return routes.map((route: NavigationItem, index: number) => {
|
return routes.map((route: NavigationItem, index: number) => {
|
||||||
if (!route.path || !route.component) return null;
|
if (!route.path || !route.component) return null;
|
||||||
|
@ -38,6 +38,7 @@ import {
|
|||||||
ExpandLess,
|
ExpandLess,
|
||||||
KeyboardArrowDown,
|
KeyboardArrowDown,
|
||||||
} from '@mui/icons-material';
|
} from '@mui/icons-material';
|
||||||
|
import FaceRetouchingNaturalIcon from '@mui/icons-material/FaceRetouchingNatural';
|
||||||
|
|
||||||
import { NavigationItem } from 'types/navigation';
|
import { NavigationItem } from 'types/navigation';
|
||||||
import { Beta } from 'components/ui/Beta';
|
import { Beta } from 'components/ui/Beta';
|
||||||
@ -47,6 +48,7 @@ import { CopyBubble } from 'components/CopyBubble';
|
|||||||
|
|
||||||
import 'components/layout/Header.css';
|
import 'components/layout/Header.css';
|
||||||
import { useAuth } from 'hooks/AuthContext';
|
import { useAuth } from 'hooks/AuthContext';
|
||||||
|
import { useAppState } from 'hooks/GlobalContext';
|
||||||
|
|
||||||
// Styled components
|
// Styled components
|
||||||
const StyledAppBar = styled(AppBar, {
|
const StyledAppBar = styled(AppBar, {
|
||||||
@ -123,16 +125,15 @@ interface HeaderProps {
|
|||||||
|
|
||||||
const Header: React.FC<HeaderProps> = (props: HeaderProps) => {
|
const Header: React.FC<HeaderProps> = (props: HeaderProps) => {
|
||||||
const { user, logout } = useAuth();
|
const { user, logout } = useAuth();
|
||||||
const candidate: Candidate | null = (user && user.userType === "candidate") ? user as Candidate : null;
|
|
||||||
const employer: Employer | null = (user && user.userType === "employer") ? user as Employer : null;
|
|
||||||
const {
|
const {
|
||||||
transparent = false,
|
transparent = false,
|
||||||
className,
|
className,
|
||||||
navigate,
|
navigate,
|
||||||
navigationItems,
|
navigationItems,
|
||||||
sessionId,
|
sessionId,
|
||||||
setSnack,
|
|
||||||
} = props;
|
} = props;
|
||||||
|
|
||||||
|
const { setSnack } = useAppState();
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
const location = useLocation();
|
const location = useLocation();
|
||||||
|
|
||||||
@ -186,6 +187,16 @@ const Header: React.FC<HeaderProps> = (props: HeaderProps) => {
|
|||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
|
if (user?.isAdmin) {
|
||||||
|
const divider = userMenuItems.findIndex(p => p.id === 'divider');
|
||||||
|
if (divider !== -1) {
|
||||||
|
userMenuItems.splice(divider, 0, ...[
|
||||||
|
{ id: 'divider', label: '', icon: null, action: () => { } },
|
||||||
|
{ id: 'generate', label: 'Generate Candidate', icon: <FaceRetouchingNaturalIcon fontSize="small" />, action: () => { navigate('/admin/generate-candidate'); } }
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Helper function to check if current path matches navigation item
|
// Helper function to check if current path matches navigation item
|
||||||
const isCurrentPath = (item: NavigationItem): boolean => {
|
const isCurrentPath = (item: NavigationItem): boolean => {
|
||||||
if (!item.path) return false;
|
if (!item.path) return false;
|
||||||
|
@ -11,13 +11,19 @@ import {
|
|||||||
Info as InfoIcon,
|
Info as InfoIcon,
|
||||||
Person as PersonIcon,
|
Person as PersonIcon,
|
||||||
Business as BusinessIcon,
|
Business as BusinessIcon,
|
||||||
|
Quiz as QuizIcon,
|
||||||
|
Analytics as AnalyticsIcon,
|
||||||
Search as SearchIcon,
|
Search as SearchIcon,
|
||||||
Bookmark as BookmarkIcon,
|
Bookmark as BookmarkIcon,
|
||||||
History as HistoryIcon,
|
History as HistoryIcon,
|
||||||
QuestionAnswer as QuestionAnswerIcon,
|
QuestionAnswer as QuestionAnswerIcon,
|
||||||
AttachMoney as AttachMoneyIcon,
|
AttachMoney as AttachMoneyIcon,
|
||||||
|
BubbleChart,
|
||||||
|
InsertEmoticon,
|
||||||
} from '@mui/icons-material';
|
} from '@mui/icons-material';
|
||||||
|
import FaceRetouchingNaturalIcon from '@mui/icons-material/FaceRetouchingNatural';
|
||||||
|
import LibraryBooksIcon from '@mui/icons-material/LibraryBooks';
|
||||||
|
import PersonSearchIcon from '@mui/icons-material/PersonSearch';
|
||||||
import { BackstoryLogo } from 'components/ui/BackstoryLogo';
|
import { BackstoryLogo } from 'components/ui/BackstoryLogo';
|
||||||
import { HomePage } from 'pages/HomePage';
|
import { HomePage } from 'pages/HomePage';
|
||||||
import { CandidateChatPage } from 'pages/CandidateChatPage';
|
import { CandidateChatPage } from 'pages/CandidateChatPage';
|
||||||
@ -29,17 +35,19 @@ import { BetaPage } from 'pages/BetaPage';
|
|||||||
import { CandidateListingPage } from 'pages/FindCandidatePage';
|
import { CandidateListingPage } from 'pages/FindCandidatePage';
|
||||||
import { JobAnalysisPage } from 'pages/JobAnalysisPage';
|
import { JobAnalysisPage } from 'pages/JobAnalysisPage';
|
||||||
import { GenerateCandidate } from 'pages/GenerateCandidate';
|
import { GenerateCandidate } from 'pages/GenerateCandidate';
|
||||||
import { ControlsPage } from 'pages/ControlsPage';
|
import { Settings } from 'pages/candidate/Settings';
|
||||||
import { LoginPage } from 'pages/LoginPage';
|
import { LoginPage } from 'pages/LoginPage';
|
||||||
import { CandidateDashboardPage } from 'pages/candidate/Dashboard';
|
import { CandidateDashboard } from 'pages/candidate/Dashboard';
|
||||||
import { EmailVerificationPage } from 'components/EmailVerificationComponents';
|
import { EmailVerificationPage } from 'components/EmailVerificationComponents';
|
||||||
import { Typography } from '@mui/material';
|
import { Box, Typography } from '@mui/material';
|
||||||
import { NavigationConfig, NavigationItem } from 'types/navigation';
|
import { NavigationConfig, NavigationItem } from 'types/navigation';
|
||||||
|
import { CandidateProfile } from 'pages/candidate/Profile';
|
||||||
|
import { JobPicker } from 'components/ui/JobPicker';
|
||||||
|
import { DocumentManager } from 'components/DocumentManager';
|
||||||
|
import { VectorVisualizer } from 'components/VectorVisualizer';
|
||||||
|
import { ComingSoon } from 'components/ui/ComingSoon';
|
||||||
|
|
||||||
// Beta page components for placeholder routes
|
// Beta page components for placeholder routes
|
||||||
const BackstoryPage = () => (<BetaPage><Typography variant="h4">Backstory</Typography></BetaPage>);
|
|
||||||
const ResumesPage = () => (<BetaPage><Typography variant="h4">Resumes</Typography></BetaPage>);
|
|
||||||
const QASetupPage = () => (<BetaPage><Typography variant="h4">Q&A Setup</Typography></BetaPage>);
|
|
||||||
const SearchPage = () => (<BetaPage><Typography variant="h4">Search</Typography></BetaPage>);
|
const SearchPage = () => (<BetaPage><Typography variant="h4">Search</Typography></BetaPage>);
|
||||||
const SavedPage = () => (<BetaPage><Typography variant="h4">Saved</Typography></BetaPage>);
|
const SavedPage = () => (<BetaPage><Typography variant="h4">Saved</Typography></BetaPage>);
|
||||||
const JobsPage = () => (<BetaPage><Typography variant="h4">Jobs</Typography></BetaPage>);
|
const JobsPage = () => (<BetaPage><Typography variant="h4">Jobs</Typography></BetaPage>);
|
||||||
@ -62,7 +70,7 @@ export const navigationConfig: NavigationConfig = {
|
|||||||
id: 'find-candidate',
|
id: 'find-candidate',
|
||||||
label: 'Find a Candidate',
|
label: 'Find a Candidate',
|
||||||
path: '/find-a-candidate',
|
path: '/find-a-candidate',
|
||||||
icon: <InfoIcon />,
|
icon: <PersonSearchIcon />,
|
||||||
component: <CandidateListingPage />,
|
component: <CandidateListingPage />,
|
||||||
userTypes: ['guest', 'candidate', 'employer'],
|
userTypes: ['guest', 'candidate', 'employer'],
|
||||||
},
|
},
|
||||||
@ -70,18 +78,9 @@ export const navigationConfig: NavigationConfig = {
|
|||||||
id: 'docs',
|
id: 'docs',
|
||||||
label: 'Docs',
|
label: 'Docs',
|
||||||
path: '/docs/*',
|
path: '/docs/*',
|
||||||
icon: <InfoIcon />,
|
icon: <LibraryBooksIcon />,
|
||||||
component: <DocsPage />,
|
component: <DocsPage />,
|
||||||
userTypes: ['guest', 'candidate', 'employer'],
|
userTypes: ['guest', 'candidate', 'employer'],
|
||||||
// children: [
|
|
||||||
// {
|
|
||||||
// id: 'docs-subpage',
|
|
||||||
// label: 'Docs Subpage',
|
|
||||||
// path: '/docs/:subPage',
|
|
||||||
// component: <DocsPage />,
|
|
||||||
// userTypes: ['guest', 'candidate', 'employer'],
|
|
||||||
// },
|
|
||||||
// ],
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'chat',
|
id: 'chat',
|
||||||
@ -93,83 +92,20 @@ export const navigationConfig: NavigationConfig = {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'candidate-menu',
|
id: 'candidate-menu',
|
||||||
label: 'Candidate Tools',
|
label: 'Tools',
|
||||||
icon: <PersonIcon />,
|
icon: <PersonIcon />,
|
||||||
userTypes: ['candidate'],
|
userTypes: ['candidate'],
|
||||||
children: [
|
children: [
|
||||||
{
|
{ id: 'candidate-dashboard', label: 'Dashboard', path: '/candidate/dashboard', icon: <DashboardIcon />, component: <CandidateDashboard />, userTypes: ['candidate'] },
|
||||||
id: 'candidate-dashboard',
|
{ id: 'candidate-profile', label: 'Profile', icon: <PersonIcon />, path: '/candidate/profile', component: <CandidateProfile />, userTypes: ['candidate'] },
|
||||||
label: 'Dashboard',
|
{ id: 'candidate-qa-setup', label: 'Q&A Setup', icon: <QuizIcon />, path: '/candidate/qa-setup', component: <BetaPage><Box>Candidate q&a setup page</Box></BetaPage>, userTypes: ['candidate'] },
|
||||||
path: '/candidate/dashboard',
|
{ id: 'candidate-analytics', label: 'Analytics', icon: <AnalyticsIcon />, path: '/candidate/analytics', component: <BetaPage><Box>Candidate analytics page</Box></BetaPage>, userTypes: ['candidate'] },
|
||||||
icon: <DashboardIcon />,
|
{ id: 'candidate-jobs', label: 'Jobs', icon: <WorkIcon />, path: '/candidate/jobs', component: <JobPicker />, userTypes: ['candidate'] },
|
||||||
component: <CandidateDashboardPage />,
|
{ id: 'candidate-job-analysis', label: 'Job Analysis', path: '/candidate/job-analysis', icon: <WorkIcon />, component: <JobAnalysisPage />, userTypes: ['candidate'], },
|
||||||
userTypes: ['candidate'],
|
{ id: 'candidate-resumes', label: 'Resumes', icon: <DescriptionIcon />, path: '/candidate/resumes', component: <BetaPage><Box>Candidate resumes page</Box></BetaPage>, userTypes: ['candidate'] },
|
||||||
children: [
|
{ id: 'candidate-resume-builder', label: 'Resume Builder', path: '/candidate/resume-builder', icon: <DescriptionIcon />, component: <ResumeBuilderPage />, userTypes: ['candidate'], },
|
||||||
{
|
{ id: 'candidate-content', label: 'Content', icon: <BubbleChart />, path: '/candidate/content', component: <Box sx={{ display: "flex", width: "100%", flexDirection: "column" }}><VectorVisualizer /><DocumentManager /></Box>, userTypes: ['candidate'] },
|
||||||
id: 'candidate-dashboard-subpage',
|
{ id: 'candidate-settings', label: 'Settings', path: '/candidate/settings', icon: <SettingsIcon />, component: <ComingSoon><Settings /></ComingSoon>, userTypes: ['candidate'], },
|
||||||
label: 'Dashboard Subpage',
|
|
||||||
path: '/candidate/dashboard/:subPage',
|
|
||||||
component: <CandidateDashboardPage />,
|
|
||||||
userTypes: ['candidate'],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'candidate-job-analysis',
|
|
||||||
label: 'Job Analysis',
|
|
||||||
path: '/candidate/job-analysis',
|
|
||||||
icon: <WorkIcon />,
|
|
||||||
component: <JobAnalysisPage />,
|
|
||||||
userTypes: ['candidate'],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'candidate-resume-builder',
|
|
||||||
label: 'Resume Builder',
|
|
||||||
path: '/candidate/resume-builder',
|
|
||||||
icon: <DescriptionIcon />,
|
|
||||||
component: <ResumeBuilderPage />,
|
|
||||||
userTypes: ['candidate'],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'candidate-backstory',
|
|
||||||
label: 'Backstory',
|
|
||||||
path: '/candidate/backstory',
|
|
||||||
icon: <HistoryIcon />,
|
|
||||||
component: <BackstoryPage />,
|
|
||||||
userTypes: ['candidate'],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'candidate-resumes',
|
|
||||||
label: 'Resumes',
|
|
||||||
path: '/candidate/resumes',
|
|
||||||
icon: <DescriptionIcon />,
|
|
||||||
component: <ResumesPage />,
|
|
||||||
userTypes: ['candidate'],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'candidate-qa-setup',
|
|
||||||
label: 'Q&A Setup',
|
|
||||||
path: '/candidate/qa-setup',
|
|
||||||
icon: <QuestionAnswerIcon />,
|
|
||||||
component: <QASetupPage />,
|
|
||||||
userTypes: ['candidate'],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'candidate-analytics',
|
|
||||||
label: 'Analytics',
|
|
||||||
path: '/candidate/analytics',
|
|
||||||
icon: <BarChartIcon />,
|
|
||||||
component: <AnalyticsPage />,
|
|
||||||
userTypes: ['candidate'],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'candidate-settings',
|
|
||||||
label: 'Settings',
|
|
||||||
path: '/candidate/settings',
|
|
||||||
icon: <SettingsIcon />,
|
|
||||||
component: <SettingsPage />,
|
|
||||||
userTypes: ['candidate'],
|
|
||||||
},
|
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -250,55 +186,16 @@ export const navigationConfig: NavigationConfig = {
|
|||||||
component: <SettingsPage />,
|
component: <SettingsPage />,
|
||||||
userTypes: ['employer'],
|
userTypes: ['employer'],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'global-tools',
|
id: 'admin-menu',
|
||||||
label: 'Tools',
|
label: 'Admin',
|
||||||
icon: <SettingsIcon />,
|
icon: <PersonIcon />,
|
||||||
userTypes: ['candidate', 'employer'],
|
userTypes: ['admin'],
|
||||||
children: [
|
children: [
|
||||||
{
|
{ id: 'generate-candidate', label: 'Generate Candidate', path: '/admin/generate-candidate', icon: <FaceRetouchingNaturalIcon />, component: <GenerateCandidate />, userTypes: ['admin'] },
|
||||||
id: 'resume-builder',
|
],
|
||||||
label: 'Resume Builder',
|
|
||||||
path: '/resume-builder',
|
|
||||||
icon: <DescriptionIcon />,
|
|
||||||
component: <ResumeBuilderPage />,
|
|
||||||
userTypes: ['candidate', 'employer'],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'knowledge-explorer',
|
|
||||||
label: 'Knowledge Explorer',
|
|
||||||
path: '/knowledge-explorer',
|
|
||||||
icon: <WorkIcon />,
|
|
||||||
component: <VectorVisualizerPage />,
|
|
||||||
userTypes: ['candidate', 'employer'],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'job-analysis',
|
|
||||||
label: 'Job Analysis',
|
|
||||||
path: '/job-analysis',
|
|
||||||
icon: <WorkIcon />,
|
|
||||||
component: <JobAnalysisPage />,
|
|
||||||
userTypes: ['candidate', 'employer'],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'generate-candidate',
|
|
||||||
label: 'Generate Candidate',
|
|
||||||
path: '/generate-candidate',
|
|
||||||
icon: <PersonIcon />,
|
|
||||||
component: <GenerateCandidate />,
|
|
||||||
userTypes: ['candidate', 'employer'],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'settings',
|
|
||||||
label: 'Settings',
|
|
||||||
path: '/settings',
|
|
||||||
icon: <SettingsIcon />,
|
|
||||||
component: <ControlsPage />,
|
|
||||||
userTypes: ['candidate', 'employer'],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
// Auth routes (special handling)
|
// Auth routes (special handling)
|
||||||
{
|
{
|
||||||
@ -348,12 +245,11 @@ export const navigationConfig: NavigationConfig = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Utility functions for working with navigation config
|
// Utility functions for working with navigation config
|
||||||
export const getNavigationItemsForUser = (userType: 'guest' | 'candidate' | 'employer' | null): NavigationItem[] => {
|
export const getNavigationItemsForUser = (userType: 'guest' | 'candidate' | 'employer' | null, isAdmin: boolean = false): NavigationItem[] => {
|
||||||
const currentUserType = userType || 'guest';
|
const currentUserType = userType || 'guest';
|
||||||
|
|
||||||
const filterItems = (items: NavigationItem[]): NavigationItem[] => {
|
const filterItems = (items: NavigationItem[]): NavigationItem[] => {
|
||||||
return items
|
return items
|
||||||
.filter(item => !item.userTypes || item.userTypes.includes(currentUserType))
|
.filter(item => !item.userTypes || item.userTypes.includes(currentUserType) || (item.userTypes.includes('admin') && isAdmin))
|
||||||
.map(item => ({
|
.map(item => ({
|
||||||
...item,
|
...item,
|
||||||
children: item.children ? filterItems(item.children) : undefined,
|
children: item.children ? filterItems(item.children) : undefined,
|
||||||
@ -364,14 +260,14 @@ export const getNavigationItemsForUser = (userType: 'guest' | 'candidate' | 'emp
|
|||||||
return filterItems(navigationConfig.items);
|
return filterItems(navigationConfig.items);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getAllRoutes = (userType: 'guest' | 'candidate' | 'employer' | null): NavigationItem[] => {
|
export const getAllRoutes = (userType: 'guest' | 'candidate' | 'employer' | null, isAdmin: boolean = false): NavigationItem[] => {
|
||||||
const currentUserType = userType || 'guest';
|
const currentUserType = userType || 'guest';
|
||||||
|
|
||||||
const extractRoutes = (items: NavigationItem[]): NavigationItem[] => {
|
const extractRoutes = (items: NavigationItem[]): NavigationItem[] => {
|
||||||
const routes: NavigationItem[] = [];
|
const routes: NavigationItem[] = [];
|
||||||
|
|
||||||
items.forEach(item => {
|
items.forEach(item => {
|
||||||
if (!item.userTypes || item.userTypes.includes(currentUserType)) {
|
if (!item.userTypes || item.userTypes.includes(currentUserType) || (item.userTypes.includes('admin') && isAdmin)) {
|
||||||
if (item.path && item.component) {
|
if (item.path && item.component) {
|
||||||
routes.push(item);
|
routes.push(item);
|
||||||
}
|
}
|
||||||
@ -387,8 +283,8 @@ export const getAllRoutes = (userType: 'guest' | 'candidate' | 'employer' | null
|
|||||||
return extractRoutes(navigationConfig.items);
|
return extractRoutes(navigationConfig.items);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getMainNavigationItems = (userType: 'guest' | 'candidate' | 'employer' | null): NavigationItem[] => {
|
export const getMainNavigationItems = (userType: 'guest' | 'candidate' | 'employer' | null, isAdmin: boolean = false): NavigationItem[] => {
|
||||||
return getNavigationItemsForUser(userType)
|
return getNavigationItemsForUser(userType, isAdmin)
|
||||||
.filter(item =>
|
.filter(item =>
|
||||||
item.id !== 'auth' &&
|
item.id !== 'auth' &&
|
||||||
item.id !== 'catch-all' &&
|
item.id !== 'catch-all' &&
|
||||||
|
@ -38,9 +38,8 @@ const BetaPage: React.FC<BetaPageProps> = ({
|
|||||||
const location = useLocation();
|
const location = useLocation();
|
||||||
|
|
||||||
if (!children) {
|
if (!children) {
|
||||||
children = (<Box sx={{ width: "100%", display: "flex", justifyContent: "center" }}>The page you requested (<b>{location.pathname.replace(/^\//, '')}</b>) is not yet ready.</Box>);
|
children = (<Box sx={{ width: "100%", display: "flex", justifyContent: "center" }}><Typography>The page you requested (<b>{location.pathname.replace(/^\//, '')}</b>) is not yet ready.</Typography></Box>);
|
||||||
}
|
}
|
||||||
console.log("BetaPage", children);
|
|
||||||
|
|
||||||
// Enhanced sparkle effect for background elements
|
// Enhanced sparkle effect for background elements
|
||||||
const [sparkles, setSparkles] = useState<Array<{
|
const [sparkles, setSparkles] = useState<Array<{
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import React, {useState} from 'react';
|
import React from 'react';
|
||||||
import {
|
import {
|
||||||
Box,
|
Box,
|
||||||
Card,
|
Card,
|
||||||
@ -6,133 +6,205 @@ import {
|
|||||||
Typography,
|
Typography,
|
||||||
Button,
|
Button,
|
||||||
LinearProgress,
|
LinearProgress,
|
||||||
List,
|
|
||||||
ListItem,
|
|
||||||
ListItemIcon,
|
|
||||||
ListItemText,
|
|
||||||
ListItemButton,
|
|
||||||
Divider,
|
|
||||||
Chip,
|
|
||||||
Stack
|
Stack
|
||||||
} from '@mui/material';
|
} from '@mui/material';
|
||||||
import {
|
import {
|
||||||
Dashboard as DashboardIcon,
|
|
||||||
Person as PersonIcon,
|
|
||||||
Work as WorkIcon,
|
|
||||||
Article as ArticleIcon,
|
|
||||||
Description as DescriptionIcon,
|
|
||||||
Quiz as QuizIcon,
|
|
||||||
Analytics as AnalyticsIcon,
|
|
||||||
Settings as SettingsIcon,
|
|
||||||
Add as AddIcon,
|
Add as AddIcon,
|
||||||
Visibility as VisibilityIcon,
|
Visibility as VisibilityIcon,
|
||||||
Download as DownloadIcon,
|
Download as DownloadIcon,
|
||||||
ContactMail as ContactMailIcon,
|
ContactMail as ContactMailIcon,
|
||||||
Edit as EditIcon,
|
Edit as EditIcon,
|
||||||
TipsAndUpdates as TipsIcon,
|
TipsAndUpdates as TipsIcon,
|
||||||
SettingsBackupRestore,
|
|
||||||
BubbleChart
|
|
||||||
} from '@mui/icons-material';
|
} from '@mui/icons-material';
|
||||||
import { useAuth } from 'hooks/AuthContext';
|
import { useAuth } from 'hooks/AuthContext';
|
||||||
import { LoadingPage } from 'pages/LoadingPage';
|
|
||||||
import { LoginRequired } from 'pages/LoginRequired';
|
import { LoginRequired } from 'pages/LoginRequired';
|
||||||
import { BackstoryPageProps } from 'components/BackstoryTab';
|
import { BackstoryElementProps } from 'components/BackstoryTab';
|
||||||
import { Navigate, useNavigate, useParams } from 'react-router-dom';
|
import { useNavigate } from 'react-router-dom';
|
||||||
import { BetaPage } from 'pages/BetaPage';
|
import { ComingSoon } from 'components/ui/ComingSoon';
|
||||||
import { map } from 'lodash';
|
|
||||||
|
|
||||||
import { CandidateDashboard } from 'pages/candidate/dashboard/Dashboard';
|
|
||||||
import { CandidateProfile } from 'pages/candidate/dashboard/Profile';
|
|
||||||
import { VectorVisualizer } from 'components/VectorVisualizer';
|
|
||||||
import { DocumentManager } from 'components/DocumentManager';
|
|
||||||
import { JobPicker } from 'components/ui/JobPicker';
|
|
||||||
import { useAppState } from 'hooks/GlobalContext';
|
import { useAppState } from 'hooks/GlobalContext';
|
||||||
|
|
||||||
interface DashboardProps extends BackstoryPageProps {
|
interface CandidateDashboardProps extends BackstoryElementProps {
|
||||||
userName?: string;
|
};
|
||||||
profileCompletion?: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
const CandidateDashboardPage: React.FC<DashboardProps> = (props: DashboardProps) => {
|
const CandidateDashboard = (props: CandidateDashboardProps) => {
|
||||||
const navigate = useNavigate();
|
|
||||||
const { subPage = 'dashboard' } = useParams();
|
|
||||||
const [activeTab, setActiveTab] = useState<string>(subPage);
|
|
||||||
const { user, isLoading, isInitializing, isAuthenticated } = useAuth();
|
|
||||||
const profileCompletion = 75;
|
|
||||||
const { setSnack } = useAppState();
|
const { setSnack } = useAppState();
|
||||||
|
const navigate = useNavigate();
|
||||||
|
const { user } = useAuth();
|
||||||
|
const profileCompletion = 75;
|
||||||
|
|
||||||
const sidebarItems = [
|
if (!user) {
|
||||||
{ text: 'Dashboard', icon: <DashboardIcon />, path: '/', element: <CandidateDashboard /> },
|
return <LoginRequired />;
|
||||||
{ text: 'Profile', icon: <PersonIcon />, path: '/profile', element: <CandidateProfile /> },
|
}
|
||||||
{ text: 'Jobs', icon: <WorkIcon />, path: '/jobs', element: <JobPicker /> },
|
|
||||||
{ text: 'Resumes', icon: <DescriptionIcon />,path: '/resumes', element: <BetaPage><Box>Candidate resumes page</Box></BetaPage> },
|
|
||||||
{ text: 'Content', icon: <BubbleChart />, path: '/rag', element: <Box sx={{ display: "flex", width: "100%", flexDirection: "column" }}><VectorVisualizer /><DocumentManager /></Box> },
|
|
||||||
{ text: 'Q&A Setup', icon: <QuizIcon />,path: '/q-a-setup', element: <BetaPage><Box>Candidate q&a setup page</Box></BetaPage> },
|
|
||||||
{ text: 'Analytics', icon: <AnalyticsIcon />,path: '/analytics', element: <BetaPage><Box>Candidate analytics page</Box></BetaPage> },
|
|
||||||
{ text: 'Settings', icon: <SettingsIcon />,path: '/settings', element: <BetaPage><Box>Candidate settings page</Box></BetaPage> },
|
|
||||||
]
|
|
||||||
|
|
||||||
if (isLoading || isInitializing) {
|
if (user?.userType !== 'candidate') {
|
||||||
return (<LoadingPage {...props}/>);
|
|
||||||
}
|
|
||||||
if (!user || !isAuthenticated) {
|
|
||||||
return (<LoginRequired {...props}/>);
|
|
||||||
}
|
|
||||||
if (user.userType !== 'candidate') {
|
|
||||||
setSnack(`The page you were on is only available for candidates (you are a ${user.userType}`, 'warning');
|
setSnack(`The page you were on is only available for candidates (you are a ${user.userType}`, 'warning');
|
||||||
navigate('/');
|
navigate('/');
|
||||||
return (<></>);
|
return (<></>);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (<>
|
||||||
<Box sx={{ display: 'flex', minHeight: '100vh', backgroundColor: '#f5f5f5' }}>
|
|
||||||
{/* Sidebar */}
|
|
||||||
<Box
|
|
||||||
sx={{
|
|
||||||
width: 250,
|
|
||||||
backgroundColor: 'white',
|
|
||||||
borderRight: '1px solid #e0e0e0',
|
|
||||||
p: 2,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<List>
|
|
||||||
{sidebarItems.map((item, index) => (
|
|
||||||
<ListItem key={index} disablePadding sx={{ mb: 0.5 }}>
|
|
||||||
<ListItemButton
|
|
||||||
sx={{
|
|
||||||
borderRadius: 1,
|
|
||||||
backgroundColor: (item.text.toLowerCase() === activeTab )? '#e3f2fd' : 'transparent',
|
|
||||||
color: (item.text.toLowerCase() === activeTab ) ? '#1976d2' : '#666',
|
|
||||||
'&:hover': {
|
|
||||||
backgroundColor: (item.text.toLowerCase() === activeTab ) ? '#e3f2fd' : '#f5f5f5',
|
|
||||||
},
|
|
||||||
}}
|
|
||||||
onClick={()=>{setActiveTab(item.text.toLowerCase()); navigate(`/candidate/dashboard/${item.text.toLowerCase()}`);}}
|
|
||||||
>
|
|
||||||
<ListItemIcon sx={{ color: 'inherit', minWidth: 40 }}>
|
|
||||||
{item.icon}
|
|
||||||
</ListItemIcon>
|
|
||||||
<ListItemText
|
|
||||||
primary={item.text}
|
|
||||||
primaryTypographyProps={{
|
|
||||||
fontSize: '0.9rem',
|
|
||||||
fontWeight: (item.text === activeTab ) ? 600 : 400,
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</ListItemButton>
|
|
||||||
</ListItem>
|
|
||||||
))}
|
|
||||||
</List>
|
|
||||||
</Box>
|
|
||||||
|
|
||||||
{/* Main Content */}
|
{/* Main Content */}
|
||||||
|
<ComingSoon>
|
||||||
<Box sx={{ flex: 1, p: 3 }}>
|
<Box sx={{ flex: 1, p: 3 }}>
|
||||||
{ sidebarItems.map(item =>
|
{/* Welcome Section */}
|
||||||
<Box sx={{display: (item.text.toLowerCase() === activeTab) ? "flex": "none", width: "100%"}}>{item.element}</Box>
|
<Box sx={{ mb: 4 }}>
|
||||||
)}
|
<Typography variant="h4" sx={{ mb: 2, fontWeight: 'bold' }}>
|
||||||
|
Welcome back, {user.firstName}!
|
||||||
|
</Typography>
|
||||||
|
|
||||||
|
<Box sx={{ mb: 2 }}>
|
||||||
|
<Typography variant="body1" sx={{ mb: 1 }}>
|
||||||
|
Your profile is {profileCompletion}% complete
|
||||||
|
</Typography>
|
||||||
|
<LinearProgress
|
||||||
|
variant="determinate"
|
||||||
|
value={profileCompletion}
|
||||||
|
sx={{
|
||||||
|
height: 8,
|
||||||
|
borderRadius: 4,
|
||||||
|
backgroundColor: '#e0e0e0',
|
||||||
|
'& .MuiLinearProgress-bar': {
|
||||||
|
backgroundColor: '#4caf50',
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
|
|
||||||
|
<Button
|
||||||
|
variant="contained"
|
||||||
|
color="primary"
|
||||||
|
sx={{ mt: 1 }}
|
||||||
|
onClick={(e) => {e.stopPropagation(); navigate('/candidate/dashboard/profile'); }}
|
||||||
|
>
|
||||||
|
Complete Your Profile
|
||||||
|
</Button>
|
||||||
|
</Box>
|
||||||
|
|
||||||
|
{/* Cards Grid */}
|
||||||
|
<Box sx={{ display: 'flex', flexDirection: 'column', gap: 3 }}>
|
||||||
|
{/* Top Row */}
|
||||||
|
<Box sx={{ display: 'flex', gap: 3 }}>
|
||||||
|
{/* Resume Builder Card */}
|
||||||
|
<Card sx={{ flex: 1, minHeight: 200 }}>
|
||||||
|
<CardContent>
|
||||||
|
<Typography variant="h6" sx={{ mb: 2, fontWeight: 'bold' }}>
|
||||||
|
Resume Builder
|
||||||
|
</Typography>
|
||||||
|
|
||||||
|
<Typography variant="body2" sx={{ mb: 1, color: '#666' }}>
|
||||||
|
3 custom resumes
|
||||||
|
</Typography>
|
||||||
|
|
||||||
|
<Typography variant="body2" sx={{ mb: 3, color: '#666' }}>
|
||||||
|
Last created: May 15, 2025
|
||||||
|
</Typography>
|
||||||
|
|
||||||
|
<Button
|
||||||
|
variant="outlined"
|
||||||
|
startIcon={<AddIcon />}
|
||||||
|
fullWidth
|
||||||
|
>
|
||||||
|
Create New
|
||||||
|
</Button>
|
||||||
|
</CardContent>
|
||||||
|
</Card>
|
||||||
|
|
||||||
|
{/* Recent Activity Card */}
|
||||||
|
<Card sx={{ flex: 1, minHeight: 200 }}>
|
||||||
|
<CardContent>
|
||||||
|
<Typography variant="h6" sx={{ mb: 2, fontWeight: 'bold' }}>
|
||||||
|
Recent Activity
|
||||||
|
</Typography>
|
||||||
|
|
||||||
|
<Stack spacing={1} sx={{ mb: 3 }}>
|
||||||
|
<Box sx={{ display: 'flex', alignItems: 'center', gap: 1 }}>
|
||||||
|
<VisibilityIcon sx={{ fontSize: 16, color: '#666' }} />
|
||||||
|
<Typography variant="body2">5 profile views</Typography>
|
||||||
|
</Box>
|
||||||
|
|
||||||
|
<Box sx={{ display: 'flex', alignItems: 'center', gap: 1 }}>
|
||||||
|
<DownloadIcon sx={{ fontSize: 16, color: '#666' }} />
|
||||||
|
<Typography variant="body2">2 resume downloads</Typography>
|
||||||
|
</Box>
|
||||||
|
|
||||||
|
<Box sx={{ display: 'flex', alignItems: 'center', gap: 1 }}>
|
||||||
|
<ContactMailIcon sx={{ fontSize: 16, color: '#666' }} />
|
||||||
|
<Typography variant="body2">1 direct contact</Typography>
|
||||||
|
</Box>
|
||||||
|
</Stack>
|
||||||
|
|
||||||
|
<Button
|
||||||
|
variant="outlined"
|
||||||
|
fullWidth
|
||||||
|
>
|
||||||
|
View All Activity
|
||||||
|
</Button>
|
||||||
|
</CardContent>
|
||||||
|
</Card>
|
||||||
|
</Box>
|
||||||
|
|
||||||
|
{/* Bottom Row */}
|
||||||
|
<Box sx={{ display: 'flex', gap: 3 }}>
|
||||||
|
{/* Complete Your Backstory Card */}
|
||||||
|
<Card sx={{ flex: 1, minHeight: 200 }}>
|
||||||
|
<CardContent>
|
||||||
|
<Typography variant="h6" sx={{ mb: 2, fontWeight: 'bold' }}>
|
||||||
|
Complete Your Backstory
|
||||||
|
</Typography>
|
||||||
|
|
||||||
|
<Stack spacing={1} sx={{ mb: 3 }}>
|
||||||
|
<Typography variant="body2" sx={{ display: 'flex', alignItems: 'center' }}>
|
||||||
|
• Add projects
|
||||||
|
</Typography>
|
||||||
|
<Typography variant="body2" sx={{ display: 'flex', alignItems: 'center' }}>
|
||||||
|
• Detail skills
|
||||||
|
</Typography>
|
||||||
|
<Typography variant="body2" sx={{ display: 'flex', alignItems: 'center' }}>
|
||||||
|
• Work history
|
||||||
|
</Typography>
|
||||||
|
</Stack>
|
||||||
|
|
||||||
|
<Button
|
||||||
|
variant="outlined"
|
||||||
|
startIcon={<EditIcon />}
|
||||||
|
fullWidth
|
||||||
|
>
|
||||||
|
Edit Backstory
|
||||||
|
</Button>
|
||||||
|
</CardContent>
|
||||||
|
</Card>
|
||||||
|
|
||||||
|
{/* Improvement Suggestions Card */}
|
||||||
|
<Card sx={{ flex: 1, minHeight: 200 }}>
|
||||||
|
<CardContent>
|
||||||
|
<Typography variant="h6" sx={{ mb: 2, fontWeight: 'bold' }}>
|
||||||
|
Improvement Suggestions
|
||||||
|
</Typography>
|
||||||
|
|
||||||
|
<Stack spacing={1} sx={{ mb: 3 }}>
|
||||||
|
<Typography variant="body2" sx={{ display: 'flex', alignItems: 'center' }}>
|
||||||
|
• Add certifications
|
||||||
|
</Typography>
|
||||||
|
<Typography variant="body2" sx={{ display: 'flex', alignItems: 'center' }}>
|
||||||
|
• Enhance your project details
|
||||||
|
</Typography>
|
||||||
|
</Stack>
|
||||||
|
|
||||||
|
<Button
|
||||||
|
variant="outlined"
|
||||||
|
startIcon={<TipsIcon />}
|
||||||
|
fullWidth
|
||||||
|
>
|
||||||
|
View All Tips
|
||||||
|
</Button>
|
||||||
|
</CardContent>
|
||||||
|
</Card>
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
</Box>
|
</Box>
|
||||||
</Box>
|
</ComingSoon>
|
||||||
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export { CandidateDashboardPage };
|
export { CandidateDashboard };
|
@ -14,8 +14,8 @@ import Typography from '@mui/material/Typography';
|
|||||||
// import ResetIcon from '@mui/icons-material/History';
|
// import ResetIcon from '@mui/icons-material/History';
|
||||||
import ExpandMoreIcon from '@mui/icons-material/ExpandMore';
|
import ExpandMoreIcon from '@mui/icons-material/ExpandMore';
|
||||||
|
|
||||||
import { connectionBase } from '../utils/Global';
|
import { connectionBase } from '../../utils/Global';
|
||||||
import { BackstoryPageProps } from '../components/BackstoryTab';
|
import { BackstoryPageProps } from '../../components/BackstoryTab';
|
||||||
import { useAppState } from 'hooks/GlobalContext';
|
import { useAppState } from 'hooks/GlobalContext';
|
||||||
|
|
||||||
interface ServerTunables {
|
interface ServerTunables {
|
||||||
@ -85,7 +85,7 @@ const SystemInfoComponent: React.FC<{ systemInfo: SystemInfo | undefined }> = ({
|
|||||||
return <div className="SystemInfo">{systemElements}</div>;
|
return <div className="SystemInfo">{systemElements}</div>;
|
||||||
};
|
};
|
||||||
|
|
||||||
const ControlsPage = (props: BackstoryPageProps) => {
|
const Settings = (props: BackstoryPageProps) => {
|
||||||
const { setSnack } = useAppState();
|
const { setSnack } = useAppState();
|
||||||
const [editSystemPrompt, setEditSystemPrompt] = useState<string>("");
|
const [editSystemPrompt, setEditSystemPrompt] = useState<string>("");
|
||||||
const [systemInfo, setSystemInfo] = useState<SystemInfo | undefined>(undefined);
|
const [systemInfo, setSystemInfo] = useState<SystemInfo | undefined>(undefined);
|
||||||
@ -429,5 +429,5 @@ const ControlsPage = (props: BackstoryPageProps) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export {
|
export {
|
||||||
ControlsPage
|
Settings
|
||||||
};
|
};
|
@ -1,210 +0,0 @@
|
|||||||
import React from 'react';
|
|
||||||
import {
|
|
||||||
Box,
|
|
||||||
Card,
|
|
||||||
CardContent,
|
|
||||||
Typography,
|
|
||||||
Button,
|
|
||||||
LinearProgress,
|
|
||||||
Stack
|
|
||||||
} from '@mui/material';
|
|
||||||
import {
|
|
||||||
Add as AddIcon,
|
|
||||||
Visibility as VisibilityIcon,
|
|
||||||
Download as DownloadIcon,
|
|
||||||
ContactMail as ContactMailIcon,
|
|
||||||
Edit as EditIcon,
|
|
||||||
TipsAndUpdates as TipsIcon,
|
|
||||||
} from '@mui/icons-material';
|
|
||||||
import { useAuth } from 'hooks/AuthContext';
|
|
||||||
import { LoginRequired } from 'pages/LoginRequired';
|
|
||||||
import { BackstoryElementProps } from 'components/BackstoryTab';
|
|
||||||
import { useNavigate } from 'react-router-dom';
|
|
||||||
import { ComingSoon } from 'components/ui/ComingSoon';
|
|
||||||
import { useAppState } from 'hooks/GlobalContext';
|
|
||||||
|
|
||||||
interface CandidateDashboardProps extends BackstoryElementProps {
|
|
||||||
};
|
|
||||||
|
|
||||||
const CandidateDashboard = (props: CandidateDashboardProps) => {
|
|
||||||
const { setSnack } = useAppState();
|
|
||||||
const navigate = useNavigate();
|
|
||||||
const { user } = useAuth();
|
|
||||||
const profileCompletion = 75;
|
|
||||||
|
|
||||||
if (!user) {
|
|
||||||
return <LoginRequired />;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (user?.userType !== 'candidate') {
|
|
||||||
setSnack(`The page you were on is only available for candidates (you are a ${user.userType}`, 'warning');
|
|
||||||
navigate('/');
|
|
||||||
return (<></>);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (<>
|
|
||||||
{/* Main Content */}
|
|
||||||
<ComingSoon>
|
|
||||||
<Box sx={{ flex: 1, p: 3 }}>
|
|
||||||
{/* Welcome Section */}
|
|
||||||
<Box sx={{ mb: 4 }}>
|
|
||||||
<Typography variant="h4" sx={{ mb: 2, fontWeight: 'bold' }}>
|
|
||||||
Welcome back, {user.firstName}!
|
|
||||||
</Typography>
|
|
||||||
|
|
||||||
<Box sx={{ mb: 2 }}>
|
|
||||||
<Typography variant="body1" sx={{ mb: 1 }}>
|
|
||||||
Your profile is {profileCompletion}% complete
|
|
||||||
</Typography>
|
|
||||||
<LinearProgress
|
|
||||||
variant="determinate"
|
|
||||||
value={profileCompletion}
|
|
||||||
sx={{
|
|
||||||
height: 8,
|
|
||||||
borderRadius: 4,
|
|
||||||
backgroundColor: '#e0e0e0',
|
|
||||||
'& .MuiLinearProgress-bar': {
|
|
||||||
backgroundColor: '#4caf50',
|
|
||||||
},
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</Box>
|
|
||||||
|
|
||||||
<Button
|
|
||||||
variant="contained"
|
|
||||||
color="primary"
|
|
||||||
sx={{ mt: 1 }}
|
|
||||||
onClick={(e) => {e.stopPropagation(); navigate('/candidate/dashboard/profile'); }}
|
|
||||||
>
|
|
||||||
Complete Your Profile
|
|
||||||
</Button>
|
|
||||||
</Box>
|
|
||||||
|
|
||||||
{/* Cards Grid */}
|
|
||||||
<Box sx={{ display: 'flex', flexDirection: 'column', gap: 3 }}>
|
|
||||||
{/* Top Row */}
|
|
||||||
<Box sx={{ display: 'flex', gap: 3 }}>
|
|
||||||
{/* Resume Builder Card */}
|
|
||||||
<Card sx={{ flex: 1, minHeight: 200 }}>
|
|
||||||
<CardContent>
|
|
||||||
<Typography variant="h6" sx={{ mb: 2, fontWeight: 'bold' }}>
|
|
||||||
Resume Builder
|
|
||||||
</Typography>
|
|
||||||
|
|
||||||
<Typography variant="body2" sx={{ mb: 1, color: '#666' }}>
|
|
||||||
3 custom resumes
|
|
||||||
</Typography>
|
|
||||||
|
|
||||||
<Typography variant="body2" sx={{ mb: 3, color: '#666' }}>
|
|
||||||
Last created: May 15, 2025
|
|
||||||
</Typography>
|
|
||||||
|
|
||||||
<Button
|
|
||||||
variant="outlined"
|
|
||||||
startIcon={<AddIcon />}
|
|
||||||
fullWidth
|
|
||||||
>
|
|
||||||
Create New
|
|
||||||
</Button>
|
|
||||||
</CardContent>
|
|
||||||
</Card>
|
|
||||||
|
|
||||||
{/* Recent Activity Card */}
|
|
||||||
<Card sx={{ flex: 1, minHeight: 200 }}>
|
|
||||||
<CardContent>
|
|
||||||
<Typography variant="h6" sx={{ mb: 2, fontWeight: 'bold' }}>
|
|
||||||
Recent Activity
|
|
||||||
</Typography>
|
|
||||||
|
|
||||||
<Stack spacing={1} sx={{ mb: 3 }}>
|
|
||||||
<Box sx={{ display: 'flex', alignItems: 'center', gap: 1 }}>
|
|
||||||
<VisibilityIcon sx={{ fontSize: 16, color: '#666' }} />
|
|
||||||
<Typography variant="body2">5 profile views</Typography>
|
|
||||||
</Box>
|
|
||||||
|
|
||||||
<Box sx={{ display: 'flex', alignItems: 'center', gap: 1 }}>
|
|
||||||
<DownloadIcon sx={{ fontSize: 16, color: '#666' }} />
|
|
||||||
<Typography variant="body2">2 resume downloads</Typography>
|
|
||||||
</Box>
|
|
||||||
|
|
||||||
<Box sx={{ display: 'flex', alignItems: 'center', gap: 1 }}>
|
|
||||||
<ContactMailIcon sx={{ fontSize: 16, color: '#666' }} />
|
|
||||||
<Typography variant="body2">1 direct contact</Typography>
|
|
||||||
</Box>
|
|
||||||
</Stack>
|
|
||||||
|
|
||||||
<Button
|
|
||||||
variant="outlined"
|
|
||||||
fullWidth
|
|
||||||
>
|
|
||||||
View All Activity
|
|
||||||
</Button>
|
|
||||||
</CardContent>
|
|
||||||
</Card>
|
|
||||||
</Box>
|
|
||||||
|
|
||||||
{/* Bottom Row */}
|
|
||||||
<Box sx={{ display: 'flex', gap: 3 }}>
|
|
||||||
{/* Complete Your Backstory Card */}
|
|
||||||
<Card sx={{ flex: 1, minHeight: 200 }}>
|
|
||||||
<CardContent>
|
|
||||||
<Typography variant="h6" sx={{ mb: 2, fontWeight: 'bold' }}>
|
|
||||||
Complete Your Backstory
|
|
||||||
</Typography>
|
|
||||||
|
|
||||||
<Stack spacing={1} sx={{ mb: 3 }}>
|
|
||||||
<Typography variant="body2" sx={{ display: 'flex', alignItems: 'center' }}>
|
|
||||||
• Add projects
|
|
||||||
</Typography>
|
|
||||||
<Typography variant="body2" sx={{ display: 'flex', alignItems: 'center' }}>
|
|
||||||
• Detail skills
|
|
||||||
</Typography>
|
|
||||||
<Typography variant="body2" sx={{ display: 'flex', alignItems: 'center' }}>
|
|
||||||
• Work history
|
|
||||||
</Typography>
|
|
||||||
</Stack>
|
|
||||||
|
|
||||||
<Button
|
|
||||||
variant="outlined"
|
|
||||||
startIcon={<EditIcon />}
|
|
||||||
fullWidth
|
|
||||||
>
|
|
||||||
Edit Backstory
|
|
||||||
</Button>
|
|
||||||
</CardContent>
|
|
||||||
</Card>
|
|
||||||
|
|
||||||
{/* Improvement Suggestions Card */}
|
|
||||||
<Card sx={{ flex: 1, minHeight: 200 }}>
|
|
||||||
<CardContent>
|
|
||||||
<Typography variant="h6" sx={{ mb: 2, fontWeight: 'bold' }}>
|
|
||||||
Improvement Suggestions
|
|
||||||
</Typography>
|
|
||||||
|
|
||||||
<Stack spacing={1} sx={{ mb: 3 }}>
|
|
||||||
<Typography variant="body2" sx={{ display: 'flex', alignItems: 'center' }}>
|
|
||||||
• Add certifications
|
|
||||||
</Typography>
|
|
||||||
<Typography variant="body2" sx={{ display: 'flex', alignItems: 'center' }}>
|
|
||||||
• Enhance your project details
|
|
||||||
</Typography>
|
|
||||||
</Stack>
|
|
||||||
|
|
||||||
<Button
|
|
||||||
variant="outlined"
|
|
||||||
startIcon={<TipsIcon />}
|
|
||||||
fullWidth
|
|
||||||
>
|
|
||||||
View All Tips
|
|
||||||
</Button>
|
|
||||||
</CardContent>
|
|
||||||
</Card>
|
|
||||||
</Box>
|
|
||||||
</Box>
|
|
||||||
</Box>
|
|
||||||
</ComingSoon>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export { CandidateDashboard };
|
|
@ -8,7 +8,7 @@ export interface NavigationItem {
|
|||||||
icon?: ReactElement;
|
icon?: ReactElement;
|
||||||
children?: NavigationItem[];
|
children?: NavigationItem[];
|
||||||
component?: ReactElement;
|
component?: ReactElement;
|
||||||
userTypes?: ('candidate' | 'employer' | 'guest')[];
|
userTypes?: ('candidate' | 'employer' | 'guest' | 'admin')[];
|
||||||
exact?: boolean;
|
exact?: boolean;
|
||||||
divider?: boolean;
|
divider?: boolean;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user