171 lines
4.2 KiB
Text
171 lines
4.2 KiB
Text
package templates
|
|
|
|
templ UserDashboard() {
|
|
<div class="flex-between mb-2">
|
|
<h2>User Management</h2>
|
|
<button class="btn btn-primary"
|
|
hx-get="/admin/users/create-form"
|
|
hx-target="#form-container"
|
|
hx-swap="innerHTML">
|
|
+ Add User
|
|
</button>
|
|
</div>
|
|
|
|
<div id="form-container" class="mb-2"></div>
|
|
|
|
<div class="card" id="user-table-container">
|
|
<div class="flex-between mb-1">
|
|
<h2>Users</h2>
|
|
<button class="btn btn-sm btn-primary"
|
|
hx-get="/admin/api/users"
|
|
hx-target="#user-table-body"
|
|
hx-swap="innerHTML"
|
|
hx-trigger="load, click">
|
|
Refresh
|
|
</button>
|
|
</div>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Username</th>
|
|
<th>Display Name</th>
|
|
<th>Email</th>
|
|
<th>Groups</th>
|
|
<th>Status</th>
|
|
<th>Actions</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody id="user-table-body"
|
|
hx-get="/admin/api/users"
|
|
hx-trigger="load"
|
|
hx-swap="innerHTML">
|
|
<tr><td colspan="6" style="text-align:center;color:var(--text-muted);padding:2rem;">Loading users...</td></tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
}
|
|
|
|
templ UserRows(users []UserRow) {
|
|
for _, u := range users {
|
|
<tr>
|
|
<td><strong>{ u.Username }</strong></td>
|
|
<td>{ u.DisplayName }</td>
|
|
<td>{ u.Email }</td>
|
|
<td>{ u.Groups }</td>
|
|
<td>
|
|
if u.Disabled {
|
|
<span class="badge badge-danger">Disabled</span>
|
|
} else {
|
|
<span class="badge badge-success">Active</span>
|
|
}
|
|
</td>
|
|
<td>
|
|
<button class="btn btn-sm btn-danger"
|
|
hx-delete="/admin/api/users/{ u.Username }"
|
|
hx-confirm="Delete user { u.Username }?"
|
|
hx-target="closest tr"
|
|
hx-swap="delete">
|
|
Delete
|
|
</button>
|
|
</td>
|
|
</tr>
|
|
}
|
|
}
|
|
|
|
templ CreateUserForm() {
|
|
<div class="card" id="create-form">
|
|
<div class="flex-between mb-1">
|
|
<h2>Create New User</h2>
|
|
<button class="btn btn-sm btn-danger"
|
|
hx-get="/admin/users/cancel-form"
|
|
hx-target="#form-container"
|
|
hx-swap="innerHTML">
|
|
Cancel
|
|
</button>
|
|
</div>
|
|
<form hx-post="/admin/api/users"
|
|
hx-target="#form-container"
|
|
hx-swap="innerHTML">
|
|
<div class="form-row">
|
|
<div class="form-group">
|
|
<label>Username *</label>
|
|
<input type="text" name="username" class="form-input" required placeholder="e.g. jdoe"/>
|
|
</div>
|
|
<div class="form-group">
|
|
<label>Display Name</label>
|
|
<input type="text" name="display_name" class="form-input" placeholder="e.g. John Doe"/>
|
|
</div>
|
|
</div>
|
|
<div class="form-row">
|
|
<div class="form-group">
|
|
<label>Email</label>
|
|
<input type="email" name="email" class="form-input" placeholder="e.g. john@example.com"/>
|
|
</div>
|
|
<div class="form-group">
|
|
<label>Groups</label>
|
|
<input type="text" name="groups" class="form-input" placeholder="e.g. admins,users"/>
|
|
</div>
|
|
</div>
|
|
<button type="submit" class="btn btn-primary mt-2">Create User</button>
|
|
</form>
|
|
</div>
|
|
}
|
|
|
|
templ CreateUserSuccess(results []CreateUserResultRow) {
|
|
<div class="alert alert-success">
|
|
<strong>Users created successfully!</strong>
|
|
<div class="flex-between mt-2">
|
|
<span></span>
|
|
<button class="btn btn-sm btn-primary"
|
|
hx-get="/admin/users/create-form"
|
|
hx-target="#form-container"
|
|
hx-swap="innerHTML">
|
|
+ Add Another
|
|
</button>
|
|
</div>
|
|
</div>
|
|
for _, r := range results {
|
|
<div class="card">
|
|
<div class="flex-between">
|
|
<div>
|
|
<strong>{ r.Username }</strong>
|
|
if r.Error != "" {
|
|
<span class="badge badge-danger">Error</span>
|
|
} else {
|
|
<span class="badge badge-success">Created</span>
|
|
}
|
|
</div>
|
|
</div>
|
|
if r.Error != "" {
|
|
<p class="mt-2" style="color:var(--danger);">{ r.Error }</p>
|
|
} else {
|
|
<div class="mt-2">
|
|
<label style="font-size:0.75rem;color:var(--text-muted);">Generated Password (save this now)</label>
|
|
<div class="password-display">{ r.GeneratedPassword }</div>
|
|
</div>
|
|
}
|
|
</div>
|
|
}
|
|
<script type="text/javascript">
|
|
// Auto-refresh the user table after creation
|
|
setTimeout(function() {
|
|
htmx.trigger("#user-table-body", "click");
|
|
}, 500);
|
|
</script>
|
|
}
|
|
|
|
// Data types for template rendering
|
|
|
|
type UserRow struct {
|
|
Username string
|
|
DisplayName string
|
|
Email string
|
|
Groups string
|
|
Disabled bool
|
|
}
|
|
|
|
type CreateUserResultRow struct {
|
|
Username string
|
|
GeneratedPassword string
|
|
Error string
|
|
}
|