Skip to content

Commit

Permalink
Merge pull request #253 from thinc-org/beta
Browse files Browse the repository at this point in the history
Deploy to Production (7th Nov 2021)
  • Loading branch information
suphon-t authored Nov 7, 2021
2 parents c500a9f + d3061d9 commit 720f5ad
Show file tree
Hide file tree
Showing 19 changed files with 692 additions and 368 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/build-and-deploy.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ env:
jobs:
release-note:
name: Release
if: ${{ github.ref == 'refs/heads/master' }}
runs-on: ubuntu-latest
steps:
- name: Checkout
Expand All @@ -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 }}
Expand Down
135 changes: 135 additions & 0 deletions src/__mock__/overlap.ts
Original file line number Diff line number Diff line change
@@ -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'] },
}
12 changes: 11 additions & 1 deletion src/common/components/TopBar/components/MobileNavBar/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand Down Expand Up @@ -49,6 +54,11 @@ export const MobileNavBar = observer(() => {
<NavBarItem onClick={onClose}>{t('navBar:timetable')}</NavBarItem>
</LinkWithAnalytics>
</div>
<div>
<LinkWithAnalytics href={buildLink(`/about`, {}, false)} passHref elementName={NAVBAR_ABOUT}>
<NavBarItem onClick={onClose}>{t('navBar:about')}</NavBarItem>
</LinkWithAnalytics>
</div>
<SectionSpacer />
<div>
<Analytics elementName={REPORT_PROBLEM}>
Expand Down
7 changes: 7 additions & 0 deletions src/configs/theme/articletext.ts
Original file line number Diff line number Diff line change
@@ -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;
`
2 changes: 1 addition & 1 deletion src/modules/App/components/CourseSnackbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ export const CourseSnackbar = () => {
onOpen()
}}
>
{snackbar.message}
{snackbar.action}
</Button>
)}
</Analytics>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { styledWithTheme } from '@/common/utils/styledWithTheme'

import { colsCount } from '../constants'
import { useDimensions } from '../dimensions'

interface GutterProps {
Expand All @@ -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(<Gutter key={`x${x}`} x={x} />)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand All @@ -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++) {
Expand Down
3 changes: 0 additions & 3 deletions src/modules/Schedule/components/Schedule/constants.ts
Original file line number Diff line number Diff line change
@@ -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
39 changes: 31 additions & 8 deletions src/modules/Schedule/components/Schedule/dimensions.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { createContext, PropsWithChildren, useContext, useMemo } from 'react'

import { colsCount } from './constants'
import { hourStart } from './constants'

interface CellPosition {
top: number
Expand All @@ -16,6 +16,9 @@ interface Dimensions {
width: number
height: number
daysCount: number
colsCount: number
hourStart: number
hourEnd: number
cellWidth: number
cellHeight: number
stubCellWidth: number
Expand All @@ -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 {
Expand All @@ -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)
Expand All @@ -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 <DimensionsContext.Provider value={dimensions}>{children}</DimensionsContext.Provider>
}
2 changes: 1 addition & 1 deletion src/modules/Schedule/components/Schedule/index.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,5 @@ export default {

export const ScheduleStory = () => {
const scheduleClasses = useScheduleClass(mockClasses)
return <Schedule classes={scheduleClasses} daysCount={5} />
return <Schedule classes={scheduleClasses} daysCount={5} hourEnd={18} />
}
7 changes: 4 additions & 3 deletions src/modules/Schedule/components/Schedule/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -47,15 +47,16 @@ const ScheduleContainer = styled.div`

export interface AutoScaleScheduleProps extends ScheduleProps {
daysCount: number
hourEnd: number
}

const AutoScaleSchedule = withContentRect('bounds')<AutoScaleScheduleProps>(
({ measureRef, contentRect, daysCount, ...props }) => (
({ measureRef, contentRect, daysCount, hourEnd, ...props }) => (
<>
<div ref={measureRef} style={{ width: '100%' }} />
<ScheduleContainer style={{ paddingTop: `${getHeightRatio(daysCount) * 100}%` }}>
<ScheduleContainer style={{ paddingTop: `${getHeightRatio(daysCount, hourEnd) * 100}%` }}>
{contentRect.bounds?.width ? (
<DimensionsProvider width={contentRect.bounds.width} daysCount={daysCount}>
<DimensionsProvider width={contentRect.bounds.width} daysCount={daysCount} hourEnd={hourEnd}>
<Schedule {...props} />
</DimensionsProvider>
) : null}
Expand Down
Loading

0 comments on commit 720f5ad

Please sign in to comment.