From 6e2147a4890ab620e56a10e81a75ae6876026fb3 Mon Sep 17 00:00:00 2001 From: Puechberty Arthur Date: Tue, 31 Mar 2026 17:10:39 +0200 Subject: [PATCH] =?UTF-8?q?feat:=20ajouter=20des=20liens=20GitHub=20aux=20?= =?UTF-8?q?pages=20de=20projet=20et=20impl=C3=A9menter=20le=20composant=20?= =?UTF-8?q?PastilleStatut=20pour=20le=20suivi=20de=20l'=C3=A9tat=20en=20li?= =?UTF-8?q?gne?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package-lock.json | 12 ------ src/app/projets/blocnote/page.tsx | 1 + src/app/projets/calculatrice/page.tsx | 1 + src/app/projets/chrono/page.tsx | 1 + src/app/projets/clock/page.tsx | 1 + src/app/projets/formcraft/page.tsx | 1 + src/app/projets/imprimersudoku/page.tsx | 1 + src/app/projets/lazybot/page.tsx | 1 + src/app/projets/learn/page.tsx | 1 + src/app/projets/moon/page.tsx | 1 + src/app/projets/pomodoro/page.tsx | 1 + src/app/projets/portfolio/page.tsx | 1 + src/app/projets/qcu/page.tsx | 1 + src/app/projets/qrcode/page.tsx | 1 + src/app/projets/reducelink/page.tsx | 1 + src/app/projets/sudoku/page.tsx | 1 + src/app/projets/visio/page.tsx | 1 + src/components/PastilleStatut.tsx | 51 +++++++++++++++++++++++++ src/components/ProjectInfoPage.tsx | 33 ++++++++++++---- 19 files changed, 92 insertions(+), 20 deletions(-) create mode 100644 src/components/PastilleStatut.tsx diff --git a/package-lock.json b/package-lock.json index f187f3c..bf5639e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -67,7 +67,6 @@ "integrity": "sha512-H3mcG6ZDLTlYfaSNi0iOKkigqMFvkTKlGUYlD8GW7nNOYRrevuA46iTypPyv+06V3fEmvvazfntkBU34L0azAw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/code-frame": "^7.28.6", "@babel/generator": "^7.28.6", @@ -1562,7 +1561,6 @@ "integrity": "sha512-WPigyYuGhgZ/cTPRXB2EwUw+XvsRA3GqHlsP4qteqrnnjDrApbS7MxcGr/hke5iUoeB7E/gQtrs9I37zAJ0Vjw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "csstype": "^3.2.2" } @@ -1622,7 +1620,6 @@ "integrity": "sha512-BtE0k6cjwjLZoZixN0t5AKP0kSzlGu7FctRXYuPAm//aaiZhmfq1JwdYpYr1brzEspYyFeF+8XF5j2VK6oalrA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@typescript-eslint/scope-manager": "8.54.0", "@typescript-eslint/types": "8.54.0", @@ -2122,7 +2119,6 @@ "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", "dev": true, "license": "MIT", - "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -2463,7 +2459,6 @@ } ], "license": "MIT", - "peer": true, "dependencies": { "baseline-browser-mapping": "^2.9.0", "caniuse-lite": "^1.0.30001759", @@ -3031,7 +3026,6 @@ "integrity": "sha512-LEyamqS7W5HB3ujJyvi0HQK/dtVINZvd5mAAp9eT5S/ujByGjiZLCzPcHVzuXbpJDJF/cxwHlfceVUDZ2lnSTw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.8.0", "@eslint-community/regexpp": "^4.12.1", @@ -3217,7 +3211,6 @@ "integrity": "sha512-whOE1HFo/qJDyX4SnXzP4N6zOWn79WhnCUY/iDR0mPfQZO8wcYE4JClzI2oZrhBnnMUCBCHZhO6VQyoBU95mZA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@rtsao/scc": "^1.1.0", "array-includes": "^3.1.9", @@ -5390,7 +5383,6 @@ "resolved": "https://registry.npmjs.org/react/-/react-19.2.3.tgz", "integrity": "sha512-Ku/hhYbVjOQnXDZFv2+RibmLFGwFdeeKHFcOTlrt7xplBnya5OGn/hIRDsqDiSUcfORsDC7MPxwork8jBwsIWA==", "license": "MIT", - "peer": true, "engines": { "node": ">=0.10.0" } @@ -5400,7 +5392,6 @@ "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.3.tgz", "integrity": "sha512-yELu4WmLPw5Mr/lmeEpox5rw3RETacE++JgHqQzd2dg+YbJuat3jH4ingc+WPZhxaoFzdv9y33G+F7Nl5O0GBg==", "license": "MIT", - "peer": true, "dependencies": { "scheduler": "^0.27.0" }, @@ -6089,7 +6080,6 @@ "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=12" }, @@ -6252,7 +6242,6 @@ "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", "dev": true, "license": "Apache-2.0", - "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -6528,7 +6517,6 @@ "integrity": "sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg==", "dev": true, "license": "MIT", - "peer": true, "funding": { "url": "https://github.com/sponsors/colinhacks" } diff --git a/src/app/projets/blocnote/page.tsx b/src/app/projets/blocnote/page.tsx index 38d342d..b31edcb 100644 --- a/src/app/projets/blocnote/page.tsx +++ b/src/app/projets/blocnote/page.tsx @@ -44,6 +44,7 @@ export default function BlocNoteInfo() { ]} images={["/placeholder-blocnote.webp", "/placeholder-blocnote-2.webp", "/placeholder-blocnote-3.webp"]} url="https://blocnote.arthurp.fr" + githubUrl="https://github.com/arthur-pbty/blocnote" /> ); } diff --git a/src/app/projets/calculatrice/page.tsx b/src/app/projets/calculatrice/page.tsx index c0f670f..2982302 100644 --- a/src/app/projets/calculatrice/page.tsx +++ b/src/app/projets/calculatrice/page.tsx @@ -43,6 +43,7 @@ export default function CalculatriceInfo() { ]} images={["/placeholder-calculatrice.webp", "/placeholder-calculatrice-2.webp", "/placeholder-calculatrice-3.webp"]} url="https://calculatrice.arthurp.fr" + githubUrl="https://github.com/arthur-pbty/calculatrice" /> ); } diff --git a/src/app/projets/chrono/page.tsx b/src/app/projets/chrono/page.tsx index ca6cbdc..cd70b03 100644 --- a/src/app/projets/chrono/page.tsx +++ b/src/app/projets/chrono/page.tsx @@ -45,6 +45,7 @@ export default function ChronoInfo() { ]} images={["/placeholder-chrono.webp", "/placeholder-chrono-2.webp", "/placeholder-chrono-3.webp"]} url="https://chrono.arthurp.fr" + githubUrl="https://github.com/arthur-pbty/chrono" /> ); } diff --git a/src/app/projets/clock/page.tsx b/src/app/projets/clock/page.tsx index 2825178..d2c1ef6 100644 --- a/src/app/projets/clock/page.tsx +++ b/src/app/projets/clock/page.tsx @@ -43,6 +43,7 @@ export default function ClockInfo() { ]} images={["/placeholder-clock.webp", "/placeholder-clock-2.webp", "/placeholder-clock-3.webp"]} url="https://clock.arthurp.fr" + githubUrl="https://github.com/arthur-pbty/clock" /> ); } diff --git a/src/app/projets/formcraft/page.tsx b/src/app/projets/formcraft/page.tsx index fbe9152..e921ab5 100644 --- a/src/app/projets/formcraft/page.tsx +++ b/src/app/projets/formcraft/page.tsx @@ -45,6 +45,7 @@ export default function FormCraftInfo() { ]} images={["/placeholder-formcraft.webp", "/placeholder-formcraft-2.webp", "/placeholder-formcraft-3.webp"]} url="https://form.arthurp.fr/" + githubUrl="https://github.com/arthur-pbty/form" /> ); } diff --git a/src/app/projets/imprimersudoku/page.tsx b/src/app/projets/imprimersudoku/page.tsx index 8a9163e..4f27383 100644 --- a/src/app/projets/imprimersudoku/page.tsx +++ b/src/app/projets/imprimersudoku/page.tsx @@ -43,6 +43,7 @@ export default function ImprimerSudokuInfo() { ]} images={["/placeholder-imprimersudoku.webp", "/placeholder-imprimersudoku-2.webp", "/placeholder-imprimersudoku-3.webp"]} url="https://imprimersudoku.arthurp.fr" + githubUrl="https://github.com/arthur-pbty/imprimersudoku" /> ); } diff --git a/src/app/projets/lazybot/page.tsx b/src/app/projets/lazybot/page.tsx index 380dae8..1558875 100644 --- a/src/app/projets/lazybot/page.tsx +++ b/src/app/projets/lazybot/page.tsx @@ -44,6 +44,7 @@ export default function LazyBotInfo() { ]} images={["/placeholder-lazybot.webp", "/placeholder-lazybot-2.webp", "/placeholder-lazybot-3.webp"]} url="https://lazybot.arthurp.fr" + githubUrl="https://github.com/arthur-pbty/LazyBot" /> ); } diff --git a/src/app/projets/learn/page.tsx b/src/app/projets/learn/page.tsx index 36fc87f..1644623 100644 --- a/src/app/projets/learn/page.tsx +++ b/src/app/projets/learn/page.tsx @@ -43,6 +43,7 @@ export default function LearnInfo() { ]} images={["/placeholder-learn.webp", "/placeholder-learn-2.webp", "/placeholder-learn-3.webp"]} url="https://learn.arthurp.fr" + githubUrl="https://github.com/arthur-pbty/learn" /> ); } diff --git a/src/app/projets/moon/page.tsx b/src/app/projets/moon/page.tsx index 9e9c39e..be17958 100644 --- a/src/app/projets/moon/page.tsx +++ b/src/app/projets/moon/page.tsx @@ -44,6 +44,7 @@ export default function MoonInfo() { ]} images={["/placeholder-moon.webp", "/placeholder-moon-2.webp", "/placeholder-moon-3.webp"]} url="https://moon.arthurp.fr" + githubUrl="https://github.com/arthur-pbty/moon" /> ); } diff --git a/src/app/projets/pomodoro/page.tsx b/src/app/projets/pomodoro/page.tsx index 55e5e9e..56e9017 100644 --- a/src/app/projets/pomodoro/page.tsx +++ b/src/app/projets/pomodoro/page.tsx @@ -43,6 +43,7 @@ export default function PomodoroInfo() { ]} images={["/placeholder-pomodoro.webp", "/placeholder-pomodoro-2.webp", "/placeholder-pomodoro-3.webp"]} url="https://pomodoro.arthurp.fr" + githubUrl="https://github.com/arthur-pbty/pomodoro" /> ); } diff --git a/src/app/projets/portfolio/page.tsx b/src/app/projets/portfolio/page.tsx index 17ce8fb..9183933 100644 --- a/src/app/projets/portfolio/page.tsx +++ b/src/app/projets/portfolio/page.tsx @@ -44,6 +44,7 @@ export default function PortfolioInfo() { ]} images={["/placeholder-portfolio.webp", "/placeholder-portfolio-2.webp", "/placeholder-portfolio-3.webp"]} url="https://portfolio.arthurp.fr" + githubUrl="https://github.com/arthur-pbty/portfolio" /> ); } diff --git a/src/app/projets/qcu/page.tsx b/src/app/projets/qcu/page.tsx index e83724f..94862d2 100644 --- a/src/app/projets/qcu/page.tsx +++ b/src/app/projets/qcu/page.tsx @@ -43,6 +43,7 @@ export default function QCUInfo() { ]} images={["/placeholder-qcu.webp", "/placeholder-qcu-2.webp", "/placeholder-qcu-3.webp"]} url="https://qcu.arthurp.fr" + githubUrl="https://github.com/arthur-pbty/QCM_physique" /> ); } diff --git a/src/app/projets/qrcode/page.tsx b/src/app/projets/qrcode/page.tsx index 07cacf3..e4720ca 100644 --- a/src/app/projets/qrcode/page.tsx +++ b/src/app/projets/qrcode/page.tsx @@ -43,6 +43,7 @@ export default function QRCodeInfo() { ]} images={["/placeholder-qrcode.webp", "/placeholder-qrcode-2.webp", "/placeholder-qrcode-3.webp"]} url="https://qrcode.arthurp.fr" + githubUrl="https://github.com/arthur-pbty/qrcode" /> ); } diff --git a/src/app/projets/reducelink/page.tsx b/src/app/projets/reducelink/page.tsx index f2b15a7..0c43eef 100644 --- a/src/app/projets/reducelink/page.tsx +++ b/src/app/projets/reducelink/page.tsx @@ -43,6 +43,7 @@ export default function Page() { ]} images={["/placeholder-reducelink.webp", "/placeholder-reducelink-2.webp", "/placeholder-reducelink-3.webp"]} url="https://reducelink.arthurp.fr/" + githubUrl="https://github.com/arthur-pbty/reducelink" /> ); } diff --git a/src/app/projets/sudoku/page.tsx b/src/app/projets/sudoku/page.tsx index 2717607..09c8595 100644 --- a/src/app/projets/sudoku/page.tsx +++ b/src/app/projets/sudoku/page.tsx @@ -43,6 +43,7 @@ export default function SudokuProjectPage() { ]} images={["/placeholder-sudoku.webp", "/placeholder-sudoku-2.webp", "/placeholder-sudoku-3.webp"]} url="https://sudoku.arthurp.fr" + githubUrl="https://github.com/arthur-pbty/sudoku" /> ); } \ No newline at end of file diff --git a/src/app/projets/visio/page.tsx b/src/app/projets/visio/page.tsx index c2b8215..5fc5381 100644 --- a/src/app/projets/visio/page.tsx +++ b/src/app/projets/visio/page.tsx @@ -43,6 +43,7 @@ export default function VisioInfo() { ]} images={["/placeholder-visio.webp", "/placeholder-visio-2.webp", "/placeholder-visio-3.webp"]} url="https://visio.arthurp.fr" + githubUrl="https://github.com/arthur-pbty/visio" /> ); } diff --git a/src/components/PastilleStatut.tsx b/src/components/PastilleStatut.tsx new file mode 100644 index 0000000..9908584 --- /dev/null +++ b/src/components/PastilleStatut.tsx @@ -0,0 +1,51 @@ +"use client"; +import { useEffect, useState } from "react"; + +interface PastilleStatutProps { + url: string; + intervalMs?: number; +} + +export default function PastilleStatut({ url, intervalMs = 60000 }: PastilleStatutProps) { + const [statut, setStatut] = useState<"en-ligne" | "hors-ligne" | "inconnu">("inconnu"); + + useEffect(() => { + let timeout: NodeJS.Timeout; + let isMounted = true; + const check = async () => { + try { + const res = await fetch(url, { method: "HEAD", mode: "no-cors" }); + if (isMounted) setStatut("en-ligne"); + } catch { + if (isMounted) setStatut("hors-ligne"); + } + timeout = setTimeout(check, intervalMs); + }; + check(); + return () => { + isMounted = false; + clearTimeout(timeout); + }; + }, [url, intervalMs]); + + let color = "bg-gray-400", label = "Statut inconnu"; + if (statut === "en-ligne") { + color = "bg-green-500"; + label = "Site en ligne"; + } else if (statut === "hors-ligne") { + color = "bg-red-500"; + label = "Site hors ligne"; + } + + return ( + + + {label} + + ); +} diff --git a/src/components/ProjectInfoPage.tsx b/src/components/ProjectInfoPage.tsx index b96a809..6e5d0ce 100644 --- a/src/components/ProjectInfoPage.tsx +++ b/src/components/ProjectInfoPage.tsx @@ -1,6 +1,7 @@ import Image from "next/image"; import Link from "next/link"; import JsonLd from "@/components/JsonLd"; +import PastilleStatut from "@/components/PastilleStatut"; interface FAQ { question: string; @@ -17,6 +18,7 @@ interface ProjectInfoPageProps { faq?: FAQ[]; images: string[]; url: string; + githubUrl?: string; } export default function ProjectInfoPage({ @@ -29,6 +31,7 @@ export default function ProjectInfoPage({ faq, images, url, + githubUrl, }: ProjectInfoPageProps) { return (
@@ -97,14 +100,28 @@ export default function ProjectInfoPage({
- - {"Acc\u00e9der \u00e0 l\u2019outil"} - + +
+ + {"Acc\u00e9der \u00e0 l\u2019outil"} + + {githubUrl && ( + + {"Voir sur GitHub"} + + )} + +
{longDescription && (