Replace details/summary expanders with toggle buttons for list/deck forms
New list, Bulk import, New deck, and Bulk import decks are now proper buttons. Clicking one toggles the form open (highlighted blue) and clicking again or cancelling closes it. Only one form open at a time. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
1 parent
4613946cea
commit
2d663f6964
3 files changed
+64
-16
No files matched your search
+22
-14
@@ -305,8 +305,12 @@
|
|||||||
<div id="results-area"></div>
|
<div id="results-area"></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="panel-col">
|
<div class="panel-col">
|
||||||
<details id="list-editor-details">
|
<div class="toggle-btns">
|
||||||
<summary id="list-editor-title">New list</summary>
|
<button type="button" id="list-new-btn">+ New list</button>
|
||||||
|
<button type="button" id="list-bulk-btn" class="secondary">⬆ Bulk import</button>
|
||||||
|
</div>
|
||||||
|
<div id="list-editor-section" hidden>
|
||||||
|
<h3 id="list-editor-title" class="section-form-title">New list</h3>
|
||||||
<form id="list-form" class="admin-card">
|
<form id="list-form" class="admin-card">
|
||||||
<input type="hidden" id="list-id">
|
<input type="hidden" id="list-id">
|
||||||
<input id="list-name" placeholder="List name (e.g. Week of July 6)" aria-label="List name">
|
<input id="list-name" placeholder="List name (e.g. Week of July 6)" aria-label="List name">
|
||||||
@@ -316,12 +320,12 @@
|
|||||||
placeholder="One word per line. Paste any list from your curriculum! Add an example sentence with | receive | Did you receive my letter? Or just a plain list: because enough friend"></textarea>
|
placeholder="One word per line. Paste any list from your curriculum! Add an example sentence with | receive | Did you receive my letter? Or just a plain list: because enough friend"></textarea>
|
||||||
<div class="row-actions">
|
<div class="row-actions">
|
||||||
<button type="submit">Save list</button>
|
<button type="submit">Save list</button>
|
||||||
<button type="button" id="list-cancel" class="secondary">Clear</button>
|
<button type="button" id="list-cancel" class="secondary">Cancel</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</details>
|
</div>
|
||||||
<details id="list-bulk-details">
|
<div id="list-bulk-section" hidden>
|
||||||
<summary>Bulk import lists</summary>
|
<h3 class="section-form-title">Bulk import lists</h3>
|
||||||
<div class="admin-card">
|
<div class="admin-card">
|
||||||
<p class="hint" style="margin:0 0 0.5rem">Start each list with <strong># List name</strong> on its own line, then words below it. Optional group applies to all imported lists.</p>
|
<p class="hint" style="margin:0 0 0.5rem">Start each list with <strong># List name</strong> on its own line, then words below it. Optional group applies to all imported lists.</p>
|
||||||
<input id="list-bulk-group" placeholder="Group (e.g. Bible 6) — optional" aria-label="Group for bulk import" list="list-groups-datalist">
|
<input id="list-bulk-group" placeholder="Group (e.g. Bible 6) — optional" aria-label="Group for bulk import" list="list-groups-datalist">
|
||||||
@@ -333,7 +337,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<p id="list-bulk-status" class="hint" style="margin:0.4rem 0 0"></p>
|
<p id="list-bulk-status" class="hint" style="margin:0.4rem 0 0"></p>
|
||||||
</div>
|
</div>
|
||||||
</details>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
@@ -346,8 +350,12 @@
|
|||||||
<div id="deck-rows"></div>
|
<div id="deck-rows"></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="panel-col">
|
<div class="panel-col">
|
||||||
<details id="deck-editor-details">
|
<div class="toggle-btns">
|
||||||
<summary id="deck-editor-title">New deck</summary>
|
<button type="button" id="deck-new-btn">+ New deck</button>
|
||||||
|
<button type="button" id="deck-bulk-btn" class="secondary">⬆ Bulk import</button>
|
||||||
|
</div>
|
||||||
|
<div id="deck-editor-section" hidden>
|
||||||
|
<h3 id="deck-editor-title" class="section-form-title">New deck</h3>
|
||||||
<form id="deck-form" class="admin-card">
|
<form id="deck-form" class="admin-card">
|
||||||
<input type="hidden" id="deck-id">
|
<input type="hidden" id="deck-id">
|
||||||
<input id="deck-name" placeholder="Deck name (e.g. State Capitals)" aria-label="Deck name">
|
<input id="deck-name" placeholder="Deck name (e.g. State Capitals)" aria-label="Deck name">
|
||||||
@@ -357,12 +365,12 @@
|
|||||||
placeholder="One card per line: front | back What is the capital of Ohio? | Columbus"></textarea>
|
placeholder="One card per line: front | back What is the capital of Ohio? | Columbus"></textarea>
|
||||||
<div class="row-actions">
|
<div class="row-actions">
|
||||||
<button type="submit">Save deck</button>
|
<button type="submit">Save deck</button>
|
||||||
<button type="button" id="deck-cancel" class="secondary">Clear</button>
|
<button type="button" id="deck-cancel" class="secondary">Cancel</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</details>
|
</div>
|
||||||
<details id="deck-bulk-details">
|
<div id="deck-bulk-section" hidden>
|
||||||
<summary>Bulk import decks</summary>
|
<h3 class="section-form-title">Bulk import decks</h3>
|
||||||
<div class="admin-card">
|
<div class="admin-card">
|
||||||
<p class="hint" style="margin:0 0 0.5rem">Start each deck with <strong># Deck name</strong> on its own line, then cards below as <strong>front | back</strong>. Optional group applies to all imported decks.</p>
|
<p class="hint" style="margin:0 0 0.5rem">Start each deck with <strong># Deck name</strong> on its own line, then cards below as <strong>front | back</strong>. Optional group applies to all imported decks.</p>
|
||||||
<input id="deck-bulk-group" placeholder="Group (e.g. Bible 6) — optional" aria-label="Group for bulk import" list="deck-groups-datalist">
|
<input id="deck-bulk-group" placeholder="Group (e.g. Bible 6) — optional" aria-label="Group for bulk import" list="deck-groups-datalist">
|
||||||
@@ -374,7 +382,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<p id="deck-bulk-status" class="hint" style="margin:0.4rem 0 0"></p>
|
<p id="deck-bulk-status" class="hint" style="margin:0.4rem 0 0"></p>
|
||||||
</div>
|
</div>
|
||||||
</details>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|||||||
+37
-2
@@ -1368,7 +1368,7 @@ function renderLists(lists) {
|
|||||||
return w.word;
|
return w.word;
|
||||||
}).join('\n');
|
}).join('\n');
|
||||||
$('#list-editor-title').textContent = list.builtin ? 'New list (from copy)' : `Editing: ${list.name}`;
|
$('#list-editor-title').textContent = list.builtin ? 'New list (from copy)' : `Editing: ${list.name}`;
|
||||||
$('#list-editor-details').open = true;
|
showSection('list', 'editor');
|
||||||
$('#list-name').scrollIntoView({ behavior: 'smooth' });
|
$('#list-name').scrollIntoView({ behavior: 'smooth' });
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
@@ -1398,6 +1398,7 @@ $('#list-form').addEventListener('submit', async (e) => {
|
|||||||
if (id) await api(`/api/lists/${id}`, { method: 'PUT', body: { name, words, groupName } });
|
if (id) await api(`/api/lists/${id}`, { method: 'PUT', body: { name, words, groupName } });
|
||||||
else await api('/api/lists', { method: 'POST', body: { name, words, groupName } });
|
else await api('/api/lists', { method: 'POST', body: { name, words, groupName } });
|
||||||
clearListForm();
|
clearListForm();
|
||||||
|
hideSections('list');
|
||||||
msg('List saved.');
|
msg('List saved.');
|
||||||
loadSpelling();
|
loadSpelling();
|
||||||
});
|
});
|
||||||
@@ -1408,8 +1409,31 @@ function clearListForm() {
|
|||||||
$('#list-group').value = '';
|
$('#list-group').value = '';
|
||||||
$('#list-words').value = '';
|
$('#list-words').value = '';
|
||||||
$('#list-editor-title').textContent = 'New list';
|
$('#list-editor-title').textContent = 'New list';
|
||||||
|
hideSections('list');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function showSection(type, which) {
|
||||||
|
$(`#${type}-editor-section`).hidden = which !== 'editor';
|
||||||
|
$(`#${type}-bulk-section`).hidden = which !== 'bulk';
|
||||||
|
$(`#${type}-new-btn`).classList.toggle('active', which === 'editor');
|
||||||
|
$(`#${type}-bulk-btn`).classList.toggle('active', which === 'bulk');
|
||||||
|
}
|
||||||
|
function hideSections(type) {
|
||||||
|
$(`#${type}-editor-section`).hidden = true;
|
||||||
|
$(`#${type}-bulk-section`).hidden = true;
|
||||||
|
$(`#${type}-new-btn`).classList.remove('active');
|
||||||
|
$(`#${type}-bulk-btn`).classList.remove('active');
|
||||||
|
}
|
||||||
|
|
||||||
|
$('#list-new-btn').addEventListener('click', () => {
|
||||||
|
if ($('#list-editor-section').hidden) showSection('list', 'editor');
|
||||||
|
else hideSections('list');
|
||||||
|
});
|
||||||
|
$('#list-bulk-btn').addEventListener('click', () => {
|
||||||
|
if ($('#list-bulk-section').hidden) showSection('list', 'bulk');
|
||||||
|
else hideSections('list');
|
||||||
|
});
|
||||||
|
|
||||||
function parseBulkSections(text) {
|
function parseBulkSections(text) {
|
||||||
const sections = [];
|
const sections = [];
|
||||||
let current = null;
|
let current = null;
|
||||||
@@ -1560,7 +1584,7 @@ async function loadDecks() {
|
|||||||
$('#deck-group').value = deck.group_name || '';
|
$('#deck-group').value = deck.group_name || '';
|
||||||
$('#deck-cards').value = deck.cards.map((c) => `${c.front} | ${c.back}`).join('\n');
|
$('#deck-cards').value = deck.cards.map((c) => `${c.front} | ${c.back}`).join('\n');
|
||||||
$('#deck-editor-title').textContent = deck.builtin ? 'New deck (from copy)' : `Editing: ${deck.name}`;
|
$('#deck-editor-title').textContent = deck.builtin ? 'New deck (from copy)' : `Editing: ${deck.name}`;
|
||||||
$('#deck-editor-details').open = true;
|
showSection('deck', 'editor');
|
||||||
$('#deck-name').scrollIntoView({ behavior: 'smooth' });
|
$('#deck-name').scrollIntoView({ behavior: 'smooth' });
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
@@ -1590,6 +1614,7 @@ $('#deck-form').addEventListener('submit', async (e) => {
|
|||||||
if (id) await api(`/api/decks/${id}`, { method: 'PUT', body: { name, cards, groupName } });
|
if (id) await api(`/api/decks/${id}`, { method: 'PUT', body: { name, cards, groupName } });
|
||||||
else await api('/api/decks', { method: 'POST', body: { name, cards, groupName } });
|
else await api('/api/decks', { method: 'POST', body: { name, cards, groupName } });
|
||||||
clearDeckForm();
|
clearDeckForm();
|
||||||
|
hideSections('deck');
|
||||||
msg('Deck saved.');
|
msg('Deck saved.');
|
||||||
loadDecks();
|
loadDecks();
|
||||||
});
|
});
|
||||||
@@ -1600,8 +1625,18 @@ function clearDeckForm() {
|
|||||||
$('#deck-group').value = '';
|
$('#deck-group').value = '';
|
||||||
$('#deck-cards').value = '';
|
$('#deck-cards').value = '';
|
||||||
$('#deck-editor-title').textContent = 'New deck';
|
$('#deck-editor-title').textContent = 'New deck';
|
||||||
|
hideSections('deck');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$('#deck-new-btn').addEventListener('click', () => {
|
||||||
|
if ($('#deck-editor-section').hidden) showSection('deck', 'editor');
|
||||||
|
else hideSections('deck');
|
||||||
|
});
|
||||||
|
$('#deck-bulk-btn').addEventListener('click', () => {
|
||||||
|
if ($('#deck-bulk-section').hidden) showSection('deck', 'bulk');
|
||||||
|
else hideSections('deck');
|
||||||
|
});
|
||||||
|
|
||||||
$('#deck-bulk-save').addEventListener('click', async () => {
|
$('#deck-bulk-save').addEventListener('click', async () => {
|
||||||
const groupName = $('#deck-bulk-group').value.trim();
|
const groupName = $('#deck-bulk-group').value.trim();
|
||||||
const sections = parseBulkSections($('#deck-bulk-text').value);
|
const sections = parseBulkSections($('#deck-bulk-text').value);
|
||||||
|
|||||||
@@ -338,6 +338,11 @@ table.results tr:nth-child(even) td { background: #faf7ee; }
|
|||||||
.admin-main h2 { margin: 1.5rem 0 0.5rem; font-size: 1.15rem; }
|
.admin-main h2 { margin: 1.5rem 0 0.5rem; font-size: 1.15rem; }
|
||||||
.panel { text-align: left; }
|
.panel { text-align: left; }
|
||||||
|
|
||||||
|
/* ---------- toggle button rows (new/bulk import) ---------- */
|
||||||
|
.toggle-btns { display: flex; gap: 0.5rem; flex-wrap: wrap; margin-bottom: 0.75rem; }
|
||||||
|
.toggle-btns button.active { background: var(--accent); color: #fff; }
|
||||||
|
.section-form-title { font-size: 1rem; font-weight: 700; margin: 0 0 0; color: var(--ink); }
|
||||||
|
|
||||||
/* 2-column layout for wide screens */
|
/* 2-column layout for wide screens */
|
||||||
.panel-cols { display: flex; flex-direction: column; gap: 1.5rem; }
|
.panel-cols { display: flex; flex-direction: column; gap: 1.5rem; }
|
||||||
.panel-col { min-width: 0; }
|
.panel-col { min-width: 0; }
|
||||||
|
|||||||
Reference in new issue
Block a user