mirror of
https://github.com/arthur-pbty/hub.git
synced 2026-06-09 01:01:59 +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:
@@ -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