From f74186e5398c48e7cdc5d369e493d185cc4337ca Mon Sep 17 00:00:00 2001 From: Simon C Date: Mon, 6 May 2024 22:35:25 +0200 Subject: [PATCH] feat: Nouvelle version --- .../[departementSlug]/[communeSlug]/page.tsx | 179 + .../[regionSlug]/[departementSlug]/page.tsx | 48 + app/annuaire/[regionSlug]/page.tsx | 85 + app/annuaire/page.tsx | 19 + app/blog/[slug]/page.tsx | 123 + app/blog/page.tsx | 12 + .../posts/2024-05-03-nouveau-site-web.mdx | 32 + app/blog/posts/static-typing.mdx | 52 + app/blog/posts/vim.mdx | 39 + app/blog/utils.ts | 91 + app/globals.css | 61 +- app/layout.tsx | 15 +- app/mdx-components.tsx | 7 + app/mentions-legales/index.md | 44 + app/mentions-legales/page.tsx | 37 + app/page.tsx | 127 +- app/sitemap.ts | 17 + components/Article.tsx | 89 + components/Blog.tsx | 337 ++ components/Concepts.tsx | 309 ++ components/Footer.tsx | 108 + components/Hero.tsx | 185 + components/Mdx.tsx | 109 + components/Nav.tsx | 138 + components/Newsletter.tsx | 94 + components/Post.tsx | 39 + components/Posts.tsx | 213 + components/Projects.tsx | 174 + components/Roadmap.tsx | 164 + components/Testimonial.tsx | 0 next.config.mjs | 24 +- package-lock.json | 3559 ++++++++++++++++- package.json | 16 +- public/ProtestRevolution-Regular.woff2 | Bin 0 -> 268928 bytes public/Thomas-Kuhn.jpg | Bin 0 -> 23418 bytes public/atis-assets/background/lines.svg | 239 ++ public/atis-assets/elements/blue-up.svg | 3 + .../elements/bullets-dark-left.svg | 56 + .../elements/bullets-dark-right.svg | 56 + .../elements/bullets-gray-left.svg | 56 + .../elements/bullets-gray-right.svg | 56 + .../elements/bullets-green-left.svg | 56 + .../elements/bullets-green-right.svg | 56 + .../elements/bullets-pink-left.svg | 56 + .../elements/bullets-purple-left.png | Bin 0 -> 2264 bytes .../elements/bullets-yellow-left.svg | 56 + .../elements/bullets-yellow-right.svg | 56 + public/atis-assets/elements/green-dark-up.svg | 3 + public/atis-assets/elements/green-up.svg | 3 + public/atis-assets/elements/left-quote.png | Bin 0 -> 1320 bytes .../atis-assets/elements/line-light-gray.svg | 3 + public/atis-assets/elements/line-light.svg | 3 + public/atis-assets/elements/line.svg | 3 + public/atis-assets/elements/purple-up.svg | 3 + public/atis-assets/elements/puzzle.svg | 9 + public/atis-assets/elements/quote-grey.svg | 4 + public/atis-assets/elements/terminal.svg | 9 + public/atis-assets/elements/thumb-up.svg | 9 + public/atis-assets/elements/user-circle.svg | 9 + .../atis-assets/elements/wing-green-down.svg | 3 + .../atis-assets/elements/wing-pink-down.svg | 3 + .../atis-assets/elements/wing-purple-down.svg | 3 + .../atis-assets/elements/wing-yellow-down.svg | 3 + .../illustrations/book-detail-full.png | Bin 0 -> 52003 bytes .../atis-assets/illustrations/book-detail.png | Bin 0 -> 79982 bytes .../illustrations/details-full.png | Bin 0 -> 57529 bytes public/atis-assets/illustrations/details.png | Bin 0 -> 23526 bytes public/atis-assets/illustrations/home.png | Bin 0 -> 46889 bytes .../atis-assets/illustrations/login-full.png | Bin 0 -> 43720 bytes public/atis-assets/illustrations/login.png | Bin 0 -> 11558 bytes .../men-on-chair-green-background.png | Bin 0 -> 22245 bytes .../men-on-chair-light-green.png | Bin 0 -> 79584 bytes .../illustrations/men-on-chair-light.png | Bin 0 -> 78406 bytes .../men-on-chair-purple-background.png | Bin 0 -> 22331 bytes .../men-on-chair-purple-dark.png | Bin 0 -> 80776 bytes .../illustrations/men-on-chair.png | Bin 0 -> 55157 bytes .../pablo-coming-soon-dark-mono.png | Bin 0 -> 36572 bytes .../pablo-coming-soon-flat-color.png | Bin 0 -> 35768 bytes .../pablo-coming-soon-light-color.png | Bin 0 -> 36304 bytes .../illustrations/pablo-coming-soon-mono.png | Bin 0 -> 35844 bytes .../illustrations/pablo-working.png | Bin 0 -> 46101 bytes public/atis-assets/illustrations/pablo.png | Bin 0 -> 39829 bytes public/atis-assets/illustrations/scene.png | Bin 0 -> 94481 bytes .../technical-support-dark-green.png | Bin 0 -> 59645 bytes .../technical-support-little-dark-green.png | Bin 0 -> 60106 bytes .../technical-support-little-dark-purple.png | Bin 0 -> 60760 bytes .../logo/atis/atis-color-black.svg | 10 + .../atis-assets/logo/atis/atis-color-sign.svg | 9 + .../logo/atis/atis-color-white.svg | 10 + .../atis-assets/logo/atis/atis-flat-white.svg | 10 + public/atis-assets/logo/atis/atis-flat.svg | 9 + .../atis-assets/logo/atis/atis-mono-black.svg | 10 + .../atis-assets/logo/atis/atis-mono-green.svg | 9 + .../atis-assets/logo/atis/atis-mono-light.svg | 10 + .../atis-assets/logo/atis/atis-mono-sign.svg | 9 + .../atis-assets/logo/atis/atis-mono-white.svg | 10 + .../atis-assets/logo/brands/amazon-grey.png | Bin 0 -> 1774 bytes public/atis-assets/logo/brands/amazon.png | Bin 0 -> 1687 bytes .../logo/brands/app-store-download.png | Bin 0 -> 2573 bytes .../atis-assets/logo/brands/dropbox-grey.png | Bin 0 -> 2269 bytes public/atis-assets/logo/brands/dropbox.png | Bin 0 -> 2028 bytes .../logo/brands/google-play-store.png | Bin 0 -> 3610 bytes .../atis-assets/logo/brands/netflix-grey.png | Bin 0 -> 1401 bytes public/atis-assets/logo/brands/netflix.png | Bin 0 -> 1484 bytes public/atis-assets/logo/brands/slack-grey.png | Bin 0 -> 2059 bytes public/atis-assets/logo/brands/slack.png | Bin 0 -> 2176 bytes .../atis-assets/logo/brands/spotify-grey.png | Bin 0 -> 2368 bytes public/atis-assets/logo/brands/spotify.png | Bin 0 -> 2631 bytes .../atis-assets/logo/brands/stripe-grey.png | Bin 0 -> 1571 bytes public/atis-assets/logo/brands/stripe.png | Bin 0 -> 1582 bytes public/atis-assets/social/brand-linkedin.svg | 1 + public/atis-assets/social/clutch-logo.png | Bin 0 -> 1341 bytes .../social/facebook-light-green.svg | 8 + public/atis-assets/social/facebook-logo.png | Bin 0 -> 352 bytes public/atis-assets/social/facebook-name.png | Bin 0 -> 1778 bytes public/atis-assets/social/facebook-purple.svg | 8 + public/atis-assets/social/facebook-yellow.svg | 8 + public/atis-assets/social/facebook.svg | 8 + public/atis-assets/social/google-logo.png | Bin 0 -> 624 bytes .../social/instagram-light-green.svg | 8 + .../atis-assets/social/instagram-purple.svg | 8 + .../atis-assets/social/instagram-yellow.svg | 8 + public/atis-assets/social/instagram.svg | 8 + .../social/twitter-light-green.svg | 8 + public/atis-assets/social/twitter-purple.svg | 8 + public/atis-assets/social/twitter-yellow.svg | 8 + public/atis-assets/social/twitter.svg | 8 + public/etactics-inc-4SeuwHcdq2w-unsplash.jpg | Bin 0 -> 29101 bytes public/etactics-inc-Apdejs-GxW4-unsplash.jpg | Bin 0 -> 47227 bytes public/etactics-inc-FnGty3_1Fz4-unsplash.jpg | Bin 0 -> 28925 bytes public/logo.svg | 377 ++ public/logo2.svg | 711 ++++ ...ucas-george-wendt-zEp3CgWcOj0-unsplash.jpg | Bin 0 -> 49143 bytes public/sante.webp | Bin 0 -> 305986 bytes ...towfiqu-barbhuiya-HNPrWOH2Z8U-unsplash.jpg | Bin 0 -> 42167 bytes tailwind.config.ts | 647 ++- 136 files changed, 8965 insertions(+), 325 deletions(-) create mode 100644 app/annuaire/[regionSlug]/[departementSlug]/[communeSlug]/page.tsx create mode 100644 app/annuaire/[regionSlug]/[departementSlug]/page.tsx create mode 100644 app/annuaire/[regionSlug]/page.tsx create mode 100644 app/annuaire/page.tsx create mode 100644 app/blog/[slug]/page.tsx create mode 100644 app/blog/page.tsx create mode 100644 app/blog/posts/2024-05-03-nouveau-site-web.mdx create mode 100644 app/blog/posts/static-typing.mdx create mode 100644 app/blog/posts/vim.mdx create mode 100644 app/blog/utils.ts create mode 100644 app/mdx-components.tsx create mode 100644 app/mentions-legales/index.md create mode 100644 app/mentions-legales/page.tsx create mode 100644 app/sitemap.ts create mode 100644 components/Article.tsx create mode 100644 components/Blog.tsx create mode 100644 components/Concepts.tsx create mode 100644 components/Footer.tsx create mode 100644 components/Hero.tsx create mode 100644 components/Mdx.tsx create mode 100644 components/Nav.tsx create mode 100644 components/Newsletter.tsx create mode 100644 components/Post.tsx create mode 100644 components/Posts.tsx create mode 100644 components/Projects.tsx create mode 100644 components/Roadmap.tsx create mode 100644 components/Testimonial.tsx create mode 100644 public/ProtestRevolution-Regular.woff2 create mode 100644 public/Thomas-Kuhn.jpg create mode 100644 public/atis-assets/background/lines.svg create mode 100644 public/atis-assets/elements/blue-up.svg create mode 100644 public/atis-assets/elements/bullets-dark-left.svg create mode 100644 public/atis-assets/elements/bullets-dark-right.svg create mode 100644 public/atis-assets/elements/bullets-gray-left.svg create mode 100644 public/atis-assets/elements/bullets-gray-right.svg create mode 100644 public/atis-assets/elements/bullets-green-left.svg create mode 100644 public/atis-assets/elements/bullets-green-right.svg create mode 100644 public/atis-assets/elements/bullets-pink-left.svg create mode 100644 public/atis-assets/elements/bullets-purple-left.png create mode 100644 public/atis-assets/elements/bullets-yellow-left.svg create mode 100644 public/atis-assets/elements/bullets-yellow-right.svg create mode 100644 public/atis-assets/elements/green-dark-up.svg create mode 100644 public/atis-assets/elements/green-up.svg create mode 100644 public/atis-assets/elements/left-quote.png create mode 100644 public/atis-assets/elements/line-light-gray.svg create mode 100644 public/atis-assets/elements/line-light.svg create mode 100644 public/atis-assets/elements/line.svg create mode 100644 public/atis-assets/elements/purple-up.svg create mode 100644 public/atis-assets/elements/puzzle.svg create mode 100644 public/atis-assets/elements/quote-grey.svg create mode 100644 public/atis-assets/elements/terminal.svg create mode 100644 public/atis-assets/elements/thumb-up.svg create mode 100644 public/atis-assets/elements/user-circle.svg create mode 100644 public/atis-assets/elements/wing-green-down.svg create mode 100644 public/atis-assets/elements/wing-pink-down.svg create mode 100644 public/atis-assets/elements/wing-purple-down.svg create mode 100644 public/atis-assets/elements/wing-yellow-down.svg create mode 100644 public/atis-assets/illustrations/book-detail-full.png create mode 100644 public/atis-assets/illustrations/book-detail.png create mode 100644 public/atis-assets/illustrations/details-full.png create mode 100644 public/atis-assets/illustrations/details.png create mode 100644 public/atis-assets/illustrations/home.png create mode 100644 public/atis-assets/illustrations/login-full.png create mode 100644 public/atis-assets/illustrations/login.png create mode 100644 public/atis-assets/illustrations/men-on-chair-green-background.png create mode 100644 public/atis-assets/illustrations/men-on-chair-light-green.png create mode 100644 public/atis-assets/illustrations/men-on-chair-light.png create mode 100644 public/atis-assets/illustrations/men-on-chair-purple-background.png create mode 100644 public/atis-assets/illustrations/men-on-chair-purple-dark.png create mode 100644 public/atis-assets/illustrations/men-on-chair.png create mode 100644 public/atis-assets/illustrations/pablo-coming-soon-dark-mono.png create mode 100644 public/atis-assets/illustrations/pablo-coming-soon-flat-color.png create mode 100644 public/atis-assets/illustrations/pablo-coming-soon-light-color.png create mode 100644 public/atis-assets/illustrations/pablo-coming-soon-mono.png create mode 100644 public/atis-assets/illustrations/pablo-working.png create mode 100644 public/atis-assets/illustrations/pablo.png create mode 100644 public/atis-assets/illustrations/scene.png create mode 100644 public/atis-assets/illustrations/technical-support-dark-green.png create mode 100644 public/atis-assets/illustrations/technical-support-little-dark-green.png create mode 100644 public/atis-assets/illustrations/technical-support-little-dark-purple.png create mode 100644 public/atis-assets/logo/atis/atis-color-black.svg create mode 100644 public/atis-assets/logo/atis/atis-color-sign.svg create mode 100644 public/atis-assets/logo/atis/atis-color-white.svg create mode 100644 public/atis-assets/logo/atis/atis-flat-white.svg create mode 100644 public/atis-assets/logo/atis/atis-flat.svg create mode 100644 public/atis-assets/logo/atis/atis-mono-black.svg create mode 100644 public/atis-assets/logo/atis/atis-mono-green.svg create mode 100644 public/atis-assets/logo/atis/atis-mono-light.svg create mode 100644 public/atis-assets/logo/atis/atis-mono-sign.svg create mode 100644 public/atis-assets/logo/atis/atis-mono-white.svg create mode 100644 public/atis-assets/logo/brands/amazon-grey.png create mode 100644 public/atis-assets/logo/brands/amazon.png create mode 100644 public/atis-assets/logo/brands/app-store-download.png create mode 100644 public/atis-assets/logo/brands/dropbox-grey.png create mode 100644 public/atis-assets/logo/brands/dropbox.png create mode 100644 public/atis-assets/logo/brands/google-play-store.png create mode 100644 public/atis-assets/logo/brands/netflix-grey.png create mode 100644 public/atis-assets/logo/brands/netflix.png create mode 100644 public/atis-assets/logo/brands/slack-grey.png create mode 100644 public/atis-assets/logo/brands/slack.png create mode 100644 public/atis-assets/logo/brands/spotify-grey.png create mode 100644 public/atis-assets/logo/brands/spotify.png create mode 100644 public/atis-assets/logo/brands/stripe-grey.png create mode 100644 public/atis-assets/logo/brands/stripe.png create mode 100644 public/atis-assets/social/brand-linkedin.svg create mode 100644 public/atis-assets/social/clutch-logo.png create mode 100644 public/atis-assets/social/facebook-light-green.svg create mode 100644 public/atis-assets/social/facebook-logo.png create mode 100644 public/atis-assets/social/facebook-name.png create mode 100644 public/atis-assets/social/facebook-purple.svg create mode 100644 public/atis-assets/social/facebook-yellow.svg create mode 100644 public/atis-assets/social/facebook.svg create mode 100644 public/atis-assets/social/google-logo.png create mode 100644 public/atis-assets/social/instagram-light-green.svg create mode 100644 public/atis-assets/social/instagram-purple.svg create mode 100644 public/atis-assets/social/instagram-yellow.svg create mode 100644 public/atis-assets/social/instagram.svg create mode 100644 public/atis-assets/social/twitter-light-green.svg create mode 100644 public/atis-assets/social/twitter-purple.svg create mode 100644 public/atis-assets/social/twitter-yellow.svg create mode 100644 public/atis-assets/social/twitter.svg create mode 100644 public/etactics-inc-4SeuwHcdq2w-unsplash.jpg create mode 100644 public/etactics-inc-Apdejs-GxW4-unsplash.jpg create mode 100644 public/etactics-inc-FnGty3_1Fz4-unsplash.jpg create mode 100644 public/logo.svg create mode 100644 public/logo2.svg create mode 100644 public/lucas-george-wendt-zEp3CgWcOj0-unsplash.jpg create mode 100644 public/sante.webp create mode 100644 public/towfiqu-barbhuiya-HNPrWOH2Z8U-unsplash.jpg diff --git a/app/annuaire/[regionSlug]/[departementSlug]/[communeSlug]/page.tsx b/app/annuaire/[regionSlug]/[departementSlug]/[communeSlug]/page.tsx new file mode 100644 index 0000000..7bd9c84 --- /dev/null +++ b/app/annuaire/[regionSlug]/[departementSlug]/[communeSlug]/page.tsx @@ -0,0 +1,179 @@ +import { Metadata } from "next"; +import { notFound } from "next/navigation"; + +import { + Header, + CommunesList, + DepartementsList, + RegionList, +} from "@/components/index"; +import communes, { + Commune, + getCommuneFromSlug, + getSlugFromCommune, + getCodesPostaux, + getChefLieu, + CommuneDeleguee, +} from "@/lib/communes"; +import { + Content, + ContentHeader, + ContentBody, + ContentFull, + ContentHalf, +} from "@/components/Content/Content"; + +import departements, { + getSlugFromDepartement, + getDepartementFromSlug, +} from "@/lib/departements"; +import { getRegionFromCode, getSlugFromRegion } from "@/lib/regions"; +import Link from "next/link"; + +import { getMSPFromCodesPostaux } from "@/lib/api-annuaire-sante"; + +export const metadata: Metadata = { + title: "Annuaire", + description: "L'annuaire collaboratif des professionnels de la santé", +}; + +export async function generateStaticParams() { + return communes.map((commune) => ({ + commune: getSlugFromCommune(commune), + })); +} + +async function getData(codesPostaux: Array) { + const res = await fetch( + `http://localhost:8000/fhir/v1/Organization?address-postalcode%3Aexact=${codesPostaux.join( + "%2C", + )}&_count=5000&type=https://mos.esante.gouv.fr/NOS/TRE_R66-CategorieEtablissement/FHIR/TRE-R66-CategorieEtablissement%7C603`, + { cache: "force-cache" }, + ); + // The return value is *not* serialized + // You can return Date, Map, Set, etc. + + if (!res.ok) { + // This will activate the closest `error.js` Error Boundary + throw new Error("Failed to fetch data"); + } + + return res.json(); +} + +export default async function CommunePage({ + params, +}: { + params: { regionSlug: string; departementSlug: string; communeSlug: string }; +}) { + const commune = getCommuneFromSlug(params.communeSlug); + if (!commune) return notFound(); + const departement = getDepartementFromSlug(params.departementSlug); + if (!departement) return notFound(); + const region = getRegionFromCode(departement.region); + if (!region) return notFound(); + + let chefLieu: Commune | Boolean = commune.chefLieu + ? getChefLieu(commune) + : false; + + const codesPostaux = commune.chefLieu + ? [commune.chefLieu] + : commune.codesPostaux; + const msps = await getMSPFromCodesPostaux(codesPostaux); + + return ( + <> +
+ +
+
+
+
+

{commune.nom}

+

{getCodesPostaux(commune)}

+
+
+ + + + + + + + + + + {commune.population && ( + + + + + )} + {chefLieu && ( + + + + + )} + +
Région + + {region.nom} + +
Département + + {departement.nom} ({departement.code}) + +
Population + {commune.population.toLocaleString("fr-FR")} habiants +
Cheflieu + + {chefLieu.nom} + +
+
+
+
+
+ +
+ {msps.entry && ( +
+
+

Informations sur les {msps.total} structures

+
    + {msps.entry.map((msp) => ( +
  • {msp.resource.name}
  • + ))} +
+
+
+ )} +
+
+

Dirigeants et représentants de P4PILLON

+
+
+
+ test +
+
+ +
+ +
+ + + ); +} diff --git a/app/annuaire/[regionSlug]/[departementSlug]/page.tsx b/app/annuaire/[regionSlug]/[departementSlug]/page.tsx new file mode 100644 index 0000000..a874867 --- /dev/null +++ b/app/annuaire/[regionSlug]/[departementSlug]/page.tsx @@ -0,0 +1,48 @@ +import { Metadata } from "next"; +import { notFound } from "next/navigation"; + +import { + Header, + CommunesList, + DepartementsList, + RegionList, +} from "@/components/index"; + +import departements, { + getSlugFromDepartement, + getDepartementFromSlug, +} from "@/lib/departements"; +import { getRegionFromCode } from "@/lib/regions"; + +export const metadata: Metadata = { + title: "Annuaire", + description: "L'annuaire collaboratif des professionnels de la santé", +}; + +export async function generateStaticParams() { + return departements.map((departement) => ({ + departement: getSlugFromDepartement(departement), + })); +} + +export default function DepartementPage({ + params, +}: { + params: { regionSlug: string; departementSlug: string }; +}) { + const departement = getDepartementFromSlug(params.departementSlug); + if (!departement) return notFound(); + const region = getRegionFromCode(departement.region); + if (!region) return notFound(); + + return ( + <> +
+ +
+ +
+ + + ); +} diff --git a/app/annuaire/[regionSlug]/page.tsx b/app/annuaire/[regionSlug]/page.tsx new file mode 100644 index 0000000..270a0de --- /dev/null +++ b/app/annuaire/[regionSlug]/page.tsx @@ -0,0 +1,85 @@ +import { Metadata } from "next"; +import { notFound } from "next/navigation"; +import regionsCpts from "../../../regions_cpts.json"; + +import regions, { getRegionFromSlug, getSlugFromRegion } from "@/lib/regions"; +import { Header, DepartementsList, RegionList } from "@/components/index"; +import { + Content, + ContentHeader, + ContentBody, + ContentFull, + ContentHalf, +} from "@/components/Content/Content"; +import { getCommuneFromCodePostal } from "@/lib/communes"; +import Link from "next/link"; + +export const metadata: Metadata = { + title: "Annuaire", + description: "L'annuaire collaboratif des professionnels de la santé", +}; + +export async function generateStaticParams() { + return regions.map((region) => ({ + region: getSlugFromRegion(region), + })); +} + +export default function RegionPage({ + params, +}: { + params: { regionSlug: string }; +}) { + const region = getRegionFromSlug(params.regionSlug); + if (!region) return notFound(); + // const nbHabitants = getCommuesFromRegion() + + return ( + <> +
+ + +
+

{region.nom}

+

+ {getCommuneFromCodePostal(region.chefLieu).nom} +

+
+
+ + + + + + + + + + + + + + + + + + + + + + + +
Nombre de départements
Nombre d'habitants
Nombre de SISA
Nombre de CPTS
Nombre de SISA
+
+
+ + yep + +
+ +
+ +
+ + ); +} diff --git a/app/annuaire/page.tsx b/app/annuaire/page.tsx new file mode 100644 index 0000000..131a288 --- /dev/null +++ b/app/annuaire/page.tsx @@ -0,0 +1,19 @@ +import { Metadata } from "next"; + +import { Header, Hero, RegionList } from "@/components/index"; + +export const metadata: Metadata = { + title: "Annuaire", + description: "L'annuaire collaboratif des professionnels de la santé", +}; + +export default function DashboardPage() { + return ( + <> +
+ + +
+ + ); +} diff --git a/app/blog/[slug]/page.tsx b/app/blog/[slug]/page.tsx new file mode 100644 index 0000000..2022524 --- /dev/null +++ b/app/blog/[slug]/page.tsx @@ -0,0 +1,123 @@ +import { notFound } from 'next/navigation' +import { CustomMDX } from '@/components/Mdx' +import { formatDate, getBlogPosts } from '@/app/blog/utils' +import { baseUrl } from '@/app/sitemap' + +export async function generateStaticParams() { + let posts = getBlogPosts() + + return posts.map((post) => ({ + slug: post.slug, + })) +} + +export function generateMetadata({ params }) { + let post = getBlogPosts().find((post) => post.slug === params.slug) + if (!post) { + return + } + + let { + title, + publishedAt: publishedTime, + summary: description, + image, + } = post.metadata + let ogImage = image ? image : `${baseUrl}/og?title=${encodeURIComponent(title)}` + + return { + title, + description, + openGraph: { + title, + description, + type: 'article', + publishedTime, + url: `${baseUrl}/blog/${post.slug}`, + images: [ + { + url: ogImage, + }, + ], + }, + twitter: { + card: 'summary_large_image', + title, + description, + images: [ogImage], + }, + } +} + +export default function Blog({ params }) { + let post = getBlogPosts().find((post) => post.slug === params.slug) + + if (!post) { + notFound() + } + + return ( +
+