summaryrefslogtreecommitdiff
path: root/Biz/PodcastItLater/Admin
diff options
context:
space:
mode:
Diffstat (limited to 'Biz/PodcastItLater/Admin')
-rw-r--r--Biz/PodcastItLater/Admin/Handlers.py28
-rw-r--r--Biz/PodcastItLater/Admin/Views.py89
2 files changed, 117 insertions, 0 deletions
diff --git a/Biz/PodcastItLater/Admin/Handlers.py b/Biz/PodcastItLater/Admin/Handlers.py
index b98c551..9e06fe6 100644
--- a/Biz/PodcastItLater/Admin/Handlers.py
+++ b/Biz/PodcastItLater/Admin/Handlers.py
@@ -296,3 +296,31 @@ def admin_metrics(request: Request) -> Views.MetricsDashboard | Response:
metrics = Core.Database.get_metrics_summary()
return Views.MetricsDashboard(metrics=metrics, user=user)
+
+
+def admin_feedback(request: Request) -> Views.AdminFeedback | Response:
+ """Admin feedback view."""
+ # Check if user is logged in and is admin
+ user_id = request.session.get("user_id")
+ if not user_id:
+ return Response(
+ "",
+ status_code=302,
+ headers={"Location": "/"},
+ )
+
+ user = Core.Database.get_user_by_id(
+ user_id,
+ )
+ if not user or not Core.is_admin(user):
+ return Response(
+ "",
+ status_code=302,
+ headers={"Location": "/?error=forbidden"},
+ )
+
+ # Get feedback data
+ feedback = Core.Database.get_feedback(limit=100)
+ count = Core.Database.get_feedback_count()
+
+ return Views.AdminFeedback(feedback=feedback, count=count, user=user)
diff --git a/Biz/PodcastItLater/Admin/Views.py b/Biz/PodcastItLater/Admin/Views.py
index 7cc71a5..7834340 100644
--- a/Biz/PodcastItLater/Admin/Views.py
+++ b/Biz/PodcastItLater/Admin/Views.py
@@ -742,3 +742,92 @@ class AdminView(Component[AnyChildren, AdminViewAttrs]):
),
),
)
+
+
+class AdminFeedbackAttrs(Attrs):
+ """Attributes for AdminFeedback component."""
+
+ feedback: list[dict[str, typing.Any]]
+ count: int
+ user: dict[str, typing.Any]
+
+
+class AdminFeedback(Component[AnyChildren, AdminFeedbackAttrs]):
+ """Admin feedback listing page."""
+
+ @override
+ def render(self) -> UI.PageLayout:
+ feedback = self.attrs["feedback"]
+ count = self.attrs["count"]
+ user = self.attrs["user"]
+
+ rows = [
+ html.tr(
+ html.td(html.small(fb["id"][:8], classes=["text-muted"])),
+ html.td(fb.get("email") or "-"),
+ html.td(
+ html.span(
+ fb.get("source") or "-",
+ classes=["badge", "bg-secondary"],
+ ),
+ ),
+ html.td(str(fb.get("rating") or "-")),
+ html.td(
+ TruncatedText(
+ text=fb.get("use_case") or "-",
+ max_length=50,
+ ),
+ ),
+ html.td(
+ TruncatedText(
+ text=fb.get("feedback_text") or "-",
+ max_length=50,
+ ),
+ ),
+ html.td(
+ html.small(
+ fb["created_at"],
+ classes=["text-muted"],
+ ),
+ ),
+ )
+ for fb in feedback
+ ]
+
+ return UI.PageLayout(
+ html.div(
+ html.h2(
+ html.i(classes=["bi", "bi-chat-heart-fill", "me-2"]),
+ f"Feedback ({count})",
+ classes=["mb-4"],
+ ),
+ html.div(
+ html.table(
+ create_table_header([
+ "ID",
+ "Email",
+ "Source",
+ "Rating",
+ "Use Case",
+ "Feedback",
+ "Created",
+ ]),
+ html.tbody(*rows),
+ classes=["table", "table-hover", "table-sm"],
+ ),
+ classes=["table-responsive"],
+ )
+ if rows
+ else html.div(
+ html.p(
+ "No feedback yet.",
+ classes=["text-muted", "text-center", "py-5"],
+ ),
+ ),
+ ),
+ user=user,
+ current_page="admin",
+ page_title="Admin Feedback - PodcastItLater",
+ error=None,
+ meta_tags=[],
+ )