crabfit/frontend/src/utils/calculateTable.ts
2023-06-18 13:55:44 +10:00

62 lines
2.1 KiB
TypeScript

import { calculateColumns } from '/src/utils/calculateColumns'
import { calculateRows } from '/src/utils/calculateRows'
import { convertTimesToDates } from '/src/utils/convertTimesToDates'
import { serializeTime } from '/src/utils/serializeTime'
export interface CalculateTableArgs {
/** As `HHmm-DDMMYYYY` or `HHmm-d` strings */
times: string[]
locale: string
timeFormat: '12h' | '24h'
timezone: string
}
/**
* Take rows and columns and turn them into a data structure representing an availability table
*/
export const calculateTable = ({
/** As `HHmm-DDMMYYYY` or `HHmm-d` strings */
times,
locale,
timeFormat,
timezone,
}: CalculateTableArgs) => {
const dates = convertTimesToDates(times, timezone)
const rows = calculateRows(dates)
const columns = calculateColumns(dates)
// Is specific dates or just days of the week
const isSpecificDates = times[0]?.length === 13
return {
rows: rows.map(row => row && row.minute === 0 ? {
label: row.toLocaleString(locale, { hour: 'numeric', hourCycle: timeFormat === '12h' ? 'h12' : 'h24' }),
string: row.toString(),
} : null),
columns: columns.map(column => column ? {
header: {
dateLabel: isSpecificDates ? column.toLocaleString(locale, { month: 'short', day: 'numeric' }) : undefined,
weekdayLabel: column.toLocaleString(locale, { weekday: 'short' }),
string: column.toString(),
},
cells: rows.map(row => {
if (!row) return null
const date = column.toZonedDateTime({ timeZone: timezone, plainTime: row })
const serialized = serializeTime(date, isSpecificDates)
// Cell not in dates
if (!times.includes(serialized)) return null
return {
serialized,
minute: date.minute,
label: isSpecificDates
? date.toLocaleString(locale, { dateStyle: 'long', timeStyle: 'short', hourCycle: timeFormat === '12h' ? 'h12' : 'h24' })
: `${date.toLocaleString(locale, { timeStyle: 'short', hourCycle: timeFormat === '12h' ? 'h12' : 'h24' })}, ${date.toLocaleString(locale, { weekday: 'long' })}`,
}
})
} : null)
}
}