Skip to content

Commit 6942a95

Browse files
committed
classrooms: WIP better date picker design?
1 parent 2c78d5f commit 6942a95

File tree

10 files changed

+288
-76
lines changed

10 files changed

+288
-76
lines changed
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
/** @jsxImportSource preact */
2+
/// <reference no-default-lib="true"/>
3+
/// <reference lib="dom" />
4+
/// <reference lib="deno.ns" />
5+
6+
import { ComponentChildren } from 'preact'
7+
8+
export type AbbrevHeadingProps = {
9+
heading: 'h1' | 'h2' | 'h3'
10+
abbrev?: ComponentChildren
11+
children?: ComponentChildren
12+
class?: string
13+
}
14+
export function AbbrevHeading ({
15+
heading: Heading,
16+
abbrev,
17+
children,
18+
class: className = ''
19+
}: AbbrevHeadingProps) {
20+
return (
21+
<Heading class={`abbrev-heading ${className}`}>
22+
<span class='abbrev'>{abbrev}</span>
23+
<span class='colon'>: </span>
24+
<span class='long'>{children}</span>
25+
</Heading>
26+
)
27+
}

classrooms/components/date-time/Calendar.tsx

Lines changed: 3 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -114,28 +114,9 @@ export function Calendar ({ date, onDate, scrollToDate }: CalendarProps) {
114114
}
115115

116116
return (
117-
<div class='calendar'>
118-
<div class='date-time-flex'>
119-
<input
120-
type='date'
121-
name='date'
122-
value={date.toString()}
123-
onInput={e => {
124-
const date = Day.parse(e.currentTarget.value)
125-
if (date) {
126-
onDate(date, true)
127-
}
128-
}}
129-
class='date-input'
130-
/>
131-
<button class='today-btn' onClick={() => onDate(Day.today(), true)}>
132-
Today
133-
</button>
134-
</div>
135-
<div class='calendar-scroll-area'>
136-
<CalendarHeaderRow />
137-
{calendars}
138-
</div>
117+
<div class='calendar-scroll-area'>
118+
<CalendarHeaderRow />
119+
{calendars}
139120
</div>
140121
)
141122
}

classrooms/components/date-time/CalendarRow.tsx

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { ComponentChildren } from 'preact'
77
import { useEffect, useRef } from 'preact/hooks'
88
import { Season, termCode, TermDays, termName } from '../../../terms/index.ts'
99
import { Day, DAY_NUMS } from '../../../util/Day.ts'
10+
import { AbbrevHeading } from '../AbbrevHeading.tsx'
1011

1112
export type CalendarHeaderRowProps = {}
1213
export function CalendarHeaderRow ({}: CalendarHeaderRowProps) {
@@ -51,9 +52,13 @@ export function CalendarQuarterHeadingRow ({
5152
}: CalendarQuarterHeadingRowProps) {
5253
return (
5354
<CalendarHeadingRow class='calendar-quarter-heading-row'>
54-
<h2 class='calendar-heading calendar-quarter-heading'>
55-
{termCode(year, season)}: {termName(year, season)}
56-
</h2>
55+
<AbbrevHeading
56+
heading='h2'
57+
abbrev={termCode(year, season)}
58+
class='calendar-heading calendar-quarter-heading'
59+
>
60+
{termName(year, season)}
61+
</AbbrevHeading>
5762
</CalendarHeadingRow>
5863
)
5964
}
@@ -74,7 +79,7 @@ export function CalendarMonthHeadingRow ({
7479
}
7580

7681
/** Height of the calendar header. */
77-
const HEADER_HEIGHT = 90
82+
const HEADER_HEIGHT = 110
7883

7984
export type CalendarRowProps = {
8085
termDays: TermDays
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
/** @jsxImportSource preact */
2+
/// <reference no-default-lib="true"/>
3+
/// <reference lib="dom" />
4+
/// <reference lib="deno.ns" />
5+
6+
import { getTerm, termCode } from '../../../terms/index.ts'
7+
import { Day } from '../../../util/Day.ts'
8+
import { Time } from '../../../util/Time.ts'
9+
10+
export type DateTimeButtonProps = {
11+
date: Day
12+
time: Time
13+
onClick: () => void
14+
disabled: boolean
15+
}
16+
export function DateTimeButton ({
17+
date,
18+
time,
19+
onClick,
20+
disabled
21+
}: DateTimeButtonProps) {
22+
const { year, season, current, week } = getTerm(date)
23+
return (
24+
<button class='date-time-button' onClick={onClick} disabled={disabled}>
25+
<p class='showing-schedule-wrapper'>
26+
<span class='showing-schedule-text'>Showing schedule for</span>
27+
<div class='date-time'>
28+
<span class='date'>{date.toString()}</span>
29+
<span class='time'>{time.toString()}</span>
30+
</div>
31+
{current && (
32+
<span class='quarter-week'>
33+
{termCode(year, season)} Week {week}{' '}
34+
{date.dayName('short', 'en-US')}
35+
</span>
36+
)}
37+
</p>
38+
<div class='icon-btn edit-icon'>Edit</div>
39+
</button>
40+
)
41+
}

classrooms/components/date-time/DateTimePicker.tsx renamed to classrooms/components/date-time/DateTimePanel.tsx

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,24 +7,48 @@ import { Day } from '../../../util/Day.ts'
77
import { Time } from '../../../util/Time.ts'
88
import { Calendar } from './Calendar.tsx'
99

10-
export type DateTimePickerProps = {
10+
export type DateTimePanelProps = {
1111
date: Day
1212
onDate: (date: Day, scrollToDate?: boolean) => void
1313
scrollToDate: number | null
1414
realTime: Time
1515
customTime: Time | null
1616
onCustomTime: (customTime: Time | null) => void
17+
visible: boolean
18+
onClose: () => void
1719
}
18-
export function DateTimePicker ({
20+
export function DateTimePanel ({
1921
date,
2022
onDate,
2123
scrollToDate,
2224
realTime,
2325
customTime,
24-
onCustomTime
25-
}: DateTimePickerProps) {
26+
onCustomTime,
27+
visible,
28+
onClose
29+
}: DateTimePanelProps) {
2630
return (
27-
<div class='date-time-picker'>
31+
<div class={`date-time-picker ${visible ? '' : 'date-time-picker-hidden'}`}>
32+
<div class='date-time-flex'>
33+
<input
34+
type='date'
35+
name='date'
36+
value={date.toString()}
37+
onInput={e => {
38+
const date = Day.parse(e.currentTarget.value)
39+
if (date) {
40+
onDate(date, true)
41+
}
42+
}}
43+
class='date-input'
44+
/>
45+
<button class='today-btn' onClick={() => onDate(Day.today(), true)}>
46+
Today
47+
</button>
48+
<button class='icon-btn close-date-btn' onClick={onClose}>
49+
Close
50+
</button>
51+
</div>
2852
<Calendar date={date} onDate={onDate} scrollToDate={scrollToDate} />
2953
<div class='date-time-flex'>
3054
<label class='checkbox-label'>

classrooms/index.tsx

Lines changed: 28 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ import { Day } from '../util/Day.ts'
1010
import { Time } from '../util/Time.ts'
1111
import { useAsyncEffect } from '../util/useAsyncEffect.ts'
1212
import { BuildingButton } from './components/BuildingButton.tsx'
13-
import { Calendar } from './components/date-time/Calendar.tsx'
14-
import { DateTimePicker } from './components/date-time/DateTimePicker.tsx'
13+
import { DateTimeButton } from './components/date-time/DateTimeButton.tsx'
14+
import { DateTimePanel } from './components/date-time/DateTimePanel.tsx'
1515
import { InfoPanel } from './components/InfoPanel.tsx'
1616
import { RoomList } from './components/RoomList.tsx'
1717
import {
@@ -29,6 +29,7 @@ import { QuarterCache } from './lib/QuarterCache.ts'
2929

3030
function App () {
3131
const quarters = useRef(new QuarterCache())
32+
const [showDate, setShowDate] = useState(false)
3233
const [date, setDate] = useState(Day.today())
3334
const [customTime, setCustomTime] = useState<Time | null>(null)
3435
const [scrollToDate, setScrollToDate] = useState<number | null>(1)
@@ -98,24 +99,32 @@ function App () {
9899

99100
return (
100101
<>
102+
<DateTimeButton
103+
date={date}
104+
time={currentTime.time}
105+
onClick={() => setShowDate(true)}
106+
disabled={showDate}
107+
/>
108+
<DateTimePanel
109+
date={date}
110+
onDate={(date, scrollToDate) => {
111+
setDate(date)
112+
if (scrollToDate) {
113+
// Force useEffect to run again, if necessary. Start counting from 2
114+
// to reserve `scrollToDate = 1` to mean "app just loaded"
115+
setScrollToDate(scrollToDate => (scrollToDate ?? 1) + 1)
116+
} else {
117+
setScrollToDate(null)
118+
}
119+
}}
120+
scrollToDate={scrollToDate}
121+
realTime={realTime}
122+
customTime={customTime}
123+
onCustomTime={setCustomTime}
124+
visible={showDate}
125+
onClose={() => setShowDate(false)}
126+
/>
101127
<div class='buildings-wrapper'>
102-
<DateTimePicker
103-
date={date}
104-
onDate={(date, scrollToDate) => {
105-
setDate(date)
106-
if (scrollToDate) {
107-
// Force useEffect to run again, if necessary. Start counting from 2
108-
// to reserve `scrollToDate = 1` to mean "app just loaded"
109-
setScrollToDate(scrollToDate => (scrollToDate ?? 1) + 1)
110-
} else {
111-
setScrollToDate(null)
112-
}
113-
}}
114-
scrollToDate={scrollToDate}
115-
realTime={realTime}
116-
customTime={customTime}
117-
onCustomTime={setCustomTime}
118-
/>
119128
<p class={`notice ${noticeVisible ? 'notice-visible' : ''}`}>
120129
<span class='notice-text'>{notice}</span>
121130
</p>

0 commit comments

Comments
 (0)