tailwind c ss

This commit is contained in:
fabio
2026-02-22 18:31:19 +01:00
parent 81245535b3
commit 0cd6ce05cd
15 changed files with 4742 additions and 89 deletions

View File

@@ -1,8 +1,10 @@
{{define "content"}}
<h1>Admin Dashboard</h1>
<p class="muted">Area amministrazione.</p>
<div class="row">
<a href="/admin/users">Gestione utenti</a>
<a href="/users">Vista utenti (private)</a>
<div class="space-y-3">
<h1 class="text-2xl font-semibold">Admin Dashboard</h1>
<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}}

View File

@@ -1,53 +1,59 @@
{{define "content"}}
<h1>Admin - Users</h1>
<p class="muted">Elenco utenti server-rendered.</p>
<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" method="get" action="/admin/users">
<input type="text" name="q" placeholder="Cerca nome o email" value="{{.PageData.Q}}">
<select name="sort" style="padding:10px;border:1px solid #d1d5db;border-radius:8px;">
<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 name="dir" style="padding:10px;border:1px solid #d1d5db;border-radius:8px;">
<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 type="number" name="pageSize" min="1" max="100" value="{{.PageData.PageSize}}" style="max-width:120px;">
<input type="hidden" name="page" value="1">
<button type="submit">Filtra</button>
</form>
<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>
<table style="width:100%;border-collapse:collapse;margin-top:16px;">
<thead>
<tr>
<th style="text-align:left;border-bottom:1px solid #e5e7eb;padding:8px;">ID</th>
<th style="text-align:left;border-bottom:1px solid #e5e7eb;padding:8px;">Name</th>
<th style="text-align:left;border-bottom:1px solid #e5e7eb;padding:8px;">Email</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;">Verified</th>
</tr>
</thead>
<tbody>
{{range .PageData.Users}}
<tr>
<td style="border-bottom:1px solid #f1f5f9;padding:8px;">{{.ID}}</td>
<td style="border-bottom:1px solid #f1f5f9;padding:8px;">{{if .Name}}{{.Name}}{{else}}-{{end}}</td>
<td style="border-bottom:1px solid #f1f5f9;padding:8px;">{{.Email}}</td>
<td style="border-bottom:1px solid #f1f5f9;padding:8px;">{{.Role}}</td>
<td style="border-bottom:1px solid #f1f5f9;padding:8px;">{{if .EmailVerified}}yes{{else}}no{{end}}</td>
</tr>
{{else}}
<tr><td colspan="5" style="padding:12px;">Nessun utente trovato.</td></tr>
{{end}}
</tbody>
</table>
<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" style="margin-top:12px;align-items:center;justify-content:space-between;">
<div class="muted">Totale: {{.PageData.Total}} utenti. Pagina {{.PageData.Page}}{{if gt .PageData.TotalPages 0}} / {{.PageData.TotalPages}}{{end}}</div>
<div class="row">
<a {{if not .PageData.HasPrev}}style="pointer-events:none;opacity:.5;"{{end}} href="/admin/users?q={{.PageData.Q}}&sort={{.PageData.Sort}}&dir={{.PageData.Dir}}&page={{.PageData.PrevPage}}&pageSize={{.PageData.PageSize}}">Prev</a>
<a {{if not .PageData.HasNext}}style="pointer-events:none;opacity:.5;"{{end}} href="/admin/users?q={{.PageData.Q}}&sort={{.PageData.Sort}}&dir={{.PageData.Dir}}&page={{.PageData.NextPage}}&pageSize={{.PageData.PageSize}}">Next</a>
<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}}

View File

@@ -4,40 +4,28 @@
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>{{.Title}}</title>
<style>
body { font-family: system-ui, sans-serif; margin: 0; background: #f5f7fb; color: #1f2937; }
nav { background: #111827; color: #fff; padding: 12px 16px; display: flex; gap: 12px; }
nav a { color: #e5e7eb; text-decoration: none; }
nav a.active { color: #fff; font-weight: 600; }
.container { max-width: 920px; margin: 20px auto; padding: 0 16px; }
.card { background: #fff; border-radius: 10px; padding: 20px; }
form { display: grid; gap: 10px; max-width: 420px; }
input { padding: 10px; border: 1px solid #d1d5db; border-radius: 8px; }
button { padding: 10px 14px; border: 0; border-radius: 8px; background: #111827; color: #fff; cursor: pointer; }
.muted { color: #6b7280; font-size: 0.95rem; }
.row { display: flex; gap: 10px; flex-wrap: wrap; }
</style>
<link rel="stylesheet" href="/static/css/app.css?v={{.BuildHash}}">
<link rel="stylesheet" href="/static/ui/ui.css?v={{.BuildHash}}">
<script src="https://unpkg.com/htmx.org@1.9.12"></script>
<script type="module" src="/static/ui/ui.esm.js?v={{.BuildHash}}"></script>
</head>
<body>
<nav>
<a href="/" class="{{if eq .NavSection "public"}}active{{end}}">Public</a>
<a href="/private" class="{{if eq .NavSection "private"}}active{{end}}">Private</a>
<nav class="flex gap-3 bg-slate-900 px-4 py-3 text-white">
<a href="/" class="text-slate-200 hover:text-white {{if eq .NavSection "public"}}font-semibold text-white{{end}}">Public</a>
<a href="/private" class="text-slate-200 hover:text-white {{if eq .NavSection "private"}}font-semibold text-white{{end}}">Private</a>
{{if and .CurrentUser (eq .CurrentUser.Role "admin")}}
<a href="/admin" class="{{if eq .NavSection "admin"}}active{{end}}">Admin</a>
<a href="/admin" class="text-slate-200 hover:text-white {{if eq .NavSection "admin"}}font-semibold text-white{{end}}">Admin</a>
{{end}}
{{if .CurrentUser}}
<form action="/logout" method="post" style="margin-left:auto;">
<button type="submit">Logout</button>
<form action="/logout" method="post" class="ml-auto">
<button type="submit" class="btn-primary">Logout</button>
</form>
{{end}}
</nav>
<div class="container">
<div class="mx-auto my-5 max-w-5xl px-4">
{{template "_flash.html" .}}
<div class="card">
<div class="rounded-xl bg-white p-5 shadow-sm">
{{template "content" .}}
</div>
</div>