added highlighting of hovered group and updated styles

This commit is contained in:
Maciek Głowacki 2020-11-26 03:09:58 +01:00
parent 3f0aaf42ca
commit e7e8c6efdd
5 changed files with 97 additions and 19 deletions

View File

@ -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 Collapse from '@material-ui/core/Collapse';
import { ReactComponent as Expand } from '../assets/expand.svg'; import { ReactComponent as Expand } from '../assets/expand.svg';
import { Course, Group, GroupType } from '../types/index'; 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 { makeStyles } from '@material-ui/core/styles';
import { ReactComponent as Bin } from '../assets/bin.svg'; import { ReactComponent as Bin } from '../assets/bin.svg';
import DeleteIcon from '@material-ui/icons/Delete'; import DeleteIcon from '@material-ui/icons/Delete';
import { useMemo } from 'react';
const CourseCardWrapper = styled.div` const CourseCardWrapper = styled.div`
position: relative; position: relative;
@ -134,13 +135,19 @@ interface CourseCardProps {
export const CourseCard = ({ course }: CourseCardProps) => { export const CourseCard = ({ course }: CourseCardProps) => {
const classes = useStyles(); const classes = useStyles();
const { changeGroupInBasket, deleteFromBasket } = useContext(coursesContext)!; const {
hoveredGroup,
changeGroupInBasket,
deleteFromBasket,
selectBasketCourseGroups,
changeHoveredGroup,
} = useContext(coursesContext)!;
const [isSelected, setSelected] = useState(false); const [isSelected, setSelected] = useState(false);
const groups = [...course.lectures!, ...course.classes!]; const groups = [...course.lectures!, ...course.classes!];
const [courseLecture, courseClasses] = selectBasketCourseGroups(course.id);
const onGroupClick = (group: Group, id: number) => changeGroupInBasket(group, id); // console.log('lecture is: ', courseLecture);
// console.log('class is: ', courseClasses);
const onGroupClick = (group: Group, courseId: number) => changeGroupInBasket(group, courseId);
return ( return (
<CourseCardWrapper> <CourseCardWrapper>
@ -156,8 +163,27 @@ export const CourseCard = ({ course }: CourseCardProps) => {
<ExpandIcon onClick={() => setSelected(!isSelected)} selected={isSelected} /> <ExpandIcon onClick={() => setSelected(!isSelected)} selected={isSelected} />
</TitleWrapper> </TitleWrapper>
<Collapse className={classes.expanded} in={isSelected} timeout="auto" unmountOnExit> <Collapse className={classes.expanded} in={isSelected} timeout="auto" unmountOnExit>
{groups.map((group, index) => ( {groups.map((group: Group, index) => (
<ClassGroupStyled key={index} onClick={() => onGroupClick(group, course.id)}> <ClassGroupStyled
key={index}
onClick={() => 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);
}
}}
>
<StyledGroupType groupType={group.type}>{group.type === 'CLASS' ? 'ĆW' : 'WYK'}</StyledGroupType> <StyledGroupType groupType={group.type}>{group.type === 'CLASS' ? 'ĆW' : 'WYK'}</StyledGroupType>
<FlexboxWrapper> <FlexboxWrapper>
{group.lecturer.replace('UAM', '').length >= 32 ? ( {group.lecturer.replace('UAM', '').length >= 32 ? (

View File

@ -52,7 +52,6 @@ export const Rightbar = () => {
const basketCourses = selectBasketCourses(); const basketCourses = selectBasketCourses();
const handleSave = debounce(() => saveBasket(), 500); const handleSave = debounce(() => saveBasket(), 500);
return ( return (
<RightbarWrapper> <RightbarWrapper>
<SaveButton onClick={handleSave}>ZAPISZ</SaveButton> <SaveButton onClick={handleSave}>ZAPISZ</SaveButton>

View File

@ -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 { GroupType, SchedulerEvent } from '../types';
import styled, { css } from 'styled-components/macro'; import styled, { css } from 'styled-components/macro';
import Popover from '@material-ui/core/Popover'; import Popover from '@material-ui/core/Popover';
import { makeStyles, createStyles, Theme } from '@material-ui/core/styles'; import { makeStyles, createStyles, Theme } from '@material-ui/core/styles';
import { MONDAY_TO_FRIDAY } from '../constants'; import { MONDAY_TO_FRIDAY } from '../constants';
import { coursesContext } from '../contexts/CoursesProvider';
import { group } from 'console';
const useStyles = makeStyles((theme: Theme) => const useStyles = makeStyles((theme: Theme) =>
createStyles({ createStyles({
@ -46,6 +48,7 @@ interface SchedulerEventProps {
cellWidth: number; cellWidth: number;
cellHeight: number; cellHeight: number;
groupType: GroupType; groupType: GroupType;
isHovered: boolean;
} }
const StyledSchedulerEvent = styled.div<SchedulerEventProps>` const StyledSchedulerEvent = styled.div<SchedulerEventProps>`
@ -62,15 +65,22 @@ const StyledSchedulerEvent = styled.div<SchedulerEventProps>`
margin-right: 5px; margin-right: 5px;
padding: 5px 5px 0 5px; padding: 5px 5px 0 5px;
text-align: center; 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); box-shadow: 3px 3px 3px 0px rgba(0, 0, 0, 0.75);
`; `;
const threeStyles = () => { const threeStyles = () => {
return css` return css`
white-space: nowrap; white-space: nowrap;
text-overflow: ellipsis; text-overflow: ellipsis;
max-width: 70px;`; max-width: 70px;
`;
}; };
type BoldParagraphProps = { type BoldParagraphProps = {
@ -119,6 +129,12 @@ const getGroupsPerDay = (groups: Array<SchedulerEvent>) => {
}; };
export const SchedulerRow = ({ groups, indexRow, rowTop, cellWidth, cellHeight }: SchedulerRowProps) => { 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 classes = useStyles();
const groupsPerDay = getGroupsPerDay(groups); const groupsPerDay = getGroupsPerDay(groups);
const [anchorEl, setAnchorEl] = React.useState<HTMLDivElement | null>(null); const [anchorEl, setAnchorEl] = React.useState<HTMLDivElement | null>(null);
@ -152,6 +168,7 @@ export const SchedulerRow = ({ groups, indexRow, rowTop, cellWidth, cellHeight }
group.day === eventIndex && ( group.day === eventIndex && (
<Fragment key={index}> <Fragment key={index}>
<StyledSchedulerEvent <StyledSchedulerEvent
isHovered={group.id === hoveredGroup?.id}
groupType={group.type} groupType={group.type}
cellWidth={cellWidth} cellWidth={cellWidth}
cellHeight={cellHeight} cellHeight={cellHeight}

View File

@ -180,7 +180,6 @@ export default function ({ handleTransfer }: TopbarProps) {
onChange={handleChange} onChange={handleChange}
value={input} value={input}
onFocus={() => { onFocus={() => {
console.log('i am in on focus');
handleShowDropdown(); handleShowDropdown();
}} }}
/> />

View File

@ -15,13 +15,17 @@ const StyledCloseIcon = styled(CloseIcon)`
interface CourseContext { interface CourseContext {
courses: Array<Course>; courses: Array<Course>;
basket: Array<Basket>; basket: Array<Basket>;
hoveredGroup: Group | undefined | null;
addCourseToBasket: (courses: Course) => void; 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; deleteFromBasket: (id: number) => void;
saveBasket: () => void; saveBasket: () => void;
selectSchedulerEvents: () => Array<SchedulerEvent>; selectSchedulerEvents: () => Array<SchedulerEvent>;
selectBasketNames: () => Array<string>; selectBasketNames: () => Array<string>;
selectBasketCourses: () => Array<Course>; selectBasketCourses: () => Array<Course>;
selectBasketCourseGroups: (courseId: number) => Array<Group | undefined>;
} }
export const coursesContext = createContext<CourseContext | undefined>(undefined); export const coursesContext = createContext<CourseContext | undefined>(undefined);
@ -32,10 +36,14 @@ interface CoursesProviderProps {
export const CoursesProvider = ({ children }: CoursesProviderProps) => { export const CoursesProvider = ({ children }: CoursesProviderProps) => {
const { enqueueSnackbar } = useSnackbar(); const { enqueueSnackbar } = useSnackbar();
const { closeSnackbar } = useSnackbar(); const { closeSnackbar } = useSnackbar();
//fetch courses with groups //fetch courses with groups
const [courses, setCourses] = useState<Array<Course>>([]); const [courses, setCourses] = useState<Array<Course>>([]);
const [basket, setBasket] = useState<Array<Basket>>([]); const [basket, setBasket] = useState<Array<Basket>>([]);
const [hoveredGroup, setHoveredGroup] = useState<Group | undefined | null>(null);
useEffect(() => {
console.log('actually hovered group is: ', hoveredGroup);
}, [hoveredGroup]);
const selectBasketIds = () => { const selectBasketIds = () => {
const classesIds = basket.map((course) => course?.classes?.id).filter((course) => course !== undefined); const classesIds = basket.map((course) => course?.classes?.id).filter((course) => course !== undefined);
const lecturesIds = basket.map((course) => course?.lecture?.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<SchedulerEvent>); }, [] as Array<SchedulerEvent>);
}; };
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 addCourseToBasket = (course: Course) => {
const courseToBasket: Basket = { const courseToBasket: Basket = {
name: course.name, name: course.name,
@ -106,8 +125,8 @@ export const CoursesProvider = ({ children }: CoursesProviderProps) => {
} }
}; };
const changeGroupInBasket = (choosenGroup: Group, id: number) => { const changeGroupInBasket = (choosenGroup: Group, courseId: number) => {
const basketCourse = basket.filter((course) => course.id === id)[0]; const basketCourse = basket.filter((course) => course.id === courseId)[0];
const { type } = choosenGroup; const { type } = choosenGroup;
if (type === GroupType.CLASS) { if (type === GroupType.CLASS) {
setBasket( 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 () => { const getNewestTimetable = async () => {
try { try {
const { data } = await axiosInstance.get( const { data } = await axiosInstance.get(
@ -157,13 +190,17 @@ export const CoursesProvider = ({ children }: CoursesProviderProps) => {
value={{ value={{
courses, courses,
basket, basket,
hoveredGroup,
addCourseToBasket, addCourseToBasket,
changeHoveredGroup,
changeGroupInBasket, changeGroupInBasket,
deleteFromBasket, deleteFromBasket,
restoreGroupInBasket,
saveBasket, saveBasket,
selectSchedulerEvents, selectSchedulerEvents,
selectBasketNames, selectBasketNames,
selectBasketCourses, selectBasketCourses,
selectBasketCourseGroups,
}} }}
> >
{children} {children}