feat: implemented teacher profile button and popup#58
Conversation
|
The latest updates on your projects. Learn more about Vercel for Git ↗︎
|
ChinemeremChigbo
left a comment
There was a problem hiding this comment.
I have listed some suggested changed. I also think you should remove the profile.tsx file. I have made a PR that implements the changes I would like here: . If you agree, please squash these changes into your branch and re-request a review
There was a problem hiding this comment.
The month text should be left aligned and I would remove unnecessary comments:
import React from 'react';
import {
Menu,
MenuButton,
IconButton,
MenuList,
Text,
Avatar,
Button,
useColorModeValue,
} from '@chakra-ui/react';
import { signOut } from 'next-auth/react';
// Helper to color-code the "X/Y Absences Taken"
function getAbsenceColor(usedAbsences: number) {
if (usedAbsences <= 6) return 'green.500';
if (usedAbsences <= 8) return 'yellow.500';
return 'red.500';
}
// Same interface as used in CalendarHeader, or define your own
interface UserData {
name: string;
email: string;
image?: string;
usedAbsences: number;
numOfAbsences: number;
}
interface ProfileMenuProps {
userData?: UserData;
}
const ProfileMenu: React.FC<ProfileMenuProps> = ({ userData }) => {
const absenceColor = userData
? getAbsenceColor(userData.usedAbsences)
: 'gray.500';
return (
<Menu>
<MenuButton
as={IconButton}
icon={
<Avatar
name={userData?.name ?? 'User'}
src={userData?.image}
size="sm"
/>
}
variant="ghost"
aria-label="Open profile menu"
_hover={{ bg: useColorModeValue('gray.100', 'gray.700') }}
/>
<MenuList
minW="280px" // Make the pop-up larger
p="2rem" // Add some padding
textAlign="center"
boxShadow="lg"
borderRadius="md"
>
{/* Title: "Hi, [Name]!" in 2xl */}
<Text fontSize="2xl" fontWeight="semibold" mb={1}>
Hi, {userData?.name}!
</Text>
{/* Email below the title */}
<Text fontSize="sm" color="gray.500" mb={3}>
{userData?.email}
</Text>
{/* Larger avatar below the email */}
<Avatar
name={userData?.name ?? 'User'}
src={userData?.image}
size="xl"
mx="auto"
mb={3}
/>
{/* Absences Taken: e.g. "4/10" in color */}
<Text fontSize="md" mb={4}>
<Text as="span" fontWeight="bold" color={absenceColor}>
{userData?.usedAbsences}/{userData?.numOfAbsences}
</Text>{' '}
Absences Taken
</Text>
{/* Log Out button: white background, gray border */}
<Button
onClick={() => signOut()}
variant="outline"
borderColor="gray.300"
borderRadius="md"
size="md"
width="100%"
_hover={{ bg: useColorModeValue('gray.100', 'gray.700') }}
>
Log Out
</Button>
</MenuList>
</Menu>
);
};
export default ProfileMenu;
src/components/ProfileMenu.tsx
Outdated
| import { signOut } from 'next-auth/react'; | ||
|
|
||
| // Helper to color-code the "X/Y Absences Taken" | ||
| function getAbsenceColor(usedAbsences: number) { |
There was a problem hiding this comment.
I would use const instead of function
src/components/ProfileMenu.tsx
Outdated
| icon={ | ||
| <Avatar | ||
| name={userData?.name ?? 'User'} | ||
| src={userData?.image} |
There was a problem hiding this comment.
Hmm, not sure why but sometimes I need to navigate to the /profile page, and then navigate back to the calendar to get the image to show up. I assume it works on the profile page since it uses a use effect to make sure the data is available whereas this does not? Not quite sure, but would be nice if the image / other data was useeffected for this component.

src/pages/calendar.tsx
Outdated
| `/api/users/email/${session.user.email}?shouldIncludeAbsences=true` | ||
| ); | ||
| const data = await res.json(); | ||
| // data.numOfAbsences plus data.absences?.length is the usage |
There was a problem hiding this comment.
I would remove comments for things that feel obvious and make some changes to the spacing. Here are some of my suggestions:
import React from 'react';
import {
Menu,
MenuButton,
IconButton,
MenuList,
Text,
Avatar,
Button,
useColorModeValue,
} from '@chakra-ui/react';
import { signOut } from 'next-auth/react';
const getAbsenceColor = (usedAbsences: number) => {
if (usedAbsences <= 6) return 'green.500';
if (usedAbsences <= 8) return 'yellow.500';
return 'red.500';
};
interface UserData {
name: string;
email: string;
image?: string;
usedAbsences: number;
numOfAbsences: number;
}
interface ProfileMenuProps {
userData?: UserData;
}
const ProfileMenu: React.FC<ProfileMenuProps> = ({ userData }) => {
const absenceColor = userData
? getAbsenceColor(userData.usedAbsences)
: 'gray.500';
return (
<Menu>
<MenuButton
as={IconButton}
icon={
<Avatar
name={userData?.name ?? 'User'}
src={userData?.image}
size="sm"
/>
}
variant="ghost"
aria-label="Open profile menu"
_hover={{ bg: useColorModeValue('gray.100', 'gray.700') }}
/>
<MenuList
minW="280px"
maxW="320px"
p="3rem"
textAlign="center"
boxShadow="lg"
borderRadius="md"
>
<Text
fontSize="2xl"
fontWeight="semibold"
mb={2}
whiteSpace="normal"
wordBreak="break-word"
>
Hi, {userData?.name}!
</Text>
<Text fontSize="sm" color="gray.500" mb={4}>
{userData?.email}
</Text>
<Avatar
name={userData?.name ?? 'User'}
src={userData?.image}
size="xl"
mx="auto"
mb={4}
/>
<Text fontSize="md" mb={5}>
<Text as="span" fontWeight="bold" color={absenceColor}>
{userData?.usedAbsences}/{userData?.numOfAbsences}
</Text>{' '}
Absences Taken
</Text>
<Button
onClick={() => signOut()}
variant="outline"
borderColor="gray.300"
borderRadius="md"
size="md"
width="100%"
_hover={{ bg: useColorModeValue('gray.100', 'gray.700') }}
>
Log Out
</Button>
</MenuList>
</Menu>
);
};
export default ProfileMenu;
src/components/CalendarHeader.tsx
Outdated
| } from '@chakra-ui/icons'; | ||
| import ProfileMenu from './ProfileMenu'; | ||
|
|
||
| // Example interface for userData; adjust fields as needed. |
There was a problem hiding this comment.
note: interfaces may be moved to a types.ts file to be shared globally. mentioning just in case my PR gets merged before yours
src/components/CalendarHeader.tsx
Outdated
| } from '@chakra-ui/icons'; | ||
| import ProfileMenu from './ProfileMenu'; | ||
|
|
||
| interface UserData { |
There was a problem hiding this comment.
sorry lol looks like I was merged in first, please import from latest in main: d3663c8 for this file and ProfileMenu.tsx

Notion ticket link
Teacher Profile Popup Frontend
Implementation description
-implemented teacher popup on the right side of CalendarHeader, created ProfileMenu component
Steps to test
What should reviewers focus on?
Checklist