107 lines
2.3 KiB
TypeScript
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
|
|
}
|
|
}
|