Ajout de HelloFresh
This commit is contained in:
174
wwwroot/js/HelloFresh/historique.js
Normal file
174
wwwroot/js/HelloFresh/historique.js
Normal file
@@ -0,0 +1,174 @@
|
||||
// ---------- ÉTAT ----------
|
||||
let HISTORY_CACHE = []; // [{ date, rawDate, items: [...] }]
|
||||
let HISTORY_SEARCH = "";
|
||||
|
||||
// Normalisation basique pour la recherche
|
||||
const ACCENT_RX = /[\u0300-\u036f]/g;
|
||||
const norm = s => (s || "").toString().toLowerCase()
|
||||
.normalize("NFD").replace(ACCENT_RX, "").trim();
|
||||
|
||||
// Palette de couleurs (plus large possible pour différencier)
|
||||
const USER_COLORS = [
|
||||
"#C0392B", // rouge foncé
|
||||
"#2980B9", // bleu foncé
|
||||
"#27AE60", // vert foncé
|
||||
"#D35400", // orange foncé
|
||||
"#8E44AD", // violet foncé
|
||||
"#2C3E50", // gris/bleu très foncé
|
||||
"#7D3C98", // violet profond
|
||||
"#1ABC9C" // turquoise foncé
|
||||
];
|
||||
// Cache pour assigner une couleur unique par user
|
||||
const userColorMap = new Map();
|
||||
let userColorIndex = 0;
|
||||
|
||||
function getUserColor(username) {
|
||||
if (!username) return "#999";
|
||||
if (!userColorMap.has(username)) {
|
||||
// Assigne une couleur en cycle
|
||||
userColorMap.set(username, USER_COLORS[userColorIndex % USER_COLORS.length]);
|
||||
userColorIndex++;
|
||||
}
|
||||
return userColorMap.get(username);
|
||||
}
|
||||
|
||||
function buildUserBadges(usersArr) {
|
||||
const wrap = document.createElement("div");
|
||||
wrap.className = "label-container";
|
||||
(usersArr || []).forEach(u => {
|
||||
const span = document.createElement("span");
|
||||
span.className = "label-badge user-badge";
|
||||
span.textContent = u;
|
||||
|
||||
// Couleur dynamique par utilisateur
|
||||
span.style.backgroundColor = getUserColor(u);
|
||||
span.style.color = "#fff"; // texte blanc pour lisibilité
|
||||
|
||||
wrap.appendChild(span);
|
||||
});
|
||||
return wrap;
|
||||
}
|
||||
|
||||
const truncate = (s, m) => (s && s.length > m ? s.slice(0, m) + "…" : (s ?? ""));
|
||||
|
||||
function buildRecipeCardHistory(rec) {
|
||||
const card = document.createElement("div");
|
||||
card.className = "card";
|
||||
card.id = `hist-${rec.id}`;
|
||||
|
||||
const name = rec.name || `Recette ${rec.id}`;
|
||||
const imgSrc = rec.image || "/images/recipe-placeholder.png"; // mets un vrai fichier ici
|
||||
|
||||
card.innerHTML = `
|
||||
<div class="image-container">
|
||||
<img src="${imgSrc}" alt="${truncate(name, 10)}"
|
||||
onerror="this.onerror=null;this.src='/images/recipe-placeholder.png'">
|
||||
<div class="badge-portions">${rec.portions} portion${rec.portions > 1 ? 's' : ''}</div>
|
||||
</div>
|
||||
<div class="card-content"><h3>${name}</h3></div>
|
||||
`;
|
||||
|
||||
// badges utilisateurs (JSON camelCase => "users")
|
||||
const users = Array.isArray(rec.users) ? rec.users : Array.isArray(rec.Users) ? rec.Users : [];
|
||||
if (users.length) {
|
||||
card.querySelector(".image-container")?.appendChild(buildUserBadges(users));
|
||||
}
|
||||
return card;
|
||||
}
|
||||
|
||||
|
||||
function buildDateSection(dateStr, items) {
|
||||
const sec = document.createElement("section");
|
||||
sec.className = "history-section";
|
||||
|
||||
const h = document.createElement("h3");
|
||||
h.className = "history-date";
|
||||
h.textContent = dateStr;
|
||||
sec.appendChild(h);
|
||||
|
||||
const grid = document.createElement("div");
|
||||
grid.className = "hf-grid";
|
||||
if (Array.isArray(items) && items.length) {
|
||||
items.forEach(r => grid.appendChild(buildRecipeCardHistory(r)));
|
||||
} else {
|
||||
grid.innerHTML = `<p class="placeholder">Aucune recette pour cette date.</p>`;
|
||||
}
|
||||
sec.appendChild(grid);
|
||||
return sec;
|
||||
}
|
||||
|
||||
// Applique la recherche sur le cache et rend
|
||||
function renderHistoryFiltered() {
|
||||
const container = document.getElementById("historyContainer");
|
||||
if (!container) return;
|
||||
|
||||
const q = norm(HISTORY_SEARCH);
|
||||
const groups = [];
|
||||
|
||||
for (const g of (HISTORY_CACHE || [])) {
|
||||
if (!q) {
|
||||
groups.push(g);
|
||||
continue;
|
||||
}
|
||||
const filteredItems = (g.items || []).filter(it => norm(it.name).includes(q));
|
||||
if (filteredItems.length) {
|
||||
groups.push({ date: g.date, rawDate: g.rawDate, items: filteredItems });
|
||||
}
|
||||
}
|
||||
|
||||
container.innerHTML = "";
|
||||
if (!groups.length) {
|
||||
container.innerHTML = `<p class="placeholder">Aucun résultat pour “${HISTORY_SEARCH}”.</p>`;
|
||||
return;
|
||||
}
|
||||
groups.forEach(group => container.appendChild(buildDateSection(group.date, group.items)));
|
||||
}
|
||||
|
||||
// ---------- CHARGEMENT ----------
|
||||
async function loadHistory(scope = "mine") {
|
||||
const container = document.getElementById("historyContainer");
|
||||
if (!container) return;
|
||||
container.innerHTML = "Chargement…";
|
||||
try {
|
||||
const isUserImportant = (scope !== "all");
|
||||
const res = await fetch(`/HelloFresh/GetHistory?isUserImportant=${isUserImportant ? "true" : "false"}&search=${encodeURIComponent(HISTORY_SEARCH)}`, { credentials: "same-origin" });
|
||||
if (!res.ok) throw new Error(`HTTP ${res.status}`);
|
||||
const data = await res.json(); // [{ date, rawDate, items }]
|
||||
|
||||
HISTORY_CACHE = Array.isArray(data) ? data : [];
|
||||
renderHistoryFiltered(); // premier rendu (avec éventuel terme déjà saisi)
|
||||
} catch (e) {
|
||||
console.error("loadHistory error:", e);
|
||||
container.innerHTML = `<p class="placeholder">Erreur de chargement.</p>`;
|
||||
}
|
||||
}
|
||||
|
||||
// ---------- INIT ----------
|
||||
document.addEventListener("DOMContentLoaded", () => {
|
||||
const scopeSel = document.getElementById("historyScope");
|
||||
const search = document.getElementById("historySearch");
|
||||
|
||||
// charge au démarrage
|
||||
loadHistory(scopeSel?.value || "mine");
|
||||
|
||||
// changement de portée
|
||||
scopeSel?.addEventListener("change", () => loadHistory(scopeSel.value || "mine"));
|
||||
|
||||
// recherche (debounce)
|
||||
let timer;
|
||||
search?.addEventListener("input", (e) => {
|
||||
HISTORY_SEARCH = e.target.value || "";
|
||||
clearTimeout(timer);
|
||||
timer = setTimeout(renderHistoryFiltered, 200);
|
||||
});
|
||||
|
||||
// Entrée = rendu immédiat
|
||||
search?.addEventListener("keydown", (e) => {
|
||||
if (e.key === "Enter") {
|
||||
e.preventDefault();
|
||||
clearTimeout(timer);
|
||||
renderHistoryFiltered();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user