Files
bookhoard/templates/admin_library.templ
T
john-okeefe a075a5061f feat(ui): refresh auth, entry, admin, and secondary pages
Apply the new design-system primitives across the remaining pages so the
whole app shares one visual language:

- Auth/entry: redesigned index, login, register (centered card layout,
  SVG icons, semantic tokens)
- Admin: sidebar nav with icons, cohesive admin dashboard/users/library/
  processing-issues/settings (tables use border-line + hover states;
  scan/websocket attributes preserved)
- Secondary: analytics (stat cards), devices, progress, conflicts, queue,
  profile + form/modal all migrated to .card/.btn/.input primitives and
  SVG action icons
- Docs + API explorer + setup wizard + collection/rules/modals +
  unlinked books + book-detail modals: consistent chrome, modal scrims
  use --surface-overlay, close buttons use icon-btn
- reader.templ and error.templ intentionally left unchanged
2026-08-05 16:01:22 -04:00

158 lines
7.0 KiB
Templ

package templates
templ AdminLibrary(user User, libraries []LibraryData, users []User) {
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8"/>
<title>Library Management - Bookhoard</title>
<link href="/static/style.css" rel="stylesheet"/>
</head>
<body x-data="library" x-init="initializeLibraryAdmin" class="theme-{ user.Theme }">
@Header(user, "/admin/library")
<div class="flex min-h-screen bg-surface">
@AdminSidebar(user, "/admin/library")
<main class="flex-1 p-6 sm:p-8">
<div class="w-full">
<div class="mb-8">
<div class="flex items-center justify-between mb-4">
<a href="/admin" class="btn btn-secondary font-medium">
@Icon("arrow-left", "h-4 w-4")
Back to Dashboard
</a>
<button data-action="show-create-modal" class="btn btn-primary font-medium">
@Icon("plus", "h-4 w-4")
Create Library
</button>
</div>
<h1 class="text-2xl font-bold tracking-tight text-content mb-2">Library Management</h1>
<p class="text-content-muted">Manage libraries and configure media scanning</p>
</div>
<div class="grid grid-cols-1 lg:grid-cols-2 gap-8">
<!-- Libraries Section -->
<div class="card p-6">
<h3 class="text-xl font-semibold mb-6 text-content">Libraries</h3>
<p class="text-content-muted mb-4">Manage media libraries and their folders</p>
<div id="libraries-list" class="space-y-3 mb-6">
if len(libraries) == 0 {
<p class="text-content-muted text-center py-8">
No libraries yet. Create your first library to get started.
</p>
} else {
for _, library := range libraries {
<div class="p-4 border border-line rounded-lg bg-surface">
<div class="flex justify-between items-start mb-2">
<div>
<h4 class="font-semibold text-content">{ library.Name }</h4>
if library.Description != "" {
<p class="text-sm text-content-muted">{ library.Description }</p>
}
<span class="badge bg-brand text-white">
{ library.TypeName }
</span>
</div>
<div class="flex space-x-2">
<button data-library-id={ library.ID } data-action="show-folders" class="btn btn-secondary text-xs">Folders</button>
<button data-library-id={ library.ID } data-action="edit" class="btn btn-primary text-xs">Edit</button>
<button data-library-id={ library.ID } data-action="delete" class="btn btn-danger text-xs">Delete</button>
</div>
</div>
<div id={ "library-folders-" + library.ID } class="hidden mt-3 space-y-2"></div>
</div>
}
}
</div>
</div>
<!-- User Library Visibility Section -->
<div class="card p-6">
<h3 class="text-xl font-semibold mb-6 text-content">Library Visibility</h3>
<p class="text-content-muted mb-4">Control which libraries are visible to users</p>
<div id="visibility-controls" class="space-y-4">
<!-- Visibility controls will be loaded here -->
</div>
</div>
</div>
<!-- User Visibility Management -->
<div class="mt-8 card p-6">
<h3 class="text-xl font-semibold mb-6 text-content">User Library Access</h3>
<p class="text-content-muted mb-4">Manage individual user access to specific libraries</p>
<div class="mb-4">
<select id="user-select" onchange="loadUserVisibility()" class="input">
<option value="">Select a user...</option>
for _, user := range users {
<option value="{ user.ID }">{ user.Username } ({ user.Email })</option>
}
</select>
</div>
<div id="user-libraries" class="space-y-3">
<!-- User library checkboxes will be loaded here -->
</div>
</div>
</div>
</main>
</div>
<!-- Create Library Modal -->
<div id="create-library-modal" class="hidden fixed inset-0 z-50 flex items-center justify-center" style="background-color: rgba(0, 0, 0, 0.7);">
<div class="card p-6 w-full max-w-md mx-4">
<div class="flex justify-between items-center mb-6">
<h2 class="text-xl font-bold text-content">Create Library</h2>
<button type="button" data-action="hide-create-modal" class="p-2 hover:bg-surface-hover rounded text-content">@Icon("close", "h-4 w-4")</button>
</div>
<form id="create-library-form">
<input type="hidden" id="library-id" name="id"/>
<div class="mb-4">
<label class="block text-sm font-medium mb-2 text-content">Library Name</label>
<input type="text" name="name" placeholder="My Ebook Library" class="input" required/>
</div>
<div class="mb-4">
<label class="block text-sm font-medium mb-2 text-content">Description</label>
<textarea name="description" placeholder="Optional description" rows="3" class="input"></textarea>
</div>
<div class="mb-4">
<label class="block text-sm font-medium mb-2 text-content">Library Type</label>
<select name="type" class="input" required>
<option value="ebooks">📚 Ebooks</option>
<option value="comics">📖 Comics</option>
<option value="manga">🗾 Manga</option>
</select>
</div>
<div class="flex justify-end space-x-3">
<button type="button" data-action="hide-create-modal" class="btn btn-secondary">Cancel</button>
<button type="submit" class="btn btn-primary">Create</button>
</div>
</form>
</div>
</div>
<!-- Folder Browser Modal -->
<div id="folder-browser-modal" class="hidden fixed inset-0 z-50 flex items-center justify-center" style="background-color: rgba(0, 0, 0, 0.7);">
<div class="card p-6 w-full max-w-md mx-4">
<div class="flex justify-between items-center mb-4">
<h2 class="text-xl font-bold text-content">Browse Folders</h2>
<button type="button" data-action="browse-cancel" class="p-2 hover:bg-surface-hover rounded text-content">@Icon("close", "h-4 w-4")</button>
</div>
<div id="folder-browser-content">
<!-- Directory listings will be rendered here -->
</div>
</div>
</div>
<!-- Delete Library Confirmation Modal -->
<div id="delete-library-modal" class="hidden fixed inset-0 z-50 flex items-center justify-center" style="background-color: rgba(0, 0, 0, 0.7);">
<div class="card p-6 w-full max-w-md mx-4">
<div class="flex justify-between items-center mb-4">
<h2 class="text-xl font-bold text-content">Delete Library</h2>
<button type="button" data-action="hide-delete-modal" class="p-2 hover:bg-surface-hover rounded text-content">@Icon("close", "h-4 w-4")</button>
</div>
<div id="delete-modal-content" class="mb-6 text-content">
<!-- Dynamic content will be injected here -->
</div>
<div class="flex justify-end space-x-3">
<button type="button" data-action="hide-delete-modal" class="btn btn-secondary">Cancel</button>
<button type="button" data-action="confirm-delete" class="btn btn-danger">Delete</button>
</div>
</div>
</div>
<script src="/static/htmx.min.js"></script>
</body>
</html>
}