Skip to content

Commit

Permalink
Extract RouteScheduleTable component from ScheduleAccordionItem
Browse files Browse the repository at this point in the history
...and use it on the schedule page. By extracting the inner component from the accordion item, we decouple some implementation details of the Flowbite accordion from this piece of UI, and allow ourselves to further reuse it elsewhere if and when we need to.

This commit is a WIP.

- [ ] Show all routes/Collapse all routes buttons aren't working
- [ ] Sticky route schedule headers have a gap above them
- [ ] The datepicker appears behind the sticky headers
- [ ] All schedules should be expanded by default
  • Loading branch information
aaronbrethorst committed Nov 25, 2024
1 parent eb3cbce commit a30d93f
Show file tree
Hide file tree
Showing 3 changed files with 116 additions and 122 deletions.
108 changes: 108 additions & 0 deletions src/components/schedule-for-stop/RouteScheduleTable.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
<script>
import { createEventDispatcher } from 'svelte';
import { t } from 'svelte-i18n';
export let schedule;
export let expanded;

Check failure on line 6 in src/components/schedule-for-stop/RouteScheduleTable.svelte

View workflow job for this annotation

GitHub Actions / lint

Component has unused export property 'expanded'. If it is for external reference only, please consider using `export const expanded`(unused-export-let)
const dispatch = createEventDispatcher();
function handleToggle() {

Check failure on line 10 in src/components/schedule-for-stop/RouteScheduleTable.svelte

View workflow job for this annotation

GitHub Actions / lint

'handleToggle' is defined but never used
dispatch('toggle');
}
function formatHour(hour) {
const hourInt = +hour;
if (hourInt === 0) return '12';
if (hourInt > 12) return hourInt - 12;
return hourInt;
}
function renderScheduleTable(schedule) {
const stopTimes = Object.entries(schedule.stopTimes);
const amTimes = stopTimes.filter(([hour]) => +hour < 12);
const pmTimes = stopTimes.filter(([hour]) => +hour >= 12);
return {
amTimes,
pmTimes
};
}
function extractMinutes(arrivalTime) {
return arrivalTime.replace(/[AP]M/, '').split(':')[1];
}
</script>

<div class="overflow-x-auto">
<table class="mt-4 w-full table-auto rounded-lg border border-gray-200 shadow-lg">
<thead class="bg-gray-100 text-gray-800">
<tr>
<th class="cursor-pointer px-6 py-3 text-left">{$t('schedule_for_stop.hour')}</th>
<th class="cursor-pointer px-6 py-3 text-left">{$t('schedule_for_stop.minutes')}</th>
</tr>
</thead>
<tbody>
<tr class="bg-gray-50 hover:bg-gray-100">
<td colspan="2" class="px-6 py-3 font-semibold text-gray-700">AM</td>
</tr>
{#if renderScheduleTable(schedule).amTimes.length === 0}
<tr>
<td colspan="2" class="border px-6 py-3 text-center text-gray-500">
{$t('schedule_for_stop.no_am_schedules_available')}
</td>
</tr>
{:else}
{#each renderScheduleTable(schedule).amTimes as [hour, times]}
<tr class="hover:bg-gray-100">
<td
class="border px-6 py-3 text-center text-lg font-semibold"
title="Full Time: {hour}:{extractMinutes(times[0].arrivalTime)}"
>
{formatHour(hour)} <span class="text-sm text-gray-600">AM</span>
</td>
<td class="border px-6 py-3 text-lg">
{#each times as stopTime, index (index)}
<span>
{extractMinutes(stopTime.arrivalTime)}
{index < times.length - 1 ? ', ' : ''}
</span>
{/each}
</td>
</tr>
{/each}
{/if}

<tr class="bg-gray-50 hover:bg-gray-100">
<td colspan="2" class="px-6 py-3 font-semibold text-gray-700">PM</td>
</tr>
{#if renderScheduleTable(schedule).pmTimes.length === 0}
<tr>
<td colspan="2" class="border px-6 py-3 text-center text-gray-500">
{$t('schedule_for_stop.no_pm_schedules_available')}
</td>
</tr>
{:else}
{#each renderScheduleTable(schedule).pmTimes as [hour, times]}
<tr class="hover:bg-gray-100">
<td
class="border px-6 py-3 text-center text-lg font-semibold"
title="Full Time: {hour}:{extractMinutes(times[0].arrivalTime)}"
>
{formatHour(hour)} <span class="text-sm text-gray-600">PM</span>
</td>
<td class="border px-6 py-3 text-lg">
{#each times as stopTime, index (index)}
<span>
{extractMinutes(stopTime.arrivalTime)}
{index < times.length - 1 ? ', ' : ''}
</span>
{/each}
</td>
</tr>
{/each}
{/if}
</tbody>
</table>
</div>
114 changes: 0 additions & 114 deletions src/components/schedule-for-stop/ScheduleAccordionItem.svelte

This file was deleted.

16 changes: 8 additions & 8 deletions src/routes/stops/[stopID]/schedule/+page.svelte
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
<script>
import { page } from '$app/stores';
import LoadingSpinner from '$components/LoadingSpinner.svelte';
import ScheduleAccordionItem from '$components/schedule-for-stop/ScheduleAccordionItem.svelte';
import RouteScheduleTable from '$components/schedule-for-stop/RouteScheduleTable.svelte';
import StopPageHeader from '$components/stops/StopPageHeader.svelte';
import StandalonePage from '$components/StandalonePage.svelte';
import { formatTime } from '$lib/formatters.js';
import { Accordion } from 'flowbite-svelte';
import Accordion from '$components/containers/Accordion.svelte';
import AccordionItem from '$components/containers/AccordionItem.svelte';
import { Datepicker } from 'flowbite-svelte';
import { onMount } from 'svelte';
import { isLoading } from 'svelte-i18n';
Expand Down Expand Up @@ -165,13 +166,12 @@
{$t('schedule_for_stop.no_schedules_available')}
</p>
{:else}
<Accordion flush multiple>
<Accordion>
{#each schedules as schedule, index (schedule.tripHeadsign)}

Check failure on line 170 in src/routes/stops/[stopID]/schedule/+page.svelte

View workflow job for this annotation

GitHub Actions / lint

'index' is defined but never used
<ScheduleAccordionItem
{schedule}
expanded={expandedItems[index]}
on:toggle={() => toggleAccordion(index)}
/>
<AccordionItem>
<span slot="header">{schedule.tripHeadsign}</span>
<RouteScheduleTable {schedule} />
</AccordionItem>
{/each}
</Accordion>
{/if}
Expand Down

0 comments on commit a30d93f

Please sign in to comment.