genarato alcuni partials e corretto drop down

This commit is contained in:
fabio
2026-02-23 17:09:35 +01:00
parent 3fc01cc4f7
commit 2552b8ad8f
35 changed files with 587 additions and 221 deletions

View File

@@ -1,36 +1,36 @@
{{define "users_modal"}}
<div class="grid gap-3 text-sm text-gray-700 sm:grid-cols-2">
<div>
<span class="font-semibold text-gray-900">ID:</span>
<span class="font-semibold text-gray-900" data-i18n="table.id">ID</span>:
<span>{{.User.ID}}</span>
</div>
<div>
<span class="font-semibold text-gray-900">Role:</span>
<span class="font-semibold text-gray-900" data-i18n="table.role">Role</span>:
{{if eq .User.Role "admin"}}
<span class="rounded-sm bg-red-100 px-2.5 py-0.5 text-xs font-medium text-red-800">admin</span>
<span class="rounded-sm bg-red-100 px-2.5 py-0.5 text-xs font-medium text-red-800" data-i18n="user.role_admin">admin</span>
{{else}}
<span class="rounded-sm bg-blue-100 px-2.5 py-0.5 text-xs font-medium text-blue-800">user</span>
<span class="rounded-sm bg-blue-100 px-2.5 py-0.5 text-xs font-medium text-blue-800" data-i18n="user.role_user">user</span>
{{end}}
</div>
<div class="sm:col-span-2">
<span class="font-semibold text-gray-900">Name:</span>
<span class="font-semibold text-gray-900" data-i18n="table.name">Name</span>:
<span>{{if .User.Name}}{{.User.Name}}{{else}}-{{end}}</span>
</div>
<div class="sm:col-span-2">
<span class="font-semibold text-gray-900">Email:</span>
<span class="font-semibold text-gray-900" data-i18n="table.email">Email</span>:
<span>{{.User.Email}}</span>
</div>
<div>
<span class="font-semibold text-gray-900">Verified:</span>
<span>{{if .User.EmailVerified}}yes{{else}}no{{end}}</span>
<span class="font-semibold text-gray-900" data-i18n="user.verified">Verified</span>:
<span>{{if .User.EmailVerified}}<span data-i18n="user.yes">yes</span>{{else}}<span data-i18n="user.no">no</span>{{end}}</span>
</div>
<div>
<span class="font-semibold text-gray-900">Created:</span>
<span>{{.User.CreatedAt}}</span>
<span class="font-semibold text-gray-900" data-i18n="user.created">Created</span>:
<span data-localize-date="{{.User.CreatedAt.Format "2006-01-02T15:04:05Z07:00"}}">{{.User.CreatedAt}}</span>
</div>
</div>
<div class="mt-5">
<button type="button" class="rounded-lg bg-blue-700 px-5 py-2.5 text-sm font-medium text-white hover:bg-blue-800" data-modal-hide="userModal">Chiudi</button>
<button type="button" class="rounded-lg bg-blue-700 px-5 py-2.5 text-sm font-medium text-white hover:bg-blue-800" data-modal-hide="userModal" data-i18n="users.close">Chiudi</button>
</div>
{{end}}

View File

@@ -5,16 +5,16 @@
<thead class="bg-gray-50 text-xs uppercase text-gray-700">
<tr>
<th scope="col" class="px-6 py-3">
<button type="button" class="inline-flex items-center gap-1 hover:text-blue-700" 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</button>
<button type="button" class="inline-flex items-center gap-1 hover:text-blue-700" 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" data-i18n="table.id">ID</button>
</th>
<th scope="col" class="px-6 py-3">
<button type="button" class="inline-flex items-center gap-1 hover:text-blue-700" 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</button>
<button type="button" class="inline-flex items-center gap-1 hover:text-blue-700" 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" data-i18n="table.name">Name</button>
</th>
<th scope="col" class="px-6 py-3">
<button type="button" class="inline-flex items-center gap-1 hover:text-blue-700" 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</button>
<button type="button" class="inline-flex items-center gap-1 hover:text-blue-700" 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" data-i18n="table.email">Email</button>
</th>
<th scope="col" class="px-6 py-3">Role</th>
<th scope="col" class="px-6 py-3">Azioni</th>
<th scope="col" class="px-6 py-3" data-i18n="table.role">Role</th>
<th scope="col" class="px-6 py-3" data-i18n="users.actions">Azioni</th>
</tr>
</thead>
<tbody>
@@ -25,18 +25,18 @@
<td class="px-6 py-4">{{$u.Email}}</td>
<td class="px-6 py-4">
{{if eq $u.Role "admin"}}
<span class="rounded-sm bg-red-100 px-2.5 py-0.5 text-xs font-medium text-red-800">admin</span>
<span class="rounded-sm bg-red-100 px-2.5 py-0.5 text-xs font-medium text-red-800" data-i18n="user.role_admin">admin</span>
{{else}}
<span class="rounded-sm bg-blue-100 px-2.5 py-0.5 text-xs font-medium text-blue-800">user</span>
<span class="rounded-sm bg-blue-100 px-2.5 py-0.5 text-xs font-medium text-blue-800" data-i18n="user.role_user">user</span>
{{end}}
</td>
<td class="px-6 py-4">
<button type="button" class="rounded-lg bg-blue-700 px-3 py-2 text-xs font-medium text-white hover:bg-blue-800" data-modal-target="userModal" data-modal-toggle="userModal" hx-get="/admin/users/{{$u.ID}}/modal" hx-target="#userModalContent" hx-swap="innerHTML">Apri</button>
<button type="button" class="rounded-lg bg-blue-700 px-3 py-2 text-xs font-medium text-white hover:bg-blue-800" data-modal-target="userModal" data-modal-toggle="userModal" hx-get="/admin/users/{{$u.ID}}/modal" hx-target="#userModalContent" hx-swap="innerHTML" data-i18n="users.open">Apri</button>
</td>
</tr>
{{else}}
<tr class="bg-white">
<td colspan="5" class="px-6 py-4 text-center text-gray-500">Nessun utente trovato.</td>
<td colspan="5" class="px-6 py-4 text-center text-gray-500" data-i18n="users.none">Nessun utente trovato.</td>
</tr>
{{end}}
</tbody>
@@ -44,10 +44,10 @@
</div>
<div class="mt-4 flex flex-wrap items-center justify-between gap-3">
<div class="text-sm text-gray-600">Totale: {{$p.Total}} utenti. Pagina {{$p.Page}}{{if gt $p.TotalPages 0}} / {{$p.TotalPages}}{{end}}</div>
<div class="text-sm text-gray-600"><span data-i18n="users.total">Totale</span>: {{$p.Total}} <span data-i18n="users.users_label">utenti</span>. <span data-i18n="users.page">Pagina</span> {{$p.Page}}{{if gt $p.TotalPages 0}} / {{$p.TotalPages}}{{end}}</div>
<div class="inline-flex gap-2">
<button type="button" class="rounded-lg border border-gray-300 bg-white px-4 py-2 text-sm font-medium text-gray-900 hover:bg-gray-100 disabled:cursor-not-allowed disabled:opacity-50" {{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 type="button" class="rounded-lg border border-gray-300 bg-white px-4 py-2 text-sm font-medium text-gray-900 hover:bg-gray-100 disabled:cursor-not-allowed disabled:opacity-50" {{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>
<button type="button" class="rounded-lg border border-gray-300 bg-white px-4 py-2 text-sm font-medium text-gray-900 hover:bg-gray-100 disabled:cursor-not-allowed disabled:opacity-50" {{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" data-i18n="users.prev">Prev</button>
<button type="button" class="rounded-lg border border-gray-300 bg-white px-4 py-2 text-sm font-medium text-gray-900 hover:bg-gray-100 disabled:cursor-not-allowed disabled:opacity-50" {{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" data-i18n="users.next">Next</button>
</div>
</div>
{{end}}

View File

@@ -2,25 +2,25 @@
<section class="space-y-6">
<div class="flex flex-wrap items-center justify-between gap-3">
<div>
<h1 class="text-3xl font-bold text-gray-900">Users</h1>
<p class="text-gray-600">Ricerca, ordinamento e paging server-side via HTMX.</p>
<h1 class="text-3xl font-bold text-gray-900" data-i18n="users.title">Users</h1>
<p class="text-gray-600" data-i18n="users.subtitle">Ricerca, ordinamento e paging server-side via HTMX.</p>
</div>
<button type="button" data-modal-target="newUserModal" data-modal-toggle="newUserModal" class="inline-flex items-center rounded-lg bg-blue-700 px-5 py-2.5 text-sm font-medium text-white hover:bg-blue-800 focus:outline-none focus:ring-4 focus:ring-blue-300">
<button type="button" data-modal-target="newUserModal" data-modal-toggle="newUserModal" class="inline-flex items-center rounded-lg bg-blue-700 px-5 py-2.5 text-sm font-medium text-white hover:bg-blue-800 focus:outline-none focus:ring-4 focus:ring-blue-300" data-i18n="users.new_user">
Nuovo Utente
</button>
</div>
<form id="usersFilters" class="grid gap-3 rounded-lg border border-gray-200 bg-white p-4 shadow-sm md:grid-cols-4" hx-get="/admin/users/table" hx-target="#usersTableContainer" hx-swap="innerHTML">
<div class="md:col-span-2">
<label for="users-q" class="mb-2 block text-sm font-medium text-gray-900">Search</label>
<input id="users-q" type="text" name="q" placeholder="Cerca nome o email" value="{{.PageData.Q}}" class="block w-full rounded-lg border border-gray-300 bg-gray-50 p-2.5 text-sm text-gray-900 focus:border-blue-500 focus:ring-blue-500">
<label for="users-q" class="mb-2 block text-sm font-medium text-gray-900" data-i18n="users.search">Search</label>
<input id="users-q" type="text" name="q" placeholder="Cerca nome o email" data-i18n-placeholder="users.search_placeholder" value="{{.PageData.Q}}" class="block w-full rounded-lg border border-gray-300 bg-gray-50 p-2.5 text-sm text-gray-900 focus:border-blue-500 focus:ring-blue-500">
</div>
<div>
<label for="users-size" class="mb-2 block text-sm font-medium text-gray-900">Page size</label>
<label for="users-size" class="mb-2 block text-sm font-medium text-gray-900" data-i18n="users.page_size">Page size</label>
<input id="users-size" type="number" name="pageSize" min="1" max="100" value="{{.PageData.PageSize}}" class="block w-full rounded-lg border border-gray-300 bg-gray-50 p-2.5 text-sm text-gray-900 focus:border-blue-500 focus:ring-blue-500">
</div>
<div class="flex items-end">
<button type="submit" class="w-full rounded-lg bg-blue-700 px-5 py-2.5 text-sm font-medium text-white hover:bg-blue-800 focus:outline-none focus:ring-4 focus:ring-blue-300">Cerca</button>
<button type="submit" class="w-full rounded-lg bg-blue-700 px-5 py-2.5 text-sm font-medium text-white hover:bg-blue-800 focus:outline-none focus:ring-4 focus:ring-blue-300" data-i18n="users.search_button">Cerca</button>
</div>
<input type="hidden" name="sort" value="{{.PageData.Sort}}">
<input type="hidden" name="dir" value="{{.PageData.Dir}}">
@@ -36,9 +36,9 @@
<div class="relative max-h-full w-full max-w-2xl">
<div class="relative rounded-lg bg-white shadow-sm">
<div class="flex items-start justify-between rounded-t border-b p-4 md:p-5">
<h3 class="text-xl font-semibold text-gray-900">Dettaglio utente</h3>
<h3 class="text-xl font-semibold text-gray-900" data-i18n="users.user_detail">Dettaglio utente</h3>
<button type="button" class="ms-auto inline-flex h-8 w-8 items-center justify-center rounded-lg bg-transparent text-sm text-gray-400 hover:bg-gray-200 hover:text-gray-900" data-modal-hide="userModal" aria-label="Close modal">
<span class="sr-only">Close modal</span>
<span class="sr-only" data-i18n="users.close">Close modal</span>
<svg class="h-3 w-3" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 14 14">
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="m1 1 6 6m0 0 6 6M7 7l6-6M7 7l-6 6" />
</svg>
@@ -53,18 +53,18 @@
<div class="relative max-h-full w-full max-w-xl">
<div class="relative rounded-lg bg-white shadow-sm">
<div class="flex items-start justify-between rounded-t border-b p-4 md:p-5">
<h3 class="text-xl font-semibold text-gray-900">Nuovo utente</h3>
<h3 class="text-xl font-semibold text-gray-900" data-i18n="users.new_user_modal_title">Nuovo utente</h3>
<button type="button" class="ms-auto inline-flex h-8 w-8 items-center justify-center rounded-lg bg-transparent text-sm text-gray-400 hover:bg-gray-200 hover:text-gray-900" data-modal-hide="newUserModal" aria-label="Close modal">
<span class="sr-only">Close modal</span>
<span class="sr-only" data-i18n="users.close">Close modal</span>
<svg class="h-3 w-3" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 14 14">
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="m1 1 6 6m0 0 6 6M7 7l6-6M7 7l-6 6" />
</svg>
</button>
</div>
<div class="space-y-4 p-4 md:p-5">
<p class="text-sm text-gray-600">Placeholder UI Flowbite. La creazione utente può essere collegata a una route backend quando disponibile.</p>
<p class="text-sm text-gray-600" data-i18n="users.new_user_modal_placeholder">Placeholder UI Flowbite. La creazione utente può essere collegata a una route backend quando disponibile.</p>
<div>
<label for="new-user-email" class="mb-2 block text-sm font-medium text-gray-900">Email</label>
<label for="new-user-email" class="mb-2 block text-sm font-medium text-gray-900" data-i18n="form.email">Email</label>
<input id="new-user-email" type="email" class="block w-full rounded-lg border border-gray-300 bg-gray-50 p-2.5 text-sm text-gray-900" placeholder="name@company.com" disabled>
</div>
</div>