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

Zotistics graph pops up on hover #727

Merged
merged 13 commits into from
Oct 26, 2023
9 changes: 6 additions & 3 deletions apps/antalmanac/src/components/PatchNotes.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -51,15 +51,18 @@ function PatchNotes() {
data-testid={dialogTestId}
slots={{ backdrop: PatchNotesBackdrop }}
>
<DialogTitle>{"What's New - August 2023"}</DialogTitle>
<DialogTitle>{"What's New - October 2023"}</DialogTitle>

<DialogContent>
<Typography>Features</Typography>
<ul>
<li>Courses will now be greyed out if they conflict with your current schedule</li>
<li>
You can now hover over the Zotistics button to see the Zotistics graph! On mobile, you can still
click the Zotistics button to toggle the graph.
</li>
</ul>
<img
src="https://user-images.githubusercontent.com/100006999/255796434-10555ecb-5632-4ff3-8be3-c04267722011.gif"
src="https://user-images.githubusercontent.com/78244965/277567417-f9816b9d-ddda-4c0f-80f4-eeac92428612.gif"
alt="(gif of the new feature)"
style={{
maxWidth: '100%',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@ function flattenSOCObject(SOCObject: WebsocAPIResponse): (WebsocSchool | WebsocD
return accumulator;
}, []);
}

const RecruitmentBanner = () => {
const [bannerVisibility, setBannerVisibility] = React.useState<boolean>(true);

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Button, Popover, useMediaQuery } from '@material-ui/core';
import { Button, Paper, Popper, useMediaQuery } from '@material-ui/core';
import { withStyles } from '@material-ui/core/styles';
import { ClassNameMap } from '@material-ui/core/styles/withStyles';
import React, { useState } from 'react';
import React, { useEffect, useState } from 'react';

import { MOBILE_BREAKPOINT } from '../../../globals';
import { logAnalytics } from '$lib/analytics';
Expand Down Expand Up @@ -34,49 +34,67 @@ function CourseInfoButton({
}: CourseInfoButtonProps) {
const [popupAnchor, setPopupAnchor] = useState<HTMLElement | null>(null);
const isMobileScreen = useMediaQuery(`(max-width: ${MOBILE_BREAKPOINT})`);
const [isClicked, setIsClicked] = useState(false);

useEffect(() => {
// When the user clicks on the button, it triggers both onMouseEnter
// and onClick. In order to log the analytics only once, we should
// have this hook when the popupAnchor changes
if (popupAnchor) {
logAnalytics({
category: analyticsCategory,
action: analyticsAction,
});
}
}, [popupAnchor, analyticsCategory, analyticsAction]);

const handleMouseEnter = (event: React.MouseEvent<HTMLElement>) => {
// If there is popup content, allow the content to be shown when the button is hovered
// Note that on mobile devices, hovering is not possible, so the popup still needs to be able
// to appear when the button is clicked
if (popupContent) {
setPopupAnchor(event.currentTarget);
}
};

const handleMouseLeave = () => {
if (popupContent) {
setIsClicked(false);
setPopupAnchor(null);
}
};

return (
<>
<div onMouseEnter={handleMouseEnter} onMouseLeave={handleMouseLeave} style={{ display: 'flex' }}>
<Button
className={classes.button}
startIcon={!isMobileScreen && icon}
variant="contained"
size="small"
onClick={(event: React.MouseEvent<HTMLElement>) => {
logAnalytics({
category: analyticsCategory,
action: analyticsAction,
});

if (redirectLink) {
window.open(redirectLink);
}

if (popupContent) {
setPopupAnchor(event.currentTarget);
// This is mostly used for devices that don't support hovering
// and thus only support clicking to open/close the popup
// If isClicked is true, then the popup is currently visible; otherwise, if
// isClicked is false, then the popup is currently hidden
setPopupAnchor(isClicked ? null : event.currentTarget);
setIsClicked((prev) => !prev);
}
}}
>
{text}
</Button>

{popupContent && (
<Popover
anchorEl={popupAnchor}
open={Boolean(popupAnchor)}
onClose={() => setPopupAnchor(null)}
anchorOrigin={{
vertical: 'bottom',
horizontal: 'center',
}}
transformOrigin={{
vertical: 'top',
horizontal: 'center',
}}
>
{popupContent}
</Popover>
<Popper anchorEl={popupAnchor} open={Boolean(popupAnchor)} placement="bottom">
<Paper>{popupContent}</Paper>
</Popper>
)}
</>
</div>
);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,20 +57,22 @@ function GradesPopup(props: GradesPopupProps) {

const [gradeData, setGradeData] = useState<GradeData>();

const width = useMemo(() => (isMobileScreen ? 300 : 500), [isMobileScreen]);
const width = useMemo(() => (isMobileScreen ? 250 : 400), [isMobileScreen]);

const height = useMemo(() => (isMobileScreen ? 200 : 300), [isMobileScreen]);
const height = useMemo(() => (isMobileScreen ? 150 : 200), [isMobileScreen]);

const graphTitle = useMemo(() => {
return gradeData
? `${deptCode} ${courseNumber}${instructor ? ` — ${instructor}` : "" } | Average GPA: ${gradeData.courseGrades.averageGPA.toFixed(2)}`
? `${deptCode} ${courseNumber}${
instructor ? ` — ${instructor}` : ''
} | Average GPA: ${gradeData.courseGrades.averageGPA.toFixed(2)}`
: 'Grades are not available for this class.';
}, [deptCode, instructor, gradeData]);

const gpaString = useMemo(
() => (gradeData ? `Average GPA: ${gradeData.courseGrades.averageGPA.toFixed(2)}` : ""),
() => (gradeData ? `Average GPA: ${gradeData.courseGrades.averageGPA.toFixed(2)}` : ''),
[gradeData]
)
);

useEffect(() => {
if (loading === false) {
Expand Down Expand Up @@ -107,15 +109,15 @@ function GradesPopup(props: GradesPopupProps) {
const axisColor = isDarkMode() ? '#fff' : '#111';

return (
<Box>
<Box sx={{ padding: '4px' }}>
<Typography
sx={{
marginTop: '.5rem',
textAlign: 'center',
fontWeight: 500,
fontSize: '1.2rem',
marginRight: '4rem',
marginLeft: '4rem',
marginRight: '2rem',
marginLeft: '2rem',
marginBottom: '.5rem',
}}
>
{graphTitle}
Expand Down
2 changes: 1 addition & 1 deletion apps/antalmanac/src/stores/ColumnStore.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { create } from 'zustand';
import analyticsEnum, { logAnalytics } from '$lib/analytics';
import useTabStore from './TabStore';
import analyticsEnum, { logAnalytics } from '$lib/analytics';

/**
* Search results are displayed in a tabular format.
Expand Down
Loading