From e7e8c6efdd691fa2256b9e52238ccd2319b9d530 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maciek=20G=C5=82owacki?= Date: Thu, 26 Nov 2020 03:09:58 +0100 Subject: [PATCH] added highlighting of hovered group and updated styles --- src/components/CourseCard.tsx | 42 +++++++++++++++++++++++------ src/components/Rightbar.tsx | 1 - src/components/SchedulerRow.tsx | 27 +++++++++++++++---- src/components/Topbar.tsx | 1 - src/contexts/CoursesProvider.tsx | 45 +++++++++++++++++++++++++++++--- 5 files changed, 97 insertions(+), 19 deletions(-) diff --git a/src/components/CourseCard.tsx b/src/components/CourseCard.tsx index fb37e21..e6fa084 100644 --- a/src/components/CourseCard.tsx +++ b/src/components/CourseCard.tsx @@ -1,4 +1,4 @@ -import React, { useState, useContext } from 'react'; +import React, { useState, useContext, useEffect } from 'react'; import Collapse from '@material-ui/core/Collapse'; import { ReactComponent as Expand } from '../assets/expand.svg'; import { Course, Group, GroupType } from '../types/index'; @@ -7,6 +7,7 @@ import styled, { css } from 'styled-components'; import { makeStyles } from '@material-ui/core/styles'; import { ReactComponent as Bin } from '../assets/bin.svg'; import DeleteIcon from '@material-ui/icons/Delete'; +import { useMemo } from 'react'; const CourseCardWrapper = styled.div` position: relative; @@ -134,13 +135,19 @@ interface CourseCardProps { export const CourseCard = ({ course }: CourseCardProps) => { const classes = useStyles(); - const { changeGroupInBasket, deleteFromBasket } = useContext(coursesContext)!; - + const { + hoveredGroup, + changeGroupInBasket, + deleteFromBasket, + selectBasketCourseGroups, + changeHoveredGroup, + } = useContext(coursesContext)!; const [isSelected, setSelected] = useState(false); - const groups = [...course.lectures!, ...course.classes!]; - - const onGroupClick = (group: Group, id: number) => changeGroupInBasket(group, id); + const [courseLecture, courseClasses] = selectBasketCourseGroups(course.id); + // console.log('lecture is: ', courseLecture); + // console.log('class is: ', courseClasses); + const onGroupClick = (group: Group, courseId: number) => changeGroupInBasket(group, courseId); return ( @@ -156,8 +163,27 @@ export const CourseCard = ({ course }: CourseCardProps) => { setSelected(!isSelected)} selected={isSelected} /> - {groups.map((group, index) => ( - onGroupClick(group, course.id)}> + {groups.map((group: Group, index) => ( + onGroupClick(group, course.id)} + onMouseEnter={() => { + if (group.type === GroupType.CLASS && courseClasses !== undefined) { + changeHoveredGroup(courseClasses); + changeGroupInBasket(group, course.id); + } + if (group.type === GroupType.LECTURE && courseLecture !== undefined) { + changeHoveredGroup(courseLecture); + changeGroupInBasket(group, course.id); + } + }} + onMouseLeave={() => { + if (hoveredGroup) { + changeGroupInBasket(hoveredGroup, course.id); + changeHoveredGroup(null); + } + }} + > {group.type === 'CLASS' ? 'ĆW' : 'WYK'} {group.lecturer.replace('UAM', '').length >= 32 ? ( diff --git a/src/components/Rightbar.tsx b/src/components/Rightbar.tsx index e4ce78a..610def4 100644 --- a/src/components/Rightbar.tsx +++ b/src/components/Rightbar.tsx @@ -52,7 +52,6 @@ export const Rightbar = () => { const basketCourses = selectBasketCourses(); const handleSave = debounce(() => saveBasket(), 500); - return ( ZAPISZ diff --git a/src/components/SchedulerRow.tsx b/src/components/SchedulerRow.tsx index 03450a3..5d3192a 100644 --- a/src/components/SchedulerRow.tsx +++ b/src/components/SchedulerRow.tsx @@ -1,9 +1,11 @@ -import React, { Fragment, MouseEvent, useState, useEffect, useRef } from 'react'; +import React, { Fragment, MouseEvent, useState, useEffect, useRef, useContext, useMemo } from 'react'; import { GroupType, SchedulerEvent } from '../types'; import styled, { css } from 'styled-components/macro'; import Popover from '@material-ui/core/Popover'; import { makeStyles, createStyles, Theme } from '@material-ui/core/styles'; import { MONDAY_TO_FRIDAY } from '../constants'; +import { coursesContext } from '../contexts/CoursesProvider'; +import { group } from 'console'; const useStyles = makeStyles((theme: Theme) => createStyles({ @@ -46,6 +48,7 @@ interface SchedulerEventProps { cellWidth: number; cellHeight: number; groupType: GroupType; + isHovered: boolean; } const StyledSchedulerEvent = styled.div` @@ -62,15 +65,22 @@ const StyledSchedulerEvent = styled.div` margin-right: 5px; padding: 5px 5px 0 5px; text-align: center; - background-color: ${({ groupType }) => (groupType === 'CLASS' ? '#FFDC61' : '#9ed3ff')}; + background-color: ${({ groupType, isHovered }) => { + if (isHovered) { + return groupType === 'CLASS' ? '#ffefb5' : '#d4ecff'; + } else { + return groupType === 'CLASS' ? '#FFDC61' : '#9ed3ff'; + } + }}; box-shadow: 3px 3px 3px 0px rgba(0, 0, 0, 0.75); `; const threeStyles = () => { return css` - white-space: nowrap; - text-overflow: ellipsis; - max-width: 70px;`; + white-space: nowrap; + text-overflow: ellipsis; + max-width: 70px; + `; }; type BoldParagraphProps = { @@ -119,6 +129,12 @@ const getGroupsPerDay = (groups: Array) => { }; export const SchedulerRow = ({ groups, indexRow, rowTop, cellWidth, cellHeight }: SchedulerRowProps) => { + const { hoveredGroup, selectBasketNames } = useContext(coursesContext)!; + console.log('hovered group is: ', hoveredGroup); + console.log('groups: ', groups); + const basketNames = useMemo(() => selectBasketNames(), [selectBasketNames]); + console.log('basket names: ', basketNames); + console.log('groups: ', groups); const classes = useStyles(); const groupsPerDay = getGroupsPerDay(groups); const [anchorEl, setAnchorEl] = React.useState(null); @@ -152,6 +168,7 @@ export const SchedulerRow = ({ groups, indexRow, rowTop, cellWidth, cellHeight } group.day === eventIndex && ( { - console.log('i am in on focus'); handleShowDropdown(); }} /> diff --git a/src/contexts/CoursesProvider.tsx b/src/contexts/CoursesProvider.tsx index 7ed62c9..4fe013b 100644 --- a/src/contexts/CoursesProvider.tsx +++ b/src/contexts/CoursesProvider.tsx @@ -15,13 +15,17 @@ const StyledCloseIcon = styled(CloseIcon)` interface CourseContext { courses: Array; basket: Array; + hoveredGroup: Group | undefined | null; addCourseToBasket: (courses: Course) => void; - changeGroupInBasket: (group: Group, id: number) => void; + changeHoveredGroup: (group: Group | null) => void; + changeGroupInBasket: (group: Group, courseId: number) => void; + restoreGroupInBasket: (restoreGroup: Group, courseId: number) => void; deleteFromBasket: (id: number) => void; saveBasket: () => void; selectSchedulerEvents: () => Array; selectBasketNames: () => Array; selectBasketCourses: () => Array; + selectBasketCourseGroups: (courseId: number) => Array; } export const coursesContext = createContext(undefined); @@ -32,10 +36,14 @@ interface CoursesProviderProps { export const CoursesProvider = ({ children }: CoursesProviderProps) => { const { enqueueSnackbar } = useSnackbar(); const { closeSnackbar } = useSnackbar(); + //fetch courses with groups const [courses, setCourses] = useState>([]); const [basket, setBasket] = useState>([]); - + const [hoveredGroup, setHoveredGroup] = useState(null); + useEffect(() => { + console.log('actually hovered group is: ', hoveredGroup); + }, [hoveredGroup]); const selectBasketIds = () => { const classesIds = basket.map((course) => course?.classes?.id).filter((course) => course !== undefined); const lecturesIds = basket.map((course) => course?.lecture?.id).filter((course) => course !== undefined); @@ -67,6 +75,17 @@ export const CoursesProvider = ({ children }: CoursesProviderProps) => { }, [] as Array); }; + const selectBasketCourseGroups = (courseId: number) => { + const course = basket.find(({ id }) => id === courseId); + if (course !== undefined) { + return [course.lecture, course.classes]; + } else { + return [undefined, undefined]; + } + }; + + const changeHoveredGroup = (group: Group | null) => setHoveredGroup(group); + const addCourseToBasket = (course: Course) => { const courseToBasket: Basket = { name: course.name, @@ -106,8 +125,8 @@ export const CoursesProvider = ({ children }: CoursesProviderProps) => { } }; - const changeGroupInBasket = (choosenGroup: Group, id: number) => { - const basketCourse = basket.filter((course) => course.id === id)[0]; + const changeGroupInBasket = (choosenGroup: Group, courseId: number) => { + const basketCourse = basket.filter((course) => course.id === courseId)[0]; const { type } = choosenGroup; if (type === GroupType.CLASS) { setBasket( @@ -120,6 +139,20 @@ export const CoursesProvider = ({ children }: CoursesProviderProps) => { } }; + const restoreGroupInBasket = (restoreGroup: Group, courseId: number) => { + const basketCourse = basket.filter((course) => course.id === courseId)[0]; + const { type } = restoreGroup; + if (type === GroupType.CLASS) { + setBasket( + basket.map((basket) => (basket.id === basketCourse.id ? { ...basket, classes: restoreGroup } : basket)), + ); + } else if (type === GroupType.LECTURE) { + setBasket( + basket.map((basket) => (basket.id === basketCourse.id ? { ...basket, lecture: restoreGroup } : basket)), + ); + } + }; + const getNewestTimetable = async () => { try { const { data } = await axiosInstance.get( @@ -157,13 +190,17 @@ export const CoursesProvider = ({ children }: CoursesProviderProps) => { value={{ courses, basket, + hoveredGroup, addCourseToBasket, + changeHoveredGroup, changeGroupInBasket, deleteFromBasket, + restoreGroupInBasket, saveBasket, selectSchedulerEvents, selectBasketNames, selectBasketCourses, + selectBasketCourseGroups, }} > {children}