Skip to content

Commit

Permalink
Better UI for admin settings (thomiceli#30)
Browse files Browse the repository at this point in the history
  • Loading branch information
thomiceli committed May 11, 2023
1 parent 089d321 commit 5fe8416
Show file tree
Hide file tree
Showing 6 changed files with 74 additions and 33 deletions.
8 changes: 8 additions & 0 deletions internal/web/admin.go
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,14 @@ func adminSyncReposFromDB(ctx echo.Context) error {
return redirect(ctx, "/admin-panel")
}

func adminSettings(ctx echo.Context) error {
setData(ctx, "title", "Admin Settings")
setData(ctx, "htmlTitle", "Admin Settings - Admin panel")
setData(ctx, "adminHeaderPage", "settings")

return html(ctx, "admin_settings.html")
}

func adminSetSetting(ctx echo.Context) error {
key := ctx.FormValue("key")
value := ctx.FormValue("value")
Expand Down
1 change: 1 addition & 0 deletions internal/web/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,7 @@ func Start() {
g2.POST("/gists/:gist/delete", adminGistDelete)
g2.POST("/sync-fs", adminSyncReposFromFS)
g2.POST("/sync-db", adminSyncReposFromDB)
g2.GET("/settings", adminSettings)
g2.PUT("/set-setting", adminSetSetting)
}

Expand Down
24 changes: 16 additions & 8 deletions public/admin.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,32 @@
document.addEventListener('DOMContentLoaded', () => {
registerDomSetting(document.getElementById('disable-signup') as HTMLInputElement);
registerDomSetting(document.getElementById('require-login') as HTMLInputElement);
registerDomSetting(document.getElementById('disable-login-form') as HTMLInputElement);
let elems = Array.from(document.getElementsByClassName("toggle-button"));
for (let elem of elems) {
elem.addEventListener('click', () => {
registerDomSetting(elem as HTMLElement)
})
}
});

const setSetting = (key: string, value: string) => {
const data = new URLSearchParams();
data.append('key', key);
data.append('value', value);
data.append('_csrf', ((document.getElementsByName('_csrf')[0] as HTMLInputElement).value));
fetch('/admin-panel/set-setting', {
return fetch('/admin-panel/set-setting', {
method: 'PUT',
credentials: 'same-origin',
body: data,
});
};

const registerDomSetting = (el: HTMLInputElement) => {
el.addEventListener('change', () => {
setSetting(el.id, el.checked ? '1' : '0');
});
const registerDomSetting = (el: HTMLElement) => {
// @ts-ignore
el.dataset["bool"] = !(el.dataset["bool"] === 'true');
setSetting(el.id, el.dataset["bool"] === 'true' ? '1' : '0')
.then(() => {
el.classList.toggle("bg-primary-600");
el.classList.toggle("bg-gray-400");
(el.childNodes.item(1) as HTMLElement).classList.toggle("translate-x-5");
});
};

2 changes: 2 additions & 0 deletions templates/base/admin_header.html
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ <h1 class="text-2xl font-bold leading-tight">Admin panel</h1>
{{ else }} text-gray-400 hover:text-slate-300 px-3 py-2 font-medium text-sm rounded-md {{ end }}" aria-current="page">Users</a>
<a href="/admin-panel/gists" class="{{ if eq .adminHeaderPage "gists" }}bg-gray-700 text-slate-300 hover:text-slate-300 px-3 py-2 font-medium text-sm rounded-md
{{ else }} text-gray-400 hover:text-slate-300 px-3 py-2 font-medium text-sm rounded-md {{ end }}" aria-current="page">Gists</a>
<a href="/admin-panel/settings" class="{{ if eq .adminHeaderPage "settings" }}bg-gray-700 text-slate-300 hover:text-slate-300 px-3 py-2 font-medium text-sm rounded-md
{{ else }} text-gray-400 hover:text-slate-300 px-3 py-2 font-medium text-sm rounded-md {{ end }}" aria-current="page">Admin settings</a>
</nav>
</div>
</div>
Expand Down
25 changes: 0 additions & 25 deletions templates/pages/admin_index.html
Original file line number Diff line number Diff line change
Expand Up @@ -71,32 +71,7 @@
</div>
</div>
</div>

<div class="sm:overflow-hidden ">
<div class="space-y-2 bg-gray-800 py-6 px-6 rounded-md border border-gray-700">
<div>
<span class="text-base font-bold leading-6 text-slate-300">Settings</span>
</div>
{{ .csrfHtml }}
<div class="space-y-2">
<div>
<label for="disable-signup" class="text-sm text-slate-300">Disable signup</label>
<input type="checkbox" id="disable-signup" name="disable-signup" {{ if .DisableSignup }}checked="checked"{{ end }} class="ml-1 h-4 w-4 rounded border-gray-300 text-primary-600 focus:ring-primary-600" />
</div>
<div>
<label for="require-login" class="text-sm text-slate-300">Require login</label>
<input type="checkbox" id="require-login" name="require-login" {{ if .RequireLogin }}checked="checked"{{ end }} class="ml-1 h-4 w-4 rounded border-gray-300 text-primary-600 focus:ring-primary-600" />
</div>
<div>
<label for="disable-login-form" class="text-sm text-slate-300">Disable login form</label>
<input type="checkbox" id="disable-login-form" name="disable-login-form" {{ if .DisableLoginForm }}checked="checked"{{ end }} class="ml-1 h-4 w-4 rounded border-gray-300 text-primary-600 focus:ring-primary-600" />
</div>
</div>
</div>
</div>
</div>

<script type="module" src="{{ asset "admin.ts" }}"></script>

{{ template "admin_footer" .}}
{{ template "footer" .}}
47 changes: 47 additions & 0 deletions templates/pages/admin_settings.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
{{ template "header" .}}
{{ template "admin_header" .}}

<div class="mx-auto max-w-lg px-4 py-2 sm:px-6 bg-gray-800 rounded-md border border-gray-700">

<ul role="list" class="divide-y divide-gray-100">
<li class="list-none gap-x-4 py-5">
<div class="flex items-center justify-between">
<span class="flex flex-grow flex-col">
<span class="text-sm font-medium leading-6 text-slate-300">Disable signup</span>
<span class="text-sm text-gray-400">Forbid the creation of new accounts.</span>
</span>
<button type="button" id="disable-signup" data-bool="{{ .DisableSignup }}" class="toggle-button {{ if .DisableSignup }}bg-primary-600{{else}}bg-gray-400{{end}} relative inline-flex h-6 w-11 ml-4 flex-shrink-0 cursor-pointer rounded-full border-2 border-transparent transition-colors duration-200 ease-in-out focus:outline-none focus:ring-2 focus:ring-primary-600 focus:ring-offset-2" role="switch" aria-checked="false" aria-labelledby="availability-label" aria-describedby="availability-description">
<span aria-hidden="true" class="{{ if .DisableSignup }}translate-x-5{{else}}translate-x-0{{end}} pointer-events-none inline-block h-5 w-5 transform rounded-full bg-white shadow ring-0 transition duration-200 ease-in-out"></span>
</button>
</div>
</li>
<li class="list-none gap-x-4 py-5">
<div class="flex items-center justify-between">
<span class="flex flex-grow flex-col">
<span class="text-sm font-medium leading-6 text-slate-300">Require login</span>
<span class="text-sm text-gray-400">Enforce users to be logged in to see gists.</span>
</span>
<button type="button" id="require-login" data-bool="{{ .RequireLogin }}" class="toggle-button {{ if .RequireLogin }}bg-primary-600{{else}}bg-gray-400{{end}} relative inline-flex h-6 w-11 ml-4 flex-shrink-0 cursor-pointer rounded-full border-2 border-transparent transition-colors duration-200 ease-in-out focus:outline-none focus:ring-2 focus:ring-primary-600 focus:ring-offset-2" role="switch" aria-checked="false" aria-labelledby="availability-label" aria-describedby="availability-description">
<span aria-hidden="true" class="{{ if .RequireLogin }}translate-x-5{{else}}translate-x-0{{end}} pointer-events-none inline-block h-5 w-5 transform rounded-full bg-white shadow ring-0 transition duration-200 ease-in-out"></span>
</button>
</div>
</li>
<li class="list-none gap-x-4 py-5">
<div class="flex items-center justify-between">
<span class="flex flex-grow flex-col">
<span class="text-sm font-medium leading-6 text-slate-300">Disable login form</span>
<span class="text-sm text-gray-400">Forbid logging in via the login form to force using OAuth providers instead.</span>
</span>
<button type="button" id="disable-login-form" data-bool="{{ .DisableLoginForm }}" class="toggle-button {{ if .DisableLoginForm }}bg-primary-600{{else}}bg-gray-400{{end}} relative inline-flex h-6 w-11 ml-4 flex-shrink-0 cursor-pointer rounded-full border-2 border-transparent transition-colors duration-200 ease-in-out focus:outline-none focus:ring-2 focus:ring-primary-600 focus:ring-offset-2" role="switch" aria-checked="false" aria-labelledby="availability-label" aria-describedby="availability-description">
<span aria-hidden="true" class="{{ if .DisableLoginForm }}translate-x-5{{else}}translate-x-0{{end}} pointer-events-none inline-block h-5 w-5 transform rounded-full bg-white shadow ring-0 transition duration-200 ease-in-out"></span>
</button>
</div>
</li>
</ul>
{{ .csrfHtml }}
</div>

<script type="module" src="{{ asset "admin.ts" }}"></script>

{{ template "admin_footer" .}}
{{ template "footer" .}}

0 comments on commit 5fe8416

Please sign in to comment.