feature: cache events
This commit is contained in:
parent
ba2721fbea
commit
bff425c3bd
2 changed files with 112 additions and 55 deletions
|
|
@ -32,7 +32,7 @@ export async function EventsBlock({
|
|||
<Title color={'contrast'} title={title || 'Veranstaltungen'} />
|
||||
<Events
|
||||
events={transformOccurrences(occurrenceDocs)}
|
||||
n={itemsPerPage || 6}
|
||||
n={6}
|
||||
schema={'contrast'}
|
||||
/>
|
||||
</Section>
|
||||
|
|
|
|||
|
|
@ -1,7 +1,10 @@
|
|||
import { getPayload, PaginatedDocs } from 'payload'
|
||||
import { unstable_cache } from 'next/cache'
|
||||
import config from '@/payload.config'
|
||||
import { EventOccurrence } from '@/payload-types'
|
||||
|
||||
const CACHE_TTL = 300 // 5 minutes
|
||||
|
||||
type ListArgs = {
|
||||
parishId?: string
|
||||
groupId?: string
|
||||
|
|
@ -12,10 +15,66 @@ type ListArgs = {
|
|||
toDate?: Date
|
||||
}
|
||||
|
||||
// Resolved args use ISO strings so they serialize into a stable cache key.
|
||||
type ResolvedArgs = {
|
||||
parishId?: string
|
||||
groupId?: string
|
||||
eventId?: string
|
||||
limit: number
|
||||
page: number
|
||||
fromDate?: string
|
||||
toDate?: string
|
||||
}
|
||||
|
||||
// Round down to the cache window so a default `new Date()` (millisecond
|
||||
// precision) produces 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)
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch upcoming event occurrences, joined to their parent event. Always
|
||||
* filters to occurrences whose parent event is published.
|
||||
*/
|
||||
const getUpcomingOccurrences = unstable_cache(
|
||||
async (args: ResolvedArgs): Promise<PaginatedDocs<EventOccurrence>> => {
|
||||
const { parishId, groupId, eventId, limit, page, fromDate, toDate } = args
|
||||
|
||||
const query: any = {
|
||||
and: [
|
||||
{ date: { greater_than_equal: fromDate } },
|
||||
{ 'event._status': { equals: 'published' } },
|
||||
],
|
||||
}
|
||||
|
||||
if (toDate) {
|
||||
query.and.push({ date: { less_than: toDate } })
|
||||
}
|
||||
if (eventId) {
|
||||
query.and.push({ event: { equals: eventId } })
|
||||
}
|
||||
if (parishId) {
|
||||
query.and.push({ 'event.parish': { equals: parishId } })
|
||||
}
|
||||
if (groupId) {
|
||||
query.and.push({ 'event.group': { equals: groupId } })
|
||||
}
|
||||
|
||||
const payload = await getPayload({ config })
|
||||
return payload.find({
|
||||
collection: 'eventOccurrence',
|
||||
sort: 'date',
|
||||
where: query,
|
||||
depth: 2,
|
||||
limit,
|
||||
page,
|
||||
}) as Promise<PaginatedDocs<EventOccurrence>>
|
||||
},
|
||||
['fetchUpcomingOccurrences'],
|
||||
{ revalidate: CACHE_TTL },
|
||||
)
|
||||
|
||||
export async function fetchUpcomingOccurrences(
|
||||
args?: ListArgs,
|
||||
): Promise<PaginatedDocs<EventOccurrence>> {
|
||||
|
|
@ -29,41 +88,59 @@ export async function fetchUpcomingOccurrences(
|
|||
toDate,
|
||||
} = args || {}
|
||||
|
||||
const query: any = {
|
||||
and: [
|
||||
{ date: { greater_than_equal: fromDate.toISOString() } },
|
||||
{ 'event._status': { equals: 'published' } },
|
||||
],
|
||||
}
|
||||
|
||||
if (toDate) {
|
||||
query.and.push({ date: { less_than: toDate.toISOString() } })
|
||||
}
|
||||
if (eventId) {
|
||||
query.and.push({ event: { equals: eventId } })
|
||||
}
|
||||
if (parishId) {
|
||||
query.and.push({ 'event.parish': { equals: parishId } })
|
||||
}
|
||||
if (groupId) {
|
||||
query.and.push({ 'event.group': { equals: groupId } })
|
||||
}
|
||||
|
||||
const payload = await getPayload({ config })
|
||||
return payload.find({
|
||||
collection: 'eventOccurrence',
|
||||
sort: 'date',
|
||||
where: query,
|
||||
depth: 2,
|
||||
return getUpcomingOccurrences({
|
||||
parishId,
|
||||
groupId,
|
||||
eventId,
|
||||
limit,
|
||||
page,
|
||||
}) as Promise<PaginatedDocs<EventOccurrence>>
|
||||
fromDate: roundDownToTtl(fromDate).toISOString(),
|
||||
toDate: toDate?.toISOString(),
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch past event occurrences (most recent first), joined to their parent
|
||||
* event. Always filters to occurrences whose parent event is published.
|
||||
*/
|
||||
const getPastOccurrences = unstable_cache(
|
||||
async (args: ResolvedArgs): Promise<PaginatedDocs<EventOccurrence>> => {
|
||||
const { parishId, groupId, eventId, limit, page, fromDate, toDate } = args
|
||||
|
||||
const query: any = {
|
||||
and: [
|
||||
{ date: { less_than: toDate } },
|
||||
{ 'event._status': { equals: 'published' } },
|
||||
],
|
||||
}
|
||||
|
||||
if (fromDate) {
|
||||
query.and.push({ date: { greater_than_equal: fromDate } })
|
||||
}
|
||||
if (eventId) {
|
||||
query.and.push({ event: { equals: eventId } })
|
||||
}
|
||||
if (parishId) {
|
||||
query.and.push({ 'event.parish': { equals: parishId } })
|
||||
}
|
||||
if (groupId) {
|
||||
query.and.push({ 'event.group': { equals: groupId } })
|
||||
}
|
||||
|
||||
const payload = await getPayload({ config })
|
||||
return payload.find({
|
||||
collection: 'eventOccurrence',
|
||||
sort: '-date',
|
||||
where: query,
|
||||
depth: 2,
|
||||
limit,
|
||||
page,
|
||||
}) as Promise<PaginatedDocs<EventOccurrence>>
|
||||
},
|
||||
['fetchPastOccurrences'],
|
||||
{ revalidate: CACHE_TTL },
|
||||
)
|
||||
|
||||
export async function fetchPastOccurrences(
|
||||
args?: ListArgs,
|
||||
): Promise<PaginatedDocs<EventOccurrence>> {
|
||||
|
|
@ -77,35 +154,15 @@ export async function fetchPastOccurrences(
|
|||
toDate = new Date(),
|
||||
} = args || {}
|
||||
|
||||
const query: any = {
|
||||
and: [
|
||||
{ date: { less_than: toDate.toISOString() } },
|
||||
{ 'event._status': { equals: 'published' } },
|
||||
],
|
||||
}
|
||||
|
||||
if (fromDate) {
|
||||
query.and.push({ date: { greater_than_equal: fromDate.toISOString() } })
|
||||
}
|
||||
if (eventId) {
|
||||
query.and.push({ event: { equals: eventId } })
|
||||
}
|
||||
if (parishId) {
|
||||
query.and.push({ 'event.parish': { equals: parishId } })
|
||||
}
|
||||
if (groupId) {
|
||||
query.and.push({ 'event.group': { equals: groupId } })
|
||||
}
|
||||
|
||||
const payload = await getPayload({ config })
|
||||
return payload.find({
|
||||
collection: 'eventOccurrence',
|
||||
sort: '-date',
|
||||
where: query,
|
||||
depth: 2,
|
||||
return getPastOccurrences({
|
||||
parishId,
|
||||
groupId,
|
||||
eventId,
|
||||
limit,
|
||||
page,
|
||||
}) as Promise<PaginatedDocs<EventOccurrence>>
|
||||
fromDate: fromDate?.toISOString(),
|
||||
toDate: roundDownToTtl(toDate).toISOString(),
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
Loading…
Reference in a new issue