From 3c372878a3f74c91c55408201bd813962823a6c8 Mon Sep 17 00:00:00 2001 From: 0x1d Date: Sat, 15 Nov 2025 19:21:40 +0100 Subject: [PATCH] feat: UX improvements for list handling --- public/app.js | 41 ++++++++++++++++++------------------ public/index.html | 4 ---- public/styles.css | 53 ----------------------------------------------- 3 files changed, 21 insertions(+), 77 deletions(-) diff --git a/public/app.js b/public/app.js index 4e2e752..26e89d0 100644 --- a/public/app.js +++ b/public/app.js @@ -25,8 +25,6 @@ const createListBtn = document.getElementById('createListBtn'); const listSelectionOverlay = document.getElementById('listSelectionOverlay'); const listSelectionBody = document.getElementById('listSelectionBody'); const closeListSelection = document.getElementById('closeListSelection'); -const saveListSelection = document.getElementById('saveListSelection'); -const cancelListSelection = document.getElementById('cancelListSelection'); const listFilterWrapper = document.getElementById('listFilterWrapper'); const listFilterChips = document.getElementById('listFilterChips'); const clearListFilters = document.getElementById('clearListFilters'); @@ -717,13 +715,6 @@ function setupListsManagement() { currentLinkForListSelection = null; }); - cancelListSelection.addEventListener('click', () => { - listSelectionOverlay.classList.remove('show'); - currentLinkForListSelection = null; - }); - - saveListSelection.addEventListener('click', handleSaveListSelection); - // Close on backdrop click listSelectionOverlay.addEventListener('click', (e) => { if (e.target === listSelectionOverlay) { @@ -976,20 +967,27 @@ function handleAddToLists(linkId) { ${escapeHtml(list.name)} `).join(''); + + // Add event listeners to checkboxes for auto-save + listSelectionBody.querySelectorAll('input[type="checkbox"]').forEach(checkbox => { + checkbox.addEventListener('change', () => { + handleCheckboxChange(linkId); + }); + }); } listSelectionOverlay.classList.add('show'); } -// Handle save list selection -async function handleSaveListSelection() { - if (!currentLinkForListSelection) return; +// Handle checkbox change (auto-save) +async function handleCheckboxChange(linkId) { + if (!linkId) return; const checkboxes = listSelectionBody.querySelectorAll('input[type="checkbox"]:checked'); const selectedListIds = Array.from(checkboxes).map(cb => cb.value); try { - const response = await fetch(`${API_BASE}/${currentLinkForListSelection}/lists`, { + const response = await fetch(`${API_BASE}/${linkId}/lists`, { method: 'PATCH', headers: { 'Content-Type': 'application/json' @@ -1004,20 +1002,23 @@ async function handleSaveListSelection() { } // Update local array - const linkIndex = allLinks.findIndex(l => l.id === currentLinkForListSelection); + const linkIndex = allLinks.findIndex(l => l.id === linkId); if (linkIndex !== -1) { allLinks[linkIndex].listIds = selectedListIds; } - // Update display - displayLinks(getFilteredLinks()); - - listSelectionOverlay.classList.remove('show'); - currentLinkForListSelection = null; - showMessage('Link lists updated successfully!', 'success'); + // No need to refresh the display - the link is already visible + // Only update if the link's visibility might have changed due to list filters + // But since we're just assigning lists, not changing visibility, we skip the refresh } catch (error) { showMessage('Failed to update link lists', 'error'); console.error('Error updating link lists:', error); + // Revert checkbox state on error + const link = allLinks.find(l => l.id === linkId); + const linkListIds = link?.listIds || []; + listSelectionBody.querySelectorAll('input[type="checkbox"]').forEach(checkbox => { + checkbox.checked = linkListIds.includes(checkbox.value); + }); } } diff --git a/public/index.html b/public/index.html index 54aadf6..fa009c0 100644 --- a/public/index.html +++ b/public/index.html @@ -188,10 +188,6 @@
- diff --git a/public/styles.css b/public/styles.css index 584aa37..d5bf225 100644 --- a/public/styles.css +++ b/public/styles.css @@ -1694,50 +1694,6 @@ body { flex: 1; } -.list-selection-footer { - display: flex; - gap: 0.75rem; - padding: 1.5rem; - border-top: 1px solid var(--border); - justify-content: flex-end; -} - -.btn-save-lists, -.btn-cancel-lists { - padding: 0.75rem 1.5rem; - border-radius: 8px; - cursor: pointer; - font-weight: 600; - transition: all 0.3s ease; - border: none; -} - -.btn-save-lists { - background: linear-gradient(135deg, var(--primary-color), var(--secondary-color)); - color: white; - box-shadow: 0 2px 8px rgba(99, 102, 241, 0.3); -} - -.btn-save-lists:hover { - transform: translateY(-1px); - box-shadow: 0 6px 16px rgba(99, 102, 241, 0.4); -} - -.btn-save-lists:active { - transform: translateY(0); -} - -.btn-cancel-lists { - background: transparent; - color: var(--text-secondary); - border: 1px solid var(--border); -} - -.btn-cancel-lists:hover { - background: var(--surface-light); - border-color: var(--primary-color); - color: var(--primary-color); -} /* Add to List Button in Link Cards */ .add-to-list-btn { @@ -1789,15 +1745,6 @@ body { flex-direction: column; } - .list-selection-footer { - flex-direction: column; - } - - .btn-save-lists, - .btn-cancel-lists { - width: 100%; - } - .list-item { gap: 0.5rem; padding: 0.5rem;