document.addEventListener('DOMContentLoaded', function() { const linksList = document.getElementById('links-list'); const modal = document.getElementById('link-modal'); const deleteModal = document.getElementById('delete-modal'); const form = document.getElementById('link-form'); const searchInput = document.getElementById('search-input'); let deleteTargetId = null; async function loadLinks(search = '') { try { const links = await LinkSync.getLinks(search ? { search } : {}); renderLinks(Array.isArray(links) ? links : []); } catch (err) { linksList.innerHTML = `

Failed to load links: ${err.message}

`; } } function renderLinks(links) { if (!links || links.length === 0) { linksList.innerHTML = '

No links found.

'; document.getElementById('empty-add-btn').addEventListener('click', openModal); return; } linksList.innerHTML = `
${links.map(link => ` `).join('')}
Title URL Tags Created Actions
${escapeHtml(link.title)} ${escapeHtml(link.url)}
${(link.tags || []).map(t => `${escapeHtml(t)}`).join('')}
${formatDate(link.created_at)}
`; linksList.querySelectorAll('[data-action="edit"]').forEach(btn => { btn.addEventListener('click', () => editLink(btn.dataset.id)); }); linksList.querySelectorAll('[data-action="delete"]').forEach(btn => { btn.addEventListener('click', () => confirmDelete(btn.dataset.id)); }); } function openModal(link = null) { document.getElementById('modal-title').textContent = link ? 'Edit Link' : 'Add Link'; document.getElementById('link-id').value = link ? link.id : ''; document.getElementById('link-url').value = link ? link.url : ''; document.getElementById('link-title').value = link ? link.title : ''; document.getElementById('link-description').value = link ? (link.description || '') : ''; document.getElementById('link-notes').value = link ? (link.notes || '') : ''; document.getElementById('link-tags').value = link ? (link.tags || []).join(', ') : ''; document.getElementById('link-favicon').value = link ? (link.favicon_url || '') : ''; document.getElementById('link-path').value = link ? (link.path || '') : ''; modal.style.display = 'flex'; } async function editLink(id) { try { const links = await LinkSync.getLinks(); const link = (Array.isArray(links) ? links : []).find(l => l.id === id); if (link) openModal(link); } catch (err) { alert('Failed to load link details'); } } function confirmDelete(id) { deleteTargetId = id; deleteModal.style.display = 'flex'; } function closeModal() { modal.style.display = 'none'; form.reset(); } function closeDeleteModal() { deleteModal.style.display = 'none'; deleteTargetId = null; } document.getElementById('new-link-btn').addEventListener('click', () => openModal()); document.getElementById('modal-close').addEventListener('click', closeModal); document.getElementById('cancel-btn').addEventListener('click', closeModal); document.getElementById('delete-cancel-btn').addEventListener('click', closeDeleteModal); modal.querySelector('.modal-overlay').addEventListener('click', closeModal); deleteModal.querySelector('.modal-overlay').addEventListener('click', closeDeleteModal); form.addEventListener('submit', async function(e) { e.preventDefault(); const saveBtn = document.getElementById('save-btn'); saveBtn.disabled = true; saveBtn.textContent = 'Saving...'; const id = document.getElementById('link-id').value; const tagsRaw = document.getElementById('link-tags').value; const data = { url: document.getElementById('link-url').value, title: document.getElementById('link-title').value, description: document.getElementById('link-description').value || null, notes: document.getElementById('link-notes').value || null, tags: tagsRaw ? tagsRaw.split(',').map(t => t.trim()).filter(t => t) : [], favicon_url: document.getElementById('link-favicon').value || null, path: document.getElementById('link-path').value || null, }; try { if (id) { await LinkSync.updateLink(id, data); } else { await LinkSync.createLink(data); } closeModal(); loadLinks(searchInput.value); } catch (err) { alert('Failed to save link: ' + err.message); } finally { saveBtn.disabled = false; saveBtn.textContent = 'Save'; } }); document.getElementById('confirm-delete-btn').addEventListener('click', async function() { if (!deleteTargetId) return; try { await LinkSync.deleteLink(deleteTargetId); closeDeleteModal(); loadLinks(searchInput.value); } catch (err) { alert('Failed to delete link: ' + err.message); } }); document.getElementById('search-btn').addEventListener('click', () => loadLinks(searchInput.value)); searchInput.addEventListener('keypress', function(e) { if (e.key === 'Enter') loadLinks(searchInput.value); }); const urlParams = new URLSearchParams(window.location.search); if (urlParams.get('action') === 'new') { openModal(); } loadLinks(); function escapeHtml(str) { if (!str) return ''; const div = document.createElement('div'); div.textContent = str; return div.innerHTML; } function formatDate(dateStr) { if (!dateStr) return '-'; const d = new Date(dateStr); return d.toLocaleDateString(); } });