{"path":"docs/wiki/Dashboard.md","size":4854,"locked":false,"binary":false,"truncated":false,"content":"# Dashboard\n\nThe Mappers Dashboard (`apps/dashboard/`) is a single-page application that provides real-time visibility into escrow jobs, oracle health, and aggregate protocol statistics.\n\n---\n\n## Tech Stack\n\n| Layer | Technology |\n|---|---|\n| Build tool | Vite |\n| UI framework | React 19 |\n| Data fetching | TanStack Query (React Query) |\n| Component library | shadcn/ui |\n| Styling | Tailwind CSS |\n| Type safety | TypeScript + generated Zod schemas |\n| API client | `@workspace/api-client-react` (auto-generated hooks) |\n\n---\n\n## Features\n\n### Job Overview\n\nThe main view displays all escrow jobs with:\n- Job ID and wallet addresses (truncated with copy-to-clipboard)\n- Status badges (pending, completed, cancelled) with color coding\n- Escrowed amount formatted in SOL\n- Creation and last update timestamps\n\nJobs can be filtered by status and client address.\n\n### Job Details\n\nClicking a job shows full metadata:\n- Complete wallet addresses (client, freelancer, oracle)\n- Exact lamport amount and SOL equivalent\n- Transaction signature (linked to Solana Explorer when available)\n- Full description and acceptance criteria\n- State transition history via timestamps\n\n### Statistics Dashboard\n\nAggregate view showing:\n- Total jobs registered\n- Breakdown by status (pending / completed / cancelled)\n- Total SOL currently in escrow\n- Oracle health status\n\n### Oracle Health\n\nLive indicator showing whether the AI oracle middleware is reachable and how many jobs are in its pending queue.\n\n---\n\n## Running Locally\n\n### Development\n\n```bash\ncd apps/dashboard\npnpm run dev\n```\n\nOpens at `http://localhost:5173`. Hot-reloads on file changes.\n\n### Production Build\n\n```bash\ncd apps/dashboard\npnpm run build    # Outputs to dist/\npnpm run serve    # Preview the production build\n```\n\n### Configuration\n\n| Variable | Default | Description |\n|---|---|---|\n| `PORT` | `5173` | Dev server port |\n| `BASE_PATH` | `/` | Base path for deployment behind a reverse proxy |\n\n---\n\n## Architecture\n\n```\nDashboard (React 19)\n    |\n    | uses hooks from @workspace/api-client-react\n    |   (generated by orval from the OpenAPI spec)\n    v\nCustom Fetch Layer (lib/api-client-react/src/custom-fetch.ts)\n    |\n    | setBaseUrl() configures the target\n    | setAuthTokenGetter() adds bearer tokens (for mobile/Expo)\n    v\nAPI Server (Express 5)\n```\n\n### Generated Hooks\n\nThe dashboard uses auto-generated TanStack Query hooks. These are created by [orval](https://orval.dev/) from the OpenAPI spec in `lib/api-spec/`:\n\n```typescript\n// Available hooks (from @workspace/api-client-react):\nuseHealthCheck()\nuseListJobs(params?)\nuseGetJob(jobId)\nuseCreateJob()\nuseUpdateJob(jobId)\nuseSubmitDeliverable(jobId)\nuseGetStats()\nuseGetOracleHealth()\n```\n\nEach hook provides:\n- Automatic caching and background refetching\n- Loading and error states\n- Type-safe request/response types\n- Optimistic updates where applicable\n\n### Custom Fetch\n\nThe `customFetch` function (in `lib/api-client-react/src/custom-fetch.ts`) handles:\n- Base URL resolution (for cross-origin deployments)\n- Bearer token injection (for mobile/Expo apps)\n- Response parsing (JSON, text, blob)\n- Error normalization (all errors become `ApiError` instances)\n\n---\n\n## Component Structure\n\n```\nsrc/\n|-- App.tsx                    Main app with routing and layout\n|-- components/\n|   |-- job-card.tsx           Individual job display card\n|   |-- status-badge.tsx       Colored status indicator\n|   |-- ui/                    shadcn/ui primitive components\n|-- lib/\n|   |-- format.ts             Formatting utilities (lamports, pubkeys, dates)\n```\n\n### Utility Functions\n\n```typescript\n// lib/format.ts\n\n// Format lamports to SOL with locale-aware separators\nformatLamports(\"5000000000\")  // \"5.00\"\nformatLamports(\"123456789012345678\")  // \"123,456,789.0123\"\n\n// Truncate a public key for display\ntruncatePubkey(\"7xKXtg2CW87d97TXJSDpbD5jBkheTqA83TZRuJosgAsU\")\n// \"7xKX...AsU\"\n\n// Format ISO date to locale string\nformatDate(\"2026-01-15T10:30:00.000Z\")\n// \"1/15/2026, 10:30:00 AM\"\n```\n\n---\n\n## Development Tips\n\n**Adding a new API endpoint to the dashboard:**\n\n1. Add the endpoint to the OpenAPI spec in `lib/api-spec/`\n2. Run `cd lib/api-spec && pnpm run codegen` to regenerate hooks\n3. Import and use the new hook in your component:\n   ```typescript\n   import { useMyNewEndpoint } from \"@workspace/api-client-react\";\n   ```\n\n**Adding a new UI component:**\n- shadcn/ui components live in `src/components/ui/`\n- Business logic components go in `src/components/`\n- Follow existing patterns for consistency\n\n**Connecting to a different API server:**\n```typescript\nimport { setBaseUrl } from \"@workspace/api-client-react\";\nsetBaseUrl(\"https://api.mappers.example.com\");\n```\n\n---\n\nSee [Getting Started](Getting-Started.md) to run the full stack, or the [API Reference](API-Reference.md) for the endpoints the dashboard consumes.\n"}