church-website/src/fetch/worship.ts
2026-07-21 11:19:52 +02:00

107 lines
2.3 KiB
TypeScript

import { getPayload, PaginatedDocs } from 'payload'
import { unstable_cache } from 'next/cache'
import config from '@/payload.config'
import { Worship } from '@/payload-types'
const CACHE_TTL = 300 // 5 minutes
type FetchWorshipArgs = {
fromDate?: Date
tillDate?: Date
locations?: string[]
}
// Resolved args use ISO strings so they serialize into a stable cache key.
type ResolvedWorshipArgs = {
fromDate: string
tillDate?: string
locations?: string[]
}
// Round down to the cache window so millisecond-precision dates produce a
// stable key for the duration of the TTL.
function roundDownToTtl(date: Date): Date {
const ms = CACHE_TTL * 1000
return new Date(Math.floor(date.getTime() / ms) * ms)
}
const getWorship = unstable_cache(
async (args: ResolvedWorshipArgs): Promise<PaginatedDocs<Worship>> => {
const { fromDate, tillDate, locations } = args
const query: any = {
and: [
{
date: {
greater_than_equal: fromDate,
},
},
],
}
if (tillDate) {
query.and.push({
date: {
less_than: tillDate,
},
})
}
if (locations) {
query.and.push({
location: {
in: locations,
},
})
}
const payload = await getPayload({ config })
return payload.find({
collection: 'worship',
sort: 'date',
where: query,
select: {
type: true,
date: true,
cancelled: true,
location: true,
title: true,
},
limit: 100,
}) as Promise<PaginatedDocs<Worship>>
},
['fetchWorship'],
{ tags: ['worship'], revalidate: CACHE_TTL },
)
export const fetchWorship = async (
args?: FetchWorshipArgs,
): Promise<PaginatedDocs<Worship>> => {
const { fromDate, tillDate, locations } = args || {}
let date = fromDate
if (!date) {
date = new Date()
date.setHours(0, 0, 0, 0)
}
return getWorship({
fromDate: roundDownToTtl(date).toISOString(),
tillDate: tillDate ? roundDownToTtl(tillDate).toISOString() : undefined,
locations,
})
}
/**
* Fetch a single worship entry by ID
*/
export async function fetchWorshipById(
id: string,
): Promise<Worship | undefined> {
try {
const payload = await getPayload({ config })
return await payload.findByID({ collection: 'worship', id })
} catch {
return undefined
}
}