Move admin user deletion confirmation to modal

Ref T319
This commit is contained in:
Matt Baer 2021-04-22 10:08:05 -04:00
parent 3b58d77e67
commit e4164cbf67
5 changed files with 100 additions and 25 deletions

View File

@ -1044,6 +1044,19 @@ li {
background-color: #dff0d8; background-color: #dff0d8;
border-color: #d6e9c6; border-color: #d6e9c6;
} }
&.danger {
border-color: #856404;
background-color: white;
h3 {
margin: 0 0 0.5em 0;
font-size: 1em;
font-weight: bold;
color: black !important;
}
h3 + p, button {
font-size: 0.86em;
}
}
p { p {
margin: 0; margin: 0;

View File

@ -340,6 +340,15 @@ body#pad {
} }
} }
.body {
line-height: 1.5;
input[type=text].confirm {
width: 100%;
box-sizing: border-box;
}
}
.short { .short {
text-align: center; text-align: center;
} }

24
static/js/modals.js Normal file
View File

@ -0,0 +1,24 @@
/*
* Copyright © 2016-2021 A Bunch Tell LLC.
*
* This file is part of WriteFreely.
*
* WriteFreely is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, included
* in the LICENSE file in this source code package.
*/
function showModal(id) {
document.getElementById('overlay').style.display = 'block';
document.getElementById('modal-'+id).style.display = 'block';
}
var closeModals = function(e) {
e.preventDefault();
document.getElementById('overlay').style.display = 'none';
var modals = document.querySelectorAll('.modal');
for (var i=0; i<modals.length; i++) {
modals[i].style.display = 'none';
}
};
H.getEl('overlay').on('click', closeModals);

View File

@ -32,8 +32,13 @@ input.copy-text {
width: 100%; width: 100%;
box-sizing: border-box; box-sizing: border-box;
} }
.modal {
position: fixed;
}
</style> </style>
<div class="snug content-container"> <div class="snug content-container">
<div id="overlay"></div>
{{template "admin-header" .}} {{template "admin-header" .}}
<h2 id="posts-header">{{.User.Username}}</h2> <h2 id="posts-header">{{.User.Username}}</h2>
@ -141,19 +146,58 @@ input.copy-text {
{{end}} {{end}}
{{ if not .User.IsAdmin }} {{ if not .User.IsAdmin }}
<hr/> <h2>Incinerator</h2>
<h2>Delete Account</h2> <div class="alert danger">
<h3><strong>Danger Zone - This cannot be undone</strong></h3> <div class="row">
<p>This will delete the user {{.User.Username}} and all their blogs AND posts.</p> <div>
<form action="/admin/user/{{.User.Username}}/delete" method="post"> <h3>Delete this user</h3>
<p>Type their username to confirm deletion.<p> <p>Permanently erase all user data, with no way to recover it.</p>
<input name="confirm-username" type="text" title="confirm username to delete" placeholder="confirm username"> </div>
<input class="danger" type="submit" value="DELETE"> <button class="cta danger" onclick="prepareDeleteUser()">Delete this user...</button>
</form> </div>
</div>
{{end}} {{end}}
</div> </div>
<div id="modal-delete-user" class="modal">
<h2>Are you sure?</h2>
<div class="body">
<p style="text-align:left">This action <strong>cannot</strong> be undone. It will permanently erase all traces of this user, <strong>{{.User.Username}}</strong>, including their account information, blogs, and posts.</p>
<p>Please type <strong>{{.User.Username}}</strong> to confirm.</p>
<ul id="delete-errors" class="errors"></ul>
<form action="/admin/user/{{.User.Username}}/delete" method="post" onsubmit="confirmDeletion()">
<input id="confirm-text" placeholder="{{.User.Username}}" type="text" class="confirm boxy" name="confirm-username" style="margin-top: 0.5em;" />
<div style="text-align:right; margin-top: 1em;">
<a id="cancel-delete" style="margin-right:2em" href="#">Cancel</a>
<input class="danger" type="submit" id="confirm-delete" value="Delete this user" disabled />
</div>
</div>
</div>
<script src="/js/h.js"></script>
<script src="/js/modals.js"></script>
<script type="text/javascript"> <script type="text/javascript">
H.getEl('cancel-delete').on('click', closeModals);
let $confirmDelBtn = document.getElementById('confirm-delete');
let $confirmText = document.getElementById('confirm-text')
$confirmText.addEventListener('input', function() {
$confirmDelBtn.disabled = this.value !== '{{.User.Username}}'
});
function prepareDeleteUser() {
$confirmText.value = ''
showModal('delete-user')
$confirmText.focus()
}
function confirmDeletion() {
$confirmDelBtn.disabled = true
$confirmDelBtn.value = 'Deleting...'
}
function confirmSilence() { function confirmSilence() {
return confirm("Silence this user? They'll still be able to log in and access their posts, but no one else will be able to see them anymore. You can reverse this decision at any time."); return confirm("Silence this user? They'll still be able to log in and access their posts, but no one else will be able to see them anymore. You can reverse this decision at any time.");
} }

View File

@ -193,25 +193,10 @@ textarea.section.norm {
</div> </div>
<script src="/js/h.js"></script> <script src="/js/h.js"></script>
<script src="/js/modals.js"></script>
<script src="/js/ace.js" type="text/javascript" charset="utf-8"></script> <script src="/js/ace.js" type="text/javascript" charset="utf-8"></script>
<script> <script>
// Begin shared modal code
function showModal(id) {
document.getElementById('overlay').style.display = 'block';
document.getElementById('modal-'+id).style.display = 'block';
}
var closeModals = function(e) {
e.preventDefault();
document.getElementById('overlay').style.display = 'none';
var modals = document.querySelectorAll('.modal');
for (var i=0; i<modals.length; i++) {
modals[i].style.display = 'none';
}
};
H.getEl('overlay').on('click', closeModals);
H.getEl('cancel-delete').on('click', closeModals); H.getEl('cancel-delete').on('click', closeModals);
// end
var deleteBlog = function(e) { var deleteBlog = function(e) {
if (document.getElementById('confirm-text').value != '{{.Alias}}') { if (document.getElementById('confirm-text').value != '{{.Alias}}') {
document.getElementById('delete-errors').innerHTML = '<li class="urgent">Enter <strong>{{.Alias}}</strong> in the box below.</li>'; document.getElementById('delete-errors').innerHTML = '<li class="urgent">Enter <strong>{{.Alias}}</strong> in the box below.</li>';