diff --git a/static/default.css b/static/default.css
index 56bb632..be53619 100644
--- a/static/default.css
+++ b/static/default.css
@@ -107,10 +107,6 @@ input, kbd { font: inherit; color: inherit; }
textarea {font-size:16px; font-family: 'PT Sans', 'Liberation Sans', sans-serif;}
::-webkit-file-upload-button,
-.btn { line-height: normal; display: inline-block; border: 1px #999 solid; border-radius: .25rem; text-decoration: none; padding: .25rem; font-size: 1rem; margin: 0; }
-.btn_weak { border: 1px #999 dashed; }
-.btn_accent { font-weight: bold; }
-.btn:hover, .btn:active { cursor: pointer; }
.edit { min-height: 80vh; }
.edit__title { margin-top: 0; }
@@ -300,10 +296,6 @@ article .codeblock,
textarea,
table { border: 0; background-color: #444444; color: #ddd; }
.transclusion_stand-out { background-color: rgba(68, 68, 68, 0.5); }
-.btn:visited { color: #ddd;}
-
- .btn { border: #444 solid 1px; border-radius: .25rem; }
- .btn_weak { background-color: transparent; }
.transclusion code,
.transclusion .codeblock { background-color: #454545; }
@@ -446,23 +438,32 @@ kbd {
}
@media (min-width: 600px) {
- .form-field {
+ .form--double .form-field {
display: grid;
grid-template-columns: 150px max-content;
grid-column-gap: 16px;
}
- .form-field label {
+ .form--double .form-field label {
grid-column: 1;
}
- .form-field input,
- .form-field button,
- .form-field select,
- .form-field textarea,
- .form-field .form-field__input {
+ .form--double .form-field input,
+ .form--double .form-field button,
+ .form--double .form-field select,
+ .form--double .form-field textarea,
+ .form--double .form-field__input {
grid-column: 2;
}
}
+/*
+ * Form wrap
+ */
+
+.form-wrap h2 {
+ margin: 1.5em 0 0.25em;
+ font-size: 1.2em;
+}
+
/*
* Notices
*/
@@ -484,3 +485,55 @@ kbd {
background-color: #5b3535;
}
}
+
+/*
+ * Buttons
+ */
+
+.btn {
+ line-height: normal;
+ display: inline-block;
+ border: 1px #999 solid;
+ border-radius: .15rem;
+ text-decoration: none;
+ padding: .25rem .5rem;
+ font-size: 1rem;
+ margin: 0;
+}
+
+.btn:hover {
+ cursor: pointer;
+}
+
+.btn_accent {
+ font-weight: bold;
+}
+
+.btn_weak {
+ border: 1px dashed #999;
+}
+
+.btn_destructive {
+ border-color: #aa1818;
+ background-color: #ee4343;
+ color: white;
+}
+
+@media (prefers-color-scheme: dark) {
+ .btn {
+ border-color: #444 solid 1px;
+ }
+
+ .btn:visited {
+ color: #ddd;
+ }
+
+ .btn_weak {
+ background-color: transparent;
+ }
+
+ .btn_destructive {
+ border-color: #e34343;
+ background-color: #b92828;
+ }
+}
diff --git a/user/users.go b/user/users.go
index 2abd829..6daa301 100644
--- a/user/users.go
+++ b/user/users.go
@@ -60,6 +60,18 @@ func UserByName(username string) *User {
return EmptyUser()
}
+func DeleteUser(name string) error {
+ user, loaded := users.LoadAndDelete(name)
+ if loaded {
+ u := user.(*User)
+ u.Name = "anon"
+ u.Group = "anon"
+ u.Password = ""
+ return SaveUserDatabase()
+ }
+ return nil
+}
+
func commenceSession(username, token string) {
tokens.Store(token, username)
dumpTokens()
diff --git a/views/admin.qtpl b/views/admin.qtpl
index 9eeba97..e7f1dc3 100644
--- a/views/admin.qtpl
+++ b/views/admin.qtpl
@@ -80,37 +80,37 @@
{% endfunc %}
-{% func AdminUserNewHTML(formData util.FormData) %}
+{% func AdminUserNewHTML(f util.FormData) %}
-
+
New user
- {% if formData.HasError() %}
+ {% if f.HasError() %}
Error:
- {%s formData.Error() %}
+ {%s f.Error() %}
{% endif %}
-
{% endfunc %}
-{% func AdminUsersUserHTML(u *user.User) %}
+{% func AdminUserEditHTML(u *user.User, f util.FormData) %}
-
- {%s u.Name %}
+
+
+ ←
+ {%s u.Name %}
+
+
+ Change group
+
+ {% if f.HasError() %}
+
+ Error:
+ {%s f.Error() %}
+
+ {% endif %}
+
+ Delete user
+ Remove the user from the database. Changes made by the user will
+ be preserved.
+ Delete
+
+
+{% endfunc %}
+
+{% func AdminUserDeleteHTML(u *user.User, f util.FormData) %}
+
+
+ Delete user
+
+ {% if f.HasError() %}
+
+ Error:
+ {%s f.Error() %}
+
+ {% endif %}
+
+ Are you sure you want to delete {%s u.Name %}
+ from the database? This action is irreversible.
+
+
diff --git a/views/admin.qtpl.go b/views/admin.qtpl.go
index cfb7011..3a34d2f 100644
--- a/views/admin.qtpl.go
+++ b/views/admin.qtpl.go
@@ -211,23 +211,23 @@ func AdminUsersPanelHTML(userList []*user.User) string {
}
//line views/admin.qtpl:83
-func StreamAdminUserNewHTML(qw422016 *qt422016.Writer, formData util.FormData) {
+func StreamAdminUserNewHTML(qw422016 *qt422016.Writer, f util.FormData) {
//line views/admin.qtpl:83
qw422016.N().S(`
-
+
New user
`)
//line views/admin.qtpl:88
- if formData.HasError() {
+ if f.HasError() {
//line views/admin.qtpl:88
qw422016.N().S(`
Error:
`)
//line views/admin.qtpl:91
- qw422016.E().S(formData.Error())
+ qw422016.E().S(f.Error())
//line views/admin.qtpl:91
qw422016.N().S(`
@@ -237,12 +237,12 @@ func StreamAdminUserNewHTML(qw422016 *qt422016.Writer, formData util.FormData) {
//line views/admin.qtpl:93
qw422016.N().S(`
-
@@ -261,7 +261,7 @@ func StreamAdminUserNewHTML(qw422016 *qt422016.Writer, formData util.FormData) {