event page progress, make separate details component and move some stuff around

This commit is contained in:
elise
2024-08-07 21:21:02 +02:00
parent 8c5a9ad132
commit 6d3581886f
10 changed files with 150 additions and 135 deletions

View File

@ -1,6 +1,6 @@
import { getClient } from "@/app/client";
import { Blocks } from "@/components/blocks/Blocks";
import { DateList } from "@/components/events/DateList";
import { EventDetails } from "@/components/events/EventDetails";
import { EventHeader } from "@/components/events/EventHeader";
import { BgPig } from "@/components/general/BgPig";
import { graphql } from "@/gql";
@ -54,8 +54,8 @@ export default async function Page({ params }: { params: { slug: string } }) {
<>
<main className="site-main" id="main">
<EventHeader event={event} />
<EventDetails event={event} />
<section className="pageContent">
<DateList event={event} />
<Blocks blocks={event.body} />
</section>
</main>

View File

@ -54,10 +54,7 @@ export const DateList = ({ event }: { event: EventFragment }) => {
return (
<div className={styles.dateWrapper}>
<h2 className="circlehead">
<span className="circle"></span>
<span className="circle"></span>
<span className="circle"></span>
<h2 className="suphead">
Kommende datoer{" "}
<span className="number">({futureOccurrences.length})</span>
</h2>

View File

@ -0,0 +1,68 @@
import { EventFragment } from "@/lib/event";
import styles from "./eventDetails.module.scss";
import { OrganizerList } from "./OrganizerList";
import Icon from "../general/Icon";
import { DateList } from "./DateList";
function formatPrice(price: number): string {
if (price === null) {
// should not happen
return "?";
}
if (price === 0) {
return "Gratis";
}
return `${price} kr`;
}
export const EventDetails = ({ event }: { event: EventFragment }) => {
const featuredImage: any = event.featuredImage;
return (
<div className={styles.eventDetails}>
<div className={styles.content}>
<div className={styles.prices}>
<span className="suphead">Pris</span>
<ul className={styles.priceList}>
{event.free && (
<li className={styles.priceItem}>
<span>Gratis</span>
</li>
)}
{typeof event.priceRegular === "number" && (
<li className={styles.priceItem}>
<span className={styles.priceLabel}>Ordinær</span>{" "}
{formatPrice(event.priceRegular)}
</li>
)}
{typeof event.priceStudent === "number" && (
<li className={styles.priceItem}>
<span className={styles.priceLabel}>Student</span>{" "}
{formatPrice(event.priceStudent)}
</li>
)}
{typeof event.priceMember === "number" && (
<li className={styles.priceItem}>
<span className={styles.priceLabel}>Medlem</span>{" "}
{formatPrice(event.priceMember)}
</li>
)}
</ul>
</div>
{event.organizers && (
<div>
<div className="suphead">Arrangeres av</div>{" "}
<OrganizerList event={event} />
</div>
)}
{event.facebookUrl && (
<a href={event.facebookUrl} className="button tertiary">
<span> til Facebook-event</span>
<Icon type="externalLink" />
</a>
)}
</div>
<DateList event={event} />
</div>
);
};

View File

@ -1,21 +1,8 @@
import { EventFragment } from "@/lib/event";
import styles from "./eventHeader.module.scss";
import { Image } from "@/components/general/Image";
import Link from "next/link";
import { OrganizerList } from "./OrganizerList";
import Icon from "../general/Icon";
import { Breadcrumb } from "../general/Breadcrumb";
function formatPrice(price: number): string {
if (price === null) {
// should not happen
return "?";
}
if (price === 0) {
return "Gratis";
}
return `${price} kr`;
}
import Icon from "../general/Icon";
export const EventHeader = ({ event }: { event: EventFragment }) => {
// TODO: where should we show image attribution for the featured image?
@ -24,63 +11,23 @@ export const EventHeader = ({ event }: { event: EventFragment }) => {
return (
<div className={styles.eventHeader}>
<div className={styles.text}>
<Breadcrumb link="/arrangementer" text="Arrangement" />
<h1 className={styles.title}>{event.title}</h1>
<div className={styles.eventDetails}>
<div className={styles.prices}>
<span className={styles.label}>Pris:</span>
<ul className={styles.priceList}>
{event.free && (
<li className={styles.priceItem}>
<span>Gratis</span>
</li>
)}
{typeof event.priceRegular === "number" && (
<li className={styles.priceItem}>
<span className={styles.priceLabel}>Ordinær:</span>{" "}
{formatPrice(event.priceRegular)}
</li>
)}
{typeof event.priceStudent === "number" && (
<li className={styles.priceItem}>
<span className={styles.priceLabel}>Student:</span>{" "}
{formatPrice(event.priceStudent)}
</li>
)}
{typeof event.priceMember === "number" && (
<li className={styles.priceItem}>
<span className={styles.priceLabel}>Medlem:</span>{" "}
{formatPrice(event.priceMember)}
</li>
)}
</ul>
<div className={styles.heading}>
{/*<Breadcrumb link="/arrangementer" text="Arrangement" />*/}
{event.categories.length > 0 && (
<div className={styles.categories}>
{event.categories.map(category => (
<div key={category.name} className="tag">{category.name}</div>
))}
</div>
{event.categories.length > 0 && (
<div>
<span className={styles.label}>Kategorier:</span>{" "}
{event.categories.map((x) => x.name).join(", ")}
</div>
)}
{event.organizers && (
<div>
<span className={styles.label}>Arrangeres av:</span>{" "}
<OrganizerList event={event} />
</div>
)}
</div>
)}
<h1 className={styles.title}>{event.title}</h1>
<p className={styles.details}>Evt. andre detaljer</p>
{event.ticketUrl && (
<a href={event.ticketUrl} className="button cta">
<span>Kjøp billetter</span>
<Icon type="tickets" />
</a>
)}
{event.facebookUrl && (
<a href={event.facebookUrl} className="button tertiary">
<span> til Facebook-event</span>
<Icon type="externalLink" />
</a>
)}
</div>
<div className={styles.image}>
{featuredImage && (

View File

@ -1,26 +1,19 @@
.dateWrapper {
background: var(--color-background-secondary);
margin: 0 calc(var(--spacing-sitepadding-inline)*-1) var(--spacing-sitepadding-block);
padding: var(--spacing-s) var(--spacing-sitepadding-inline) var(--spacing-m);
margin-top: var(--spacing-m);
}
.dateList {
list-style: none;
display: flex;
gap: var(--spacing-s);
margin-top: var(--spacing-xs);
}
.date {
display: inline-block;
font-family: var(--font-serif);
font-size: var(--font-size-body);
position: relative;
line-height: 1.2;
border-right: var(--border);
padding-right: var(--spacing-s);
&:last-child {
border: none;
}
margin: 0 2rem 1rem 0;
}
.time {

View File

@ -0,0 +1,36 @@
.eventDetails {
background: var(--color-background-secondary);
margin: 0 calc(var(--spacing-sitepadding-inline)*-1) var(--spacing-sitepadding-block);
padding: var(--spacing-s) var(--spacing-sitepadding-inline) var(--spacing-m);
}
.content {
display: grid;
grid-template-columns: repeat(4, 1fr);
column-gap: var(--spacing-gap-column);
margin-bottom: var(--spacing-gap-row);
align-items: flex-start;
}
.priceList {
list-style: none;
max-width: 10rem;
}
.priceItem {
position: relative;
display: grid;
grid-template-columns: 1fr 1fr;
gap: 1rem;
text-align: right;
}
.priceLabel {
display: block;
text-align: left;
}
.label {
font-weight: 600;
width: 7rem;
}

View File

@ -3,8 +3,14 @@
display: grid;
grid-template-columns: repeat(3, 1fr);
column-gap: var(--spacing-gap-column);
align-items: flex-end;
row-gap: var(--spacing-gap-row);
align-items: center;
padding: 0;
margin: calc(var(--spacing-sitepadding-block)*-1) auto 0;
}
.categories {
margin: 0 0 var(--spacing-m);
}
.title {
@ -13,7 +19,6 @@
.image {
grid-column: span 2;
margin-top: calc(var(--spacing-sitepadding-block)*-2);
img {
max-width: 100%;
@ -22,58 +27,14 @@
}
}
.text {
padding-bottom: var(--spacing-m);
.details {
font-size: var(--font-size-h2);
font-family: var(--font-serif);
margin: var(--spacing-xs) 0 var(--spacing-l);
}
.eventDetails {
font-size: var(--font-size-caption);
margin: var(--spacing-m) 0;
>div {
padding: var(--spacing-xs) 0;
border-bottom: var(--border);
display: flex;
@media (max-width: 800px) {
.eventHeader {
grid-template-columns: 1fr;
}
}
.prices {
padding: var(--spacing-xs) 0 0;
border-top: var(--border);
display: flex;
}
.priceList {
list-style: none;
//flex-grow: 1;
}
.priceItem {
position: relative;
display: grid;
grid-template-columns: 1fr 1fr;
gap: 1rem;
/*padding: var(--spacing-xs) 0;
border-bottom: var(--border);
&:first-child {
padding-top: 0;
}
&:last-child {
border-bottom: 0;
padding-bottom: 0;
}*/
}
.priceLabel {
display: block;
}
.label {
font-weight: 600;
}
.label {
width: 7rem;
}

View File

@ -4,6 +4,5 @@
li {
display: inline;
font-size: var(--font-size-caption);
}
}

View File

@ -328,3 +328,16 @@ select {
max-width: var(--size-width-p);
margin: 0 auto 1rem;
}
.tag {
display: inline-block;
border-radius: 10rem;
background: var(--color-goldenBeige);
color: var(--color-deepBrick);
padding: 0 .7em;
margin: 0 .4em var(--spacing-s) 0;
font-family: var(--font-main);
font-size: var(--font-size-caption);
font-weight: 500;
text-decoration: none;
}

View File

@ -62,6 +62,7 @@
// sizes
--size-width-p: 36rem;
--size-width-lead: 48rem;
--size-width-pageheader: 54rem;
--size-icon: 1em;
--size-icon-circle: 2.4rem;
--size-icon-large: 3.4rem;