adattato html, test htmx con componente svelte
This commit is contained in:
@@ -4,7 +4,6 @@
|
||||
<p class="muted">Area amministrazione.</p>
|
||||
<div class="row">
|
||||
<a href="/admin/users" class="rounded-lg border border-slate-300 px-4 py-2 hover:bg-slate-50">Gestione utenti</a>
|
||||
<a href="/users" class="rounded-lg border border-slate-300 px-4 py-2 hover:bg-slate-50">Vista utenti (private)</a>
|
||||
</div>
|
||||
</div>
|
||||
{{end}}
|
||||
|
||||
@@ -1,59 +0,0 @@
|
||||
{{define "content"}}
|
||||
<div class="space-y-4">
|
||||
<div>
|
||||
<h1 class="text-2xl font-semibold">Admin - Users</h1>
|
||||
<p class="muted">Elenco utenti server-rendered.</p>
|
||||
</div>
|
||||
|
||||
<form class="row items-center" method="get" action="/admin/users">
|
||||
<input class="input-base" type="text" name="q" placeholder="Cerca nome o email" value="{{.PageData.Q}}">
|
||||
<select class="input-base" name="sort">
|
||||
<option value="id" {{if eq .PageData.Sort "id"}}selected{{end}}>ID</option>
|
||||
<option value="name" {{if eq .PageData.Sort "name"}}selected{{end}}>Name</option>
|
||||
<option value="email" {{if eq .PageData.Sort "email"}}selected{{end}}>Email</option>
|
||||
</select>
|
||||
<select class="input-base" name="dir">
|
||||
<option value="asc" {{if eq .PageData.Dir "asc"}}selected{{end}}>ASC</option>
|
||||
<option value="desc" {{if eq .PageData.Dir "desc"}}selected{{end}}>DESC</option>
|
||||
</select>
|
||||
<input class="input-base w-28" type="number" name="pageSize" min="1" max="100" value="{{.PageData.PageSize}}">
|
||||
<input type="hidden" name="page" value="1">
|
||||
<button class="btn-primary" type="submit">Filtra</button>
|
||||
</form>
|
||||
|
||||
<div class="overflow-x-auto">
|
||||
<table class="w-full border-collapse">
|
||||
<thead>
|
||||
<tr class="border-b border-slate-200 text-left">
|
||||
<th class="px-2 py-2">ID</th>
|
||||
<th class="px-2 py-2">Name</th>
|
||||
<th class="px-2 py-2">Email</th>
|
||||
<th class="px-2 py-2">Role</th>
|
||||
<th class="px-2 py-2">Verified</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{{range .PageData.Users}}
|
||||
<tr class="border-b border-slate-100">
|
||||
<td class="px-2 py-2">{{.ID}}</td>
|
||||
<td class="px-2 py-2">{{if .Name}}{{.Name}}{{else}}-{{end}}</td>
|
||||
<td class="px-2 py-2">{{.Email}}</td>
|
||||
<td class="px-2 py-2">{{.Role}}</td>
|
||||
<td class="px-2 py-2">{{if .EmailVerified}}yes{{else}}no{{end}}</td>
|
||||
</tr>
|
||||
{{else}}
|
||||
<tr><td colspan="5" class="px-2 py-3">Nessun utente trovato.</td></tr>
|
||||
{{end}}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="row items-center justify-between">
|
||||
<div class="muted">Totale: {{.PageData.Total}} utenti. Pagina {{.PageData.Page}}{{if gt .PageData.TotalPages 0}} / {{.PageData.TotalPages}}{{end}}</div>
|
||||
<div class="row">
|
||||
<a class="rounded border border-slate-300 px-3 py-1.5 hover:bg-slate-50 {{if not .PageData.HasPrev}}pointer-events-none opacity-50{{end}}" href="/admin/users?q={{.PageData.Q}}&sort={{.PageData.Sort}}&dir={{.PageData.Dir}}&page={{.PageData.PrevPage}}&pageSize={{.PageData.PageSize}}">Prev</a>
|
||||
<a class="rounded border border-slate-300 px-3 py-1.5 hover:bg-slate-50 {{if not .PageData.HasNext}}pointer-events-none opacity-50{{end}}" href="/admin/users?q={{.PageData.Q}}&sort={{.PageData.Sort}}&dir={{.PageData.Dir}}&page={{.PageData.NextPage}}&pageSize={{.PageData.PageSize}}">Next</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{end}}
|
||||
13
web/templates/admin/users/_modal.html
Normal file
13
web/templates/admin/users/_modal.html
Normal file
@@ -0,0 +1,13 @@
|
||||
{{define "users_modal"}}
|
||||
<div style="padding:16px;">
|
||||
<h3 style="margin-top:0;">Dettaglio utente #{{.User.ID}}</h3>
|
||||
<p><strong>Name:</strong> {{if .User.Name}}{{.User.Name}}{{else}}-{{end}}</p>
|
||||
<p><strong>Email:</strong> {{.User.Email}}</p>
|
||||
<p><strong>Role:</strong> {{.User.Role}}</p>
|
||||
<p><strong>Verified:</strong> {{if .User.EmailVerified}}yes{{else}}no{{end}}</p>
|
||||
<p><strong>Created:</strong> {{.User.CreatedAt}}</p>
|
||||
<div class="row">
|
||||
<button type="button" onclick="document.getElementById('userModal').removeAttribute('open')">Chiudi</button>
|
||||
</div>
|
||||
</div>
|
||||
{{end}}
|
||||
47
web/templates/admin/users/_table.html
Normal file
47
web/templates/admin/users/_table.html
Normal file
@@ -0,0 +1,47 @@
|
||||
{{define "users_table"}}
|
||||
{{ $p := .PageData }}
|
||||
<table style="width:100%;border-collapse:collapse;margin-top:16px;">
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="text-align:left;border-bottom:1px solid #e5e7eb;padding:8px;">
|
||||
<a href="#" hx-get="/admin/users/table?q={{$p.Q}}&sort=id&dir={{if and (eq $p.Sort "id") (eq $p.Dir "asc")}}desc{{else}}asc{{end}}&page=1&pageSize={{$p.PageSize}}" hx-target="#usersTableContainer" hx-swap="innerHTML">ID</a>
|
||||
</th>
|
||||
<th style="text-align:left;border-bottom:1px solid #e5e7eb;padding:8px;">
|
||||
<a href="#" hx-get="/admin/users/table?q={{$p.Q}}&sort=name&dir={{if and (eq $p.Sort "name") (eq $p.Dir "asc")}}desc{{else}}asc{{end}}&page=1&pageSize={{$p.PageSize}}" hx-target="#usersTableContainer" hx-swap="innerHTML">Name</a>
|
||||
</th>
|
||||
<th style="text-align:left;border-bottom:1px solid #e5e7eb;padding:8px;">
|
||||
<a href="#" hx-get="/admin/users/table?q={{$p.Q}}&sort=email&dir={{if and (eq $p.Sort "email") (eq $p.Dir "asc")}}desc{{else}}asc{{end}}&page=1&pageSize={{$p.PageSize}}" hx-target="#usersTableContainer" hx-swap="innerHTML">Email</a>
|
||||
</th>
|
||||
<th style="text-align:left;border-bottom:1px solid #e5e7eb;padding:8px;">Role</th>
|
||||
<th style="text-align:left;border-bottom:1px solid #e5e7eb;padding:8px;">Azioni</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{{range $u := $p.Users}}
|
||||
<tr>
|
||||
<td style="border-bottom:1px solid #f1f5f9;padding:8px;">{{$u.ID}}</td>
|
||||
<td style="border-bottom:1px solid #f1f5f9;padding:8px;">{{if $u.Name}}{{$u.Name}}{{else}}-{{end}}</td>
|
||||
<td style="border-bottom:1px solid #f1f5f9;padding:8px;">{{$u.Email}}</td>
|
||||
<td style="border-bottom:1px solid #f1f5f9;padding:8px;">{{$u.Role}}</td>
|
||||
<td style="border-bottom:1px solid #f1f5f9;padding:8px;">
|
||||
<button
|
||||
hx-get="/admin/users/{{$u.ID}}/modal"
|
||||
hx-target="#userModalContent"
|
||||
hx-swap="innerHTML"
|
||||
>Apri</button>
|
||||
</td>
|
||||
</tr>
|
||||
{{else}}
|
||||
<tr><td colspan="5" style="padding:12px;">Nessun utente trovato.</td></tr>
|
||||
{{end}}
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<div class="row" style="margin-top:12px;align-items:center;justify-content:space-between;">
|
||||
<div class="muted">Totale: {{$p.Total}} utenti. Pagina {{$p.Page}}{{if gt $p.TotalPages 0}} / {{$p.TotalPages}}{{end}}</div>
|
||||
<div class="row">
|
||||
<button {{if not $p.HasPrev}}disabled{{end}} hx-get="/admin/users/table?q={{$p.Q}}&sort={{$p.Sort}}&dir={{$p.Dir}}&page={{$p.PrevPage}}&pageSize={{$p.PageSize}}" hx-target="#usersTableContainer" hx-swap="innerHTML">Prev</button>
|
||||
<button {{if not $p.HasNext}}disabled{{end}} hx-get="/admin/users/table?q={{$p.Q}}&sort={{$p.Sort}}&dir={{$p.Dir}}&page={{$p.NextPage}}&pageSize={{$p.PageSize}}" hx-target="#usersTableContainer" hx-swap="innerHTML">Next</button>
|
||||
</div>
|
||||
</div>
|
||||
{{end}}
|
||||
36
web/templates/admin/users/index.html
Normal file
36
web/templates/admin/users/index.html
Normal file
@@ -0,0 +1,36 @@
|
||||
{{define "content"}}
|
||||
<h1>Users</h1>
|
||||
<p class="muted">Ricerca, ordinamento e paging server-side via HTMX.</p>
|
||||
|
||||
<form id="usersFilters" class="row" hx-get="/admin/users/table" hx-target="#usersTableContainer" hx-swap="innerHTML">
|
||||
<input type="text" name="q" placeholder="Cerca nome o email" value="{{.PageData.Q}}">
|
||||
<input type="number" name="pageSize" min="1" max="100" value="{{.PageData.PageSize}}" style="max-width:120px;">
|
||||
<input type="hidden" name="sort" value="{{.PageData.Sort}}">
|
||||
<input type="hidden" name="dir" value="{{.PageData.Dir}}">
|
||||
<input type="hidden" name="page" value="1">
|
||||
<button type="submit">Cerca</button>
|
||||
</form>
|
||||
|
||||
<div id="usersTableContainer" hx-get="/admin/users/table?q={{.PageData.Q}}&sort={{.PageData.Sort}}&dir={{.PageData.Dir}}&page={{.PageData.Page}}&pageSize={{.PageData.PageSize}}" hx-trigger="load" hx-swap="innerHTML">
|
||||
{{template "users_table" .}}
|
||||
</div>
|
||||
|
||||
<ui-modal id="userModal" title="Dettaglio utente">
|
||||
<div
|
||||
id="userModalContent"
|
||||
hx-on:htmx:after-swap="document.getElementById('userModal').setAttribute('open','')"
|
||||
></div>
|
||||
</ui-modal>
|
||||
|
||||
<script>
|
||||
(function () {
|
||||
var modal = document.getElementById('userModal');
|
||||
var content = document.getElementById('userModalContent');
|
||||
if (!modal || !content || modal.dataset.closeBound === '1') return;
|
||||
modal.dataset.closeBound = '1';
|
||||
modal.addEventListener('ui:close', function () {
|
||||
content.innerHTML = '';
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
{{end}}
|
||||
Reference in New Issue
Block a user