You are a senior frontend engineer. Generate a **production-ready Next.js (App Router) admin dashboard** using **Tabler UI** as the design system. Use this prompt as the current source of truth for backend behavior. ## Backend Summary (Current) - Base URL: `http://` (Swagger: `/swagger-ui.html`, OpenAPI: `/v3/api-docs`) - Security: JWT (Bearer token) - Multi-tenancy: required via header `X-Tenant-Id` - Optional LDAP mode: `app.ldap.enabled` (backend switch) - API pattern: most state-changing endpoints are workflow-driven approvals - Default responses use: ```ts type ApiResponse = { success: boolean message: string data: T timestamp: string } ``` ## Tech Stack - Next.js (App Router) - React 18+ - TypeScript - Tabler UI (CSS/React components) - Axios - Zustand (recommended) - Tailwind (optional only for utility overrides) - react-intl or next-intl for i18n ## Recommended Project Structure - `app/` - `(auth)/login/page.tsx` - `(dashboard)/layout.tsx` - `(dashboard)/page.tsx` - `api-proxy/` or service barrel exports - `components/` - `layout/` (DashboardShell, Sidebar, Header) - `ui/` (Table, Form, Modal, Alert, Badge, Drawer) - `workflow/` (ApprovalTable, StatusBadge, ApprovalActionModal) - `user/` (UserForm, UpdateRolesForm) - `role/` (RoleForm, RolePermissionForm) - `services/` - `api.ts` - `auth.ts` - `users.ts` - `workflow.ts` - `tenant.ts` - `audit.ts` - `store/` - `authStore.ts` - `uiStore.ts` - `tenantStore.ts` - `permissionStore.ts` - `hooks/` - `useAuth.ts`, `useTenantHeader.ts`, `useApi.ts`, `usePermissions.ts` - `types/` - API contracts and DTO types ## API Endpoints to Use (exact) ### Auth - `POST /api/auth/login` - `POST /api/auth/refresh` - `POST /api/auth/logout` ### Authenticated profile - `GET /api/users/me` ### User management (workflow requests) - `POST /api/users/management/requests/create` - `POST /api/users/management/requests/update-roles` ### Role management (workflow requests) - `POST /api/roles/management/requests/create` - `POST /api/roles/management/requests/update-permissions` ### Workflow - `POST /api/workflow/request` - `POST /api/workflow/{id}/approve` - `POST /api/workflow/{id}/reject` - `GET /api/workflow/requests?status=PENDING&resourceType=...&makerUsername=...&limit=50` ### Modules - `GET /api/modules` - `POST /api/modules/{code}/toggle` ### Tenant & audit - `GET /api/tenant/context` - `GET /api/audit?limit=50` ## Authentication and request headers For **every request** after login: - `Authorization: Bearer ` - `X-Tenant-Id: ` Login request also requires tenant context because backend resolves tenant at auth time: - `POST /api/auth/login` with header `X-Tenant-Id` Logout request behavior: - `POST /api/auth/logout` requires a valid Bearer token because backend invalidates/revokes refresh/session context. Optional: - `Accept-Language: en-US` or `id-ID` ## JWT/session behavior - Access token in response includes `tokenType: "Bearer"`, `accessToken`, `refreshToken`, `expiresIn` - Store tokens in secure storage strategy (HTTP-only cookies preferred if possible; otherwise memory + storage hardening) - Add request interceptor to attach token and `X-Tenant-Id` - Add response interceptor for 401: - clear auth state - redirect to login - keep tenant and locale selections persisted ## Important authorization model Backend sends authorities as roles/permissions: - Roles come as `ROLE_` (from DB role code) - Permissions come as plain `...` codes - Controllers currently check: - User create/update-roles: `hasAuthority('USER_MANAGE') or hasRole('USER_ROLE_ADMIN')` - Role create/update-permissions: `hasAuthority('ROLE_MANAGE') or hasRole('USER_ROLE_ADMIN')` - Create workflow request: `hasAuthority('WORKFLOW_CREATE') or hasRole('MAKER')` - Approve/reject: `hasAuthority('WORKFLOW_APPROVE') or hasRole('CHECKER')` - Workflow list: `hasAuthority('WORKFLOW_APPROVE') or hasRole('CHECKER') or hasRole('ADMIN')` - `/api/audit`: `hasRole('ADMIN')` - `/api/users/me`: `hasAuthority('USER_READ') or hasRole('ADMIN')` So frontend should render actions conditionally using permissions derived from `/api/users/me`. ## LDAP mode alignment Backend has optional LDAP mode (`app.ldap.enabled`). - **Local mode** - `/api/users/management/requests/create` requires `password` - **LDAP mode** - Password is managed in directory (backend does not require password for user provisioning) - `password` should not be sent for user creation - optional `ldapDn` may be included - Common for both modes - user update roles still workflow-driven - role create/update-permissions still workflow-driven - no direct mutation endpoints for user/role entities ## Required front-end behavior by page ### 1) Login page - Input: username, password, tenant selector - Submit `POST /api/auth/login` - Pass `X-Tenant-Id` header - Handle error responses from backend localization keys and lockout messages ### 2) Dashboard shell - Sidebar: Dashboard, Users, Roles, Workflow, Audit, Modules, Settings - Top bar: tenant selector, locale switch, user menu/logout - Display auth mode indicator (Local / LDAP) when available ### 3) Dashboard home - Show summary cards: - pending workflow count - pending checker workload (from `/api/workflow/requests?status=PENDING`) - audit/approval health snapshots (from `/api/audit?limit=50`) - recent audits (from /api/audit) ### 4) Users page - There is no direct `/api/users` list endpoint in current backend, so derive list/context from workflow/request history and `/api/users/me` context. - Actions: - create user request (workflow) - update user roles request (workflow) - In LDAP mode hide password input on create form - In local mode enforce password validation before submit ### 5) Roles page - No direct role list endpoint exists in current backend; show role/permission operations using current user context and workflow history as available. - Implement create role request + permission update request flows. - Permission selector from current in-app permission catalog (from `/api/users/me`, seeded defaults, and known workflow operations). ### 6) Workflow page - Show `/api/workflow/requests` with filters - `status` (`DRAFT`, `PENDING`, `APPROVED`, `REJECTED`) - `resourceType` - `makerUsername` - `limit` - Actions: - Approve modal - Reject modal - show notes and optional checkerRole (if omitted, backend uses step role default `CHECKER`) ### 7) Audit page - Admin-only - `GET /api/audit?limit=50` - render `action`, `resourceType`, `resourceId`, before/after snapshots, outcome, correlation id - Keep pagination/infinite-load support for audit + workflow lists. ## DTO references for implementation ### Login ```ts { username: string; password: string } ``` ### Create user management request - Local mode: ```ts { username: string password: string enabled?: boolean roleCodes: string[] } ``` - LDAP mode: ```ts { username: string ldapDn?: string enabled?: boolean roleCodes: string[] } ``` ### Update user roles ```ts { username: string; roleCodes: string[] } ``` ### Create role request ```ts { code: string; name: string; permissionCodes: string[] } ``` ### Update role permissions ```ts { code: string; permissionCodes: string[] } ``` ### Workflow action ```ts { notes?: string; checkerRole?: string } ``` ### Create approval request (generic) ```ts { resourceType: string; resourceId: string; payload?: string; requiredSteps: number } ``` ### Response from `/api/users/me` ```ts { tenantId: string; username: string; roles: string[]; permissions: string[] } ``` ## UI requirements - Use Tabler-inspired components for - tables - forms - modals - badges - alerts - Keep navigation corporate and simple - Add loading states, inline error states, and toast notifications - Keep table columns configurable (search, sort, pagination) ## Error handling Backend may return these patterns: - Login failures with localized message - Lockout message key in i18n when brute force threshold exceeded - Standard `ApiResponse` with `success` false Frontend should: - show notification from `message` - maintain tenant context in state across page refresh/login switch - keep unauthorized navigation blocked by RBAC-derived route guards ## Delivery expectations Please generate runnable code for: - `app/` shell and route layout - Axios client with interceptors - Login/auth flow - Tenant-aware request wrapper - Users module screens + workflow request forms - Roles module screens + workflow request forms - Workflow list/detail with approve/reject action - Audit list - Reusable table/form/modal components Please include a short setup checklist: - env vars (`NEXT_PUBLIC_API_BASE_URL` etc) - install commands - run instructions