feature: add magazine archive page

This commit is contained in:
Benno Tielen 2026-06-03 13:37:51 +02:00
parent da56be94a3
commit 6b960aef19
4 changed files with 120 additions and 9 deletions

View file

@ -0,0 +1,83 @@
import { PageHeader } from '@/compositions/PageHeader/PageHeader'
import { Container } from '@/components/Container/Container'
import { Section } from '@/components/Section/Section'
import { NextPrevButtons } from '@/components/NextPrevButtons/NextPrevButtons'
import { fetchMagazines } from '@/fetch/magazine'
import { siteConfig } from '@/config/site'
import { Media } from '@/payload-types'
import Image from 'next/image'
import styles from './styles.module.scss'
export const dynamic = 'force-dynamic'
type Props = {
searchParams: Promise<{ page?: string }>
}
export default async function MagazinArchivPage({ searchParams }: Props) {
const { page: pageParam } = await searchParams
const page = Math.max(1, parseInt(pageParam ?? '1', 10) || 1)
const result = await fetchMagazines(page)
return (
<>
<PageHeader
title={`${siteConfig.magazineName} Archiv`}
description={'Alle bisherigen Ausgaben unseres Pfarrei-Magazins auf einen Blick.'}
/>
<Section padding={'small'}>
<Container>
<div className={styles.grid}>
{result.docs.map((magazine) => {
const cover = typeof magazine.cover === 'object' ? (magazine.cover as Media) : null
const pdfUrl =
typeof magazine.document === 'object' ? magazine.document.url ?? null : null
if (!cover?.url || !pdfUrl) return null
return (
<a
key={magazine.id}
href={pdfUrl}
target="_blank"
rel="noopener noreferrer"
className={styles.item}
>
<Image
src={cover.url}
width={cover.width ?? 300}
height={cover.height ?? 400}
alt={`${siteConfig.magazineName}`}
unoptimized
className={styles.cover}
/>
</a>
)
})}
</div>
{result.docs.length === 0 && <p>Keine Ausgaben gefunden.</p>}
</Container>
</Section>
{(result.hasPrevPage || result.hasNextPage) && (
<Section padding={'small'}>
<NextPrevButtons
prev={
result.hasPrevPage && result.prevPage
? { href: `/pfarrei/magazin/archiv?page=${result.prevPage}`, text: 'Neuere Ausgaben' }
: undefined
}
next={
result.hasNextPage && result.nextPage
? { href: `/pfarrei/magazin/archiv?page=${result.nextPage}`, text: 'Ältere Ausgaben' }
: undefined
}
/>
</Section>
)}
</>
)
}

View file

@ -0,0 +1,23 @@
@import 'template.scss';
.grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
gap: 24px;
}
.item {
display: block;
cursor: pointer;
&:hover .cover {
transform: scale(1.03);
}
}
.cover {
width: 100%;
height: auto;
border: 8px solid $light-grey;
transition: transform 0.2s ease;
}

View file

@ -48,7 +48,8 @@ export default async function MagazinePage() {
Bleiben Sie auf dem Laufenden! Hier finden Sie die aktuelle Ausgabe mit allen Berichten und Terminen aus der Gemeinde. Bleiben Sie auf dem Laufenden! Hier finden Sie die aktuelle Ausgabe mit allen Berichten und Terminen aus der Gemeinde.
<br/><br/> <br/><br/>
</P> </P>
<Button size={"lg"} target={"_blank"} href={magazine_url}>{siteConfig.magazineName} herunterladen</Button> <Button size={"md"} schema={"shade"} href={`/pfarrei/magazin/archiv`}>Archiv</Button>
<Button size={"md"} target={"_blank"} href={magazine_url}>{siteConfig.magazineName} herunterladen</Button>
</Col> </Col>
</Row> </Row>
</Container> </Container>

View file

@ -1,15 +1,9 @@
import { getPayload } from 'payload' import { getPayload } from 'payload'
import config from '@/payload.config' import config from '@/payload.config'
import { Magazine } from '@/payload-types' import { Magazine } from '@/payload-types'
import { PaginatedDocs } from 'payload'
/** export const fetchLastMagazine = async (): Promise<Magazine | undefined> => {
* Asynchronously fetches the last magazine entry.
*
* @returns {Promise<Magazine | undefined>} The last magazine entry if successful, or undefined.
*/
export const fetchLastMagazine = async (): Promise<
Magazine | undefined
> => {
const payload = await getPayload({ config }) const payload = await getPayload({ config })
const result = await payload.find({ const result = await payload.find({
collection: 'magazine', collection: 'magazine',
@ -18,3 +12,13 @@ export const fetchLastMagazine = async (): Promise<
}) })
return result.docs[0] return result.docs[0]
} }
export const fetchMagazines = async (page = 1, limit = 12): Promise<PaginatedDocs<Magazine>> => {
const payload = await getPayload({ config })
return payload.find({
collection: 'magazine',
sort: '-date',
limit,
page,
})
}