feat(admin): replace browser confirm() dialogs with native <dialog> modal
- Add styled <dialog id="confirm-dialog"> to base_admin.html — frosted
backdrop, rounded card, Cancel / Confirm buttons
- Add confirmAction(message, form) JS helper — clones OK button to
avoid listener accumulation, calls form.submit() on confirm
- Replace all 5 onclick="return confirm()" across templates with
type="button" + confirmAction(..., this.closest('form'))
· articles.html — Rebuild All
· template_detail.html — Regenerate
· generate_form.html — Generate Articles
· scenario_results.html — Delete scenario
· audience_contacts.html — Remove contact
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -18,7 +18,7 @@
|
||||
<a href="{{ url_for('admin.article_new') }}" class="btn btn-sm">New Article</a>
|
||||
<form method="post" action="{{ url_for('admin.rebuild_all') }}" class="m-0" style="display:inline">
|
||||
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
|
||||
<button type="submit" class="btn-outline btn-sm" onclick="return confirm('Rebuild all articles?')">Rebuild All</button>
|
||||
<button type="button" class="btn-outline btn-sm" onclick="confirmAction('Rebuild all articles? This will re-render every article from its template.', this.closest('form'))">Rebuild All</button>
|
||||
</form>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
<form method="post" action="{{ url_for('admin.audience_contact_remove', audience_id=audience.audience_id) }}" style="display:inline">
|
||||
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
|
||||
<input type="hidden" name="contact_id" value="{{ c.id if c.id is defined else (c.get('id', '') if c is mapping else '') }}">
|
||||
<button type="submit" class="btn-outline btn-sm" style="color:#DC2626" onclick="return confirm('Remove this contact?')">Remove</button>
|
||||
<button type="button" class="btn-outline btn-sm" style="color:#DC2626" onclick="confirmAction('Remove this contact from the audience?', this.closest('form'))">Remove</button>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
@@ -27,6 +27,14 @@
|
||||
|
||||
.admin-main { flex: 1; padding: 2rem; overflow-y: auto; }
|
||||
|
||||
#confirm-dialog {
|
||||
border: none; border-radius: 12px; padding: 1.5rem; max-width: 380px; width: 90%;
|
||||
box-shadow: 0 20px 60px rgba(0,0,0,0.15), 0 4px 16px rgba(0,0,0,0.08);
|
||||
}
|
||||
#confirm-dialog::backdrop { background: rgba(15,23,42,0.45); backdrop-filter: blur(3px); }
|
||||
#confirm-dialog p { margin: 0 0 1.25rem; font-size: 0.9375rem; color: #0F172A; line-height: 1.55; }
|
||||
#confirm-dialog .dialog-actions { display: flex; gap: 0.5rem; justify-content: flex-end; }
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.admin-layout { flex-direction: column; }
|
||||
.admin-sidebar {
|
||||
@@ -130,4 +138,24 @@
|
||||
{% block admin_content %}{% endblock %}
|
||||
</main>
|
||||
</div>
|
||||
|
||||
<dialog id="confirm-dialog">
|
||||
<p id="confirm-msg"></p>
|
||||
<div class="dialog-actions">
|
||||
<button id="confirm-cancel" class="btn-outline btn-sm">Cancel</button>
|
||||
<button id="confirm-ok" class="btn btn-sm">Confirm</button>
|
||||
</div>
|
||||
</dialog>
|
||||
<script>
|
||||
function confirmAction(message, form) {
|
||||
var dialog = document.getElementById('confirm-dialog');
|
||||
document.getElementById('confirm-msg').textContent = message;
|
||||
var ok = document.getElementById('confirm-ok');
|
||||
var newOk = ok.cloneNode(true);
|
||||
ok.replaceWith(newOk);
|
||||
newOk.addEventListener('click', function() { dialog.close(); form.submit(); });
|
||||
document.getElementById('confirm-cancel').addEventListener('click', function() { dialog.close(); }, { once: true });
|
||||
dialog.showModal();
|
||||
}
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<button type="submit" class="btn" style="width: 100%;" onclick="return confirm('Generate articles? Existing articles will be updated.')">
|
||||
<button type="button" class="btn" style="width: 100%;" onclick="confirmAction('Generate articles? Existing articles will be updated in-place.', this.closest('form'))">
|
||||
Generate Articles
|
||||
</button>
|
||||
</form>
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
<a href="{{ url_for('admin.scenario_edit', scenario_id=s.id) }}" class="btn-outline btn-sm">Edit</a>
|
||||
<form method="post" action="{{ url_for('admin.scenario_delete', scenario_id=s.id) }}" class="m-0" style="display: inline;">
|
||||
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
|
||||
<button type="submit" class="btn-outline btn-sm" onclick="return confirm('Delete this scenario?')">Delete</button>
|
||||
<button type="button" class="btn-outline btn-sm" onclick="confirmAction('Delete this scenario? This cannot be undone.', this.closest('form'))">Delete</button>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
<a href="{{ url_for('admin.template_generate', slug=config_data.slug) }}" class="btn">Generate Articles</a>
|
||||
<form method="post" action="{{ url_for('admin.template_regenerate', slug=config_data.slug) }}" style="display:inline">
|
||||
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
|
||||
<button type="submit" class="btn-outline" onclick="return confirm('Regenerate all articles for this template with fresh data?')">
|
||||
<button type="button" class="btn-outline" onclick="confirmAction('Regenerate all articles for this template with fresh data? Existing articles will be overwritten.', this.closest('form'))">
|
||||
Regenerate
|
||||
</button>
|
||||
</form>
|
||||
|
||||
Reference in New Issue
Block a user