mirror of
https://github.com/arthur-pbty/hub.git
synced 2026-06-04 15:56:45 +02:00
feat: ajouter des liens GitHub aux pages de projet et implémenter le composant PastilleStatut pour le suivi de l'état en ligne
This commit is contained in:
Generated
-12
@@ -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"
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
/>
|
||||
);
|
||||
}
|
||||
@@ -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"
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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 (
|
||||
<span
|
||||
className={`inline-flex items-center gap-1 px-2 py-1 rounded-full text-xs font-medium text-white ${color}`}
|
||||
title={label}
|
||||
aria-label={label}
|
||||
style={{ minWidth: 90 }}
|
||||
>
|
||||
<span className="w-2 h-2 rounded-full bg-white/80 mr-1" style={{ backgroundColor: color.replace("bg-", "") }} />
|
||||
{label}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
@@ -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 (
|
||||
<div className="min-h-screen bg-white font-sans text-zinc-900">
|
||||
@@ -97,14 +100,28 @@ export default function ProjectInfoPage({
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<a
|
||||
href={url}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="inline-block rounded-lg bg-[#e2d6c2] px-6 py-3 text-[#5a4a2e] font-medium hover:bg-[#d6bfa3] border border-[#d6bfa3] transition-colors"
|
||||
>
|
||||
{"Acc\u00e9der \u00e0 l\u2019outil"}
|
||||
</a>
|
||||
|
||||
<div className="flex gap-4 mb-2 items-center">
|
||||
<a
|
||||
href={url}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="inline-block rounded-lg bg-[#e2d6c2] px-6 py-3 text-[#5a4a2e] font-medium hover:bg-[#d6bfa3] border border-[#d6bfa3] transition-colors"
|
||||
>
|
||||
{"Acc\u00e9der \u00e0 l\u2019outil"}
|
||||
</a>
|
||||
{githubUrl && (
|
||||
<a
|
||||
href={githubUrl}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="inline-block rounded-lg bg-zinc-900 px-6 py-3 text-white font-medium hover:bg-zinc-700 border border-zinc-800 transition-colors"
|
||||
>
|
||||
{"Voir sur GitHub"}
|
||||
</a>
|
||||
)}
|
||||
<PastilleStatut url={url} />
|
||||
</div>
|
||||
|
||||
{longDescription && (
|
||||
<section className="mt-12">
|
||||
|
||||
Reference in New Issue
Block a user