Skip to content

Commit 720f5ad

Browse files
authored
Merge pull request #253 from thinc-org/beta
Deploy to Production (7th Nov 2021)
2 parents c500a9f + d3061d9 commit 720f5ad

File tree

19 files changed

+692
-368
lines changed

19 files changed

+692
-368
lines changed

.github/workflows/build-and-deploy.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ env:
2424
jobs:
2525
release-note:
2626
name: Release
27+
if: ${{ github.ref == 'refs/heads/master' }}
2728
runs-on: ubuntu-latest
2829
steps:
2930
- name: Checkout
@@ -42,7 +43,6 @@ jobs:
4243
run: yarn --fronzen-lockfile
4344

4445
- name: Release
45-
if: ${{ github.ref == 'refs/heads/master' }}
4646
run: npx semantic-release
4747
env:
4848
GITHUB_TOKEN: ${{ github.token }}

src/__mock__/overlap.ts

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
import { ExamClass } from '@/common/utils/types'
2+
import { CourseOverlap, CourseOverlapMap, ScheduleClass } from '@/modules/Schedule/components/Schedule/utils'
3+
4+
export const courseTemplate: ScheduleClass = {
5+
courseNo: '2110316',
6+
abbrName: 'PROG LANG PRIN',
7+
genEdType: 'NO',
8+
building: 'ENG3',
9+
room: '318',
10+
teachers: ['NNN'],
11+
position: {
12+
start: 0,
13+
end: 0,
14+
},
15+
hasOverlap: false,
16+
overlaps: [],
17+
}
18+
19+
export const examTemplate: ExamClass = {
20+
courseNo: '2110316',
21+
abbrName: 'PROG LANG PRIN',
22+
genEdType: 'NO',
23+
teachers: ['NNN'],
24+
midterm: {
25+
date: '',
26+
period: { start: '', end: '' },
27+
},
28+
final: {
29+
date: '',
30+
period: { start: '', end: '' },
31+
},
32+
isHidden: false,
33+
34+
hasOverlap: false,
35+
overlaps: [],
36+
}
37+
38+
export const noOverlap: CourseOverlap = { hasOverlap: false, classes: [], exams: [] }
39+
40+
/**
41+
* 200000, 200001, 200002 are not overlapping
42+
* 200003, 200004 are overlapping exactly once
43+
* 200006, 200007 are overlapping twice
44+
* 200010 are overlapping with each 200008 and 200009 twice
45+
*/
46+
export const mockNonOverlappingCourses: ScheduleClass[] = [
47+
{ ...courseTemplate, courseNo: '200000' },
48+
{ ...courseTemplate, courseNo: '200001' },
49+
{ ...courseTemplate, courseNo: '200002' },
50+
]
51+
export const mockTwoOverlappingCourses_1: ScheduleClass[] = [
52+
{ ...courseTemplate, courseNo: '200003', hasOverlap: true, overlaps: ['200004'] },
53+
{ ...courseTemplate, courseNo: '200004', hasOverlap: true, overlaps: ['200003'] },
54+
]
55+
export const mockTwoOverlappingCourses_2: ScheduleClass[] = [
56+
{ ...courseTemplate, courseNo: '200005', hasOverlap: true, overlaps: ['200006', '200006'] },
57+
{ ...courseTemplate, courseNo: '200006', hasOverlap: true, overlaps: ['200005', '200005'] },
58+
]
59+
export const mockThreeOverlappingCourses: ScheduleClass[] = [
60+
{ ...courseTemplate, courseNo: '200007', hasOverlap: true, overlaps: ['200009', '200009'] },
61+
{ ...courseTemplate, courseNo: '200008', hasOverlap: true, overlaps: ['200009', '200009'] },
62+
{
63+
...courseTemplate,
64+
courseNo: '200009',
65+
hasOverlap: true,
66+
overlaps: ['200007', '200007', '200008', '200008'],
67+
},
68+
]
69+
70+
export const expectedNonOverlappingCourses: CourseOverlapMap = {
71+
'200000': { ...noOverlap },
72+
'200001': { ...noOverlap },
73+
'200002': { ...noOverlap },
74+
}
75+
export const expectedTwoOverlappingCourses_1: CourseOverlapMap = {
76+
'200003': { ...noOverlap, hasOverlap: true, classes: ['200004'] },
77+
'200004': { ...noOverlap, hasOverlap: true, classes: ['200003'] },
78+
}
79+
export const expectedTwoOverlappingCourses_2: CourseOverlapMap = {
80+
'200005': { ...noOverlap, hasOverlap: true, classes: ['200006'] },
81+
'200006': { ...noOverlap, hasOverlap: true, classes: ['200005'] },
82+
}
83+
export const expectedThreeOverlappingCourses: CourseOverlapMap = {
84+
'200007': { ...noOverlap, hasOverlap: true, classes: ['200009'] },
85+
'200008': { ...noOverlap, hasOverlap: true, classes: ['200009'] },
86+
'200009': { ...noOverlap, hasOverlap: true, classes: ['200007', '200008'] },
87+
}
88+
/**
89+
* 200000, 200001, 200002 are not overlapping
90+
* 200003, 200004 are overlapping exactly once
91+
* 200006, 200007 are overlapping twice
92+
* 200010 are overlapping with each 200008 and 200009 twice
93+
*/
94+
export const mockNonOverlappingExams: ExamClass[] = [
95+
{ ...examTemplate, courseNo: '200000' },
96+
{ ...examTemplate, courseNo: '200001' },
97+
{ ...examTemplate, courseNo: '200002' },
98+
]
99+
export const mockTwoOverlappingExams_1: ExamClass[] = [
100+
{ ...examTemplate, courseNo: '200003', hasOverlap: true, overlaps: ['200004'] },
101+
{ ...examTemplate, courseNo: '200004', hasOverlap: true, overlaps: ['200003'] },
102+
]
103+
export const mockTwoOverlappingExams_2: ExamClass[] = [
104+
{ ...examTemplate, courseNo: '200005', hasOverlap: true, overlaps: ['200006', '200006'] },
105+
{ ...examTemplate, courseNo: '200006', hasOverlap: true, overlaps: ['200005', '200005'] },
106+
]
107+
export const mockThreeOverlappingExams: ExamClass[] = [
108+
{ ...examTemplate, courseNo: '200007', hasOverlap: true, overlaps: ['200009', '200009'] },
109+
{ ...examTemplate, courseNo: '200008', hasOverlap: true, overlaps: ['200009', '200009'] },
110+
{
111+
...examTemplate,
112+
courseNo: '200009',
113+
hasOverlap: true,
114+
overlaps: ['200007', '200007', '200008', '200008'],
115+
},
116+
]
117+
118+
export const expectedNonOverlappingClassesAndExams: CourseOverlapMap = {
119+
'200000': { ...noOverlap },
120+
'200001': { ...noOverlap },
121+
'200002': { ...noOverlap },
122+
}
123+
export const expectedTwoOverlappingClassesAndExams_1: CourseOverlapMap = {
124+
'200003': { hasOverlap: true, classes: ['200004'], exams: ['200004'] },
125+
'200004': { hasOverlap: true, classes: ['200003'], exams: ['200003'] },
126+
}
127+
export const expectedTwoOverlappingClassesAndExams_2: CourseOverlapMap = {
128+
'200005': { hasOverlap: true, classes: ['200006'], exams: ['200006'] },
129+
'200006': { hasOverlap: true, classes: ['200005'], exams: ['200005'] },
130+
}
131+
export const expectedThreeOverlappingClassesAndExams: CourseOverlapMap = {
132+
'200007': { hasOverlap: true, classes: ['200009'], exams: ['200009'] },
133+
'200008': { hasOverlap: true, classes: ['200009'], exams: ['200009'] },
134+
'200009': { hasOverlap: true, classes: ['200007', '200008'], exams: ['200007', '200008'] },
135+
}

src/common/components/TopBar/components/MobileNavBar/index.tsx

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,12 @@ import { MdMenu } from 'react-icons/md'
99
import logo from '@/assets/images/cgrLogoDark.svg'
1010
import { Analytics } from '@/common/context/Analytics/components/Analytics'
1111
import { LinkWithAnalytics } from '@/common/context/Analytics/components/LinkWithAnalytics'
12-
import { REPORT_PROBLEM, NAVBAR_SEARCH_COURSE, NAVBAR_TIMETABLE } from '@/common/context/Analytics/constants'
12+
import {
13+
REPORT_PROBLEM,
14+
NAVBAR_SEARCH_COURSE,
15+
NAVBAR_TIMETABLE,
16+
NAVBAR_ABOUT,
17+
} from '@/common/context/Analytics/constants'
1318
import { useDisclosure } from '@/common/hooks/useDisclosure'
1419
import { useLinkBuilder } from '@/common/hooks/useLinkBuilder'
1520
import { sessionIdStore } from '@/store/sessionIdStore'
@@ -49,6 +54,11 @@ export const MobileNavBar = observer(() => {
4954
<NavBarItem onClick={onClose}>{t('navBar:timetable')}</NavBarItem>
5055
</LinkWithAnalytics>
5156
</div>
57+
<div>
58+
<LinkWithAnalytics href={buildLink(`/about`, {}, false)} passHref elementName={NAVBAR_ABOUT}>
59+
<NavBarItem onClick={onClose}>{t('navBar:about')}</NavBarItem>
60+
</LinkWithAnalytics>
61+
</div>
5262
<SectionSpacer />
5363
<div>
5464
<Analytics elementName={REPORT_PROBLEM}>

src/configs/theme/articletext.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import styled from '@emotion/styled'
2+
import { Typography } from '@material-ui/core'
3+
4+
export const StyledArticleBody = styled(Typography)`
5+
font-size: 18px;
6+
line-height: 32px;
7+
`

src/modules/App/components/CourseSnackbar.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ export const CourseSnackbar = () => {
3434
onOpen()
3535
}}
3636
>
37-
{snackbar.message}
37+
{snackbar.action}
3838
</Button>
3939
)}
4040
</Analytics>

src/modules/Schedule/components/Schedule/components/Gutters.tsx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import { styledWithTheme } from '@/common/utils/styledWithTheme'
22

3-
import { colsCount } from '../constants'
43
import { useDimensions } from '../dimensions'
54

65
interface GutterProps {
@@ -22,7 +21,7 @@ function Gutter({ x, y }: GutterProps) {
2221
}
2322

2423
export function Gutters() {
25-
const { daysCount } = useDimensions()
24+
const { daysCount, colsCount } = useDimensions()
2625
const gutters = []
2726
for (let x = 0; x <= colsCount; x++) {
2827
gutters.push(<Gutter key={`x${x}`} x={x} />)

src/modules/Schedule/components/Schedule/components/Header.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { useTranslation } from 'react-i18next'
44

55
import { dayOfWeekArray } from '@/common/constants/dayOfWeek'
66

7-
import { hourEnd, hourStart } from '../constants'
7+
import { hourStart } from '../constants'
88
import { useDimensions } from '../dimensions'
99
import { Cell } from './Cell'
1010
import { ScheduleTypography } from './ScheduleTypography'
@@ -23,7 +23,7 @@ function HourCell({ hour }: { hour: number }) {
2323

2424
export function Header() {
2525
const { t } = useTranslation('schedule')
26-
const { stubCellWidth, daysCount } = useDimensions()
26+
const { stubCellWidth, daysCount, hourStart, hourEnd } = useDimensions()
2727
const fontSize = (16 * stubCellWidth) / 77
2828
const hourCells = []
2929
for (let hour = hourStart + 1; hour <= hourEnd; hour++) {
Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,7 @@
11
import { DayOfWeek } from '@thinc-org/chula-courses'
22

33
export const hourStart = 7
4-
export const hourEnd = 18
54

65
export const days: DayOfWeek[] = ['MO', 'TU', 'WE', 'TH', 'FR']
76

8-
export const colsCount = hourEnd - hourStart + 2
9-
107
export const strokeSize = 1

src/modules/Schedule/components/Schedule/dimensions.tsx

Lines changed: 31 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { createContext, PropsWithChildren, useContext, useMemo } from 'react'
22

3-
import { colsCount } from './constants'
3+
import { hourStart } from './constants'
44

55
interface CellPosition {
66
top: number
@@ -16,6 +16,9 @@ interface Dimensions {
1616
width: number
1717
height: number
1818
daysCount: number
19+
colsCount: number
20+
hourStart: number
21+
hourEnd: number
1922
cellWidth: number
2023
cellHeight: number
2124
stubCellWidth: number
@@ -24,18 +27,24 @@ interface Dimensions {
2427
getCell: (y: number, x: number) => CellStyles
2528
}
2629

27-
export function getHeightRatio(daysCount: number) {
28-
return (6 / 7 / colsCount) * (daysCount + 0.7)
30+
export function getColsCount(hourEnd: number) {
31+
return hourEnd - hourStart + 2
2932
}
3033

31-
function getDimensions(width: number, daysCount: number): Dimensions {
34+
export function getHeightRatio(daysCount: number, hourEnd: number) {
35+
return (6 / 7 / getColsCount(hourEnd)) * (daysCount + 0.7)
36+
}
37+
38+
function getDimensions(width: number, daysCount: number, hourEnd: number): Dimensions {
39+
const colsCount = getColsCount(hourEnd)
40+
3241
const availableWidth = width
3342
const cellWidth = Math.ceil(availableWidth / colsCount)
3443
const stubCellWidth = availableWidth - cellWidth * (colsCount - 1)
3544

3645
const cellHeight = Math.ceil((cellWidth * 6) / 7)
3746

38-
const height = availableWidth * getHeightRatio(daysCount)
47+
const height = availableWidth * getHeightRatio(daysCount, hourEnd)
3948
const headerCellHeight = height - daysCount * cellHeight
4049

4150
function getPosition(y: number, x: number): CellPosition {
@@ -60,7 +69,20 @@ function getDimensions(width: number, daysCount: number): Dimensions {
6069
}
6170
}
6271

63-
return { width, height, daysCount, cellWidth, cellHeight, stubCellWidth, headerCellHeight, getPosition, getCell }
72+
return {
73+
width,
74+
height,
75+
daysCount,
76+
colsCount,
77+
hourStart,
78+
hourEnd,
79+
cellWidth,
80+
cellHeight,
81+
stubCellWidth,
82+
headerCellHeight,
83+
getPosition,
84+
getCell,
85+
}
6486
}
6587

6688
const DimensionsContext = createContext({} as Dimensions)
@@ -72,9 +94,10 @@ export function useDimensions() {
7294
type DimensionsProviderProps = PropsWithChildren<{
7395
width: number
7496
daysCount: number
97+
hourEnd: number
7598
}>
7699

77-
export function DimensionsProvider({ width, daysCount, children }: DimensionsProviderProps) {
78-
const dimensions = useMemo(() => getDimensions(width, daysCount), [width, daysCount])
100+
export function DimensionsProvider({ width, daysCount, hourEnd, children }: DimensionsProviderProps) {
101+
const dimensions = useMemo(() => getDimensions(width, daysCount, hourEnd), [width, daysCount, hourEnd])
79102
return <DimensionsContext.Provider value={dimensions}>{children}</DimensionsContext.Provider>
80103
}

src/modules/Schedule/components/Schedule/index.stories.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,5 @@ export default {
1212

1313
export const ScheduleStory = () => {
1414
const scheduleClasses = useScheduleClass(mockClasses)
15-
return <Schedule classes={scheduleClasses} daysCount={5} />
15+
return <Schedule classes={scheduleClasses} daysCount={5} hourEnd={18} />
1616
}

src/modules/Schedule/components/Schedule/index.tsx

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,15 +47,16 @@ const ScheduleContainer = styled.div`
4747

4848
export interface AutoScaleScheduleProps extends ScheduleProps {
4949
daysCount: number
50+
hourEnd: number
5051
}
5152

5253
const AutoScaleSchedule = withContentRect('bounds')<AutoScaleScheduleProps>(
53-
({ measureRef, contentRect, daysCount, ...props }) => (
54+
({ measureRef, contentRect, daysCount, hourEnd, ...props }) => (
5455
<>
5556
<div ref={measureRef} style={{ width: '100%' }} />
56-
<ScheduleContainer style={{ paddingTop: `${getHeightRatio(daysCount) * 100}%` }}>
57+
<ScheduleContainer style={{ paddingTop: `${getHeightRatio(daysCount, hourEnd) * 100}%` }}>
5758
{contentRect.bounds?.width ? (
58-
<DimensionsProvider width={contentRect.bounds.width} daysCount={daysCount}>
59+
<DimensionsProvider width={contentRect.bounds.width} daysCount={daysCount} hourEnd={hourEnd}>
5960
<Schedule {...props} />
6061
</DimensionsProvider>
6162
) : null}

0 commit comments

Comments
 (0)