From aa6e11d591612add29fba6726cfb8eab2d977bdb Mon Sep 17 00:00:00 2001 From: Konsta Purtsi Date: Wed, 10 Apr 2024 22:34:28 +0300 Subject: [PATCH] Group showmap days into groups of 5. Remove overengineered weekkey generation. --- archiver/archive.ts | 17 ++++++--- components/showlist.tsx | 28 ++++---------- components/showlistMap.tsx | 61 ++++++++++++++++++++----------- pages/arkisto/[showlistId].tsx | 9 +---- pages/index.tsx | 21 +++++------ scripts/google/client.ts | 9 ++--- scripts/google/showlistHelpers.ts | 49 +++---------------------- 7 files changed, 79 insertions(+), 115 deletions(-) diff --git a/archiver/archive.ts b/archiver/archive.ts index 053e403..6f46445 100644 --- a/archiver/archive.ts +++ b/archiver/archive.ts @@ -1,16 +1,23 @@ import { Show, - Showlist, + ShowsByDate, showsToGroups, } from '@/scripts/google/showlistHelpers'; const showlistBaseUrl = process.env.ARCHIVE_SOURCE_URL; -const emptyResponse = { showsByDate: [], weekKeys: {} } as const; +const emptyResponse = {} as const; + +interface LegacyShowList { + showsByDate: ShowsByDate; + weekKeys: Record; +} /** * Archive S3 bucket API */ -export const fetchArchivedShowlist = async (showlistId: string) => { +export const fetchArchivedShowlist = async ( + showlistId: string +): Promise => { if (!showlistBaseUrl) { console.error('Arkiston polkua ei ole määritetty'); return emptyResponse; @@ -19,13 +26,13 @@ export const fetchArchivedShowlist = async (showlistId: string) => { try { const response = await fetch(url); - const showlist: Show[] | Showlist = await response.json(); + const showlist: Show[] | LegacyShowList = await response.json(); if (Array.isArray(showlist)) { return showsToGroups(showlist); } if (showlist?.showsByDate) { - return showlist; + return showlist.showsByDate; } return emptyResponse; } catch (error) { diff --git a/components/showlist.tsx b/components/showlist.tsx index 52321b5..f70ea26 100644 --- a/components/showlist.tsx +++ b/components/showlist.tsx @@ -1,19 +1,16 @@ import { useState } from 'react'; import { useViewport } from '@/hooks/useViewport'; -import { Show } from '@/scripts/google/showlistHelpers'; +import { Show, ShowsByDate } from '@/scripts/google/showlistHelpers'; import { ModeButton } from './button'; import ResponsiveShowlist from './responsiveShowlist'; import ShowlistMap from './showlistMap'; interface ShowlistProps { - showsByDate: { - [key: string]: Show[]; - }; - weekKeys: Record; + showsByDate: ShowsByDate; } -export const Showlist = ({ showsByDate, weekKeys }: ShowlistProps) => { +export const Showlist = ({ showsByDate }: ShowlistProps) => { const [mode, setMode] = useState<'list' | 'map'>('list'); const { isDesktop } = useViewport(); @@ -39,28 +36,17 @@ export const Showlist = ({ showsByDate, weekKeys }: ShowlistProps) => { )} - + ); }; interface ShowlistSelectorProps { - showsByDate: { - [key: string]: Show[]; - }; - weekKeys: Record; + showsByDate: ShowsByDate; mode: 'list' | 'map'; } -const ShowlistSelector = ({ - showsByDate, - weekKeys, - mode, -}: ShowlistSelectorProps) => { +const ShowlistSelector = ({ showsByDate, mode }: ShowlistSelectorProps) => { const { isDesktop } = useViewport(); if (!isDesktop) { @@ -71,7 +57,7 @@ const ShowlistSelector = ({ case 'list': return ; case 'map': - return ; + return ; } }; diff --git a/components/showlistMap.tsx b/components/showlistMap.tsx index 16b5981..e4d7365 100644 --- a/components/showlistMap.tsx +++ b/components/showlistMap.tsx @@ -1,25 +1,39 @@ import { useState } from 'react'; import { differenceInMinutes, format, parse } from 'date-fns'; import fi from 'date-fns/locale/fi'; -import { head, keys } from 'ramda'; +import { append, head, keys, last } from 'ramda'; -import { Show } from '@/scripts/google/showlistHelpers'; +import { Show, ShowsByDate } from '@/scripts/google/showlistHelpers'; import { ModeButton } from './button'; import { ShowCard } from './showcard'; import { WideScreencard } from './widescreen-card'; +const GROUP_SIZE = 5; + interface ShowlistMapProps { - showsByDate: Record; - weekKeys: Record; + showsByDate: ShowsByDate; } -export const ShowlistMap = ({ showsByDate, weekKeys }: ShowlistMapProps) => { - const weeks = keys(weekKeys); +export const ShowlistMap = ({ showsByDate }: ShowlistMapProps) => { + // Take every n consecutive days. + const groups: string[][] = keys(showsByDate).reduce((acc, date, idx) => { + const groupIdx = Math.floor(idx / GROUP_SIZE); + acc[groupIdx] = append(date, acc[groupIdx] ?? []); + return acc; + }, []); const [selectedShow, setSelectedShow] = useState(null); - const [openWeek, setOpenWeek] = useState(head(weeks)); + const [openGroup, setOpenGroup] = useState(0); + + const openWeekDays = groups[openGroup]; - const openWeekDays = weekKeys[openWeek] ?? []; + const formatGroupButtonText = (group: string[]): string => { + if (group.length === 1) return formatDayKey(head(group)); + + const startDay = formatDayKey(head(group), 'EEEEEE dd.'); + const endDay = formatDayKey(last(group)); + return `${startDay} – ${endDay}`; + }; // prettier-ignore const timeStamps: string[] = ['00', '01', '02', '03', '04', '05', '06', '07', '08', '09', '10', '11', @@ -35,16 +49,18 @@ export const ShowlistMap = ({ showsByDate, weekKeys }: ShowlistMapProps) => { forceOpen={true} /> )} -
- {weeks.map((n, i) => ( - setOpenWeek(n)} - isActive={openWeek === n} - /> - ))} -
+ {groups.length > 1 ? ( +
+ {groups.map((group, idx) => ( + setOpenGroup(idx)} + isActive={openGroup === idx} + /> + ))} +
+ ) : null}
{timeStamps.map((timeStamp, i) => ( @@ -61,9 +77,7 @@ export const ShowlistMap = ({ showsByDate, weekKeys }: ShowlistMapProps) => { className="flex w-full max-w-[1/7] flex-col text-center" >

- {format(parse(day, 'y.M.dd', new Date()), 'EEEEEE dd.M.', { - locale: fi, - })} + {formatDayKey(day)}

{/* If the first show of the day does not start at midnight, add buffer */} @@ -94,6 +108,11 @@ export const ShowlistMap = ({ showsByDate, weekKeys }: ShowlistMapProps) => { ); }; +const formatDayKey = (day: string, format_: string = 'EEEEEE dd.M.'): string => + format(parse(day, 'y.M.dd', new Date()), format_, { + locale: fi, + }); + // If the first show of the day does not start at midnight, add buffer const Buffer = ({ firstShow, day }: { firstShow: Show; day: string }) => { const dayParsed = parse(day, 'y.M.dd', new Date()); diff --git a/pages/arkisto/[showlistId].tsx b/pages/arkisto/[showlistId].tsx index 6fbb917..ac63d0c 100644 --- a/pages/arkisto/[showlistId].tsx +++ b/pages/arkisto/[showlistId].tsx @@ -26,7 +26,6 @@ interface ShowListPageProps { showsByDate: { [key: string]: Show[]; }; - weekKeys: Record; heroImage: { url?: string; }; @@ -37,7 +36,6 @@ export const ShowListPage: NextPage = ({ name, showsByDate, heroImage, - weekKeys, navigationItems, heroSubtext, }) => { @@ -69,7 +67,7 @@ export const ShowListPage: NextPage = ({
- +
); }; @@ -103,9 +101,7 @@ export const getStaticProps: GetStaticProps = async (context) => { const { name, id, heroImage, heroSubtext } = data.programmeCollection.items[0]; - const { showsByDate, weekKeys } = await fetchArchivedShowlist( - currentShowlistId - ); + const showsByDate = await fetchArchivedShowlist(currentShowlistId); const navigationItems = await fetchNavigationItems(); @@ -114,7 +110,6 @@ export const getStaticProps: GetStaticProps = async (context) => { name, id, showsByDate, - weekKeys, navigationItems, heroImage, heroSubtext, diff --git a/pages/index.tsx b/pages/index.tsx index d767744..bcf7486 100644 --- a/pages/index.tsx +++ b/pages/index.tsx @@ -17,7 +17,7 @@ import { import { contentfulImageLoader } from '@/contentful/contentfulImageLoader'; import { IndexDocument, IndexQuery } from '@/contentful/graphql/index.graphql'; import { fetchShowlist } from '@/scripts/google/client'; -import { Show } from '@/scripts/google/showlistHelpers'; +import { Show, ShowsByDate } from '@/scripts/google/showlistHelpers'; const isPlayerLive = process.env.NEXT_PUBLIC_PLAYER_MODE === 'live'; @@ -33,8 +33,7 @@ interface IndexProps { heroButtonText: string; heroButtonLink: string; navigationItems: NavigationItem[]; - showsByDate: Record; - weekKeys: Record; + showsByDate: ShowsByDate; firstDecorativeImage: { url?: string; width?: number; @@ -64,12 +63,11 @@ const Index: NextPage = ({ heroButtonLink, navigationItems, showsByDate, - weekKeys, - firstDecorativeImage, - secondDecorativeImage, - firstContent, - secondContent, - thirdContent, + // firstDecorativeImage, + // secondDecorativeImage, + // firstContent, + // secondContent, + // thirdContent, sponsors, playing, onPlayPause, @@ -106,7 +104,7 @@ const Index: NextPage = ({ /> )} - + {/* First section */} {/*
*/} @@ -175,7 +173,7 @@ export const getStaticProps: GetStaticProps = async () => { const navigationItems = await fetchNavigationItems(); - const { showsByDate, weekKeys } = await fetchShowlist(); + const showsByDate = await fetchShowlist(); return { props: { @@ -186,7 +184,6 @@ export const getStaticProps: GetStaticProps = async () => { heroButtonLink, navigationItems, showsByDate, - weekKeys, firstDecorativeImage, secondDecorativeImage, firstContent, diff --git a/scripts/google/client.ts b/scripts/google/client.ts index d54febb..8a1de32 100644 --- a/scripts/google/client.ts +++ b/scripts/google/client.ts @@ -1,4 +1,4 @@ -import { Color, Show, Showlist, showsToGroups } from './showlistHelpers'; +import { Color, Show, ShowsByDate, showsToGroups } from './showlistHelpers'; import { sheets_v4 } from '@googleapis/sheets'; import { addMilliseconds, formatISO, getHours } from 'date-fns'; @@ -116,17 +116,14 @@ export const parseSheetToShowList = async ( return showList; }; -export const fetchShowlist = async (): Promise => { +export const fetchShowlist = async (): Promise => { const data = await getSheet({ apiKey: process.env.GA_API_KEY, spreadsheetId: process.env.GA_SPREADSHEET_SHOWLIST, range: process.env.GA_SPREADSHEET_RANGE, }); if (!data) { - return { - showsByDate: {}, - weekKeys: {}, - }; + return {}; } const shows = data ? await parseSheetToShowList(data, { apiKey: process.env.GA_API_KEY }) diff --git a/scripts/google/showlistHelpers.ts b/scripts/google/showlistHelpers.ts index 9920893..c4aba03 100644 --- a/scripts/google/showlistHelpers.ts +++ b/scripts/google/showlistHelpers.ts @@ -1,12 +1,5 @@ -import { - addDays, - eachDayOfInterval, - eachWeekOfInterval, - format, - getISOWeek, - parse, -} from 'date-fns'; -import { groupBy, head, keys, last } from 'ramda'; +import { format } from 'date-fns'; +import { groupBy } from 'ramda'; export enum Color { Night = 'night', @@ -24,38 +17,8 @@ export interface Show { color?: Color | null; } -export interface Showlist { - showsByDate: Record; - weekKeys: Record; -} - -export const showsToGroups = (shows: Show[]) => { - const showsByDate = groupBy( - (day: any) => format(new Date(day.start), 'y.M.dd'), - shows - ); - const weekKeys = generateWeekObj(showsByDate); - return { showsByDate, weekKeys }; -}; - -// Generate a nicely formatted object to use as keys. -const generateWeekObj = (showsByDate: Record) => { - const start = parse(head(keys(showsByDate)), 'y.M.dd', new Date()); - const end = parse(last(keys(showsByDate)), 'y.M.dd', new Date()); - const weeks = eachWeekOfInterval({ start, end }, { weekStartsOn: 1 }); - - const weekObj = weeks.reduce( - (acc: Record, weekStart: Date) => { - const weekKey = getISOWeek(weekStart).toString(); - const days = eachDayOfInterval({ - start: weekStart, - end: addDays(new Date(weekStart), 6), - }).map((day: Date) => format(day, 'y.M.dd')); - acc[weekKey] = days; - return acc; - }, - {} - ); +// key is a date encoded as string, in the format YYYY.MM.DD +export type ShowsByDate = Record; - return weekObj; -}; +export const showsToGroups = (shows: Show[]): ShowsByDate => + groupBy((day: any) => format(new Date(day.start), 'y.M.dd'), shows);