aboutsummaryrefslogtreecommitdiffstats
path: root/internal/web/templates/admin
diff options
context:
space:
mode:
authorgramanas <grm@eyesin.space>2026-09-12 11:24:17 +0300
committergramanas <grm@eyesin.space>2026-09-12 11:24:17 +0300
commit3eb04b1a2bdf9e53231fe862cfd76327371a9741 (patch)
treeb38b2d82a47233fd8e0bb18c59e4a8f3dd2412d7 /internal/web/templates/admin
downloadblogspace-3eb04b1a2bdf9e53231fe862cfd76327371a9741.tar.gz
blogspace-3eb04b1a2bdf9e53231fe862cfd76327371a9741.tar.bz2
blogspace-3eb04b1a2bdf9e53231fe862cfd76327371a9741.zip
Initial multi-tenant blog host
Go + Postgres application serving a management dashboard on the base domain and one public blog per subdomain. Markdown posts organised in pages, form-based theme customisation, image uploads stored in Postgres, JWT cookie sessions with CSRF, superadmin user management, RSS feeds. Docker/compose deployment and a Makefile-driven dev environment with seed data. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Sd8UPWrvyYCLj97JexNw3A
Diffstat (limited to 'internal/web/templates/admin')
-rw-r--r--internal/web/templates/admin/delete_user.html12
-rw-r--r--internal/web/templates/admin/index.html28
-rw-r--r--internal/web/templates/admin/new_user.html15
3 files changed, 55 insertions, 0 deletions
diff --git a/internal/web/templates/admin/delete_user.html b/internal/web/templates/admin/delete_user.html
new file mode 100644
index 0000000..34d3fb9
--- /dev/null
+++ b/internal/web/templates/admin/delete_user.html
@@ -0,0 +1,12 @@
+{{define "title"}}Delete user · Blogspace{{end}}
+{{define "content"}}
+<div class="card narrow">
+ <h1>Delete {{.Data.target.Username}}?</h1>
+ <p>This permanently deletes the user <strong>{{.Data.target.Username}}</strong>, their blog, and every page, post and image in it.</p>
+ <form method="post" action="/admin/users/{{.Data.target.ID}}/delete">
+ <input type="hidden" name="_csrf" value="{{.CSRF}}">
+ <button type="submit" class="danger">Yes, delete everything</button>
+ <a class="btn secondary" href="/admin/">Cancel</a>
+ </form>
+</div>
+{{end}}
diff --git a/internal/web/templates/admin/index.html b/internal/web/templates/admin/index.html
new file mode 100644
index 0000000..c74d426
--- /dev/null
+++ b/internal/web/templates/admin/index.html
@@ -0,0 +1,28 @@
+{{define "title"}}Admin · Blogspace{{end}}
+{{define "content"}}
+<h1>Users &amp; blogs <a class="btn small" href="/admin/users/new">+ New blogger</a></h1>
+<div class="card">
+<table>
+ <tr><th>User</th><th>Role</th><th>Blog</th><th>Since</th><th>Actions</th></tr>
+ {{range .Data.users}}<tr{{if .Disabled}} class="disabled"{{end}}>
+ <td>{{.Username}}{{if .Disabled}} <span class="tag">disabled</span>{{end}}</td>
+ <td>{{.Role}}</td>
+ <td>{{if .Subdomain}}<a href="/b/{{deref .Subdomain}}/">{{deref .BlogTitle}}</a> <a href="{{$.Data.cfg.BlogURL (deref .Subdomain)}}" target="_blank" class="muted">{{deref .Subdomain}} &#8599;</a>{{else}}<span class="muted">—</span>{{end}}</td>
+ <td class="nowrap">{{date .CreatedAt}}</td>
+ <td class="nowrap">
+ {{if ne .ID $.User.ID}}
+ <details class="inline"><summary class="mini">reset password</summary>
+ <form method="post" action="/admin/users/{{.ID}}/reset-password" class="inline">
+ <input type="hidden" name="_csrf" value="{{$.CSRF}}">
+ <input type="password" name="password" placeholder="new password" minlength="8" required size="14">
+ <button class="mini">Set</button>
+ </form></details>
+ {{if .Disabled}}<form method="post" action="/admin/users/{{.ID}}/enable" class="inline"><input type="hidden" name="_csrf" value="{{$.CSRF}}"><button class="mini">enable</button></form>
+ {{else}}<form method="post" action="/admin/users/{{.ID}}/disable" class="inline"><input type="hidden" name="_csrf" value="{{$.CSRF}}"><button class="mini">disable</button></form>{{end}}
+ <a class="danger" href="/admin/users/{{.ID}}/delete">delete</a>
+ {{else}}<span class="muted">(you)</span>{{end}}
+ </td>
+ </tr>{{end}}
+</table>
+</div>
+{{end}}
diff --git a/internal/web/templates/admin/new_user.html b/internal/web/templates/admin/new_user.html
new file mode 100644
index 0000000..87d1186
--- /dev/null
+++ b/internal/web/templates/admin/new_user.html
@@ -0,0 +1,15 @@
+{{define "title"}}New blogger · Blogspace{{end}}
+{{define "content"}}
+<div class="card narrow">
+ <h1>New blogger</h1>
+ <form method="post" action="/admin/users/new">
+ <input type="hidden" name="_csrf" value="{{.CSRF}}">
+ <label>Username<br><input name="username" value="{{.Data.username}}" required pattern="[a-zA-Z0-9_.-]{2,40}" autofocus></label>
+ <label>Password <span class="muted">(min 8 characters; they can change it later)</span><br><input type="password" name="password" required minlength="8"></label>
+ <label>Subdomain <span class="muted">(defaults to the username)</span><br>
+ <span class="nowrap"><input name="subdomain" value="{{.Data.subdomain}}" pattern="[a-z0-9]([a-z0-9-]*[a-z0-9])?" maxlength="63" size="14">.{{.Data.cfg.BaseDomain}}</span></label>
+ <label>Blog title<br><input name="title" value="{{.Data.title}}" maxlength="120"></label>
+ <button type="submit">Create</button> <a href="/admin/">Cancel</a>
+ </form>
+</div>
+{{end}}