From 14feb47640540a0b26b1afe781423104a3b22ac1 Mon Sep 17 00:00:00 2001 From: ari melody Date: Mon, 20 Oct 2025 08:31:36 +0100 Subject: [PATCH 1/2] tidy up unfinished admin css --- admin/static/admin.css | 5 ++++- admin/static/edit-account.css | 8 +++++--- admin/static/edit-release.css | 9 +++++++++ admin/static/index.css | 4 ++-- 4 files changed, 20 insertions(+), 6 deletions(-) diff --git a/admin/static/admin.css b/admin/static/admin.css index 1f5a1fb..3b490b6 100644 --- a/admin/static/admin.css +++ b/admin/static/admin.css @@ -107,7 +107,6 @@ nav .icon img { .nav-item { width: auto; height: 100%; - padding: 0 1em; display: flex; color: var(--fg-2); @@ -123,9 +122,13 @@ nav .icon img { text-decoration: none; } nav a { + padding: 0 1em; text-decoration: none; color: inherit; } +nav a.icon { + padding: 0; +} nav #logout { /* margin-left: auto; */ } diff --git a/admin/static/edit-account.css b/admin/static/edit-account.css index 7a4d34a..9db3773 100644 --- a/admin/static/edit-account.css +++ b/admin/static/edit-account.css @@ -25,12 +25,14 @@ input { .mfa-device { padding: .75em; - background: #f8f8f8f8; - border: 1px solid #808080; - border-radius: 8px; margin-bottom: .5em; display: flex; justify-content: space-between; + + color: var(--fg-3); + background: var(--bg-2); + box-shadow: var(--shadow-md); + border-radius: 16px; } .mfa-device div { diff --git a/admin/static/edit-release.css b/admin/static/edit-release.css index d30db84..c8e6153 100644 --- a/admin/static/edit-release.css +++ b/admin/static/edit-release.css @@ -313,19 +313,28 @@ dialog div.dialog-actions { gap: .2em; } +.card.links a.button:hover { + color: var(--bg-3) !important; + background-color: var(--fg-3) !important; +} + .card.links a.button[data-name="spotify"] { + color: #101010; background-color: #8cff83 } .card.links a.button[data-name="apple music"] { + color: #101010; background-color: #8cd9ff } .card.links a.button[data-name="soundcloud"] { + color: #101010; background-color: #fdaa6d } .card.links a.button[data-name="youtube"] { + color: #101010; background-color: #ff6e6e } diff --git a/admin/static/index.css b/admin/static/index.css index 278224e..5516656 100644 --- a/admin/static/index.css +++ b/admin/static/index.css @@ -7,11 +7,11 @@ flex-direction: row; align-items: center; gap: .5em; - color: var(--fg-3); - border-radius: 16px; + color: var(--fg-3); background: var(--bg-2); box-shadow: var(--shadow-md); + border-radius: 16px; transition: background .1s ease-out; cursor: pointer; From f324c249f6bd391b6f840506a6117f250402fba3 Mon Sep 17 00:00:00 2001 From: ari melody Date: Tue, 21 Oct 2025 15:37:40 +0100 Subject: [PATCH 2/2] start huge dashboard rework; improve dark theme --- admin/accounthttp.go | 20 ++-- admin/artisthttp.go | 4 +- admin/http.go | 43 ++++---- admin/logshttp.go | 4 +- admin/releasehttp.go | 4 +- admin/static/admin.css | 145 ++++++++++++++++++------- admin/static/edit-artist.css | 11 +- admin/static/edit-artist.js | 8 ++ admin/static/edit-release.css | 57 ++++++---- admin/static/edit-release.js | 8 ++ admin/static/index.css | 15 +-- admin/static/index.js | 2 +- admin/static/release-list-item.css | 2 + admin/templates/html/edit-account.html | 18 +-- admin/templates/html/edit-artist.html | 16 +-- admin/templates/html/edit-release.html | 76 ++++++------- admin/templates/html/edit-track.html | 12 +- admin/templates/html/index.html | 116 ++++++++++---------- admin/templates/html/layout.html | 24 +++- admin/trackhttp.go | 4 +- controller/release.go | 11 ++ 21 files changed, 365 insertions(+), 235 deletions(-) diff --git a/admin/accounthttp.go b/admin/accounthttp.go index b2c3b0d..1e4742b 100644 --- a/admin/accounthttp.go +++ b/admin/accounthttp.go @@ -45,7 +45,7 @@ func accountIndexHandler(app *model.AppState) http.Handler { } accountResponse struct { - Session *model.Session + adminPageData TOTPs []TOTP } ) @@ -66,7 +66,7 @@ func accountIndexHandler(app *model.AppState) http.Handler { session.Error = sessionError err = templates.AccountTemplate.Execute(w, accountResponse{ - Session: session, + adminPageData: adminPageData{ Path: r.URL.Path, Session: session }, TOTPs: totps, }) if err != nil { @@ -170,7 +170,7 @@ func deleteAccountHandler(app *model.AppState) http.Handler { } type totpConfirmData struct { - Session *model.Session + adminPageData TOTP *model.TOTP NameEscaped string QRBase64Image string @@ -179,13 +179,9 @@ type totpConfirmData struct { func totpSetupHandler(app *model.AppState) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { if r.Method == http.MethodGet { - type totpSetupData struct { - Session *model.Session - } - session := r.Context().Value("session").(*model.Session) - err := templates.TOTPSetupTemplate.Execute(w, totpSetupData{ Session: session }) + err := templates.TOTPSetupTemplate.Execute(w, adminPageData{ Path: "/account", Session: session }) if err != nil { fmt.Printf("WARN: Failed to render TOTP setup page: %s\n", err) http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) @@ -222,7 +218,9 @@ func totpSetupHandler(app *model.AppState) http.Handler { if err != nil { fmt.Printf("WARN: Failed to create TOTP method: %s\n", err) controller.SetSessionError(app.DB, session, "Something went wrong. Please try again.") - err := templates.TOTPSetupTemplate.Execute(w, totpConfirmData{ Session: session }) + err := templates.TOTPSetupTemplate.Execute(w, totpConfirmData{ + adminPageData: adminPageData{ Path: r.URL.Path, Session: session }, + }) if err != nil { fmt.Printf("WARN: Failed to render TOTP setup page: %s\n", err) http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) @@ -237,7 +235,7 @@ func totpSetupHandler(app *model.AppState) http.Handler { } err = templates.TOTPConfirmTemplate.Execute(w, totpConfirmData{ - Session: session, + adminPageData: adminPageData{ Path: r.URL.Path, Session: session }, TOTP: &totp, NameEscaped: url.PathEscape(totp.Name), QRBase64Image: qrBase64Image, @@ -298,7 +296,7 @@ func totpConfirmHandler(app *model.AppState) http.Handler { if code != confirmCodeOffset { session.Error = sql.NullString{ Valid: true, String: "Incorrect TOTP code. Please try again." } err = templates.TOTPConfirmTemplate.Execute(w, totpConfirmData{ - Session: session, + adminPageData: adminPageData{ Path: r.URL.Path, Session: session }, TOTP: totp, NameEscaped: url.PathEscape(totp.Name), QRBase64Image: qrBase64Image, diff --git a/admin/artisthttp.go b/admin/artisthttp.go index 67ea7d2..8c33050 100644 --- a/admin/artisthttp.go +++ b/admin/artisthttp.go @@ -33,7 +33,7 @@ func serveArtist(app *model.AppState) http.Handler { } type ArtistResponse struct { - Session *model.Session + adminPageData Artist *model.Artist Credits []*model.Credit } @@ -41,7 +41,7 @@ func serveArtist(app *model.AppState) http.Handler { session := r.Context().Value("session").(*model.Session) err = templates.EditArtistTemplate.Execute(w, ArtistResponse{ - Session: session, + adminPageData: adminPageData{ Path: r.URL.Path, Session: session }, Artist: artist, Credits: credits, }) diff --git a/admin/http.go b/admin/http.go index 05e181d..136309e 100644 --- a/admin/http.go +++ b/admin/http.go @@ -21,6 +21,11 @@ import ( "golang.org/x/crypto/bcrypt" ) +type adminPageData struct { + Path string + Session *model.Session +} + func Handler(app *model.AppState) http.Handler { mux := http.NewServeMux() @@ -67,12 +72,18 @@ func AdminIndexHandler(app *model.AppState) http.Handler { session := r.Context().Value("session").(*model.Session) - releases, err := controller.GetAllReleases(app.DB, false, 0, true) + releases, err := controller.GetAllReleases(app.DB, false, 3, true) if err != nil { fmt.Fprintf(os.Stderr, "WARN: Failed to pull releases: %s\n", err) http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) return } + releaseCount, err := controller.GetReleasesCount(app.DB, false) + if err != nil { + fmt.Fprintf(os.Stderr, "WARN: Failed to pull releases count: %s\n", err) + http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) + return + } artists, err := controller.GetAllArtists(app.DB) if err != nil { @@ -89,15 +100,17 @@ func AdminIndexHandler(app *model.AppState) http.Handler { } type IndexData struct { - Session *model.Session - Releases []*model.Release - Artists []*model.Artist - Tracks []*model.Track + adminPageData + Releases []*model.Release + ReleaseCount int + Artists []*model.Artist + Tracks []*model.Track } err = templates.IndexTemplate.Execute(w, IndexData{ - Session: session, + adminPageData: adminPageData{ Path: r.URL.Path, Session: session }, Releases: releases, + ReleaseCount: releaseCount, Artists: artists, Tracks: tracks, }) @@ -119,12 +132,8 @@ func registerAccountHandler(app *model.AppState) http.Handler { return } - type registerData struct { - Session *model.Session - } - render := func() { - err := templates.RegisterTemplate.Execute(w, registerData{ Session: session }) + err := templates.RegisterTemplate.Execute(w, adminPageData{ Path: r.URL.Path, Session: session }) if err != nil { fmt.Printf("WARN: Error rendering create account page: %s\n", err) http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) @@ -229,12 +238,8 @@ func loginHandler(app *model.AppState) http.Handler { session := r.Context().Value("session").(*model.Session) - type loginData struct { - Session *model.Session - } - render := func() { - err := templates.LoginTemplate.Execute(w, loginData{ Session: session }) + err := templates.LoginTemplate.Execute(w, adminPageData{ Path: r.URL.Path, Session: session }) if err != nil { fmt.Fprintf(os.Stderr, "WARN: Error rendering admin login page: %s\n", err) http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) @@ -345,12 +350,8 @@ func loginTOTPHandler(app *model.AppState) http.Handler { return } - type loginTOTPData struct { - Session *model.Session - } - render := func() { - err := templates.LoginTOTPTemplate.Execute(w, loginTOTPData{ Session: session }) + err := templates.LoginTOTPTemplate.Execute(w, adminPageData{ Path: r.URL.Path, Session: session }) if err != nil { fmt.Fprintf(os.Stderr, "WARN: Failed to render login TOTP page: %v\n", err) http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) diff --git a/admin/logshttp.go b/admin/logshttp.go index 99f0ef1..a6d8e40 100644 --- a/admin/logshttp.go +++ b/admin/logshttp.go @@ -51,12 +51,12 @@ func logsHandler(app *model.AppState) http.Handler { } type LogsResponse struct { - Session *model.Session + adminPageData Logs []*log.Log } err = templates.LogsTemplate.Execute(w, LogsResponse{ - Session: session, + adminPageData: adminPageData{ Path: r.URL.Path, Session: session }, Logs: logs, }) if err != nil { diff --git a/admin/releasehttp.go b/admin/releasehttp.go index 30c967b..991845f 100644 --- a/admin/releasehttp.go +++ b/admin/releasehttp.go @@ -57,12 +57,12 @@ func serveRelease(app *model.AppState) http.Handler { } type ReleaseResponse struct { - Session *model.Session + adminPageData Release *model.Release } err = templates.EditReleaseTemplate.Execute(w, ReleaseResponse{ - Session: session, + adminPageData: adminPageData{ Path: r.URL.Path, Session: session }, Release: release, }) if err != nil { diff --git a/admin/static/admin.css b/admin/static/admin.css index 3b490b6..7dad27f 100644 --- a/admin/static/admin.css +++ b/admin/static/admin.css @@ -3,9 +3,9 @@ :root { --bg-0: #101010; - --bg-1: #141414; - --bg-2: #181818; - --bg-3: #202020; + --bg-1: #181818; + --bg-2: #282828; + --bg-3: #404040; --fg-0: #b0b0b0; --fg-1: #c0c0c0; @@ -67,77 +67,111 @@ } body { - width: 100%; + width: calc(100% - 180px); height: calc(100vh - 1em); - margin: 0; + margin: 0 0 0 180px; padding: 0; + display: flex; + flex-direction: row; font-family: "Inter", sans-serif; font-size: 16px; - color: var(--fg-0); background: var(--bg-0); + + transition: background .1s ease-out, color .1s ease-out; } h1, h2, h3, h4, h5, h6 { color: var(--fg-3); } -nav { - width: min(720px, calc(100% - 2em)); - height: 2em; - margin: 1em auto; +header { + position: fixed; + left: 0; + height: 100vh; display: flex; - flex-direction: row; + flex-direction: column; + width: 180px; + background-color: var(--bg-1); + box-shadow: var(--shadow-md); + + transition: background .1s ease-out, color .1s ease-out; +} +nav { + height: 100%; + margin: 1em 0; + display: flex; + flex-direction: column; justify-content: left; - gap: .5em; user-select: none; } nav .icon { - height: 100%; - border-radius: 100%; - box-shadow: var(--shadow-sm); - overflow: hidden; -} -nav .icon img { - width: 100%; - height: 100%; -} -.nav-item { - width: auto; - height: 100%; + width: fit-content; + height: fit-content; + padding: 0; + margin: 0 auto 1em auto; display: flex; - color: var(--fg-2); - background: var(--bg-2); - border-radius: 10em; + border-radius: 100%; box-shadow: var(--shadow-sm); - + overflow: clip; +} +nav .icon img { + width: 3em; + height: 3em; +} +.nav-item { + display: flex; + color: var(--fg-2); line-height: 2em; font-weight: 500; + transition: color .1s, background-color .1s; } .nav-item:hover { - background: var(--bg-1); + background: var(--bg-2); text-decoration: none; } +.nav-item.active { + border-left: 4px solid var(--fg-2); +} +.nav-item.active a { + padding-left: calc(1em - 4px); +} nav a { - padding: 0 1em; + padding: .2em 1em; text-decoration: none; color: inherit; + width: 100%; } -nav a.icon { - padding: 0; +nav a.active { + border-left: 5px solid var(--fg-0); + padding-left: calc(1em - 5px); } -nav #logout { - /* margin-left: auto; */ +nav hr { + width: calc(100% - 2em); + margin: .5em auto; + border: none; + border-bottom: 1px solid var(--fg-0); +} +nav .section-label { + margin: 8px 0 2px 15px; + font-size: 10px; + text-transform: uppercase; + font-weight: 600; } main { - width: min(720px, calc(100% - 2em)); + width: min(calc(100% - 16px), 720px); + height: fit-content; + min-height: calc(100vh - 2em); margin: 0 auto; padding: 1em; } +main.dashboard { + width: 100%; +} a { color: inherit; @@ -163,7 +197,24 @@ code { +.cards { + width: 100%; + height: fit-content; + display: flex; + gap: 2em; + flex-wrap: wrap; +} + .card { + flex-basis: 40em; + padding: 1em; + background: var(--bg-1); + border-radius: 16px; + box-shadow: var(--shadow-lg); + + transition: background .1s ease-out, color .1s ease-out; +} +main:not(.dashboard) .card { margin-bottom: 1em; } @@ -171,7 +222,7 @@ code { margin: 0 0 .5em 0; } -.card-title { +.card-header { margin-bottom: 1em; display: flex; gap: 1em; @@ -179,17 +230,31 @@ code { align-items: center; justify-content: space-between; } - -.card-title h1, -.card-title h2, -.card-title h3 { +.card-header h1, +.card-header h2, +.card-header h3 { margin: 0; } +.card-header a:hover { + text-decoration: underline; +} +.card-header small { + display: inline-block; + font-size: 15px; + transform: translateY(-2px); + color: var(--fg-0); +} .flex-fill { flex-grow: 1; } +.artists-group { + display: grid; + grid-template-columns: repeat(5, 1fr); + gap: 1em; +} + @media screen and (max-width: 520px) { body { font-size: 12px; diff --git a/admin/static/edit-artist.css b/admin/static/edit-artist.css index 1bab082..b171a6e 100644 --- a/admin/static/edit-artist.css +++ b/admin/static/edit-artist.css @@ -28,7 +28,7 @@ h1 { } .artist-avatar #remove-avatar { margin-top: .5em; - padding: .3em .4em; + padding: .3em .6em; } .artist-info { @@ -75,7 +75,7 @@ input[type="text"]:focus { justify-content: right; } -.card-title a.button { +.card-header a.button { text-decoration: none; } @@ -90,6 +90,13 @@ input[type="text"]:focus { border-radius: 16px; background: var(--bg-2); box-shadow: var(--shadow-md); + + cursor: pointer; + transition: background .1s; +} + +.credit:hover { + background: var(--bg-1); } .release-artwork { diff --git a/admin/static/edit-artist.js b/admin/static/edit-artist.js index 8f1bb2b..2ca4c0d 100644 --- a/admin/static/edit-artist.js +++ b/admin/static/edit-artist.js @@ -1,3 +1,5 @@ +import { hijackClickEvent } from "./admin.js"; + const artistID = document.getElementById("artist").dataset.id; const nameInput = document.getElementById("name"); const avatarImg = document.getElementById("avatar"); @@ -77,3 +79,9 @@ removeAvatarBtn.addEventListener("click", () => { avatarImg.src = "/img/default-avatar.png" saveBtn.disabled = false; }); + +document.addEventListener('readystatechange', () => { + document.querySelectorAll('.card#releases .credit').forEach(el => { + hijackClickEvent(el, el.querySelector('.credit-name a')); + }); +}); diff --git a/admin/static/edit-release.css b/admin/static/edit-release.css index c8e6153..b4fe17b 100644 --- a/admin/static/edit-release.css +++ b/admin/static/edit-release.css @@ -155,7 +155,7 @@ dialog div.dialog-actions { gap: .5em; } -.card-title a.button { +.card-header a.button { text-decoration: none; } @@ -163,7 +163,7 @@ dialog div.dialog-actions { * RELEASE CREDITS */ -.card.credits .credit { +.card#credits .credit { margin-bottom: .5em; padding: .5em; display: flex; @@ -172,24 +172,30 @@ dialog div.dialog-actions { gap: 1em; border-radius: 16px; - background: var(--bg-2); + background-color: var(--bg-2); box-shadow: var(--shadow-md); + + cursor: pointer; + transition: background .1s ease-out; +} +.card#credits .credit:hover { + background-color: var(--bg-1); } -.card.credits .credit p { +.card#credits .credit p { margin: 0; } -.card.credits .credit .artist-avatar { +.card#credits .credit .artist-avatar { border-radius: 12px; } -.card.credits .credit .artist-name { +.card#credits .credit .artist-name { color: var(--fg-3); font-weight: bold; } -.card.credits .credit .artist-role small { +.card#credits .credit .artist-role small { font-size: inherit; opacity: .66; } @@ -308,32 +314,33 @@ dialog div.dialog-actions { * RELEASE LINKS */ -.card.links { +.card#links ul { + padding: 0; display: flex; gap: .2em; } -.card.links a.button:hover { +.card#links a.button:hover { color: var(--bg-3) !important; background-color: var(--fg-3) !important; } -.card.links a.button[data-name="spotify"] { +.card#links a.button[data-name="spotify"] { color: #101010; background-color: #8cff83 } -.card.links a.button[data-name="apple music"] { +.card#links a.button[data-name="apple music"] { color: #101010; background-color: #8cd9ff } -.card.links a.button[data-name="soundcloud"] { +.card#links a.button[data-name="soundcloud"] { color: #101010; background-color: #fdaa6d } -.card.links a.button[data-name="youtube"] { +.card#links a.button[data-name="youtube"] { color: #101010; background-color: #ff6e6e } @@ -421,7 +428,7 @@ dialog div.dialog-actions { * RELEASE TRACKS */ -.card.tracks .track { +.card#tracks .track { margin-bottom: 1em; padding: 1em; display: flex; @@ -433,43 +440,47 @@ dialog div.dialog-actions { box-shadow: var(--shadow-md); } -.card.tracks .track h3, -.card.tracks .track p { +.card#tracks .track h3, +.card#tracks .track p { margin: 0; } -.card.tracks h2.track-title { +.card#tracks h2.track-title { margin: 0; display: flex; gap: .5em; } -.card.tracks h2.track-title .track-number { +.card#tracks h2.track-title .track-number { opacity: .5; } -.card.tracks .track-album { +.card#tracks a:hover { + text-decoration: underline; +} + +.card#tracks .track-album { margin-left: auto; font-style: italic; font-size: .75em; opacity: .5; } -.card.tracks .track-album.empty { +.card#tracks .track-album.empty { color: #ff2020; opacity: 1; } -.card.tracks .track-description { +.card#tracks .track-description { font-style: italic; } -.card.tracks .track-lyrics { +.card#tracks .track-lyrics { max-height: 10em; overflow-y: scroll; } -.card.tracks .track .empty { +.card#tracks .track .empty { opacity: 0.75; } diff --git a/admin/static/edit-release.js b/admin/static/edit-release.js index 11d21f0..5db4bbf 100644 --- a/admin/static/edit-release.js +++ b/admin/static/edit-release.js @@ -1,3 +1,5 @@ +import { hijackClickEvent } from "./admin.js"; + const releaseID = document.getElementById("release").dataset.id; const titleInput = document.getElementById("title"); const artworkImg = document.getElementById("artwork"); @@ -96,3 +98,9 @@ removeArtworkBtn.addEventListener("click", () => { artworkData = ""; saveBtn.disabled = false; }); + +document.addEventListener("readystatechange", () => { + document.querySelectorAll(".card#credits .credit").forEach(el => { + hijackClickEvent(el, el.querySelector(".artist-name a")); + }); +}); diff --git a/admin/static/index.css b/admin/static/index.css index 5516656..5f64a2f 100644 --- a/admin/static/index.css +++ b/admin/static/index.css @@ -1,20 +1,16 @@ @import url("/admin/static/release-list-item.css"); .artist { - margin-bottom: .5em; padding: .5em; - display: flex; - flex-direction: row; - align-items: center; - gap: .5em; color: var(--fg-3); background: var(--bg-2); box-shadow: var(--shadow-md); border-radius: 16px; + text-align: center; - transition: background .1s ease-out; cursor: pointer; + transition: background .1s ease-out, color .1s ease-out; } .artist:hover { @@ -23,10 +19,9 @@ } .artist-avatar { - width: 32px; - height: 32px; + width: 100%; object-fit: cover; - border-radius: 100%; + border-radius: 8px; } .track { @@ -39,6 +34,8 @@ border-radius: 8px; background: #f8f8f8f8; border: 1px solid #808080; + + transition: background .1s ease-out, color .1s ease-out; } .track p { diff --git a/admin/static/index.js b/admin/static/index.js index 0091fa4..c35b596 100644 --- a/admin/static/index.js +++ b/admin/static/index.js @@ -76,7 +76,7 @@ newTrackBtn.addEventListener("click", event => { }); document.addEventListener("readystatechange", () => { - document.querySelectorAll(".card.artists .artist").forEach(el => { + document.querySelectorAll("#artists .artist").forEach(el => { hijackClickEvent(el, el.querySelector("a.artist-name")) }); }); diff --git a/admin/static/release-list-item.css b/admin/static/release-list-item.css index fb5d2d4..3481257 100644 --- a/admin/static/release-list-item.css +++ b/admin/static/release-list-item.css @@ -8,6 +8,8 @@ border-radius: 16px; background: var(--bg-2); box-shadow: var(--shadow-md); + + transition: background .1s ease-out, color .1s ease-out; } .release h3, diff --git a/admin/templates/html/edit-account.html b/admin/templates/html/edit-account.html index 6c17088..a081995 100644 --- a/admin/templates/html/edit-account.html +++ b/admin/templates/html/edit-account.html @@ -14,10 +14,10 @@ {{end}}

Account Settings ({{.Session.Account.Username}})

-
-

Change Password

-
+
+

Change Password

+
@@ -32,10 +32,10 @@
-
-

MFA Devices

-
+
+

MFA Devices

+
{{if .TOTPs}} {{range .TOTPs}}
@@ -58,10 +58,10 @@
-
-

Danger Zone

-
+
+

Danger Zone

+

Clicking the button below will delete your account. This action is irreversible. diff --git a/admin/templates/html/edit-artist.html b/admin/templates/html/edit-artist.html index b0cfb41..6b95de8 100644 --- a/admin/templates/html/edit-artist.html +++ b/admin/templates/html/edit-artist.html @@ -29,10 +29,10 @@

-
-

Featured in

-
-
+
+
+

Featured in

+
{{if .Credits}} {{range .Credits}}
@@ -54,10 +54,10 @@ {{end}}
-
-

Danger Zone

-
-
+
+
+

Danger Zone

+

Clicking the button below will delete this artist. This action is irreversible. diff --git a/admin/templates/html/edit-release.html b/admin/templates/html/edit-release.html index 02447e1..309decf 100644 --- a/admin/templates/html/edit-release.html +++ b/admin/templates/html/edit-release.html @@ -97,16 +97,16 @@

-
-

Credits ({{len .Release.Credits}})

- Edit -
-
+
+
+

Credits ({{len .Release.Credits}})

+ Edit +
{{range .Release.Credits}}
@@ -126,31 +126,33 @@ {{end}}
-
-

Links ({{len .Release.Links}})

- Edit -
-