Skip to content

Commit

Permalink
feat: chronological ordering (#62)
Browse files Browse the repository at this point in the history
* remove status bage from grid page, change text size on mobile

* Fixing typing and colors

* Adding emojis for headers

---------

Co-authored-by: Devin Matte <[email protected]>
  • Loading branch information
skaplan-dev and devinmatte authored May 28, 2024
1 parent 0cb6b4f commit 6287128
Show file tree
Hide file tree
Showing 6 changed files with 112 additions and 63 deletions.
2 changes: 1 addition & 1 deletion src/components/LineGraph.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ export const LineGraph: React.FunctionComponent<LineGraphProps> = ({ line: selec
x: {
type: 'time',
min:
range === 'future'
range === 'upcoming'
? dayjs(new Date()).toISOString()
: dayjs(new Date(2023, 11, 1)).toISOString(),
max:
Expand Down
46 changes: 24 additions & 22 deletions src/components/RangeButtons.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import { capitalize, colorToStyle } from '../styles';
const RANGE_ICONS = {
all: <PlayIcon className="h-4 md:h-5 w-4 md:w-5 text-white" />,
past: <BackwardIcon className="h-4 md:h-5 w-4 md:w-5 text-white" />,
future: <ForwardIcon className="h-4 md:h-5 w-4 md:w-5 text-white" />,
upcoming: <ForwardIcon className="h-4 md:h-5 w-4 md:w-5 text-white" />,
};

export const RangeButtons = () => {
Expand Down Expand Up @@ -42,27 +42,29 @@ export const RangeButtons = () => {
leaveTo="transform scale-95 opacity-0"
>
<ListboxOptions className={'md:absolute md:z-10'}>
{(['all', 'past', 'future'] as ('all' | 'past' | 'future')[]).map((selectedRange) => (
<ListboxOption
key={`button-range-${selectedRange}`}
value={selectedRange}
className={classNames(
'border-1',
colorToStyle['all'].bg,
`md:uppercase px-3 py-1 m-2 hover:ring-2`,
`rounded text-white`,
colorToStyle['all'].hover,
'hover:scale-105',
'transition ease-in-out cursor-pointer'
)}
onClick={() => setRange(selectedRange)}
>
<span className="flex flex-row gap-1">
{RANGE_ICONS[selectedRange]}
{`${capitalize(selectedRange)} shutdowns`}
</span>
</ListboxOption>
))}
{(['all', 'past', 'upcoming'] as ('all' | 'past' | 'upcoming')[]).map(
(selectedRange) => (
<ListboxOption
key={`button-range-${selectedRange}`}
value={selectedRange}
className={classNames(
'border-1',
colorToStyle['all'].bg,
`md:uppercase px-3 py-1 m-2 hover:ring-2`,
`rounded text-white`,
colorToStyle['all'].hover,
'hover:scale-105',
'transition ease-in-out cursor-pointer'
)}
onClick={() => setRange(selectedRange)}
>
<span className="flex flex-row gap-1">
{RANGE_ICONS[selectedRange]}
{`${capitalize(selectedRange)} shutdowns`}
</span>
</ListboxOption>
)
)}
</ListboxOptions>
</Transition>
</Listbox>
Expand Down
6 changes: 3 additions & 3 deletions src/components/Shutdowns/ChartContainer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ const ChartContainer = ({ before, after, line, shutdown, title }: ChartContainer
{!isMobile ? 'Before' : 'Before shutdown'}
</dt>
<dd className="mt-1 text-xl md:text-3xl font-semibold tracking-tight">
{getFormattedTimeValue(beforeAvg, true)}
{getFormattedTimeValue(beforeAvg, !!isMobile)}
</dd>
</div>
<div className={`flex flex-col flex-1 ${cardStyles} justify-center text-center`}>
Expand All @@ -61,13 +61,13 @@ const ChartContainer = ({ before, after, line, shutdown, title }: ChartContainer
{!isMobile ? 'After' : 'After shutdown'}
</dt>
<dd className="mt-1 text-xl md:text-3xl font-semibold tracking-tight">
{getFormattedTimeValue(afterAvg, true)}
{getFormattedTimeValue(afterAvg, !!isMobile)}
</dd>
</div>
<div className={`flex flex-col flex-1 ${cardStyles} justify-center text-center`}>
<dt className="md:truncate text-sm font-medium text-gray-700 dark:text-white">Change</dt>
<dd className="mt-1 text-xl md:text-3xl font-semibold tracking-tight">
{getFormattedTimeValue(difference, true, direction)}
{getFormattedTimeValue(difference, !!isMobile, direction)}
</dd>
</div>
</div>
Expand Down
112 changes: 81 additions & 31 deletions src/components/Shutdowns/ShutdownContainer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,39 +13,89 @@ export const ShutdownCards: React.FunctionComponent<ShutdownCardsProps> = ({
}) => {
const { range } = useStore();

const mappedShutdowns = useMemo(
() =>
Object.entries(shutdowns)
.filter(([line]) => line === selectedLine || selectedLine === 'all')
.map(([line, shutdowns]) =>
shutdowns
.filter((sd) => {
if (range === 'past') {
return (
dayjs(sd.stop_date).isBefore(dayjs(), 'day') ||
dayjs(sd.stop_date).isSame(dayjs(), 'day')
);
} else if (range === 'future') {
return (
dayjs(sd.start_date).isAfter(dayjs(), 'day') ||
dayjs(sd.stop_date).isSame(dayjs(), 'day')
);
const groupedAndSortedShutdowns = useMemo(() => {
const now = dayjs();

const shutdownsByGroup = Object.entries(shutdowns)
.filter(([line]) => line === selectedLine || selectedLine === 'all')
.reduce<{
active: { card: JSX.Element; date: dayjs.Dayjs }[];
upcoming: { card: JSX.Element; date: dayjs.Dayjs }[];
completed: { card: JSX.Element; date: dayjs.Dayjs }[];
}>(
(acc, [line, shutdownList]) => {
shutdownList.forEach((sd, index) => {
if (
(range === 'past' &&
(dayjs(sd.stop_date).isBefore(now, 'day') ||
dayjs(sd.stop_date).isSame(now, 'day'))) ||
(range === 'upcoming' &&
(dayjs(sd.start_date).isAfter(now, 'day') ||
dayjs(sd.stop_date).isSame(now, 'day'))) ||
range === 'all'
) {
const shutdownCard = (
<ShutdownCard
key={`${line}-${sd.start_date}-${sd.stop_date}-${index}`}
line={line as Lines}
shutdown={sd}
/>
);

if (dayjs(sd.start_date).isAfter(now, 'day')) {
acc.upcoming.push({ card: shutdownCard, date: dayjs(sd.start_date) });
} else if (dayjs(sd.stop_date).isBefore(now, 'day')) {
acc.completed.push({ card: shutdownCard, date: dayjs(sd.start_date) });
} else {
acc.active.push({ card: shutdownCard, date: dayjs(sd.start_date) });
}
return true;
})
.sort((a, b) => (dayjs(a.start_date).isAfter(dayjs(b.start_date)) ? 1 : -1))
.map((sd, index) => (
<ShutdownCard
key={`${line}-${sd.start_date}-${sd.stop_date}-${index}`}
line={line as Lines}
shutdown={sd}
/>
))
),
[range, selectedLine]
);
}
});
return acc;
},
{
active: [],
upcoming: [],
completed: [],
}
);

const sortByDate = (
a: { card: JSX.Element; date: dayjs.Dayjs },
b: { card: JSX.Element; date: dayjs.Dayjs }
) => a.date.diff(b.date);

const sortedActive = shutdownsByGroup.active.sort(sortByDate).map((item) => item.card);
const sortedUpcoming = shutdownsByGroup.upcoming.sort(sortByDate).map((item) => item.card);
const sortedCompleted = shutdownsByGroup.completed.sort(sortByDate).map((item) => item.card);

return { active: sortedActive, upcoming: sortedUpcoming, completed: sortedCompleted };
}, [range, selectedLine]);

return (
<div className="w-full overflow-y-hidden my-8 grid md:grid-cols-3 gap-4">{mappedShutdowns}</div>
<div>
{!!groupedAndSortedShutdowns.active.length && (
<div className="md:my-8 my-4">
<h3 className="md:text-xl font-medium mb-4 dark:text-white">Active Shutdowns 🚧</h3>
<div className="w-full overflow-y-hidden grid md:grid-cols-3 gap-4">
{groupedAndSortedShutdowns.active}
</div>
</div>
)}
{!!groupedAndSortedShutdowns.upcoming.length && (
<div className="md:my-8 my-4">
<h3 className="md:text-xl font-medium mb-4 dark:text-white">Upcoming Shutdowns 🔜</h3>
<div className="w-full overflow-y-hidden grid md:grid-cols-3 gap-4">
{groupedAndSortedShutdowns.upcoming}
</div>
</div>
)}
<div className="md:my-8 my-4">
<h3 className="md:text-xl mb-4 font-medium dark:text-white">Completed Shutdowns ✅</h3>
<div className="w-full overflow-y-hidden grid md:grid-cols-3 gap-4">
{groupedAndSortedShutdowns.completed}
</div>
</div>
</div>
);
};
3 changes: 0 additions & 3 deletions src/components/Shutdowns/ShutdownTitle.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import { abbreviateStationName } from '../../constants/stations';
import { Shutdown } from '../../types';
import { useBreakpoint } from '../../hooks/useBreakpoint';
import { Lines } from '../../store';
import StatusBadge from './StatusBadge';

const ShutdownTitle = ({ shutdown, line }: { shutdown: Shutdown; line: Lines }) => {
const isMobile = useBreakpoint('sm');
Expand All @@ -20,8 +19,6 @@ const ShutdownTitle = ({ shutdown, line }: { shutdown: Shutdown; line: Lines })
{' - '}
{abbreviateStationName(shutdown.end_station?.stop_name, isMobile)}
</div>

<StatusBadge start_date={shutdown.start_date} stop_date={shutdown.stop_date} />
</div>
<div className="text-xs mt-1 text-gray-500 dark:text-slate-400">
{dayjs(shutdown.start_date).format('MM/DD/YY')} -{' '}
Expand Down
6 changes: 3 additions & 3 deletions src/store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ export interface Store {
setDarkMode: (mode: boolean) => void;
details?: { shutdown: Shutdown; line: Lines };
setDetails: (details: Shutdown, line: Lines) => void;
range: 'all' | 'past' | 'future';
setRange: (range: 'all' | 'past' | 'future') => void;
range: 'all' | 'past' | 'upcoming';
setRange: (range: 'all' | 'past' | 'upcoming') => void;
}

export const useStore = create<Store>((set) => ({
Expand All @@ -28,5 +28,5 @@ export const useStore = create<Store>((set) => ({
setDarkMode: (mode: boolean) => set({ darkMode: mode }),
setDetails: (shutdown: Shutdown, line: Lines) => set({ details: { shutdown, line } }),
range: 'all',
setRange: (range: 'all' | 'past' | 'future') => set({ range }),
setRange: (range: 'all' | 'past' | 'upcoming') => set({ range }),
}));

0 comments on commit 6287128

Please sign in to comment.