summaryrefslogtreecommitdiff
path: root/Biz/PodcastItLater/Admin.py
diff options
context:
space:
mode:
Diffstat (limited to 'Biz/PodcastItLater/Admin.py')
-rw-r--r--Biz/PodcastItLater/Admin.py140
1 files changed, 37 insertions, 103 deletions
diff --git a/Biz/PodcastItLater/Admin.py b/Biz/PodcastItLater/Admin.py
index d7a0a4e..6ee255e 100644
--- a/Biz/PodcastItLater/Admin.py
+++ b/Biz/PodcastItLater/Admin.py
@@ -13,7 +13,6 @@ Admin pages and functionality for managing users and queue items.
# : dep pytest-mock
import Biz.PodcastItLater.Core as Core
import Biz.PodcastItLater.UI as UI
-import ludic.catalog.layouts as layouts
import ludic.html as html
# i need to import these unused because bild cannot get local transitive python
@@ -36,6 +35,7 @@ class AdminUsersAttrs(Attrs):
"""Attributes for AdminUsers component."""
users: list[dict[str, typing.Any]]
+ user: dict[str, typing.Any] | None
class StatusBadgeAttrs(Attrs):
@@ -295,45 +295,19 @@ class AdminUsers(Component[AnyChildren, AdminUsersAttrs]):
"""Admin view for managing users."""
@override
- def render(self) -> html.html:
+ def render(self) -> UI.PageLayout:
users = self.attrs["users"]
+ user = self.attrs.get("user")
- return html.html(
- html.head(
- html.meta(charset="utf-8"),
- html.meta(
- name="viewport",
- content="width=device-width, initial-scale=1",
- ),
- html.meta(
- name="color-scheme",
- content="light dark",
- ),
- html.title("PodcastItLater - User Management"),
- UI.create_htmx_script(),
- ),
- html.body(
- UI.create_bootstrap_styles(),
- # Auto dark mode CSS (must come after Bootstrap)
- UI.create_auto_dark_mode_style(),
- html.div(
- html.h1(
- "PodcastItLater - User Management",
- classes=["mb-4"],
- ),
- html.div(
- html.a(
- html.i(classes=["bi", "bi-arrow-left", "me-2"]),
- "Back to Admin",
- href="/admin",
- classes=["btn", "btn-outline-primary", "mb-3"],
- ),
- ),
- self._render_users_table(users),
- id="admin-users-content",
- classes=["container", "my-4"],
- ),
+ return UI.PageLayout(
+ html.h2(
+ "User Management",
+ classes=["mb-4"],
),
+ self._render_users_table(users),
+ user=user,
+ current_page="admin-users",
+ error=None,
)
@staticmethod
@@ -365,89 +339,55 @@ class AdminViewAttrs(Attrs):
queue_items: list[dict[str, typing.Any]]
episodes: list[dict[str, typing.Any]]
status_counts: dict[str, int]
+ user: dict[str, typing.Any] | None
class AdminView(Component[AnyChildren, AdminViewAttrs]):
"""Admin view showing all queue items and episodes in tables."""
@override
- def render(self) -> html.html:
+ def render(self) -> UI.PageLayout:
queue_items = self.attrs["queue_items"]
episodes = self.attrs["episodes"]
status_counts = self.attrs.get("status_counts", {})
+ user = self.attrs.get("user")
- return html.html(
- html.head(
- html.meta(charset="utf-8"),
- html.meta(
- name="viewport",
- content="width=device-width, initial-scale=1",
- ),
- html.meta(
- name="color-scheme",
- content="light dark",
- ),
- html.title("PodcastItLater - Admin Queue Status"),
- UI.create_htmx_script(),
- ),
- html.body(
- UI.create_bootstrap_styles(),
- # Auto dark mode CSS (must come after Bootstrap)
- UI.create_auto_dark_mode_style(),
- html.div(
- AdminView._render_content(
- queue_items,
- episodes,
- status_counts,
- ),
- id="admin-content",
- hx_get="/admin",
- hx_trigger="every 10s",
- hx_swap="innerHTML",
- hx_target="#admin-content",
- classes=["container", "my-4"],
+ return UI.PageLayout(
+ html.div(
+ AdminView.render_content(
+ queue_items,
+ episodes,
+ status_counts,
),
+ id="admin-content",
+ hx_get="/admin",
+ hx_trigger="every 10s",
+ hx_swap="innerHTML",
+ hx_target="#admin-content",
),
+ user=user,
+ current_page="admin",
+ error=None,
)
@staticmethod
- def _render_content(
+ def render_content(
queue_items: list[dict[str, typing.Any]],
episodes: list[dict[str, typing.Any]],
status_counts: dict[str, int],
) -> html.div:
"""Render the main content of the admin page."""
return html.div(
- html.h1(
- "PodcastItLater Admin - Queue Status",
+ html.h2(
+ "Admin Queue Status",
classes=["mb-4"],
),
- AdminView.render_navigation(),
AdminView.render_status_summary(status_counts),
AdminView.render_queue_table(queue_items),
AdminView.render_episodes_table(episodes),
)
@staticmethod
- def render_navigation() -> html.div:
- """Render navigation links."""
- return html.div(
- html.a(
- html.i(classes=["bi", "bi-arrow-left", "me-2"]),
- "Back to Home",
- href="/",
- classes=["btn", "btn-outline-primary", "btn-sm", "me-2"],
- ),
- html.a(
- html.i(classes=["bi", "bi-people", "me-2"]),
- "Manage Users",
- href="/admin/users",
- classes=["btn", "btn-outline-secondary", "btn-sm"],
- ),
- classes=["mb-3"],
- )
-
- @staticmethod
def render_status_summary(status_counts: dict[str, int]) -> html.div:
"""Render status summary section."""
return html.div(
@@ -568,17 +508,10 @@ def admin_queue_status(request: Request) -> AdminView | Response | html.div:
# Check if this is an HTMX request for auto-update
if request.headers.get("HX-Request") == "true":
# Return just the content div for HTMX updates
- AdminView(
- queue_items=all_queue_items,
- episodes=all_episodes,
- status_counts=status_counts,
- )
- content = layouts.Stack(
- html.h1("PodcastItLater Admin - Queue Status"),
- AdminView.render_navigation(),
- AdminView.render_status_summary(status_counts),
- AdminView.render_queue_table(all_queue_items),
- AdminView.render_episodes_table(all_episodes),
+ content = AdminView.render_content(
+ all_queue_items,
+ all_episodes,
+ status_counts,
)
return html.div(
content,
@@ -591,6 +524,7 @@ def admin_queue_status(request: Request) -> AdminView | Response | html.div:
queue_items=all_queue_items,
episodes=all_episodes,
status_counts=status_counts,
+ user=user,
)
@@ -696,7 +630,7 @@ def admin_users(request: Request) -> AdminUsers | Response:
rows = cursor.fetchall()
users = [dict(row) for row in rows]
- return AdminUsers(users=users)
+ return AdminUsers(users=users, user=user)
def update_user_status(