feature: Event excerpt with clickable mail address

This commit is contained in:
Benno Tielen 2024-12-13 12:05:00 +01:00
parent 2cce2676db
commit ef913bc500
7 changed files with 98 additions and 74 deletions

View file

@ -0,0 +1,28 @@
import { Meta, StoryObj } from '@storybook/react'
import { ContactPerson2 } from './ContactPerson2'
const meta: Meta<typeof ContactPerson2> = {
component: ContactPerson2,
}
type Story = StoryObj<typeof ContactPerson2>;
export default meta
export const Default: Story = {
args: {
contact: {
id: "some_id",
name: "Pfr. M. Mustermann",
email: "m.mustermann@gmail.com",
telephone: "+491234567890",
createdAt: "2021-03-01T00:00:00.000Z",
updatedAt: ""
}
},
}
export const NotFound: Story = {
args: {
contact: "Some weird id"
},
}

View file

@ -0,0 +1,29 @@
import styles from "./styles.module.scss"
import { ContactPerson } from '@/payload-types'
type ContactPerson2Props = {
contact: null | string | undefined | ContactPerson
}
export const ContactPerson2 = ({contact}: ContactPerson2Props) => {
if (contact === null || contact === undefined || typeof contact === 'string') {
return "Unbekannt"
}
return (
<div className={styles.contact}>
{contact.name}
{contact.email &&
<>
<br/> <a href={`mailto:${contact.email}`} className={styles.hover}>{contact.email}</a>
</>
}
{
contact.telephone &&
<>
<br/> <a href={`tel:${contact.telephone}`}>{contact.telephone}</a>
</>
}
</div>
)
}

View file

@ -0,0 +1,8 @@
.contact a {
text-decoration: none;
color: inherit;
}
.hover:hover {
text-decoration: underline;
}

View file

@ -1,5 +1,6 @@
import { Meta, StoryObj } from '@storybook/react' import { Meta, StoryObj } from '@storybook/react'
import { EventExcerpt } from './EventExcerpt' import { EventExcerpt, EventExcerptRow } from './EventExcerpt'
import { TextDiv } from '@/components/Text/TextDiv'
const meta: Meta<typeof EventExcerpt> = { const meta: Meta<typeof EventExcerpt> = {
component: EventExcerpt, component: EventExcerpt,
@ -10,21 +11,17 @@ export default meta
export const Default: Story = { export const Default: Story = {
args: { args: {
what: 'Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum.', children: <>
where: 'St. Richard\n' + <EventExcerptRow label={"What: "}>
'Braunschweiger Str. 18, 12055 Berlin \n' + <TextDiv text={"Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum."}/>
'Anfahrt über S-Sonnenallee oder Mareschtraße \n', </EventExcerptRow>
who: 'Pfarrei Ulrich Kotzur\n' + <EventExcerptRow label={"Where:"}>
'pfarrer@sankt-clara.de\n' + <p>
'+4930 6851042' St. Richard<br/>
}, Braunschweiger Str. 18, 12055 Berlin<br/>
} Anfahrt über S-Sonnenallee oder Mareschtraße
</p>
export const OnlyWhatAndWhere: Story = { </EventExcerptRow>
args: { </>
what: 'Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum.',
where: 'St. Richard\n' +
'Braunschweiger Str. 18, 12055 Berlin \n' +
'Anfahrt über S-Sonnenallee oder Mareschtraße \n',
}, },
} }

View file

@ -1,44 +1,31 @@
import styles from "./styles.module.scss" import styles from "./styles.module.scss"
import { TextDiv } from '@/components/Text/TextDiv'
type EventExcerptProps = { type EventExcerptProps = {
what?: string | null, children?: React.ReactNode
where?: string | null,
who?: string | null
} }
type RowProps = { type RowProps = {
label: string, label: string,
text: string children: React.ReactNode
} }
const Row = ({label, text}: RowProps) => { export const EventExcerptRow = ({label, children}: RowProps) => {
return ( return (
<div className={styles.row}> <div className={styles.row}>
<div className={styles.col1}> <div className={styles.col1}>
{label} {label}
</div> </div>
<div> <div>
<TextDiv text={text} /> {children}
</div> </div>
</div> </div>
) )
} }
export const EventExcerpt = ({ what, where, who }: EventExcerptProps) => { export const EventExcerpt = ({ children }: EventExcerptProps) => {
return ( return (
<div className={styles.container}> <div className={styles.container}>
{ what && {children}
<Row label={"Was:"} text={what} />
}
{ where &&
<Row label={"Wo:"} text={where} />
}
{ who &&
<Row label={"Ansprechperson:"} text={who} />
}
</div> </div>
) )
} }

View file

@ -3,18 +3,17 @@ import { ContactPerson, Document, Location } from '@/payload-types'
import { Section } from '@/components/Section/Section' import { Section } from '@/components/Section/Section'
import { Title } from '@/components/Title/Title' import { Title } from '@/components/Title/Title'
import { Container } from '@/components/Container/Container' import { Container } from '@/components/Container/Container'
import { Row } from '@/components/Flex/Row'
import { Col } from '@/components/Flex/Col' import { Col } from '@/components/Flex/Col'
import { Pill } from '@/components/Pill/Pill' import { Pill } from '@/components/Pill/Pill'
import { HR } from '@/components/HorizontalRule/HorizontalRule' import { HR } from '@/components/HorizontalRule/HorizontalRule'
import { useDate } from '@/hooks/useCompactDate' import { useDate } from '@/hooks/useCompactDate'
import { readableDateTime } from '@/utils/readableDate' import { readableDateTime } from '@/utils/readableDate'
import { TextDiv } from '@/components/Text/TextDiv' import { TextDiv } from '@/components/Text/TextDiv'
import { EventExcerpt } from '@/components/EventExcerpt/EventExcerpt' import { EventExcerpt, EventExcerptRow } from '@/components/EventExcerpt/EventExcerpt'
import { Button } from '@/components/Button/Button' import { Button } from '@/components/Button/Button'
import { StaticImageData } from 'next/image' import { StaticImageData } from 'next/image'
import { locationString } from '@/utils/dto/location' import { locationString } from '@/utils/dto/location'
import { contactPersonString } from '@/utils/dto/contact' import { ContactPerson2 } from '@/components/ContactPerson2/ContactPerson2'
type EventProps = { type EventProps = {
title: string, title: string,
@ -50,7 +49,6 @@ export function EventPage(
const published = useDate(createdAt) const published = useDate(createdAt)
const readableDate = readableDateTime(date) const readableDate = readableDateTime(date)
const where = locationString(location); const where = locationString(location);
const who = contactPersonString(contact)
return ( return (
<> <>
@ -140,11 +138,17 @@ export function EventPage(
</Section> </Section>
</Container> </Container>
<EventExcerpt <EventExcerpt>
what={shortDescription} <EventExcerptRow label={"Was:"}>
where={where} <TextDiv text={shortDescription} />
who={who} </EventExcerptRow>
/> <EventExcerptRow label={"Wo:"}>
<TextDiv text={where} />
</EventExcerptRow>
<EventExcerptRow label={"Ansprechperson:"}>
<ContactPerson2 contact={contact} />
</EventExcerptRow>
</EventExcerpt>
</Section> </Section>
<Section/> <Section/>

View file

@ -1,29 +0,0 @@
import { ContactPerson } from '@/payload-types'
/**
* Return contact person as a readable string
*
* e.G
*
* Hans Mustermann
* hans@mustermann.com
* 030-65625885
*/
export const contactPersonString = (c: string | ContactPerson | undefined) => {
if(typeof c === "string" || !c) {
return "Unbekannt"
}
let s = c.name
if (c.email) {
s += '\n' + c.email;
}
if (c.telephone) {
s += '\n' + c.telephone;
}
return s
}