Skip to content

Commit

Permalink
feat: add tracks
Browse files Browse the repository at this point in the history
This adds the ability to specify a track or room for a session
so there can be multiple sessions in parallel
  • Loading branch information
coderbyheart committed Aug 24, 2022
1 parent 0d199e8 commit 42ef87a
Show file tree
Hide file tree
Showing 5 changed files with 222 additions and 162 deletions.
23 changes: 15 additions & 8 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,13 @@ if (typeof window.matchMedia === 'function') {
defaultTheme = match.matches ? Theme.dark : Theme.light
}

export type Sessions = Record<string, string>

export type Schedule = {
name: string
day: string
tz: string
sessions: Record<number, string>
sessions: Sessions
hidePastSessions: boolean
}

Expand All @@ -46,6 +48,7 @@ export const App = () => {
1430: 'Session 3',
1530: 'Coffee Break',
1545: 'Session 4',
'1545@Main hall': `You can have sessions at the same time, too!`,
1645: 'Coffee Break',
1700: 'Closing & Retro',
1730: 'Dinner Break',
Expand Down Expand Up @@ -137,17 +140,21 @@ export const App = () => {
</div>
<Editor
onAdd={(add) => {
updateSessions((sessions) => ({
...sessions,
[parseInt(`${add.hour}${add.minute}`, 10)]: `${add.name}${
add.url === '' ? '' : `|${add.url.toString()}`
}`,
}))
updateSessions((sessions) => {
let time = parseInt(`${add.hour}${add.minute}`, 10).toString()
if (add.track.length > 0) time = `${time}@${add.track}`
return {
...sessions,
[time]: `${add.name}${
add.url === '' ? '' : `|${add.url.toString()}`
}`,
}
})
}}
onDelete={(time) => {
updateSessions((sessions) => {
const s = { ...sessions }
delete (s as { [key: number]: string })[time]
delete (s as { [key: string]: string })[time]
return s
})
}}
Expand Down
238 changes: 136 additions & 102 deletions src/Editor.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import type { Sessions } from 'app/App'
import { AddIcon, DeleteIcon } from 'app/FeatherIcons'
import formStyles from 'app/Form.module.css'
import { SessionName } from 'app/SessionName'
Expand All @@ -10,6 +11,7 @@ type AddSession = {
hour: string
minute: string
url: string
track: string
}

const toNumber = (n: string) => {
Expand All @@ -31,15 +33,16 @@ export const Editor = ({
}: {
conferenceDate: string
eventTimezoneName: string
sessions: { [key: number]: string }
sessions: Sessions
onAdd: (newSession: AddSession) => void
onDelete: (time: number) => void
onDelete: (timeWithTrackA: string) => void
}) => {
const [add, updateAdd] = useState<AddSession>({
name: '',
hour: '19',
minute: '45',
url: '',
track: '',
})
const inputRef = useRef<HTMLInputElement>(null)
const isInputValid = () => {
Expand Down Expand Up @@ -67,12 +70,13 @@ export const Editor = ({
...add,
name: '',
url: '',
track: '',
})
inputRef.current?.focus()
}

return (
<>
<form className={formStyles.Form}>
<table className={tableStyles.Table}>
<thead>
<tr>
Expand All @@ -95,113 +99,143 @@ export const Editor = ({
</button>
</td>
<td className="time">
<input
className={formStyles.NumberInput}
ref={inputRef}
type="text"
inputMode="numeric"
value={add.hour}
onChange={({ target: { value } }) => {
updateAdd({
...add,
hour: value,
})
}}
name="session-hour"
/>
{':'}
<input
className={formStyles.NumberInput}
type="text"
inputMode="numeric"
value={add.minute}
onChange={({ target: { value } }) => {
updateAdd({
...add,
minute: value,
})
}}
name="session-minute"
/>
<fieldset>
<legend>Local time</legend>
<input
className={formStyles.NumberInput}
ref={inputRef}
type="text"
inputMode="numeric"
value={add.hour}
onChange={({ target: { value } }) => {
updateAdd({
...add,
hour: value,
})
}}
name="session-hour"
maxLength={2}
/>
{':'}
<input
className={formStyles.NumberInput}
type="text"
inputMode="numeric"
value={add.minute}
onChange={({ target: { value } }) => {
updateAdd({
...add,
minute: value,
})
}}
name="session-minute"
maxLength={2}
/>
</fieldset>
<fieldset>
<label htmlFor="track">Track/Room</label>
<input
className={formStyles.TextInput}
type="text"
value={add.track ?? ''}
id={'track'}
onChange={({ target: { value } }) =>
updateAdd({
...add,
track: value,
})
}
placeholder='e.g. "Main room"'
name="session-track"
/>
</fieldset>
</td>
<td>
<form className={formStyles.Form}>
<fieldset>
<label htmlFor="name">Session name</label>
<input
className={formStyles.TextInput}
type="text"
value={add.name}
id={'name'}
onKeyUp={({ key }) => {
if (key === 'Enter') {
if (isInputValid()) {
addAction(add)
onAdd(add)
}
<fieldset>
<label htmlFor="name">Session name</label>
<input
className={formStyles.TextInput}
type="text"
value={add.name}
id={'name'}
onKeyUp={({ key }) => {
if (key === 'Enter') {
if (isInputValid()) {
addAction(add)
onAdd(add)
}
}}
onChange={({ target: { value } }) =>
updateAdd({
...add,
name: value,
})
}
placeholder='e.g. "Intro Session"'
name="session-name"
/>
</fieldset>
<fieldset>
<label htmlFor="url">
Optional: URL to use as a hyperlink.
</label>
<input
className={formStyles.TextInput}
type="url"
id="url"
value={add.url ?? ''}
onChange={({ target: { value } }) =>
updateAdd({
...add,
url: value,
})
}
onKeyUp={({ key }) => {
if (key === 'Enter') {
if (isInputValid()) {
addAction(add)
onAdd(add)
}
}}
onChange={({ target: { value } }) =>
updateAdd({
...add,
name: value,
})
}
placeholder='e.g. "Intro Session"'
name="session-name"
/>
</fieldset>
<fieldset>
<label htmlFor="url">
Optional: URL to use as a hyperlink.
</label>
<input
className={formStyles.TextInput}
type="url"
id="url"
value={add.url ?? ''}
onChange={({ target: { value } }) =>
updateAdd({
...add,
url: value,
})
}
onKeyUp={({ key }) => {
if (key === 'Enter') {
if (isInputValid()) {
addAction(add)
onAdd(add)
}
}}
placeholder='e.g. "https://example.com/"'
/>
</fieldset>
</form>
}
}}
placeholder='e.g. "https://example.com/"'
/>
</fieldset>
</td>
</tr>
{Object.entries(sessions).map(([time, name]) => (
<tr key={time}>
<td>
<button
className={formStyles.DeleteButton}
onClick={() => {
onDelete(time as unknown as number)
}}
>
<DeleteIcon />
</button>
</td>
<td className={'time'}>
{formatEventTime(eventTime(time as unknown as number))}
</td>
<td>
<SessionName name={name} />
</td>
</tr>
))}
{Object.entries(sessions)
.sort(
([timeWithTrackA], [timeWithTrackB]) =>
parseInt(timeWithTrackA.split('@')[0]) -
parseInt(timeWithTrackB.split('@')[0]),
)
.map(([timeWithTrack, name]) => {
const [time, track] = timeWithTrack.split('@')
return (
<tr key={timeWithTrack}>
<td>
<button
className={formStyles.DeleteButton}
onClick={() => {
onDelete(timeWithTrack)
}}
>
<DeleteIcon />
</button>
</td>
<td className={'time'}>
{formatEventTime(eventTime(parseInt(time, 10)))}
{track === undefined ? '' : ` @ ${track}`}
</td>
<td>
<SessionName name={name} />
</td>
</tr>
)
})}
</tbody>
</table>
</>
</form>
)
}
15 changes: 12 additions & 3 deletions src/Schedule.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -105,14 +105,21 @@ export const Schedule = ({
{formatTimezone(userTimeZone)} ({userFormat(currentTime)})
</small>
</th>
<th>Track/Room</th>
<th>Starts in</th>
<th>Session</th>
</tr>
</thead>
<tbody>
{Object.entries(sessions)
.sort(
([timeWithTrackA], [timeWithTrackB]) =>
parseInt(timeWithTrackA.split('@')[0]) -
parseInt(timeWithTrackB.split('@')[0]),
)
.map((session, i, sessions) => {
const time = session[0] as unknown as number
const timeWithTrack = session[0]
const time = parseInt(timeWithTrack.split('@')[0])

const nextIsOngoing =
sessions[i + 1] !== undefined
Expand All @@ -127,15 +134,17 @@ export const Schedule = ({
return { session, isPast, isOngoing }
})
.filter(({ isPast }) => (hidePastSessions ? !isPast : true))
.map(({ session: [time, name], isOngoing }) => {
.map(({ session: [timeWithTrack, name], isOngoing }) => {
const [time, track] = timeWithTrack.split('@')
return (
<tr key={time} className={isOngoing ? 'ongoing' : ''}>
<tr key={timeWithTrack} className={isOngoing ? 'ongoing' : ''}>
<td className={'time'}>
{formatEventTime(eventTime(time as unknown as number))}
</td>
<td className={'time'}>
{userFormat(userTime(time as unknown as number))}
</td>
<td>{track ?? '—'}</td>
{isOngoing && (
<td>
<em>ongoing</em>
Expand Down
4 changes: 4 additions & 0 deletions src/Table.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,10 @@
width: 10%;
white-space: nowrap;
}
.Table td:global(.time) legend {
text-align: left;
margin-bottom: 0.5rem;
}
.Table td:global(.hot) {
background-color: var(--color-countdownWarning);
}
Expand Down
Loading

0 comments on commit 42ef87a

Please sign in to comment.