From 4c7d8d4af77b774f969b2907ca483df6f8ba0d04 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Wed, 26 Aug 2026 00:34:29 +0000 Subject: [PATCH 1/2] feat(ui): decompose admin pages into reusable AdminTable and AdminModal components Refactored AdminInvitesPage, AdminUserDetailsPage, AdminRolesPage, and AdminAppsPage to use the new pure Hono SSR JSX stateless components. Fixed missing import definitions in AdminRolesPage. Moved task file to complete state. Co-authored-by: mrteye <1945243+mrteye@users.noreply.github.com> --- dump_invites.txt | 352 +++++++++++ dump_roles.txt | 132 ++++ fix_lint.py | 8 + replace_invites.py | 246 ++++++++ replace_roles.py | 568 ++++++++++++++++++ replace_roles2.py | 10 + replace_roles_form.py | 204 +++++++ replace_roles_table.py | 355 +++++++++++ replace_user_details.py | 385 ++++++++++++ ...monolith-decomposition-roadmap-1845.ph2.md | 0 ui/components/AdminAppsPage.tsx | 318 +++++----- ui/components/AdminInvitesPage.tsx | 342 +++++------ ui/components/AdminRolesPage.tsx | 24 +- ui/components/AdminUserDetailsPage.tsx | 130 ++-- ui/components/admin/AdminModal.tsx | 40 ++ ui/components/admin/AdminTable.tsx | 67 +++ 16 files changed, 2721 insertions(+), 460 deletions(-) create mode 100644 dump_invites.txt create mode 100644 dump_roles.txt create mode 100644 fix_lint.py create mode 100644 replace_invites.py create mode 100644 replace_roles.py create mode 100644 replace_roles2.py create mode 100644 replace_roles_form.py create mode 100644 replace_roles_table.py create mode 100644 replace_user_details.py rename tasks/{new => complete}/2026-0825.01.jul.story.arch.monolith-decomposition-roadmap-1845.ph2.md (100%) create mode 100644 ui/components/admin/AdminModal.tsx create mode 100644 ui/components/admin/AdminTable.tsx diff --git a/dump_invites.txt b/dump_invites.txt new file mode 100644 index 0000000..2c35e3f --- /dev/null +++ b/dump_invites.txt @@ -0,0 +1,352 @@ + + {/* Desktop Ledger Table (≥ 768px) */} + + + {/* Mobile Adaptive Cards View (< 768px) */} +
+ {invites.map((inv) => { + const usesCount = inv.uses_count || 0; + const maxUses = inv.max_uses; + const isUnlimited = maxUses === null; + const isExhausted = !isUnlimited && usesCount >= maxUses; + const isExpired = new Date(inv.expires_at) < new Date(); + const isActive = !isExhausted && !isExpired; + + return ( +
+
+
+ + {inv.code} + +
+ {inv.app_name || "Global / Open"} • Role:{" "} + {inv.role} +
+
+ + {isExhausted && ( + Exhausted + )} + {isExpired && !isExhausted && ( + Expired + )} + {isActive && Active} +
+ +
+
+ + Capacity:{" "} + {isUnlimited ? "Unlimited" : `${usesCount} / ${maxUses}`} + + + Expires: {new Date(inv.expires_at).toLocaleDateString()} + +
+ {!isUnlimited && ( +
+
+
+ )} +
+ +
+ {isActive && ( + + )} + {usesCount > 0 && ( + + )} + {isActive && ( + + )} +
+
+ ); + })} +
+ + {/* Redemptions Modal */} + + + + +