UI: add console colors, state badges, sticky header and clearer actions
This commit is contained in:
82
app.js
82
app.js
@@ -564,6 +564,13 @@ gamesList.addEventListener("click", async (event) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (apiReachable && dataMode !== "local-pending-import") {
|
if (apiReachable && dataMode !== "local-pending-import") {
|
||||||
|
if (action === "delete") {
|
||||||
|
const confirmed = window.confirm("Etes-vous sur de vouloir supprimer ce jeu ?");
|
||||||
|
if (!confirmed) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (action === "delete") {
|
if (action === "delete") {
|
||||||
await apiRequest(`/api/catalog/games/${id}`, { method: "DELETE" });
|
await apiRequest(`/api/catalog/games/${id}`, { method: "DELETE" });
|
||||||
@@ -603,6 +610,10 @@ gamesList.addEventListener("click", async (event) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (action === "delete") {
|
if (action === "delete") {
|
||||||
|
const confirmed = window.confirm("Etes-vous sur de vouloir supprimer ce jeu ?");
|
||||||
|
if (!confirmed) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
games.splice(idx, 1);
|
games.splice(idx, 1);
|
||||||
if (editingGameId === id) {
|
if (editingGameId === id) {
|
||||||
resetEditMode();
|
resetEditMode();
|
||||||
@@ -977,6 +988,58 @@ function badgeClassForGenre(genreValue) {
|
|||||||
return "default";
|
return "default";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function consoleThemeClass(consoleName) {
|
||||||
|
const normalized = normalizeText(consoleName).toLowerCase();
|
||||||
|
if (normalized.includes("playstation 5") || normalized === "ps5") {
|
||||||
|
return "console-theme-ps5";
|
||||||
|
}
|
||||||
|
if (normalized.includes("playstation 4") || normalized === "ps4") {
|
||||||
|
return "console-theme-ps4";
|
||||||
|
}
|
||||||
|
if (normalized.includes("playstation 3") || normalized === "ps3") {
|
||||||
|
return "console-theme-ps3";
|
||||||
|
}
|
||||||
|
if (normalized.includes("playstation 2") || normalized === "ps2") {
|
||||||
|
return "console-theme-ps2";
|
||||||
|
}
|
||||||
|
if (normalized.includes("playstation") || normalized === "ps1") {
|
||||||
|
return "console-theme-ps1";
|
||||||
|
}
|
||||||
|
if (normalized.includes("switch")) {
|
||||||
|
return "console-theme-switch";
|
||||||
|
}
|
||||||
|
if (normalized.includes("xbox")) {
|
||||||
|
return "console-theme-xbox";
|
||||||
|
}
|
||||||
|
if (normalized.includes("wii")) {
|
||||||
|
return "console-theme-wii";
|
||||||
|
}
|
||||||
|
if (normalized.includes("snes")) {
|
||||||
|
return "console-theme-snes";
|
||||||
|
}
|
||||||
|
if (normalized.includes("nes")) {
|
||||||
|
return "console-theme-nes";
|
||||||
|
}
|
||||||
|
return "console-theme-default";
|
||||||
|
}
|
||||||
|
|
||||||
|
function conditionBadgeClass(conditionValue) {
|
||||||
|
if (conditionValue == null || Number.isNaN(Number(conditionValue))) {
|
||||||
|
return "status-neutral";
|
||||||
|
}
|
||||||
|
const value = Number(conditionValue);
|
||||||
|
if (value >= 9) {
|
||||||
|
return "status-good";
|
||||||
|
}
|
||||||
|
if (value >= 7) {
|
||||||
|
return "status-medium";
|
||||||
|
}
|
||||||
|
if (value >= 5) {
|
||||||
|
return "status-warning";
|
||||||
|
}
|
||||||
|
return "status-low";
|
||||||
|
}
|
||||||
|
|
||||||
function renderSearchResults() {
|
function renderSearchResults() {
|
||||||
if (!quickSearchResults) {
|
if (!quickSearchResults) {
|
||||||
return;
|
return;
|
||||||
@@ -1143,7 +1206,7 @@ function renderGames() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (v2StickyCount) {
|
if (v2StickyCount) {
|
||||||
v2StickyCount.textContent = `${games.length} jeu${games.length > 1 ? "x" : ""}`;
|
v2StickyCount.textContent = `${games.length} jeu${games.length > 1 ? "x" : ""} affiche${games.length > 1 ? "s" : ""}`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1157,6 +1220,7 @@ function renderGames() {
|
|||||||
for (const game of games) {
|
for (const game of games) {
|
||||||
const card = gameCardTemplate.content.cloneNode(true);
|
const card = gameCardTemplate.content.cloneNode(true);
|
||||||
const article = card.querySelector(".game-card");
|
const article = card.querySelector(".game-card");
|
||||||
|
article.classList.add(consoleThemeClass(game.consoleName));
|
||||||
if (inlineEditingGameId === game.id) {
|
if (inlineEditingGameId === game.id) {
|
||||||
article.classList.add("editing");
|
article.classList.add("editing");
|
||||||
}
|
}
|
||||||
@@ -1195,6 +1259,12 @@ function renderGames() {
|
|||||||
} else {
|
} else {
|
||||||
badgesContainer.innerHTML = "";
|
badgesContainer.innerHTML = "";
|
||||||
}
|
}
|
||||||
|
if (game.condition != null && !Number.isNaN(Number(game.condition))) {
|
||||||
|
badgesContainer.insertAdjacentHTML(
|
||||||
|
"beforeend",
|
||||||
|
`<span class="status-badge ${conditionBadgeClass(game.condition)}">Etat ${escapeHtml(String(game.condition))}/10</span>`,
|
||||||
|
);
|
||||||
|
}
|
||||||
const coverEl = card.querySelector(".game-cover");
|
const coverEl = card.querySelector(".game-cover");
|
||||||
const coverUrl = normalizeText(game.coverUrl);
|
const coverUrl = normalizeText(game.coverUrl);
|
||||||
if (coverUrl) {
|
if (coverUrl) {
|
||||||
@@ -1214,10 +1284,18 @@ function renderGames() {
|
|||||||
const deleteBtn = card.querySelector('[data-action="delete"]');
|
const deleteBtn = card.querySelector('[data-action="delete"]');
|
||||||
|
|
||||||
editBtn.dataset.id = game.id;
|
editBtn.dataset.id = game.id;
|
||||||
|
editBtn.textContent = "✏️ Editer";
|
||||||
|
editBtn.title = "Editer ce jeu";
|
||||||
|
editBtn.setAttribute("aria-label", "Editer ce jeu");
|
||||||
toggleBtn.dataset.id = game.id;
|
toggleBtn.dataset.id = game.id;
|
||||||
toggleBtn.textContent = game.loanedTo ? "Marquer comme rendu" : "Marquer comme prete";
|
toggleBtn.textContent = game.loanedTo ? "📥 Rendu" : "📤 Preter";
|
||||||
|
toggleBtn.title = game.loanedTo ? "Marquer comme rendu" : "Marquer comme prete";
|
||||||
|
toggleBtn.setAttribute("aria-label", toggleBtn.title);
|
||||||
|
|
||||||
deleteBtn.dataset.id = game.id;
|
deleteBtn.dataset.id = game.id;
|
||||||
|
deleteBtn.textContent = "🗑️ Supprimer";
|
||||||
|
deleteBtn.title = "Supprimer ce jeu";
|
||||||
|
deleteBtn.setAttribute("aria-label", "Supprimer ce jeu");
|
||||||
|
|
||||||
if (inlineEditingGameId === game.id) {
|
if (inlineEditingGameId === game.id) {
|
||||||
const editor = document.createElement("div");
|
const editor = document.createElement("div");
|
||||||
|
|||||||
@@ -63,7 +63,7 @@
|
|||||||
<main class="app-shell">
|
<main class="app-shell">
|
||||||
<div id="v2StickyBar" class="v2-sticky hidden">
|
<div id="v2StickyBar" class="v2-sticky hidden">
|
||||||
<div class="v2-sticky-title">Vue catalogue</div>
|
<div class="v2-sticky-title">Vue catalogue</div>
|
||||||
<div id="v2StickyCount" class="v2-sticky-count">0 jeu</div>
|
<div id="v2StickyCount" class="v2-sticky-count">0 jeu affiche</div>
|
||||||
<div class="v2-sticky-actions">
|
<div class="v2-sticky-actions">
|
||||||
<button id="v2ToggleFormBtn" type="button" class="btn-secondary">Ajouter</button>
|
<button id="v2ToggleFormBtn" type="button" class="btn-secondary">Ajouter</button>
|
||||||
<button id="v2QuickBackupBtn" type="button" class="btn-secondary">Sauvegarder</button>
|
<button id="v2QuickBackupBtn" type="button" class="btn-secondary">Sauvegarder</button>
|
||||||
|
|||||||
95
styles.css
95
styles.css
@@ -439,6 +439,50 @@ button {
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.console-theme-default {
|
||||||
|
background: #ffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.console-theme-ps5 {
|
||||||
|
background: linear-gradient(165deg, #eef6ff 0%, #ffffff 52%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.console-theme-ps4 {
|
||||||
|
background: linear-gradient(165deg, #f1f6ff 0%, #ffffff 54%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.console-theme-ps3 {
|
||||||
|
background: linear-gradient(165deg, #f6f7ff 0%, #ffffff 54%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.console-theme-ps2 {
|
||||||
|
background: linear-gradient(165deg, #f2f0ff 0%, #ffffff 56%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.console-theme-ps1 {
|
||||||
|
background: linear-gradient(165deg, #f3f5ff 0%, #ffffff 56%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.console-theme-switch {
|
||||||
|
background: linear-gradient(165deg, #fff0f1 0%, #ffffff 56%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.console-theme-xbox {
|
||||||
|
background: linear-gradient(165deg, #ecfff6 0%, #ffffff 56%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.console-theme-wii {
|
||||||
|
background: linear-gradient(165deg, #edf9ff 0%, #ffffff 56%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.console-theme-snes {
|
||||||
|
background: linear-gradient(165deg, #f5f2ff 0%, #ffffff 56%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.console-theme-nes {
|
||||||
|
background: linear-gradient(165deg, #f7f7f7 0%, #ffffff 56%);
|
||||||
|
}
|
||||||
|
|
||||||
.game-cover {
|
.game-cover {
|
||||||
width: 56px;
|
width: 56px;
|
||||||
height: 76px;
|
height: 76px;
|
||||||
@@ -619,6 +663,47 @@ button {
|
|||||||
border-color: #ffe6b9;
|
border-color: #ffe6b9;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.status-badge {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
padding: 0.2rem 0.5rem;
|
||||||
|
border-radius: 999px;
|
||||||
|
font-size: 0.73rem;
|
||||||
|
font-weight: 700;
|
||||||
|
letter-spacing: 0.01em;
|
||||||
|
border: 1px solid transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-badge.status-good {
|
||||||
|
background: #e5f9ef;
|
||||||
|
color: #126948;
|
||||||
|
border-color: #c3efd9;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-badge.status-medium {
|
||||||
|
background: #ebf7ff;
|
||||||
|
color: #135b84;
|
||||||
|
border-color: #cae9fa;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-badge.status-warning {
|
||||||
|
background: #fff6e6;
|
||||||
|
color: #915f12;
|
||||||
|
border-color: #ffe5b6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-badge.status-low {
|
||||||
|
background: #ffecef;
|
||||||
|
color: #9a2d41;
|
||||||
|
border-color: #ffcfd9;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-badge.status-neutral {
|
||||||
|
background: #edf1f7;
|
||||||
|
color: #2f4255;
|
||||||
|
border-color: #d8e1ed;
|
||||||
|
}
|
||||||
|
|
||||||
.toast-container {
|
.toast-container {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
right: 1rem;
|
right: 1rem;
|
||||||
@@ -666,9 +751,9 @@ body.ui-v2 .game-card {
|
|||||||
}
|
}
|
||||||
|
|
||||||
body.ui-v2 .game-card:hover {
|
body.ui-v2 .game-card:hover {
|
||||||
transform: translateY(-2px);
|
transform: translateY(-1px);
|
||||||
border-color: #d3cef9;
|
border-color: #d3cef9;
|
||||||
box-shadow: 0 12px 24px rgba(50, 50, 93, 0.14);
|
box-shadow: 0 8px 16px rgba(50, 50, 93, 0.1);
|
||||||
}
|
}
|
||||||
|
|
||||||
body.ui-v2 .game-cover {
|
body.ui-v2 .game-cover {
|
||||||
@@ -681,6 +766,12 @@ body.ui-v2 .game-actions {
|
|||||||
grid-template-columns: 1fr;
|
grid-template-columns: 1fr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
body.ui-v2 .hero {
|
||||||
|
position: sticky;
|
||||||
|
top: 4.2rem;
|
||||||
|
z-index: 15;
|
||||||
|
}
|
||||||
|
|
||||||
@media (max-width: 1100px) {
|
@media (max-width: 1100px) {
|
||||||
body.ui-v2 .games-list {
|
body.ui-v2 .games-list {
|
||||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||||
|
|||||||
Reference in New Issue
Block a user