diff --git a/.gitignore b/.gitignore index 5ef6a52..cdd314c 100644 --- a/.gitignore +++ b/.gitignore @@ -30,6 +30,9 @@ yarn-debug.log* yarn-error.log* .pnpm-debug.log* +# local editor settings (can contain private deployment config) +.vscode/ + # env files (can opt-in for committing if needed) .env* diff --git a/README.md b/README.md index e215bc4..f875504 100644 --- a/README.md +++ b/README.md @@ -1,36 +1,99 @@ -This is a [Next.js](https://nextjs.org) project bootstrapped with [`create-next-app`](https://nextjs.org/docs/app/api-reference/cli/create-next-app). +# Hub ArthurP -## Getting Started +Hub centralisant les projets et outils d'ArthurP. -First, run the development server: +Le site regroupe des applications web (productivite, utilitaires, education, etc.) avec une page detaillee pour chaque projet, des pages legales, et les elements SEO (robots, sitemap, donnees structurees). + +## Site en production + +- URL officielle: https://arthurp.fr + +## Stack technique + +- Next.js 16 (App Router) +- React 19 +- TypeScript +- Tailwind CSS 4 +- ESLint + +## Fonctionnalites principales + +- Page d'accueil avec presentation des projets +- Pages dediees par projet dans `src/app/projets/*` +- Pages legales dans `src/app/legal/*` +- SEO technique avec `public/robots.txt` et `src/app/sitemap.ts` +- Donnees structurees JSON-LD via composant reutilisable + +## Installation locale + +Pre-requis: + +- Node.js 20+ +- npm + +Installation: + +```bash +npm install +``` + +## Lancer le projet + +Developpement: ```bash npm run dev -# or -yarn dev -# or -pnpm dev -# or -bun dev ``` -Open [http://localhost:3000](http://localhost:3000) with your browser to see the result. +Build de production: -You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file. +```bash +npm run build +``` -This project uses [`next/font`](https://nextjs.org/docs/app/building-your-application/optimizing/fonts) to automatically optimize and load [Geist](https://vercel.com/font), a new font family for Vercel. +Lancer le build en local: -## Learn More +```bash +npm run start +``` -To learn more about Next.js, take a look at the following resources: +Lint: -- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API. -- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial. +```bash +npm run lint +``` -You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js) - your feedback and contributions are welcome! +## Scripts npm -## Deploy on Vercel +- `dev`: demarre le serveur Next.js en mode developpement +- `build`: genere le build de production +- `start`: demarre le serveur sur le build genere +- `lint`: verifie la qualite du code avec ESLint -The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js. +## Structure du projet -Check out our [Next.js deployment documentation](https://nextjs.org/docs/app/building-your-application/deploying) for more details. +```text +src/ + app/ + page.tsx + layout.tsx + globals.css + legal/ + projets/ + sitemap.ts + components/ +public/ + robots.txt +``` + +## Publication GitHub + +Points importants avant push: + +- Ne jamais versionner de secrets ou credentials +- Verifier que les fichiers d'environnement restent ignores (`.env*`) +- Verifier que les configurations locales editeur/deploiement restent ignorees (`.vscode/`) + +## License + +Projet prive - tous droits reserves sauf mention contraire. diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..c042f06 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,10 @@ +services: + web: + image: node:20-alpine + working_dir: /app + volumes: + - ./:/app + ports: + - "3004:3000" + command: sh -c "npm install && npm run build && npm start" + restart: unless-stopped \ No newline at end of file diff --git a/jsconfig.json b/jsconfig.json new file mode 100644 index 0000000..1f6603c --- /dev/null +++ b/jsconfig.json @@ -0,0 +1,8 @@ +{ + "compilerOptions": { + "baseUrl": ".", + "paths": { + "@/components/*": ["src/components/*"] + } + } +} diff --git a/package-lock.json b/package-lock.json index 792a424..f187f3c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,7 +8,7 @@ "name": "hub", "version": "0.1.0", "dependencies": { - "next": "16.1.6", + "next": "^16.2.1", "react": "19.2.3", "react-dom": "19.2.3" }, @@ -18,7 +18,7 @@ "@types/react": "^19", "@types/react-dom": "^19", "eslint": "^9", - "eslint-config-next": "16.1.6", + "eslint-config-next": "^16.2.1", "tailwindcss": "^4", "typescript": "^5" } @@ -1036,15 +1036,15 @@ } }, "node_modules/@next/env": { - "version": "16.1.6", - "resolved": "https://registry.npmjs.org/@next/env/-/env-16.1.6.tgz", - "integrity": "sha512-N1ySLuZjnAtN3kFnwhAwPvZah8RJxKasD7x1f8shFqhncnWZn4JMfg37diLNuoHsLAlrDfM3g4mawVdtAG8XLQ==", + "version": "16.2.1", + "resolved": "https://registry.npmjs.org/@next/env/-/env-16.2.1.tgz", + "integrity": "sha512-n8P/HCkIWW+gVal2Z8XqXJ6aB3J0tuM29OcHpCsobWlChH/SITBs1DFBk/HajgrwDkqqBXPbuUuzgDvUekREPg==", "license": "MIT" }, "node_modules/@next/eslint-plugin-next": { - "version": "16.1.6", - "resolved": "https://registry.npmjs.org/@next/eslint-plugin-next/-/eslint-plugin-next-16.1.6.tgz", - "integrity": "sha512-/Qq3PTagA6+nYVfryAtQ7/9FEr/6YVyvOtl6rZnGsbReGLf0jZU6gkpr1FuChAQpvV46a78p4cmHOVP8mbfSMQ==", + "version": "16.2.1", + "resolved": "https://registry.npmjs.org/@next/eslint-plugin-next/-/eslint-plugin-next-16.2.1.tgz", + "integrity": "sha512-r0epZGo24eT4g08jJlg2OEryBphXqO8aL18oajoTKLzHJ6jVr6P6FI58DLMug04MwD3j8Fj0YK0slyzneKVyzA==", "dev": true, "license": "MIT", "dependencies": { @@ -1052,9 +1052,9 @@ } }, "node_modules/@next/swc-darwin-arm64": { - "version": "16.1.6", - "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-16.1.6.tgz", - "integrity": "sha512-wTzYulosJr/6nFnqGW7FrG3jfUUlEf8UjGA0/pyypJl42ExdVgC6xJgcXQ+V8QFn6niSG2Pb8+MIG1mZr2vczw==", + "version": "16.2.1", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-16.2.1.tgz", + "integrity": "sha512-BwZ8w8YTaSEr2HIuXLMLxIdElNMPvY9fLqb20LX9A9OMGtJilhHLbCL3ggyd0TwjmMcTxi0XXt+ur1vWUoxj2Q==", "cpu": [ "arm64" ], @@ -1068,9 +1068,9 @@ } }, "node_modules/@next/swc-darwin-x64": { - "version": "16.1.6", - "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-16.1.6.tgz", - "integrity": "sha512-BLFPYPDO+MNJsiDWbeVzqvYd4NyuRrEYVB5k2N3JfWncuHAy2IVwMAOlVQDFjj+krkWzhY2apvmekMkfQR0CUQ==", + "version": "16.2.1", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-16.2.1.tgz", + "integrity": "sha512-/vrcE6iQSJq3uL3VGVHiXeaKbn8Es10DGTGRJnRZlkNQQk3kaNtAJg8Y6xuAlrx/6INKVjkfi5rY0iEXorZ6uA==", "cpu": [ "x64" ], @@ -1084,9 +1084,9 @@ } }, "node_modules/@next/swc-linux-arm64-gnu": { - "version": "16.1.6", - "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-16.1.6.tgz", - "integrity": "sha512-OJYkCd5pj/QloBvoEcJ2XiMnlJkRv9idWA/j0ugSuA34gMT6f5b7vOiCQHVRpvStoZUknhl6/UxOXL4OwtdaBw==", + "version": "16.2.1", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-16.2.1.tgz", + "integrity": "sha512-uLn+0BK+C31LTVbQ/QU+UaVrV0rRSJQ8RfniQAHPghDdgE+SlroYqcmFnO5iNjNfVWCyKZHYrs3Nl0mUzWxbBw==", "cpu": [ "arm64" ], @@ -1100,9 +1100,9 @@ } }, "node_modules/@next/swc-linux-arm64-musl": { - "version": "16.1.6", - "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-16.1.6.tgz", - "integrity": "sha512-S4J2v+8tT3NIO9u2q+S0G5KdvNDjXfAv06OhfOzNDaBn5rw84DGXWndOEB7d5/x852A20sW1M56vhC/tRVbccQ==", + "version": "16.2.1", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-16.2.1.tgz", + "integrity": "sha512-ssKq6iMRnHdnycGp9hCuGnXJZ0YPr4/wNwrfE5DbmvEcgl9+yv97/Kq3TPVDfYome1SW5geciLB9aiEqKXQjlQ==", "cpu": [ "arm64" ], @@ -1116,9 +1116,9 @@ } }, "node_modules/@next/swc-linux-x64-gnu": { - "version": "16.1.6", - "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-16.1.6.tgz", - "integrity": "sha512-2eEBDkFlMMNQnkTyPBhQOAyn2qMxyG2eE7GPH2WIDGEpEILcBPI/jdSv4t6xupSP+ot/jkfrCShLAa7+ZUPcJQ==", + "version": "16.2.1", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-16.2.1.tgz", + "integrity": "sha512-HQm7SrHRELJ30T1TSmT706IWovFFSRGxfgUkyWJZF/RKBMdbdRWJuFrcpDdE5vy9UXjFOx6L3mRdqH04Mmx0hg==", "cpu": [ "x64" ], @@ -1132,9 +1132,9 @@ } }, "node_modules/@next/swc-linux-x64-musl": { - "version": "16.1.6", - "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-16.1.6.tgz", - "integrity": "sha512-oicJwRlyOoZXVlxmIMaTq7f8pN9QNbdes0q2FXfRsPhfCi8n8JmOZJm5oo1pwDaFbnnD421rVU409M3evFbIqg==", + "version": "16.2.1", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-16.2.1.tgz", + "integrity": "sha512-aV2iUaC/5HGEpbBkE+4B8aHIudoOy5DYekAKOMSHoIYQ66y/wIVeaRx8MS2ZMdxe/HIXlMho4ubdZs/J8441Tg==", "cpu": [ "x64" ], @@ -1148,9 +1148,9 @@ } }, "node_modules/@next/swc-win32-arm64-msvc": { - "version": "16.1.6", - "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-16.1.6.tgz", - "integrity": "sha512-gQmm8izDTPgs+DCWH22kcDmuUp7NyiJgEl18bcr8irXA5N2m2O+JQIr6f3ct42GOs9c0h8QF3L5SzIxcYAAXXw==", + "version": "16.2.1", + "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-16.2.1.tgz", + "integrity": "sha512-IXdNgiDHaSk0ZUJ+xp0OQTdTgnpx1RCfRTalhn3cjOP+IddTMINwA7DXZrwTmGDO8SUr5q2hdP/du4DcrB1GxA==", "cpu": [ "arm64" ], @@ -1164,9 +1164,9 @@ } }, "node_modules/@next/swc-win32-x64-msvc": { - "version": "16.1.6", - "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-16.1.6.tgz", - "integrity": "sha512-NRfO39AIrzBnixKbjuo2YiYhB6o9d8v/ymU9m/Xk8cyVk+k7XylniXkHwjs4s70wedVffc6bQNbufk5v0xEm0A==", + "version": "16.2.1", + "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-16.2.1.tgz", + "integrity": "sha512-qvU+3a39Hay+ieIztkGSbF7+mccbbg1Tk25hc4JDylf8IHjYmY/Zm64Qq1602yPyQqvie+vf5T/uPwNxDNIoeg==", "cpu": [ "x64" ], @@ -1767,9 +1767,9 @@ } }, "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", - "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.3.tgz", + "integrity": "sha512-MCV/fYJEbqx68aE58kv2cA/kiky1G8vux3OR6/jbS+jIMe/6fJWa0DTzJU7dqijOWYwHi1t29FlfYI9uytqlpA==", "dev": true, "license": "MIT", "dependencies": { @@ -1777,13 +1777,13 @@ } }, "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "version": "9.0.9", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz", + "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==", "dev": true, "license": "ISC", "dependencies": { - "brace-expansion": "^2.0.1" + "brace-expansion": "^2.0.2" }, "engines": { "node": ">=16 || 14 >=14.17" @@ -2141,9 +2141,9 @@ } }, "node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "version": "6.14.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.14.0.tgz", + "integrity": "sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw==", "dev": true, "license": "MIT", "dependencies": { @@ -2420,9 +2420,9 @@ } }, "node_modules/brace-expansion": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", - "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.13.tgz", + "integrity": "sha512-9ZLprWS6EENmhEOpjCYW2c8VkmOvckIJZfkr7rBW6dObmfgJ/L1GpSYW5Hpo9lDz4D1+n0Ckz8rU7FwHDQiG/w==", "dev": true, "license": "MIT", "dependencies": { @@ -3087,13 +3087,13 @@ } }, "node_modules/eslint-config-next": { - "version": "16.1.6", - "resolved": "https://registry.npmjs.org/eslint-config-next/-/eslint-config-next-16.1.6.tgz", - "integrity": "sha512-vKq40io2B0XtkkNDYyleATwblNt8xuh3FWp8SpSz3pt7P01OkBFlKsJZ2mWt5WsCySlDQLckb1zMY9yE9Qy0LA==", + "version": "16.2.1", + "resolved": "https://registry.npmjs.org/eslint-config-next/-/eslint-config-next-16.2.1.tgz", + "integrity": "sha512-qhabwjQZ1Mk53XzXvmogf8KQ0tG0CQXF0CZ56+2/lVhmObgmaqj7x5A1DSrWdZd3kwI7GTPGUjFne+krRxYmFg==", "dev": true, "license": "MIT", "dependencies": { - "@next/eslint-plugin-next": "16.1.6", + "@next/eslint-plugin-next": "16.2.1", "eslint-import-resolver-node": "^0.3.6", "eslint-import-resolver-typescript": "^3.5.2", "eslint-plugin-import": "^2.32.0", @@ -3217,6 +3217,7 @@ "integrity": "sha512-whOE1HFo/qJDyX4SnXzP4N6zOWn79WhnCUY/iDR0mPfQZO8wcYE4JClzI2oZrhBnnMUCBCHZhO6VQyoBU95mZA==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@rtsao/scc": "^1.1.0", "array-includes": "^3.1.9", @@ -3569,9 +3570,9 @@ } }, "node_modules/flatted": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz", - "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==", + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.4.2.tgz", + "integrity": "sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==", "dev": true, "license": "ISC" }, @@ -4884,9 +4885,9 @@ } }, "node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", "dev": true, "license": "ISC", "dependencies": { @@ -4955,14 +4956,14 @@ "license": "MIT" }, "node_modules/next": { - "version": "16.1.6", - "resolved": "https://registry.npmjs.org/next/-/next-16.1.6.tgz", - "integrity": "sha512-hkyRkcu5x/41KoqnROkfTm2pZVbKxvbZRuNvKXLRXxs3VfyO0WhY50TQS40EuKO9SW3rBj/sF3WbVwDACeMZyw==", + "version": "16.2.1", + "resolved": "https://registry.npmjs.org/next/-/next-16.2.1.tgz", + "integrity": "sha512-VaChzNL7o9rbfdt60HUj8tev4m6d7iC1igAy157526+cJlXOQu5LzsBXNT+xaJnTP/k+utSX5vMv7m0G+zKH+Q==", "license": "MIT", "dependencies": { - "@next/env": "16.1.6", + "@next/env": "16.2.1", "@swc/helpers": "0.5.15", - "baseline-browser-mapping": "^2.8.3", + "baseline-browser-mapping": "^2.9.19", "caniuse-lite": "^1.0.30001579", "postcss": "8.4.31", "styled-jsx": "5.1.6" @@ -4974,15 +4975,15 @@ "node": ">=20.9.0" }, "optionalDependencies": { - "@next/swc-darwin-arm64": "16.1.6", - "@next/swc-darwin-x64": "16.1.6", - "@next/swc-linux-arm64-gnu": "16.1.6", - "@next/swc-linux-arm64-musl": "16.1.6", - "@next/swc-linux-x64-gnu": "16.1.6", - "@next/swc-linux-x64-musl": "16.1.6", - "@next/swc-win32-arm64-msvc": "16.1.6", - "@next/swc-win32-x64-msvc": "16.1.6", - "sharp": "^0.34.4" + "@next/swc-darwin-arm64": "16.2.1", + "@next/swc-darwin-x64": "16.2.1", + "@next/swc-linux-arm64-gnu": "16.2.1", + "@next/swc-linux-arm64-musl": "16.2.1", + "@next/swc-linux-x64-gnu": "16.2.1", + "@next/swc-linux-x64-musl": "16.2.1", + "@next/swc-win32-arm64-msvc": "16.2.1", + "@next/swc-win32-x64-msvc": "16.2.1", + "sharp": "^0.34.5" }, "peerDependencies": { "@opentelemetry/api": "^1.1.0", @@ -5280,9 +5281,9 @@ "license": "ISC" }, "node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz", + "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==", "dev": true, "license": "MIT", "engines": { @@ -6083,9 +6084,9 @@ } }, "node_modules/tinyglobby/node_modules/picomatch": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", - "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", + "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", "dev": true, "license": "MIT", "peer": true, diff --git a/package.json b/package.json index 410194d..4b637f3 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,7 @@ "lint": "eslint" }, "dependencies": { - "next": "16.1.6", + "next": "^16.2.1", "react": "19.2.3", "react-dom": "19.2.3" }, @@ -19,7 +19,7 @@ "@types/react": "^19", "@types/react-dom": "^19", "eslint": "^9", - "eslint-config-next": "16.1.6", + "eslint-config-next": "^16.2.1", "tailwindcss": "^4", "typescript": "^5" } diff --git a/public/favicon.ico b/public/favicon.ico new file mode 100644 index 0000000..ca20015 Binary files /dev/null and b/public/favicon.ico differ diff --git a/public/file.svg b/public/file.svg deleted file mode 100644 index 004145c..0000000 --- a/public/file.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/public/globe.svg b/public/globe.svg deleted file mode 100644 index 567f17b..0000000 --- a/public/globe.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/public/next.svg b/public/next.svg deleted file mode 100644 index 5174b28..0000000 --- a/public/next.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/public/placeholder-blocnote-2.webp b/public/placeholder-blocnote-2.webp new file mode 100644 index 0000000..0fafc56 Binary files /dev/null and b/public/placeholder-blocnote-2.webp differ diff --git a/public/placeholder-blocnote-3.webp b/public/placeholder-blocnote-3.webp new file mode 100644 index 0000000..2eaf796 Binary files /dev/null and b/public/placeholder-blocnote-3.webp differ diff --git a/public/placeholder-blocnote.webp b/public/placeholder-blocnote.webp new file mode 100644 index 0000000..0fafc56 Binary files /dev/null and b/public/placeholder-blocnote.webp differ diff --git a/public/placeholder-calculatrice-2.webp b/public/placeholder-calculatrice-2.webp new file mode 100644 index 0000000..f6e74d1 Binary files /dev/null and b/public/placeholder-calculatrice-2.webp differ diff --git a/public/placeholder-calculatrice-3.webp b/public/placeholder-calculatrice-3.webp new file mode 100644 index 0000000..68ff2c1 Binary files /dev/null and b/public/placeholder-calculatrice-3.webp differ diff --git a/public/placeholder-calculatrice.webp b/public/placeholder-calculatrice.webp new file mode 100644 index 0000000..b0f0be8 Binary files /dev/null and b/public/placeholder-calculatrice.webp differ diff --git a/public/placeholder-chrono-2.webp b/public/placeholder-chrono-2.webp new file mode 100644 index 0000000..87c1f45 Binary files /dev/null and b/public/placeholder-chrono-2.webp differ diff --git a/public/placeholder-chrono-3.webp b/public/placeholder-chrono-3.webp new file mode 100644 index 0000000..84b09e7 Binary files /dev/null and b/public/placeholder-chrono-3.webp differ diff --git a/public/placeholder-chrono.webp b/public/placeholder-chrono.webp new file mode 100644 index 0000000..a8382d7 Binary files /dev/null and b/public/placeholder-chrono.webp differ diff --git a/public/placeholder-clock-2.webp b/public/placeholder-clock-2.webp new file mode 100644 index 0000000..2b5969f Binary files /dev/null and b/public/placeholder-clock-2.webp differ diff --git a/public/placeholder-clock-3.webp b/public/placeholder-clock-3.webp new file mode 100644 index 0000000..897c22b Binary files /dev/null and b/public/placeholder-clock-3.webp differ diff --git a/public/placeholder-clock.webp b/public/placeholder-clock.webp new file mode 100644 index 0000000..9deb9e8 Binary files /dev/null and b/public/placeholder-clock.webp differ diff --git a/public/placeholder-doudou-2.webp b/public/placeholder-doudou-2.webp new file mode 100644 index 0000000..43b3d69 Binary files /dev/null and b/public/placeholder-doudou-2.webp differ diff --git a/public/placeholder-doudou-3.webp b/public/placeholder-doudou-3.webp new file mode 100644 index 0000000..ff75321 Binary files /dev/null and b/public/placeholder-doudou-3.webp differ diff --git a/public/placeholder-doudou.webp b/public/placeholder-doudou.webp new file mode 100644 index 0000000..880d258 Binary files /dev/null and b/public/placeholder-doudou.webp differ diff --git a/public/placeholder-formcraft-2.webp b/public/placeholder-formcraft-2.webp new file mode 100644 index 0000000..74b5ccc Binary files /dev/null and b/public/placeholder-formcraft-2.webp differ diff --git a/public/placeholder-formcraft-3.webp b/public/placeholder-formcraft-3.webp new file mode 100644 index 0000000..0748bae Binary files /dev/null and b/public/placeholder-formcraft-3.webp differ diff --git a/public/placeholder-formcraft.webp b/public/placeholder-formcraft.webp new file mode 100644 index 0000000..31c2869 Binary files /dev/null and b/public/placeholder-formcraft.webp differ diff --git a/public/placeholder-imprimersudoku-2.webp b/public/placeholder-imprimersudoku-2.webp new file mode 100644 index 0000000..82c1586 Binary files /dev/null and b/public/placeholder-imprimersudoku-2.webp differ diff --git a/public/placeholder-imprimersudoku-3.webp b/public/placeholder-imprimersudoku-3.webp new file mode 100644 index 0000000..1ae23a0 Binary files /dev/null and b/public/placeholder-imprimersudoku-3.webp differ diff --git a/public/placeholder-imprimersudoku.webp b/public/placeholder-imprimersudoku.webp new file mode 100644 index 0000000..956c2fe Binary files /dev/null and b/public/placeholder-imprimersudoku.webp differ diff --git a/public/placeholder-lazybot-2.webp b/public/placeholder-lazybot-2.webp new file mode 100644 index 0000000..e13975b Binary files /dev/null and b/public/placeholder-lazybot-2.webp differ diff --git a/public/placeholder-lazybot-3.webp b/public/placeholder-lazybot-3.webp new file mode 100644 index 0000000..c2478f6 Binary files /dev/null and b/public/placeholder-lazybot-3.webp differ diff --git a/public/placeholder-lazybot.webp b/public/placeholder-lazybot.webp new file mode 100644 index 0000000..5ecdd19 Binary files /dev/null and b/public/placeholder-lazybot.webp differ diff --git a/public/placeholder-learn-2.webp b/public/placeholder-learn-2.webp new file mode 100644 index 0000000..ee855f9 Binary files /dev/null and b/public/placeholder-learn-2.webp differ diff --git a/public/placeholder-learn-3.webp b/public/placeholder-learn-3.webp new file mode 100644 index 0000000..04baae0 Binary files /dev/null and b/public/placeholder-learn-3.webp differ diff --git a/public/placeholder-learn.webp b/public/placeholder-learn.webp new file mode 100644 index 0000000..90fc6af Binary files /dev/null and b/public/placeholder-learn.webp differ diff --git a/public/placeholder-linktree-2.webp b/public/placeholder-linktree-2.webp new file mode 100644 index 0000000..e82c5ec Binary files /dev/null and b/public/placeholder-linktree-2.webp differ diff --git a/public/placeholder-linktree-3.webp b/public/placeholder-linktree-3.webp new file mode 100644 index 0000000..3bdfd9b Binary files /dev/null and b/public/placeholder-linktree-3.webp differ diff --git a/public/placeholder-linktree.webp b/public/placeholder-linktree.webp new file mode 100644 index 0000000..9fad7ce Binary files /dev/null and b/public/placeholder-linktree.webp differ diff --git a/public/placeholder-moon-2.webp b/public/placeholder-moon-2.webp new file mode 100644 index 0000000..13748a7 Binary files /dev/null and b/public/placeholder-moon-2.webp differ diff --git a/public/placeholder-moon-3.webp b/public/placeholder-moon-3.webp new file mode 100644 index 0000000..bb74b2e Binary files /dev/null and b/public/placeholder-moon-3.webp differ diff --git a/public/placeholder-moon.webp b/public/placeholder-moon.webp new file mode 100644 index 0000000..bc7b22e Binary files /dev/null and b/public/placeholder-moon.webp differ diff --git a/public/placeholder-pomodoro-2.webp b/public/placeholder-pomodoro-2.webp new file mode 100644 index 0000000..3f78c36 Binary files /dev/null and b/public/placeholder-pomodoro-2.webp differ diff --git a/public/placeholder-pomodoro-3.webp b/public/placeholder-pomodoro-3.webp new file mode 100644 index 0000000..2fb1450 Binary files /dev/null and b/public/placeholder-pomodoro-3.webp differ diff --git a/public/placeholder-pomodoro.webp b/public/placeholder-pomodoro.webp new file mode 100644 index 0000000..86fa038 Binary files /dev/null and b/public/placeholder-pomodoro.webp differ diff --git a/public/placeholder-portfolio-2.webp b/public/placeholder-portfolio-2.webp new file mode 100644 index 0000000..dca7a08 Binary files /dev/null and b/public/placeholder-portfolio-2.webp differ diff --git a/public/placeholder-portfolio-3.webp b/public/placeholder-portfolio-3.webp new file mode 100644 index 0000000..29fd3b9 Binary files /dev/null and b/public/placeholder-portfolio-3.webp differ diff --git a/public/placeholder-portfolio.webp b/public/placeholder-portfolio.webp new file mode 100644 index 0000000..3198426 Binary files /dev/null and b/public/placeholder-portfolio.webp differ diff --git a/public/placeholder-qcu-2.webp b/public/placeholder-qcu-2.webp new file mode 100644 index 0000000..e5849cb Binary files /dev/null and b/public/placeholder-qcu-2.webp differ diff --git a/public/placeholder-qcu-3.webp b/public/placeholder-qcu-3.webp new file mode 100644 index 0000000..a4c0b8c Binary files /dev/null and b/public/placeholder-qcu-3.webp differ diff --git a/public/placeholder-qcu.webp b/public/placeholder-qcu.webp new file mode 100644 index 0000000..11e111b Binary files /dev/null and b/public/placeholder-qcu.webp differ diff --git a/public/placeholder-qrcode-2.webp b/public/placeholder-qrcode-2.webp new file mode 100644 index 0000000..6f5c74e Binary files /dev/null and b/public/placeholder-qrcode-2.webp differ diff --git a/public/placeholder-qrcode-3.webp b/public/placeholder-qrcode-3.webp new file mode 100644 index 0000000..3320bef Binary files /dev/null and b/public/placeholder-qrcode-3.webp differ diff --git a/public/placeholder-qrcode.webp b/public/placeholder-qrcode.webp new file mode 100644 index 0000000..323996c Binary files /dev/null and b/public/placeholder-qrcode.webp differ diff --git a/public/placeholder-reducelink-2.webp b/public/placeholder-reducelink-2.webp new file mode 100644 index 0000000..9a4b926 Binary files /dev/null and b/public/placeholder-reducelink-2.webp differ diff --git a/public/placeholder-reducelink-3.webp b/public/placeholder-reducelink-3.webp new file mode 100644 index 0000000..5390394 Binary files /dev/null and b/public/placeholder-reducelink-3.webp differ diff --git a/public/placeholder-reducelink.webp b/public/placeholder-reducelink.webp new file mode 100644 index 0000000..448f2f4 Binary files /dev/null and b/public/placeholder-reducelink.webp differ diff --git a/public/placeholder-sudoku-2.webp b/public/placeholder-sudoku-2.webp new file mode 100644 index 0000000..433f25b Binary files /dev/null and b/public/placeholder-sudoku-2.webp differ diff --git a/public/placeholder-sudoku-3.webp b/public/placeholder-sudoku-3.webp new file mode 100644 index 0000000..4065698 Binary files /dev/null and b/public/placeholder-sudoku-3.webp differ diff --git a/public/placeholder-sudoku.webp b/public/placeholder-sudoku.webp new file mode 100644 index 0000000..5f5d088 Binary files /dev/null and b/public/placeholder-sudoku.webp differ diff --git a/public/placeholder-visio-2.webp b/public/placeholder-visio-2.webp new file mode 100644 index 0000000..2f64bfc Binary files /dev/null and b/public/placeholder-visio-2.webp differ diff --git a/public/placeholder-visio-3.webp b/public/placeholder-visio-3.webp new file mode 100644 index 0000000..84ab506 Binary files /dev/null and b/public/placeholder-visio-3.webp differ diff --git a/public/placeholder-visio.webp b/public/placeholder-visio.webp new file mode 100644 index 0000000..a9068a0 Binary files /dev/null and b/public/placeholder-visio.webp differ diff --git a/public/robots.txt b/public/robots.txt new file mode 100644 index 0000000..da4f231 --- /dev/null +++ b/public/robots.txt @@ -0,0 +1,3 @@ +User-agent: * +Allow: / +Sitemap: https://arthurp.fr/sitemap.xml diff --git a/public/vercel.svg b/public/vercel.svg deleted file mode 100644 index 7705396..0000000 --- a/public/vercel.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/public/window.svg b/public/window.svg deleted file mode 100644 index b2b2a44..0000000 --- a/public/window.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/app/favicon.ico b/src/app/favicon.ico deleted file mode 100644 index 718d6fe..0000000 Binary files a/src/app/favicon.ico and /dev/null differ diff --git a/src/app/globals.css b/src/app/globals.css index a2dc41e..fdaf36d 100644 --- a/src/app/globals.css +++ b/src/app/globals.css @@ -1,8 +1,12 @@ @import "tailwindcss"; + :root { - --background: #ffffff; + --background: #f8f6f3; /* blanc-beige */ --foreground: #171717; + --scrollbar-bg: #f3ede6; + --scrollbar-thumb: #e2d6c2; + --scrollbar-thumb-hover: #cbb893; } @theme inline { @@ -12,10 +16,14 @@ --font-mono: var(--font-geist-mono); } + @media (prefers-color-scheme: dark) { :root { --background: #0a0a0a; --foreground: #ededed; + --scrollbar-bg: #23211e; + --scrollbar-thumb: #3a3327; + --scrollbar-thumb-hover: #5a4a2e; } } @@ -24,3 +32,48 @@ body { color: var(--foreground); font-family: Arial, Helvetica, sans-serif; } + +/* Scrollbar styling (Webkit/Blink) */ +::-webkit-scrollbar { + width: 12px; + background: var(--scrollbar-bg); +} +::-webkit-scrollbar-thumb { + background: var(--scrollbar-thumb); + border-radius: 8px; + border: 2px solid var(--scrollbar-bg); +} +::-webkit-scrollbar-thumb:hover { + background: var(--scrollbar-thumb-hover); +} +::-webkit-scrollbar-corner { + background: var(--scrollbar-bg); +} + +/* Scrollbar styling (Firefox) */ +html { + scrollbar-width: thin; + scrollbar-color: var(--scrollbar-thumb) var(--scrollbar-bg); +} + +/* Scrollbar styling */ +::-webkit-scrollbar { + width: 10px; + background: #f4f4f5; +} +::-webkit-scrollbar-thumb { + background: #dbeafe; + border-radius: 8px; + border: 2px solid #f4f4f5; +} +::-webkit-scrollbar-thumb:hover { + background: #60a5fa; +} +::-webkit-scrollbar-corner { + background: #f4f4f5; +} + +html { + scrollbar-width: thin; + scrollbar-color: #dbeafe #f4f4f5; +} diff --git a/src/app/layout.tsx b/src/app/layout.tsx index f7fa87e..cbb92e8 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -1,5 +1,7 @@ import type { Metadata } from "next"; import { Geist, Geist_Mono } from "next/font/google"; +import Link from "next/link"; +import JsonLd from "@/components/JsonLd"; import "./globals.css"; const geistSans = Geist({ @@ -13,8 +15,26 @@ const geistMono = Geist_Mono({ }); export const metadata: Metadata = { - title: "Create Next App", - description: "Generated by create next app", + title: "ArthurP.fr – Hub de projets et outils", + description: "Découvre tous les outils, bots Discord, QCM, générateurs et ressources créés par ArthurP. Un point d’accès unique pour tout ce que je développe et partage.", + metadataBase: new URL("https://arthurp.fr"), + openGraph: { + title: "ArthurP.fr – Hub de projets et outils", + description: "Découvre tous les outils, bots Discord, QCM, générateurs et ressources créés par ArthurP.", + url: "https://arthurp.fr", + siteName: "ArthurP.fr", + locale: "fr_FR", + type: "website", + }, + twitter: { + card: "summary_large_image", + title: "ArthurP.fr – Hub de projets et outils", + description: "Découvre tous les outils, bots Discord, QCM, générateurs et ressources créés par ArthurP.", + }, + robots: { + index: true, + follow: true, + }, }; export default function RootLayout({ @@ -23,11 +43,37 @@ export default function RootLayout({ children: React.ReactNode; }>) { return ( - - - {children} + + + +
+
+ {children} +
+
+ +
© {new Date().getFullYear()} ArthurP
+
+
); diff --git a/src/app/legal/cgu/page.tsx b/src/app/legal/cgu/page.tsx new file mode 100644 index 0000000..12e235b --- /dev/null +++ b/src/app/legal/cgu/page.tsx @@ -0,0 +1,16 @@ +import Link from "next/link"; + +export default function CGU() { + return ( +
+
+ + + +

Conditions Générales d’Utilisation

+

L’utilisation des outils proposés sur arthurp.fr est libre et gratuite. L’éditeur ne saurait être tenu responsable d’un usage inapproprié ou des conséquences liées à l’utilisation des outils.

+

En utilisant ce site, vous acceptez ces conditions. Pour toute question, contactez-moi à contact [at] arthurp.fr.

+
+
+ ); +} diff --git a/src/app/legal/confidentialite/page.tsx b/src/app/legal/confidentialite/page.tsx new file mode 100644 index 0000000..ec4fdfe --- /dev/null +++ b/src/app/legal/confidentialite/page.tsx @@ -0,0 +1,16 @@ +import Link from "next/link"; + +export default function Confidentialite() { + return ( +
+
+ + + +

Politique de confidentialité

+

Aucune donnée personnelle n’est collectée à des fins commerciales. Les outils proposés peuvent utiliser des cookies techniques pour le bon fonctionnement du site.

+

Aucune information n’est transmise à des tiers. Pour toute question, contactez-moi à contact [at] arthurp.fr.

+
+
+ ); +} diff --git a/src/app/legal/mentions-legales/page.tsx b/src/app/legal/mentions-legales/page.tsx new file mode 100644 index 0000000..953567b --- /dev/null +++ b/src/app/legal/mentions-legales/page.tsx @@ -0,0 +1,20 @@ +import Link from "next/link"; + +export default function MentionsLegales() { + return ( +
+
+ + + +

Mentions légales

+

Conformément à la loi, voici les informations légales du site arthurp.fr.

+
    +
  • Éditeur : Arthur P. (contact via Discord ou formulaire sur le site)
  • +
  • Contact : contact [at] arthurp.fr
  • +
+

Ce site est un projet personnel, sans but commercial.

+
+
+ ); +} diff --git a/src/app/page.tsx b/src/app/page.tsx index 295f8fd..f569449 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -1,63 +1,178 @@ + import Image from "next/image"; +import Link from "next/link"; + +const projects = [ + { + title: "LazyBot", + description: "Un bot Discord configurable avec dashboard web, inspiré de Draftbot.", + image: "/placeholder-lazybot.webp", // À remplacer par une capture plus tard + url: "https://lazybot.arthurp.fr", + infoUrl: "/projets/lazybot" + }, + { + title: "QRCode", + description: "Générateur de QR codes personnalisés, partageable par URL, sans téléchargement d'image.", + image: "/placeholder-qrcode.webp", + url: "https://qrcode.arthurp.fr", + infoUrl: "/projets/qrcode" + }, + { + title: "QCU Physique-Chimie", + description: "Révise la physique-chimie avec plus de 150 QCU configurables et corrigés.", + image: "/placeholder-qcu.webp", + url: "https://qcu.arthurp.fr", + infoUrl: "/projets/qcu" + }, + { + title: "ReduceLink", + description: "Transformez vos URLs longues en liens courts et mémorables. Gratuit, sans inscription, avec QR Code et statistiques.", + image: "/placeholder-reducelink.webp", + url: "https://reducelink.arthurp.fr/", + infoUrl: "/projets/reducelink" + }, + { + title: "Linktree", + description: "Tous mes réseaux et liens importants, centralisés pour ma communauté.", + image: "/placeholder-linktree.webp", + url: "https://links.arthurp.fr", + infoUrl: "/projets/links" + }, + { + title: "Learn", + description: "Des réponses claires à des questions populaires sur de nombreux sujets.", + image: "/placeholder-learn.webp", + url: "https://learn.arthurp.fr", + infoUrl: "/projets/learn" + }, + { + title: "Sudoku Generator & Solver", + description: "Génère, résout et vérifie des grilles de sudoku de plusieurs niveaux de difficulté.", + image: "/placeholder-sudoku.webp", + url: "https://sudoku.arthurp.fr", + infoUrl: "/projets/sudoku" + } + , + { + title: "Clock", + description: "Affiche l’heure en temps réel, analogique ou numérique, avec personnalisation du thème.", + image: "/placeholder-clock.webp", + url: "https://clock.arthurp.fr", + infoUrl: "/projets/clock" + } + , + { + title: "FormCraft", + description: "Générez des formulaires sans inscription, une alternative à Google Forms. Simple, rapide et privé.", + image: "/placeholder-formcraft.webp", + url: "https://form.arthurp.fr/", + infoUrl: "/projets/formcraft" + }, + { + title: "FocusPomodoro", + description: "Boostez votre productivité avec la technique Pomodoro : sessions de focus, pauses, statistiques et gestion des tâches.", + image: "/placeholder-pomodoro.webp", + url: "https://pomodoro.arthurp.fr", + infoUrl: "/projets/pomodoro" + }, + { + title: "Visio", + description: "Créez une salle de visioconférence en un clic et partagez le lien avec vos participants. Aucune inscription requise.", + image: "/placeholder-visio.webp", + url: "https://visio.arthurp.fr", + infoUrl: "/projets/visio" + }, + { + title: "Les Aventures de Doudou", + description: "Un album photo interactif racontant les merveilleuses aventures de Doudou, avec vue chronologique ou par albums.", + image: "/placeholder-doudou.webp", + url: "https://doudou.arthurp.fr", + infoUrl: "/projets/doudou" + }, + { + title: "Portfolio ArthurP", + description: "Le site personnel d'Arthur : développeur passionné par l'auto-hébergement, navigateur de haut niveau en voile.", + image: "/placeholder-portfolio.webp", + url: "https://portfolio.arthurp.fr", + infoUrl: "/projets/portfolio" + }, + { + title: "Moon Phases", + description: "Explorez les phases lunaires en temps réel, consultez le calendrier, la prochaine pleine lune, un simulateur et un quiz.", + image: "/placeholder-moon.webp", + url: "https://moon.arthurp.fr", + infoUrl: "/projets/moon" + }, + { + title: "Calculatrice", + description: "Calculatrice en ligne gratuite avec modes simple et scientifique, historique des calculs et thème sombre/clair.", + image: "/placeholder-calculatrice.webp", + url: "https://calculatrice.arthurp.fr", + infoUrl: "/projets/calculatrice" + }, + { + title: "Chrono", + description: "Chronomètre précis à la milliseconde et minuteur flexible avec enregistrement des tours et raccourcis clavier.", + image: "/placeholder-chrono.webp", + url: "https://chrono.arthurp.fr", + infoUrl: "/projets/chrono" + }, + { + title: "BlocNote", + description: "Application de prise de notes en ligne : créez, recherchez et organisez vos notes avec mode sombre, sans inscription.", + image: "/placeholder-blocnote.webp", + url: "https://blocnote.arthurp.fr", + infoUrl: "/projets/blocnote" + }, + { + title: "ImprimerSudoku", + description: "Générez 6 grilles de sudoku imprimables sur feuille A4 avec solutions. 4 niveaux de difficulté, en un clic.", + image: "/placeholder-imprimersudoku.webp", + url: "https://imprimersudoku.arthurp.fr", + infoUrl: "/projets/imprimersudoku" + }, +]; export default function Home() { return ( -
-
- Next.js logo -
-

- To get started, edit the page.tsx file. -

-

- Looking for a starting point or more instructions? Head over to{" "} - - Templates - {" "} - or the{" "} - - Learning - {" "} - center. -

-
-
- - Vercel logomark - Deploy Now - - - Documentation - +
+
+

Le hub d'ArthurP

+

+ Découvre tous mes outils, projets et ressources en ligne : bots Discord, générateurs, QCM, linktree et plus encore. Un point d’accès unique pour tout ce que je développe et partage. +

+
+ {projects.map((project) => ( +
+ {project.title} +
+

{project.title}

+

{project.description}

+
+ + Accéder à l’outil + + + Plus d’info + +
+
+
+ ))}
diff --git a/src/app/projets/blocnote/page.tsx b/src/app/projets/blocnote/page.tsx new file mode 100644 index 0000000..38d342d --- /dev/null +++ b/src/app/projets/blocnote/page.tsx @@ -0,0 +1,49 @@ +import ProjectInfoPage from "@/components/ProjectInfoPage"; +import type { Metadata } from "next"; + +export const metadata: Metadata = { + title: "BlocNote – Prise de notes en ligne | ArthurP.fr", + description: "Application de prise de notes en ligne simple et rapide : créez, recherchez et organisez vos notes avec mode sombre, sans inscription.", + alternates: { canonical: "https://arthurp.fr/projets/blocnote" }, + openGraph: { + title: "BlocNote – Prise de notes en ligne", + description: "Prenez des notes rapidement en ligne, avec recherche, tri par date et mode sombre. Simple et sans inscription.", + url: "https://arthurp.fr/projets/blocnote", + siteName: "ArthurP.fr", + locale: "fr_FR", + type: "website", + }, +}; + +export default function BlocNoteInfo() { + return ( + + ); +} diff --git a/src/app/projets/calculatrice/page.tsx b/src/app/projets/calculatrice/page.tsx new file mode 100644 index 0000000..c0f670f --- /dev/null +++ b/src/app/projets/calculatrice/page.tsx @@ -0,0 +1,48 @@ +import ProjectInfoPage from "@/components/ProjectInfoPage"; +import type { Metadata } from "next"; + +export const metadata: Metadata = { + title: "Calculatrice – Calculatrice en ligne simple et scientifique | ArthurP.fr", + description: "Calculatrice en ligne gratuite avec mode simple et mode scientifique, historique des calculs et thème sombre/clair.", + alternates: { canonical: "https://arthurp.fr/projets/calculatrice" }, + openGraph: { + title: "Calculatrice – Calculatrice en ligne simple et scientifique", + description: "Effectuez vos calculs en ligne avec une calculatrice simple ou scientifique, avec historique et mode sombre.", + url: "https://arthurp.fr/projets/calculatrice", + siteName: "ArthurP.fr", + locale: "fr_FR", + type: "website", + }, +}; + +export default function CalculatriceInfo() { + return ( + + ); +} diff --git a/src/app/projets/chrono/page.tsx b/src/app/projets/chrono/page.tsx new file mode 100644 index 0000000..ca6cbdc --- /dev/null +++ b/src/app/projets/chrono/page.tsx @@ -0,0 +1,50 @@ +import ProjectInfoPage from "@/components/ProjectInfoPage"; +import type { Metadata } from "next"; + +export const metadata: Metadata = { + title: "Chrono – Chronomètre et minuteur en ligne | ArthurP.fr", + description: "Chronomètre en ligne avec précision à la milliseconde, enregistrement des tours (laps), minuteur avec préréglages rapides et raccourcis clavier.", + alternates: { canonical: "https://arthurp.fr/projets/chrono" }, + openGraph: { + title: "Chrono – Chronomètre et minuteur en ligne", + description: "Chronomètre professionnel et minuteur flexible, précis à la milliseconde, avec raccourcis clavier et préréglages.", + url: "https://arthurp.fr/projets/chrono", + siteName: "ArthurP.fr", + locale: "fr_FR", + type: "website", + }, +}; + +export default function ChronoInfo() { + return ( + + ); +} diff --git a/src/app/projets/clock/page.tsx b/src/app/projets/clock/page.tsx new file mode 100644 index 0000000..2825178 --- /dev/null +++ b/src/app/projets/clock/page.tsx @@ -0,0 +1,48 @@ +import ProjectInfoPage from "@/components/ProjectInfoPage"; +import type { Metadata } from "next"; + +export const metadata: Metadata = { + title: "Clock – Horloge en ligne personnalisable | ArthurP.fr", + description: "Affichez l'heure en temps réel : horloge analogique ou numérique, personnalisation du thème (clair/sombre/couleurs).", + alternates: { canonical: "https://arthurp.fr/projets/clock" }, + openGraph: { + title: "Clock – Horloge en ligne personnalisable", + description: "Affichez l'heure en temps réel avec une horloge analogique ou numérique personnalisable.", + url: "https://arthurp.fr/projets/clock", + siteName: "ArthurP.fr", + locale: "fr_FR", + type: "website", + }, +}; + +export default function ClockInfo() { + return ( + + ); +} diff --git a/src/app/projets/doudou/page.tsx b/src/app/projets/doudou/page.tsx new file mode 100644 index 0000000..75bc3e9 --- /dev/null +++ b/src/app/projets/doudou/page.tsx @@ -0,0 +1,47 @@ +import ProjectInfoPage from "@/components/ProjectInfoPage"; +import type { Metadata } from "next"; + +export const metadata: Metadata = { + title: "Les Aventures de Doudou – Album photo interactif | ArthurP.fr", + description: "Découvrez les aventures de Doudou, un album de photos et d'histoires racontant les péripéties d'un doudou bien-aimé.", + alternates: { canonical: "https://arthurp.fr/projets/doudou" }, + openGraph: { + title: "Les Aventures de Doudou – Album photo interactif", + description: "Un album photo interactif racontant les merveilleuses aventures de Doudou.", + url: "https://arthurp.fr/projets/doudou", + siteName: "ArthurP.fr", + locale: "fr_FR", + type: "website", + }, +}; + +export default function DoudouInfo() { + return ( + + ); +} diff --git a/src/app/projets/formcraft/page.tsx b/src/app/projets/formcraft/page.tsx new file mode 100644 index 0000000..fbe9152 --- /dev/null +++ b/src/app/projets/formcraft/page.tsx @@ -0,0 +1,50 @@ +import ProjectInfoPage from "@/components/ProjectInfoPage"; +import type { Metadata } from "next"; + +export const metadata: Metadata = { + title: "FormCraft – Créez des formulaires sans inscription | ArthurP.fr", + description: "Générez des formulaires en ligne sans inscription ni collecte de données personnelles. Alternative simple et rapide à Google Forms.", + alternates: { canonical: "https://arthurp.fr/projets/formcraft" }, + openGraph: { + title: "FormCraft – Créez des formulaires sans inscription", + description: "Générez des formulaires en ligne sans inscription. Alternative simple à Google Forms.", + url: "https://arthurp.fr/projets/formcraft", + siteName: "ArthurP.fr", + locale: "fr_FR", + type: "website", + }, +}; + +export default function FormCraftInfo() { + return ( + + ); +} diff --git a/src/app/projets/imprimersudoku/page.tsx b/src/app/projets/imprimersudoku/page.tsx new file mode 100644 index 0000000..8a9163e --- /dev/null +++ b/src/app/projets/imprimersudoku/page.tsx @@ -0,0 +1,48 @@ +import ProjectInfoPage from "@/components/ProjectInfoPage"; +import type { Metadata } from "next"; + +export const metadata: Metadata = { + title: "ImprimerSudoku – Générateur de sudoku imprimable | ArthurP.fr", + description: "Générez 6 grilles de sudoku sur une feuille A4 avec leurs solutions. Choisissez votre niveau de difficulté et imprimez en un clic.", + alternates: { canonical: "https://arthurp.fr/projets/imprimersudoku" }, + openGraph: { + title: "ImprimerSudoku – Générateur de sudoku imprimable", + description: "Imprimez 6 sudokus par page avec solutions. 4 niveaux de difficulté, génération instantanée.", + url: "https://arthurp.fr/projets/imprimersudoku", + siteName: "ArthurP.fr", + locale: "fr_FR", + type: "website", + }, +}; + +export default function ImprimerSudokuInfo() { + return ( + + ); +} diff --git a/src/app/projets/lazybot/page.tsx b/src/app/projets/lazybot/page.tsx new file mode 100644 index 0000000..380dae8 --- /dev/null +++ b/src/app/projets/lazybot/page.tsx @@ -0,0 +1,49 @@ +import ProjectInfoPage from "@/components/ProjectInfoPage"; +import type { Metadata } from "next"; + +export const metadata: Metadata = { + title: "LazyBot – Bot Discord configurable | ArthurP.fr", + description: "Un bot Discord configurable avec dashboard web, inspiré de Draftbot. Gérez votre serveur, personnalisez les fonctionnalités et profitez d'une expérience unique.", + alternates: { canonical: "https://arthurp.fr/projets/lazybot" }, + openGraph: { + title: "LazyBot – Bot Discord configurable", + description: "Un bot Discord configurable avec dashboard web, inspiré de Draftbot.", + url: "https://arthurp.fr/projets/lazybot", + siteName: "ArthurP.fr", + locale: "fr_FR", + type: "website", + }, +}; + +export default function LazyBotInfo() { + return ( + + ); +} diff --git a/src/app/projets/learn/page.tsx b/src/app/projets/learn/page.tsx new file mode 100644 index 0000000..36fc87f --- /dev/null +++ b/src/app/projets/learn/page.tsx @@ -0,0 +1,48 @@ +import ProjectInfoPage from "@/components/ProjectInfoPage"; +import type { Metadata } from "next"; + +export const metadata: Metadata = { + title: "Learn – Réponses claires à vos questions | ArthurP.fr", + description: "Des réponses claires à des questions populaires sur de nombreux sujets. Idéal pour apprendre rapidement et efficacement.", + alternates: { canonical: "https://arthurp.fr/projets/learn" }, + openGraph: { + title: "Learn – Réponses claires à vos questions", + description: "Des réponses claires à des questions populaires sur de nombreux sujets.", + url: "https://arthurp.fr/projets/learn", + siteName: "ArthurP.fr", + locale: "fr_FR", + type: "website", + }, +}; + +export default function LearnInfo() { + return ( + + ); +} diff --git a/src/app/projets/links/page.tsx b/src/app/projets/links/page.tsx new file mode 100644 index 0000000..0a3c90d --- /dev/null +++ b/src/app/projets/links/page.tsx @@ -0,0 +1,46 @@ +import ProjectInfoPage from "@/components/ProjectInfoPage"; +import type { Metadata } from "next"; + +export const metadata: Metadata = { + title: "Linktree – Tous mes liens et réseaux | ArthurP.fr", + description: "Tous mes réseaux et liens importants, centralisés pour ma communauté. Facile à partager et à mettre à jour.", + alternates: { canonical: "https://arthurp.fr/projets/links" }, + openGraph: { + title: "Linktree – Tous mes liens et réseaux", + description: "Tous mes réseaux et liens importants, centralisés pour ma communauté.", + url: "https://arthurp.fr/projets/links", + siteName: "ArthurP.fr", + locale: "fr_FR", + type: "website", + }, +}; + +export default function LinksInfo() { + return ( + + ); +} diff --git a/src/app/projets/moon/page.tsx b/src/app/projets/moon/page.tsx new file mode 100644 index 0000000..9e9c39e --- /dev/null +++ b/src/app/projets/moon/page.tsx @@ -0,0 +1,49 @@ +import ProjectInfoPage from "@/components/ProjectInfoPage"; +import type { Metadata } from "next"; + +export const metadata: Metadata = { + title: "Moon Phases – Phases lunaires et calendrier | ArthurP.fr", + description: "Explorez les phases de la lune en temps réel : phase actuelle, prochaine pleine lune, calendrier lunaire, simulateur et quiz.", + alternates: { canonical: "https://arthurp.fr/projets/moon" }, + openGraph: { + title: "Moon Phases – Phases lunaires et calendrier", + description: "Suivez les phases de la lune, consultez le calendrier lunaire et découvrez les traditions liées aux pleines lunes.", + url: "https://arthurp.fr/projets/moon", + siteName: "ArthurP.fr", + locale: "fr_FR", + type: "website", + }, +}; + +export default function MoonInfo() { + return ( + + ); +} diff --git a/src/app/projets/pomodoro/page.tsx b/src/app/projets/pomodoro/page.tsx new file mode 100644 index 0000000..55e5e9e --- /dev/null +++ b/src/app/projets/pomodoro/page.tsx @@ -0,0 +1,48 @@ +import ProjectInfoPage from "@/components/ProjectInfoPage"; +import type { Metadata } from "next"; + +export const metadata: Metadata = { + title: "FocusPomodoro – Timer Pomodoro en ligne | ArthurP.fr", + description: "Boostez votre productivité avec la technique Pomodoro : sessions de focus de 25 minutes, pauses, statistiques quotidiennes et gestion de tâches.", + alternates: { canonical: "https://arthurp.fr/projets/pomodoro" }, + openGraph: { + title: "FocusPomodoro – Timer Pomodoro en ligne", + description: "Restez concentré et productif grâce au timer Pomodoro avec statistiques et gestion des tâches.", + url: "https://arthurp.fr/projets/pomodoro", + siteName: "ArthurP.fr", + locale: "fr_FR", + type: "website", + }, +}; + +export default function PomodoroInfo() { + return ( + + ); +} diff --git a/src/app/projets/portfolio/page.tsx b/src/app/projets/portfolio/page.tsx new file mode 100644 index 0000000..17ce8fb --- /dev/null +++ b/src/app/projets/portfolio/page.tsx @@ -0,0 +1,49 @@ +import ProjectInfoPage from "@/components/ProjectInfoPage"; +import type { Metadata } from "next"; + +export const metadata: Metadata = { + title: "Portfolio – Site personnel d'ArthurP | ArthurP.fr", + description: "Découvrez le portfolio personnel d'Arthur : développeur passionné par l'auto-hébergement et l'infrastructure, et sportif de haut niveau en voile.", + alternates: { canonical: "https://arthurp.fr/projets/portfolio" }, + openGraph: { + title: "Portfolio – Site personnel d'ArthurP", + description: "Portfolio de développeur et navigateur passionné par l'auto-hébergement, l'infrastructure et la voile.", + url: "https://arthurp.fr/projets/portfolio", + siteName: "ArthurP.fr", + locale: "fr_FR", + type: "website", + }, +}; + +export default function PortfolioInfo() { + return ( + + ); +} diff --git a/src/app/projets/qcu/page.tsx b/src/app/projets/qcu/page.tsx new file mode 100644 index 0000000..e83724f --- /dev/null +++ b/src/app/projets/qcu/page.tsx @@ -0,0 +1,48 @@ +import ProjectInfoPage from "@/components/ProjectInfoPage"; +import type { Metadata } from "next"; + +export const metadata: Metadata = { + title: "QCU Physique-Chimie – Révise avec 150+ QCU | ArthurP.fr", + description: "Révise la physique-chimie avec plus de 150 QCU configurables et corrigés. Mode aléatoire, filtrage des questions, réponses détaillées.", + alternates: { canonical: "https://arthurp.fr/projets/qcu" }, + openGraph: { + title: "QCU Physique-Chimie – 150+ QCU corrigés", + description: "Révise la physique-chimie avec plus de 150 QCU configurables et corrigés.", + url: "https://arthurp.fr/projets/qcu", + siteName: "ArthurP.fr", + locale: "fr_FR", + type: "website", + }, +}; + +export default function QCUInfo() { + return ( + + ); +} diff --git a/src/app/projets/qrcode/page.tsx b/src/app/projets/qrcode/page.tsx new file mode 100644 index 0000000..07cacf3 --- /dev/null +++ b/src/app/projets/qrcode/page.tsx @@ -0,0 +1,48 @@ +import ProjectInfoPage from "@/components/ProjectInfoPage"; +import type { Metadata } from "next"; + +export const metadata: Metadata = { + title: "QRCode – Générateur de QR codes personnalisés | ArthurP.fr", + description: "Générateur de QR codes personnalisés, partageable par URL, sans téléchargement d'image. Configurez vos QR codes comme vous le souhaitez.", + alternates: { canonical: "https://arthurp.fr/projets/qrcode" }, + openGraph: { + title: "QRCode – Générateur de QR codes personnalisés", + description: "Générateur de QR codes personnalisés, partageable par URL, sans téléchargement d'image.", + url: "https://arthurp.fr/projets/qrcode", + siteName: "ArthurP.fr", + locale: "fr_FR", + type: "website", + }, +}; + +export default function QRCodeInfo() { + return ( + + ); +} diff --git a/src/app/projets/reducelink/page.tsx b/src/app/projets/reducelink/page.tsx new file mode 100644 index 0000000..f2b15a7 --- /dev/null +++ b/src/app/projets/reducelink/page.tsx @@ -0,0 +1,48 @@ +import ProjectInfoPage from "@/components/ProjectInfoPage"; +import type { Metadata } from "next"; + +export const metadata: Metadata = { + title: "ReduceLink – Raccourcisseur d'URL gratuit | ArthurP.fr", + description: "Transformez vos URLs longues en liens courts et mémorables. Gratuit, sans inscription, avec QR Code et statistiques.", + alternates: { canonical: "https://arthurp.fr/projets/reducelink" }, + openGraph: { + title: "ReduceLink – Raccourcisseur d'URL gratuit", + description: "Transformez vos URLs longues en liens courts et mémorables. Gratuit, sans inscription.", + url: "https://arthurp.fr/projets/reducelink", + siteName: "ArthurP.fr", + locale: "fr_FR", + type: "website", + }, +}; + +export default function Page() { + return ( + + ); +} diff --git a/src/app/projets/sudoku/page.tsx b/src/app/projets/sudoku/page.tsx new file mode 100644 index 0000000..2717607 --- /dev/null +++ b/src/app/projets/sudoku/page.tsx @@ -0,0 +1,48 @@ +import ProjectInfoPage from '../../../components/ProjectInfoPage'; +import type { Metadata } from "next"; + +export const metadata: Metadata = { + title: "Sudoku Generator & Solver – Générez et résolvez des sudokus | ArthurP.fr", + description: "Générez des grilles de sudoku de plusieurs niveaux de difficulté, résolvez-les, vérifiez vos solutions et entraînez-vous.", + alternates: { canonical: "https://arthurp.fr/projets/sudoku" }, + openGraph: { + title: "Sudoku Generator & Solver", + description: "Générez des grilles de sudoku de plusieurs niveaux de difficulté, résolvez-les et entraînez-vous.", + url: "https://arthurp.fr/projets/sudoku", + siteName: "ArthurP.fr", + locale: "fr_FR", + type: "website", + }, +}; + +export default function SudokuProjectPage() { + return ( + + ); +} \ No newline at end of file diff --git a/src/app/projets/visio/page.tsx b/src/app/projets/visio/page.tsx new file mode 100644 index 0000000..c2b8215 --- /dev/null +++ b/src/app/projets/visio/page.tsx @@ -0,0 +1,48 @@ +import ProjectInfoPage from "@/components/ProjectInfoPage"; +import type { Metadata } from "next"; + +export const metadata: Metadata = { + title: "Visio – Visioconférence simple et gratuite | ArthurP.fr", + description: "Créez une salle de visioconférence en un clic et partagez le lien avec vos participants. Aucune inscription requise.", + alternates: { canonical: "https://arthurp.fr/projets/visio" }, + openGraph: { + title: "Visio – Visioconférence simple et gratuite", + description: "Lancez une visioconférence instantanément sans inscription. Partagez un lien et invitez vos participants.", + url: "https://arthurp.fr/projets/visio", + siteName: "ArthurP.fr", + locale: "fr_FR", + type: "website", + }, +}; + +export default function VisioInfo() { + return ( + + ); +} diff --git a/src/app/sitemap.ts b/src/app/sitemap.ts new file mode 100644 index 0000000..3c576dc --- /dev/null +++ b/src/app/sitemap.ts @@ -0,0 +1,62 @@ +import type { MetadataRoute } from "next"; + +export default function sitemap(): MetadataRoute.Sitemap { + const baseUrl = "https://arthurp.fr"; + + const staticPages: MetadataRoute.Sitemap = [ + { + url: baseUrl, + lastModified: new Date(), + changeFrequency: "monthly", + priority: 1, + }, + { + url: `${baseUrl}/legal/mentions-legales`, + lastModified: new Date(), + changeFrequency: "yearly", + priority: 0.3, + }, + { + url: `${baseUrl}/legal/confidentialite`, + lastModified: new Date(), + changeFrequency: "yearly", + priority: 0.3, + }, + { + url: `${baseUrl}/legal/cgu`, + lastModified: new Date(), + changeFrequency: "yearly", + priority: 0.3, + }, + ]; + + const projects = [ + "lazybot", + "qrcode", + "qcu", + "reducelink", + "links", + "learn", + "sudoku", + "clock", + "formcraft", + "pomodoro", + "visio", + "doudou", + "portfolio", + "moon", + "calculatrice", + "chrono", + "blocnote", + "imprimersudoku", + ]; + + const projectPages: MetadataRoute.Sitemap = projects.map((slug) => ({ + url: `${baseUrl}/projets/${slug}`, + lastModified: new Date(), + changeFrequency: "monthly" as const, + priority: 0.8, + })); + + return [...staticPages, ...projectPages]; +} diff --git a/src/components/JsonLd.tsx b/src/components/JsonLd.tsx new file mode 100644 index 0000000..94b0d28 --- /dev/null +++ b/src/components/JsonLd.tsx @@ -0,0 +1,12 @@ +interface JsonLdProps { + data: Record; +} + +export default function JsonLd({ data }: JsonLdProps) { + return ( +