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.
<br/><br/>
</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>
</Row>
</Container>

View file

@ -1,15 +1,9 @@
import { getPayload } from 'payload'
import config from '@/payload.config'
import { Magazine } from '@/payload-types'
import { PaginatedDocs } from 'payload'
/**
* 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
> => {
export const fetchLastMagazine = async (): Promise<Magazine | undefined> => {
const payload = await getPayload({ config })
const result = await payload.find({
collection: 'magazine',
@ -18,3 +12,13 @@ export const fetchLastMagazine = async (): Promise<
})
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,
})
}