Admin web app for managing the Service Hub platform: catalog, orders, payments, users, and vendor onboarding. Talks to service-hub-backend.
| Category | Library |
|---|---|
| Framework / build | React 18, Vite 5 |
| UI kit | Ant Design 5 (antd), @ant-design/charts |
| Styling | Tailwind CSS 3 (+ tailwind-merge, tailwind-scrollbar), daisyui |
| Data fetching | TanStack Query 5 (@tanstack/react-query) |
| State | Zustand |
| Routing | React Router 6 |
| Charts | apexcharts / react-apexcharts, echarts-for-react, recharts |
| HTTP | axios |
| Auth | jwt-decode, httpOnly-cookie session via the backend |
| Maps | @react-google-maps/api, @vis.gl/react-google-maps |
| Realtime | socket.io-client |
| Misc | dayjs, lodash, react-hot-toast, firebase (push), react-onesignal |
Single source of truth: src/theme/tokens.js — radius,
spacing, typography, and per-theme (lightTheme/darkTheme) colors/shadows.
This file feeds both styling systems so they can't drift apart:
tailwind.config.js— extends Tailwind's theme from the token values (e.g.bg-surface dark:bg-surface-dark).src/theme/antdTheme.js/src/theme/ThemeProvider.jsx— maps the same tokens into antd'sConfigProvidertheme.token/theme.components.
Reusable primitives built on top of the tokens live in
src/components/ds/ (Button, DataTable, StatusBadge,
StatCard, EmptyState, PageHeader, tones.js) — see Reusable Components below.
A standalone, unauthenticated /design-preview and /design-preview/live route exists
for reviewing the design system in isolation (src/pages/DesignPreview.jsx).
Routing (src/App.jsx) mixes two generations of code:
src/features/*(auth,dashboard-overview,service-catalog,product-catalog,order-management,payment-management,customer-management) — the current design-system implementation, wired to the backend's livesrc/features/*routes (confirmed againstsrc/apis/endpoints.js, which explicitly comments which blocks are live vs. dead).src/pages/*+src/containers/*+src/features/Dashboard/*(note the capitalD, a different, older folder) — an earlier implementation. Some of it (Categories/Vendor-service-requests routing, since replaced) is superseded; a large chunk of it is still routed inApp.jsxbut calls backend endpoints (/vendor-kyc/*,/vendors,/wallets/*,/bank-account/*,/transactions,/banner,/coupons/*,/memberships/*,/withdrawal/*,/admin/sub-admin,/calculator/leads,/rating/*) that do not exist on the current backend — see Known Gaps.
Live, working against real backend data:
- Dashboard (
/) —features/dashboard-overview, backed by/admin/dashboard/{summary,revenue-trend,category-performance,action-needed,recent-activity}. This is the redesigned version with real Mongo-aggregated data, not mock data — it replaced an older dashboard (src/features/Dashboard/*+pages/home/modules/*, which are no longer routed). - Service Catalog (
/categories,/categories/:categoryId,/categories/:categoryId/:subcategoryId,/services,/addons,/vendor-service-requests) —features/service-catalog, full Category → Subcategory → ServiceGroup → Service hierarchy management, Add-ons, and vendor request approve/reject, against the live/service-catalog/*backend routes. - Product Catalog (
/products,/products/categories) —features/product-catalog, list + create/edit drawer (no detail page, matching the Category/Service convention), against the live/products/*backend routes. - User Management (
/users,/users/:id) —Customerspage +UserDetailsPage, list/detail/block/deactivate against the live/admin/users/*backend routes. - Orders (
/orders,/orders/:id,/bookings,/bookings/:id) —features/order-management:ProductOrdersScreen/ServiceOrdersScreen(the 5 old status-based sub-routes were collapsed into one route + a status filter), sharedOrderDetailScreen, status updates, vendor assignment on service orders — against live/admin/orders/*and/admin/service-orders/:id/assign-vendor. - Payments (
/payments,/payments/:id) —features/payment-management, list + detail, and a workingRefundModalthat calls the real refund endpoint (/admin/payments/:id/refund) — not disabled, but the modal's own copy warns it moves real money via Razorpay, matching the backend's "code-complete, not proven against live credentials" status.
src/components/ds/ is the pattern to extend, not rebuild:
| Component | Purpose |
|---|---|
<DataTable /> |
Token-driven table wrapper (pagination, empty/loading states) used across every list screen in the migrated features |
<StatusBadge /> |
Tone-mapped status pill (see tones.js for the tone→color mapping) |
<StatCard /> |
Dashboard/summary metric tile |
<EmptyState /> |
Consistent "nothing here" placeholder |
<PageHeader /> |
Title/subtitle/actions row used at the top of every screen |
<Button /> |
Themed button with variant/danger/loading props over antd's Button |
New screens in the migrated features (service-catalog, product-catalog,
order-management, payment-management, dashboard-overview) should compose these
rather than building new table/badge/empty-state markup.
From .env:
| Variable | Required | Description |
|---|---|---|
VITE_APP_ENVIRONMENT |
yes | development selects the localhost API base URL; anything else selects the production one |
VITE_APP_LOCALHOST_BASE_URL |
yes (dev) | e.g. http://localhost:8000/api/v1 |
VITE_APP_BASE_URL |
yes (prod) | Deployed backend API base URL |
VITE_GOOGLE_MAPS_API_KEY |
yes (for map features) | Google Maps JS API key |
git clone <repo-url>
cd service-hub-admin
npm install
cp .env.example .env # if no .env.example exists, copy the table above into .env
npm run devOther scripts:
npm run build # vite build
npm run preview # preview a production build locally
npm run lint # eslint src
npm run lint:fix
npm run format # prettier --write- A large share of routed pages call backend endpoints that don't exist. Verified
by cross-referencing
src/apis/endpoints.js(which flags several blocks in comments as pointing at dead/never-mounted routes) against the backend's actual mounted feature list. Pages currently inApp.jsxthat are affected:- Vendor management (
/vendors,/vendor/:id,/vendors/add) — no vendor CRUD feature exists on the backend. - KYC (legacy pages) (
/kyc,/kyc/:id,/kyc/add) — hits/vendor-kyc/*, which doesn't match the backend's real KYC routes (/vendor/kyc/steps/*,/admin/kyc/:vendorId/approve|reject). The admin-side KYC approve/reject that does exist on the backend has no corresponding UI here yet. - Wallets (
/wallets/*) and Bank Accounts (/bank-accounts/*) — no wallet or bank-account feature on the backend. - Transactions (
/transactions/*) — no general transactions/ledger endpoint on the backend. - Banner (
/banner) — no banner feature on the backend. - Coupons (
/coupons) — no coupon feature on the backend. - Membership (
/membership/*) — no membership feature on the backend (explicitly future scope there too). - Withdrawals (
/withdrawals) — no withdrawal feature on the backend. - Admin management (
/admins) — the page expects list/create/update-permissions endpoints that don't exist; the backend only supportsPATCH /admin/:adminId/sub-roleand provisions the first admin via a CLI seed script. - Settings (
/settings), Calculator leads (/calculator-leads), Chat (/chats) — no matching backend feature. - Treat all of the above as UI shells pending backend work, not working features.
- Vendor management (
pages/Product.jsx/ProductContaineris an orphaned legacy file — not routed anywhere inApp.jsx(superseded byfeatures/product-catalog'sProductScreen).- No automated tests in this package (no test script/framework in
package.json).