From 522cae2d3f119f7acc6b5c4e299e9dc9f8c10029 Mon Sep 17 00:00:00 2001 From: Suphon Thanakornpakapong Date: Thu, 4 Nov 2021 12:20:22 +0700 Subject: [PATCH 1/8] Fix schedule for classes after 7pm --- .../Schedule/components/Gutters.tsx | 3 +- .../components/Schedule/components/Header.tsx | 4 +- .../Schedule/components/Schedule/constants.ts | 3 -- .../components/Schedule/dimensions.tsx | 39 +++++++++++++++---- .../Schedule/components/Schedule/index.tsx | 7 ++-- .../Schedule/components/Schedule/utils.ts | 9 +++++ src/modules/Schedule/index.tsx | 11 +++++- 7 files changed, 56 insertions(+), 20 deletions(-) diff --git a/src/modules/Schedule/components/Schedule/components/Gutters.tsx b/src/modules/Schedule/components/Schedule/components/Gutters.tsx index b0536e786..8c1043053 100644 --- a/src/modules/Schedule/components/Schedule/components/Gutters.tsx +++ b/src/modules/Schedule/components/Schedule/components/Gutters.tsx @@ -1,6 +1,5 @@ import { styledWithTheme } from '@/common/utils/styledWithTheme' -import { colsCount } from '../constants' import { useDimensions } from '../dimensions' interface GutterProps { @@ -22,7 +21,7 @@ function Gutter({ x, y }: GutterProps) { } export function Gutters() { - const { daysCount } = useDimensions() + const { daysCount, colsCount } = useDimensions() const gutters = [] for (let x = 0; x <= colsCount; x++) { gutters.push() diff --git a/src/modules/Schedule/components/Schedule/components/Header.tsx b/src/modules/Schedule/components/Schedule/components/Header.tsx index 8c87514b4..c49865699 100644 --- a/src/modules/Schedule/components/Schedule/components/Header.tsx +++ b/src/modules/Schedule/components/Schedule/components/Header.tsx @@ -4,7 +4,7 @@ import { useTranslation } from 'react-i18next' import { dayOfWeekArray } from '@/common/constants/dayOfWeek' -import { hourEnd, hourStart } from '../constants' +import { hourStart } from '../constants' import { useDimensions } from '../dimensions' import { Cell } from './Cell' import { ScheduleTypography } from './ScheduleTypography' @@ -23,7 +23,7 @@ function HourCell({ hour }: { hour: number }) { export function Header() { const { t } = useTranslation('schedule') - const { stubCellWidth, daysCount } = useDimensions() + const { stubCellWidth, daysCount, hourStart, hourEnd } = useDimensions() const fontSize = (16 * stubCellWidth) / 77 const hourCells = [] for (let hour = hourStart + 1; hour <= hourEnd; hour++) { diff --git a/src/modules/Schedule/components/Schedule/constants.ts b/src/modules/Schedule/components/Schedule/constants.ts index 2e2d70db5..9941cf502 100644 --- a/src/modules/Schedule/components/Schedule/constants.ts +++ b/src/modules/Schedule/components/Schedule/constants.ts @@ -1,10 +1,7 @@ import { DayOfWeek } from '@thinc-org/chula-courses' export const hourStart = 7 -export const hourEnd = 18 export const days: DayOfWeek[] = ['MO', 'TU', 'WE', 'TH', 'FR'] -export const colsCount = hourEnd - hourStart + 2 - export const strokeSize = 1 diff --git a/src/modules/Schedule/components/Schedule/dimensions.tsx b/src/modules/Schedule/components/Schedule/dimensions.tsx index 08e120f6f..5b0b9b9f2 100644 --- a/src/modules/Schedule/components/Schedule/dimensions.tsx +++ b/src/modules/Schedule/components/Schedule/dimensions.tsx @@ -1,6 +1,6 @@ import { createContext, PropsWithChildren, useContext, useMemo } from 'react' -import { colsCount } from './constants' +import { hourStart } from './constants' interface CellPosition { top: number @@ -16,6 +16,9 @@ interface Dimensions { width: number height: number daysCount: number + colsCount: number + hourStart: number + hourEnd: number cellWidth: number cellHeight: number stubCellWidth: number @@ -24,18 +27,24 @@ interface Dimensions { getCell: (y: number, x: number) => CellStyles } -export function getHeightRatio(daysCount: number) { - return (6 / 7 / colsCount) * (daysCount + 0.7) +export function getColsCount(hourEnd: number) { + return hourEnd - hourStart + 2 } -function getDimensions(width: number, daysCount: number): Dimensions { +export function getHeightRatio(daysCount: number, hourEnd: number) { + return (6 / 7 / getColsCount(hourEnd)) * (daysCount + 0.7) +} + +function getDimensions(width: number, daysCount: number, hourEnd: number): Dimensions { + const colsCount = getColsCount(hourEnd) + const availableWidth = width const cellWidth = Math.ceil(availableWidth / colsCount) const stubCellWidth = availableWidth - cellWidth * (colsCount - 1) const cellHeight = Math.ceil((cellWidth * 6) / 7) - const height = availableWidth * getHeightRatio(daysCount) + const height = availableWidth * getHeightRatio(daysCount, hourEnd) const headerCellHeight = height - daysCount * cellHeight function getPosition(y: number, x: number): CellPosition { @@ -60,7 +69,20 @@ function getDimensions(width: number, daysCount: number): Dimensions { } } - return { width, height, daysCount, cellWidth, cellHeight, stubCellWidth, headerCellHeight, getPosition, getCell } + return { + width, + height, + daysCount, + colsCount, + hourStart, + hourEnd, + cellWidth, + cellHeight, + stubCellWidth, + headerCellHeight, + getPosition, + getCell, + } } const DimensionsContext = createContext({} as Dimensions) @@ -72,9 +94,10 @@ export function useDimensions() { type DimensionsProviderProps = PropsWithChildren<{ width: number daysCount: number + hourEnd: number }> -export function DimensionsProvider({ width, daysCount, children }: DimensionsProviderProps) { - const dimensions = useMemo(() => getDimensions(width, daysCount), [width, daysCount]) +export function DimensionsProvider({ width, daysCount, hourEnd, children }: DimensionsProviderProps) { + const dimensions = useMemo(() => getDimensions(width, daysCount, hourEnd), [width, daysCount, hourEnd]) return {children} } diff --git a/src/modules/Schedule/components/Schedule/index.tsx b/src/modules/Schedule/components/Schedule/index.tsx index d994eccd4..92b276d80 100644 --- a/src/modules/Schedule/components/Schedule/index.tsx +++ b/src/modules/Schedule/components/Schedule/index.tsx @@ -47,15 +47,16 @@ const ScheduleContainer = styled.div` export interface AutoScaleScheduleProps extends ScheduleProps { daysCount: number + hourEnd: number } const AutoScaleSchedule = withContentRect('bounds')( - ({ measureRef, contentRect, daysCount, ...props }) => ( + ({ measureRef, contentRect, daysCount, hourEnd, ...props }) => ( <>
- + {contentRect.bounds?.width ? ( - + ) : null} diff --git a/src/modules/Schedule/components/Schedule/utils.ts b/src/modules/Schedule/components/Schedule/utils.ts index 4bf9a0c9f..2627688fa 100644 --- a/src/modules/Schedule/components/Schedule/utils.ts +++ b/src/modules/Schedule/components/Schedule/utils.ts @@ -124,6 +124,15 @@ export function useDaysCount(classes: ScheduleClass[]): number { return daysCount } +export function useHourEnd(classes: ScheduleClass[]): number { + let rightmostPosition = 0 + for (const cls of classes) { + rightmostPosition = Math.max(rightmostPosition, cls.position.end) + } + const coursesHourEnd = Math.ceil(rightmostPosition + hourStart) - 2 + return Math.max(coursesHourEnd, 18) +} + export type CourseOverlap = { hasOverlap: boolean classes: string[] diff --git a/src/modules/Schedule/index.tsx b/src/modules/Schedule/index.tsx index 7b5311fd8..68c9c8822 100644 --- a/src/modules/Schedule/index.tsx +++ b/src/modules/Schedule/index.tsx @@ -14,7 +14,13 @@ import { ExamSchedule } from './components/ExamSchedule' import { useExamClasses } from './components/ExamSchedule/utils' import { SaveImgButton } from './components/SaveImgButton' import { Schedule } from './components/Schedule' -import { useDaysCount, useOverlappingCourses, useScheduleClass, useTimetableClasses } from './components/Schedule/utils' +import { + useDaysCount, + useHourEnd, + useOverlappingCourses, + useScheduleClass, + useTimetableClasses, +} from './components/Schedule/utils' import { ScheduleTable } from './components/ScheduleTable' import { InfoBar, @@ -36,6 +42,7 @@ export const SchedulePage = observer(() => { const classes = useTimetableClasses(shopItems) const scheduleClasses = useScheduleClass(classes) const daysCount = useDaysCount(scheduleClasses) + const hourEnd = useHourEnd(scheduleClasses) const { midtermClasses, finalClasses } = useExamClasses(shopItems) const overlappingCourses = useOverlappingCourses(scheduleClasses, midtermClasses, finalClasses) @@ -80,7 +87,7 @@ export const SchedulePage = observer(() => {
- +
From 8261ff9fa84b9722e875948d6031f8005038de16 Mon Sep 17 00:00:00 2001 From: Suphon Thanakornpakapong Date: Thu, 4 Nov 2021 12:26:10 +0700 Subject: [PATCH 2/8] Fix build --- src/modules/Schedule/components/Schedule/index.stories.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modules/Schedule/components/Schedule/index.stories.tsx b/src/modules/Schedule/components/Schedule/index.stories.tsx index 317b05d03..cd22cbec8 100644 --- a/src/modules/Schedule/components/Schedule/index.stories.tsx +++ b/src/modules/Schedule/components/Schedule/index.stories.tsx @@ -12,5 +12,5 @@ export default { export const ScheduleStory = () => { const scheduleClasses = useScheduleClass(mockClasses) - return + return } From 839fe8d1aa3412faa1009ca0cbeb9e90f9981a49 Mon Sep 17 00:00:00 2001 From: Nattamon Polv Date: Thu, 4 Nov 2021 17:15:06 +0700 Subject: [PATCH 3/8] fix: about page (#247) * fix: add about link to mobile navbar * fix: article readability * update: about page info * fix: max width of text * fix: max width of privacy policy * fix: build error due to file structure * fix: remove unused imports --- .../TopBar/components/MobileNavBar/index.tsx | 12 +- src/configs/theme/articletext.ts | 7 + src/pages/about/index.tsx | 332 +++++++++--------- src/pages/privacy/index.tsx | 277 ++++++++------- 4 files changed, 326 insertions(+), 302 deletions(-) create mode 100644 src/configs/theme/articletext.ts diff --git a/src/common/components/TopBar/components/MobileNavBar/index.tsx b/src/common/components/TopBar/components/MobileNavBar/index.tsx index 23b1e5226..f436290d8 100644 --- a/src/common/components/TopBar/components/MobileNavBar/index.tsx +++ b/src/common/components/TopBar/components/MobileNavBar/index.tsx @@ -9,7 +9,12 @@ import { MdMenu } from 'react-icons/md' import logo from '@/assets/images/cgrLogoDark.svg' import { Analytics } from '@/common/context/Analytics/components/Analytics' import { LinkWithAnalytics } from '@/common/context/Analytics/components/LinkWithAnalytics' -import { REPORT_PROBLEM, NAVBAR_SEARCH_COURSE, NAVBAR_TIMETABLE } from '@/common/context/Analytics/constants' +import { + REPORT_PROBLEM, + NAVBAR_SEARCH_COURSE, + NAVBAR_TIMETABLE, + NAVBAR_ABOUT, +} from '@/common/context/Analytics/constants' import { useDisclosure } from '@/common/hooks/useDisclosure' import { useLinkBuilder } from '@/common/hooks/useLinkBuilder' import { sessionIdStore } from '@/store/sessionIdStore' @@ -49,6 +54,11 @@ export const MobileNavBar = observer(() => { {t('navBar:timetable')}
+
+ + {t('navBar:about')} + +
diff --git a/src/configs/theme/articletext.ts b/src/configs/theme/articletext.ts new file mode 100644 index 000000000..68ac632e9 --- /dev/null +++ b/src/configs/theme/articletext.ts @@ -0,0 +1,7 @@ +import styled from '@emotion/styled' +import { Typography } from '@material-ui/core' + +export const StyledArticleBody = styled(Typography)` + font-size: 18px; + line-height: 32px; +` diff --git a/src/pages/about/index.tsx b/src/pages/about/index.tsx index 3f4a791a4..092a853d8 100644 --- a/src/pages/about/index.tsx +++ b/src/pages/about/index.tsx @@ -1,10 +1,9 @@ -import { Box, Paper, Card, Typography, Link, useTheme } from '@material-ui/core' +import { Box, Card, Typography, Link, useTheme } from '@material-ui/core' import React from 'react' +import { StyledArticleBody } from '@/configs/theme/articletext' import { sessionIdStore } from '@/store/sessionIdStore' -// TODO : Change a tag to MUI Link on both policy and about pages - export default function About() { const theme = useTheme() @@ -13,172 +12,181 @@ export default function About() { return ( - - - เกี่ยวกับเรา - - ชมรม Thinc. จุฬาลงกรณ์มหาวิทยาลัย - - - ชมรม Thinc. เป็นชมรมที่จัดตั้งและดำเนินการโดยนิสิต โดยสังกัดกรรมการนิสิตคณะวิศวกรรมศาสตร์ (กวศ.) - มีวัตถุประสงค์เพื่อฝึกฝนและฟูมฟักผู้มีความสนใจในการออกแบบและพัฒนาซอฟต์แวร์ - ผ่านการทำโปรเจคพัฒนาซอฟต์แวร์เพื่อสังคมจุฬาฯ - - - ผลงานที่ผ่านมาของชมรม Thinc. เช่น -
    -
  • แอปพลิเคชัน CU Pop Bus
  • -
  • ระบบจองสนามกีฬา CU Sport Complex (เปิดใช้งานเร็ว ๆ นี้)
  • -
  • ระบบลงทะเบียนขึ้นสแตนด์แปรอักษรฝั่งจุฬาฯ งานฟุตบอลประเพณีจุฬาฯ-ธรรมศาสตร์ ครั้งที่ 74
  • -
  • Companion App ในงาน JavaScript Bangkok 1.0.0
  • -
-
- - สามารถติดตามชมรม Thinc. ได้ทาง{' '} - - Facebook Page: Thinc. - - + + เกี่ยวกับเรา + + ชมรม Thinc. จุฬาลงกรณ์มหาวิทยาลัย + + + ชมรม Thinc. เป็นชมรมที่จัดตั้งและดำเนินการโดยนิสิต โดยสังกัดกรรมการนิสิตคณะวิศวกรรมศาสตร์ (กวศ.) + มีวัตถุประสงค์เพื่อฝึกฝนและฟูมฟักผู้มีความสนใจในการออกแบบและพัฒนาซอฟต์แวร์ + ผ่านการทำโปรเจคพัฒนาซอฟต์แวร์เพื่อสังคมจุฬาฯ + + + ผลงานที่ผ่านมาของชมรม Thinc. เช่น +
    +
  • แอปพลิเคชัน CU Pop Bus
  • +
  • ระบบจองสนามกีฬา CU Sport Complex (เปิดใช้งานเร็ว ๆ นี้)
  • +
  • ระบบลงทะเบียนขึ้นสแตนด์แปรอักษรฝั่งจุฬาฯ งานฟุตบอลประเพณีจุฬาฯ-ธรรมศาสตร์ ครั้งที่ 74
  • +
  • Companion App ในงาน JavaScript Bangkok 1.0.0
  • +
+
+ + สามารถติดตามชมรม Thinc. ได้ทาง{' '} + + Facebook Page: Thinc. + + - - เกี่ยวกับ CU Get Reg - + + เกี่ยวกับ CU Get Reg + - - ที่มาของโปรเจค - - - CU Get Reg เกิดมาจาก Pain Point ในการลงทะเบียนเรียนของนิสิตจุฬาฯ ที่มักจะต้องลงทะเบียนทั้งวิชาบังคับ - วิชาเลือก และวิชาศึกษาทั่วไป (GenEd) ในแต่ละเทอม แต่จำเป็นต้องหาข้อมูลจากหลาย ๆ แหล่งที่แตกต่างกัน - ทั้งยังไม่มีแหล่งใดที่นำเสนอตารางเรียนออกมาเป็นภาพให้เข้าใจง่ายตั้งแต่ก่อนลงทะเบียน - - - ด้วยเหตุนี้ ทางทีมงานจึงได้พัฒนา CU Get Reg ขึ้น เพื่อให้สามารถค้นหาและเลือกรายวิชาได้อย่างสะดวก - และจัดตารางเรียนตามข้อจำกัดของหลักสูตรของแต่ละคนได้ง่ายขึ้น - - - ทางทีมงานมีความมุ่งมั่นที่จะทำให้ CU Get Reg เป็นเว็บไซต์ศูนย์กลางที่รวบรวมข้อมูลรายวิชาไว้ได้อย่างครบถ้วน - และมุ่งที่จะสร้างเว็บไวต์นี้ให้เป็นพื้นที่สำหรับการแบ่งปันข้อมูลรายวิชาระหว่างนิสิตในอนาคต - + + ที่มาของโปรเจค + + + CU Get Reg เกิดมาจาก Pain Point ในการลงทะเบียนเรียนของนิสิตจุฬาฯ ที่มักจะต้องลงทะเบียนทั้งวิชาบังคับ วิชาเลือก + และวิชาศึกษาทั่วไป (GenEd) ในแต่ละเทอม แต่จำเป็นต้องหาข้อมูลจากหลาย ๆ แหล่งที่แตกต่างกัน + ทั้งยังไม่มีแหล่งใดที่นำเสนอตารางเรียนออกมาเป็นภาพให้เข้าใจง่ายตั้งแต่ก่อนลงทะเบียน + + + ด้วยเหตุนี้ ทางทีมงานจึงได้พัฒนา CU Get Reg ขึ้น เพื่อให้สามารถค้นหาและเลือกรายวิชาได้อย่างสะดวก + และจัดตารางเรียนตามข้อจำกัดของหลักสูตรของแต่ละคนได้ง่ายขึ้น + + + ทางทีมงานมีความมุ่งมั่นที่จะทำให้ CU Get Reg เป็นเว็บไซต์ศูนย์กลางที่รวบรวมข้อมูลรายวิชาไว้ได้อย่างครบถ้วน + และมุ่งที่จะสร้างเว็บไวต์นี้ให้เป็นพื้นที่สำหรับการแบ่งปันข้อมูลรายวิชาระหว่างนิสิตในอนาคต + - - - ทั้งนี้ CU Get Reg เป็นเพียงเครื่องมือที่ช่วยให้การวางแผนลงทะเบียนเรียนง่ายขึ้น{' '} - - แต่ไม่ใช่การลงทะเบียนเรียนจริง คุณสามารถลงทะเบียนเรียนได้ที่{' '} - - https://www2.reg.chula.ac.th/ - {' '} - เพียงช่องทางเดียวเท่านั้น - - - + + + ทั้งนี้ CU Get Reg เป็นเพียงเครื่องมือที่ช่วยให้การวางแผนลงทะเบียนเรียนง่ายขึ้น{' '} + + แต่ไม่ใช่การลงทะเบียนเรียนจริง คุณสามารถลงทะเบียนเรียนได้ที่{' '} + + https://www2.reg.chula.ac.th/ + {' '} + เพียงช่องทางเดียวเท่านั้น + + + - - CU Get Reg นำข้อมูลมาจากไหน? - - - ข้อมูลรายวิชาของ CU Get Reg นำมาจากหน้า{' '} - - สอบถามตารางสอนตารางสอบ - {' '} - ของสำนักงานการทะเบียนทั้งหมด ในปัจจุบัน ข้อมูลจากหน้านี้อาจล่าช้าจากข้อมูลภายในระบบ Reg Chula ไป 1 วัน - ทั้งนี้ ทีมงานกำลังประสานงานกับสำนักงานการทะเบียนเพื่อเข้าถึงข้อมูลรายวิชาโดยตรง เพื่อให้ไม่พบปัญหาดังกล่าว - + + CU Get Reg นำข้อมูลมาจากไหน? + + + ข้อมูลรายวิชาของ CU Get Reg นำมาจากหน้า{' '} + + สอบถามตารางสอนตารางสอบ + {' '} + ของสำนักงานการทะเบียนทั้งหมด ในปัจจุบัน ข้อมูลจากหน้านี้อาจล่าช้าจากข้อมูลภายในระบบ Reg Chula ไป 1 วัน ทั้งนี้ + ทีมงานกำลังประสานงานกับสำนักงานการทะเบียนเพื่อเข้าถึงข้อมูลรายวิชาโดยตรง เพื่อให้ไม่พบปัญหาดังกล่าว + - - การเข้าสู่ระบบ มีประโยชน์อย่างไรบ้าง? - - - เมื่อคุณเข้าสู่ระบบ ระบบจะบันทึกข้อมูลตารางเรียนไว้ในบัญชี Google ของคุณ - ทำให้สามารถเข้าสู่ระบบเพื่อดูข้อมูลตารางเรียนที่เลือกไว้ข้ามอุปกรณ์ได้ ทั้งนี้ ในอนาคตอาจมีฟีเจอร์อื่น ๆ - ที่เกี่ยวข้องกับการเข้าสู่ระบบเพิ่มขึ้น - - - ในการเข้าสู่ระบบ สามารถใช้บัญชีอีเมลนิสิต (รหัสนิสิต@student.chula.ac.th) เท่านั้น - เพื่อให้สามารถยืนยันตัวตนได้ว่าเป็นนิสิตจุฬาฯ - - - หากต้องการทราบว่าเราเก็บข้อมูลใดและนำไปใช้อย่างไรบ้าง สามารถอ่านเพิ่มเติมได้ที่{' '} - - Privacy Policy - {' '} - ของเรา - + + การเข้าสู่ระบบ มีประโยชน์อย่างไรบ้าง? + + + เมื่อคุณเข้าสู่ระบบ ระบบจะบันทึกข้อมูลตารางเรียนไว้ในบัญชี Google ของคุณ + ทำให้สามารถเข้าสู่ระบบเพื่อดูข้อมูลตารางเรียนที่เลือกไว้ข้ามอุปกรณ์ได้ ทั้งนี้ ในอนาคตอาจมีฟีเจอร์อื่น ๆ + ที่เกี่ยวข้องกับการเข้าสู่ระบบเพิ่มขึ้น + + + ในการเข้าสู่ระบบ สามารถใช้บัญชีอีเมลนิสิต (รหัสนิสิต@student.chula.ac.th) เท่านั้น + เพื่อให้สามารถยืนยันตัวตนได้ว่าเป็นนิสิตจุฬาฯ + + + หากต้องการทราบว่าเราเก็บข้อมูลใดและนำไปใช้อย่างไรบ้าง สามารถอ่านเพิ่มเติมได้ที่{' '} + + Privacy Policy + {' '} + ของเรา + - - ความร่วมมือกับหน่วยงานอื่น ๆ - - - CU Get Reg มีความร่วมมือกับหน่วยงานอื่นภายในจุฬาฯ ได้แก่ -
    -
  • - สำนักงานการทะเบียน (Reg Chula): CU Get Reg - ได้รับการสนับสนุนเซิร์ฟเวอร์จากสำนักงานการทะเบียน นอกจากนี้ - ทางสำนักงานการทะเบียนยังพร้อมให้ความสนับสนุนในด้านข้อมูลรายวิชา ซึ่งกำลังอยู่ในระหว่างดำเนินการ{' '} - - (เว็บไซต์ สำนักงานการทะเบียน) - -
  • -
  • - Gen อย่าได้ Ed: ปัจจุบันร่วมมือกับ CU Get Reg - ในการประชาสัมพันธ์เว็บไซต์ให้กับนิสิตจุฬาฯ{' '} - - (Facebook Page: Gen อย่าได้ Ed) - -
  • -
-
+ + ความร่วมมือกับหน่วยงานอื่น ๆ + + + CU Get Reg มีความร่วมมือกับหน่วยงานอื่นภายในจุฬาฯ ได้แก่ +
    +
  • + สำนักงานการทะเบียน (Reg Chula): CU Get Reg + ได้รับการสนับสนุนเซิร์ฟเวอร์จากสำนักงานการทะเบียน นอกจากนี้ + ทางสำนักงานการทะเบียนยังพร้อมให้ความสนับสนุนในด้านข้อมูลรายวิชา ซึ่งกำลังอยู่ในระหว่างดำเนินการ{' '} + + (เว็บไซต์ สำนักงานการทะเบียน) + +
  • +
  • + Gen อย่าได้ Ed: ปัจจุบันร่วมมือกับ CU Get Reg ในการประชาสัมพันธ์เว็บไซต์ให้กับนิสิตจุฬาฯ{' '} + + (Facebook Page: Gen อย่าได้ Ed) + +
  • +
  • + ศูนย์การศึกษาทั่วไป (GenEd Chula): CU Get Reg + ได้รับการสนับสนุนจากศูนย์การศึกษาทั่วไปในด้านข้อมูลรายวิชาศึกษาทั่วไป (GenEd){' '} + + (เว็บไซต์ ศูนย์การศึกษาทั่วไป) + +
  • +
+
- - ติดต่อทีมงาน - - - สามารถแจ้งปัญหาขัดข้องเกี่ยวกับการใช้งานเว็บไซต์ ข้อมูลที่ไม่ถูกต้อง หรือข้อเสนอแนะต่าง ๆ ได้ทาง{' '} - - ฟอร์มแจ้งปัญหา - {' '} - ที่มุมบนขวาของหน้าเว็บ - - - หากต้องการติดต่อสอบถามเกี่ยวกับเว็บไซต์ CU Get Reg หรือติดต่อชมรม Thinc. สามารถสอบถามทาง{' '} - - Facebook Page: Thinc. - {' '} - ได้โดยตรง - -
-
+ + ติดต่อทีมงาน + + + สามารถแจ้งปัญหาขัดข้องเกี่ยวกับการใช้งานเว็บไซต์ ข้อมูลที่ไม่ถูกต้อง หรือข้อเสนอแนะต่าง ๆ ได้ทาง{' '} + + ฟอร์มแจ้งปัญหา + {' '} + ที่มุมบนขวาของหน้าเว็บ + + + หากต้องการติดต่อสอบถามเกี่ยวกับเว็บไซต์ CU Get Reg หรือติดต่อชมรม Thinc. สามารถสอบถามทาง{' '} + + Facebook Page: Thinc. + {' '} + ได้โดยตรง + +
) } diff --git a/src/pages/privacy/index.tsx b/src/pages/privacy/index.tsx index 61407b712..ad543e544 100644 --- a/src/pages/privacy/index.tsx +++ b/src/pages/privacy/index.tsx @@ -1,6 +1,7 @@ -import { Box, Paper, Typography, Link, useTheme } from '@material-ui/core' +import { Box, Typography, Link, useTheme } from '@material-ui/core' import React from 'react' +import { StyledArticleBody } from '@/configs/theme/articletext' import { sessionIdStore } from '@/store/sessionIdStore' export default function PrivacyPolicy() { @@ -11,145 +12,143 @@ export default function PrivacyPolicy() { return ( - - - Privacy Policy - - 1. Information we collect - - - 1.1 Information you provide to us - - When you log in with Google, we collect your -
    -
  • Name
  • -
  • Google User ID
  • -
  • Google Drive App Data (Only the data associated with this app such as your course schedule)
  • -
- - 1.2 Information we collect automatically - - - When you use our website, we collect your interactions with the website, which includes - -
    -
  • - Device ID (associated with the browser that you use and can be renewed by clearing the browser's - local storage) -
  • -
  • Search query
  • -
  • Click interaction
  • -
  • Page visit
  • -
  • Google User ID
  • -
  • Courses you selected
  • -
  • IP address
  • -
  • User agent
  • -
- - When you submit the feedback form, the above information will be included in the submission if you provide - the Session ID. - - - 1.3 Third-Party Information - + + Privacy Policy + + 1. Information we collect + + + 1.1 Information you provide to us + + When you log in with Google, we collect your +
    +
  • Name
  • +
  • Google User ID
  • +
  • Google Drive App Data (Only the data associated with this app such as your course schedule)
  • +
+ + 1.2 Information we collect automatically + + + When you use our website, we collect your interactions with the website, which includes + +
    +
  • + Device ID (associated with the browser that you use and can be renewed by clearing the browser's local + storage) +
  • +
  • Search query
  • +
  • Click interaction
  • +
  • Page visit
  • +
  • Google User ID
  • +
  • Courses you selected
  • +
  • IP address
  • +
  • User agent
  • +
+ + When you submit the feedback form, the above information will be included in the submission if you provide the + Session ID. + + + 1.3 Third-Party Information + - - We use third-party services to collect your interactions with the website, namely - -
    -
  • - Google Analytics{' '} - - (Privacy Policy) - -
  • -
  • - Hotjar{' '} - - (Privacy Policy) - -
  • -
- - By using this website, you must agree to the specified third-party’s Terms of Service and Privacy Policy. - - - Our website is hosted on the Office of the Registrar Chulalongkorn University’s server. They do not endorse - us in any way including the correctness of the data. You must still follow their Terms of Service and - associated university’s law. - - - 2. How we use your information - - - We use your information for the following purposes: - - - 2.1 Core Functionality - - - We use your search and the associated query and context to provide you with the correct ranking of the - search results. We also use your Google Drive App information storage to provide multi-device course - schedule synchronization. - - - 2.2 Functionality Enrichment - - - In the future, we may use the information to provide you with customized search results and recommendations - to enhance your experience. - - - 2.3 Research and Product Development - - - We use your information to better understand our user’s interactions with the website. The information is - used to - -
    -
  • Research user behaviour
  • -
  • Better understand user needs and preferences
  • -
  • Improve this website and manage the release of future features
  • -
  • Create new products and/or features to further satisfy user needs
  • -
- - 2.4 Security - - - We collect the information to prevent our service against spam and security threats. - - - 3. How we share your information - - - Your information is shared within our website’s development team. In the future, We may share your - anonymized information with our partners who would collaborate with us to better meet our user’s needs. In - the case that this project is reorganized to other organizations within Chulalongkorn University, your - information will be transferred along with the website to them. - - - 4. Contact information and inquiry - - - If you have any questions or concerns about our use of your information, send us an email to “thinc.org at - gmail.com”, or more preferably, the{' '} - - report problem - {' '} - link on the top right corner of this page. - -
-
+ + We use third-party services to collect your interactions with the website, namely + +
    +
  • + Google Analytics{' '} + + (Privacy Policy) + +
  • +
  • + Hotjar{' '} + + (Privacy Policy) + +
  • +
+ + By using this website, you must agree to the specified third-party’s Terms of Service and Privacy Policy. + + + Our website is hosted on the Office of the Registrar Chulalongkorn University’s server. They do not endorse us + in any way including the correctness of the data. You must still follow their Terms of Service and associated + university’s law. + + + 2. How we use your information + + + We use your information for the following purposes: + + + 2.1 Core Functionality + + + We use your search and the associated query and context to provide you with the correct ranking of the search + results. We also use your Google Drive App information storage to provide multi-device course schedule + synchronization. + + + 2.2 Functionality Enrichment + + + In the future, we may use the information to provide you with customized search results and recommendations to + enhance your experience. + + + 2.3 Research and Product Development + + + We use your information to better understand our user’s interactions with the website. The information is used + to + +
    +
  • Research user behaviour
  • +
  • Better understand user needs and preferences
  • +
  • Improve this website and manage the release of future features
  • +
  • Create new products and/or features to further satisfy user needs
  • +
+ + 2.4 Security + + + We collect the information to prevent our service against spam and security threats. + + + 3. How we share your information + + + Your information is shared within our website’s development team. In the future, We may share your anonymized + information with our partners who would collaborate with us to better meet our user’s needs. In the case that + this project is reorganized to other organizations within Chulalongkorn University, your information will be + transferred along with the website to them. + + + 4. Contact information and inquiry + + + If you have any questions or concerns about our use of your information, send us an email to “thinc.org at + gmail.com”, or more preferably, the{' '} + + report problem + {' '} + link on the top right corner of this page. + +
) } From 1d099d6e62f81afb94c55f5e03170602be135c72 Mon Sep 17 00:00:00 2001 From: Anos Posidos <51981658+Anon-136@users.noreply.github.com> Date: Fri, 5 Nov 2021 13:52:15 +0700 Subject: [PATCH 4/8] fix: some overlaps warning is missing (#246) * fix: overlaps warning is incomplete * fix: eslint warning * test: write test for getOverlapping * test: add notes and change test case format * test: rename mock const * test: fix grammar for test name --- src/__mock__/overlap.ts | 135 ++++++++++++++++++ .../utils/getOverlappingCourses/index.test.ts | 107 ++++++++++++++ .../utils/getOverlappingCourses/index.ts | 48 +++++++ .../Schedule/{utils.ts => utils/index.ts} | 33 +---- 4 files changed, 297 insertions(+), 26 deletions(-) create mode 100644 src/__mock__/overlap.ts create mode 100644 src/modules/Schedule/components/Schedule/utils/getOverlappingCourses/index.test.ts create mode 100644 src/modules/Schedule/components/Schedule/utils/getOverlappingCourses/index.ts rename src/modules/Schedule/components/Schedule/{utils.ts => utils/index.ts} (86%) diff --git a/src/__mock__/overlap.ts b/src/__mock__/overlap.ts new file mode 100644 index 000000000..afda8d329 --- /dev/null +++ b/src/__mock__/overlap.ts @@ -0,0 +1,135 @@ +import { ExamClass } from '@/common/utils/types' +import { CourseOverlap, CourseOverlapMap, ScheduleClass } from '@/modules/Schedule/components/Schedule/utils' + +export const courseTemplate: ScheduleClass = { + courseNo: '2110316', + abbrName: 'PROG LANG PRIN', + genEdType: 'NO', + building: 'ENG3', + room: '318', + teachers: ['NNN'], + position: { + start: 0, + end: 0, + }, + hasOverlap: false, + overlaps: [], +} + +export const examTemplate: ExamClass = { + courseNo: '2110316', + abbrName: 'PROG LANG PRIN', + genEdType: 'NO', + teachers: ['NNN'], + midterm: { + date: '', + period: { start: '', end: '' }, + }, + final: { + date: '', + period: { start: '', end: '' }, + }, + isHidden: false, + + hasOverlap: false, + overlaps: [], +} + +export const noOverlap: CourseOverlap = { hasOverlap: false, classes: [], exams: [] } + +/** + * 200000, 200001, 200002 are not overlapping + * 200003, 200004 are overlapping exactly once + * 200006, 200007 are overlapping twice + * 200010 are overlapping with each 200008 and 200009 twice + */ +export const mockNonOverlappingCourses: ScheduleClass[] = [ + { ...courseTemplate, courseNo: '200000' }, + { ...courseTemplate, courseNo: '200001' }, + { ...courseTemplate, courseNo: '200002' }, +] +export const mockTwoOverlappingCourses_1: ScheduleClass[] = [ + { ...courseTemplate, courseNo: '200003', hasOverlap: true, overlaps: ['200004'] }, + { ...courseTemplate, courseNo: '200004', hasOverlap: true, overlaps: ['200003'] }, +] +export const mockTwoOverlappingCourses_2: ScheduleClass[] = [ + { ...courseTemplate, courseNo: '200005', hasOverlap: true, overlaps: ['200006', '200006'] }, + { ...courseTemplate, courseNo: '200006', hasOverlap: true, overlaps: ['200005', '200005'] }, +] +export const mockThreeOverlappingCourses: ScheduleClass[] = [ + { ...courseTemplate, courseNo: '200007', hasOverlap: true, overlaps: ['200009', '200009'] }, + { ...courseTemplate, courseNo: '200008', hasOverlap: true, overlaps: ['200009', '200009'] }, + { + ...courseTemplate, + courseNo: '200009', + hasOverlap: true, + overlaps: ['200007', '200007', '200008', '200008'], + }, +] + +export const expectedNonOverlappingCourses: CourseOverlapMap = { + '200000': { ...noOverlap }, + '200001': { ...noOverlap }, + '200002': { ...noOverlap }, +} +export const expectedTwoOverlappingCourses_1: CourseOverlapMap = { + '200003': { ...noOverlap, hasOverlap: true, classes: ['200004'] }, + '200004': { ...noOverlap, hasOverlap: true, classes: ['200003'] }, +} +export const expectedTwoOverlappingCourses_2: CourseOverlapMap = { + '200005': { ...noOverlap, hasOverlap: true, classes: ['200006'] }, + '200006': { ...noOverlap, hasOverlap: true, classes: ['200005'] }, +} +export const expectedThreeOverlappingCourses: CourseOverlapMap = { + '200007': { ...noOverlap, hasOverlap: true, classes: ['200009'] }, + '200008': { ...noOverlap, hasOverlap: true, classes: ['200009'] }, + '200009': { ...noOverlap, hasOverlap: true, classes: ['200007', '200008'] }, +} +/** + * 200000, 200001, 200002 are not overlapping + * 200003, 200004 are overlapping exactly once + * 200006, 200007 are overlapping twice + * 200010 are overlapping with each 200008 and 200009 twice + */ +export const mockNonOverlappingExams: ExamClass[] = [ + { ...examTemplate, courseNo: '200000' }, + { ...examTemplate, courseNo: '200001' }, + { ...examTemplate, courseNo: '200002' }, +] +export const mockTwoOverlappingExams_1: ExamClass[] = [ + { ...examTemplate, courseNo: '200003', hasOverlap: true, overlaps: ['200004'] }, + { ...examTemplate, courseNo: '200004', hasOverlap: true, overlaps: ['200003'] }, +] +export const mockTwoOverlappingExams_2: ExamClass[] = [ + { ...examTemplate, courseNo: '200005', hasOverlap: true, overlaps: ['200006', '200006'] }, + { ...examTemplate, courseNo: '200006', hasOverlap: true, overlaps: ['200005', '200005'] }, +] +export const mockThreeOverlappingExams: ExamClass[] = [ + { ...examTemplate, courseNo: '200007', hasOverlap: true, overlaps: ['200009', '200009'] }, + { ...examTemplate, courseNo: '200008', hasOverlap: true, overlaps: ['200009', '200009'] }, + { + ...examTemplate, + courseNo: '200009', + hasOverlap: true, + overlaps: ['200007', '200007', '200008', '200008'], + }, +] + +export const expectedNonOverlappingClassesAndExams: CourseOverlapMap = { + '200000': { ...noOverlap }, + '200001': { ...noOverlap }, + '200002': { ...noOverlap }, +} +export const expectedTwoOverlappingClassesAndExams_1: CourseOverlapMap = { + '200003': { hasOverlap: true, classes: ['200004'], exams: ['200004'] }, + '200004': { hasOverlap: true, classes: ['200003'], exams: ['200003'] }, +} +export const expectedTwoOverlappingClassesAndExams_2: CourseOverlapMap = { + '200005': { hasOverlap: true, classes: ['200006'], exams: ['200006'] }, + '200006': { hasOverlap: true, classes: ['200005'], exams: ['200005'] }, +} +export const expectedThreeOverlappingClassesAndExams: CourseOverlapMap = { + '200007': { hasOverlap: true, classes: ['200009'], exams: ['200009'] }, + '200008': { hasOverlap: true, classes: ['200009'], exams: ['200009'] }, + '200009': { hasOverlap: true, classes: ['200007', '200008'], exams: ['200007', '200008'] }, +} diff --git a/src/modules/Schedule/components/Schedule/utils/getOverlappingCourses/index.test.ts b/src/modules/Schedule/components/Schedule/utils/getOverlappingCourses/index.test.ts new file mode 100644 index 000000000..8fc8acdd4 --- /dev/null +++ b/src/modules/Schedule/components/Schedule/utils/getOverlappingCourses/index.test.ts @@ -0,0 +1,107 @@ +import { + expectedNonOverlappingCourses, + expectedThreeOverlappingCourses, + expectedTwoOverlappingClassesAndExams_1, + expectedTwoOverlappingClassesAndExams_2, + expectedTwoOverlappingCourses_1, + expectedTwoOverlappingCourses_2, + mockNonOverlappingCourses, + mockNonOverlappingExams, + mockThreeOverlappingCourses, + mockThreeOverlappingExams, + mockTwoOverlappingCourses_1, + mockTwoOverlappingCourses_2, + mockTwoOverlappingExams_1, + mockTwoOverlappingExams_2, + expectedThreeOverlappingClassesAndExams, +} from '@/__mock__/overlap' + +import { getOverlappingCourses } from '.' + +describe('getOverlappingCourses', () => { + it('No course selected should return nothing', () => { + const result = getOverlappingCourses([], [], []) + expect(result).toEqual({}) + }) + it('Course selected exactly once should return no overlap', () => { + const result = getOverlappingCourses( + [mockNonOverlappingCourses[0]], + [mockNonOverlappingExams[0]], + [mockNonOverlappingExams[0]] + ) + expect(result).toEqual({ '200000': expectedNonOverlappingCourses['200000'] }) + }) + it('3 non-overlapping courses should return non-overlapping each ', () => { + const result = getOverlappingCourses(mockNonOverlappingCourses, [], []) + expect(result).toEqual(expectedNonOverlappingCourses) + }) + it('2 overlapping classes should return overlap for each other', () => { + const result = getOverlappingCourses(mockTwoOverlappingCourses_1, [], []) + expect(result).toEqual(expectedTwoOverlappingCourses_1) + }) + it('2 overlapping classes and 1 non-overlapping class should return overlap and no overlap', () => { + const result1 = getOverlappingCourses([mockNonOverlappingCourses[0], ...mockNonOverlappingCourses], [], []) + const result2 = getOverlappingCourses([...mockNonOverlappingCourses, mockNonOverlappingCourses[0]], [], []) + const expectedResult = { '200000': expectedNonOverlappingCourses['200000'], ...expectedNonOverlappingCourses } + expect(result1).toEqual(expectedResult) + expect(result2).toEqual(expectedResult) + }) + it('2 double overlapping classes should return overlap only once', () => { + const result = getOverlappingCourses(mockTwoOverlappingCourses_2, [], []) + expect(result).toEqual(expectedTwoOverlappingCourses_2) + }) + it('A class, overlapping with 2 other classes twice, should return two unique overlaps', () => { + const result = getOverlappingCourses(mockThreeOverlappingCourses, [], []) + expect(result).toEqual(expectedThreeOverlappingCourses) + }) + it('2 overlapping classes and midterm exams should return both exam and class overlaps', () => { + const result = getOverlappingCourses(mockTwoOverlappingCourses_1, mockTwoOverlappingExams_1, []) + expect(result).toEqual(expectedTwoOverlappingClassesAndExams_1) + }) + it('2 overlapping classes and final exams return both exam and class overlaps', () => { + const result = getOverlappingCourses(mockTwoOverlappingCourses_1, [], mockTwoOverlappingExams_1) + expect(result).toEqual(expectedTwoOverlappingClassesAndExams_1) + }) + it('2 overlapping both midterm and final exams should return both exam and class overlaps only once', () => { + const result = getOverlappingCourses( + mockTwoOverlappingCourses_1, + mockTwoOverlappingExams_1, + mockTwoOverlappingExams_1 + ) + expect(result).toEqual(expectedTwoOverlappingClassesAndExams_1) + }) + it('2 overlapping exams with 1 non-overlapping exam should return overlap and no overlap', () => { + const result1 = getOverlappingCourses( + [mockNonOverlappingCourses[0], ...mockTwoOverlappingCourses_1], + [mockNonOverlappingExams[0], ...mockTwoOverlappingExams_1], + [mockNonOverlappingExams[0], ...mockTwoOverlappingExams_1] + ) + const result2 = getOverlappingCourses( + [mockNonOverlappingCourses[0], ...mockTwoOverlappingCourses_1], + [...mockTwoOverlappingExams_1, mockNonOverlappingExams[0]], + [...mockTwoOverlappingExams_1, mockNonOverlappingExams[0]] + ) + const expectedResult = { + '200000': expectedNonOverlappingCourses['200000'], + ...expectedTwoOverlappingClassesAndExams_1, + } + expect(result1).toEqual(expectedResult) + expect(result2).toEqual(expectedResult) + }) + it('2 double overlapping exams should return exam class overlap only once', () => { + const result = getOverlappingCourses( + mockTwoOverlappingCourses_2, + mockTwoOverlappingExams_2, + mockTwoOverlappingExams_2 + ) + expect(result).toEqual(expectedTwoOverlappingClassesAndExams_2) + }) + it('An exam, overlapping with 2 other exams twice, should return two unique overlaps', () => { + const result = getOverlappingCourses( + mockThreeOverlappingCourses, + mockThreeOverlappingExams, + mockThreeOverlappingExams + ) + expect(result).toEqual(expectedThreeOverlappingClassesAndExams) + }) +}) diff --git a/src/modules/Schedule/components/Schedule/utils/getOverlappingCourses/index.ts b/src/modules/Schedule/components/Schedule/utils/getOverlappingCourses/index.ts new file mode 100644 index 000000000..23a6e3f3f --- /dev/null +++ b/src/modules/Schedule/components/Schedule/utils/getOverlappingCourses/index.ts @@ -0,0 +1,48 @@ +import { uniq } from 'lodash' + +import { ExamClass } from '@/common/utils/types' + +import { ScheduleClass, CourseOverlapMap } from '..' + +/** + * get a course overlap map which tells that for each course (key), + * what other courses are overlapping with it in terms of classes and exams (value) + * for the purpose of showing overlaps warning + * @param classes a list of class which have been checked for overlapping + * @param midtermClasses a list of midterm exams which have been checked for overlapping + * @param finalClasses a list of final exams which have been checked for overlapping + * @returns A record of key `courseNo` and value `CourseOverlap` + */ +export function getOverlappingCourses( + classes: ScheduleClass[], + midtermClasses: ExamClass[], + finalClasses: ExamClass[] +) { + const courses: CourseOverlapMap = {} + classes.forEach((it) => { + courses[it.courseNo] = { + hasOverlap: false, + classes: [], + exams: [], + } + }) + classes.forEach((it) => { + courses[it.courseNo].classes = [...courses[it.courseNo].classes, ...it.overlaps] + }) + midtermClasses.forEach((it) => { + if (it.hasOverlap === true) { + courses[it.courseNo].exams = [...courses[it.courseNo].exams, ...it.overlaps] + } + }) + finalClasses.forEach((it) => { + if (it.hasOverlap === true) { + courses[it.courseNo].exams = [...courses[it.courseNo].exams, ...it.overlaps] + } + }) + Object.entries(courses).forEach(([, course]) => { + course.classes = uniq(course.classes) + course.exams = uniq(course.exams) + course.hasOverlap = course.classes.length > 0 || course.exams.length > 0 + }) + return courses +} diff --git a/src/modules/Schedule/components/Schedule/utils.ts b/src/modules/Schedule/components/Schedule/utils/index.ts similarity index 86% rename from src/modules/Schedule/components/Schedule/utils.ts rename to src/modules/Schedule/components/Schedule/utils/index.ts index 2627688fa..3a76df73b 100644 --- a/src/modules/Schedule/components/Schedule/utils.ts +++ b/src/modules/Schedule/components/Schedule/utils/index.ts @@ -1,13 +1,13 @@ import { useTheme } from '@material-ui/core' import { Course, Class, DayOfWeek, GenEdType } from '@thinc-org/chula-courses' -import { uniq } from 'lodash' import { useMemo } from 'react' import { getPaletteRange } from '@/common/utils/getPaletteRange' import { ExamClass } from '@/common/utils/types' import { CourseCartItem } from '@/store' -import { hourStart } from './constants' +import { hourStart } from '../constants' +import { getOverlappingCourses } from './getOverlappingCourses' export type TimetableClass = Pick & Omit & { @@ -148,30 +148,11 @@ export function useOverlappingCourses( midtermClasses: ExamClass[], finalClasses: ExamClass[] ) { - return useMemo(() => { - const courses: CourseOverlapMap = {} - classes.forEach((it) => { - courses[it.courseNo] = { - hasOverlap: false, - classes: uniq(it.overlaps), - exams: [], - } - }) - midtermClasses.forEach((it) => { - if (it.hasOverlap === true) { - courses[it.courseNo].exams = it.overlaps - } - }) - finalClasses.forEach((it) => { - if (it.hasOverlap === true) { - courses[it.courseNo].exams = uniq([...courses[it.courseNo].exams, ...it.overlaps]) - } - }) - Object.entries(courses).forEach(([courseNo, course]) => { - courses[courseNo].hasOverlap = course.classes.length > 0 || course.exams.length > 0 - }) - return courses - }, [classes, midtermClasses, finalClasses]) + return useMemo(() => getOverlappingCourses(classes, midtermClasses, finalClasses), [ + classes, + midtermClasses, + finalClasses, + ]) } interface ColorScheme { From 6e6d45a4a1292d5fb90e0a21446ba12feec0d4ca Mon Sep 17 00:00:00 2001 From: Anos Posidos <51981658+Anon-136@users.noreply.github.com> Date: Fri, 5 Nov 2021 14:35:49 +0700 Subject: [PATCH 5/8] fix: snackbar action text (#248) --- src/modules/App/components/CourseSnackbar.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modules/App/components/CourseSnackbar.tsx b/src/modules/App/components/CourseSnackbar.tsx index d90c5f54c..ef97b0b3c 100644 --- a/src/modules/App/components/CourseSnackbar.tsx +++ b/src/modules/App/components/CourseSnackbar.tsx @@ -34,7 +34,7 @@ export const CourseSnackbar = () => { onOpen() }} > - {snackbar.message} + {snackbar.action} )}
From 413752ca426834991087e66f0cefde0c240e44cb Mon Sep 17 00:00:00 2001 From: Suphon Thanakornpakapong Date: Fri, 5 Nov 2021 21:58:06 +0700 Subject: [PATCH 6/8] Don't run release job unless on master --- .github/workflows/build-and-deploy.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-and-deploy.yaml b/.github/workflows/build-and-deploy.yaml index e5ce42a00..d80e00ff6 100644 --- a/.github/workflows/build-and-deploy.yaml +++ b/.github/workflows/build-and-deploy.yaml @@ -24,6 +24,7 @@ env: jobs: release-note: name: Release + if: ${{ github.ref == 'refs/heads/master' }} runs-on: ubuntu-latest steps: - name: Checkout @@ -42,7 +43,6 @@ jobs: run: yarn --fronzen-lockfile - name: Release - if: ${{ github.ref == 'refs/heads/master' }} run: npx semantic-release env: GITHUB_TOKEN: ${{ github.token }} From af80cd030c767bd2cf5056baab47d8fb20f8f405 Mon Sep 17 00:00:00 2001 From: Suphon Thanakornpakapong Date: Fri, 5 Nov 2021 19:43:25 +0700 Subject: [PATCH 7/8] Sync hidden state --- src/services/apollo/query/user.ts | 1 + src/store/courseCart.ts | 25 ++++++++----------------- 2 files changed, 9 insertions(+), 17 deletions(-) diff --git a/src/services/apollo/query/user.ts b/src/services/apollo/query/user.ts index dbdddff63..50164cdbf 100644 --- a/src/services/apollo/query/user.ts +++ b/src/services/apollo/query/user.ts @@ -32,6 +32,7 @@ export const GET_COURSE_CART = gql` courseNo semester selectedSectionNo + isHidden } } ` diff --git a/src/store/courseCart.ts b/src/store/courseCart.ts index 75d0e51e3..1a82d94a0 100644 --- a/src/store/courseCart.ts +++ b/src/store/courseCart.ts @@ -14,7 +14,6 @@ import { userStore } from '@/store/userStore' export interface CourseCartItem extends Course { selectedSectionNo: string - isSelected: boolean isHidden: boolean } @@ -39,6 +38,7 @@ interface CourseCartStoreItem { courseNo: string semester: string selectedSectionNo: string + isHidden: boolean } export interface CourseCartStore { @@ -145,9 +145,9 @@ export class CourseCart implements CourseCartProps { }) try { const courses = await this.source.syncFromStore() - const fullCourses: (Course & { selectedSectionNo: string })[] = [] + const fullCourses: CourseCartItem[] = [] for (const course of courses) { - let detail + let detail: CourseCartItem try { const { data } = await client.query({ query: GET_COURSE, @@ -160,11 +160,12 @@ export class CourseCart implements CourseCartProps { }, }, }) - detail = { ...data.course, selectedSectionNo: course.selectedSectionNo } + detail = { ...data.course, selectedSectionNo: course.selectedSectionNo, isHidden: course.isHidden } } catch (e) { detail = { ...unknownCourse, selectedSectionNo: course.selectedSectionNo, + isHidden: course.isHidden, studyProgram: course.studyProgram as StudyProgram, semester: course.semester as Semester, academicYear: course.academicYear, @@ -174,7 +175,7 @@ export class CourseCart implements CourseCartProps { fullCourses.push(detail) } runInAction(() => { - this.shopItems = fullCourses.map((course) => ({ ...course, isSelected: false, isHidden: false })) + this.shopItems = fullCourses.map((course) => ({ ...course })) }) setTimeout( action('Delayed sync icon', () => { @@ -203,6 +204,7 @@ export class CourseCart implements CourseCartProps { semester: item.semester, courseNo: item.courseNo, selectedSectionNo: item.selectedSectionNo, + isHidden: item.isHidden, })) ) setTimeout( @@ -261,7 +263,7 @@ export class CourseCart implements CourseCartProps { }) if (!selectedSectionNo) selectedSectionNo = this.findFirstSectionNo(course) - const newItem: CourseCartItem = { ...course, selectedSectionNo, isSelected: false, isHidden: false } + const newItem: CourseCartItem = { ...course, selectedSectionNo, isHidden: false } const foundIndex = this.shopItems.findIndex((item) => isSameKey(item, newItem)) if (foundIndex != -1) this.shopItems[foundIndex] = newItem else this.shopItems.push(newItem) @@ -286,17 +288,6 @@ export class CourseCart implements CourseCartProps { const foundIndex = this.shopItems.findIndex((item) => isSameKey(item, course)) if (foundIndex == -1) return this.shopItems[foundIndex].isHidden = !this.shopItems[foundIndex].isHidden - } - - /** - * Use to remove all selected items - */ - @action - removeItems(): void { - if (this.state === 'default') return - this.shopItems = this.shopItems.filter((item) => item.isSelected === false) - this.state = 'default' - this.onChange() } From f8663d5fcb74a4f103d6050d564f5282a4c4e10c Mon Sep 17 00:00:00 2001 From: Suphon Thanakornpakapong Date: Fri, 5 Nov 2021 21:51:03 +0700 Subject: [PATCH 8/8] Sync on reorder --- src/store/courseCart.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/store/courseCart.ts b/src/store/courseCart.ts index 1a82d94a0..e8a7c3b3f 100644 --- a/src/store/courseCart.ts +++ b/src/store/courseCart.ts @@ -298,6 +298,7 @@ export class CourseCart implements CourseCartProps { const [removed] = result.splice(from, 1) result.splice(to, 0, removed) this.shopItems = result + this.onChange() } /**