277 lines
9.1 KiB
TypeScript
277 lines
9.1 KiB
TypeScript
import React from 'react';
|
|
import {
|
|
Box,
|
|
Card,
|
|
CardContent,
|
|
Typography,
|
|
Button,
|
|
LinearProgress,
|
|
List,
|
|
ListItem,
|
|
ListItemIcon,
|
|
ListItemText,
|
|
ListItemButton,
|
|
Divider,
|
|
Chip,
|
|
Stack
|
|
} from '@mui/material';
|
|
import {
|
|
Dashboard as DashboardIcon,
|
|
Person as PersonIcon,
|
|
Article as ArticleIcon,
|
|
Description as DescriptionIcon,
|
|
Quiz as QuizIcon,
|
|
Analytics as AnalyticsIcon,
|
|
Settings as SettingsIcon,
|
|
Add as AddIcon,
|
|
Visibility as VisibilityIcon,
|
|
Download as DownloadIcon,
|
|
ContactMail as ContactMailIcon,
|
|
Edit as EditIcon,
|
|
TipsAndUpdates as TipsIcon,
|
|
SettingsBackupRestore
|
|
} from '@mui/icons-material';
|
|
import { useAuth } from 'hooks/AuthContext';
|
|
import { LoadingPage } from './LoadingPage';
|
|
import { LoginRequired } from './LoginRequired';
|
|
import { BackstoryPageProps } from 'components/BackstoryTab';
|
|
import { Navigate, useNavigate } from 'react-router-dom';
|
|
|
|
interface DashboardProps extends BackstoryPageProps {
|
|
userName?: string;
|
|
profileCompletion?: number;
|
|
}
|
|
|
|
const CandidateDashboardPage: React.FC<DashboardProps> = (props: DashboardProps) => {
|
|
const navigate = useNavigate();
|
|
const { setSnack } = props;
|
|
const { user, isLoading, isInitializing, isAuthenticated } = useAuth();
|
|
const profileCompletion = 75;
|
|
const sidebarItems = [
|
|
{ icon: <DashboardIcon />, text: 'Dashboard', active: true },
|
|
{ icon: <PersonIcon />, text: 'Profile', active: false },
|
|
{ icon: <ArticleIcon />, text: 'Backstory', active: false },
|
|
{ icon: <DescriptionIcon />, text: 'Resumes', active: false },
|
|
{ icon: <QuizIcon />, text: 'Q&A Setup', active: false },
|
|
{ icon: <AnalyticsIcon />, text: 'Analytics', active: false },
|
|
{ icon: <SettingsIcon />, text: 'Settings', active: false },
|
|
];
|
|
|
|
if (isLoading || isInitializing) {
|
|
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');
|
|
navigate('/');
|
|
return (<></>);
|
|
}
|
|
|
|
return (
|
|
<Box sx={{ display: 'flex', minHeight: '100vh', backgroundColor: '#f5f5f5' }}>
|
|
{/* Sidebar */}
|
|
<Box
|
|
sx={{
|
|
width: 250,
|
|
backgroundColor: 'white',
|
|
borderRight: '1px solid #e0e0e0',
|
|
p: 2,
|
|
}}
|
|
>
|
|
<Typography variant="h6" sx={{ mb: 3, fontWeight: 'bold', color: '#1976d2' }}>
|
|
JobPortal
|
|
</Typography>
|
|
|
|
<List>
|
|
{sidebarItems.map((item, index) => (
|
|
<ListItem key={index} disablePadding sx={{ mb: 0.5 }}>
|
|
<ListItemButton
|
|
sx={{
|
|
borderRadius: 1,
|
|
backgroundColor: item.active ? '#e3f2fd' : 'transparent',
|
|
color: item.active ? '#1976d2' : '#666',
|
|
'&:hover': {
|
|
backgroundColor: item.active ? '#e3f2fd' : '#f5f5f5',
|
|
},
|
|
}}
|
|
>
|
|
<ListItemIcon sx={{ color: 'inherit', minWidth: 40 }}>
|
|
{item.icon}
|
|
</ListItemIcon>
|
|
<ListItemText
|
|
primary={item.text}
|
|
primaryTypographyProps={{
|
|
fontSize: '0.9rem',
|
|
fontWeight: item.active ? 600 : 400,
|
|
}}
|
|
/>
|
|
</ListItemButton>
|
|
</ListItem>
|
|
))}
|
|
</List>
|
|
</Box>
|
|
|
|
{/* Main Content */}
|
|
<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 }}
|
|
>
|
|
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>
|
|
);
|
|
};
|
|
|
|
export { CandidateDashboardPage }; |