diff --git a/.commitlintrc.json b/.commitlintrc.json deleted file mode 100644 index d3d7f0c..0000000 --- a/.commitlintrc.json +++ /dev/null @@ -1 +0,0 @@ -{ "extends": ["@commitlint/config-conventional"] } diff --git a/.dockerignore b/.dockerignore index ba056b2..b5a934d 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,7 +1,10 @@ +**/.git **/.turbo **/.next **/out +**/dist **/build +**/storybook-static **/coverage **/node_modules @@ -11,10 +14,24 @@ .env.development secrets +# IDEs and editors +.idea +.project +.classpath +.c9/ +*.launch +.settings/ +*.sublime-workspace +.vscode + # misc .DS_Store *.pem Dockerfile +README.md + +# vercel +.vercel # typescript *.tsbuildinfo diff --git a/.env.example b/.env.example index 3958efe..1958f4a 100644 --- a/.env.example +++ b/.env.example @@ -1,4 +1 @@ -COMPOSE_PROJECT_NAME=theoludwig -HOSTNAME=0.0.0.0 -PORT=3000 -NEXT_TELEMETRY_DISABLED=1 +WEBSITE_PORT=3000 diff --git a/.eslintrc.json b/.eslintrc.json deleted file mode 100644 index 5f49665..0000000 --- a/.eslintrc.json +++ /dev/null @@ -1,38 +0,0 @@ -{ - "root": true, - "extends": [ - "conventions", - "next/core-web-vitals", - "plugin:tailwindcss/recommended" - ], - "plugins": ["import", "promise", "unicorn"], - "settings": { - "tailwindcss": { - "callees": ["classNames"] - }, - "react": { - "version": "detect" - } - }, - "rules": { - "react/self-closing-comp": [ - "error", - { - "component": true, - "html": true - } - ], - "react/void-dom-elements-no-children": "error", - "react/jsx-boolean-value": "error" - }, - "overrides": [ - { - "files": ["*.ts", "*.tsx"], - "parser": "@typescript-eslint/parser", - "plugins": ["@typescript-eslint"], - "parserOptions": { - "project": "./tsconfig.json" - } - } - ] -} diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml deleted file mode 100644 index 86829a2..0000000 --- a/.github/workflows/build.yml +++ /dev/null @@ -1,25 +0,0 @@ -name: "Build" - -on: - push: - branches: [develop] - pull_request: - branches: [main, develop] - -jobs: - build: - runs-on: "ubuntu-latest" - steps: - - uses: "actions/checkout@v4.1.6" - - - name: "Setup Node.js" - uses: "actions/setup-node@v4.0.2" - with: - node-version: "20.x" - cache: "npm" - - - name: "Install dependencies" - run: "npm clean-install" - - - name: "Build" - run: "npm run build" diff --git a/.github/workflows/chromatic.yml b/.github/workflows/chromatic.yml new file mode 100644 index 0000000..135ae5b --- /dev/null +++ b/.github/workflows/chromatic.yml @@ -0,0 +1,33 @@ +name: "Chromatic" + +on: + push: + branches: [develop] + pull_request: + branches: [develop, staging, main] + +jobs: + chromatic: + timeout-minutes: 30 + runs-on: "ubuntu-latest" + steps: + - uses: "actions/checkout@v4.1.7" + with: + fetch-depth: 0 + + - uses: "pnpm/action-setup@v4.0.0" + + - name: "Setup Node.js" + uses: "actions/setup-node@v4.0.3" + with: + node-version: "22.x" + cache: "pnpm" + + - name: "Install dependencies" + run: "pnpm install --frozen-lockfile" + + - name: "Run Chromatic" + uses: "chromaui/action@latest" + with: + projectToken: ${{ secrets.CHROMATIC_PROJECT_TOKEN }} + workingDir: "apps/storybook" diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..aeafcae --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,43 @@ +name: "CI" + +on: + push: + branches: [develop] + pull_request: + branches: [develop, staging, main] + +jobs: + ci: + timeout-minutes: 30 + runs-on: "ubuntu-latest" + steps: + - uses: "actions/checkout@v4.1.7" + + - uses: "pnpm/action-setup@v4.0.0" + + - name: "Setup Node.js" + uses: "actions/setup-node@v4.0.3" + with: + node-version: "22.x" + cache: "pnpm" + + - name: "Install dependencies" + run: "pnpm install --frozen-lockfile" + + - name: "Install Playwright" + run: "pnpm exec playwright install --with-deps" + + - run: "node --run lint:editorconfig" + - run: "node --run lint:markdown" + - run: "node --run lint:prettier" + - run: "node --run lint:eslint" + - run: "node --run lint:typescript" + - run: "node --run test" + - run: "node --run build" + + commitlint: + runs-on: "ubuntu-latest" + steps: + - uses: "actions/checkout@v4.1.7" + + - uses: "wagoid/commitlint-github-action@v6.0.1" diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml deleted file mode 100644 index f1fee09..0000000 --- a/.github/workflows/lint.yml +++ /dev/null @@ -1,42 +0,0 @@ -name: "Lint" - -on: - push: - branches: [develop] - pull_request: - branches: [main, develop] - -jobs: - lint: - runs-on: "ubuntu-latest" - steps: - - uses: "actions/checkout@v4.1.6" - - - name: "Setup Node.js" - uses: "actions/setup-node@v4.0.2" - with: - node-version: "20.x" - cache: "npm" - - - name: "Install dependencies" - run: "npm clean-install" - - - name: "lint:commit" - run: 'npm run lint:commit -- --to "${{ github.sha }}"' - - - name: "lint:editorconfig" - run: "npm run lint:editorconfig" - - - name: "lint:markdown" - run: "npm run lint:markdown" - - - name: "lint:eslint" - run: "npm run lint:eslint" - - - name: "lint:prettier" - run: "npm run lint:prettier" - - - name: "lint:dotenv" - uses: "dotenv-linter/action-dotenv-linter@v2.21.0" - with: - github_token: ${{ secrets.github_token }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 68491f2..ea4cec3 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -2,13 +2,19 @@ name: "Release" on: push: - branches: [main] + branches: [main, staging] jobs: release: + timeout-minutes: 30 runs-on: "ubuntu-latest" + permissions: + contents: "write" + issues: "write" + pull-requests: "write" + id-token: "write" steps: - - uses: "actions/checkout@v4.1.6" + - uses: "actions/checkout@v4.1.7" with: fetch-depth: 0 persist-credentials: false @@ -20,17 +26,19 @@ jobs: git_user_signingkey: true git_commit_gpgsign: true + - uses: "pnpm/action-setup@v4.0.0" + - name: "Setup Node.js" - uses: "actions/setup-node@v4.0.2" + uses: "actions/setup-node@v4.0.3" with: - node-version: "20.x" - cache: "npm" + node-version: "22.x" + cache: "pnpm" - name: "Install dependencies" - run: "npm clean-install" + run: "pnpm install --frozen-lockfile" - name: "Release" - run: "npm run release" + run: "node --run release" env: GH_TOKEN: ${{ secrets.GH_TOKEN }} GIT_COMMITTER_NAME: ${{ secrets.GIT_NAME }} diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml deleted file mode 100644 index d46e37e..0000000 --- a/.github/workflows/test.yml +++ /dev/null @@ -1,48 +0,0 @@ -name: "Test" - -on: - push: - branches: [develop] - pull_request: - branches: [main, develop] - -jobs: - test-unit: - runs-on: "ubuntu-latest" - steps: - - uses: "actions/checkout@v4.1.6" - - - name: "Setup Node.js" - uses: "actions/setup-node@v4.0.2" - with: - node-version: "20.x" - cache: "npm" - - - name: "Install dependencies" - run: "npm clean-install" - - - name: "Unit Test" - run: "npm run test:unit" - - test-e2e: - runs-on: "ubuntu-latest" - steps: - - uses: "actions/checkout@v4.1.6" - - - name: "Setup Node.js" - uses: "actions/setup-node@v4.0.2" - with: - node-version: "20.x" - cache: "npm" - - - name: "Install dependencies" - run: "npm clean-install" - - - name: "Build" - run: "npm run build" - - - name: "html-w3c-validator" - run: "npm run test:html-w3c-validator" - - - name: "End To End (e2e) Test" - run: "npm run test:e2e" diff --git a/.gitignore b/.gitignore index e09c58a..cbec9be 100644 --- a/.gitignore +++ b/.gitignore @@ -1,33 +1,39 @@ -# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. - # dependencies node_modules .npm - -# next.js -.next -out - -# production -build -dist -public/curriculum-vitae +package-lock.json +.pnpm-store +.pnp +.pnp.js +.yarn/install-state.gz # testing coverage -cypress/screenshots -cypress/videos -cypress/downloads -# envs -.env -.env.production +# production +.next/ +out/ +dist/ +build/ +# apps/website/public/curriculum-vitae/ + +# misc +.DS_Store +*.pem +.turbo +bin/ # debug npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# Storybook +*storybook.log +storybook-static # IDEs and editors -/.idea +.idea .project .classpath .c9/ @@ -35,17 +41,14 @@ npm-debug.log* .settings/ *.sublime-workspace -# IDE - VSCode -.vscode/* -!.vscode/settings.json -!.vscode/tasks.json -!.vscode/launch.json -!.vscode/extensions.json +# local env files +.env +.env.production +.env*.local -# misc -.DS_Store -.lighthouseci +# vercel +.vercel # typescript *.tsbuildinfo -next-env.d.ts +# next-env.d.ts diff --git a/.html-w3c-validatorrc.json b/.html-w3c-validatorrc.json deleted file mode 100644 index 724c149..0000000 --- a/.html-w3c-validatorrc.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "$schema": "https://raw.githubusercontent.com/theoludwig/html-w3c-validator/master/schema/html-w3c-validatorrc-schema.json", - "urls": ["http://127.0.0.1:3000/", "http://127.0.0.1:3000/blog"], - "files": ["./public/curriculum-vitae/index.html"], - "severities": ["error"] -} diff --git a/.husky/commit-msg b/.husky/commit-msg deleted file mode 100755 index f5d969d..0000000 --- a/.husky/commit-msg +++ /dev/null @@ -1,3 +0,0 @@ -#!/usr/bin/env sh - -npm run lint:commit -- --edit diff --git a/.husky/pre-commit b/.husky/pre-commit deleted file mode 100755 index 20e719e..0000000 --- a/.husky/pre-commit +++ /dev/null @@ -1,3 +0,0 @@ -#!/usr/bin/env sh - -npm run lint:staged diff --git a/.lintstagedrc.json b/.lintstagedrc.json deleted file mode 100644 index ebbecc7..0000000 --- a/.lintstagedrc.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "**/*": ["editorconfig-checker", "prettier --write --ignore-unknown"], - "**/*.md": ["markdownlint-cli2 --fix --no-globs"], - "**/*.{js,jsx,ts,tsx}": [ - "eslint --fix --max-warnings 0 --report-unused-disable-directives" - ] -} diff --git a/.npmrc b/.npmrc index cffe8cd..1dab4ed 100644 --- a/.npmrc +++ b/.npmrc @@ -1 +1 @@ -save-exact=true +save-exact = true diff --git a/.prettierrc.json b/.prettierrc.json old mode 100644 new mode 100755 index 4d9a0bb..30351be --- a/.prettierrc.json +++ b/.prettierrc.json @@ -1,4 +1,13 @@ { "semi": false, - "plugins": ["prettier-plugin-tailwindcss"] + "plugins": ["prettier-plugin-tailwindcss"], + "tailwindFunctions": ["classNames", "cva"], + "overrides": [ + { + "files": "pnpm-lock.yaml", + "options": { + "rangeEnd": 0 + } + } + ] } diff --git a/.releaserc.json b/.releaserc.json index c5979ae..fb75ef7 100644 --- a/.releaserc.json +++ b/.releaserc.json @@ -1,28 +1,22 @@ { - "branches": ["main"], + "branches": ["main", { "name": "staging", "prerelease": true }], "plugins": [ + "@semantic-release/commit-analyzer", + "@semantic-release/release-notes-generator", [ - "@semantic-release/commit-analyzer", + "@semantic-release/exec", { - "preset": "conventionalcommits" - } - ], - [ - "@semantic-release/release-notes-generator", - { - "preset": "conventionalcommits" - } - ], - [ - "@semantic-release/npm", - { - "npmPublish": false + "prepareCmd": "replace-in-files --regex='version\": *\"[^\"]*' --replacement='\"version\": \"${nextRelease.version}\"' '**/package.json' '!**/node_modules/**'" } ], [ "@semantic-release/git", { - "assets": ["package.json", "package-lock.json"], + "assets": [ + "package.json", + "apps/*/package.json", + "packages/*/package.json" + ], "message": "chore(release): ${nextRelease.version} [skip ci]" } ], @@ -30,8 +24,10 @@ [ "@saithodev/semantic-release-backmerge", { - "branches": [{ "from": "main", "to": "develop" }], - "backmergeStrategy": "merge" + "branches": [ + { "from": "main", "to": "develop" }, + { "from": "staging", "to": "develop" } + ] } ] ] diff --git a/.vscode/extensions.json b/.vscode/extensions.json index 8aae002..3cd506d 100644 --- a/.vscode/extensions.json +++ b/.vscode/extensions.json @@ -1,5 +1,6 @@ { "recommendations": [ + "Vercel.turbo-vsc", "editorconfig.editorconfig", "esbenp.prettier-vscode", "dbaeumer.vscode-eslint", diff --git a/.vscode/react.code-snippets b/.vscode/react.code-snippets new file mode 100644 index 0000000..38f5c1c --- /dev/null +++ b/.vscode/react.code-snippets @@ -0,0 +1,43 @@ +{ + "React Component": { + "scope": "typescriptreact", + "prefix": "rfc", + "body": [ + "export interface ${1:ComponentName}Props {}", + "", + "export const ${1:ComponentName}: React.FC<${1:ComponentName}Props> = () => {", + " return (", + "
", + "

${1:ComponentName}

", + "
", + " )", + "}", + "", + ], + "description": "React Component", + }, + "React Component Story": { + "scope": "typescriptreact", + "prefix": "rfcs", + "body": [ + "import type { Meta, StoryObj } from \"@storybook/react\"", + "", + "import { ${1:ComponentName} as ${1:ComponentName}Component } from \"./${1:ComponentName}\"", + "", + "const meta = {", + " title: \"${1:ComponentName}\",", + " component: ${1:ComponentName}Component", + "} satisfies Meta", + "", + "export default meta", + "", + "type Story = StoryObj", + "", + "export const ${1:ComponentName}: Story = {", + " args: {}", + "}", + "", + ], + "description": "React Component Story", + }, +} diff --git a/.vscode/settings.json b/.vscode/settings.json index 3240653..f6ffb0a 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,14 +1,20 @@ { "typescript.tsdk": "node_modules/typescript/lib", "editor.bracketPairColorization.enabled": true, + "editor.wordWrap": "on", "prettier.configPath": ".prettierrc.json", "editor.defaultFormatter": "esbenp.prettier-vscode", "editor.formatOnSave": true, "editor.codeActionsOnSave": { - "source.fixAll": "explicit" + "source.fixAll": "explicit", + "source.organizeImports": "explicit" }, "eslint.options": { "ignorePath": ".gitignore" }, - "prettier.ignorePath": ".gitignore" + "prettier.ignorePath": ".gitignore", + "tailwindCSS.experimental.classRegex": [ + ["cva\\(([^)]*)\\)", "[\"'`]([^\"'`]*).*?[\"'`]"], + ["cx\\(([^)]*)\\)", "(?:'|\"|`)([^']*)(?:'|\"|`)"] + ] } diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 9cb9e67..afa3894 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -31,8 +31,8 @@ The commit message guidelines adheres to [Conventional Commits](https://www.conv ### Prerequisites -- [Node.js](https://nodejs.org/) >= 20.0.0 -- [npm](https://www.npmjs.com/) >= 10.0.0 +- [Node.js](https://nodejs.org/) >= 22.0.0 +- [pnpm](https://pnpm.io/) >= 9.5.0 ### Installation @@ -40,21 +40,35 @@ The commit message guidelines adheres to [Conventional Commits](https://www.conv # Clone the repository git clone git@github.com:theoludwig/theoludwig.git -# Go to the project root -cd theoludwig - # Configure environment variables cp .env.example .env +cp apps/website/.env.example apps/website/.env -# Install -npm clean-install +# Install dependencies +pnpm install --frozen-lockfile + +# Install Playwright browser binaries and their dependencies (tests) +pnpm exec playwright install --with-deps ``` -### Local Development environment +### Development ```sh -# Run website -npm run dev +# Start the development server +node --run dev + +# Lint +node --run lint:editorconfig +node --run lint:markdown +node --run lint:prettier +node --run lint:eslint +node --run lint:typescript + +# Tests +node --run test + +# Build +node --run build ``` ### Production environment with [Docker](https://www.docker.com/) @@ -64,6 +78,6 @@ npm run dev docker compose up --build ``` -### Service started +#### Services started -`website`: +`theoludwig`: diff --git a/Dockerfile b/Dockerfile deleted file mode 100644 index c58cad1..0000000 --- a/Dockerfile +++ /dev/null @@ -1,28 +0,0 @@ -FROM node:20.15.1 AS builder-dependencies -WORKDIR /usr/src/application -COPY ./package*.json ./ -RUN npm clean-install - -FROM node:20.15.1 AS builder -ENV NEXT_TELEMETRY_DISABLED=1 -ENV IS_STANDALONE=true -WORKDIR /usr/src/application -COPY --from=builder-dependencies /usr/src/application/node_modules ./node_modules -COPY ./ ./ -RUN npm run build - -FROM node:20.15.1-slim AS runner -ENV NODE_ENV=production -ENV HOSTNAME=0.0.0.0 -ENV NEXT_TELEMETRY_DISABLED=1 -ENV IS_STANDALONE=true -WORKDIR /usr/src/application -RUN addgroup --system --gid 1001 nodejs && adduser --system --uid 1001 applicationrunner -USER applicationrunner -COPY --from=builder-dependencies --chown=applicationrunner:nodejs /usr/src/application/node_modules ./node_modules -COPY --from=builder --chown=applicationrunner:nodejs /usr/src/application/.next/standalone ./ -COPY --from=builder --chown=applicationrunner:nodejs /usr/src/application/.next/static ./.next/static -COPY --from=builder --chown=applicationrunner:nodejs /usr/src/application/public ./public -COPY --from=builder --chown=applicationrunner:nodejs /usr/src/application/i18n/translations ./i18n/translations -COPY --from=builder --chown=applicationrunner:nodejs /usr/src/application/next.config.js ./next.config.js -CMD ["./server.js"] diff --git a/README.md b/README.md index ff68a0f..64dc285 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ GitHub GitLab npm - Twitter + Twitter YouTube Twitch Website @@ -23,7 +23,7 @@ { "name": "Théo LUDWIG", "pronouns": "He/Him", - "birthDate": "31/03/2003", + "birthDate": "2003-03-31", "nationality": "Alsace, France", "interests": ["Developer Full Stack", "Open-Source Enthusiast"], "skills": { diff --git a/app/blog/[slug]/loading.tsx b/app/blog/[slug]/loading.tsx deleted file mode 100644 index 94a0104..0000000 --- a/app/blog/[slug]/loading.tsx +++ /dev/null @@ -1,11 +0,0 @@ -import { Loader } from "@/components/design/Loader" - -const Loading = (): JSX.Element => { - return ( -
- -
- ) -} - -export default Loading diff --git a/app/blog/loading.tsx b/app/blog/loading.tsx deleted file mode 100644 index 94a0104..0000000 --- a/app/blog/loading.tsx +++ /dev/null @@ -1,11 +0,0 @@ -import { Loader } from "@/components/design/Loader" - -const Loading = (): JSX.Element => { - return ( -
- -
- ) -} - -export default Loading diff --git a/app/blog/page.tsx b/app/blog/page.tsx deleted file mode 100644 index 7a4dc30..0000000 --- a/app/blog/page.tsx +++ /dev/null @@ -1,42 +0,0 @@ -import { Suspense } from "react" -import type { Metadata } from "next" - -import { BlogPosts } from "@/blog/BlogPosts" -import { Loader } from "@/components/design/Loader" - -const title = "Blog | Théo LUDWIG" -const description = - "The latest news about my journey of learning computer science." - -export const metadata: Metadata = { - title, - description, - openGraph: { - title, - description, - }, - twitter: { - title, - description, - }, -} - -const BlogPage = async (): Promise => { - return ( -
-
-

- Blog -

-

- {description} -

-
- }> - - -
- ) -} - -export default BlogPage diff --git a/app/error.tsx b/app/error.tsx deleted file mode 100644 index ae26055..0000000 --- a/app/error.tsx +++ /dev/null @@ -1,32 +0,0 @@ -"use client" - -import { useEffect } from "react" - -export interface ErrorHandlingProps { - error: Error -} - -const ErrorHandling = (props: ErrorHandlingProps): JSX.Element => { - const { error } = props - - useEffect(() => { - console.error(error) - }, [error]) - - return ( -
-

- Error{" "} - - 500 - -

-

Server error

-
- ) -} - -export default ErrorHandling diff --git a/app/globals.css b/app/globals.css deleted file mode 100644 index 9ea82ac..0000000 --- a/app/globals.css +++ /dev/null @@ -1,80 +0,0 @@ -@tailwind base; -@tailwind components; -@tailwind utilities; - -.break-wrap-words { - word-wrap: break-word; - word-break: break-word; -} - -.text-base { - line-height: 1.75rem; -} - -.prose { - @apply !max-w-5xl scroll-smooth text-gray dark:text-gray-300; -} - -.prose p { - @apply text-justify; -} - -.prose [id]::before { - content: ""; - display: block; - height: 90px; - margin-top: -90px; - visibility: hidden; -} - -.prose a, -.prose strong { - @apply !font-semibold text-primary dark:text-primary-dark; -} - -strong, -b { - @apply font-bold; -} - -.prose h2, -.prose h3, -.prose h4, -.prose h5, -.prose h6 { - @apply mt-1 text-gray dark:text-gray-dark; -} - -.prose code { - color: #ce9178; -} -.prose :where(code):not(:where([class~="not-prose"] *))::before, -.prose :where(code):not(:where([class~="not-prose"] *))::after { - content: ""; -} -.shiki { - white-space: pre-wrap !important; -} -code { - counter-reset: step; - counter-increment: step 0; -} -code .line::before { - content: counter(step); - counter-increment: step; - margin-right: 1rem; - text-align: right; - color: rgba(133, 133, 133, 0.8); - word-wrap: normal; - word-break: normal; -} - -code .line:last-child { - display: none; -} - -.katex .base { - display: inline !important; - white-space: normal !important; - width: 100% !important; -} diff --git a/app/layout.tsx b/app/layout.tsx deleted file mode 100644 index 22876f6..0000000 --- a/app/layout.tsx +++ /dev/null @@ -1,80 +0,0 @@ -import type { Metadata } from "next" -import classNames from "clsx" - -import "@fontsource/montserrat/400.css" -import "@fontsource/montserrat/600.css" -import "./globals.css" - -import { Header } from "@/components/Header" -import { Footer } from "@/components/Footer" -import { getI18n } from "@/i18n/i18n.server" -import { getTheme } from "@/theme/theme.server" - -const title = "Théo LUDWIG" -const description = - "Théo LUDWIG - Developer Full Stack • Open-Source Enthusiast" -const image = "/images/logo.png" -const url = new URL("https://theoludwig.fr") -const locale = "fr-FR, en-US" - -export const metadata: Metadata = { - title, - description, - metadataBase: url, - openGraph: { - title, - description, - url, - siteName: title, - images: [ - { - url: image, - width: 96, - height: 96, - }, - ], - locale, - type: "website", - }, - twitter: { - card: "summary", - title, - description, - images: [image], - }, -} - -interface RootLayoutProps { - children: React.ReactNode -} - -const RootLayout = (props: RootLayoutProps): JSX.Element => { - const { children } = props - - const i18n = getI18n() - const theme = getTheme() - - return ( - - -
- {children} -