Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: implemented teacher profile button and popup #58

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

daniel-su1
Copy link

@daniel-su1 daniel-su1 commented Feb 5, 2025

Notion ticket link

Teacher Profile Popup Frontend

Implementation description

-implemented teacher popup on the right side of CalendarHeader, created ProfileMenu component

Steps to test

  1. go to main calendar page and click on it, it should be there 💀

What should reviewers focus on?

Checklist

  • My PR name is descriptive and in imperative tense
  • My commit messages are descriptive and in imperative tense. My commits are atomic and trivial commits are squashed or fixup'd into non-trivial commits
  • I have run the appropriate linter(s)
  • I have requested a review from the PL, as well as other devs who have background knowledge on this PR or who will be building on top of this PR

Copy link

vercel bot commented Feb 5, 2025

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
sistema ✅ Ready (Inspect) Visit Preview 💬 Add feedback Feb 5, 2025 1:18am

@daniel-su1 daniel-su1 requested review from ChinemeremChigbo, 135ze and a team February 5, 2025 01:24
@ChinemeremChigbo ChinemeremChigbo requested review from a team and removed request for a team February 5, 2025 01:27
Copy link
Member

@ChinemeremChigbo ChinemeremChigbo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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;

import { signOut } from 'next-auth/react';

// Helper to color-code the "X/Y Absences Taken"
function getAbsenceColor(usedAbsences: number) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would use const instead of function

icon={
<Avatar
name={userData?.name ?? 'User'}
src={userData?.image}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.
image

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be:
image

`/api/users/email/${session.user.email}?shouldIncludeAbsences=true`
);
const data = await res.json();
// data.numOfAbsences plus data.absences?.length is the usage
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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;

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants