document.addEventListener('DOMContentLoaded', function() { const collectionsList = document.getElementById('collections-list'); const modal = document.getElementById('collection-modal'); const deleteModal = document.getElementById('delete-collection-modal'); const form = document.getElementById('collection-form'); const typeSelect = document.getElementById('collection-type'); const querySection = document.getElementById('query-builder-section'); const queryInput = document.getElementById('collection-query'); const previewBtn = document.getElementById('preview-query-btn'); const queryStatus = document.getElementById('query-status'); const previewResults = document.getElementById('query-preview-results'); let deleteTargetId = null; typeSelect.addEventListener('change', function() { querySection.style.display = this.value === 'dynamic' ? '' : 'none'; if (this.value !== 'dynamic') { queryInput.value = ''; previewResults.style.display = 'none'; queryStatus.textContent = ''; } }); async function loadCollections() { try { const collections = await LinkSync.getCollections(); renderCollections(Array.isArray(collections) ? collections : []); } catch (err) { collectionsList.innerHTML = `

Failed to load collections: ${err.message}

`; } } function renderCollections(collections) { if (!collections || collections.length === 0) { collectionsList.innerHTML = '

No collections found.

'; document.getElementById('empty-add-col-btn').addEventListener('click', openCollectionModal); return; } collectionsList.innerHTML = collections.map(col => `

${escapeHtml(col.name)}

${escapeHtml(col.description || 'No description')}

${col.query_type} ${col.is_public ? 'Public' : 'Private'}
${col.query_type === 'dynamic' && col.query_expression ? `
${escapeHtml(col.query_expression.expression || '')}
` : ''}
`).join(''); collectionsList.querySelectorAll('[data-action="edit"]').forEach(btn => { btn.addEventListener('click', () => editCollection(btn.dataset.id)); }); collectionsList.querySelectorAll('[data-action="delete"]').forEach(btn => { btn.addEventListener('click', () => confirmDeleteCollection(btn.dataset.id)); }); } function openCollectionModal(col = null) { document.getElementById('collection-modal-title').textContent = col ? 'Edit Collection' : 'Create Collection'; document.getElementById('collection-id').value = (col && col.id) ? col.id : ''; document.getElementById('collection-name').value = col ? col.name : ''; document.getElementById('collection-description').value = col ? (col.description || '') : ''; document.getElementById('collection-type').value = col ? col.query_type : 'static'; document.getElementById('collection-public').checked = col ? col.is_public : false; if (col && col.query_type === 'dynamic' && col.query_expression) { queryInput.value = col.query_expression.expression || ''; querySection.style.display = ''; } else { queryInput.value = ''; querySection.style.display = 'none'; } previewResults.style.display = 'none'; queryStatus.textContent = ''; modal.style.display = 'flex'; } async function editCollection(id) { try { const collections = await LinkSync.getCollections(); const col = (Array.isArray(collections) ? collections : []).find(c => c.id === id); if (col) openCollectionModal(col); } catch (err) { alert('Failed to load collection details'); } } function confirmDeleteCollection(id) { deleteTargetId = id; deleteModal.style.display = 'flex'; } function closeModal() { modal.style.display = 'none'; form.reset(); querySection.style.display = 'none'; previewResults.style.display = 'none'; queryStatus.textContent = ''; } function closeDeleteModal() { deleteModal.style.display = 'none'; deleteTargetId = null; } document.getElementById('new-collection-btn').addEventListener('click', () => openCollectionModal()); document.getElementById('collection-modal-close').addEventListener('click', closeModal); document.getElementById('collection-cancel-btn').addEventListener('click', closeModal); document.getElementById('delete-collection-cancel-btn').addEventListener('click', closeDeleteModal); modal.querySelector('.modal-overlay').addEventListener('click', closeModal); deleteModal.querySelector('.modal-overlay').addEventListener('click', closeDeleteModal); previewBtn.addEventListener('click', async function() { const expression = queryInput.value.trim(); if (!expression) { queryStatus.textContent = 'Enter a query expression'; queryStatus.style.color = 'var(--warning)'; return; } queryStatus.textContent = 'Loading...'; queryStatus.style.color = 'var(--text-muted)'; try { const results = await LinkSync.previewQuery(expression); const count = Array.isArray(results) ? results.length : 0; queryStatus.textContent = `${count} result${count !== 1 ? 's' : ''}`; queryStatus.style.color = 'var(--success)'; if (count > 0) { previewResults.innerHTML = `
${count} matching links:
` + results.slice(0, 10).map(link => `
${escapeHtml(link.title)}
`).join('') + (count > 10 ? `
...and ${count - 10} more
` : ''); previewResults.style.display = ''; } else { previewResults.innerHTML = '

No matching links

'; previewResults.style.display = ''; } } catch (err) { queryStatus.textContent = err.message; queryStatus.style.color = 'var(--error)'; previewResults.style.display = 'none'; } }); form.addEventListener('submit', async function(e) { e.preventDefault(); const saveBtn = document.getElementById('collection-save-btn'); saveBtn.disabled = true; saveBtn.textContent = 'Saving...'; const id = document.getElementById('collection-id').value; const isEdit = id && id !== '' && id !== 'undefined'; const queryType = document.getElementById('collection-type').value; const data = { name: document.getElementById('collection-name').value, description: document.getElementById('collection-description').value || null, query_type: queryType, is_public: document.getElementById('collection-public').checked, }; if (queryType === 'dynamic') { const expression = queryInput.value.trim(); if (expression) { data.query_expression = { expression }; } } try { if (isEdit) { await LinkSync.updateCollection(id, data); } else { await LinkSync.createCollection(data); } closeModal(); loadCollections(); } catch (err) { alert('Failed to save collection: ' + err.message); } finally { saveBtn.disabled = false; saveBtn.textContent = 'Save'; } }); document.getElementById('confirm-delete-collection-btn').addEventListener('click', async function() { if (!deleteTargetId) return; try { await LinkSync.deleteCollection(deleteTargetId); closeDeleteModal(); loadCollections(); } catch (err) { alert('Failed to delete collection: ' + err.message); } }); const urlParams = new URLSearchParams(window.location.search); if (urlParams.get('action') === 'new') { openCollectionModal(); } loadCollections(); function escapeHtml(str) { if (!str) return ''; const div = document.createElement('div'); div.textContent = str; return div.innerHTML; } });