summaryrefslogtreecommitdiff
path: root/Biz/PodcastItLater/Admin/Views.py
diff options
context:
space:
mode:
authorBen Sima <ben@bensima.com>2025-12-17 13:29:40 -0500
committerBen Sima <ben@bensima.com>2025-12-17 13:29:40 -0500
commitab01b34bf563990e0f491ada646472aaade97610 (patch)
tree5e46a1a157bb846b0c3a090a83153c788da2b977 /Biz/PodcastItLater/Admin/Views.py
parente112d3ce07fa24f31a281e521a554cc881a76c7b (diff)
parent337648981cc5a55935116141341521f4fce83214 (diff)
Merge Ava deployment changes
Diffstat (limited to 'Biz/PodcastItLater/Admin/Views.py')
-rw-r--r--Biz/PodcastItLater/Admin/Views.py107
1 files changed, 98 insertions, 9 deletions
diff --git a/Biz/PodcastItLater/Admin/Views.py b/Biz/PodcastItLater/Admin/Views.py
index 7cc71a5..057c5e0 100644
--- a/Biz/PodcastItLater/Admin/Views.py
+++ b/Biz/PodcastItLater/Admin/Views.py
@@ -263,16 +263,16 @@ class MetricsDashboard(Component[AnyChildren, MetricsAttrs]):
"Most Played",
classes=["card-title", "mb-0"],
),
- classes=["card-header", "bg-white"],
+ classes=["card-header"],
),
TopEpisodesTable(
episodes=metrics["most_played"],
metric_name="Plays",
count_key="play_count",
),
- classes=["card", "shadow-sm"],
+ classes=["card", "shadow-sm", "mb-3"],
),
- classes=["col-lg-4"],
+ classes=["col-12"],
),
html.div(
html.div(
@@ -288,16 +288,16 @@ class MetricsDashboard(Component[AnyChildren, MetricsAttrs]):
"Most Downloaded",
classes=["card-title", "mb-0"],
),
- classes=["card-header", "bg-white"],
+ classes=["card-header"],
),
TopEpisodesTable(
episodes=metrics["most_downloaded"],
metric_name="Downloads",
count_key="download_count",
),
- classes=["card", "shadow-sm"],
+ classes=["card", "shadow-sm", "mb-3"],
),
- classes=["col-lg-4"],
+ classes=["col-12"],
),
html.div(
html.div(
@@ -313,16 +313,16 @@ class MetricsDashboard(Component[AnyChildren, MetricsAttrs]):
"Most Added to Feeds",
classes=["card-title", "mb-0"],
),
- classes=["card-header", "bg-white"],
+ classes=["card-header"],
),
TopEpisodesTable(
episodes=metrics["most_added"],
metric_name="Adds",
count_key="add_count",
),
- classes=["card", "shadow-sm"],
+ classes=["card", "shadow-sm", "mb-3"],
),
- classes=["col-lg-4"],
+ classes=["col-12"],
),
classes=["row", "g-3"],
),
@@ -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=[],
+ )