From cd9b89b69e39bf6721cdb7e0ee0b0d1c8b556ad5 Mon Sep 17 00:00:00 2001 From: Tahsin Shahriar Date: Thu, 24 Sep 2026 22:40:00 +0600 Subject: [PATCH] feat(admin): migrate panel to TSX and unify dashboard chrome - Migrate admin pages from Vue SFCs to TypeScript TSX components and redesign. - New resources/js/components/admin/ui.tsx: AdminPageHeader, SegmentedTabs, AdminSelect, sub-nav, buttons, lists, table shell; all 18 admin pages migrated. - Fix invisible segmented active state in dark mode (gray-700 pill, no ring/glow); hover rows use spaced lists instead of divide+hover-pill outline clash. - Dark-safe native selects (color-scheme + themed options); Bulk Rename into node header; boxed moderation table; mobile header-action wrapping. - app.blade.php resolves the Inertia page entry by existing extension (.vue vs .tsx) so migrated pages load in production builds. --- resources/js/app.ts | 19 + .../js/components/admin/BulkImageModal.vue | 6 +- .../js/components/admin/BulkRenameModal.vue | 4 +- .../js/components/admin/BulkVideoModal.vue | 2 +- .../js/components/admin/CreateNodeModal.vue | 2 +- .../components/admin/CreateResourceModal.vue | 2 +- .../components/admin/CreateSubjectModal.vue | 4 +- resources/js/components/admin/NodeHeader.vue | 42 +- resources/js/components/admin/NodeRow.vue | 2 +- .../js/components/admin/NodeTabsHeader.vue | 55 +- .../components/admin/PendingSubmissionRow.vue | 14 +- resources/js/components/admin/ResourceRow.vue | 16 +- .../components/admin/ReviewResourceModal.vue | 12 +- resources/js/components/admin/SubjectCard.vue | 2 +- resources/js/components/admin/UserRow.vue | 19 +- resources/js/components/admin/ui.tsx | 423 ++++++ .../js/components/navigation/Navigation.tsx | 13 +- resources/js/layouts/AdminLayout.vue | 22 +- resources/js/lib/adminFormGuard.ts | 60 + resources/js/pages/admin/ChatSettings.tsx | 1191 +++++++++++++++++ resources/js/pages/admin/ChatSettings.vue | 1069 --------------- resources/js/pages/admin/Dashboard.tsx | 445 ++++++ resources/js/pages/admin/Dashboard.vue | 417 ------ resources/js/pages/admin/EmailSend.tsx | 1183 ++++++++++++++++ resources/js/pages/admin/EmailSend.vue | 1166 ---------------- resources/js/pages/admin/Index.tsx | 212 +++ resources/js/pages/admin/Index.vue | 155 --- resources/js/pages/admin/Node.tsx | 485 +++++++ resources/js/pages/admin/Node.vue | 424 ------ resources/js/pages/admin/NoticeEdit.tsx | 479 +++++++ resources/js/pages/admin/NoticeEdit.vue | 376 ------ resources/js/pages/admin/PeerSettings.tsx | 303 +++++ resources/js/pages/admin/PeerSettings.vue | 356 ----- resources/js/pages/admin/Tickets.tsx | 633 +++++++++ resources/js/pages/admin/Tickets.vue | 633 --------- resources/js/pages/admin/chat/Reports.tsx | 448 +++++++ resources/js/pages/admin/chat/Reports.vue | 548 -------- resources/js/pages/admin/forums/Index.tsx | 529 ++++++++ resources/js/pages/admin/forums/Index.vue | 482 ------- resources/js/pages/admin/forums/Reports.tsx | 486 +++++++ resources/js/pages/admin/forums/Reports.vue | 474 ------- resources/js/pages/admin/forums/Settings.tsx | 433 ++++++ resources/js/pages/admin/forums/Settings.vue | 330 ----- .../js/pages/admin/moderation/Resources.vue | 8 +- .../js/pages/admin/users/CreateOrEdit.tsx | 759 +++++++++++ .../js/pages/admin/users/CreateOrEdit.vue | 651 --------- resources/js/pages/admin/users/Index.tsx | 288 ++++ resources/js/pages/admin/users/Index.vue | 279 ---- resources/views/app.blade.php | 12 +- 49 files changed, 8510 insertions(+), 7463 deletions(-) create mode 100644 resources/js/components/admin/ui.tsx create mode 100644 resources/js/lib/adminFormGuard.ts create mode 100644 resources/js/pages/admin/ChatSettings.tsx delete mode 100644 resources/js/pages/admin/ChatSettings.vue create mode 100644 resources/js/pages/admin/Dashboard.tsx delete mode 100644 resources/js/pages/admin/Dashboard.vue create mode 100644 resources/js/pages/admin/EmailSend.tsx delete mode 100644 resources/js/pages/admin/EmailSend.vue create mode 100644 resources/js/pages/admin/Index.tsx delete mode 100644 resources/js/pages/admin/Index.vue create mode 100644 resources/js/pages/admin/Node.tsx delete mode 100644 resources/js/pages/admin/Node.vue create mode 100644 resources/js/pages/admin/NoticeEdit.tsx delete mode 100644 resources/js/pages/admin/NoticeEdit.vue create mode 100644 resources/js/pages/admin/PeerSettings.tsx delete mode 100644 resources/js/pages/admin/PeerSettings.vue create mode 100644 resources/js/pages/admin/Tickets.tsx delete mode 100644 resources/js/pages/admin/Tickets.vue create mode 100644 resources/js/pages/admin/chat/Reports.tsx delete mode 100644 resources/js/pages/admin/chat/Reports.vue create mode 100644 resources/js/pages/admin/forums/Index.tsx delete mode 100644 resources/js/pages/admin/forums/Index.vue create mode 100644 resources/js/pages/admin/forums/Reports.tsx delete mode 100644 resources/js/pages/admin/forums/Reports.vue create mode 100644 resources/js/pages/admin/forums/Settings.tsx delete mode 100644 resources/js/pages/admin/forums/Settings.vue create mode 100644 resources/js/pages/admin/users/CreateOrEdit.tsx delete mode 100644 resources/js/pages/admin/users/CreateOrEdit.vue create mode 100644 resources/js/pages/admin/users/Index.tsx delete mode 100644 resources/js/pages/admin/users/Index.vue diff --git a/resources/js/app.ts b/resources/js/app.ts index 1bd2831f..12a20506 100644 --- a/resources/js/app.ts +++ b/resources/js/app.ts @@ -20,6 +20,25 @@ router.on('navigate', () => { createInertiaApp({ title: (title) => (title ? `${title} - ${appName}` : appName), + /** + * Loads a page by its path relative to pages/, preferring .vue over .tsx. + * Resolves to the default export, or the module if that export is nullish. + * Throws if neither entry exists; import failures reject the promise. + */ + resolve: (name) => { + const pages = import.meta.glob('./pages/**/*.{vue,tsx}') as Record< + string, + () => Promise<{ default: unknown }> + >; + const loader = + pages[`./pages/${name}.vue`] ?? pages[`./pages/${name}.tsx`]; + + if (!loader) { + throw new Error(`Page not found: ${name}`); + } + + return loader().then((module) => module.default ?? module); + }, layout: (name) => { switch (true) { case name.startsWith('admin/'): diff --git a/resources/js/components/admin/BulkImageModal.vue b/resources/js/components/admin/BulkImageModal.vue index 07903f34..884fd95c 100644 --- a/resources/js/components/admin/BulkImageModal.vue +++ b/resources/js/components/admin/BulkImageModal.vue @@ -569,7 +569,7 @@ const submitForm = async () => {
{
{