initial admin dashboard with orders technicians reports users#138
Merged
Conversation
There was a problem hiding this comment.
Pull request overview
Scaffolds an apps/admin Vite + React + TanStack Router dashboard inside the existing pnpm/turbo monorepo, with mock-driven Orders / Technicians / Reports / Users pages, a design-token-based Tailwind setup, Zustand auth + theme stores, and a @FixIt/env web entry point. The PR is intentionally UI-first scaffolding — most data is mocked and the login flow stubs a session.
Changes:
- New
apps/adminworkspace: Vite/Vitest config, Tailwind + design tokens, TanStack Router tree, AppShell/Sidebar/Topbar layout, dashboard/orders/technicians/reports/homeowners pages, Zustand auth & theme stores, Supabase client placeholder. - Adds a
./webexport andcreateWebEnvto@FixIt/env, plus rootpackage.jsonscripts (dev:admin,dev:web) and a pnpmchokidaroverride. - Introduces mock domain types/data and shared UI primitives (cards, charts, filters) to drive the scaffolded admin views.
Reviewed changes
Copilot reviewed 105 out of 108 changed files in this pull request and generated 21 comments.
Show a summary per file
| File | Description |
|---|---|
| package.json | Adds admin/web turbo scripts and chokidar pnpm override; dev:web duplicates dev:admin. |
| packages/env/package.json | Exposes new ./web subpath export. |
| packages/env/src/web.ts | Adds createWebEnv with Vite client env validation. |
| apps/admin/vite.config.ts | Vite + TanStack Router + Vitest setup with @ alias. |
| apps/admin/tsr.config.json | TanStack Router generator configuration. |
| apps/admin/tsconfig*.json | App and Node tsconfig extending shared base. |
| apps/admin/tailwind.config.ts | Tailwind theme wired to local design tokens and CSS variables. |
| apps/admin/src/vite-env.d.ts | Types Vite env vars for the admin app. |
| apps/admin/src/types/domain.ts | Mock domain model types for orders/techs/reports/etc. |
| apps/admin/src/test/setup.ts | Vitest + Testing Library setup. |
| apps/admin/src/styles/globals.css | Light/dark CSS variables and Tailwind base layer. |
| apps/admin/src/stores/theme-store.ts | Persisted theme preference store. |
| apps/admin/src/stores/auth-store.ts | Persisted admin auth store (tokens persisted to localStorage). |
| apps/admin/src/routeTree.gen.ts | Generated TanStack route tree. |
| (other admin files) | Layout, dashboard widgets, mock data, login flow, and route screens supporting the scaffolded pages. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| "check-types": "turbo check-types", | ||
| "dev:native": "turbo -F native dev", | ||
| "dev:admin": "turbo -F admin dev", | ||
| "dev:web": "turbo -F admin dev", |
| const [range, setRange] = useState<Range>("30d"); | ||
|
|
||
| const sliced: OrderSeries = (() => { | ||
| const days = range === "7d" ? 7 : range === "90d" ? 30 : 30; |
Comment on lines
+43
to
+44
| const result = loginSchema.safeParse(value); | ||
| if (!result.success) return; |
Comment on lines
+7
to
+18
| const PAGE_TITLES: Record<string, string> = { | ||
| "/dashboard": "Dashboard", | ||
| "/orders": "Orders", | ||
| "/categories": "Categories", | ||
| "/technicians": "Technicians", | ||
| "/users": "Homeowners", | ||
| "/reviews": "Reviews", | ||
| "/reports": "Reports", | ||
| "/payouts": "Payouts", | ||
| "/settings": "Settings", | ||
| "/support": "Help & Support", | ||
| }; |
Comment on lines
+9
to
+21
| const SPECIALTY_TO_CATEGORY_ID: Record<string, string> = { | ||
| "Plumbing": "plumb", | ||
| "Air Conditioning": "ac", | ||
| "Electrician": "elec", | ||
| "Electrical": "elec", | ||
| "Home Cleaning": "clean", | ||
| "Painter": "paint", | ||
| "Painting": "paint", | ||
| "Carpentry": "carp", | ||
| "Oven & Cooker": "oven", | ||
| "Fridge / Freezer": "fridge", | ||
| "Dish Installation": "ac", | ||
| }; |
Comment on lines
+22
to
+50
| <button | ||
| key={r.id} | ||
| type="button" | ||
| onClick={() => onView(r)} | ||
| className="text-left rounded-lg border border-border bg-card p-3 hover:bg-muted/30 transition-colors" | ||
| > | ||
| <div className="flex items-start gap-3"> | ||
| <TechAvatar initials={r.reporterInitials} color={r.reporterColor} size="md" /> | ||
| <div className="flex-1 min-w-0"> | ||
| <div className="flex items-center gap-2 flex-wrap"> | ||
| <p className="text-sm font-semibold text-foreground truncate">{r.reporterName}</p> | ||
| <RoleChip role={r.reporterRole} /> | ||
| </div> | ||
| <p className="text-xs text-muted-foreground mt-0.5">vs {r.against} · {r.filedAt}</p> | ||
| <p className="text-sm text-foreground mt-1.5 line-clamp-2">{r.summary}</p> | ||
| <div className="flex items-center gap-2 mt-2 flex-wrap"> | ||
| <span className="text-[11px] font-mono text-muted-foreground">{r.orderId}</span> | ||
| <CategoryTag meta={getCategoryMetaById(r.category)} fallbackLabel={r.category} size="sm" hideLabel /> | ||
| {r.status === "closed" && r.resolution && ( | ||
| <StatusBadge | ||
| variant={r.resolution === "resolved" ? "success" : "muted"} | ||
| label={r.resolution} | ||
| /> | ||
| )} | ||
| </div> | ||
| </div> | ||
| <Button size="sm" variant="outline" onClick={(e) => { e.stopPropagation(); onView(r); }}>View</Button> | ||
| </div> | ||
| </button> |
Comment on lines
+21
to
+24
| const MOCK_ADMIN = { | ||
| email: "admin@fixit.com", | ||
| password: "admin123", | ||
| }; |
Comment on lines
+85
to
+118
| {field.state.meta.errors.length > 0 && ( | ||
| <p className="text-xs text-destructive">{String(field.state.meta.errors[0] ?? "")}</p> | ||
| )} | ||
| </div> | ||
| )} | ||
| </form.Field> | ||
|
|
||
| <form.Field name="password"> | ||
| {(field) => ( | ||
| <div className="flex flex-col gap-1.5"> | ||
| <Label htmlFor="password">Password</Label> | ||
| <div className="relative"> | ||
| <Input | ||
| id="password" | ||
| type={showPassword ? "text" : "password"} | ||
| placeholder="••••••••" | ||
| autoComplete="current-password" | ||
| value={field.state.value} | ||
| onChange={(e) => field.handleChange(e.target.value)} | ||
| onBlur={field.handleBlur} | ||
| className={field.state.meta.errors.length > 0 ? "border-destructive pr-10" : "pr-10"} | ||
| /> | ||
| <button | ||
| type="button" | ||
| onClick={() => setShowPassword((p) => !p)} | ||
| className="absolute right-3 top-1/2 -translate-y-1/2 text-muted-foreground hover:text-foreground transition-colors" | ||
| aria-label={showPassword ? "Hide password" : "Show password"} | ||
| > | ||
| {showPassword ? <EyeOff className="h-4 w-4" /> : <Eye className="h-4 w-4" />} | ||
| </button> | ||
| </div> | ||
| {field.state.meta.errors.length > 0 && ( | ||
| <p className="text-xs text-destructive">{String(field.state.meta.errors[0] ?? "")}</p> | ||
| )} |
Comment on lines
+9
to
+21
| const SPECIALTY_TO_CATEGORY_ID: Record<string, string> = { | ||
| "Plumbing": "plumb", | ||
| "Air Conditioning": "ac", | ||
| "Electrician": "elec", | ||
| "Electrical": "elec", | ||
| "Home Cleaning": "clean", | ||
| "Painter": "paint", | ||
| "Painting": "paint", | ||
| "Carpentry": "carp", | ||
| "Oven & Cooker": "oven", | ||
| "Fridge / Freezer": "fridge", | ||
| "Dish Installation": "ac", | ||
| }; |
| <CardHeader className="flex-row items-center justify-between gap-4 pb-2 flex-wrap"> | ||
| <div> | ||
| <CardTitle className="text-base">Orders Over Time</CardTitle> | ||
| <p className="text-xs text-muted-foreground mt-0.5">Homeowner vs technician order volumes</p> |
This was
linked to
issues
May 26, 2026
Closed
MeryAmr
approved these changes
May 27, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
added initial pages frontend for admin dashboard ,orders page, users page ,technician page , reports page with the setup and folder structure for mono repo