2025-05-28 09:32:36 -07:00

518 lines
21 KiB
TypeScript

import React, { useState } from 'react';
import {
AppBar, Avatar, Box, Button, Chip, Container, Divider, Drawer,
IconButton, InputBase, List, ListItem, ListItemButton, ListItemIcon,
ListItemText, Paper, Tab, Tabs, TextField, Typography,
useMediaQuery, useTheme
} from '@mui/material';
import {
Menu as MenuIcon, Search as SearchIcon, Description as FileTextIcon,
Person as UserIcon, Settings as SettingsIcon, Add as PlusIcon,
Edit as EditIcon, Visibility as EyeIcon, Save as SaveIcon,
Delete as TrashIcon, AccessTime as ClockIcon, ChevronRight as ChevronRightIcon
} from '@mui/icons-material';
interface Resume {
id: number;
name: string;
date: string;
isRecent: boolean;
}
const MockupPage = () => {
const theme = useTheme();
const isMobile = useMediaQuery(theme.breakpoints.down('md'));
const [activeTab, setActiveTab] = useState<string>("resume");
const [isMobileMenuOpen, setIsMobileMenuOpen] = useState<boolean>(false);
const [selectedResume, setSelectedResume] = useState<number | null>(null);
// Mock data
const savedResumes: Resume[] = [
{ id: 1, name: "Software Engineer - Tech Co", date: "May 15, 2025", isRecent: true },
{ id: 2, name: "Product Manager - StartupX", date: "May 10, 2025", isRecent: false },
{ id: 3, name: "Data Scientist - AI Corp", date: "May 5, 2025", isRecent: false },
];
return (
<Box sx={{ display: 'flex', flexDirection: 'column', height: '100%', bgcolor: 'background.default' }}>
{/* Header */}
<AppBar position="static" color="default" elevation={1} sx={{ zIndex: (theme) => theme.zIndex.drawer + 1 }}>
<Box sx={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', px: 2, py: 1 }}>
<Box sx={{ display: 'flex', alignItems: 'center', gap: 1 }}>
<Typography variant="h6" component="h1" fontWeight="bold" color="text.primary">Backstory</Typography>
{isMobile && (
<IconButton edge="start" color="inherit" onClick={() => setIsMobileMenuOpen(!isMobileMenuOpen)}>
<MenuIcon />
</IconButton>
)}
</Box>
<Box sx={{ display: 'flex', alignItems: 'center', gap: 2 }}>
{!isMobile && (
<Button
startIcon={<PlusIcon />}
color="primary"
size="small"
>
New Resume
</Button>
)}
<IconButton sx={{ bgcolor: 'action.hover', borderRadius: '50%' }}>
<UserIcon />
</IconButton>
</Box>
</Box>
</AppBar>
<Box sx={{ display: 'flex', flex: 1, overflow: 'hidden' }}>
{/* Sidebar - hidden on mobile */}
{!isMobile && (
<Drawer
variant="permanent"
sx={{
width: 240,
flexShrink: 0,
[`& .MuiDrawer-paper`]: { width: 240, boxSizing: 'border-box', position: 'relative' },
}}
>
<Box sx={{ p: 2, display: 'flex', flexDirection: 'column', height: '100%' }}>
<Box sx={{ mb: 3 }}>
<Typography variant="overline" color="text.secondary" gutterBottom>Main</Typography>
<List disablePadding>
<ListItem disablePadding>
<ListItemButton sx={{ borderRadius: 1 }}>
<ListItemIcon sx={{ minWidth: 36 }}>
<SearchIcon fontSize="small" />
</ListItemIcon>
<ListItemText primary="Q&A" />
</ListItemButton>
</ListItem>
<ListItem disablePadding>
<ListItemButton
sx={{ borderRadius: 1, bgcolor: 'primary.lighter', color: 'primary.main' }}
>
<ListItemIcon sx={{ minWidth: 36, color: 'primary.main' }}>
<FileTextIcon fontSize="small" />
</ListItemIcon>
<ListItemText primary="Resume Builder" />
</ListItemButton>
</ListItem>
</List>
</Box>
<Box sx={{ mb: 3 }}>
<Typography variant="overline" color="text.secondary" gutterBottom>My Content</Typography>
<List disablePadding>
<ListItem disablePadding>
<ListItemButton sx={{ borderRadius: 1 }}>
<ListItemIcon sx={{ minWidth: 36 }}>
<FileTextIcon fontSize="small" />
</ListItemIcon>
<ListItemText primary="My Resumes" />
<Chip
label={savedResumes.length}
size="small"
sx={{ height: 20, fontSize: 12 }}
/>
</ListItemButton>
</ListItem>
<ListItem disablePadding>
<ListItemButton sx={{ borderRadius: 1 }}>
<ListItemIcon sx={{ minWidth: 36 }}>
<SettingsIcon fontSize="small" />
</ListItemIcon>
<ListItemText primary="Settings" />
</ListItemButton>
</ListItem>
</List>
</Box>
<Box sx={{ mt: 'auto' }}>
<Paper variant="outlined" sx={{ p: 2, bgcolor: 'background.default' }}>
<Typography variant="subtitle2" color="text.primary" gutterBottom>Recent Activity</Typography>
<List dense disablePadding>
{savedResumes.filter(r => r.isRecent).map(resume => (
<ListItem key={resume.id} disablePadding sx={{ mb: 0.5 }}>
<ListItemIcon sx={{ minWidth: 24 }}>
<ClockIcon fontSize="small" />
</ListItemIcon>
<Typography variant="body2" noWrap>{resume.name}</Typography>
</ListItem>
))}
</List>
</Paper>
</Box>
</Box>
</Drawer>
)}
{/* Mobile menu - drawer */}
<Drawer
anchor="left"
open={isMobileMenuOpen}
onClose={() => setIsMobileMenuOpen(false)}
sx={{
display: { xs: 'block', md: 'none' },
'& .MuiDrawer-paper': { width: 240 }
}}
>
<Box sx={{ p: 2, display: 'flex', flexDirection: 'column', height: '100%' }}>
<Box sx={{ mb: 3 }}>
<Typography variant="overline" color="text.secondary" gutterBottom>Main</Typography>
<List disablePadding>
<ListItem disablePadding>
<ListItemButton onClick={() => setIsMobileMenuOpen(false)}>
<ListItemIcon>
<SearchIcon fontSize="small" />
</ListItemIcon>
<ListItemText primary="Q&A" />
</ListItemButton>
</ListItem>
<ListItem disablePadding>
<ListItemButton
onClick={() => setIsMobileMenuOpen(false)}
sx={{ bgcolor: 'primary.lighter', color: 'primary.main' }}
>
<ListItemIcon sx={{ color: 'primary.main' }}>
<FileTextIcon fontSize="small" />
</ListItemIcon>
<ListItemText primary="Resume Builder" />
</ListItemButton>
</ListItem>
</List>
</Box>
<Box sx={{ mb: 3 }}>
<Typography variant="overline" color="text.secondary" gutterBottom>My Content</Typography>
<List disablePadding>
<ListItem disablePadding>
<ListItemButton onClick={() => setIsMobileMenuOpen(false)}>
<ListItemIcon>
<FileTextIcon fontSize="small" />
</ListItemIcon>
<ListItemText primary="My Resumes" />
<Chip
label={savedResumes.length}
size="small"
sx={{ height: 20, fontSize: 12 }}
/>
</ListItemButton>
</ListItem>
<ListItem disablePadding>
<ListItemButton onClick={() => setIsMobileMenuOpen(false)}>
<ListItemIcon>
<SettingsIcon fontSize="small" />
</ListItemIcon>
<ListItemText primary="Settings" />
</ListItemButton>
</ListItem>
</List>
</Box>
</Box>
</Drawer>
{/* Main content */}
<Box sx={{ flex: 1, overflow: 'auto', p: 3 }}>
{/* Resume Builder content */}
<Box sx={{ mb: 4 }}>
<Typography variant="h5" component="h2" fontWeight="bold" gutterBottom>Resume Builder</Typography>
<Typography variant="body2" color="text.secondary">Generate and customize resumes based on job descriptions</Typography>
</Box>
{/* Tabs */}
<Box sx={{ borderBottom: 1, borderColor: 'divider', mb: 3 }}>
<Tabs
value={activeTab}
onChange={(_, newValue) => setActiveTab(newValue)}
aria-label="Resume builder tabs"
variant={isMobile ? "scrollable" : "standard"}
scrollButtons={isMobile ? "auto" : undefined}
>
<Tab label="Job Description" value="job" />
<Tab label="Resume" value="resume" />
<Tab label="Fact Check" value="fact" />
<Tab label="Saved Resumes" value="saved" />
</Tabs>
</Box>
{/* Tab content */}
{activeTab === 'job' && (
<Paper variant="outlined" sx={{ p: 3 }}>
<Typography variant="h6" gutterBottom>Job Description</Typography>
<TextField
fullWidth
multiline
rows={10}
placeholder="Paste the job description here..."
variant="outlined"
/>
<Box sx={{ mt: 3 }}>
<Button variant="contained" color="primary">
Generate Resume
</Button>
</Box>
</Paper>
)}
{activeTab === 'resume' && (
<Paper variant="outlined" sx={{ p: 3 }}>
<Box sx={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', mb: 3 }}>
<Typography variant="h6">Resume Editor</Typography>
<Box sx={{ display: 'flex', gap: 1 }}>
<Button
variant="outlined"
size="small"
startIcon={<SaveIcon />}
>
Save
</Button>
<Button
variant="outlined"
size="small"
startIcon={<EyeIcon />}
>
Preview
</Button>
</Box>
</Box>
{/* Resume content editor with sections */}
<Box sx={{ display: 'flex', flexDirection: 'column', gap: 2 }}>
{/* Contact information */}
<Paper variant="outlined" sx={{ p: 2 }}>
<Box sx={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', mb: 2 }}>
<Typography variant="subtitle1" fontWeight="medium">Contact Information</Typography>
<IconButton size="small" color="default">
<EditIcon fontSize="small" />
</IconButton>
</Box>
<Box sx={{ display: 'grid', gridTemplateColumns: { xs: '1fr', md: '1fr 1fr' }, gap: 2 }}>
<Box>
<Typography variant="caption" color="text.secondary" display="block" gutterBottom>
Full Name
</Typography>
<TextField size="small" fullWidth defaultValue="John Doe" />
</Box>
<Box>
<Typography variant="caption" color="text.secondary" display="block" gutterBottom>
Email
</Typography>
<TextField size="small" fullWidth defaultValue="john@example.com" />
</Box>
</Box>
</Paper>
{/* Professional Summary */}
<Paper variant="outlined" sx={{ p: 2 }}>
<Box sx={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', mb: 2 }}>
<Typography variant="subtitle1" fontWeight="medium">Professional Summary</Typography>
<IconButton size="small" color="default">
<EditIcon fontSize="small" />
</IconButton>
</Box>
<TextField
fullWidth
multiline
rows={3}
size="small"
defaultValue="Experienced software developer with 8+ years in full-stack development, specializing in React, Node.js, and cloud infrastructure. Passionate about creating scalable, maintainable applications."
/>
</Paper>
{/* Work Experience */}
<Paper variant="outlined" sx={{ p: 2 }}>
<Box sx={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', mb: 2 }}>
<Typography variant="subtitle1" fontWeight="medium">Work Experience</Typography>
<Button
startIcon={<PlusIcon />}
color="primary"
size="small"
>
Add Position
</Button>
</Box>
{/* Job entry */}
<Paper variant="outlined" sx={{ p: 2, mb: 2, bgcolor: 'background.default' }}>
<Box sx={{ display: 'flex', justifyContent: 'space-between' }}>
<Typography variant="subtitle2" fontWeight="medium">Senior Developer</Typography>
<Box sx={{ display: 'flex', gap: 0.5 }}>
<IconButton size="small">
<EditIcon fontSize="small" />
</IconButton>
<IconButton size="small" color="error">
<TrashIcon fontSize="small" />
</IconButton>
</Box>
</Box>
<Typography variant="body2" color="text.secondary">Tech Company Inc. 2020-Present</Typography>
<Box component="ul" sx={{ pl: 2, mt: 1 }}>
<Typography component="li" variant="body2">Led development of company's flagship product</Typography>
<Typography component="li" variant="body2">Improved performance by 40% through code optimization</Typography>
</Box>
</Paper>
</Paper>
{/* Add more sections button */}
<Button
variant="outlined"
fullWidth
sx={{
borderStyle: 'dashed',
p: 1.5,
color: 'text.secondary',
'&:hover': { bgcolor: 'background.default' }
}}
startIcon={<PlusIcon />}
>
Add Section
</Button>
</Box>
</Paper>
)} {activeTab === 'saved' && (
<Paper variant="outlined" sx={{ p: 3 }}>
<Box sx={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', mb: 3 }}>
<Typography variant="h6">Saved Resumes</Typography>
<Button
variant="contained"
color="primary"
size="small"
startIcon={<PlusIcon />}
>
New Resume
</Button>
</Box>
{/* Resume list */}
<Box sx={{ display: 'flex', flexDirection: 'column', gap: 2 }}>
{savedResumes.map(resume => (
<Paper
key={resume.id}
variant="outlined"
sx={{
p: 2,
display: 'flex',
justifyContent: 'space-between',
alignItems: 'center',
cursor: 'pointer',
bgcolor: selectedResume === resume.id ? 'primary.lighter' : 'background.paper',
borderColor: selectedResume === resume.id ? 'primary.light' : 'divider',
'&:hover': { bgcolor: selectedResume === resume.id ? 'primary.lighter' : 'action.hover' }
}}
onClick={() => setSelectedResume(resume.id)}
>
<Box>
<Typography variant="subtitle2">{resume.name}</Typography>
<Typography variant="caption" color="text.secondary">Last edited: {resume.date}</Typography>
</Box>
<Box sx={{ display: 'flex', gap: 1 }}>
<IconButton size="small">
<EditIcon fontSize="small" />
</IconButton>
<IconButton size="small" color="error">
<TrashIcon fontSize="small" />
</IconButton>
</Box>
</Paper>
))}
</Box>
</Paper>
)}
{activeTab === 'fact' && (
<Paper variant="outlined" sx={{ p: 3 }}>
<Typography variant="h6" gutterBottom>Fact Check</Typography>
<Typography variant="body2" color="text.secondary" paragraph>
This tab shows how your resume content compares to your employment history data.
</Typography>
<Box sx={{ mt: 2 }}>
<Paper variant="outlined" sx={{ p: 2, mb: 2, bgcolor: 'success.lighter' }}>
<Typography variant="subtitle2" fontWeight="medium" color="success.dark">
✓ Work History Verification
</Typography>
<Typography variant="body2">
All employment dates match your documented history.
</Typography>
</Paper>
<Paper variant="outlined" sx={{ p: 2, mb: 2, bgcolor: 'warning.lighter' }}>
<Typography variant="subtitle2" fontWeight="medium" color="warning.dark">
⚠ Skills Verification
</Typography>
<Typography variant="body2">
Some skills listed (React Native, Flutter) are not strongly supported by your experience documents.
</Typography>
</Paper>
</Box>
</Paper>
)}
</Box>
</Box>
{/* Mobile bottom navigation */}
{isMobile && (
<Paper
sx={{
position: 'fixed',
bottom: 0,
left: 0,
right: 0,
display: 'flex',
justifyContent: 'space-around',
borderTop: 1,
borderColor: 'divider',
zIndex: 1100
}}
elevation={3}
>
<Box
sx={{
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
py: 1,
px: 2,
color: 'text.secondary'
}}
component="button"
>
<SearchIcon />
<Typography variant="caption">Q&A</Typography>
</Box>
<Box
sx={{
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
py: 1,
px: 2,
color: 'primary.main'
}}
component="button"
>
<FileTextIcon />
<Typography variant="caption">Resume</Typography>
</Box>
<Box
sx={{
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
py: 1,
px: 2,
color: 'text.secondary'
}}
component="button"
>
<UserIcon />
<Typography variant="caption">Profile</Typography>
</Box>
</Paper>
)}
</Box>
);
}
export {
MockupPage
};