From aba572b813b1ba4f9d41928f32252d4197604cb3 Mon Sep 17 00:00:00 2001 From: NishchintDhawan Date: Sat, 4 Jun 2022 21:57:04 -0700 Subject: [PATCH] Allow custom color for courses (#361) --- src/lib/hooks/useSavedCourses.ts | 13 +++ src/pages/scheduler/components/CourseCard.tsx | 93 ++++++++++++++++--- .../scheduler/components/SchedulerSidebar.tsx | 24 ++++- 3 files changed, 114 insertions(+), 16 deletions(-) diff --git a/src/lib/hooks/useSavedCourses.ts b/src/lib/hooks/useSavedCourses.ts index 784a5049..883f76a8 100644 --- a/src/lib/hooks/useSavedCourses.ts +++ b/src/lib/hooks/useSavedCourses.ts @@ -66,6 +66,7 @@ type SavedCourses = { clearCourses: (term: string) => void; setSection: (type: string, newSection: SavedSection, existingCourse: SavedCourse) => void; contains: (pid: string, term: string) => boolean; + updateCourseColor: (pid: string, term: string, color: string) => void; sectionIsSaved: (pid: string, term: string, sectionCode: string) => boolean; setSelected: (selected: boolean, existingCourse: SavedCourse) => void; setShowSections: (showSections: boolean, existingCourse: SavedCourse) => void; @@ -100,6 +101,17 @@ export const useSavedCourses = (): SavedCourses => { [data] ); + const updateCourseColor = useCallback( + (pid: string, term: string, color: string) => { + data.map((item) => { + if (item.term == term && item.pid == pid) { + item.color = color; + } + }); + setData(data); + }, + [data] + ); /** * Checks the equality of two courses * @param a Course @@ -303,6 +315,7 @@ export const useSavedCourses = (): SavedCourses => { clearCourses, setSection, contains, + updateCourseColor, sectionIsSaved, setSelected, setShowSections, diff --git a/src/pages/scheduler/components/CourseCard.tsx b/src/pages/scheduler/components/CourseCard.tsx index ddfb6690..1328de55 100644 --- a/src/pages/scheduler/components/CourseCard.tsx +++ b/src/pages/scheduler/components/CourseCard.tsx @@ -1,7 +1,20 @@ import { useCallback } from 'react'; -import { ChevronDownIcon, ChevronUpIcon, CloseIcon } from '@chakra-ui/icons'; -import { Box, Text, Flex, VStack, Checkbox, IconButton, BackgroundProps, Skeleton } from '@chakra-ui/react'; +import { ChevronDownIcon, ChevronUpIcon, CloseIcon, CopyIcon, EditIcon } from '@chakra-ui/icons'; +import { + Box, + Text, + Flex, + VStack, + Checkbox, + IconButton, + BackgroundProps, + Skeleton, + Menu, + MenuButton, + MenuList, + MenuItem, +} from '@chakra-ui/react'; import { Link } from 'react-router-dom'; import { Term, useGetCourse } from 'lib/fetchers'; @@ -30,6 +43,19 @@ export type CourseCardProps = { selected?: boolean; }) => void; handleDelete: ({ code, pid, subject, term }: { code: string; pid: string; subject: string; term: string }) => void; + handleColorChange: ({ + code, + pid, + subject, + term, + color, + }: { + code: string; + pid: string; + subject: string; + term: string; + color: string; + }) => void; handleShowSections: ({ code, pid, @@ -43,6 +69,7 @@ export type CourseCardProps = { term: string; showSections?: boolean; }) => void; + colorList: { color: string; name: string }[]; }; export function CourseCard({ @@ -57,12 +84,21 @@ export function CourseCard({ handleSelection, handleShowSections, handleDelete, + handleColorChange, + colorList, }: CourseCardProps): JSX.Element { const mode = useDarkMode(); const onChange = useCallback(() => { handleSelection({ term, code, subject, pid, selected }); }, [code, handleSelection, pid, selected, subject, term]); + const onColorChange = useCallback( + (color: string) => { + handleColorChange({ term, code, subject, pid, color }); + }, + [code, handleDelete, pid, subject, term, color] + ); + const onShowSections = useCallback(() => { handleShowSections({ term, code, subject, pid, showSections }); }, [code, handleShowSections, pid, showSections, subject, term]); @@ -87,18 +123,47 @@ export function CourseCard({ {hasSections ? ( - - - + <> + + + + + + + } + /> + + {colorList.map((colorOption) => { + return ( + } + key={colorOption.color} + onClick={() => onColorChange(colorOption.color)} + > + {colorOption.name} + + ); + })} + + + + + ) : ( )} diff --git a/src/pages/scheduler/components/SchedulerSidebar.tsx b/src/pages/scheduler/components/SchedulerSidebar.tsx index 7ddce928..3def4ddc 100644 --- a/src/pages/scheduler/components/SchedulerSidebar.tsx +++ b/src/pages/scheduler/components/SchedulerSidebar.tsx @@ -14,14 +14,25 @@ import { CourseCard } from './CourseCard'; import { SectionsCardContainer } from './SchedulerSections'; // GREEN, RED, YELLOW, BLUE, PURPLE, ORANGE -export const COLORS = ['#32a852', '#b33127', '#e8e523', '#247fe0', '#971dcc', '#cc7d1d']; +export const COLORS: { color: string; name: string }[] = [ + { color: '#F56565', name: 'Red' }, + { color: '#48BB78', name: 'Green' }, + { color: '#4299E1', name: 'Blue' }, + { color: '#ED8936', name: 'Orange' }, + { color: '#38B2AC', name: 'Teal' }, + { color: '#9F7AEA', name: 'Purple' }, + { color: '#ECC94B', name: 'Yellow' }, + { color: '#0BC5EA', name: 'Cyan' }, + { color: '#ED64A6', name: 'Pink' }, +]; interface SchedulerSidebarProps { term: string; } export function SchedulerSidebar({ term }: SchedulerSidebarProps): JSX.Element { - const { deleteCourse, setSection, setShowSections, courses, setSelected, clearCourses } = useSavedCourses(); + const { deleteCourse, setSection, setShowSections, updateCourseColor, courses, setSelected, clearCourses } = + useSavedCourses(); const coursesResult = useGetCourseSections(term, courses); const handleCourseSectionChange = useCallback( @@ -63,6 +74,13 @@ export function SchedulerSidebar({ term }: SchedulerSidebarProps): JSX.Element { [deleteCourse] ); + const handleColorChange = useCallback( + ({ pid, term, color }: { pid: string; term: string; color: string }) => { + updateCourseColor(pid, term, color); + }, + [updateCourseColor] + ); + const handleCourseToggle = useCallback( ({ code, @@ -139,6 +157,8 @@ export function SchedulerSidebar({ term }: SchedulerSidebarProps): JSX.Element { handleSelection={handleCourseToggle} handleDelete={handleCourseDelete} handleShowSections={handleShowSections} + handleColorChange={handleColorChange} + colorList={COLORS} />