feature: event photo

This commit is contained in:
Benno Tielen 2024-12-11 10:17:37 +01:00
parent 1def791cfb
commit fd55e88166
14 changed files with 7144 additions and 42 deletions

View file

@ -1,29 +1,14 @@
# Heilige Drei Könige Website
This is the repository for the Heilige Drei Könige Catholic Church website, built using
Payload CMS v3, NextJS, React and MongoDB.
Payload CMS v3, NextJS, React and Postges.
## Getting Started
### Prerequisites
- Node.js and npm: Make sure you have Node.js and npm installed on your machine.
- MongoDB: You'll need a MongoDB database to store the website data.
- Postgres: You'll need a PostgresSQL database to store the website data.
### MongoDB
If you don't have docker on system installed, please
follow the instructions for your operating system on the Docker website.
To pull the MongoDB docker image:
```bash
docker pull mongodb/mongodb-community-server:latest
```
To Run the image as a Container
```bash
docker run --name mongodb -p 27017:27017 -d mongodb/mongodb-community-server:latest
```
### Postgres Database
You will need the an Postgres database including the postgis extension

View file

@ -2,6 +2,7 @@ import { notFound } from 'next/navigation'
import { Event } from '@/payload-types'
import { EventPage } from '@/pageComponents/Event/Event'
import { stringify } from 'qs-esm'
import { getPhoto } from '@/utils/dto/gallery'
export default async function Page({ params }: { params: Promise<{id: string}>}) {
@ -32,8 +33,8 @@ export default async function Page({ params }: { params: Promise<{id: string}>})
}
const event = await res.json() as Event;
console.log(event)
const group = Array.isArray(event.group) && event.group.length > 0 && typeof event.group[0] == "object" ? event.group[0].slug : undefined;
const photo = getPhoto("tablet", event.photo);
return (
<EventPage
@ -48,6 +49,7 @@ export default async function Page({ params }: { params: Promise<{id: string}>})
group={group}
contact={event.contact || undefined}
flyer={typeof event.flyer === 'object' ? event.flyer || undefined : undefined}
photo={photo}
/>
)
}

View file

@ -6,7 +6,6 @@
.col {
flex: 1 1 0;
width: 0;
}
@media screen and (max-width: 576px) {

View file

@ -24,6 +24,7 @@ export const Fullscreen = ({display, image, closeClicked, alt, nextClicked}: Ful
width={image.width}
src={image.src}
alt={alt || ""}
unoptimized={true}
/>
</div>
)

View file

@ -38,6 +38,7 @@ const GalleryItem = ({ thumbnail, alt, onClick }: GalleryItemProps) => {
height={thumbnail.height}
width={thumbnail.width}
alt={alt}
unoptimized={true}
/>
)
}

View file

@ -11,3 +11,9 @@
flex: 1 1 0;
height: 28px;
}
@media screen and (max-width: 1100px) {
.container {
padding: 20px;
}
}

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

9
src/migrations/index.ts Normal file
View file

@ -0,0 +1,9 @@
import * as migration_20241205_121237 from './20241205_121237';
export const migrations = [
{
up: migration_20241205_121237.up,
down: migration_20241205_121237.down,
name: '20241205_121237'
},
];

View file

@ -1,5 +1,6 @@
import { Meta, StoryObj } from '@storybook/react'
import { EventPage as Event } from './Event'
import photo from "./lobpreis.jpeg"
const meta: Meta<typeof Event> = {
component: Event,
@ -60,4 +61,11 @@ export const WithFlyerAndGroup: Story = {
...WithFlyer.args,
group: "some_group"
}
}
export const WithPhoto: Story = {
args: {
...Default.args,
photo: photo
}
}

View file

@ -62,9 +62,10 @@ export function EventPage(
color={"contrast"}
cancelled={cancelled}
/>
</Container>
<Row alignItems={'center'}>
<Col>
<div className={styles.header}>
<div className={styles.headerText}>
<p>
Herzliche Einladungen an unseren kommenden Veranstaltungen und Events teilzunehmen.
</p>
@ -80,11 +81,18 @@ export function EventPage(
<Pill schema={"contrast"}>Abgesagt</Pill>
}
</div>
</Col>
</div>
<Col>
{ photo &&
<img
src={photo.src}
className={styles.photo}
alt={"Veranstaltungsbild"}
/>
}
</Col>
</Row>
</Container>
</div>
<HR />
</Section>

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

View file

@ -1,3 +1,5 @@
@import "template.scss";
.description {
text-align: center;
padding: 0 100px;
@ -18,8 +20,53 @@
justify-content: center;
}
.header {
display: flex;
padding: 0 20px;
max-width: 1100px;
gap: 80px;
margin: 0 auto;
overflow: hidden;
}
.photo {
object-fit: cover;
height: 200px;
width: 510px;
border-radius: $border-radius
}
@media screen and (max-width: 576px) {
.headerText {
padding: 0 20px;
}
.header {
padding: 0;
flex-direction: column;
gap: 20px;
}
.photo {
border-radius: 0;
width: 100vw;
}
.description {
padding: 0;
}
}
@media screen and (max-width: 1000px) {
.header {
flex-direction: column;
flex-flow: column-reverse;
gap: 20px;
}
.photo {
width: 500px;
}
}

View file

@ -1,5 +1,6 @@
import { Media } from '@/payload-types'
import { GalleryItem } from '@/components/Gallery/Gallery'
import { StaticImageData } from 'next/image'
type Items = {
photo: string | Media;
@ -11,31 +12,57 @@ export const transformGallery = (items: Items) => {
items.forEach(item => {
if (typeof item === "object" && typeof item.photo === "object" && item.id) {
const thumbnail = item.photo.sizes?.gallery?.url;
const tWidth = item.photo.sizes?.gallery?.width;
const tHeight = item.photo.sizes?.gallery?.height;
const image = item.photo.sizes?.tablet?.url;
const iWidth = item.photo.sizes?.tablet?.width;
const iHeight = item.photo.sizes?.tablet?.height;
const thumbnail = getPhoto("gallery", item.photo);
const image = getPhoto("tablet", item.photo);
if (thumbnail && image && tWidth && tHeight && iWidth && iHeight) {
if (thumbnail && image) {
galleryItems.push({
alt: item.photo.alt,
id: item.id,
thumbnail: {
src: thumbnail,
width: tWidth,
height: tHeight,
},
image: {
src: image,
width: iWidth,
height: iHeight
}
thumbnail,
image
})
}
}
})
return galleryItems
}
}
type Size = "thumbnail" | "banner" | "gallery" | "tablet";
type OptionalMedia = string | null | undefined | Media;
/**
* Get image data from optional media
*
*/
export const getPhoto = (size: Size, data: OptionalMedia): StaticImageData | undefined => {
if (!data) {
return undefined;
}
if (typeof data === "string") {
return undefined;
}
if (!data.sizes) {
return undefined;
}
const sizeData = data.sizes[size]
if (!sizeData) {
return undefined;
}
if (sizeData.url && sizeData.width && sizeData.height) {
return {
src: sizeData.url,
width: sizeData.width,
height: sizeData.height
}
}
return undefined;
}