1
1
mirror of https://github.com/theoludwig/theoludwig.git synced 2024-12-08 00:44:30 +01:00

Compare commits

..

No commits in common. "59153a7a69bc419e6c7aadcededc3a950e7f6911" and "12f1d6cdf282fef65ad4f478d8531b30b1b265a8" have entirely different histories.

37 changed files with 2782 additions and 2870 deletions

View File

@ -1,2 +1 @@
TZ=UTC
WEBSITE_PORT=3000

View File

@ -11,14 +11,14 @@ jobs:
timeout-minutes: 30
runs-on: "ubuntu-latest"
steps:
- uses: "actions/checkout@v4.2.1"
- 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.4"
uses: "actions/setup-node@v4.0.3"
with:
node-version: "22.x"
cache: "pnpm"

View File

@ -11,12 +11,12 @@ jobs:
timeout-minutes: 30
runs-on: "ubuntu-latest"
steps:
- uses: "actions/checkout@v4.2.1"
- uses: "actions/checkout@v4.1.7"
- uses: "pnpm/action-setup@v4.0.0"
- name: "Setup Node.js"
uses: "actions/setup-node@v4.0.4"
uses: "actions/setup-node@v4.0.3"
with:
node-version: "22.x"
cache: "pnpm"
@ -29,15 +29,15 @@ jobs:
- run: "node --run lint:editorconfig"
- run: "node --run lint:markdown"
- run: "node --run lint:typescript"
- run: "node --run lint:eslint"
- 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.2.1"
- uses: "actions/checkout@v4.1.7"
- uses: "wagoid/commitlint-github-action@v6.1.2"

View File

@ -14,7 +14,7 @@ jobs:
pull-requests: "write"
id-token: "write"
steps:
- uses: "actions/checkout@v4.2.1"
- uses: "actions/checkout@v4.1.7"
with:
fetch-depth: 0
persist-credentials: false
@ -29,7 +29,7 @@ jobs:
- uses: "pnpm/action-setup@v4.0.0"
- name: "Setup Node.js"
uses: "actions/setup-node@v4.0.4"
uses: "actions/setup-node@v4.0.3"
with:
node-version: "22.x"
cache: "pnpm"

1
.npmrc Normal file
View File

@ -0,0 +1 @@
save-exact = true

View File

@ -3,11 +3,9 @@
"editorconfig.editorconfig",
"esbenp.prettier-vscode",
"dbaeumer.vscode-eslint",
"davidanson.vscode-markdownlint",
"bradlc.vscode-tailwindcss",
"mikestead.dotenv",
"ms-azuretools.vscode-docker",
"antfu.pnpm-catalog-lens",
"Lokalise.i18n-ally"
"davidanson.vscode-markdownlint",
"ms-azuretools.vscode-docker"
]
}

View File

@ -16,12 +16,5 @@
"tailwindCSS.experimental.classRegex": [
["cva\\(([^)]*)\\)", "[\"'`]([^\"'`]*).*?[\"'`]"],
["cx\\(([^)]*)\\)", "(?:'|\"|`)([^']*)(?:'|\"|`)"]
],
"i18n-ally.localesPaths": ["./packages/i18n/src/translations/"],
"i18n-ally.keystyle": "nested",
"i18n-ally.sortKeys": true,
"i18n-ally.sourceLanguage": "en-US",
"i18n-ally.displayLanguage": "en-US",
"i18n-ally.enabledFrameworks": ["next-intl", "general"],
"i18n-ally.extract.autoDetect": true
]
}

View File

@ -32,8 +32,7 @@ The commit message guidelines adheres to [Conventional Commits](https://www.conv
### Prerequisites
- [Node.js](https://nodejs.org/) >= 22.0.0
- [pnpm](https://pnpm.io/) >= 9.12.1 [(`corepack enable`)](https://nodejs.org/docs/latest-v22.x/api/corepack.html)
- [Docker](https://www.docker.com/)
- [pnpm](https://pnpm.io/) >= 9.10.0
### Installation
@ -64,19 +63,15 @@ node --run dev
# Lint
node --run lint:editorconfig
node --run lint:markdown
node --run lint:typescript
node --run lint:eslint
node --run lint:prettier
node --run lint:eslint
node --run lint:typescript
# Tests
node --run test
# Build
node --run build
# To execute a command in a specific package (e.g: packages/utils)
cd packages/utils
node --run test
```
### Production environment with [Docker](https://www.docker.com/)

View File

@ -7,11 +7,7 @@ const config: StorybookConfig = {
docs: {
defaultName: "Documentation",
},
stories: [
"../../../packages/ui/src/**/*.stories.tsx",
"../../../packages/blog/src/**/*.stories.tsx",
"../stories/*.mdx",
],
stories: ["../../../packages/**/*.stories.tsx", "../stories/*.mdx"],
addons: [
"@storybook/addon-essentials",
"@storybook/addon-storysource",

View File

@ -1,7 +1,7 @@
import "@repo/config-tailwind/styles.css"
import { defaultTranslationValues } from "@repo/i18n/config"
import i18nMessagesEnglish from "@repo/i18n/translations/en-US.json"
import { LOCALE_DEFAULT } from "@repo/utils/constants"
import type { Locale } from "@repo/utils/constants"
import type { Preview } from "@storybook/react"
import { NextIntlClientProvider } from "next-intl"
import { ThemeProvider as NextThemeProvider } from "next-themes"
@ -25,7 +25,6 @@ const preview: Preview = {
stylePreview: true,
},
controls: {
disableSaveFromUI: true,
matchers: {
color: /(background|color)$/i,
date: /Date$/i,
@ -34,13 +33,14 @@ const preview: Preview = {
},
decorators: [
(Story) => {
const locale = "en-US" satisfies Locale
return (
<NextThemeProvider enableColorScheme={false}>
<NextIntlClientProvider
messages={i18nMessagesEnglish}
locale={LOCALE_DEFAULT}
locale={locale}
defaultTranslationValues={defaultTranslationValues}
timeZone={process.env["TZ"] ?? "UTC"}
>
<Story />
</NextIntlClientProvider>

View File

@ -7,9 +7,9 @@
"build": "storybook build",
"dev": "storybook dev --port 6006 --no-open",
"start": "http-server \"storybook-static\" --port 6006 --silent",
"test": "start-server-and-test \"start\" http://127.0.0.1:6006 \"test:storybook\"",
"test:dev": "start-server-and-test \"dev\" http://127.0.0.1:6006 \"test:storybook\"",
"test:storybook": "test-storybook --testTimeout=60000 --maxWorkers=2",
"test": "start-server-and-test \"dev\" http://127.0.0.1:6006 \"test:storybook\"",
"test:storybook": "test-storybook",
"test:storybook-coverage": "test-storybook --coverage",
"chromatic": "chromatic"
},
"dependencies": {

View File

@ -2,11 +2,7 @@ import sharedConfig from "@repo/config-tailwind"
/** @type {Pick<import('tailwindcss').Config, "presets" | "content">} */
const config = {
content: [
".storybook/preview.tsx",
"../../packages/ui/src/**/*.tsx",
"../../packages/blog/src/**/*.tsx",
],
content: [".storybook/preview.tsx", "../../packages/*/src/**/*.tsx"],
presets: [sharedConfig],
}

View File

@ -1,9 +0,0 @@
{
"$schema": "https://turbo.build/schema.json",
"extends": ["//"],
"tasks": {
"test": {
"dependsOn": ["^test", "build"]
}
}
}

View File

@ -7,7 +7,7 @@
"plugins": ["@typescript-eslint"],
"parser": "@typescript-eslint/parser",
"parserOptions": {
"projectService": true
"project": true
}
}
]

View File

@ -8,7 +8,7 @@ WORKDIR /usr/src/app
FROM node-pnpm AS builder
COPY ./ ./
RUN pnpm install --global turbo@2.1.3
RUN pnpm install --global turbo@2.1.1
RUN turbo prune @repo/website --docker
FROM node-pnpm AS installer

View File

@ -1,6 +1,6 @@
import { getBlogPosts } from "@repo/blog"
import { BlogPosts } from "@repo/blog/BlogPosts"
import type { LocaleProps } from "@repo/i18n/config"
import { type LocaleProps } from "@repo/i18n/config"
import { MainLayout } from "@repo/ui/Layout/MainLayout"
import {
Section,

View File

@ -2,4 +2,4 @@
/// <reference types="next/image-types/global" />
// NOTE: This file should not be edited
// see https://nextjs.org/docs/app/building-your-application/configuring/typescript for more information.
// see https://nextjs.org/docs/basic-features/typescript for more information.

View File

@ -5,10 +5,6 @@ const IS_STANDALONE = process.env.IS_STANDALONE === "true"
/** @type {import('next').NextConfig} */
const nextConfig = {
output: IS_STANDALONE ? "standalone" : undefined,
images: {
unoptimized: true,
},
compress: false,
// https://github.com/hashicorp/next-mdx-remote/issues/436#issuecomment-2066971842
transpilePackages: ["next-mdx-remote", "shiki"],

View File

@ -22,7 +22,8 @@
"next": "catalog:",
"next-intl": "catalog:",
"react": "catalog:",
"react-dom": "catalog:"
"react-dom": "catalog:",
"sharp": "catalog:"
},
"devDependencies": {
"@repo/eslint-config": "workspace:*",

View File

@ -2,11 +2,7 @@ import sharedConfig from "@repo/config-tailwind"
/** @type {Pick<import('tailwindcss').Config, "presets" | "content">} */
const config = {
content: [
"./app/**/*.tsx",
"../../packages/ui/src/**/*.tsx",
"../../packages/blog/src/**/*.tsx",
],
content: ["./app/**/*.tsx", "../../packages/*/src/**/*.tsx"],
presets: [sharedConfig],
}

View File

@ -3,10 +3,10 @@
"version": "4.0.0",
"private": true,
"type": "module",
"packageManager": "pnpm@9.12.1+sha512.e5a7e52a4183a02d5931057f7a0dbff9d5e9ce3161e33fa68ae392125b79282a8a8a470a51dfc8a0ed86221442eb2fb57019b0990ed24fab519bf0e1bc5ccfc4",
"packageManager": "pnpm@9.10.0+sha512.73a29afa36a0d092ece5271de5177ecbf8318d454ecd701343131b8ebc0c1a91c487da46ab77c8e596d6acf1461e3594ced4becedf8921b074fbd8653ed7051c",
"engines": {
"node": ">=22.0.0",
"pnpm": ">=9.12.1"
"pnpm": ">=9.10.0"
},
"scripts": {
"build": "turbo run build",
@ -15,25 +15,25 @@
"test": "turbo run test",
"lint:editorconfig": "editorconfig-checker",
"lint:markdown": "markdownlint-cli2",
"lint:typescript": "turbo run lint:typescript",
"lint:eslint": "turbo run lint:eslint",
"lint:prettier": "prettier . --check",
"lint:eslint": "turbo run lint:eslint",
"lint:typescript": "turbo run lint:typescript",
"release": "semantic-release"
},
"devDependencies": {
"@saithodev/semantic-release-backmerge": "catalog:",
"@semantic-release/exec": "catalog:",
"@semantic-release/git": "catalog:",
"editorconfig-checker": "catalog:",
"@saithodev/semantic-release-backmerge": "4.0.1",
"@semantic-release/exec": "6.0.3",
"@semantic-release/git": "10.0.1",
"editorconfig-checker": "5.1.8",
"playwright": "catalog:",
"prettier": "catalog:",
"prettier-plugin-tailwindcss": "catalog:",
"markdownlint-cli2": "catalog:",
"markdownlint": "catalog:",
"markdownlint-rule-relative-links": "catalog:",
"replace-in-files-cli": "catalog:",
"semantic-release": "catalog:",
"turbo": "catalog:",
"prettier": "3.3.3",
"prettier-plugin-tailwindcss": "0.6.6",
"markdownlint-cli2": "0.14.0",
"markdownlint": "0.35.0",
"markdownlint-rule-relative-links": "3.0.0",
"replace-in-files-cli": "3.0.0",
"semantic-release": "23.1.1",
"turbo": "2.1.1",
"typescript": "catalog:"
}
}

View File

@ -7,7 +7,7 @@
"plugins": ["@typescript-eslint"],
"parser": "@typescript-eslint/parser",
"parserOptions": {
"projectService": true
"project": true
}
}
]

View File

@ -20,7 +20,6 @@
"js": "never",
"jsx": "never"
}
],
"import-x/consistent-type-specifier-style": ["error", "prefer-top-level"]
]
}
}

View File

@ -7,7 +7,7 @@
"plugins": ["@typescript-eslint"],
"parser": "@typescript-eslint/parser",
"parserOptions": {
"projectService": true
"project": true
}
}
]

View File

@ -8,6 +8,7 @@
"noImplicitReturns": true,
"noImplicitThis": true,
"noImplicitAny": true,
"noPropertyAccessFromIndexSignature": true,
"noUncheckedIndexedAccess": true,
"noUnusedLocals": true,
"noUnusedParameters": true,

View File

@ -7,7 +7,7 @@
"plugins": ["@typescript-eslint"],
"parser": "@typescript-eslint/parser",
"parserOptions": {
"projectService": true
"project": true
}
}
]

View File

@ -1,162 +1,162 @@
{
"curriculum-vitae": {
"about": {
"description": "I constantly wonder how to improve our present, to make our future better, particularly thanks to the advancements in computer science. <br></br> My priority is to craft intuitive user experiences (UX), that meet the needs of the users in the most efficient way possible.",
"title": "About"
},
"description": "Developer Full Stack • Student",
"education": {
"cnam": {
"institution": "Conservatoire National des Arts et Métiers (CNAM), in Eckbolsheim - UIMM Alsace - ITII Alsace",
"study-type": "Engineer in Computer Science and Information Systems (IS)",
"years": {
"2024-2025": {
"courses": {},
"description": "1st year",
"title": "2024 - 2025"
}
}
},
"iut": {
"institution": "IUT Robert Schuman in Illkirch-Graffenstaden",
"study-type": "University Bachelor of Technology (BUT) Computer Science",
"years": {
"2021-2022": {
"courses": {
"java": "Object Oriented Development in Java",
"sql": "Relational database and SQL language",
"systems-c": "Systems programming in C (Memory allocation, Pointers, Structures)",
"windows-forms": "Windows Forms (.NET Framework) Application Development in C#"
},
"description": "1st year",
"title": "2021 - 2022"
},
"2022-2023": {
"courses": {
"clean-code": "Design Patterns and Principles (Maintainable and Reusable Code) in UML",
"sql-security": "Securing database access and PL/SQL",
"systems-c": "Systems programming in C (Multi-Thread, Server/Client UDP/TCP)",
"tests": "Development Quality and Automated Testing",
"web": "Web development with the Laravel framework in PHP"
},
"description": "2nd year",
"title": "2022 - 2023"
},
"2023-2024": {
"courses": {
"ci-cd": "Continuous Integration/Deployment (CI/CD) and Docker",
"complexity-algorithms": "Theoretical and Practical Algorithmic Complexity in C++",
"no-sql": "NoSQL database (Redis, MongoDB, Cassandra)",
"web": "Web development in Node.js and React.js"
},
"description": "3rd year",
"title": "2023 - 2024"
}
}
},
"lycee": {
"institution": "Heinrich Nessel High School in Haguenau",
"score": "Mention Quite Good",
"study-type": "General Baccalaureate (Mathematics and Computer Science)",
"years": {
"2019-2021": {
"title": "2019 - 2021"
}
}
},
"title": "Studies"
},
"interests": {
"high-tech": "Passionate about High-Tech",
"open-source": "Open-Source Enthusiast"
},
"work": {
"ircad": {
"duration": "4 ans",
"position": "Full Stack Web Developer Apprentice",
"summary": "Development of WebSurg, a virtual university dedicated to medical-surgical training, in React.js/Next.js and API Platform with Symfony."
},
"numerize": {
"duration": "4 months",
"position": "Full Stack Web Developer Intern",
"summary": "Development of an DMS (Document Management System) tool in React.js, Laravel and GraphQL."
},
"title": "Work experiences"
}
},
"errors": {
"error": "Error",
"not-found": "Not Found",
"page-doesnt-exist": "This page doesn't exist!",
"return-to-home-page": "Return to the home page?",
"server-error": "Internal Server Error!",
"try-again": "Try again?"
},
"footer": {
"all-rights-reserved": "All rights reserved"
},
"home": {
"about": {
"birth-date": {
"label": "Birth date",
"value": "{birthDate} ({age} years old)"
},
"description": "I constantly wonder how to <strong>improve our present, to make our future better</strong>, particularly thanks to the advancements in <strong>computer science</strong>.",
"email": {
"label": "Email",
"value": "{email}"
},
"nationality": {
"label": "Nationality",
"value": "Alsace, France"
},
"pronouns": {
"label": "Pronouns",
"value": "He/Him"
}
},
"interests": {
"code": {
"description": "My priority is to craft <strong>intuitive user experiences (<abbr-ux>UX</abbr-ux>)</strong>, that meet the needs of the users <strong>in the most efficient way possible</strong>. <br></br> Mainly focused on the development of <strong>Web solutions</strong>. <br></br> I am also interested in mobile and desktop application development, among other areas within the field of computer science.",
"title": "Developer Full Stack"
},
"open-source": {
"description": "I value the <strong>sharing of knowledge and collaboration</strong> to collectively resolve problems. <br></br> The source code of the website is available on <github-link>GitHub</github-link>.",
"title": "Open-Source Enthusiast"
},
"title": "Interests"
},
"open-source": {
"description": "Most famous open source projects I contributed to.",
"title": "Open-Source"
},
"portfolio": {
"carolo": {
"description": "Strategy board game similar to chess which allows grandiose moves (only available in French).",
"title": "Carolo"
},
"leon": {
"description": "Leon is your open-source personal assistant.",
"title": "Leon"
},
"title": "Portfolio"
},
"skills": {
"backend": "Backend",
"driving-license": "Driving license",
"frontend": "Frontend",
"others": "Others",
"programming-languages": "Programming languages",
"software-tools": "Software and tools",
"title": "Skills"
}
"meta": {
"title": "Théo LUDWIG",
"description": "Developer Full Stack • Open-Source Enthusiast"
},
"locales": {
"en-US": "English",
"fr-FR": "French"
},
"meta": {
"description": "Developer Full Stack • Open-Source Enthusiast",
"title": "Théo LUDWIG"
"footer": {
"all-rights-reserved": "All rights reserved"
},
"errors": {
"error": "Error",
"page-doesnt-exist": "This page doesn't exist!",
"not-found": "Not Found",
"server-error": "Internal Server Error!",
"return-to-home-page": "Return to the home page?",
"try-again": "Try again?"
},
"home": {
"about": {
"pronouns": {
"label": "Pronouns",
"value": "He/Him"
},
"birth-date": {
"label": "Birth date",
"value": "{birthDate} ({age} years old)"
},
"nationality": {
"label": "Nationality",
"value": "Alsace, France"
},
"email": {
"label": "Email",
"value": "{email}"
},
"description": "I constantly wonder how to <strong>improve our present, to make our future better</strong>, particularly thanks to the advancements in <strong>computer science</strong>."
},
"interests": {
"title": "Interests",
"code": {
"title": "Developer Full Stack",
"description": "My priority is to craft <strong>intuitive user experiences (<abbr-ux>UX</abbr-ux>)</strong>, that meet the needs of the users <strong>in the most efficient way possible</strong>. <br></br> Mainly focused on the development of <strong>Web solutions</strong>. <br></br> I am also interested in mobile and desktop application development, among other areas within the field of computer science."
},
"open-source": {
"title": "Open-Source Enthusiast",
"description": "I value the <strong>sharing of knowledge and collaboration</strong> to collectively resolve problems. <br></br> The source code of the website is available on <github-link>GitHub</github-link>."
}
},
"skills": {
"title": "Skills",
"programming-languages": "Programming languages",
"frontend": "Frontend",
"backend": "Backend",
"software-tools": "Software and tools",
"others": "Others",
"driving-license": "Driving license"
},
"portfolio": {
"title": "Portfolio",
"carolo": {
"title": "Carolo",
"description": "Strategy board game similar to chess which allows grandiose moves (only available in French)."
},
"leon": {
"title": "Leon",
"description": "Leon is your open-source personal assistant."
}
},
"open-source": {
"title": "Open-Source",
"description": "Most famous open source projects I contributed to."
}
},
"curriculum-vitae": {
"description": "Developer Full Stack • Student",
"about": {
"title": "About",
"description": "I constantly wonder how to improve our present, to make our future better, particularly thanks to the advancements in computer science. <br></br> My priority is to craft intuitive user experiences (UX), that meet the needs of the users in the most efficient way possible."
},
"education": {
"title": "Studies",
"cnam": {
"study-type": "Engineer in Computer Science and Information Systems (IS)",
"institution": "Conservatoire National des Arts et Métiers (CNAM), in Eckbolsheim - UIMM Alsace - ITII Alsace",
"years": {
"2024-2025": {
"title": "2024 - 2025",
"description": "1st year",
"courses": {}
}
}
},
"iut": {
"study-type": "University Bachelor of Technology (BUT) Computer Science",
"institution": "IUT Robert Schuman in Illkirch-Graffenstaden",
"years": {
"2023-2024": {
"title": "2023 - 2024",
"description": "3rd year",
"courses": {
"web": "Web development in Node.js and React.js",
"ci-cd": "Continuous Integration/Deployment (CI/CD) and Docker",
"complexity-algorithms": "Theoretical and Practical Algorithmic Complexity in C++",
"no-sql": "NoSQL database (Redis, MongoDB, Cassandra)"
}
},
"2022-2023": {
"title": "2022 - 2023",
"description": "2nd year",
"courses": {
"web": "Web development with the Laravel framework in PHP",
"tests": "Development Quality and Automated Testing",
"clean-code": "Design Patterns and Principles (Maintainable and Reusable Code) in UML",
"systems-c": "Systems programming in C (Multi-Thread, Server/Client UDP/TCP)",
"sql-security": "Securing database access and PL/SQL"
}
},
"2021-2022": {
"title": "2021 - 2022",
"description": "1st year",
"courses": {
"java": "Object Oriented Development in Java",
"systems-c": "Systems programming in C (Memory allocation, Pointers, Structures)",
"windows-forms": "Windows Forms (.NET Framework) Application Development in C#",
"sql": "Relational database and SQL language"
}
}
}
},
"lycee": {
"study-type": "General Baccalaureate (Mathematics and Computer Science)",
"institution": "Heinrich Nessel High School in Haguenau",
"score": "Mention Quite Good",
"years": {
"2019-2021": {
"title": "2019 - 2021"
}
}
}
},
"work": {
"title": "Work experiences",
"ircad": {
"summary": "Development of WebSurg, a virtual university dedicated to medical-surgical training, in React.js/Next.js and API Platform with Symfony.",
"position": "Full Stack Web Developer Apprentice",
"duration": "4 ans"
},
"numerize": {
"summary": "Development of an DMS (Document Management System) tool in React.js, Laravel and GraphQL.",
"position": "Full Stack Web Developer Intern",
"duration": "4 months"
}
},
"interests": {
"open-source": "Open-Source Enthusiast",
"high-tech": "Passionate about High-Tech"
}
}
}

View File

@ -1,162 +1,162 @@
{
"curriculum-vitae": {
"about": {
"description": "Je me demande constamment comment améliorer notre présent, afin de rendre notre futur meilleur, particulièrement grâce aux progrès de l'informatique. <br></br> Ma priorité réside dans la création d'expériences utilisateurs (UX) intuitives, répondant aux besoins des utilisateurs de la manière la plus efficace que possible.",
"title": "À propos"
},
"description": "Développeur Full Stack • Étudiant",
"education": {
"cnam": {
"institution": "Conservatoire National des Arts et Métiers (CNAM) à Eckbolsheim - UIMM Alsace - ITII Alsace",
"study-type": "Ingénieur en Informatique et Systèmes d'Information (SI)",
"years": {
"2024-2025": {
"courses": {},
"description": "1ère année",
"title": "2024 - 2025"
}
}
},
"iut": {
"institution": "IUT Robert Schuman à Illkirch-Graffenstaden",
"study-type": "Bachelor Universitaire de Technologie (BUT) Informatique",
"years": {
"2021-2022": {
"courses": {
"java": "Développement Orientée Objet en Java",
"sql": "Base de données relationnelles et langage SQL",
"systems-c": "Programmation systèmes en C (Allocation mémoire, Pointeurs, Structures)",
"windows-forms": "Développement d'application Windows Forms (.NET Framework) en C#"
},
"description": "1ère année",
"title": "2021 - 2022"
},
"2022-2023": {
"courses": {
"clean-code": "Patrons et Principes de conceptions (Code maintenable et réutilisable) en UML",
"sql-security": "Sécurisation des accès à la base de données et PL/SQL",
"systems-c": "Programmation systèmes en C (Multi-Thread, Serveur/Client UDP/TCP)",
"tests": "Qualité de développement et Tests automatisés",
"web": "Développement Web avec le framework Laravel en PHP"
},
"description": "2ème année",
"title": "2022 - 2023"
},
"2023-2024": {
"courses": {
"ci-cd": "Intégration/Déploiement Continue et Docker",
"complexity-algorithms": "Complexité Algorithmique Théorique et Pratique en C++",
"no-sql": "Base de données NoSQL (Redis, MongoDB, Cassandra)",
"web": "Développement Web en Node.js et React.js"
},
"description": "3ème année",
"title": "2023 - 2024"
}
}
},
"lycee": {
"institution": "Lycée Heinrich Nessel à Haguenau",
"score": "Mention Assez Bien",
"study-type": "Baccalauréat Général (Mathématiques et Numériques Sciences Informatiques)",
"years": {
"2019-2021": {
"title": "2019 - 2021"
}
}
},
"title": "Études"
},
"interests": {
"high-tech": "Passionné de High-Tech",
"open-source": "Enthousiaste de l'Open-Source"
},
"work": {
"ircad": {
"duration": "4 ans",
"position": "Apprenti Développeur Web Full Stack",
"summary": "Développement de WebSurg, une université virtuelle consacrée à la formation médico-chirurgicale, en React.js/Next.js et API Platform avec Symfony."
},
"numerize": {
"duration": "4 mois",
"position": "Stagiaire Développeur Web Full Stack",
"summary": "Développement d'un outil GED (Gestion Électronique de Documents) en React.js, Laravel et GraphQL."
},
"title": "Expériences professionnelles"
}
},
"errors": {
"error": "Erreur",
"not-found": "Introuvable",
"page-doesnt-exist": "Cette page n'existe pas !",
"return-to-home-page": "Retour à la page d'accueil ?",
"server-error": "Erreur interne du serveur !",
"try-again": "Réessayer ?"
},
"footer": {
"all-rights-reserved": "Tous droits réservés"
},
"home": {
"about": {
"birth-date": {
"label": "Date de naissance",
"value": "{birthDate} ({age} ans)"
},
"description": "Je me demande constamment comment <strong>améliorer notre présent, afin de rendre notre futur meilleur</strong>, particulièrement grâce aux progrès de <strong>l'informatique</strong>.",
"email": {
"label": "Email",
"value": "{email}"
},
"nationality": {
"label": "Nationalité",
"value": "Alsace, France"
},
"pronouns": {
"label": "Pronoms",
"value": "Il/Lui"
}
},
"interests": {
"code": {
"description": "Ma priorité réside dans la création <strong>d'expériences utilisateurs (<abbr-ux>UX</abbr-ux>) intuitives</strong>, répondant aux besoins des utilisateurs de la <strong>manière la plus efficace que possible</strong>. <br></br> Principalement axé sur l'élaboration de <strong>solutions en Développement Web</strong>. <br></br> Je suis également intéressé par le développement d'applications mobiles parmis d'autres domaines de l'informatique.",
"title": "Développeur Full Stack"
},
"open-source": {
"description": "J'apprécie le <strong>partage des connaissances et la collaboration</strong> pour résoudre des défis collectivement. <br></br> Le code source du site est accessible sur <github-link>GitHub</github-link>.",
"title": "Enthousiaste de l'Open-Source"
},
"title": "Intérêts"
},
"open-source": {
"description": "Projets open source les plus célèbres auxquels j'ai contribué.",
"title": "Open-Source"
},
"portfolio": {
"carolo": {
"description": "Jeu de plateau stratégique similaire aux échecs qui permet des coups grandioses, reposant sur des enchaînements remarquables.",
"title": "Carolo"
},
"leon": {
"description": "Leon est votre assistant personnel open source.",
"title": "Leon"
},
"title": "Portfolio"
},
"skills": {
"backend": "Backend",
"driving-license": "Permis B",
"frontend": "Frontend",
"others": "Autres",
"programming-languages": "Langages de programmation",
"software-tools": "Logiciels et outils",
"title": "Compétences"
}
"meta": {
"title": "Théo LUDWIG",
"description": "Développeur Full Stack • Enthousiaste de l'Open-Source"
},
"locales": {
"en-US": "Anglais",
"fr-FR": "Français"
},
"meta": {
"description": "Développeur Full Stack • Enthousiaste de l'Open-Source",
"title": "Théo LUDWIG"
"footer": {
"all-rights-reserved": "Tous droits réservés"
},
"errors": {
"error": "Erreur",
"page-doesnt-exist": "Cette page n'existe pas !",
"not-found": "Introuvable",
"server-error": "Erreur interne du serveur !",
"return-to-home-page": "Retour à la page d'accueil ?",
"try-again": "Réessayer ?"
},
"home": {
"about": {
"pronouns": {
"label": "Pronoms",
"value": "Il/Lui"
},
"birth-date": {
"label": "Date de naissance",
"value": "{birthDate} ({age} ans)"
},
"nationality": {
"label": "Nationalité",
"value": "Alsace, France"
},
"email": {
"label": "Email",
"value": "{email}"
},
"description": "Je me demande constamment comment <strong>améliorer notre présent, afin de rendre notre futur meilleur</strong>, particulièrement grâce aux progrès de <strong>l'informatique</strong>."
},
"interests": {
"title": "Intérêts",
"code": {
"title": "Développeur Full Stack",
"description": "Ma priorité réside dans la création <strong>d'expériences utilisateurs (<abbr-ux>UX</abbr-ux>) intuitives</strong>, répondant aux besoins des utilisateurs de la <strong>manière la plus efficace que possible</strong>. <br></br> Principalement axé sur l'élaboration de <strong>solutions en Développement Web</strong>. <br></br> Je suis également intéressé par le développement d'applications mobiles parmis d'autres domaines de l'informatique."
},
"open-source": {
"title": "Enthousiaste de l'Open-Source",
"description": "J'apprécie le <strong>partage des connaissances et la collaboration</strong> pour résoudre des défis collectivement. <br></br> Le code source du site est accessible sur <github-link>GitHub</github-link>."
}
},
"skills": {
"title": "Compétences",
"programming-languages": "Langages de programmation",
"frontend": "Frontend",
"backend": "Backend",
"software-tools": "Logiciels et outils",
"others": "Autres",
"driving-license": "Permis B"
},
"portfolio": {
"title": "Portfolio",
"carolo": {
"title": "Carolo",
"description": "Jeu de plateau stratégique similaire aux échecs qui permet des coups grandioses, reposant sur des enchaînements remarquables."
},
"leon": {
"title": "Leon",
"description": "Leon est votre assistant personnel open source."
}
},
"open-source": {
"title": "Open-Source",
"description": "Projets open source les plus célèbres auxquels j'ai contribué."
}
},
"curriculum-vitae": {
"description": "Développeur Full Stack • Étudiant",
"about": {
"title": "À propos",
"description": "Je me demande constamment comment améliorer notre présent, afin de rendre notre futur meilleur, particulièrement grâce aux progrès de l'informatique. <br></br> Ma priorité réside dans la création d'expériences utilisateurs (UX) intuitives, répondant aux besoins des utilisateurs de la manière la plus efficace que possible."
},
"education": {
"title": "Études",
"cnam": {
"study-type": "Ingénieur en Informatique et Systèmes d'Information (SI)",
"institution": "Conservatoire National des Arts et Métiers (CNAM) à Eckbolsheim - UIMM Alsace - ITII Alsace",
"years": {
"2024-2025": {
"title": "2024 - 2025",
"description": "1ère année",
"courses": {}
}
}
},
"iut": {
"study-type": "Bachelor Universitaire de Technologie (BUT) Informatique",
"institution": "IUT Robert Schuman à Illkirch-Graffenstaden",
"years": {
"2023-2024": {
"title": "2023 - 2024",
"description": "3ème année",
"courses": {
"web": "Développement Web en Node.js et React.js",
"ci-cd": "Intégration/Déploiement Continue et Docker",
"complexity-algorithms": "Complexité Algorithmique Théorique et Pratique en C++",
"no-sql": "Base de données NoSQL (Redis, MongoDB, Cassandra)"
}
},
"2022-2023": {
"title": "2022 - 2023",
"description": "2ème année",
"courses": {
"web": "Développement Web avec le framework Laravel en PHP",
"tests": "Qualité de développement et Tests automatisés",
"clean-code": "Patrons et Principes de conceptions (Code maintenable et réutilisable) en UML",
"systems-c": "Programmation systèmes en C (Multi-Thread, Serveur/Client UDP/TCP)",
"sql-security": "Sécurisation des accès à la base de données et PL/SQL"
}
},
"2021-2022": {
"title": "2021 - 2022",
"description": "1ère année",
"courses": {
"java": "Développement Orientée Objet en Java",
"systems-c": "Programmation systèmes en C (Allocation mémoire, Pointeurs, Structures)",
"windows-forms": "Développement d'application Windows Forms (.NET Framework) en C#",
"sql": "Base de données relationnelles et langage SQL"
}
}
}
},
"lycee": {
"study-type": "Baccalauréat Général (Mathématiques et Numériques Sciences Informatiques)",
"institution": "Lycée Heinrich Nessel à Haguenau",
"score": "Mention Assez Bien",
"years": {
"2019-2021": {
"title": "2019 - 2021"
}
}
}
},
"work": {
"title": "Expériences professionnelles",
"ircad": {
"summary": "Développement de WebSurg, une université virtuelle consacrée à la formation médico-chirurgicale, en React.js/Next.js et API Platform avec Symfony.",
"position": "Apprenti Développeur Web Full Stack",
"duration": "4 ans"
},
"numerize": {
"summary": "Développement d'un outil GED (Gestion Électronique de Documents) en React.js, Laravel et GraphQL.",
"position": "Stagiaire Développeur Web Full Stack",
"duration": "4 mois"
}
},
"interests": {
"open-source": "Enthousiaste de l'Open-Source",
"high-tech": "Passionné de High-Tech"
}
}
}

View File

@ -7,7 +7,7 @@
"plugins": ["@typescript-eslint"],
"parser": "@typescript-eslint/parser",
"parserOptions": {
"projectService": true
"project": true
}
}
]

View File

@ -7,7 +7,7 @@
"plugins": ["@typescript-eslint"],
"parser": "@typescript-eslint/parser",
"parserOptions": {
"projectService": true
"project": true
}
}
]

View File

@ -1,8 +1,7 @@
"use client"
import { useRouter } from "@repo/i18n/navigation"
import { useTranslations } from "next-intl"
import { useEffect, useTransition } from "react"
import { useEffect } from "react"
import { Button } from "../../Design/Button/Button.tsx"
import { Typography } from "../../Design/Typography/Typography.tsx"
import { MainLayout } from "../../Layout/MainLayout/MainLayout.tsx"
@ -16,9 +15,6 @@ export interface ErrorServerProps {
export const ErrorServer: React.FC<ErrorServerProps> = (props) => {
const { error, reset } = props
const [isPending, startTransition] = useTransition()
const router = useRouter()
const t = useTranslations()
useEffect(() => {
@ -33,17 +29,7 @@ export const ErrorServer: React.FC<ErrorServerProps> = (props) => {
</Typography>
<Typography variant="text1" as="p" className="mt-4">
<Button
isLoading={isPending}
onClick={() => {
startTransition(() => {
router.refresh()
reset()
})
}}
>
{t("errors.try-again")}
</Button>
<Button onClick={reset}>{t("errors.try-again")}</Button>
</Typography>
</Section>
</MainLayout>

View File

@ -1,7 +1,6 @@
import { useTranslations } from "next-intl"
import { Section, SectionTitle } from "../../Layout/Section/Section.tsx"
import type { PortfolioProject } from "./PortfolioItem.tsx"
import { PortfolioItem } from "./PortfolioItem.tsx"
import { PortfolioItem, type PortfolioProject } from "./PortfolioItem.tsx"
export interface PortfolioProps {}

View File

@ -33,7 +33,7 @@ export const PortfolioItem: React.FC<PortfolioItemProps> = (props) => {
<div className="flex justify-center">
<Image
quality={100}
className="size-[300px] transition-opacity duration-500 group-hover:opacity-20 dark:group-hover:opacity-5"
className="size-auto transition-opacity duration-500 group-hover:opacity-20 dark:group-hover:opacity-5"
width={300}
height={300}
src={image}

View File

@ -7,7 +7,7 @@
"plugins": ["@typescript-eslint"],
"parser": "@typescript-eslint/parser",
"parserOptions": {
"projectService": true
"project": true
}
}
]

4754
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@ -3,26 +3,19 @@ packages:
- "packages/*"
catalog:
# Turborepo and Releases
"turbo": "2.1.3"
"@saithodev/semantic-release-backmerge": "4.0.1"
"@semantic-release/exec": "6.0.3"
"@semantic-release/git": "10.0.1"
"semantic-release": "23.1.1"
"replace-in-files-cli": "3.0.0"
# Utils
"deepmerge": "4.3.1"
# React.js/Next.js
"next": "14.2.15"
"next-intl": "3.21.1"
"next": "14.2.7"
"next-intl": "3.19.1"
"next-themes": "0.3.0"
"react": "18.3.1"
"react-dom": "18.3.1"
"react-icons": "5.3.0"
"@types/react": "18.3.11"
"@types/react-dom": "18.3.1"
"@types/react": "18.3.5"
"@types/react-dom": "18.3.0"
"sharp": "0.33.5"
# Blog
"@giscus/react": "3.0.0"
@ -35,70 +28,60 @@ catalog:
"rehype-slug": "6.0.0"
"remark-gfm": "4.0.0"
"remark-math": "6.0.0"
"shiki": "1.22.0"
"@shikijs/rehype": "1.22.0"
"shiki": "1.17.0"
"@shikijs/rehype": "1.17.0"
# TypeScript
"typescript": "5.5.4"
"@total-typescript/ts-reset": "0.6.1"
"@types/node": "22.7.5"
"@types/node": "22.5.4"
# ESLint
"@typescript-eslint/eslint-plugin": "8.8.1"
"@typescript-eslint/parser": "8.8.1"
"eslint": "8.57.1"
"eslint-config-conventions": "16.0.1"
"@typescript-eslint/eslint-plugin": "7.18.0"
"@typescript-eslint/parser": "7.18.0"
"eslint": "8.57.0"
"eslint-config-conventions": "14.4.0"
"eslint-plugin-promise": "7.1.0"
"eslint-plugin-unicorn": "55.0.0"
"eslint-config-next": "14.2.15"
"eslint-plugin-storybook": "0.9.0"
"eslint-plugin-tailwindcss": "3.17.5"
"eslint-plugin-import-x": "4.3.1"
# Prettier
"prettier": "3.3.3"
"prettier-plugin-tailwindcss": "0.6.8"
"editorconfig-checker": "6.0.0"
# Markdown Lint
"markdownlint-cli2": "0.14.0"
"markdownlint": "0.35.0"
"markdownlint-rule-relative-links": "3.0.0"
"eslint-config-next": "14.2.7"
"eslint-plugin-storybook": "0.8.0"
"eslint-plugin-tailwindcss": "3.17.4"
"eslint-plugin-import-x": "3.1.0"
# Storybook
"@chromatic-com/storybook": "2.0.2"
"@storybook/addon-a11y": "8.3.5"
"@storybook/addon-essentials": "8.3.5"
"@storybook/addon-interactions": "8.3.5"
"@storybook/addon-links": "8.3.5"
"@storybook/addon-storysource": "8.3.5"
"@storybook/addon-themes": "8.3.5"
"@storybook/blocks": "8.3.5"
"@storybook/nextjs": "8.3.5"
"@storybook/react": "8.3.5"
"@storybook/test": "8.3.5"
"@chromatic-com/storybook": "2.0.1"
"@storybook/addon-a11y": "8.3.0"
"@storybook/addon-essentials": "8.3.0"
"@storybook/addon-interactions": "8.3.0"
"@storybook/addon-links": "8.3.0"
"@storybook/addon-storysource": "8.3.0"
"@storybook/addon-themes": "8.3.0"
"@storybook/blocks": "8.3.0"
"@storybook/nextjs": "8.3.0"
"@storybook/react": "8.3.0"
"@storybook/test": "8.3.0"
"@storybook/test-runner": "0.19.1"
"chromatic": "11.12.5"
"chromatic": "11.9.0"
"http-server": "14.1.1"
"storybook": "8.3.5"
"storybook": "8.3.0"
"storybook-dark-mode": "4.0.2"
# Testing
"playwright": "1.48.0"
"@playwright/test": "1.48.0"
"axe-playwright": "2.0.3"
"start-server-and-test": "2.0.8"
"@vitest/browser": "2.1.2"
"@vitest/coverage-istanbul": "2.1.2"
"@vitest/ui": "2.1.2"
"vitest": "2.1.2"
"playwright": "1.47.0"
"@playwright/test": "1.47.0"
"axe-playwright": "2.0.2"
"start-server-and-test": "2.0.7"
"@vitest/browser": "2.0.5"
"@vitest/coverage-istanbul": "2.0.5"
"@vitest/ui": "2.0.5"
"vitest": "2.0.5"
"@testing-library/react": "16.0.1"
# CSS
"postcss": "8.4.47"
"tailwindcss": "3.4.13"
"tailwind-merge": "2.5.3"
"postcss": "8.4.45"
"tailwindcss": "3.4.11"
"@tailwindcss/typography": "0.5.15"
"@fontsource/montserrat": "5.1.0"
"@fontsource/montserrat": "5.0.20"
"clsx": "2.1.0"
"cva": "1.0.0-beta.1"
"tailwind-merge": "2.5.2"

View File

@ -17,17 +17,11 @@
"dependsOn": ["^test"],
"outputs": ["coverage/**"]
},
"lint:eslint-transit-node": {
"dependsOn": ["^lint:eslint-transit-node"]
},
"lint:eslint": {
"dependsOn": ["lint:eslint-transit-node"]
},
"lint:typescript-transit-node": {
"dependsOn": ["^lint:typescript-transit-node"]
"dependsOn": ["^lint:eslint"]
},
"lint:typescript": {
"dependsOn": ["lint:typescript-transit-node"]
"dependsOn": ["^lint:typescript"]
},
"dev": {
"cache": false,