Skip to content

Export admin pages as components #1345

@paanSinghCoder

Description

@paanSinghCoder

Export Admin Pages as components

Problem Statement

The admin UI pages in frontier/ui/src/pages/ are tightly coupled and makes it difficult to add new external pages. We need to extract these pages as reusable, router-agnostic components that can be consumed by external applications while maintaining all functionality and adding their own pages.

It is very crucial to maintain the uniformity with SDK as similar refactor will be going on there.

Goals

  1. Export admin pages from web/lib/admin as @raystack/frontier/admin
  2. Make pages router-agnostic (accept navigation callbacks as props)
  3. Export pages with tabs as single components (individual tab pages can be exported in further iterations)
  4. Maintain all existing functionality (API calls, state management, UI structure)
  5. Keep app shell(top bar, sidebar, routing) separate from exported pages (where applicable).
  6. Detailed documentation

Architecture

Export Structure

web/lib/admin/
├── pages/
│   ├── organizations/
│   │   ├── list/
│   │   │   └── index.tsx          # OrganizationListPage (navbar + filter + table)
│   │   └── details/
│   │       └── index.tsx          # OrganizationDetailsPage (with tabs: members, projects, invoices, tokens, apis, security)
│   ├── users/
│   │   ├── list/
│   │   │   └── index.tsx           # UsersListPage (navbar + filter + table)
│   │   └── details/
│   │       └── index.tsx           # UserDetailsPage (with tabs: security)
│   ├── audit-logs/
│   │   └── list/
│   │       └── index.tsx          # AuditLogsListPage (navbar + filter + table)
│   └── invoices/
│       └── list/
│           └── index.tsx           # InvoicesListPage
├── components/                     # Shared admin components
├── contexts/                       # Page-specific contexts (OrganizationContext, UserContext)
└── index.ts                        # Main export file

Package Exports

// web/lib/admin/index.ts
export { OrganizationListPage } from './pages/organizations/list';
export { OrganizationDetailsPage } from './pages/organizations/details';
export { UsersListPage } from './pages/users/list';
export { UserDetailsPage } from './pages/users/details';
export { AuditLogsListPage } from './pages/audit-logs/list';
export { InvoicesListPage } from './pages/invoices/list';

// Types
export type { AdminPageProps, NavigationHandler } from './types';

Router-Agnostic API Design

All exported pages accept navigation callbacks instead of using react-router-dom directly:

interface NavigationHandler {
  navigate: (path: string) => void;
  getCurrentPath: () => string;
  getParams: () => Record<string, string>;
}

interface AdminPageProps {
  navigation: NavigationHandler;
  // Other page-specific props
}

Pages with Tabs

Pages with tabs (e.g., OrganizationDetailsPage, UserDetailsPage) are exported as single components with internal tab state management:

// OrganizationDetailsPage handles all tabs internally
<OrganizationDetailsPage
  organizationId={id}
  navigation={navigation}
  activeTab="members" // or "projects", "invoices", etc.
/>

Implementation Steps

  1. Create export structure in web/lib/admin/

    • Set up pages/, components/, contexts/ directories
    • Create index.ts export file
  2. Extract pages from ui/src/pages/

    • Copy page components to web/lib/admin/pages/
    • Remove router dependencies (useNavigate, useParams, NavLink)
    • Replace with navigation props
  3. Update contexts

    • Extract OrganizationContext and UserContext to web/lib/admin/contexts/
    • Make contexts accept navigation handlers
  4. Update package.json

    • Add admin export path in web/lib/package.json:
      {
        "exports": {
          "./admin": {
            "types": "./admin/index.d.ts",
            "import": "./admin/index.mjs",
            "require": "./admin/index.js"
          }
        }
      }
  5. Update build config

    • Add admin entry point in web/lib/tsup.config.ts
    • Build admin pages to admin/dist/
  6. Update web/apps/admin

    • Import pages from @raystack/frontier/admin
    • Set up routing wrapper that provides navigation handlers
    • Connect pages to app shell (sidebar, top bar)
  7. Testing

    • Verify all pages work in web/apps/admin
    • Ensure API calls, state management, and UI interactions work correctly

Files to Create/Modify

New Files

  • web/lib/admin/pages/organizations/list/index.tsx
  • web/lib/admin/pages/organizations/details/index.tsx
  • web/lib/admin/pages/users/list/index.tsx
  • web/lib/admin/pages/users/details/index.tsx
  • web/lib/admin/pages/audit-logs/list/index.tsx
  • web/lib/admin/pages/invoices/list/index.tsx
  • web/lib/admin/contexts/organization-context.tsx
  • web/lib/admin/contexts/user-context.tsx
  • web/lib/admin/types.ts
  • web/lib/admin/index.ts

Modified Files

  • web/lib/package.json - Add admin export
  • web/lib/tsup.config.ts - Add admin build entry
  • web/apps/admin/src/routes.tsx - Use exported pages with navigation wrappers

Success Criteria

  • All admin pages exportable from @raystack/frontier/admin
  • Pages are router-agnostic and accept navigation handlers
  • Pages with tabs exported as single components
  • All functionality preserved (API calls, state, UI)
  • web/apps/admin successfully consu

Metadata

Metadata

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions