feature: styling

This commit is contained in:
Benno Tielen 2024-08-22 15:01:23 +02:00
parent b3262d8700
commit 210b8641bc
24 changed files with 237 additions and 145 deletions

View file

@ -20,8 +20,6 @@
"@payloadcms/next": "beta",
"@payloadcms/plugin-cloud": "beta",
"@payloadcms/richtext-lexical": "beta",
"@romcal/calendar.france": "^3.0.0-dev.79",
"@romcal/calendar.germany": "file:./../romcal/dist/bundles/germany",
"classnames": "^2.5.1",
"cross-env": "^7.0.3",
"graphql": "^16.8.1",
@ -30,7 +28,6 @@
"payload": "beta",
"react": "^19.0.0-rc-6230622a1a-20240610",
"react-dom": "^19.0.0-rc-6230622a1a-20240610",
"romcal": "^3.0.0-dev.79",
"sharp": "0.32.6"
},
"devDependencies": {

4
src/app/globals.css Normal file
View file

@ -0,0 +1,4 @@
html,
body {
margin: 0;
}

BIN
src/app/icon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

View file

@ -1,9 +1,9 @@
import type { Metadata } from 'next'
import { lato } from './fonts'
import './globals.css'
export const metadata: Metadata = {
title: 'Katholische Pfarrei Heilige drei Könige Berlin',
description: 'Generated by create next app',
}
export default function RootLayout({

View file

@ -33,7 +33,6 @@ export default async function Page({ params }: { params: { id: string } }) {
return (
<>
<Menu />
<Container>
<MassTitle title={title} cancelled={worship.cancelled} />

View file

@ -2,11 +2,13 @@
display: flex;
gap: 30px;
margin-bottom: 80px;
flex-wrap: wrap;
justify-content: center;
}
.cardContent {
padding-top: 30px;
padding-left: 50px;
text-align: center;
}
.cardText {

View file

@ -1,6 +1,6 @@
.card {
height: 260px;
width: 235px;
width: 240px;
box-shadow: 0 0 11px 0 rgba(79, 66, 79, 0.26);
background-color: #ffffff;
}

View file

@ -16,7 +16,6 @@ export const Default: Story = {
export const Yellow: Story = {
args: {
background: 'yellow',
children: <>Some content</>,
},
}

View file

@ -1,15 +1,9 @@
import styles from './styles.module.css'
import classNames from 'classnames'
type ContainerProps = {
background?: 'yellow'
children: JSX.Element | JSX.Element[]
}
export const Container = ({ children, background }: ContainerProps) => {
return (
<div className={classNames({ [styles.yellow]: background === 'yellow' })}>
<div className={styles.container}>{children}</div>
</div>
)
export const Container = ({ children }: ContainerProps) => {
return <div className={styles.container}>{children}</div>
}

View file

@ -1,15 +1,10 @@
.container {
width: 800px;
max-width: 800px;
margin: 0 auto;
}
.yellow {
background: rgb(255, 255, 97);
background: linear-gradient(
180deg,
rgba(255, 255, 97, 0) 0%,
rgb(255 250 163) 20%
);
position: relative;
top: -70px;
@media screen and (max-width: 800px) {
.container {
padding: 0 20px;
}
}

View file

@ -19,6 +19,7 @@ export type HomeBannerHandle = {
export const HomeBanner = forwardRef<HomeBannerHandle, HomeBannerProps>(
function HomeBanner({ children, stars }: HomeBannerProps, ref) {
const canvasRef = useRef<HTMLCanvasElement>(null)
const containerRef = useRef<HTMLDivElement>(null)
const drawStarAtPosition = useCallback(
(ctx: CanvasRenderingContext2D, x: number, y: number) => {
@ -57,7 +58,8 @@ export const HomeBanner = forwardRef<HomeBannerHandle, HomeBannerProps>(
useEffect(() => {
if (canvasRef.current) {
canvasRef.current.width = window.innerWidth
canvasRef.current.width =
containerRef.current?.clientWidth || window.innerWidth
canvasRef.current.height = 0.8 * window.innerHeight
}
const context = canvasRef.current?.getContext('2d')
@ -73,7 +75,7 @@ export const HomeBanner = forwardRef<HomeBannerHandle, HomeBannerProps>(
}, [drawStar, stars])
return (
<div className="splash-bg">
<div className="splash-bg" ref={containerRef}>
<canvas ref={canvasRef} className="stars"></canvas>
<div className="splash">{children}</div>
</div>

View file

@ -4,6 +4,7 @@ import { useEffect, useRef, useState } from 'react'
import mapboxgl from 'mapbox-gl'
import styles from './styles.module.css'
import 'mapbox-gl/dist/mapbox-gl.css'
import { Container } from '@/components/Container/Container'
// todo: as env variable
mapboxgl.accessToken =
@ -31,5 +32,9 @@ export const LocationMap = () => {
}
})
return <div ref={mapContainer} className={styles.map}></div>
return (
<Container>
<div ref={mapContainer} className={styles.map}></div>
</Container>
)
}

View file

@ -15,26 +15,38 @@ export const Default: Story = {
{
id: '1',
date: '10:00',
locationName: 'St. Christopherus',
type: null,
location: 'St. Christopherus',
type: 'MASS',
cancelled: false,
updatedAt: '',
createdAt: '',
},
{
id: '1',
date: '11:00',
locationName: 'St. Richard',
type: 'FAMILY',
date: '10:00',
location: 'St. Christopherus',
type: 'MASS',
cancelled: false,
updatedAt: '',
createdAt: '',
},
{
id: '1',
date: '11:00',
locationName: 'St. Clara',
type: 'WORD',
date: '10:00',
location: 'St. Christopherus',
type: 'MASS',
cancelled: false,
updatedAt: '',
createdAt: '',
},
{
id: '1',
date: '19:00',
locationName: 'St. Clara',
type: null,
date: '10:00',
location: 'St. Christopherus',
type: 'MASS',
cancelled: false,
updatedAt: '',
createdAt: '',
},
],
},

View file

@ -11,14 +11,30 @@ export default meta
export const OneDay: Story = {
args: {
timeout: new Date().getTime() + 1000 * 60 * 60 * 24,
nextMass: {
id: '1',
location: '231234',
date: '2025-08-23T15:00:00.000Z',
type: 'WORD',
cancelled: false,
createdAt: '2025-08-23T15:00:00.000Z',
updatedAt: '2025-08-23T15:00:00.000Z',
},
onStarClick: fn(),
},
}
export const TimeOut: Story = {
args: {
timeout: new Date().getTime(),
nextMass: {
id: '1',
location: '231234',
date: '2025-08-23T15:00:00.000Z',
type: 'WORD',
cancelled: false,
createdAt: '2025-08-23T15:00:00.000Z',
updatedAt: '2025-08-23T15:00:00.000Z',
},
onStarClick: fn(),
},
}

View file

@ -32,7 +32,10 @@ export const MassTimer = ({ nextMass, onStarClick }: MassTimerProps) => {
🌟
</button>
<span onMouseEnter={() => setDisplayTooltip(true)}>
<span
onMouseEnter={() => setDisplayTooltip(true)}
suppressHydrationWarning={true}
>
{days}T {hours}S {minutes}M {seconds}S
</span>
</div>

View file

@ -1,5 +1,6 @@
.container {
position: relative;
width: 145px;
}
.starButton {

View file

@ -1,7 +1,7 @@
.title {
font-size: 48px;
font-weight: 700;
margin-block-start: 0;
margin-block-start: -10px;
}
.mass {

View file

@ -18,7 +18,7 @@ export const Menu = (props: MenuProps) => {
<Image src={MenuIcon} width={25} height={25} alt={'Menu'} />
</div>
<div className={styles.itemsLeft}>
<a className={styles.menuLink} href={''}>
<a className={styles.menuLink} href={'/'}>
Home
</a>
<a className={styles.menuLink} href={''}>
@ -35,7 +35,7 @@ export const Menu = (props: MenuProps) => {
<div className={styles.itemsRight}>
<div>
<a className={styles.menuLink} href={''}>
Spenden
Mithelfen
</a>
</div>
<div>

View file

@ -2,10 +2,10 @@
display: flex;
align-items: baseline;
gap: 20px;
color: #3d3d3d;
padding-top: 15px;
height: 50px;
border-bottom: 1px solid rgba(217, 217, 217, 0.19);
color: #1f1f1f;
padding: 15px;
border-bottom: 1px solid rgba(255, 255, 255, 0.67);
margin-bottom: 2.5em;
}
.navMobile {

View file

@ -15,3 +15,12 @@ export const Default: Story = {
'Die Eucharistie ist für mich wie ein spiritueller Boost. Wenn ich die Hostie empfange, fühle ich mich krass verbunden mit Jesus. Es ist wie ein Reminder, dass ich nicht allein bin, egal was abgeht. Dieser Moment gibt mir richtig Power und lässt mich mit einem starken Gefühl von Frieden und Hoffnung rausgehen.',
},
}
export const WithOccupation: Story = {
args: {
name: 'Johan Schäfer',
testimony:
'Die Eucharistie ist für mich wie ein spiritueller Boost. Wenn ich die Hostie empfange, fühle ich mich krass verbunden mit Jesus. Es ist wie ein Reminder, dass ich nicht allein bin, egal was abgeht. Dieser Moment gibt mir richtig Power und lässt mich mit einem starken Gefühl von Frieden und Hoffnung rausgehen.',
occupation: 'Schüler',
},
}

View file

@ -2,22 +2,32 @@ import styles from './styles.module.css'
import { Container } from '@/components/Container/Container'
import classNames from 'classnames'
import { faustina } from '@/app/fonts'
import Image from 'next/image'
import quote from './quotes.svg'
type TestimonyProps = {
name: string
testimony: string
occupation?: string
}
export const Testimony = ({ name, testimony }: TestimonyProps) => {
export const Testimony = ({ name, testimony, occupation }: TestimonyProps) => {
return (
<Container background={'yellow'}>
<Container>
<div className={styles.testimony}>
<div className={styles.person}></div>
<div>
<div className={styles.container}>
<Image
src={quote}
alt={'Quote'}
width={100}
className={classNames(styles.quote, styles.slidein)}
/>
<p className={classNames(styles.testimonyText, faustina.className)}>
{testimony}
</p>
<p>{name}</p>
<p className={styles.name}>
{name} {occupation && <>- {occupation}</>}
</p>
</div>
</div>
</Container>

View file

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg height="800px" width="800px" version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
viewBox="0 0 46.195 46.195" xml:space="preserve">
<g>
<path style="fill:#FFFF61;" d="M35.765,8.264c-5.898,0-10.555,4.782-10.555,10.68s4.844,10.68,10.742,10.68
c0.059,0,0.148-0.008,0.207-0.009c-2.332,1.857-5.261,2.976-8.467,2.976c-1.475,0-2.662,1.196-2.662,2.67s0.949,2.67,2.424,2.67
c10.469-0.001,18.741-8.518,18.741-18.987c0-0.002,0-0.004,0-0.007C46.195,13.042,41.661,8.264,35.765,8.264z"/>
<path style="fill:#FFFF61;" d="M10.75,8.264c-5.898,0-10.563,4.782-10.563,10.68s4.84,10.68,10.739,10.68
c0.059,0,0.146-0.008,0.205-0.009c-2.332,1.857-5.262,2.976-8.468,2.976C1.188,32.591,0,33.787,0,35.261s0.964,2.67,2.439,2.67
c10.469-0.001,18.756-8.518,18.756-18.987c0-0.002,0-0.004,0-0.007C21.195,13.042,16.646,8.264,10.75,8.264z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1,013 B

View file

@ -7,11 +7,41 @@
.testimonyText {
font-style: italic;
line-height: 1.7em;
font-size: 1.1em;
}
.container {
position: relative;
}
.person {
height: 150px;
width: 150px;
background-color: white;
background-color: #f6dc66;
flex-shrink: 0;
}
.name {
text-align: right;
font-weight: bold;
}
.quote {
position: absolute;
top: -10px;
left: -10px;
opacity: 0.5;
z-index: -1;
}
.slidein {
transform: translateX(-100%);
animation: slide-in 0.3s forwards;
}
@keyframes slide-in {
100% {
transform: translateX(0%);
}
}

View file

@ -8,161 +8,162 @@
export interface Config {
auth: {
users: UserAuthOperations
}
users: UserAuthOperations;
};
collections: {
users: User
media: Media
worship: Worship
church: Church
testimony: Testimony
'payload-preferences': PayloadPreference
'payload-migrations': PayloadMigration
}
users: User;
media: Media;
worship: Worship;
church: Church;
testimony: Testimony;
'payload-preferences': PayloadPreference;
'payload-migrations': PayloadMigration;
};
db: {
defaultIDType: string
}
globals: {}
locale: null
defaultIDType: string;
};
globals: {};
locale: null;
user: User & {
collection: 'users'
}
collection: 'users';
};
}
export interface UserAuthOperations {
forgotPassword: {
email: string
password: string
}
email: string;
password: string;
};
login: {
email: string
password: string
}
email: string;
password: string;
};
registerFirstUser: {
email: string
password: string
}
email: string;
password: string;
};
unlock: {
email: string
password: string
}
email: string;
password: string;
};
}
/**
* This interface was referenced by `Config`'s JSON-Schema
* via the `definition` "users".
*/
export interface User {
id: string
updatedAt: string
createdAt: string
email: string
resetPasswordToken?: string | null
resetPasswordExpiration?: string | null
salt?: string | null
hash?: string | null
loginAttempts?: number | null
lockUntil?: string | null
password?: string | null
id: string;
updatedAt: string;
createdAt: string;
email: string;
resetPasswordToken?: string | null;
resetPasswordExpiration?: string | null;
salt?: string | null;
hash?: string | null;
loginAttempts?: number | null;
lockUntil?: string | null;
password?: string | null;
}
/**
* This interface was referenced by `Config`'s JSON-Schema
* via the `definition` "media".
*/
export interface Media {
id: string
alt: string
updatedAt: string
createdAt: string
url?: string | null
thumbnailURL?: string | null
filename?: string | null
mimeType?: string | null
filesize?: number | null
width?: number | null
height?: number | null
focalX?: number | null
focalY?: number | null
id: string;
alt: string;
updatedAt: string;
createdAt: string;
url?: string | null;
thumbnailURL?: string | null;
filename?: string | null;
mimeType?: string | null;
filesize?: number | null;
width?: number | null;
height?: number | null;
focalX?: number | null;
focalY?: number | null;
}
/**
* This interface was referenced by `Config`'s JSON-Schema
* via the `definition` "worship".
*/
export interface Worship {
id: string
date: string
location: string | Church
type: 'MASS' | 'FAMILY' | 'WORD'
cancelled: boolean
title?: string | null
description?: string | null
updatedAt: string
createdAt: string
id: string;
date: string;
location: string | Church;
type: 'MASS' | 'FAMILY' | 'WORD';
cancelled: boolean;
title?: string | null;
description?: string | null;
updatedAt: string;
createdAt: string;
}
/**
* This interface was referenced by `Config`'s JSON-Schema
* via the `definition` "church".
*/
export interface Church {
id: string
name: string
address: string
updatedAt: string
createdAt: string
id: string;
name: string;
address: string;
updatedAt: string;
createdAt: string;
}
/**
* This interface was referenced by `Config`'s JSON-Schema
* via the `definition` "testimony".
*/
export interface Testimony {
id: string
testimony: string
name: string
occupation?: string | null
category: 'EUCHARIST'
updatedAt: string
createdAt: string
id: string;
testimony: string;
name: string;
occupation?: string | null;
category: 'EUCHARIST';
updatedAt: string;
createdAt: string;
}
/**
* This interface was referenced by `Config`'s JSON-Schema
* via the `definition` "payload-preferences".
*/
export interface PayloadPreference {
id: string
id: string;
user: {
relationTo: 'users'
value: string | User
}
key?: string | null
relationTo: 'users';
value: string | User;
};
key?: string | null;
value?:
| {
[k: string]: unknown
[k: string]: unknown;
}
| unknown[]
| string
| number
| boolean
| null
updatedAt: string
createdAt: string
| null;
updatedAt: string;
createdAt: string;
}
/**
* This interface was referenced by `Config`'s JSON-Schema
* via the `definition` "payload-migrations".
*/
export interface PayloadMigration {
id: string
name?: string | null
batch?: number | null
updatedAt: string
createdAt: string
id: string;
name?: string | null;
batch?: number | null;
updatedAt: string;
createdAt: string;
}
/**
* This interface was referenced by `Config`'s JSON-Schema
* via the `definition` "auth".
*/
export interface Auth {
[k: string]: unknown
[k: string]: unknown;
}
declare module 'payload' {
export interface GeneratedTypes extends Config {}
}
}