From 68b7405c52615ef5cdf4dca99284e3c56faaaeda Mon Sep 17 00:00:00 2001 From: Julien Aldon Date: Mon, 19 Jan 2026 11:43:59 +0100 Subject: [PATCH] Import repositories from gitlab --- next/.dockerignore | 15 + next/.env.example | 5 + next/.eslintrc.json | 3 + next/.gitignore | 38 + next/Dockerfile | 32 + next/README.md | 36 + next/api/index.js | 19 + next/app/contact/page.js | 24 + next/app/contact/style.module.scss | 37 + next/app/editions/[editionId]/page.js | 216 + .../editions/[editionId]/style.module.scss | 64 + next/app/editions/page.js | 132 + next/app/editions/style.module.scss | 12 + next/app/favicon.ico | Bin 0 -> 739 bytes next/app/globals.css | 44 + next/app/layout.js | 28 + next/app/legal/page.js | 22 + next/app/legal/style.module.scss | 29 + next/app/page.js | 114 + next/app/page.module.scss | 84 + next/app/prog/city-wide/page.js | 136 + next/app/prog/city-wide/style.module.scss | 95 + next/app/prog/village/page.js | 131 + next/app/prog/village/style.module.scss | 40 + next/app/sitemap.js | 74 + next/app/sponsor/page.js | 63 + next/app/sponsor/style.module.scss | 49 + next/components/articleBlock/index.jsx | 20 + .../components/articleBlock/style.module.scss | 17 + next/components/button/index.jsx | 28 + next/components/button/style.module.scss | 47 + .../editionElement/editionBlock/index.jsx | 32 + .../editionBlock/style.module.scss | 3 + next/components/editionElement/index.jsx | 31 + .../editionElement/style.module.scss | 157 + next/components/editionGallery/index.jsx | 17 + .../editionGallery/style.module.scss | 34 + next/components/email/index.jsx | 63 + next/components/email/style.module.scss | 20 + next/components/empty/index.jsx | 15 + next/components/empty/style.module.scss | 9 + next/components/fanfare/index.jsx | 10 + next/components/fanfare/style.module.scss | 22 + next/components/footer/index.jsx | 14 + next/components/footer/style.module.scss | 13 + next/components/header/index.jsx | 34 + .../header/navigationDrawer/index.jsx | 46 + .../header/navigationDrawer/style.module.scss | 156 + next/components/header/social-icon/index.jsx | 38 + next/components/header/style.module.scss | 0 next/components/imageBlock/index.jsx | 33 + next/components/imageBlock/style.module.scss | 4 + next/components/imagePopup/index.jsx | 32 + next/components/imagePopup/style.module.scss | 92 + next/components/pressBlock/index.jsx | 25 + next/components/pressBlock/style.module.scss | 36 + next/components/statBlock/index.jsx | 10 + next/components/statBlock/style.module.scss | 33 + next/components/timeSlot/index.jsx | 23 + next/components/timeSlot/style.module.scss | 17 + next/components/videoBlock/index.jsx | 15 + next/components/videoBlock/style.module.scss | 3 + next/jsconfig.json | 7 + next/next.config.js | 6 + next/package.json | 23 + next/public/fefan.png | Bin 0 -> 82711 bytes next/yarn.lock | 2191 ++++ strapi/.dockerignore | 113 + strapi/.editorconfig | 16 + strapi/.env.example | 7 + strapi/.eslintignore | 3 + strapi/.eslintrc | 27 + strapi/.gitignore | 114 + strapi/Dockerfile | 11 + strapi/README.md | 57 + strapi/config/admin.js | 17 + strapi/config/api.js | 7 + strapi/config/database.js | 92 + strapi/config/middlewares.js | 12 + strapi/config/server.js | 10 + strapi/database/migrations/.gitkeep | 0 strapi/favicon.png | Bin 0 -> 497 bytes strapi/jsconfig.json | 8 + strapi/package.json | 31 + strapi/public/robots.txt | 3 + strapi/public/uploads/.gitkeep | 0 strapi/server.js | 2 + strapi/src/admin/app.example.js | 39 + strapi/src/admin/webpack.config.example.js | 9 + strapi/src/api/.gitkeep | 0 .../article/content-types/article/schema.json | 32 + strapi/src/api/article/controllers/article.js | 9 + strapi/src/api/article/routes/article.js | 9 + strapi/src/api/article/services/article.js | 9 + .../api/band/content-types/band/schema.json | 37 + strapi/src/api/band/controllers/band.js | 9 + strapi/src/api/band/routes/band.js | 9 + strapi/src/api/band/services/band.js | 9 + .../edition/content-types/edition/schema.json | 91 + strapi/src/api/edition/controllers/edition.js | 9 + strapi/src/api/edition/routes/edition.js | 9 + strapi/src/api/edition/services/edition.js | 9 + .../program/content-types/program/schema.json | 66 + strapi/src/api/program/controllers/program.js | 9 + strapi/src/api/program/routes/program.js | 9 + strapi/src/api/program/services/program.js | 9 + .../api/site/content-types/site/schema.json | 39 + strapi/src/api/site/controllers/site.js | 9 + strapi/src/api/site/routes/site.js | 9 + strapi/src/api/site/services/site.js | 9 + .../content-types/social-link/schema.json | 37 + .../social-link/controllers/social-link.js | 9 + .../src/api/social-link/routes/social-link.js | 9 + .../api/social-link/services/social-link.js | 9 + .../sponsor/content-types/sponsor/schema.json | 32 + strapi/src/api/sponsor/controllers/sponsor.js | 9 + strapi/src/api/sponsor/routes/sponsor.js | 9 + strapi/src/api/sponsor/services/sponsor.js | 9 + .../content-types/statistic/schema.json | 30 + .../api/statistic/controllers/statistic.js | 9 + strapi/src/api/statistic/routes/statistic.js | 9 + .../src/api/statistic/services/statistic.js | 9 + .../content-types/time-slot/schema.json | 32 + .../api/time-slot/controllers/time-slot.js | 9 + strapi/src/api/time-slot/routes/time-slot.js | 9 + .../src/api/time-slot/services/time-slot.js | 9 + strapi/src/extensions/.gitkeep | 0 strapi/src/index.js | 20 + strapi/types/generated/components.d.ts | 5 + strapi/types/generated/contentTypes.d.ts | 1064 ++ strapi/yarn.lock | 9968 +++++++++++++++++ 131 files changed, 17192 insertions(+) create mode 100644 next/.dockerignore create mode 100644 next/.env.example create mode 100644 next/.eslintrc.json create mode 100644 next/.gitignore create mode 100644 next/Dockerfile create mode 100644 next/README.md create mode 100644 next/api/index.js create mode 100644 next/app/contact/page.js create mode 100644 next/app/contact/style.module.scss create mode 100644 next/app/editions/[editionId]/page.js create mode 100644 next/app/editions/[editionId]/style.module.scss create mode 100644 next/app/editions/page.js create mode 100644 next/app/editions/style.module.scss create mode 100644 next/app/favicon.ico create mode 100644 next/app/globals.css create mode 100644 next/app/layout.js create mode 100644 next/app/legal/page.js create mode 100644 next/app/legal/style.module.scss create mode 100644 next/app/page.js create mode 100644 next/app/page.module.scss create mode 100644 next/app/prog/city-wide/page.js create mode 100644 next/app/prog/city-wide/style.module.scss create mode 100644 next/app/prog/village/page.js create mode 100644 next/app/prog/village/style.module.scss create mode 100644 next/app/sitemap.js create mode 100644 next/app/sponsor/page.js create mode 100644 next/app/sponsor/style.module.scss create mode 100644 next/components/articleBlock/index.jsx create mode 100644 next/components/articleBlock/style.module.scss create mode 100644 next/components/button/index.jsx create mode 100644 next/components/button/style.module.scss create mode 100644 next/components/editionElement/editionBlock/index.jsx create mode 100644 next/components/editionElement/editionBlock/style.module.scss create mode 100644 next/components/editionElement/index.jsx create mode 100644 next/components/editionElement/style.module.scss create mode 100644 next/components/editionGallery/index.jsx create mode 100644 next/components/editionGallery/style.module.scss create mode 100644 next/components/email/index.jsx create mode 100644 next/components/email/style.module.scss create mode 100644 next/components/empty/index.jsx create mode 100644 next/components/empty/style.module.scss create mode 100644 next/components/fanfare/index.jsx create mode 100644 next/components/fanfare/style.module.scss create mode 100644 next/components/footer/index.jsx create mode 100644 next/components/footer/style.module.scss create mode 100644 next/components/header/index.jsx create mode 100644 next/components/header/navigationDrawer/index.jsx create mode 100644 next/components/header/navigationDrawer/style.module.scss create mode 100644 next/components/header/social-icon/index.jsx create mode 100644 next/components/header/style.module.scss create mode 100644 next/components/imageBlock/index.jsx create mode 100644 next/components/imageBlock/style.module.scss create mode 100644 next/components/imagePopup/index.jsx create mode 100644 next/components/imagePopup/style.module.scss create mode 100644 next/components/pressBlock/index.jsx create mode 100644 next/components/pressBlock/style.module.scss create mode 100644 next/components/statBlock/index.jsx create mode 100644 next/components/statBlock/style.module.scss create mode 100644 next/components/timeSlot/index.jsx create mode 100644 next/components/timeSlot/style.module.scss create mode 100644 next/components/videoBlock/index.jsx create mode 100644 next/components/videoBlock/style.module.scss create mode 100644 next/jsconfig.json create mode 100644 next/next.config.js create mode 100644 next/package.json create mode 100644 next/public/fefan.png create mode 100644 next/yarn.lock create mode 100644 strapi/.dockerignore create mode 100644 strapi/.editorconfig create mode 100644 strapi/.env.example create mode 100644 strapi/.eslintignore create mode 100644 strapi/.eslintrc create mode 100644 strapi/.gitignore create mode 100644 strapi/Dockerfile create mode 100644 strapi/README.md create mode 100644 strapi/config/admin.js create mode 100644 strapi/config/api.js create mode 100644 strapi/config/database.js create mode 100644 strapi/config/middlewares.js create mode 100644 strapi/config/server.js create mode 100644 strapi/database/migrations/.gitkeep create mode 100644 strapi/favicon.png create mode 100644 strapi/jsconfig.json create mode 100644 strapi/package.json create mode 100644 strapi/public/robots.txt create mode 100644 strapi/public/uploads/.gitkeep create mode 100644 strapi/server.js create mode 100644 strapi/src/admin/app.example.js create mode 100644 strapi/src/admin/webpack.config.example.js create mode 100644 strapi/src/api/.gitkeep create mode 100644 strapi/src/api/article/content-types/article/schema.json create mode 100644 strapi/src/api/article/controllers/article.js create mode 100644 strapi/src/api/article/routes/article.js create mode 100644 strapi/src/api/article/services/article.js create mode 100644 strapi/src/api/band/content-types/band/schema.json create mode 100644 strapi/src/api/band/controllers/band.js create mode 100644 strapi/src/api/band/routes/band.js create mode 100644 strapi/src/api/band/services/band.js create mode 100644 strapi/src/api/edition/content-types/edition/schema.json create mode 100644 strapi/src/api/edition/controllers/edition.js create mode 100644 strapi/src/api/edition/routes/edition.js create mode 100644 strapi/src/api/edition/services/edition.js create mode 100644 strapi/src/api/program/content-types/program/schema.json create mode 100644 strapi/src/api/program/controllers/program.js create mode 100644 strapi/src/api/program/routes/program.js create mode 100644 strapi/src/api/program/services/program.js create mode 100644 strapi/src/api/site/content-types/site/schema.json create mode 100644 strapi/src/api/site/controllers/site.js create mode 100644 strapi/src/api/site/routes/site.js create mode 100644 strapi/src/api/site/services/site.js create mode 100644 strapi/src/api/social-link/content-types/social-link/schema.json create mode 100644 strapi/src/api/social-link/controllers/social-link.js create mode 100644 strapi/src/api/social-link/routes/social-link.js create mode 100644 strapi/src/api/social-link/services/social-link.js create mode 100644 strapi/src/api/sponsor/content-types/sponsor/schema.json create mode 100644 strapi/src/api/sponsor/controllers/sponsor.js create mode 100644 strapi/src/api/sponsor/routes/sponsor.js create mode 100644 strapi/src/api/sponsor/services/sponsor.js create mode 100644 strapi/src/api/statistic/content-types/statistic/schema.json create mode 100644 strapi/src/api/statistic/controllers/statistic.js create mode 100644 strapi/src/api/statistic/routes/statistic.js create mode 100644 strapi/src/api/statistic/services/statistic.js create mode 100644 strapi/src/api/time-slot/content-types/time-slot/schema.json create mode 100644 strapi/src/api/time-slot/controllers/time-slot.js create mode 100644 strapi/src/api/time-slot/routes/time-slot.js create mode 100644 strapi/src/api/time-slot/services/time-slot.js create mode 100644 strapi/src/extensions/.gitkeep create mode 100644 strapi/src/index.js create mode 100644 strapi/types/generated/components.d.ts create mode 100644 strapi/types/generated/contentTypes.d.ts create mode 100644 strapi/yarn.lock diff --git a/next/.dockerignore b/next/.dockerignore new file mode 100644 index 0000000..9c755d1 --- /dev/null +++ b/next/.dockerignore @@ -0,0 +1,15 @@ +Dockerfile +.dockerignore +node_modules +npm-debug.log +README.md +.next +.git +/out/ +/build +.DS_Store +yarn-debug.log* +yarn-error.log* +.vercel +*.tsbuildinfo +next-env.d.ts \ No newline at end of file diff --git a/next/.env.example b/next/.env.example new file mode 100644 index 0000000..51f0820 --- /dev/null +++ b/next/.env.example @@ -0,0 +1,5 @@ +NEXT_PUBLIC_CONTENT_URI=http://127.0.0.1:1337/api +NEXT_PUBLIC_IMG_URI=http://127.0.0.1:1337 +NEXT_PUBLIC_ORIGIN=http://localhost:3000 +NEXT_PRIVATE_CONTENT_URI=https://fefan-backend:1337/api +NEXT_PRIVATE_IMG_URI=https://fefan-backend:1337 \ No newline at end of file diff --git a/next/.eslintrc.json b/next/.eslintrc.json new file mode 100644 index 0000000..bffb357 --- /dev/null +++ b/next/.eslintrc.json @@ -0,0 +1,3 @@ +{ + "extends": "next/core-web-vitals" +} diff --git a/next/.gitignore b/next/.gitignore new file mode 100644 index 0000000..b9f8d23 --- /dev/null +++ b/next/.gitignore @@ -0,0 +1,38 @@ +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# dependencies +/node_modules +/.pnp +.pnp.js +.yarn/install-state.gz + +# testing +/coverage + +# next.js +/.next/ +/out/ + +# production +/build + +# misc +.DS_Store +*.pem + +# debug +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# local env files +.env*.local + +# vercel +.vercel + +# typescript +*.tsbuildinfo +next-env.d.ts + +.env \ No newline at end of file diff --git a/next/Dockerfile b/next/Dockerfile new file mode 100644 index 0000000..77fa257 --- /dev/null +++ b/next/Dockerfile @@ -0,0 +1,32 @@ +FROM node:20.10-alpine AS base + +FROM base AS deps +RUN apk add --no-cache libc6-compat +WORKDIR /app + +COPY package.json yarn.lock ./ +RUN yarn --frozen-lockfile + +# Copy source for runtime build +FROM base AS runner +WORKDIR /app + +ENV NODE_ENV production +ENV NEXT_TELEMETRY_DISABLED 1 + +RUN addgroup --system --gid 1001 nodejs +RUN adduser --system --uid 1001 nextjs + +COPY --from=deps /app/node_modules ./node_modules +COPY . . + +# Build at container startup instead of build time +RUN mkdir .next && chown nextjs:nodejs .next +USER nextjs + +EXPOSE 3000 +ENV PORT 3000 +ENV HOSTNAME "0.0.0.0" + +# Build and start in one step +CMD ["sh", "-c", "yarn build && yarn start"] \ No newline at end of file diff --git a/next/README.md b/next/README.md new file mode 100644 index 0000000..0dc9ea2 --- /dev/null +++ b/next/README.md @@ -0,0 +1,36 @@ +This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app). + +## Getting Started + +First, run the development server: + +```bash +npm run dev +# or +yarn dev +# or +pnpm dev +# or +bun dev +``` + +Open [http://localhost:3000](http://localhost:3000) with your browser to see the result. + +You can start editing the page by modifying `app/page.js`. The page auto-updates as you edit the file. + +This project uses [`next/font`](https://nextjs.org/docs/basic-features/font-optimization) to automatically optimize and load Inter, a custom Google Font. + +## Learn More + +To learn more about Next.js, take a look at the following resources: + +- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API. +- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial. + +You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome! + +## Deploy on Vercel + +The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js. + +Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details. diff --git a/next/api/index.js b/next/api/index.js new file mode 100644 index 0000000..0f56f1f --- /dev/null +++ b/next/api/index.js @@ -0,0 +1,19 @@ +import qs from "qs"; + +async function getData(path, query) { + const queryString = qs.stringify(query); + const isServerSide = typeof window === "undefined"; + const res = await fetch( + `${ + isServerSide + ? process.env.NEXT_PRIVATE_CONTENT_URI ?? + "http://fefan-backend:1337/api" + : process.env.NEXT_PUBLIC_CONTENT_URI ?? "https://content.fefan.fr/api" + }/${path}?${queryString}`, + { cache: "no-store" } + ); + + return await res.json(); +} + +export default getData; diff --git a/next/app/contact/page.js b/next/app/contact/page.js new file mode 100644 index 0000000..b5d681f --- /dev/null +++ b/next/app/contact/page.js @@ -0,0 +1,24 @@ +import getData from "@/api"; +import { BlocksRenderer } from "@strapi/blocks-react-renderer"; +import styles from "./style.module.scss"; +import Email from "@/components/email"; +export const dynamic = "force-dynamic"; + +export async function generateMetadata() { + return { + metadataBase: `${process.env.NEXT_PUBLIC_ORIGIN}`, + title: "Contactez nous !", + }; +} + +export default async function Contact() { + const site = await getData("site", {}); + + const content = site.data?.attributes.contact_text; + return ( +
+
{content ? : null}
+ {site.data?.attributes.contact_mail ? : null} +
+ ); +} diff --git a/next/app/contact/style.module.scss b/next/app/contact/style.module.scss new file mode 100644 index 0000000..caa3979 --- /dev/null +++ b/next/app/contact/style.module.scss @@ -0,0 +1,37 @@ +.main { + display: flex; + flex: 1 1 0%; + flex-flow: column; + align-items: center; + + article { + width: 60rem; + display: flex; + flex-flow: column; + max-width: 90vw; + align-self: center; + + h2, h3, h4 { + font-family: var(--font-details); + } + + h2 { + align-self: center; + font-family: var(--font-details); + font-size: 2rem; + font-weight: 400; + } + + p { + margin: 10px; + } + } +} + +@media only screen and (max-width: 641px) { + .main { + article { + text-align: justify; + } + } +} \ No newline at end of file diff --git a/next/app/editions/[editionId]/page.js b/next/app/editions/[editionId]/page.js new file mode 100644 index 0000000..a7a0b24 --- /dev/null +++ b/next/app/editions/[editionId]/page.js @@ -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 ( +
+ {edition ? ( + <> +

{edition.data.attributes.title}

+

{edition.data.attributes.subtitle}

+ ({ + id, + type: "stat", + title: attributes.name, + value: attributes.value, + }))} + /> + {movie && bands ? ( +
+ {bands.length > 0 ? ( +
+

Les fanfares

+ {bands.map(({ id, attributes: attr }) => { + return ( + + ); + })} +
+ ) : null} + {movie ? ( + <> + + + ) : null} +
+ ) : null} + {articles.length > 0 ? ( + <> +

Ils ont parlé de nous !

+ {articles.map(({ id, attributes }, index) => { + const offset = index + (articles.length - gallery.length) / 2; + return index < gallery.length ? ( + + ) : ( + + ); + })} + + ) : null} + {articles.length <= gallery.length ? ( + <> +

Les photos du Fefan

+ + + ) : null} + + ) : ( + + )} +
+ ); +} diff --git a/next/app/editions/[editionId]/style.module.scss b/next/app/editions/[editionId]/style.module.scss new file mode 100644 index 0000000..9240efa --- /dev/null +++ b/next/app/editions/[editionId]/style.module.scss @@ -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; + } + } + } +} \ No newline at end of file diff --git a/next/app/editions/page.js b/next/app/editions/page.js new file mode 100644 index 0000000..78abd54 --- /dev/null +++ b/next/app/editions/page.js @@ -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 ( +
+ {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 ( + + ); + }) + ) : ( + + )} +
+ ); +} diff --git a/next/app/editions/style.module.scss b/next/app/editions/style.module.scss new file mode 100644 index 0000000..975aab8 --- /dev/null +++ b/next/app/editions/style.module.scss @@ -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 { + // } +} \ No newline at end of file diff --git a/next/app/favicon.ico b/next/app/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..16c95e2ba346e9e3eb183b967b42cecf31ed2ee2 GIT binary patch literal 739 zcmV<90v!E`P)LmCsKTQ4q(!^WM^~?b1RGp{)S|8i;~P`OySV96ag8 zK#UhJ8gC~4NoY*alL>etw58j9`^E$9w&h2u_&sd$X6F0Z znaRs8@xm&ASu2T)YO%0wlMsAiKut{Kk}&41B!I>7xBp<(8u_AjilR3TV0Qf;0Ha;A zZ3Dp8Pn1e*JNWtqZUIAS+`oO4KMzzcA$NeS4BjoVc?r2a0ub%iBPscD%`5N9T476& z=VAU8e*Hj)sUsmoLzGNo@CtQW^6(IumFmyO7Y7v36MS&oK20FskGc&k)TV!Sr(h%D7i(7$sdlyRK zaufixMnyr@oQ?}--PPUJXmDLHU|H}qT!)vId4HRVS$+2o>5^cNLS}oQtPK#lBTx#T zKhgRcX#kKfU+ZW@CHjp}*spCh8Zvv30Z56mgXQ-uL-W#0&kzd8B6eZ$~zNU`!eulqo2s_6;F>z}e zK~q?vqm+F3fSnSyHmO+V8^bg=cdUU1(9Uo1`~~t^Fi04@vO;bJGc&beh@L#=&F_3@ zP=Dg&9_k?dVNK++0Kfn%I>_s>QIVc%TFu}vm>XyG)v%+2s+Cut)Op%x^E65mNL;^G zKM@$9-q@+0b3m9(=|mrhz{G~6kugkOsC4i^0)qo2T3**?QDtGZ zMB-66etzv4dQ;qSK*9h*{C~d^1_OTqJIU$1prsxR0000EWmrjOO-%qQ0000800000 V0002eQ + + + + +
+ {children} +