1
1
mirror of https://github.com/theoludwig/theoludwig.git synced 2025-10-11 17:06:21 +02:00

Compare commits

..

3 Commits
v4.4.2 ... main

Author SHA1 Message Date
338741d252 fix: update portfolio/Fusey.webp 2025-10-11 16:59:52 +02:00
be738a1c8d build(deps): update latest 2025-10-11 16:59:42 +02:00
9c20844d89 fix: update Curriculum Vitae 2025-09-23 10:15:03 +02:00
32 changed files with 1461 additions and 1541 deletions

View File

@@ -25,7 +25,7 @@ jobs:
- uses: "pnpm/action-setup@v4.1.0" - uses: "pnpm/action-setup@v4.1.0"
- name: "Setup Node.js" - name: "Setup Node.js"
uses: "actions/setup-node@v4.4.0" uses: "actions/setup-node@v5.0.0"
with: with:
node-version: "24.x" node-version: "24.x"
cache: "pnpm" cache: "pnpm"

View File

@@ -23,7 +23,7 @@ jobs:
- uses: "pnpm/action-setup@v4.1.0" - uses: "pnpm/action-setup@v4.1.0"
- name: "Setup Node.js" - name: "Setup Node.js"
uses: "actions/setup-node@v4.4.0" uses: "actions/setup-node@v5.0.0"
with: with:
node-version: "24.x" node-version: "24.x"
cache: "pnpm" cache: "pnpm"

View File

@@ -4,7 +4,6 @@
"prefix": "rfc", "prefix": "rfc",
"body": [ "body": [
"export interface ${1:ComponentName}Props {}", "export interface ${1:ComponentName}Props {}",
"",
"export const ${1:ComponentName}: React.FC<${1:ComponentName}Props> = () => {", "export const ${1:ComponentName}: React.FC<${1:ComponentName}Props> = () => {",
" return (", " return (",
" <div>", " <div>",

View File

@@ -28,7 +28,7 @@ The commit message guidelines adheres to [Conventional Commits](https://www.conv
### Prerequisites ### Prerequisites
- [Node.js](https://nodejs.org/) >= v24.0.0 [(`nvm install 24`)](https://nvm.sh) - [Node.js](https://nodejs.org/) >= v24.0.0 [(`nvm install 24`)](https://nvm.sh)
- [pnpm](https://pnpm.io/) v10.15.1 [(`npm install --global corepack@0.34.0 && corepack enable`)](https://github.com/nodejs/corepack) - [pnpm](https://pnpm.io/) v10.18.2 [(`npm install --global corepack@0.34.0 && corepack enable`)](https://github.com/nodejs/corepack)
- [Docker](https://www.docker.com/) - [Docker](https://www.docker.com/)
### Installation ### Installation

View File

@@ -1,7 +1,8 @@
import typescriptESLint from "typescript-eslint" import typescriptESLint from "typescript-eslint"
import { defineConfig } from "eslint/config"
import config from "@repo/config-eslint" import config from "@repo/config-eslint"
export default typescriptESLint.config(...config, { export default defineConfig(...config, {
files: ["**/*.ts", "**/*.tsx"], files: ["**/*.ts", "**/*.tsx"],
languageOptions: { languageOptions: {
parser: typescriptESLint.parser, parser: typescriptESLint.parser,

View File

@@ -1,4 +1,4 @@
FROM node:24.7.0-slim AS node-pnpm FROM node:24.10.0-slim AS node-pnpm
ENV PNPM_HOME="/pnpm" ENV PNPM_HOME="/pnpm"
ENV PATH="$PNPM_HOME:$PATH" ENV PATH="$PNPM_HOME:$PATH"
RUN npm install --global corepack@0.34.0 && corepack enable RUN npm install --global corepack@0.34.0 && corepack enable
@@ -9,7 +9,7 @@ WORKDIR /usr/src/app
FROM node-pnpm AS builder FROM node-pnpm AS builder
COPY ./ ./ COPY ./ ./
RUN pnpm install --global turbo@2.5.6 RUN pnpm install --global turbo@2.5.8
RUN turbo prune @repo/website --docker RUN turbo prune @repo/website --docker
FROM node-pnpm AS installer FROM node-pnpm AS installer
@@ -23,7 +23,7 @@ COPY --from=builder /usr/src/app/out/full/ ./
COPY turbo.json turbo.json COPY turbo.json turbo.json
ARG VERSION="0.0.0-develop" ARG VERSION="0.0.0-develop"
RUN pnpm install --global replace-in-files-cli@3.0.0 RUN pnpm install --global replace-in-files-cli@4.0.0
RUN VERSION_STRIPPED=${VERSION#v} && replace-in-files --regex='version": *"[^"]*' --replacement='"version": "'"$VERSION_STRIPPED"'"' '**/package.json' '!**/node_modules/**' RUN VERSION_STRIPPED=${VERSION#v} && replace-in-files --regex='version": *"[^"]*' --replacement='"version": "'"$VERSION_STRIPPED"'"' '**/package.json' '!**/node_modules/**'
RUN pnpm --filter=@repo/website... exec turbo run build RUN pnpm --filter=@repo/website... exec turbo run build

View File

@@ -1,7 +1,8 @@
import typescriptESLint from "typescript-eslint" import typescriptESLint from "typescript-eslint"
import { defineConfig } from "eslint/config"
import config from "@repo/config-eslint" import config from "@repo/config-eslint"
export default typescriptESLint.config(...config, { export default defineConfig(...config, {
files: ["**/*.ts", "**/*.tsx"], files: ["**/*.ts", "**/*.tsx"],
languageOptions: { languageOptions: {
parser: typescriptESLint.parser, parser: typescriptESLint.parser,

View File

@@ -11,7 +11,7 @@
"build": "next build --turbopack", "build": "next build --turbopack",
"start": "next start --port 3000", "start": "next start --port 3000",
"typegen": "next typegen", "typegen": "next typegen",
"lint:eslint": "eslint . --max-warnings 0", "lint:eslint": "eslint app --max-warnings 0",
"lint:typescript": "next typegen && tsc --noEmit" "lint:typescript": "next typegen && tsc --noEmit"
}, },
"dependencies": { "dependencies": {

Binary file not shown.

Before

Width:  |  Height:  |  Size: 945 KiB

After

Width:  |  Height:  |  Size: 1.2 MiB

View File

@@ -4,9 +4,6 @@
"lib": ["DOM", "DOM.Iterable", "ESNext"], "lib": ["DOM", "DOM.Iterable", "ESNext"],
"types": ["@total-typescript/ts-reset", "@repo/i18n/messages.d.ts"], "types": ["@total-typescript/ts-reset", "@repo/i18n/messages.d.ts"],
"allowJs": true, "allowJs": true,
"paths": {
"#*": ["./*"]
},
"plugins": [ "plugins": [
{ {
"name": "next" "name": "next"

View File

@@ -2,42 +2,32 @@ import nextPlugin from "@next/eslint-plugin-next"
import configConventions from "eslint-config-conventions" import configConventions from "eslint-config-conventions"
import importXPlugin from "eslint-plugin-import-x" import importXPlugin from "eslint-plugin-import-x"
import reactPlugin from "eslint-plugin-react" import reactPlugin from "eslint-plugin-react"
import reactHooksPlugin from "eslint-plugin-react-hooks" import reactHooks from "eslint-plugin-react-hooks"
import typescriptESLint from "typescript-eslint" import { defineConfig, globalIgnores } from "eslint/config"
export default typescriptESLint.config( export default defineConfig(
...configConventions, ...configConventions,
reactHooksPlugin.configs.recommended,
reactPlugin.configs.flat.recommended, reactPlugin.configs.flat.recommended,
{ globalIgnores(["**/kysely.config.ts"]),
ignores: [
".next",
"**/next.config.ts",
"**/eslint.config.js",
"**/tailwind.config.js",
"**/postcss.config.js",
"**/kysely.config.ts",
],
},
{ {
name: "config-eslint", name: "config-eslint",
settings: { settings: {
react: { react: {
version: "19.1.1", version: "19.2.0",
}, },
}, },
plugins: { plugins: {
"@next/next": nextPlugin, "@next/next": nextPlugin,
"import-x": importXPlugin, "import-x": importXPlugin,
"react-hooks": reactHooks,
}, },
rules: { rules: {
...nextPlugin.configs.recommended.rules, ...nextPlugin.configs.recommended.rules,
...nextPlugin.configs["core-web-vitals"].rules, ...nextPlugin.configs["core-web-vitals"].rules,
...reactHooks.configs.recommended.rules,
"@next/next/no-html-link-for-pages": "off", "@next/next/no-html-link-for-pages": "off",
"@next/next/no-img-element": "off", "@next/next/no-img-element": "off",
"react-hooks/react-compiler": "error",
"react/jsx-no-target-blank": "off", "react/jsx-no-target-blank": "off",
"react/no-unknown-property": "off", "react/no-unknown-property": "off",
"react/react-in-jsx-scope": "off", "react/react-in-jsx-scope": "off",

View File

@@ -1,7 +1,5 @@
import type typescriptESLint from "typescript-eslint" import type { defineConfig } from "eslint/config"
declare const eslintConfigConventions: ReturnType< declare const eslintConfig: ReturnType<typeof defineConfig>
typeof typescriptESLint.config
>
export default eslintConfigConventions export default eslintConfig

View File

@@ -1,7 +1,8 @@
import typescriptESLint from "typescript-eslint" import typescriptESLint from "typescript-eslint"
import { defineConfig } from "eslint/config"
import config from "@repo/config-eslint" import config from "@repo/config-eslint"
export default typescriptESLint.config(...config, { export default defineConfig(...config, {
files: ["**/*.ts", "**/*.tsx"], files: ["**/*.ts", "**/*.tsx"],
languageOptions: { languageOptions: {
parser: typescriptESLint.parser, parser: typescriptESLint.parser,

View File

@@ -254,8 +254,8 @@ code .line::before {
padding: 10px 0; padding: 10px 0;
} }
.profile-pic img { .profile-pic img {
width: 80px; width: 100px;
height: 80px; height: 100px;
border-radius: 50%; border-radius: 50%;
vertical-align: middle; vertical-align: middle;
border: 0; border: 0;

View File

@@ -17,6 +17,7 @@
"isolatedModules": true, "isolatedModules": true,
"esModuleInterop": true, "esModuleInterop": true,
"allowImportingTsExtensions": true, "allowImportingTsExtensions": true,
"allowArbitraryExtensions": true,
"skipLibCheck": true, "skipLibCheck": true,
"jsx": "preserve", "jsx": "preserve",
"incremental": false, "incremental": false,

View File

@@ -3,7 +3,7 @@
"version": "0.0.0-develop", "version": "0.0.0-develop",
"private": true, "private": true,
"type": "module", "type": "module",
"packageManager": "pnpm@10.15.1+sha512.34e538c329b5553014ca8e8f4535997f96180a1d0f614339357449935350d924e22f8614682191264ec33d1462ac21561aff97f6bb18065351c162c7e8f6de67", "packageManager": "pnpm@10.18.2+sha512.9fb969fa749b3ade6035e0f109f0b8a60b5d08a1a87fdf72e337da90dcc93336e2280ca4e44f2358a649b83c17959e9993e777c2080879f3801e6f0d999ad3dd",
"engines": { "engines": {
"node": ">=24.0.0" "node": ">=24.0.0"
}, },

View File

@@ -1,7 +1,8 @@
import typescriptESLint from "typescript-eslint" import typescriptESLint from "typescript-eslint"
import { defineConfig } from "eslint/config"
import config from "@repo/config-eslint" import config from "@repo/config-eslint"
export default typescriptESLint.config(...config, { export default defineConfig(...config, {
files: ["**/*.ts", "**/*.tsx"], files: ["**/*.ts", "**/*.tsx"],
languageOptions: { languageOptions: {
parser: typescriptESLint.parser, parser: typescriptESLint.parser,

View File

@@ -17,7 +17,6 @@
"@repo/utils": "workspace:*", "@repo/utils": "workspace:*",
"@repo/i18n": "workspace:*", "@repo/i18n": "workspace:*",
"@repo/ui": "workspace:*", "@repo/ui": "workspace:*",
"@repo/react-hooks": "workspace:*",
"@giscus/react": "catalog:", "@giscus/react": "catalog:",
"@shikijs/rehype": "catalog:", "@shikijs/rehype": "catalog:",
"@mdx-js/mdx": "catalog:", "@mdx-js/mdx": "catalog:",

View File

@@ -1,7 +1,8 @@
import typescriptESLint from "typescript-eslint" import typescriptESLint from "typescript-eslint"
import { defineConfig } from "eslint/config"
import config from "@repo/config-eslint" import config from "@repo/config-eslint"
export default typescriptESLint.config(...config, { export default defineConfig(...config, {
files: ["**/*.ts", "**/*.tsx"], files: ["**/*.ts", "**/*.tsx"],
languageOptions: { languageOptions: {
parser: typescriptESLint.parser, parser: typescriptESLint.parser,

View File

@@ -1,13 +0,0 @@
import typescriptESLint from "typescript-eslint"
import config from "@repo/config-eslint"
export default typescriptESLint.config(...config, {
files: ["**/*.ts", "**/*.tsx"],
languageOptions: {
parser: typescriptESLint.parser,
parserOptions: {
projectService: true,
tsconfigRootDir: import.meta.dirname,
},
},
})

View File

@@ -1,29 +0,0 @@
{
"name": "@repo/react-hooks",
"version": "0.0.0-develop",
"private": true,
"type": "module",
"exports": {
"./useBoolean": "./src/useBoolean.ts",
"./useIsMounted": "./src/useIsMounted.ts"
},
"scripts": {
"lint:eslint": "eslint src --max-warnings 0",
"lint:typescript": "tsc --noEmit"
},
"dependencies": {
"react": "catalog:",
"react-dom": "catalog:"
},
"devDependencies": {
"@repo/config-eslint": "workspace:*",
"@repo/config-typescript": "workspace:*",
"@types/react": "catalog:",
"@types/react-dom": "catalog:",
"@total-typescript/ts-reset": "catalog:",
"eslint": "catalog:",
"playwright": "catalog:",
"typescript": "catalog:",
"typescript-eslint": "catalog:"
}
}

View File

@@ -1,15 +0,0 @@
import { useEffect, useState } from "react"
export interface UseIsMountedOutput {
isMounted: boolean
}
export const useIsMounted = (): UseIsMountedOutput => {
const [isMounted, setIsMounted] = useState(false)
useEffect(() => {
setIsMounted(true)
}, [])
return { isMounted }
}

View File

@@ -1,7 +0,0 @@
{
"extends": "@repo/config-typescript/tsconfig.json",
"compilerOptions": {
"lib": ["DOM", "DOM.Iterable", "ESNext"],
"types": ["@total-typescript/ts-reset"]
}
}

View File

@@ -1,7 +1,8 @@
import typescriptESLint from "typescript-eslint" import typescriptESLint from "typescript-eslint"
import { defineConfig } from "eslint/config"
import config from "@repo/config-eslint" import config from "@repo/config-eslint"
export default typescriptESLint.config(...config, { export default defineConfig(...config, {
files: ["**/*.ts", "**/*.tsx"], files: ["**/*.ts", "**/*.tsx"],
languageOptions: { languageOptions: {
parser: typescriptESLint.parser, parser: typescriptESLint.parser,

View File

@@ -30,7 +30,6 @@
"@repo/config-tailwind": "workspace:*", "@repo/config-tailwind": "workspace:*",
"@repo/utils": "workspace:*", "@repo/utils": "workspace:*",
"@repo/i18n": "workspace:*", "@repo/i18n": "workspace:*",
"@repo/react-hooks": "workspace:*",
"cva": "catalog:", "cva": "catalog:",
"next": "catalog:", "next": "catalog:",
"next-intl": "catalog:", "next-intl": "catalog:",

View File

@@ -21,9 +21,9 @@ export const CurriculumVitaeProfile: React.FC<
<Image <Image
className="mx-auto block" className="mx-auto block"
alt={t("meta.title")} alt={t("meta.title")}
src="/images/logo_background.webp" src="/images/logo.webp"
width={400} width={450}
height={400} height={450}
/> />
</div> </div>
<div className="name-and-profession text-center"> <div className="name-and-profession text-center">

View File

@@ -6,9 +6,9 @@ import { LOCALES } from "@repo/utils/constants"
import { useLocale } from "next-intl" import { useLocale } from "next-intl"
import { useEffect, useRef } from "react" import { useEffect, useRef } from "react"
import { useBoolean } from "@repo/react-hooks/useBoolean"
import { Arrow } from "./Arrow.tsx" import { Arrow } from "./Arrow.tsx"
import { LocaleFlag } from "./LocaleFlag.tsx" import { LocaleFlag } from "./LocaleFlag.tsx"
import { useBoolean } from "../../../hooks/useBoolean.ts"
export interface LocalesProps {} export interface LocalesProps {}

View File

@@ -1,13 +1,13 @@
"use client" "use client"
import { classNames } from "@repo/config-tailwind/classNames" import { classNames } from "@repo/config-tailwind/classNames"
import { useIsMounted } from "@repo/react-hooks/useIsMounted"
import type { Theme } from "@repo/utils/constants" import type { Theme } from "@repo/utils/constants"
import { THEME_DEFAULT } from "@repo/utils/constants" import { THEME_DEFAULT } from "@repo/utils/constants"
import { import {
ThemeProvider as NextThemeProvider, ThemeProvider as NextThemeProvider,
useTheme as useNextTheme, useTheme as useNextTheme,
} from "next-themes" } from "next-themes"
import { useEffect, useState } from "react"
export interface ThemeProviderProps extends React.PropsWithChildren { export interface ThemeProviderProps extends React.PropsWithChildren {
forcedTheme?: Theme forcedTheme?: Theme
@@ -35,7 +35,12 @@ export interface UseThemeOutput {
export const useTheme = (): UseThemeOutput => { export const useTheme = (): UseThemeOutput => {
const { setTheme, theme: themeData } = useNextTheme() const { setTheme, theme: themeData } = useNextTheme()
const { isMounted } = useIsMounted() const [isMounted, setIsMounted] = useState(false)
useEffect(() => {
// eslint-disable-next-line react-hooks/set-state-in-effect
setIsMounted(true)
}, [])
const theme = isMounted ? (themeData as Theme) : THEME_DEFAULT const theme = isMounted ? (themeData as Theme) : THEME_DEFAULT

View File

@@ -1,7 +1,8 @@
import typescriptESLint from "typescript-eslint" import typescriptESLint from "typescript-eslint"
import { defineConfig } from "eslint/config"
import config from "@repo/config-eslint" import config from "@repo/config-eslint"
export default typescriptESLint.config(...config, { export default defineConfig(...config, {
files: ["**/*.ts", "**/*.tsx"], files: ["**/*.ts", "**/*.tsx"],
languageOptions: { languageOptions: {
parser: typescriptESLint.parser, parser: typescriptESLint.parser,

2793
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@@ -7,30 +7,30 @@ catalogMode: "strict"
catalog: catalog:
# Turborepo # Turborepo
"turbo": "2.5.6" "turbo": "2.5.8"
# TypeScript # TypeScript
"typescript": "5.9.2" "typescript": "5.9.3"
"@total-typescript/ts-reset": "0.6.1" "@total-typescript/ts-reset": "0.6.1"
"@types/node": "24.3.1" "@types/node": "24.7.2"
# Utils # Utils
"mime": "4.0.7" "mime": "4.1.0"
# React.js/Next.js # React.js/Next.js
"next": &next "15.5.2" "next": &next "15.5.4"
"next-intl": "4.3.7" "next-intl": "4.3.12"
"next-themes": "0.4.6" "next-themes": "0.4.6"
"react": "19.1.1" "react": "19.2.0"
"react-dom": "19.1.1" "react-dom": "19.2.0"
"@types/react": "19.1.12" "@types/react": "19.2.2"
"@types/react-dom": "19.1.9" "@types/react-dom": "19.2.1"
"react-icons": "5.5.0" "react-icons": "5.5.0"
# Blog # Blog
"@giscus/react": "3.1.0" "@giscus/react": "3.1.0"
"gray-matter": "4.0.3" "gray-matter": "4.0.3"
"katex": "0.16.22" "katex": "0.16.23"
"next-mdx-remote": "5.0.0" "next-mdx-remote": "5.0.0"
"@mdx-js/mdx": "3.1.1" "@mdx-js/mdx": "3.1.1"
"rehype-katex": "7.0.1" "rehype-katex": "7.0.1"
@@ -47,16 +47,16 @@ catalog:
"markdownlint-rule-relative-links": "4.2.0" "markdownlint-rule-relative-links": "4.2.0"
# ESLint # ESLint
"globals": "16.3.0" "globals": "16.4.0"
"typescript-eslint": "8.43.0" "typescript-eslint": "8.46.0"
"eslint": "9.35.0" "eslint": "9.37.0"
"eslint-config-conventions": "20.2.0" "eslint-config-conventions": "21.0.3"
"eslint-plugin-promise": "7.2.1" "eslint-plugin-promise": "7.2.1"
"eslint-plugin-unicorn": "61.0.2" "eslint-plugin-unicorn": "61.0.2"
"eslint-plugin-import-x": "4.16.1" "eslint-plugin-import-x": "4.16.1"
"@next/eslint-plugin-next": *next "@next/eslint-plugin-next": *next
"eslint-plugin-react": "7.37.5" "eslint-plugin-react": "7.37.5"
"eslint-plugin-react-hooks": "6.0.0-rc.1" "eslint-plugin-react-hooks": "7.0.0"
# Prettier # Prettier
"prettier": "3.6.2" "prettier": "3.6.2"
@@ -64,29 +64,29 @@ catalog:
"editorconfig-checker": "6.1.0" "editorconfig-checker": "6.1.0"
# Storybook # Storybook
"storybook": &storybook "9.1.5" "storybook": &storybook "9.1.10"
"@storybook/addon-docs": *storybook "@storybook/addon-docs": *storybook
"@storybook/addon-a11y": *storybook "@storybook/addon-a11y": *storybook
"@storybook/nextjs": *storybook "@storybook/nextjs": *storybook
"@storybook/addon-themes": *storybook "@storybook/addon-themes": *storybook
"@storybook/test-runner": "0.23.0" "@storybook/test-runner": "0.23.0"
"@chromatic-com/storybook": "4.1.1" "@chromatic-com/storybook": "4.1.1"
"chromatic": "13.1.4" "chromatic": "13.3.0"
# Testing # Testing
"playwright": &playwright "1.55.0" "playwright": &playwright "1.56.0"
"@playwright/test": *playwright "@playwright/test": *playwright
"start-server-and-test": "2.1.0" "start-server-and-test": "2.1.2"
# CSS # CSS
"postcss": "8.5.6" "postcss": "8.5.6"
"@tailwindcss/postcss": "4.1.13" "@tailwindcss/postcss": "4.1.14"
"@tailwindcss/typography": "0.5.16" "@tailwindcss/typography": "0.5.19"
"tailwindcss": "4.1.13" "tailwindcss": "4.1.14"
"tailwind-merge": "3.3.1" "tailwind-merge": "3.3.1"
"clsx": "2.1.1" "clsx": "2.1.1"
"cva": "1.0.0-beta.4" "cva": "1.0.0-beta.4"
"@fontsource/montserrat": "5.2.7" "@fontsource/montserrat": "5.2.8"
onlyBuiltDependencies: onlyBuiltDependencies:
- "@swc/core" - "@swc/core"