tempalte admin users

This commit is contained in:
JACS 2026-05-03 01:58:18 -05:00
parent 7f3bfb7d59
commit f06d22072e
6 changed files with 158 additions and 8 deletions

View file

@ -225,6 +225,29 @@ func UserLock(c *core.Context) *core.Response {
return c.Response.Template("apptabler_auth-lock.html", data) return c.Response.Template("apptabler_auth-lock.html", data)
} }
// AdminUsers renders the admin users listing page.
func AdminUsers(c *core.Context) *core.Response {
type adminUsersPageData struct {
TablerPageData
AdminUsers AdminUsersPage
}
data := adminUsersPageData{
TablerPageData: TablerPageData{
PageTitle: "Admin Users",
PageDescription: "Manage system users",
ShowTopbar: true,
Sidebar: false,
PageHeader: "Admin Users",
PagePretitle: "User Management",
UserName: "Jane Doe",
UserRole: "Administrator",
NavbarMenu: SampleNavbarMenu(),
},
AdminUsers: SampleAdminUsers(),
}
return c.Response.Template("apptabler_admin-users.html", data)
}
// UserSettings renders the user settings page. // UserSettings renders the user settings page.
func UserSettings(c *core.Context) *core.Response { func UserSettings(c *core.Context) *core.Response {
type userSettingsPageData struct { type userSettingsPageData struct {
@ -242,7 +265,6 @@ func UserSettings(c *core.Context) *core.Response {
UserName: "Jane Doe", UserName: "Jane Doe",
UserRole: "Administrator", UserRole: "Administrator",
NavbarMenu: SampleNavbarMenu(), NavbarMenu: SampleNavbarMenu(),
Content: nil,
}, },
UserSettings: SampleUserSettings(), UserSettings: SampleUserSettings(),
} }

View file

@ -44,6 +44,20 @@ func SampleNavbarMenu() TablerMenu {
} }
} }
// SampleAdminUsers returns sample data for the admin users page.
func SampleAdminUsers() AdminUsersPage {
return AdminUsersPage{
AddLink: "/admin/users/add",
Users: []AdminUserRow{
{Name: "Paweł Kuna", Email: "pawel.kuna@example.com", Status: "Active", Roles: "Administrator, Editor", EditLink: "/admin/users/edit/1"},
{Name: "Jane Doe", Email: "jane.doe@example.com", Status: "Active", Roles: "Editor", EditLink: "/admin/users/edit/2"},
{Name: "Jeffie Lewzey", Email: "jlewzey@seesaa.net", Status: "Invited", Roles: "Viewer", EditLink: "/admin/users/edit/3"},
{Name: "Mallory Hulme", Email: "mhulme@domainmarket.com", Status: "Active", Roles: "Administrator", EditLink: "/admin/users/edit/4"},
{Name: "Dunn Slane", Email: "dslane@epa.gov", Status: "Inactive", Roles: "Editor, Viewer", EditLink: "/admin/users/edit/5"},
},
}
}
// SampleUserSettings returns sample data for the user settings page. // SampleUserSettings returns sample data for the user settings page.
func SampleUserSettings() FormtablerUserSettingsPage { func SampleUserSettings() FormtablerUserSettingsPage {
return FormtablerUserSettingsPage{ return FormtablerUserSettingsPage{

View file

@ -500,6 +500,21 @@ type FormtablerUserSettingsPage struct {
ActiveTab string ActiveTab string
} }
// AdminUserRow represents a single user in the admin users list.
type AdminUserRow struct {
Name string
Email string
Status string // "Active", "Inactive", "Invited"
Roles string // comma-separated role names
EditLink string
}
// AdminUsersPage holds the data for the admin users page.
type AdminUsersPage struct {
Users []AdminUserRow
AddLink string
}
// AuthLockPageData holds the data for the account lock page. // AuthLockPageData holds the data for the account lock page.
type AuthLockPageData struct { type AuthLockPageData struct {
PersonName string PersonName string

View file

@ -36,8 +36,8 @@ func registerRoutes() {
controller.Post("/reset-password/code/:code", controllers.SetNewPassword) controller.Post("/reset-password/code/:code", controllers.SetNewPassword)
// Uncomment the lines below to enable user administration // Uncomment the lines below to enable user administration
controller.Get("/admin/users", controllers.AdminUsersList) //controller.Get("/admin/users", controllers.AdminUsersList)
controller.Post("/admin/users", controllers.AdminUsersList) //controller.Post("/admin/users", controllers.AdminUsersList)
controller.Get("/admin/users/add", controllers.AdminUsersAdd) controller.Get("/admin/users/add", controllers.AdminUsersAdd)
controller.Post("/admin/users/add", controllers.AdminUsersAdd) controller.Post("/admin/users/add", controllers.AdminUsersAdd)
controller.Get("/admin/users/edit/:id", controllers.AdminUsersEdit) controller.Get("/admin/users/edit/:id", controllers.AdminUsersEdit)
@ -80,9 +80,12 @@ func registerRoutes() {
controller.Get("/user/settings", controllers.UserSettings) controller.Get("/user/settings", controllers.UserSettings)
controller.Post("/user/settings", controllers.UserSettings) controller.Post("/user/settings", controllers.UserSettings)
controller.Get("/tablertable", controllers.TablerTables) controller.Get("/admin/users", controllers.AdminUsers)
controller.Get("/tablerformelements", controllers.TablerFormElements) controller.Post("/admin/users", controllers.AdminUsers)
controller.Get("/tablercards", controllers.TablerCards)
controller.Get("/tablercomponents", controllers.TablerComponents) controller.Get("/tablertable", controllers.TablerTables)
controller.Get("/tablerformelements", controllers.TablerFormElements)
controller.Get("/tablercards", controllers.TablerCards)
controller.Get("/tablercomponents", controllers.TablerComponents)
} }

View file

@ -0,0 +1,96 @@
{{template "base_header" .}}
{{$admin := .AdminUsers}}
<div class="page">
{{if .ShowTopbar}}
{{template "tabler_navbar" .}}
{{end}}
<div class="page-wrapper">
{{if .PageHeader}}
<div class="page-header d-print-none">
<div class="container-xl">
<div class="row g-2 align-items-center">
<div class="col">
{{if .PagePretitle}}
<div class="page-pretitle">
{{.PagePretitle}}
</div>
{{end}}
<h1 class="page-title">
{{.PageHeader}}
</h1>
</div>
<div class="col-auto ms-auto d-print-none">
<div class="btn-list">
<a href="{{$admin.AddLink}}" class="btn btn-primary d-none d-sm-inline-block">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon"><path d="M12 5l0 14"></path><path d="M5 12l14 0"></path></svg>
Create new user
</a>
</div>
</div>
</div>
</div>
</div>
{{end}}
<div class="page-body">
<div class="container-xl">
<div class="card">
<div class="table-responsive">
<table class="table table-vcenter card-table">
<thead>
<tr>
<th>Name</th>
<th>Email</th>
<th>Status</th>
<th>Roles</th>
<th class="w-1"></th>
</tr>
</thead>
<tbody>
{{range $admin.Users}}
<tr>
<td>
<div class="d-flex py-1 align-items-center">
<span class="avatar avatar-sm me-2" style="background-image: url(/static/avatars/{{.Name | truncate 3}}.jpg)"></span>
<div class="flex-fill">
<div class="font-weight-medium">{{.Name}}</div>
</div>
</div>
</td>
<td class="text-secondary">{{.Email}}</td>
<td>
{{if eq .Status "Active"}}
<span class="status-dot status-dot-animated bg-green"></span>
{{else if eq .Status "Inactive"}}
<span class="status-dot bg-muted"></span>
{{else if eq .Status "Invited"}}
<span class="status-dot bg-blue"></span>
{{end}}
{{.Status}}
</td>
<td>
<div class="row g-1">
{{range split ", " .Roles}}
<div class="col-auto">
<span class="badge bg-blue-lt text-uppercase">{{.}}</span>
</div>
{{end}}
</div>
</td>
<td>
<a href="{{.EditLink}}" class="btn btn-ghost btn-sm">Edit</a>
</td>
</tr>
{{end}}
</tbody>
</table>
</div>
</div>
</div>
</div>
{{template "tabler_footer" .}}
</div>
</div>
{{template "base_footer" .}}

View file

@ -21,7 +21,7 @@
<td> <td>
{{if eq .Type "avatar"}} {{if eq .Type "avatar"}}
<div class="d-flex py-1 align-items-center"> <div class="d-flex py-1 align-items-center">
<span class="avatar me-2" style="background-image: url(/static/avatars/{{.AvatarID}}.jpg)"></span> <span class="avatar me-2" style="background-image: url(/public/static/avatars/{{.AvatarID}}.jpg)"></span>
<div class="flex-fill"> <div class="flex-fill">
<div class="font-weight-medium">{{.Value}}</div> <div class="font-weight-medium">{{.Value}}</div>
{{if .Subtext}}<div class="text-secondary"><a href="#" class="text-reset">{{.Subtext}}</a></div>{{end}} {{if .Subtext}}<div class="text-secondary"><a href="#" class="text-reset">{{.Subtext}}</a></div>{{end}}