Archive added
This commit is contained in:
parent
01a38ba145
commit
467f405f32
3 changed files with 97 additions and 25 deletions
96
app.js
96
app.js
|
|
@ -24,6 +24,9 @@ const clearAllButton = document.querySelector("#clear-all");
|
|||
const routeCount = document.querySelector("#route-count");
|
||||
const emptyState = document.querySelector("#empty-state");
|
||||
const routesList = document.querySelector("#routes-list");
|
||||
const archiveSection = document.querySelector("#archive-section");
|
||||
const archiveCount = document.querySelector("#archive-count");
|
||||
const archivedRoutesList = document.querySelector("#archived-routes-list");
|
||||
const template = document.querySelector("#route-card-template");
|
||||
|
||||
let routes = sortRoutes(loadRoutes());
|
||||
|
|
@ -35,6 +38,7 @@ form.addEventListener("submit", saveRoute);
|
|||
cancelEditButton.addEventListener("click", resetForm);
|
||||
clearAllButton?.addEventListener("click", removeAllRoutes);
|
||||
routesList.addEventListener("click", handleRouteAction);
|
||||
archivedRoutesList.addEventListener("click", handleRouteAction);
|
||||
document.addEventListener("click", closeMenusOnOutsideClick);
|
||||
document.addEventListener("keydown", closeMenusOnEscape);
|
||||
|
||||
|
|
@ -93,8 +97,8 @@ function storeRoutes() {
|
|||
|
||||
function sortRoutes(routeList) {
|
||||
return [...routeList].sort((a, b) => {
|
||||
const dateA = a.date || "0000-00-00";
|
||||
const dateB = b.date || "0000-00-00";
|
||||
const dateA = a.date || "9999-99-99";
|
||||
const dateB = b.date || "9999-99-99";
|
||||
|
||||
if (dateA !== dateB) {
|
||||
return dateA.localeCompare(dateB);
|
||||
|
|
@ -116,6 +120,7 @@ async function saveRoute(event) {
|
|||
name: nameInput.value.trim(),
|
||||
link: linkInput.value.trim(),
|
||||
date: dateInput.value,
|
||||
archived: existingRoute?.archived || false,
|
||||
picture: existingRoute?.picture || "",
|
||||
description: descriptionInput.value.trim(),
|
||||
updatedAt: new Date().toISOString(),
|
||||
|
|
@ -153,35 +158,56 @@ async function saveRoute(event) {
|
|||
|
||||
function renderRoutes() {
|
||||
routesList.innerHTML = "";
|
||||
archivedRoutesList.innerHTML = "";
|
||||
|
||||
const activeRoutes = routes.filter((route) => !route.archived);
|
||||
const archivedRoutes = routes.filter((route) => route.archived);
|
||||
|
||||
routeCount.textContent = activeRoutes.length === 1 ? "1 route saved." : `${activeRoutes.length} routes saved.`;
|
||||
emptyState.classList.toggle("hidden", activeRoutes.length > 0);
|
||||
archiveSection.hidden = archivedRoutes.length === 0;
|
||||
archiveCount.textContent = archivedRoutes.length;
|
||||
|
||||
if (!archivedRoutes.length) {
|
||||
archiveSection.open = false;
|
||||
}
|
||||
|
||||
routeCount.textContent = routes.length === 1 ? "1 route saved." : `${routes.length} routes saved.`;
|
||||
emptyState.classList.toggle("hidden", routes.length > 0);
|
||||
if (clearAllButton) {
|
||||
clearAllButton.hidden = routes.length === 0;
|
||||
}
|
||||
|
||||
for (const route of routes) {
|
||||
const card = template.content.firstElementChild.cloneNode(true);
|
||||
const image = card.querySelector(".route-image");
|
||||
const meta = card.querySelector(".route-meta");
|
||||
const title = card.querySelector(".route-title");
|
||||
const description = card.querySelector(".route-description");
|
||||
|
||||
card.dataset.id = route.id;
|
||||
meta.textContent = route.date ? formatDate(route.date) : "";
|
||||
meta.hidden = !route.date;
|
||||
title.textContent = route.name;
|
||||
title.href = route.link;
|
||||
description.textContent = route.description;
|
||||
description.hidden = !route.description;
|
||||
|
||||
if (route.picture) {
|
||||
image.hidden = false;
|
||||
image.style.backgroundImage = `url("${cssUrlEscape(route.picture)}")`;
|
||||
}
|
||||
|
||||
routesList.append(card);
|
||||
for (const route of activeRoutes) {
|
||||
routesList.append(createRouteCard(route));
|
||||
}
|
||||
|
||||
for (const route of archivedRoutes) {
|
||||
archivedRoutesList.append(createRouteCard(route));
|
||||
}
|
||||
}
|
||||
|
||||
function createRouteCard(route) {
|
||||
const card = template.content.firstElementChild.cloneNode(true);
|
||||
const image = card.querySelector(".route-image");
|
||||
const meta = card.querySelector(".route-meta");
|
||||
const title = card.querySelector(".route-title");
|
||||
const description = card.querySelector(".route-description");
|
||||
const archiveButton = card.querySelector(".archive-route");
|
||||
|
||||
card.dataset.id = route.id;
|
||||
meta.textContent = route.date ? formatDate(route.date) : "";
|
||||
meta.hidden = !route.date;
|
||||
title.textContent = route.name;
|
||||
title.href = route.link;
|
||||
description.textContent = route.description;
|
||||
description.hidden = !route.description;
|
||||
archiveButton.textContent = route.archived ? "Unarchive" : "Archive";
|
||||
|
||||
if (route.picture) {
|
||||
image.hidden = false;
|
||||
image.style.backgroundImage = `url("${cssUrlEscape(route.picture)}")`;
|
||||
}
|
||||
|
||||
return card;
|
||||
}
|
||||
|
||||
function closeMenusOnOutsideClick(event) {
|
||||
|
|
@ -227,6 +253,26 @@ function handleRouteAction(event) {
|
|||
if (button.classList.contains("share-route")) {
|
||||
shareRoute(route);
|
||||
}
|
||||
|
||||
if (button.classList.contains("archive-route")) {
|
||||
toggleArchive(route.id);
|
||||
}
|
||||
}
|
||||
|
||||
function toggleArchive(id) {
|
||||
const route = routes.find((item) => item.id === id);
|
||||
if (!route) {
|
||||
return;
|
||||
}
|
||||
|
||||
route.archived = !route.archived;
|
||||
routes = sortRoutes(routes);
|
||||
storeRoutes();
|
||||
renderRoutes();
|
||||
|
||||
if (idInput.value === id) {
|
||||
resetForm();
|
||||
}
|
||||
}
|
||||
|
||||
function startAddRoute() {
|
||||
|
|
|
|||
|
|
@ -83,6 +83,11 @@
|
|||
</div>
|
||||
|
||||
<div id="routes-list" class="routes-list" aria-live="polite"></div>
|
||||
|
||||
<details id="archive-section" class="archive-section" hidden>
|
||||
<summary>Archived (<span id="archive-count">0</span>)</summary>
|
||||
<div id="archived-routes-list" class="routes-list archived-routes-list" aria-live="polite"></div>
|
||||
</details>
|
||||
</section>
|
||||
</main>
|
||||
</div>
|
||||
|
|
@ -99,6 +104,7 @@
|
|||
<div class="menu-items">
|
||||
<button type="button" class="share-route">Share</button>
|
||||
<button type="button" class="edit-route">Edit</button>
|
||||
<button type="button" class="archive-route">Archive</button>
|
||||
<button type="button" class="danger remove-route">Delete</button>
|
||||
</div>
|
||||
</details>
|
||||
|
|
|
|||
20
styles.css
20
styles.css
|
|
@ -336,6 +336,26 @@ textarea:focus {
|
|||
background: var(--danger-dark);
|
||||
}
|
||||
|
||||
.archive-section {
|
||||
margin-top: 1rem;
|
||||
}
|
||||
|
||||
.archive-section > summary {
|
||||
padding: 0.85rem 0.2rem;
|
||||
color: var(--muted);
|
||||
font-weight: 800;
|
||||
cursor: pointer;
|
||||
list-style-position: inside;
|
||||
}
|
||||
|
||||
.archived-routes-list {
|
||||
margin-top: 0.5rem;
|
||||
}
|
||||
|
||||
.archived-routes-list .route-card {
|
||||
opacity: 0.82;
|
||||
}
|
||||
|
||||
.empty-state {
|
||||
padding: 1.5rem 1rem;
|
||||
text-align: center;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue