Import repositories from gitlab

This commit is contained in:
Julien Aldon
2026-01-19 11:43:59 +01:00
commit 68b7405c52
131 changed files with 17192 additions and 0 deletions

View File

@@ -0,0 +1,216 @@
import getData from "@/api";
import styles from "./style.module.scss";
import EditionElement from "@/components/editionElement";
import EditionGallery from "@/components/editionGallery";
import PressBlock from "@/components/pressBlock";
import Empty from "@/components/empty";
import VideoBlock from "@/components/videoBlock";
import Fanfare from "@/components/fanfare";
export const dynamic = "force-dynamic";
export async function generateMetadata({ params }) {
const data = await getData(`editions/${params.editionId}`, {
populate: {
flyer: {
fields: ["name", "alternativeText", "caption", "url"],
},
},
filters: {
$or: [{ id: { $eq: params.editionId } }],
},
});
const activeEditionData = await getData("site", {
populate: {
edition: {
fields: ["id"],
},
},
fields: ["author"],
});
const activeEdition = activeEditionData?.data?.attributes.edition.data.id;
const edition = data.data?.attributes.publishedAt ? data : null;
const flyer = edition?.data?.attributes.flyer.data.attributes;
return edition
? {
metadataBase: `${process.env.NEXT_PUBLIC_ORIGIN}`,
title: edition.title,
description: edition.description,
alternates: {
canonical:
data.data.id !== activeEdition
? `${process.env.NEXT_PUBLIC_ORIGIN}/editions/${params.editionId}`
: `${process.env.NEXT_PUBLIC_ORIGIN}`,
},
openGraph: {
title: edition.title,
url:
data.data.id !== activeEdition
? `${process.env.NEXT_PUBLIC_ORIGIN}/editions/${params.editionId}`
: `${process.env.NEXT_PUBLIC_ORIGIN}`,
description: edition.description,
images: {
url: `${process.env.NEXT_PUBLIC_IMG_URI}${flyer.url}`,
width: flyer.width,
height: flyer.height,
},
authors: [activeEditionData.data.attributes.author],
type: "website",
locale: "fr_FR",
siteName: "Le Fefan - Festival de Fanfares",
},
}
: {};
}
export default async function Edition({ params }) {
const data = await getData(`editions/${params.editionId}`, {
populate: {
flyer: {
fields: ["name", "alternativeText", "caption", "url"],
},
gallery: {
fields: ["name", "alternativeText", "caption", "url"],
},
programs: {
fields: ["map_uri", "introduction", "description", "title", "type"],
populate: {
bands: {
fields: ["name", "location"],
},
},
},
statistics: {
fields: ["name", "value", "publishedAt"],
},
social_links: {
fields: ["uri", "type"],
},
articles: {
fields: ["title", "link", "excerpt", "publishedAt"],
},
fields: ["movie"],
},
filters: {
$or: [{ id: { $eq: params.editionId } }],
},
});
const edition = data.data?.attributes.publishedAt ? data : null;
const flyer = edition?.data?.attributes.flyer.data.attributes;
const gallery = edition?.data?.attributes.gallery.data;
const statistics = edition?.data?.attributes.statistics.data;
const allArticles = edition?.data?.attributes.articles.data;
const articles = allArticles
? allArticles.filter((el) => el.attributes.publishedAt != null)
: [];
const movie = edition.data.attributes.movie
? edition.data.attributes.movie
: null;
const programs = edition?.data?.attributes?.programs?.data
? edition.data.attributes.programs.data
: [];
const program =
programs.filter((el) => el.attributes.type === "city-wide")[0] ?? null;
const bands = program ? program?.attributes?.bands.data : [];
return (
<main className={styles.main}>
{edition ? (
<>
<h2>{edition.data.attributes.title}</h2>
<h3>{edition.data.attributes.subtitle}</h3>
<EditionElement
flyerImg={`${process.env.NEXT_PUBLIC_IMG_URI}${flyer.url}`}
flyerAlt={flyer.alternativeText}
blocks={statistics.map(({ id, attributes }) => ({
id,
type: "stat",
title: attributes.name,
value: attributes.value,
}))}
/>
{movie && bands ? (
<section className={styles.smallProgram}>
{bands.length > 0 ? (
<article className={styles.featuring}>
<h4>Les fanfares</h4>
{bands.map(({ id, attributes: attr }) => {
return (
<Fanfare
key={id}
location={attr.location}
name={attr.name}
/>
);
})}
</article>
) : null}
{movie ? (
<>
<VideoBlock
src={movie}
title={`Aftermovie du festival ${
edition.data.attributes?.title ?? ""
}`}
/>
</>
) : null}
</section>
) : null}
{articles.length > 0 ? (
<>
<h4>Ils ont parlé de nous !</h4>
{articles.map(({ id, attributes }, index) => {
const offset = index + (articles.length - gallery.length) / 2;
return index < gallery.length ? (
<PressBlock
key={id}
left={{
type: "article",
title: attributes.title,
content: attributes.excerpt,
link: attributes.link,
}}
right={{
type: "image",
alt: gallery[index].attributes.alternativeText,
src: `${process.env.NEXT_PUBLIC_IMG_URI}${gallery[index].attributes.url}`,
}}
/>
) : (
<PressBlock
key={id}
left={{
type: "article",
title: attributes.title,
content: attributes.excerpt,
link: attributes.link,
}}
right={
articles[offset]
? {
type: "article",
title: articles[offset].title,
content: articles[offset].excerpt,
link: articles[offset].link,
}
: { type: null }
}
/>
);
})}
</>
) : null}
{articles.length <= gallery.length ? (
<>
<h4>Les photos du Fefan</h4>
<EditionGallery images={gallery.slice(articles.length)} />
</>
) : null}
</>
) : (
<Empty message="Il n'y a aucune information pour cette édition à afficher." />
)}
</main>
);
}

View File

@@ -0,0 +1,64 @@
.main {
flex: 1 1 0%;
display: flex;
align-items: center;
flex-flow: column;
padding-top: 1rem;
h2 {
font-family: var(--font-details);
font-size: 2rem;
font-weight: 400;
margin: 0;
}
h3 {
font-size: 0.75rem;
color: var(--fg-1);
font-weight: 700;
text-transform: uppercase;
margin: 0;
margin-bottom: 1rem;
}
h4 {
font-family: var(--font-details);
font-size: 1.8rem;
font-weight: 400;
}
.smallProgram {
margin-top: 2rem;
display: flex;
.featuring {
h4 {
grid-column: 1 / -1;
}
display: grid;
align-self: center;
grid-template-columns: repeat(2, calc(80rem / 6));
align-self: stretch;
padding: 0 0.5rem;
justify-self: stretch;
align-items: stretch;
justify-items: stretch;
align-content: start;
grid-auto-rows: max-content;
}
}
}
@media (max-width: 60rem) {
.main {
.smallProgram {
flex-direction: column;
.featuring {
grid-template-columns: 1fr;
align-self: center;
}
}
}
}

132
next/app/editions/page.js Normal file
View File

@@ -0,0 +1,132 @@
import getData from "@/api";
import styles from "./style.module.scss";
import EditionElement from "@/components/editionElement";
import Empty from "@/components/empty";
export const dynamic = "force-dynamic";
export async function generateMetadata() {
const site = await getData("site", {
fields: ["description", "author"],
});
const data = await getData("editions", {
populate: {
gallery: {
fields: ["name", "url", "alternativeText"],
},
statistics: {
fields: ["name", "value"],
},
flyer: {
fields: ["name", "url", "alternativeText", "width", "height"],
},
},
});
const editions = data.data;
return site.data
? {
metadataBase: `${process.env.NEXT_PUBLIC_ORIGIN}`,
title: "Editions précédentes — Le Fefan",
description: site.data.attributes.description,
alternates: {
canonical: "/editions",
},
openGraph: {
title: "Editions précédentes — Le Fefan",
url: `${process.env.NEXT_PUBLIC_ORIGIN}/prog/city-wide`,
description: site.data.attributes.description,
images: editions.map(({ attributes: attr }) => ({
width: attr.flyer.data.attributes.width,
height: attr.flyer.data.attributes.height,
alt: attr.flyer.data.attributes.alternativeText,
url: attr.flyer.data.attributes.url,
})),
authors: [site.data.attributes.author],
type: "website",
locale: "fr_FR",
siteName: "Le Fefan - Festival de Fanfares",
},
}
: {};
}
export default async function Editions() {
const site = await getData("site", {
fields: ["id"],
populate: {
edition: {
fields: ["id"],
},
},
});
const data = await getData("editions", {
populate: {
gallery: {
fields: ["name", "url", "alternativeText"],
},
statistics: {
fields: ["name", "value"],
},
flyer: {
fields: ["name", "url", "alternativeText"],
},
fields: ["movie"],
},
});
const editions = (data.data ?? []).filter(
(e) => e.id !== site.data?.attributes.edition.data?.id
);
return (
<main className={styles.main}>
{editions ? (
editions.map(({ id, attributes: attr }) => {
const stats = attr.statistics.data.map(({ id, attributes }) => ({
id,
type: "stat",
title: attributes.name,
value: attributes.value,
}));
const images = attr.gallery.data.map(({ id, attributes }) => ({
id,
type: "image",
title: attributes.alternativeText,
value: `${process.env.NEXT_PUBLIC_IMG_URI}${attributes.url}`,
}));
const movie = attr.movie
? [
{
id: "movie",
type: "video",
title: `Aftermovie ${attr.title}`,
value: attr.movie,
mode: "thumbnail",
},
]
: null;
return (
<EditionElement
full
key={id}
href={`/editions/${id}`}
title={attr.title}
blocks={
movie
? stats.concat(movie).concat(images)
: stats.concat(images)
}
flyerImg={`${process.env.NEXT_PUBLIC_IMG_URI}${attr.flyer.data.attributes.url}`}
flyerAlt={attr.flyer.data.attributes.alternativeText}
/>
);
})
) : (
<Empty message="Il n'y a aucune édition à afficher."></Empty>
)}
</main>
);
}

View File

@@ -0,0 +1,12 @@
.main {
flex: 1 1 0%;
display: flex;
flex-flow: column;
align-items: center;
height: 100vh;
overflow: auto;
scroll-snap-type: y mandatory;
// .editionLink {
// }
}