Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 53 additions & 0 deletions website/src/utils/timeOptions.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import { filterTimeOptions, toTimeLabel } from './timeOptions';

describe('timeOptions', () => {
describe('toTimeLabel', () => {
test.each([
['0800', '08:00'],
['0915', '09:15'],
['1030', '10:30'],
['1145', '11:45'],
['0333', '03:33'],
])('should label %s as %s', (time, expected) => {
expect(toTimeLabel(time)).toBe(expected);
});
});

describe('filterTimeOptions', () => {
const timeOptions = [
'0800',
'0830',
'0900',
'0930',
'1000',
'1030',
'1100',
'1130',
'1200',
'1230',
];

describe('when filter is greater', () => {
it('should keep times greater than selected time', () => {
expect(filterTimeOptions(timeOptions, '1000', 'greater')).toEqual([
'1030',
'1100',
'1130',
'1200',
'1230',
]);
});
});

describe('when filter is lesser', () => {
it('should keep times lesser than selected time', () => {
expect(filterTimeOptions(timeOptions, '1000', 'lesser')).toEqual([
'0800',
'0830',
'0900',
'0930',
]);
});
});
});
});
107 changes: 107 additions & 0 deletions website/src/utils/timeOptions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
export const TIME_OPTIONS = {
START_CLASS: [
'0800',
'0830',
'0900',
'0930',
'1000',
'1030',
'1100',
'1130',
'1200',
'1230',
'1300',
'1330',
'1400',
'1430',
'1500',
'1530',
'1600',
'1630',
'1700',
'1730',
'1800',
'1830',
'1900',
'1930',
'2000',
'2030',
'2100',
'2130',
'2200',
],
END_CLASS: [
'0900',
'0930',
'1000',
'1030',
'1100',
'1130',
'1200',
'1230',
'1300',
'1330',
'1400',
'1430',
'1500',
'1530',
'1600',
'1630',
'1700',
'1730',
'1800',
'1830',
'1900',
'1930',
'2000',
'2030',
'2100',
'2130',
'2200',
'2230',
'2300',
],
START_LUNCH: [
'1000',
'1030',
'1100',
'1130',
'1200',
'1230',
'1300',
'1330',
'1400',
'1430',
'1500',
'1530',
'1600',
'1630',
],
END_LUNCH: [
'1100',
'1130',
'1200',
'1230',
'1300',
'1330',
'1400',
'1430',
'1500',
'1530',
'1600',
'1630',
'1700',
'1730',
],
};

export const toTimeLabel = (time: string): string => `${time.slice(0, 2)}:${time.slice(2)}`;

export const filterTimeOptions = (
timeOptions: string[],
selectedTime: string,
filter: 'greater' | 'lesser',
) =>
filter === 'greater'
? timeOptions.filter((option) => option > selectedTime)
: timeOptions.filter((option) => option < selectedTime);
140 changes: 51 additions & 89 deletions website/src/views/optimiser/OptimiserForm.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import React, { useCallback } from 'react';
import React, { useCallback, useState } from 'react';
import classnames from 'classnames';
import { Info, X, AlertTriangle } from 'react-feather';
import Tooltip from 'views/components/Tooltip';
import { WorkingDays, Day } from 'types/modules';
import { LessonOption, FreeDayConflict } from './types';
import styles from './OptimiserForm.scss';
import { TIME_OPTIONS, filterTimeOptions, toTimeLabel } from '../../utils/timeOptions';

interface OptimiserFormProps {
lessonOptions: LessonOption[];
Expand Down Expand Up @@ -59,6 +60,11 @@ const OptimiserForm: React.FC<OptimiserFormProps> = ({
[onToggleFreeDay],
);

const [classStartTimes, setClassStartTimes] = useState(TIME_OPTIONS.START_CLASS);
const [classEndTimes, setClassEndTimes] = useState(TIME_OPTIONS.END_CLASS);
const [lunchStartTimes, setLunchStartTimes] = useState(TIME_OPTIONS.START_LUNCH);
const [lunchEndTimes, setLunchEndTimes] = useState(TIME_OPTIONS.END_LUNCH);

return (
<div className={styles.mainContent}>
<div className={styles.sectionHeader}>
Expand Down Expand Up @@ -216,36 +222,18 @@ const OptimiserForm: React.FC<OptimiserFormProps> = ({
<select
className={classnames('form-select', styles.timeSelect)}
value={earliestTime}
onChange={(e) => onEarliestTimeChange(e.target.value)}
onChange={(e) => {
onEarliestTimeChange(e.target.value);
setClassEndTimes(
filterTimeOptions(TIME_OPTIONS.END_CLASS, e.target.value, 'greater'),
);
}}
>
<option value="0800">08:00</option>
<option value="0830">08:30</option>
<option value="0900">09:00</option>
<option value="0930">09:30</option>
<option value="1000">10:00</option>
<option value="1030">10:30</option>
<option value="1100">11:00</option>
<option value="1130">11:30</option>
<option value="1200">12:00</option>
<option value="1230">12:30</option>
<option value="1300">13:00</option>
<option value="1330">13:30</option>
<option value="1400">14:00</option>
<option value="1430">14:30</option>
<option value="1500">15:00</option>
<option value="1530">15:30</option>
<option value="1600">16:00</option>
<option value="1630">16:30</option>
<option value="1700">17:00</option>
<option value="1800">18:00</option>
<option value="1830">18:30</option>
<option value="1900">19:00</option>
<option value="1930">19:30</option>
<option value="2000">20:00</option>
<option value="2030">20:30</option>
<option value="2100">21:00</option>
<option value="2130">21:30</option>
<option value="2200">22:00</option>
{classStartTimes.map((time) => (
<option key={time} value={time}>
{toTimeLabel(time)}
</option>
))}
</select>
</div>
</div>
Expand All @@ -260,36 +248,18 @@ const OptimiserForm: React.FC<OptimiserFormProps> = ({
<select
className={classnames('form-select', styles.timeSelect)}
value={latestTime}
onChange={(e) => onLatestTimeChange(e.target.value)}
onChange={(e) => {
onLatestTimeChange(e.target.value);
setClassStartTimes(
filterTimeOptions(TIME_OPTIONS.START_CLASS, e.target.value, 'lesser'),
);
}}
>
<option value="0900">09:00</option>
<option value="0930">09:30</option>
<option value="1000">10:00</option>
<option value="1030">10:30</option>
<option value="1100">11:00</option>
<option value="1130">11:30</option>
<option value="1200">12:00</option>
<option value="1230">12:30</option>
<option value="1300">13:00</option>
<option value="1330">13:30</option>
<option value="1400">14:00</option>
<option value="1430">14:30</option>
<option value="1500">15:00</option>
<option value="1530">15:30</option>
<option value="1600">16:00</option>
<option value="1630">16:30</option>
<option value="1700">17:00</option>
<option value="1800">18:00</option>
<option value="1830">18:30</option>
<option value="1900">19:00</option>
<option value="1930">19:30</option>
<option value="2000">20:00</option>
<option value="2030">20:30</option>
<option value="2100">21:00</option>
<option value="2130">21:30</option>
<option value="2200">22:00</option>
<option value="2230">22:30</option>
<option value="2300">23:00</option>
{classEndTimes.map((time) => (
<option key={time} value={time}>
{toTimeLabel(time)}
</option>
))}
</select>
</div>
</div>
Expand Down Expand Up @@ -344,43 +314,35 @@ const OptimiserForm: React.FC<OptimiserFormProps> = ({
<select
className={classnames('form-select', styles.timeSelect)}
value={earliestLunchTime}
onChange={(e) => onEarliestLunchTimeChange(e.target.value)}
onChange={(e) => {
onEarliestLunchTimeChange(e.target.value);
setLunchEndTimes(
filterTimeOptions(TIME_OPTIONS.END_LUNCH, e.target.value, 'greater'),
);
}}
>
<option value="1000">10:00</option>
<option value="1030">10:30</option>
<option value="1100">11:00</option>
<option value="1130">11:30</option>
<option value="1200">12:00</option>
<option value="1230">12:30</option>
<option value="1300">13:00</option>
<option value="1330">13:30</option>
<option value="1400">14:00</option>
<option value="1430">14:30</option>
<option value="1500">15:00</option>
<option value="1530">15:30</option>
<option value="1600">16:00</option>
<option value="1630">16:30</option>
{lunchStartTimes.map((time) => (
<option key={time} value={time}>
{toTimeLabel(time)}
</option>
))}
</select>
<div className={styles.lunchTimeSeparator}>to</div>
<select
className={classnames('form-select', styles.timeSelect)}
value={latestLunchTime}
onChange={(e) => onLatestLunchTimeChange(e.target.value)}
onChange={(e) => {
onLatestLunchTimeChange(e.target.value);
setLunchStartTimes(
filterTimeOptions(TIME_OPTIONS.START_LUNCH, e.target.value, 'lesser'),
);
}}
>
<option value="1100">11:00</option>
<option value="1130">11:30</option>
<option value="1200">12:00</option>
<option value="1230">12:30</option>
<option value="1300">13:00</option>
<option value="1330">13:30</option>
<option value="1400">14:00</option>
<option value="1430">14:30</option>
<option value="1500">15:00</option>
<option value="1530">15:30</option>
<option value="1600">16:00</option>
<option value="1630">16:30</option>
<option value="1700">17:00</option>
<option value="1730">17:30</option>
{lunchEndTimes.map((time) => (
<option key={time} value={time}>
{toTimeLabel(time)}
</option>
))}
</select>
</div>
</div>
Expand Down