Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
131 changes: 65 additions & 66 deletions client/src/features/trainee-profile/profile/ProfileSidebar.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { Avatar, Box, IconButton, Link, Stack, Typography } from '@mui/material';

import { LearningStatus } from '../../../data/types/Trainee';
import LinkedInLogo from '../../../assets/LinkedIn_logo.png';
import { Box, IconButton, Link, Stack, Typography } from '@mui/material';
import { SidebarJobPath } from '../../../components/SidebarJobPath';
import { SidebarLearningStatus } from '../../../components/SidebarLearningStatus';
import { LearningStatus } from '../../../data/types/Trainee';
import LinkedInLogo from '../../../assets/LinkedIn_logo.png';
import githubLogo from '../../../assets/github.png';
import slackLogo from '../../../assets/slack.png';
import { useTraineeInfoData } from '../personal-info/data/useTraineeInfoData';
import { ProfilePictureModal } from './components/ProfilePictureModal';

interface ProfileSidebarProps {
traineeId: string;
Expand All @@ -18,76 +18,75 @@ interface ProfileSidebarProps {
* @param {string} traineeId trainee id.
* @returns {ReactNode} A React element that renders profile page sidebar information and profile image.
*/
const ProfileSidebar = ({ traineeId }: ProfileSidebarProps) => {
export const ProfileSidebar = ({ traineeId }: ProfileSidebarProps) => {
const { data } = useTraineeInfoData(traineeId);

const slackId = data?.contactInfo?.slackId;
const githubHandle = data?.contactInfo?.githubHandle;
const linkedIn = data?.contactInfo?.linkedin;

return (
<Box
display="flex"
flexDirection="column"
alignItems="center"
gap={2}
color="black"
bgcolor="hyfBeige.main"
height="95vh"
paddingX={4}
paddingY={4}
>
{/* Profile image */}
<Box height={180} width={180} display="flex" justifyContent="center">
<Avatar variant="square" sx={{ width: '100%', height: '100%' }} src={data?.imageURL} alt={data?.displayName} />
</Box>

<Stack direction="column" spacing={1} justifyContent="center" alignItems="center">
{/* Name */}
<Typography variant="h6" fontWeight="bold" color="text.primary">
{data?.displayName}
</Typography>
{/* Pronouns */}
<Typography variant="body1" color="text.secondary">
{data?.personalInfo?.pronouns}
</Typography>
{/* Learning Status */}
{data?.educationInfo?.learningStatus === LearningStatus.Graduated ? (
<SidebarJobPath jobPath={data?.employmentInfo?.jobPath}></SidebarJobPath>
) : (
<SidebarLearningStatus learningStatus={data?.educationInfo?.learningStatus}></SidebarLearningStatus>
)}
{/* Cohort */}
<Typography variant="body1" color="text.secondary">
Cohort {data?.educationInfo?.currentCohort || 'not assigned'}
</Typography>
</Stack>
<>
<Box
display="flex"
flexDirection="column"
alignItems="center"
gap={2}
color="black"
bgcolor="#d1fbe6"
height="100vh"
paddingX={4}
paddingY={4}
>
<ProfilePictureModal data={data} onUploadModalOpen={() => null} onConfirmationDialogOpen={() => null} />

{/* social media contact info */}
<div style={{ display: 'flex', justifyContent: 'center', gap: '16px' }}>
{slackId && (
<Link href={`slack://user?team=T0EJTUQ87&id=${slackId}`}>
<IconButton aria-label="Slack Id">
<img src={slackLogo} alt="Slack" width="32" height="32" style={{ borderRadius: '50%' }} />
</IconButton>
</Link>
)}
{githubHandle && (
<Link href={`https://github.com/${githubHandle}`} target="_blank" rel="noopener">
<IconButton aria-label="GitHub handel">
<img src={githubLogo} alt="GitHub" width="32" height="32" style={{ borderRadius: '50%' }} />
</IconButton>
</Link>
)}
{linkedIn && (
<Link href={linkedIn} target="_blank" rel="noopener">
<IconButton aria-label="LinkedIn URL">
<img src={LinkedInLogo} alt="LinkedIn" width="32" height="32" />
</IconButton>
</Link>
)}
</div>
</Box>
<Stack direction="column" spacing={1} justifyContent="center" alignItems="center">
{/* Name */}
<Typography variant="h6" fontWeight="bold">
{data?.displayName}
</Typography>
{/* Pronouns */}
<Typography variant="body1" color="text.secondary">
{data?.personalInfo?.pronouns}
</Typography>
{/* Learning Status */}
{data?.educationInfo?.learningStatus === LearningStatus.Graduated ? (
<SidebarJobPath jobPath={data?.employmentInfo?.jobPath}></SidebarJobPath>
) : (
<SidebarLearningStatus learningStatus={data?.educationInfo?.learningStatus}></SidebarLearningStatus>
)}
{/* Cohort */}
<Typography variant="body1" color="text.secondary">
Cohort {data?.educationInfo?.currentCohort || 'not assigned'}
</Typography>
</Stack>
{/* social media contact info */}
<div style={{ display: 'flex', justifyContent: 'center', gap: '16px' }}>
{slackId && (
<Link href={`slack://user?team=T0EJTUQ87&id=${slackId}`}>
<IconButton aria-label="Slack Id">
<img src={slackLogo} alt="Slack" width="32" height="32" style={{ borderRadius: '50%' }} />
</IconButton>
</Link>
)}
{githubHandle && (
<Link href={`https://github.com/${githubHandle}`} target="_blank" rel="noopener">
<IconButton aria-label="GitHub handel">
<img src={githubLogo} alt="GitHub" width="32" height="32" style={{ borderRadius: '50%' }} />
</IconButton>
</Link>
)}
{linkedIn && (
<Link href={linkedIn} target="_blank" rel="noopener">
<IconButton aria-label="LinkedIn URL">
<img src={LinkedInLogo} alt="LinkedIn" width="32" height="32" />
</IconButton>
</Link>
)}
</div>
</Box>
</>
);
};

export default ProfileSidebar;
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
import { Avatar, Box, Fade, IconButton } from '@mui/material';
import React from 'react';
import EditIcon from '@mui/icons-material/Edit';
import DeleteIcon from '@mui/icons-material/Delete';
import { Trainee } from '../../../../data/types/Trainee';

interface ProfilePictureModalProps {
data: Trainee | undefined;
onUploadModalOpen: () => void;
onConfirmationDialogOpen: () => void;
}

export const ProfilePictureModal = ({
data,
onUploadModalOpen,
onConfirmationDialogOpen,
}: ProfilePictureModalProps) => {
const [isHovering, setIsHovering] = React.useState<boolean>(false);

return (
<Box
onMouseEnter={() => {
setIsHovering(true);
}}
onMouseLeave={() => {
setIsHovering(false);
}}
height={180}
width={180}
display="flex"
justifyContent="center"
position="relative"
>
<Avatar
src={data?.imageURL}
alt={data?.displayName}
variant="square"
sx={{
width: '100%',
height: '100%',
filter: isHovering ? 'brightness(0.7)' : 'none',
}}
/>

{isHovering && (
<Box
sx={{
display: 'flex',
position: 'absolute',
justifyContent: 'center',
alignItems: 'center',
gap: 5,
top: 0,
bottom: 0,
left: 0,
right: 0,
}}
>
<Fade in={isHovering}>
<IconButton onClick={onUploadModalOpen} aria-label="Edit profile picture">
<EditIcon
sx={{
color: 'white',
fontSize: 40,
'&:hover': { transform: 'scale(1.1)' },
'&:active': { transform: 'scale(0.9)' },
}}
/>
</IconButton>
</Fade>
<Fade in={isHovering}>
<IconButton onClick={onConfirmationDialogOpen} aria-label="Delete profile picture">
<DeleteIcon
sx={{
color: 'white',
fontSize: 40,
'&:hover': { transform: 'scale(1.1)' },
'&:active': { transform: 'scale(0.9)' },
}}
/>
</IconButton>
</Fade>
</Box>
)}
</Box>
);
};