feature: event photo
This commit is contained in:
parent
1def791cfb
commit
fd55e88166
14 changed files with 7144 additions and 42 deletions
19
README.md
19
README.md
|
|
@ -1,29 +1,14 @@
|
||||||
# Heilige Drei Könige Website
|
# Heilige Drei Könige Website
|
||||||
This is the repository for the Heilige Drei Könige Catholic Church website, built using
|
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
|
## Getting Started
|
||||||
|
|
||||||
### Prerequisites
|
### Prerequisites
|
||||||
- Node.js and npm: Make sure you have Node.js and npm installed on your machine.
|
- 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
|
### Postgres Database
|
||||||
|
|
||||||
You will need the an Postgres database including the postgis extension
|
You will need the an Postgres database including the postgis extension
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ import { notFound } from 'next/navigation'
|
||||||
import { Event } from '@/payload-types'
|
import { Event } from '@/payload-types'
|
||||||
import { EventPage } from '@/pageComponents/Event/Event'
|
import { EventPage } from '@/pageComponents/Event/Event'
|
||||||
import { stringify } from 'qs-esm'
|
import { stringify } from 'qs-esm'
|
||||||
|
import { getPhoto } from '@/utils/dto/gallery'
|
||||||
|
|
||||||
export default async function Page({ params }: { params: Promise<{id: string}>}) {
|
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;
|
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 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 (
|
return (
|
||||||
<EventPage
|
<EventPage
|
||||||
|
|
@ -48,6 +49,7 @@ export default async function Page({ params }: { params: Promise<{id: string}>})
|
||||||
group={group}
|
group={group}
|
||||||
contact={event.contact || undefined}
|
contact={event.contact || undefined}
|
||||||
flyer={typeof event.flyer === 'object' ? event.flyer || undefined : undefined}
|
flyer={typeof event.flyer === 'object' ? event.flyer || undefined : undefined}
|
||||||
|
photo={photo}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
@ -6,7 +6,6 @@
|
||||||
|
|
||||||
.col {
|
.col {
|
||||||
flex: 1 1 0;
|
flex: 1 1 0;
|
||||||
width: 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@media screen and (max-width: 576px) {
|
@media screen and (max-width: 576px) {
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,7 @@ export const Fullscreen = ({display, image, closeClicked, alt, nextClicked}: Ful
|
||||||
width={image.width}
|
width={image.width}
|
||||||
src={image.src}
|
src={image.src}
|
||||||
alt={alt || ""}
|
alt={alt || ""}
|
||||||
|
unoptimized={true}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -38,6 +38,7 @@ const GalleryItem = ({ thumbnail, alt, onClick }: GalleryItemProps) => {
|
||||||
height={thumbnail.height}
|
height={thumbnail.height}
|
||||||
width={thumbnail.width}
|
width={thumbnail.width}
|
||||||
alt={alt}
|
alt={alt}
|
||||||
|
unoptimized={true}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,3 +11,9 @@
|
||||||
flex: 1 1 0;
|
flex: 1 1 0;
|
||||||
height: 28px;
|
height: 28px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: 1100px) {
|
||||||
|
.container {
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
5941
src/migrations/20241205_121237.json
Normal file
5941
src/migrations/20241205_121237.json
Normal file
File diff suppressed because it is too large
Load diff
1068
src/migrations/20241205_121237.ts
Normal file
1068
src/migrations/20241205_121237.ts
Normal file
File diff suppressed because it is too large
Load diff
9
src/migrations/index.ts
Normal file
9
src/migrations/index.ts
Normal 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'
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
import { Meta, StoryObj } from '@storybook/react'
|
import { Meta, StoryObj } from '@storybook/react'
|
||||||
import { EventPage as Event } from './Event'
|
import { EventPage as Event } from './Event'
|
||||||
|
import photo from "./lobpreis.jpeg"
|
||||||
|
|
||||||
const meta: Meta<typeof Event> = {
|
const meta: Meta<typeof Event> = {
|
||||||
component: Event,
|
component: Event,
|
||||||
|
|
@ -60,4 +61,11 @@ export const WithFlyerAndGroup: Story = {
|
||||||
...WithFlyer.args,
|
...WithFlyer.args,
|
||||||
group: "some_group"
|
group: "some_group"
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const WithPhoto: Story = {
|
||||||
|
args: {
|
||||||
|
...Default.args,
|
||||||
|
photo: photo
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -62,9 +62,10 @@ export function EventPage(
|
||||||
color={"contrast"}
|
color={"contrast"}
|
||||||
cancelled={cancelled}
|
cancelled={cancelled}
|
||||||
/>
|
/>
|
||||||
|
</Container>
|
||||||
|
|
||||||
<Row alignItems={'center'}>
|
<div className={styles.header}>
|
||||||
<Col>
|
<div className={styles.headerText}>
|
||||||
<p>
|
<p>
|
||||||
Herzliche Einladungen an unseren kommenden Veranstaltungen und Events teilzunehmen.
|
Herzliche Einladungen an unseren kommenden Veranstaltungen und Events teilzunehmen.
|
||||||
</p>
|
</p>
|
||||||
|
|
@ -80,11 +81,18 @@ export function EventPage(
|
||||||
<Pill schema={"contrast"}>Abgesagt</Pill>
|
<Pill schema={"contrast"}>Abgesagt</Pill>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
</Col>
|
</div>
|
||||||
<Col>
|
<Col>
|
||||||
|
{ photo &&
|
||||||
|
<img
|
||||||
|
src={photo.src}
|
||||||
|
className={styles.photo}
|
||||||
|
alt={"Veranstaltungsbild"}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</div>
|
||||||
</Container>
|
|
||||||
<HR />
|
<HR />
|
||||||
</Section>
|
</Section>
|
||||||
|
|
||||||
|
|
|
||||||
BIN
src/pageComponents/Event/lobpreis.jpeg
Normal file
BIN
src/pageComponents/Event/lobpreis.jpeg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 19 KiB |
|
|
@ -1,3 +1,5 @@
|
||||||
|
@import "template.scss";
|
||||||
|
|
||||||
.description {
|
.description {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
padding: 0 100px;
|
padding: 0 100px;
|
||||||
|
|
@ -18,8 +20,53 @@
|
||||||
justify-content: center;
|
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) {
|
@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 {
|
.description {
|
||||||
padding: 0;
|
padding: 0;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: 1000px) {
|
||||||
|
.header {
|
||||||
|
flex-direction: column;
|
||||||
|
flex-flow: column-reverse;
|
||||||
|
gap: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.photo {
|
||||||
|
width: 500px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
import { Media } from '@/payload-types'
|
import { Media } from '@/payload-types'
|
||||||
import { GalleryItem } from '@/components/Gallery/Gallery'
|
import { GalleryItem } from '@/components/Gallery/Gallery'
|
||||||
|
import { StaticImageData } from 'next/image'
|
||||||
|
|
||||||
type Items = {
|
type Items = {
|
||||||
photo: string | Media;
|
photo: string | Media;
|
||||||
|
|
@ -11,31 +12,57 @@ export const transformGallery = (items: Items) => {
|
||||||
|
|
||||||
items.forEach(item => {
|
items.forEach(item => {
|
||||||
if (typeof item === "object" && typeof item.photo === "object" && item.id) {
|
if (typeof item === "object" && typeof item.photo === "object" && item.id) {
|
||||||
const thumbnail = item.photo.sizes?.gallery?.url;
|
const thumbnail = getPhoto("gallery", item.photo);
|
||||||
const tWidth = item.photo.sizes?.gallery?.width;
|
const image = getPhoto("tablet", item.photo);
|
||||||
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;
|
|
||||||
|
|
||||||
if (thumbnail && image && tWidth && tHeight && iWidth && iHeight) {
|
if (thumbnail && image) {
|
||||||
galleryItems.push({
|
galleryItems.push({
|
||||||
alt: item.photo.alt,
|
alt: item.photo.alt,
|
||||||
id: item.id,
|
id: item.id,
|
||||||
thumbnail: {
|
thumbnail,
|
||||||
src: thumbnail,
|
image
|
||||||
width: tWidth,
|
|
||||||
height: tHeight,
|
|
||||||
},
|
|
||||||
image: {
|
|
||||||
src: image,
|
|
||||||
width: iWidth,
|
|
||||||
height: iHeight
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
return galleryItems
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue