fix
This commit is contained in:
257
internal/server/templates/pages/admin.templ
Normal file
257
internal/server/templates/pages/admin.templ
Normal file
@@ -0,0 +1,257 @@
|
||||
package pages
|
||||
|
||||
import (
|
||||
"git.ma-al.com/goc_marek/zfs/internal/server/templates/components"
|
||||
)
|
||||
|
||||
// AdminPage renders the main admin panel
|
||||
templ AdminPage(username string) {
|
||||
@components.Layout("ZFS Backup Admin Panel", username) {
|
||||
<div class="max-w-7xl mx-auto px-6">
|
||||
@components.Header(username)
|
||||
|
||||
<!-- Stats Grid -->
|
||||
<div id="stats-grid" class="grid grid-cols-1 md:grid-cols-3 gap-6 mb-8">
|
||||
@components.StatsCard("Clients", "Loading...")
|
||||
@components.StatsCard("Total Snapshots", "Loading...")
|
||||
@components.StatsCard("Total Storage", "Loading...")
|
||||
</div>
|
||||
|
||||
<!-- Tabs -->
|
||||
<div class="flex gap-3 mb-6">
|
||||
@components.TabButton("clients", "Clients", true)
|
||||
@components.TabButton("snapshots", "Snapshots", false)
|
||||
@components.TabButton("admins", "Admins", false)
|
||||
</div>
|
||||
|
||||
<!-- Clients Tab -->
|
||||
<div id="clients-tab">
|
||||
<div class="bg-surface rounded-xl border border-gray-700 overflow-hidden">
|
||||
<div class="p-6 border-b border-gray-700 flex justify-between items-center">
|
||||
<h3 class="text-lg font-semibold text-white flex items-center gap-2">
|
||||
<i class="fas fa-users text-primary"></i>
|
||||
Clients
|
||||
</h3>
|
||||
<button
|
||||
class="px-4 py-2 bg-emerald-500 hover:bg-emerald-600 text-white rounded-lg transition-all flex items-center gap-2 shadow-lg shadow-emerald-500/25"
|
||||
data-action="show-modal"
|
||||
data-modal="add-client-modal"
|
||||
>
|
||||
<i class="fas fa-plus"></i>
|
||||
Add Client
|
||||
</button>
|
||||
</div>
|
||||
<div class="p-6 overflow-x-auto">
|
||||
<table class="w-full">
|
||||
<thead>
|
||||
<tr class="border-b border-gray-700">
|
||||
<th class="text-left py-3 px-4 text-gray-400 font-medium text-sm">Client ID</th>
|
||||
<th class="text-left py-3 px-4 text-gray-400 font-medium text-sm">Storage Type</th>
|
||||
<th class="text-left py-3 px-4 text-gray-400 font-medium text-sm">Quota</th>
|
||||
<th class="text-left py-3 px-4 text-gray-400 font-medium text-sm">Used</th>
|
||||
<th class="text-left py-3 px-4 text-gray-400 font-medium text-sm">Snapshots</th>
|
||||
<th class="text-left py-3 px-4 text-gray-400 font-medium text-sm">Status</th>
|
||||
<th class="text-left py-3 px-4 text-gray-400 font-medium text-sm">Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="clients-table"></tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Snapshots Tab -->
|
||||
<div id="snapshots-tab" class="hidden">
|
||||
<div class="bg-surface rounded-xl border border-gray-700 overflow-hidden">
|
||||
<div class="p-6 border-b border-gray-700 flex justify-between items-center">
|
||||
<h3 class="text-lg font-semibold text-white flex items-center gap-2">
|
||||
<i class="fas fa-images text-primary"></i>
|
||||
Snapshots
|
||||
</h3>
|
||||
<select id="snapshot-client-filter" class="px-4 py-2 bg-surface-dark border border-gray-600 rounded-lg text-white focus:outline-none focus:ring-2 focus:ring-primary">
|
||||
<option value="">All Clients</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="p-6 overflow-x-auto">
|
||||
<table class="w-full">
|
||||
<thead>
|
||||
<tr class="border-b border-gray-700">
|
||||
<th class="text-left py-3 px-4 text-gray-400 font-medium text-sm">Client</th>
|
||||
<th class="text-left py-3 px-4 text-gray-400 font-medium text-sm">Snapshot ID</th>
|
||||
<th class="text-left py-3 px-4 text-gray-400 font-medium text-sm">Timestamp</th>
|
||||
<th class="text-left py-3 px-4 text-gray-400 font-medium text-sm">Size</th>
|
||||
<th class="text-left py-3 px-4 text-gray-400 font-medium text-sm">Type</th>
|
||||
<th class="text-left py-3 px-4 text-gray-400 font-medium text-sm">Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="snapshots-table"></tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Admins Tab -->
|
||||
<div id="admins-tab" class="hidden">
|
||||
<div class="bg-surface rounded-xl border border-gray-700 overflow-hidden">
|
||||
<div class="p-6 border-b border-gray-700 flex justify-between items-center">
|
||||
<h3 class="text-lg font-semibold text-white flex items-center gap-2">
|
||||
<i class="fas fa-user-shield text-primary"></i>
|
||||
Admin Users
|
||||
</h3>
|
||||
<button
|
||||
class="px-4 py-2 bg-emerald-500 hover:bg-emerald-600 text-white rounded-lg transition-all flex items-center gap-2 shadow-lg shadow-emerald-500/25"
|
||||
data-action="show-modal"
|
||||
data-modal="add-admin-modal"
|
||||
>
|
||||
<i class="fas fa-plus"></i>
|
||||
Add Admin
|
||||
</button>
|
||||
</div>
|
||||
<div class="p-6 overflow-x-auto">
|
||||
<table class="w-full">
|
||||
<thead>
|
||||
<tr class="border-b border-gray-700">
|
||||
<th class="text-left py-3 px-4 text-gray-400 font-medium text-sm">ID</th>
|
||||
<th class="text-left py-3 px-4 text-gray-400 font-medium text-sm">Username</th>
|
||||
<th class="text-left py-3 px-4 text-gray-400 font-medium text-sm">Role</th>
|
||||
<th class="text-left py-3 px-4 text-gray-400 font-medium text-sm">Created</th>
|
||||
<th class="text-left py-3 px-4 text-gray-400 font-medium text-sm">Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="admins-table"></tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Modals -->
|
||||
@AddClientModal()
|
||||
@EditClientModal()
|
||||
@AddAdminModal()
|
||||
@ChangePasswordModal()
|
||||
@ClientPasswordModal()
|
||||
|
||||
@AdminScripts()
|
||||
}
|
||||
}
|
||||
|
||||
// AddClientModal renders the add client modal
|
||||
templ AddClientModal() {
|
||||
@components.Modal("add-client-modal", "Add New Client") {
|
||||
<form id="add-client-form">
|
||||
@components.FormInput("new-client-id", "Client ID", "text", "", true)
|
||||
@components.FormInput("new-client-apikey", "API Key", "text", "", true)
|
||||
@components.FormSelect("new-client-storage", "Storage Type", []components.SelectOption{
|
||||
{Value: "s3", Label: "S3", Selected: true},
|
||||
{Value: "local", Label: "Local ZFS", Selected: false},
|
||||
})
|
||||
@components.FormInput("new-client-dataset", "Target Dataset (for local storage)", "text", "backup/client1", false)
|
||||
@components.FormInput("new-client-quota", "Quota (GB)", "number", "100", true)
|
||||
@components.FormCheckbox("new-client-enabled", "Enabled", true)
|
||||
|
||||
<h4 class="text-gray-400 text-sm mt-6 mb-3 flex items-center gap-2">
|
||||
<i class="fas fa-clock-rotate-left"></i>
|
||||
Rotation Policy
|
||||
</h4>
|
||||
<div class="grid grid-cols-2 gap-4">
|
||||
@components.FormInput("new-client-hourly", "Keep Hourly", "number", "24", false)
|
||||
@components.FormInput("new-client-daily", "Keep Daily", "number", "7", false)
|
||||
@components.FormInput("new-client-weekly", "Keep Weekly", "number", "4", false)
|
||||
@components.FormInput("new-client-monthly", "Keep Monthly", "number", "12", false)
|
||||
</div>
|
||||
|
||||
<button type="submit" class="w-full mt-6 px-4 py-3 bg-emerald-500 hover:bg-emerald-600 text-white rounded-lg transition-all flex items-center justify-center gap-2 shadow-lg shadow-emerald-500/25">
|
||||
<i class="fas fa-plus"></i>
|
||||
Create Client
|
||||
</button>
|
||||
</form>
|
||||
}
|
||||
}
|
||||
|
||||
// EditClientModal renders the edit client modal
|
||||
templ EditClientModal() {
|
||||
@components.Modal("edit-client-modal", "Edit Client") {
|
||||
<form id="edit-client-form">
|
||||
<input type="hidden" id="edit-client-id"/>
|
||||
@components.FormInput("edit-client-apikey", "New API Key (leave empty to keep current)", "text", "Leave empty to keep current", false)
|
||||
@components.FormSelect("edit-client-storage", "Storage Type", []components.SelectOption{
|
||||
{Value: "s3", Label: "S3", Selected: true},
|
||||
{Value: "local", Label: "Local ZFS", Selected: false},
|
||||
})
|
||||
@components.FormInput("edit-client-dataset", "Target Dataset", "text", "", false)
|
||||
@components.FormInput("edit-client-quota", "Quota (GB)", "number", "", true)
|
||||
@components.FormCheckbox("edit-client-enabled", "Enabled", false)
|
||||
|
||||
<h4 class="text-gray-400 text-sm mt-6 mb-3 flex items-center gap-2">
|
||||
<i class="fas fa-clock-rotate-left"></i>
|
||||
Rotation Policy
|
||||
</h4>
|
||||
<div class="grid grid-cols-2 gap-4">
|
||||
@components.FormInput("edit-client-hourly", "Keep Hourly", "number", "", false)
|
||||
@components.FormInput("edit-client-daily", "Keep Daily", "number", "", false)
|
||||
@components.FormInput("edit-client-weekly", "Keep Weekly", "number", "", false)
|
||||
@components.FormInput("edit-client-monthly", "Keep Monthly", "number", "", false)
|
||||
</div>
|
||||
|
||||
<button type="submit" class="w-full mt-6 px-4 py-3 bg-primary hover:bg-primary-dark text-white rounded-lg transition-all flex items-center justify-center gap-2 shadow-lg shadow-primary/25">
|
||||
<i class="fas fa-save"></i>
|
||||
Update Client
|
||||
</button>
|
||||
</form>
|
||||
}
|
||||
}
|
||||
|
||||
// AddAdminModal renders the add admin modal
|
||||
templ AddAdminModal() {
|
||||
@components.Modal("add-admin-modal", "Add New Admin") {
|
||||
<form id="add-admin-form">
|
||||
@components.FormInput("new-admin-username", "Username", "text", "", true)
|
||||
@components.FormInput("new-admin-password", "Password", "password", "", true)
|
||||
@components.FormSelect("new-admin-role", "Role", []components.SelectOption{
|
||||
{Value: "admin", Label: "Admin", Selected: true},
|
||||
})
|
||||
<button type="submit" class="w-full mt-6 px-4 py-3 bg-emerald-500 hover:bg-emerald-600 text-white rounded-lg transition-all flex items-center justify-center gap-2 shadow-lg shadow-emerald-500/25">
|
||||
<i class="fas fa-plus"></i>
|
||||
Create Admin
|
||||
</button>
|
||||
</form>
|
||||
}
|
||||
}
|
||||
|
||||
// ChangePasswordModal renders the change password modal for admins
|
||||
templ ChangePasswordModal() {
|
||||
@components.Modal("change-password-modal", "Change Password") {
|
||||
<form id="change-password-form">
|
||||
<input type="hidden" id="change-password-admin-id"/>
|
||||
@components.FormInput("change-password-username", "Admin Username", "text", "", true)
|
||||
@components.FormInput("change-password-new", "New Password", "password", "", true)
|
||||
@components.FormInput("change-password-confirm", "Confirm New Password", "password", "", true)
|
||||
<button type="submit" class="w-full mt-6 px-4 py-3 bg-primary hover:bg-primary-dark text-white rounded-lg transition-all flex items-center justify-center gap-2 shadow-lg shadow-primary/25">
|
||||
<i class="fas fa-key"></i>
|
||||
Change Password
|
||||
</button>
|
||||
</form>
|
||||
}
|
||||
}
|
||||
|
||||
// ClientPasswordModal renders the set client API key modal
|
||||
templ ClientPasswordModal() {
|
||||
@components.Modal("client-password-modal", "Set Client API Key") {
|
||||
<form id="client-password-form">
|
||||
<input type="hidden" id="client-password-client-id"/>
|
||||
@components.FormInput("client-password-client-name", "Client ID", "text", "", true)
|
||||
@components.FormInput("client-password-new", "New API Key", "text", "", true)
|
||||
@components.FormInput("client-password-confirm", "Confirm API Key", "text", "", true)
|
||||
<button type="submit" class="w-full mt-6 px-4 py-3 bg-primary hover:bg-primary-dark text-white rounded-lg transition-all flex items-center justify-center gap-2 shadow-lg shadow-primary/25">
|
||||
<i class="fas fa-key"></i>
|
||||
Set API Key
|
||||
</button>
|
||||
</form>
|
||||
}
|
||||
}
|
||||
|
||||
// AdminScripts renders the JavaScript for the admin panel
|
||||
templ AdminScripts() {
|
||||
<script src="/admin/static/admin.js"></script>
|
||||
}
|
||||
565
internal/server/templates/pages/admin_templ.go
Normal file
565
internal/server/templates/pages/admin_templ.go
Normal file
@@ -0,0 +1,565 @@
|
||||
// Code generated by templ - DO NOT EDIT.
|
||||
|
||||
// templ: version: v0.3.977
|
||||
package pages
|
||||
|
||||
//lint:file-ignore SA4006 This context is only used if a nested component is present.
|
||||
|
||||
import "github.com/a-h/templ"
|
||||
import templruntime "github.com/a-h/templ/runtime"
|
||||
|
||||
import (
|
||||
"git.ma-al.com/goc_marek/zfs/internal/server/templates/components"
|
||||
)
|
||||
|
||||
// AdminPage renders the main admin panel
|
||||
func AdminPage(username string) templ.Component {
|
||||
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
|
||||
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
|
||||
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
|
||||
return templ_7745c5c3_CtxErr
|
||||
}
|
||||
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
defer func() {
|
||||
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err == nil {
|
||||
templ_7745c5c3_Err = templ_7745c5c3_BufErr
|
||||
}
|
||||
}()
|
||||
}
|
||||
ctx = templ.InitializeContext(ctx)
|
||||
templ_7745c5c3_Var1 := templ.GetChildren(ctx)
|
||||
if templ_7745c5c3_Var1 == nil {
|
||||
templ_7745c5c3_Var1 = templ.NopComponent
|
||||
}
|
||||
ctx = templ.ClearChildren(ctx)
|
||||
templ_7745c5c3_Var2 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
|
||||
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
|
||||
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
defer func() {
|
||||
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err == nil {
|
||||
templ_7745c5c3_Err = templ_7745c5c3_BufErr
|
||||
}
|
||||
}()
|
||||
}
|
||||
ctx = templ.InitializeContext(ctx)
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "<div class=\"max-w-6xl mx-auto p-4\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = components.Header(username).Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "<!-- Stats Grid --><div id=\"stats-grid\" class=\"grid grid-cols-1 md:grid-cols-3 gap-4 mb-4\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = components.StatsCard("Clients", "Loading...").Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = components.StatsCard("Total Snapshots", "Loading...").Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = components.StatsCard("Total Storage", "Loading...").Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "</div><!-- Tabs --><div class=\"flex gap-2 mb-4\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = components.TabButton("clients", "Clients", true).Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = components.TabButton("snapshots", "Snapshots", false).Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = components.TabButton("admins", "Admins", false).Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, "</div><!-- Clients Tab --><div id=\"clients-tab\"><div class=\"bg-white rounded-lg shadow\"><div class=\"p-4 border-b flex justify-between items-center\"><h3 class=\"font-semibold text-slate-800\">Clients</h3><button class=\"bg-success hover:bg-green-600 text-white px-4 py-2 rounded transition-colors\" data-action=\"show-modal\" data-modal=\"add-client-modal\">+ Add Client</button></div><div class=\"p-4 overflow-x-auto\"><table class=\"w-full\"><thead><tr class=\"border-b\"><th class=\"text-left py-2 px-2 text-gray-600 font-semibold\">Client ID</th><th class=\"text-left py-2 px-2 text-gray-600 font-semibold\">Storage Type</th><th class=\"text-left py-2 px-2 text-gray-600 font-semibold\">Quota</th><th class=\"text-left py-2 px-2 text-gray-600 font-semibold\">Used</th><th class=\"text-left py-2 px-2 text-gray-600 font-semibold\">Snapshots</th><th class=\"text-left py-2 px-2 text-gray-600 font-semibold\">Status</th><th class=\"text-left py-2 px-2 text-gray-600 font-semibold\">Actions</th></tr></thead> <tbody id=\"clients-table\"></tbody></table></div></div></div><!-- Snapshots Tab --><div id=\"snapshots-tab\" class=\"hidden\"><div class=\"bg-white rounded-lg shadow\"><div class=\"p-4 border-b flex justify-between items-center\"><h3 class=\"font-semibold text-slate-800\">Snapshots</h3><select id=\"snapshot-client-filter\" class=\"px-3 py-2 border rounded\"><option value=\"\">All Clients</option></select></div><div class=\"p-4 overflow-x-auto\"><table class=\"w-full\"><thead><tr class=\"border-b\"><th class=\"text-left py-2 px-2 text-gray-600 font-semibold\">Client</th><th class=\"text-left py-2 px-2 text-gray-600 font-semibold\">Snapshot ID</th><th class=\"text-left py-2 px-2 text-gray-600 font-semibold\">Timestamp</th><th class=\"text-left py-2 px-2 text-gray-600 font-semibold\">Size</th><th class=\"text-left py-2 px-2 text-gray-600 font-semibold\">Type</th><th class=\"text-left py-2 px-2 text-gray-600 font-semibold\">Actions</th></tr></thead> <tbody id=\"snapshots-table\"></tbody></table></div></div></div><!-- Admins Tab --><div id=\"admins-tab\" class=\"hidden\"><div class=\"bg-white rounded-lg shadow\"><div class=\"p-4 border-b flex justify-between items-center\"><h3 class=\"font-semibold text-slate-800\">Admin Users</h3><button class=\"bg-success hover:bg-green-600 text-white px-4 py-2 rounded transition-colors\" data-action=\"show-modal\" data-modal=\"add-admin-modal\">+ Add Admin</button></div><div class=\"p-4 overflow-x-auto\"><table class=\"w-full\"><thead><tr class=\"border-b\"><th class=\"text-left py-2 px-2 text-gray-600 font-semibold\">ID</th><th class=\"text-left py-2 px-2 text-gray-600 font-semibold\">Username</th><th class=\"text-left py-2 px-2 text-gray-600 font-semibold\">Role</th><th class=\"text-left py-2 px-2 text-gray-600 font-semibold\">Created</th><th class=\"text-left py-2 px-2 text-gray-600 font-semibold\">Actions</th></tr></thead> <tbody id=\"admins-table\"></tbody></table></div></div></div></div><!-- Modals --> ")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = AddClientModal().Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, " ")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = EditClientModal().Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, " ")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = AddAdminModal().Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, " ")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = ChangePasswordModal().Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 8, " ")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = ClientPasswordModal().Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 9, " ")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = AdminScripts().Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
return nil
|
||||
})
|
||||
templ_7745c5c3_Err = components.Layout("ZFS Backup Admin Panel", username).Render(templ.WithChildren(ctx, templ_7745c5c3_Var2), templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
// AddClientModal renders the add client modal
|
||||
func AddClientModal() templ.Component {
|
||||
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
|
||||
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
|
||||
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
|
||||
return templ_7745c5c3_CtxErr
|
||||
}
|
||||
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
defer func() {
|
||||
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err == nil {
|
||||
templ_7745c5c3_Err = templ_7745c5c3_BufErr
|
||||
}
|
||||
}()
|
||||
}
|
||||
ctx = templ.InitializeContext(ctx)
|
||||
templ_7745c5c3_Var3 := templ.GetChildren(ctx)
|
||||
if templ_7745c5c3_Var3 == nil {
|
||||
templ_7745c5c3_Var3 = templ.NopComponent
|
||||
}
|
||||
ctx = templ.ClearChildren(ctx)
|
||||
templ_7745c5c3_Var4 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
|
||||
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
|
||||
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
defer func() {
|
||||
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err == nil {
|
||||
templ_7745c5c3_Err = templ_7745c5c3_BufErr
|
||||
}
|
||||
}()
|
||||
}
|
||||
ctx = templ.InitializeContext(ctx)
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 10, "<form id=\"add-client-form\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = components.FormInput("new-client-id", "Client ID", "text", "", true).Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = components.FormInput("new-client-apikey", "API Key", "text", "", true).Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = components.FormSelect("new-client-storage", "Storage Type", []components.SelectOption{
|
||||
{Value: "s3", Label: "S3", Selected: true},
|
||||
{Value: "local", Label: "Local ZFS", Selected: false},
|
||||
}).Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = components.FormInput("new-client-dataset", "Target Dataset (for local storage)", "text", "backup/client1", false).Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = components.FormInput("new-client-quota", "Quota (GB)", "number", "100", true).Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = components.FormCheckbox("new-client-enabled", "Enabled", true).Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 11, "<h4 class=\"text-gray-500 text-sm mt-4 mb-2\">Rotation Policy</h4><div class=\"grid grid-cols-2 gap-2\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = components.FormInput("new-client-hourly", "Keep Hourly", "number", "24", false).Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = components.FormInput("new-client-daily", "Keep Daily", "number", "7", false).Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = components.FormInput("new-client-weekly", "Keep Weekly", "number", "4", false).Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = components.FormInput("new-client-monthly", "Keep Monthly", "number", "12", false).Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 12, "</div><button type=\"submit\" class=\"w-full bg-success hover:bg-green-600 text-white py-2.5 rounded mt-4 transition-colors\">Create Client</button></form>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
return nil
|
||||
})
|
||||
templ_7745c5c3_Err = components.Modal("add-client-modal", "Add New Client").Render(templ.WithChildren(ctx, templ_7745c5c3_Var4), templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
// EditClientModal renders the edit client modal
|
||||
func EditClientModal() templ.Component {
|
||||
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
|
||||
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
|
||||
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
|
||||
return templ_7745c5c3_CtxErr
|
||||
}
|
||||
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
defer func() {
|
||||
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err == nil {
|
||||
templ_7745c5c3_Err = templ_7745c5c3_BufErr
|
||||
}
|
||||
}()
|
||||
}
|
||||
ctx = templ.InitializeContext(ctx)
|
||||
templ_7745c5c3_Var5 := templ.GetChildren(ctx)
|
||||
if templ_7745c5c3_Var5 == nil {
|
||||
templ_7745c5c3_Var5 = templ.NopComponent
|
||||
}
|
||||
ctx = templ.ClearChildren(ctx)
|
||||
templ_7745c5c3_Var6 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
|
||||
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
|
||||
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
defer func() {
|
||||
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err == nil {
|
||||
templ_7745c5c3_Err = templ_7745c5c3_BufErr
|
||||
}
|
||||
}()
|
||||
}
|
||||
ctx = templ.InitializeContext(ctx)
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 13, "<form id=\"edit-client-form\"><input type=\"hidden\" id=\"edit-client-id\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = components.FormInput("edit-client-apikey", "New API Key (leave empty to keep current)", "text", "Leave empty to keep current", false).Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = components.FormSelect("edit-client-storage", "Storage Type", []components.SelectOption{
|
||||
{Value: "s3", Label: "S3", Selected: true},
|
||||
{Value: "local", Label: "Local ZFS", Selected: false},
|
||||
}).Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = components.FormInput("edit-client-dataset", "Target Dataset", "text", "", false).Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = components.FormInput("edit-client-quota", "Quota (GB)", "number", "", true).Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = components.FormCheckbox("edit-client-enabled", "Enabled", false).Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 14, "<h4 class=\"text-gray-500 text-sm mt-4 mb-2\">Rotation Policy</h4><div class=\"grid grid-cols-2 gap-2\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = components.FormInput("edit-client-hourly", "Keep Hourly", "number", "", false).Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = components.FormInput("edit-client-daily", "Keep Daily", "number", "", false).Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = components.FormInput("edit-client-weekly", "Keep Weekly", "number", "", false).Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = components.FormInput("edit-client-monthly", "Keep Monthly", "number", "", false).Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 15, "</div><button type=\"submit\" class=\"w-full bg-success hover:bg-green-600 text-white py-2.5 rounded mt-4 transition-colors\">Update Client</button></form>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
return nil
|
||||
})
|
||||
templ_7745c5c3_Err = components.Modal("edit-client-modal", "Edit Client").Render(templ.WithChildren(ctx, templ_7745c5c3_Var6), templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
// AddAdminModal renders the add admin modal
|
||||
func AddAdminModal() templ.Component {
|
||||
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
|
||||
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
|
||||
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
|
||||
return templ_7745c5c3_CtxErr
|
||||
}
|
||||
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
defer func() {
|
||||
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err == nil {
|
||||
templ_7745c5c3_Err = templ_7745c5c3_BufErr
|
||||
}
|
||||
}()
|
||||
}
|
||||
ctx = templ.InitializeContext(ctx)
|
||||
templ_7745c5c3_Var7 := templ.GetChildren(ctx)
|
||||
if templ_7745c5c3_Var7 == nil {
|
||||
templ_7745c5c3_Var7 = templ.NopComponent
|
||||
}
|
||||
ctx = templ.ClearChildren(ctx)
|
||||
templ_7745c5c3_Var8 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
|
||||
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
|
||||
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
defer func() {
|
||||
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err == nil {
|
||||
templ_7745c5c3_Err = templ_7745c5c3_BufErr
|
||||
}
|
||||
}()
|
||||
}
|
||||
ctx = templ.InitializeContext(ctx)
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 16, "<form id=\"add-admin-form\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = components.FormInput("new-admin-username", "Username", "text", "", true).Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = components.FormInput("new-admin-password", "Password", "password", "", true).Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = components.FormSelect("new-admin-role", "Role", []components.SelectOption{
|
||||
{Value: "admin", Label: "Admin", Selected: true},
|
||||
}).Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 17, "<button type=\"submit\" class=\"w-full bg-success hover:bg-green-600 text-white py-2.5 rounded mt-4 transition-colors\">Create Admin</button></form>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
return nil
|
||||
})
|
||||
templ_7745c5c3_Err = components.Modal("add-admin-modal", "Add New Admin").Render(templ.WithChildren(ctx, templ_7745c5c3_Var8), templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
// ChangePasswordModal renders the change password modal for admins
|
||||
func ChangePasswordModal() templ.Component {
|
||||
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
|
||||
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
|
||||
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
|
||||
return templ_7745c5c3_CtxErr
|
||||
}
|
||||
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
defer func() {
|
||||
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err == nil {
|
||||
templ_7745c5c3_Err = templ_7745c5c3_BufErr
|
||||
}
|
||||
}()
|
||||
}
|
||||
ctx = templ.InitializeContext(ctx)
|
||||
templ_7745c5c3_Var9 := templ.GetChildren(ctx)
|
||||
if templ_7745c5c3_Var9 == nil {
|
||||
templ_7745c5c3_Var9 = templ.NopComponent
|
||||
}
|
||||
ctx = templ.ClearChildren(ctx)
|
||||
templ_7745c5c3_Var10 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
|
||||
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
|
||||
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
defer func() {
|
||||
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err == nil {
|
||||
templ_7745c5c3_Err = templ_7745c5c3_BufErr
|
||||
}
|
||||
}()
|
||||
}
|
||||
ctx = templ.InitializeContext(ctx)
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 18, "<form id=\"change-password-form\"><input type=\"hidden\" id=\"change-password-admin-id\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = components.FormInput("change-password-username", "Admin Username", "text", "", true).Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = components.FormInput("change-password-new", "New Password", "password", "", true).Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = components.FormInput("change-password-confirm", "Confirm New Password", "password", "", true).Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 19, "<button type=\"submit\" class=\"w-full bg-success hover:bg-green-600 text-white py-2.5 rounded mt-4 transition-colors\">Change Password</button></form>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
return nil
|
||||
})
|
||||
templ_7745c5c3_Err = components.Modal("change-password-modal", "Change Password").Render(templ.WithChildren(ctx, templ_7745c5c3_Var10), templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
// ClientPasswordModal renders the set client API key modal
|
||||
func ClientPasswordModal() templ.Component {
|
||||
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
|
||||
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
|
||||
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
|
||||
return templ_7745c5c3_CtxErr
|
||||
}
|
||||
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
defer func() {
|
||||
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err == nil {
|
||||
templ_7745c5c3_Err = templ_7745c5c3_BufErr
|
||||
}
|
||||
}()
|
||||
}
|
||||
ctx = templ.InitializeContext(ctx)
|
||||
templ_7745c5c3_Var11 := templ.GetChildren(ctx)
|
||||
if templ_7745c5c3_Var11 == nil {
|
||||
templ_7745c5c3_Var11 = templ.NopComponent
|
||||
}
|
||||
ctx = templ.ClearChildren(ctx)
|
||||
templ_7745c5c3_Var12 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
|
||||
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
|
||||
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
defer func() {
|
||||
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err == nil {
|
||||
templ_7745c5c3_Err = templ_7745c5c3_BufErr
|
||||
}
|
||||
}()
|
||||
}
|
||||
ctx = templ.InitializeContext(ctx)
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 20, "<form id=\"client-password-form\"><input type=\"hidden\" id=\"client-password-client-id\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = components.FormInput("client-password-client-name", "Client ID", "text", "", true).Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = components.FormInput("client-password-new", "New API Key", "text", "", true).Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = components.FormInput("client-password-confirm", "Confirm API Key", "text", "", true).Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 21, "<button type=\"submit\" class=\"w-full bg-success hover:bg-green-600 text-white py-2.5 rounded mt-4 transition-colors\">Set API Key</button></form>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
return nil
|
||||
})
|
||||
templ_7745c5c3_Err = components.Modal("client-password-modal", "Set Client API Key").Render(templ.WithChildren(ctx, templ_7745c5c3_Var12), templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
// AdminScripts renders the JavaScript for the admin panel
|
||||
func AdminScripts() templ.Component {
|
||||
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
|
||||
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
|
||||
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
|
||||
return templ_7745c5c3_CtxErr
|
||||
}
|
||||
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
defer func() {
|
||||
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err == nil {
|
||||
templ_7745c5c3_Err = templ_7745c5c3_BufErr
|
||||
}
|
||||
}()
|
||||
}
|
||||
ctx = templ.InitializeContext(ctx)
|
||||
templ_7745c5c3_Var13 := templ.GetChildren(ctx)
|
||||
if templ_7745c5c3_Var13 == nil {
|
||||
templ_7745c5c3_Var13 = templ.NopComponent
|
||||
}
|
||||
ctx = templ.ClearChildren(ctx)
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 22, "<script src=\"/admin/static/admin.js\"></script>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
var _ = templruntime.GeneratedTemplate
|
||||
49
internal/server/templates/pages/login.templ
Normal file
49
internal/server/templates/pages/login.templ
Normal file
@@ -0,0 +1,49 @@
|
||||
package pages
|
||||
|
||||
import "git.ma-al.com/goc_marek/zfs/internal/server/templates/components"
|
||||
|
||||
// LoginPage renders the login page
|
||||
templ LoginPage() {
|
||||
@components.Layout("Admin Login", "") {
|
||||
<div class="min-h-screen flex items-center justify-center px-4">
|
||||
<div class="w-full max-w-md">
|
||||
<!-- Logo and Title -->
|
||||
<div class="text-center mb-8">
|
||||
<div class="w-16 h-16 bg-gradient-to-br from-primary to-accent rounded-2xl flex items-center justify-center mx-auto mb-4 shadow-lg shadow-primary/25">
|
||||
<i class="fas fa-database text-white text-2xl"></i>
|
||||
</div>
|
||||
<h1 class="text-2xl font-bold text-white mb-2">ZFS Backup Admin</h1>
|
||||
<p class="text-gray-400">Sign in to manage your backups</p>
|
||||
</div>
|
||||
|
||||
<!-- Login Form -->
|
||||
<div class="bg-surface rounded-2xl border border-gray-700 p-8 shadow-xl">
|
||||
<form id="login-form">
|
||||
@components.FormInput("username", "Username", "text", "", true)
|
||||
@components.FormInput("password", "Password", "password", "", true)
|
||||
<button
|
||||
type="submit"
|
||||
class="w-full mt-2 px-4 py-3 bg-primary hover:bg-primary-dark text-white rounded-lg transition-all flex items-center justify-center gap-2 shadow-lg shadow-primary/25"
|
||||
>
|
||||
<i class="fas fa-sign-in-alt"></i>
|
||||
Sign In
|
||||
</button>
|
||||
</form>
|
||||
|
||||
<div class="mt-6 pt-6 border-t border-gray-700 text-center">
|
||||
<p class="text-gray-500 text-sm">
|
||||
<i class="fas fa-info-circle mr-1"></i>
|
||||
Default: <span class="text-gray-400">admin / admin123</span>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Footer -->
|
||||
<p class="text-center text-gray-600 text-xs mt-8">
|
||||
Powered by ZFS Backup System
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<script src="/admin/static/login.js"></script>
|
||||
}
|
||||
}
|
||||
73
internal/server/templates/pages/login_templ.go
Normal file
73
internal/server/templates/pages/login_templ.go
Normal file
@@ -0,0 +1,73 @@
|
||||
// Code generated by templ - DO NOT EDIT.
|
||||
|
||||
// templ: version: v0.3.977
|
||||
package pages
|
||||
|
||||
//lint:file-ignore SA4006 This context is only used if a nested component is present.
|
||||
|
||||
import "github.com/a-h/templ"
|
||||
import templruntime "github.com/a-h/templ/runtime"
|
||||
|
||||
import "git.ma-al.com/goc_marek/zfs/internal/server/templates/components"
|
||||
|
||||
// LoginPage renders the login page
|
||||
func LoginPage() templ.Component {
|
||||
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
|
||||
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
|
||||
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
|
||||
return templ_7745c5c3_CtxErr
|
||||
}
|
||||
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
defer func() {
|
||||
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err == nil {
|
||||
templ_7745c5c3_Err = templ_7745c5c3_BufErr
|
||||
}
|
||||
}()
|
||||
}
|
||||
ctx = templ.InitializeContext(ctx)
|
||||
templ_7745c5c3_Var1 := templ.GetChildren(ctx)
|
||||
if templ_7745c5c3_Var1 == nil {
|
||||
templ_7745c5c3_Var1 = templ.NopComponent
|
||||
}
|
||||
ctx = templ.ClearChildren(ctx)
|
||||
templ_7745c5c3_Var2 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
|
||||
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
|
||||
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
defer func() {
|
||||
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err == nil {
|
||||
templ_7745c5c3_Err = templ_7745c5c3_BufErr
|
||||
}
|
||||
}()
|
||||
}
|
||||
ctx = templ.InitializeContext(ctx)
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "<div class=\"max-w-md mx-auto mt-24 bg-white p-8 rounded-lg shadow\"><h2 class=\"text-xl font-semibold text-center text-slate-800 mb-6\">Admin Login</h2><form id=\"login-form\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = components.FormInput("username", "Username", "text", "", true).Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = components.FormInput("password", "Password", "password", "", true).Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "<button type=\"submit\" class=\"w-full bg-primary hover:bg-blue-600 text-white py-2.5 rounded transition-colors\">Login</button></form><p class=\"mt-4 text-center text-gray-400 text-xs\">Default: admin / admin123</p></div><script src=\"/admin/static/login.js\"></script>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
return nil
|
||||
})
|
||||
templ_7745c5c3_Err = components.Layout("Admin Login", "").Render(templ.WithChildren(ctx, templ_7745c5c3_Var2), templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
var _ = templruntime.GeneratedTemplate
|
||||
Reference in New Issue
Block a user