Skip to content

Admin panel overview

The admin web app is the head-office operations surface. This page maps who can use it (Master vs role-limited admins), how JWT modules gates feature APIs, and how sidebar routes align with app-router.tsx.


All management URLs are nested under /dashboard and share one layout — see apps/admin-web/src/app/dashboard/layout.tsx (DashboardLayout):

RegionRole
LeftCollapsible Sidebar — navigation groups (Overview, Management, Product)
TopTopBar — account / quick actions
CenterMain — React Router <Outlet /> renders the active page

Unauthenticated flows (/, /login, /register, /forgot-password, /reset-password, /verify-otp) are full-page screens without this shell. / is the configurable marketing landing; /login is the real sign-in form.

The index route renders DashboardHomePage (apps/admin-web/src/app/dashboard/page.tsx): an analytics-style overview with:

  • Period and date range controls (e.g. last 7 / 30 / 90 days).
  • Tenant scope (all / store / vendor) when loading overview and chart data.
  • Stat cards, profit / activity charts, product lists, and low-stock widgets fed by admin dashboard APIs (admin-dashboard.api).

From here, users move to deeper areas via the sidebar (URL changes; only the outlet content updates). For field-by-field detail of the home widgets, see Dashboard home (Admin).

flowchart LR
  subgraph auth["Public"]
    A[Login / Register / OTP]
  end
  subgraph shell["Dashboard shell"]
    S[Sidebar]
    T[TopBar]
    O[Page outlet]
  end
  A -->|JWT session| shell
  O --> H[Home /dashboard]
  O --> M[Management routes]
  O --> P[Product routes]
  S --> O
  1. User signs in → redirect to /dashboard → sees home widgets scoped by JWT role and filters.
  2. User clicks a sidebar item → navigates to e.g. /dashboard/orderslist screen in the outlet.
  3. User opens a row → /dashboard/orders/:iddetail in the same shell.
  4. Create/edit flows (e.g. products, stores) use nested routes such as /dashboard/products/create — still inside the same layout.

Backend 403 responses appear when JWT modules does not allow the operation; the shell may still show the nav entry (Roles).


GoalsNon-goals
Clarify navigation and permission model before deep divesHide or replace backend 403 enforcement with UI-only hiding
Link to zones, roles, and technical tenancy docsDocument every admin API handler line-by-line

After sign-in, routes live under /dashboard. Module keys (e.g. catalog item) gate APIs—the sidebar may still show entries (Roles). Master admins (modules === null on the JWT) have unrestricted module access; other roles carry an explicit modules array. Modules registry create/edit/delete in the UI is limited to Master admins (modules === null) (Modules).


  1. Admin signs in → lands on /dashboard (Dashboard home).
  2. Opens a management area (Orders, Products, Stores, …) from the sidebar.
  3. API calls carry JWT; restricted modules → 403 from backend.

  • Treat modules: null as full module access; restricted roles need explicit module keys aligned with backend guards.
  • Data visibility for list endpoints follows each service’s rules (store filters, vendor tenancy, etc.)—never assume an empty list means no data exists elsewhere.
  • Operational onboarding (accounts, optional legacy Zones registry) is an internal process; see Troubleshooting.

IDScenarioExpected
A1Master admin opens OrdersList loads; APIs succeed for allowed scope
A2Role-limited admin opens same areaData follows API rules for that role and filters
A3Admin without item module hits catalog API403 (or equivalent) from backend

  • Master admin and role-limited staff. JWT payloads from login/me include:
    • modules: string[] | null — aligned with Laravel admin_roles.modules. modules === null means unrestricted module access (Master Admin / full access in backend guards). If modules is an array, the admin only has access to features whose module keys are listed.
  • Catalog, orders, stores, vendors, and role management — exact API access depends on role + modules (and explicit store/tenant arguments on each request where applicable). The sidebar does not hide entries by module; a missing permission shows up as 403 from the API instead.
  • Master admin — typically modules null: full module registry work (Modules) and legacy Zones UI if enabled (Zones), plus catalog and orders as the backend allows.
  • Role-limited adminmodules is a string array: APIs and UI respect those keys; module registry mutations on /dashboard/modules stay disabled unless modules === null (Modules).

Labels use i18n keys under nav.*; routes are fixed in Sidebar.tsx:

GroupItems (href)
OverviewDashboard /dashboard
ManagementOrders, Managers, Stores, Vendors, Roles, Zones, Modules
ProductProducts, Suppliers, Warehouses

Notifications, Help, and Settings are available from the shell (top bar / extra links), not this grouped list — see routes in app-router.tsx.

AreaTypical routes
Home/dashboard
Orders/dashboard/orders, /dashboard/orders/:id
Products/dashboard/products, create/edit/detail
Suppliers/dashboard/suppliers, /dashboard/suppliers/:id
Warehouses/dashboard/warehouses, /dashboard/warehouses/:id
Stores/dashboard/stores, create/edit/detail
Vendors/dashboard/vendors, create/edit/detail
Managers/dashboard/managers, create/edit
Roles/dashboard/roles, new/edit
Zones/dashboard/zones, create/detail/edit
Modules/dashboard/modules, detail
Notifications / Help / Settings/dashboard/notifications, /dashboard/help, /dashboard/settings

Source of truth: apps/admin-web/src/routes/app-router.tsx.

  • Add screenshots per major area when the UI stabilizes.