feat: show calendar fetch state on the list page
Orchestrate the feed retrieval from the list page: loading / success (event count) / actionable French error states with a Réessayer button and an Ouvrir Nextcloud link when the session is missing. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
1432aba561
commit
b27bb478bf
@@ -27,3 +27,25 @@ h1 {
|
|||||||
color: #666;
|
color: #666;
|
||||||
font-style: italic;
|
font-style: italic;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#etat {
|
||||||
|
margin-bottom: 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.etat-neutre {
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
|
||||||
|
.etat-erreur {
|
||||||
|
color: #b3261e;
|
||||||
|
}
|
||||||
|
|
||||||
|
#etat a {
|
||||||
|
display: inline-block;
|
||||||
|
margin-right: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
#etat button {
|
||||||
|
font: inherit;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
<body>
|
<body>
|
||||||
<main>
|
<main>
|
||||||
<h1>Écho du Huit</h1>
|
<h1>Écho du Huit</h1>
|
||||||
|
<div id="etat" role="status" aria-live="polite"></div>
|
||||||
<ul id="liste"></ul>
|
<ul id="liste"></ul>
|
||||||
</main>
|
</main>
|
||||||
<script type="module" src="liste.js"></script>
|
<script type="module" src="liste.js"></script>
|
||||||
|
|||||||
+68
-7
@@ -1,8 +1,69 @@
|
|||||||
// Squelette : la récupération des deux sources (Atelier du Huit, ville de
|
import {
|
||||||
// Cugnaux) arrivera dans des tâches ultérieures. Pour l'instant, état vide.
|
compterEvenements,
|
||||||
const liste = document.querySelector("#liste");
|
recupererFluxCalendrier,
|
||||||
|
} from "./nextcloud.js";
|
||||||
|
|
||||||
const vide = document.createElement("li");
|
const URL_NEXTCLOUD = "https://atelier-huit.frama.space/";
|
||||||
vide.className = "liste-vide";
|
|
||||||
vide.textContent = "Aucune donnée pour l'instant.";
|
// Mapping type d'erreur → message FR non technique et actionnable.
|
||||||
liste.append(vide);
|
const MESSAGES_ERREUR = {
|
||||||
|
"non-connecte":
|
||||||
|
"Tu n'es pas connecté·e à Nextcloud. Ouvre Nextcloud dans un onglet, connecte-toi, puis reviens et clique sur Réessayer.",
|
||||||
|
reseau:
|
||||||
|
"Impossible de joindre Nextcloud. Vérifie ta connexion internet, puis réessaie.",
|
||||||
|
serveur:
|
||||||
|
"Nextcloud a renvoyé une erreur inattendue. Réessaie dans un moment.",
|
||||||
|
};
|
||||||
|
|
||||||
|
const etat = document.querySelector("#etat");
|
||||||
|
|
||||||
|
function rendreNeutre(texte) {
|
||||||
|
etat.replaceChildren();
|
||||||
|
const p = document.createElement("p");
|
||||||
|
p.className = "etat-neutre";
|
||||||
|
p.textContent = texte;
|
||||||
|
etat.append(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
function rendreSucces(flux) {
|
||||||
|
const nombre = compterEvenements(flux);
|
||||||
|
rendreNeutre(`${nombre} événement${nombre > 1 ? "s" : ""} lu${nombre > 1 ? "s" : ""}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
function rendreErreur(typeErreur) {
|
||||||
|
etat.replaceChildren();
|
||||||
|
|
||||||
|
const message = document.createElement("p");
|
||||||
|
message.className = "etat-erreur";
|
||||||
|
message.textContent = MESSAGES_ERREUR[typeErreur];
|
||||||
|
etat.append(message);
|
||||||
|
|
||||||
|
if (typeErreur === "non-connecte") {
|
||||||
|
const lien = document.createElement("a");
|
||||||
|
lien.href = URL_NEXTCLOUD;
|
||||||
|
lien.target = "_blank";
|
||||||
|
lien.rel = "noopener";
|
||||||
|
lien.textContent = "Ouvrir Nextcloud";
|
||||||
|
etat.append(lien);
|
||||||
|
}
|
||||||
|
|
||||||
|
const reessayer = document.createElement("button");
|
||||||
|
reessayer.type = "button";
|
||||||
|
reessayer.textContent = "Réessayer";
|
||||||
|
reessayer.addEventListener("click", charger);
|
||||||
|
etat.append(reessayer);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function charger() {
|
||||||
|
rendreNeutre("Lecture du calendrier…");
|
||||||
|
// Wrapper obligatoire : un `fetch` nu détaché de `window` lève
|
||||||
|
// « Illegal invocation » dans le navigateur.
|
||||||
|
const res = await recupererFluxCalendrier((u, o) => fetch(u, o));
|
||||||
|
if (res.ok) {
|
||||||
|
rendreSucces(res.flux);
|
||||||
|
} else {
|
||||||
|
rendreErreur(res.erreur);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
charger();
|
||||||
|
|||||||
Reference in New Issue
Block a user