From 04855cb8a435aac08b380a4f8a9f4cf22ae17311 Mon Sep 17 00:00:00 2001 From: Pedro Gomes Date: Sat, 16 May 2026 16:22:55 +0100 Subject: [PATCH] MAI CALL - step 9 --- .claude/settings.local.json | 3 +- apps/operator-pwa/app/page.tsx | 128 +++++++++++-------------- apps/operator-pwa/app/ping-client.tsx | 43 --------- apps/operator-pwa/app/status-badge.tsx | 14 +++ 4 files changed, 71 insertions(+), 117 deletions(-) delete mode 100644 apps/operator-pwa/app/ping-client.tsx create mode 100644 apps/operator-pwa/app/status-badge.tsx diff --git a/.claude/settings.local.json b/.claude/settings.local.json index 2b10315..3c6f15c 100644 --- a/.claude/settings.local.json +++ b/.claude/settings.local.json @@ -33,7 +33,8 @@ "Bash(Select-String \"15\\\\.\")", "Bash(Select-Object -Last 15)", "Bash(pnpm --filter @repo/operator-pwa build -- --no-lint)", - "Bash(pnpm --filter @repo/operator-pwa exec next build)" + "Bash(pnpm --filter @repo/operator-pwa exec next build)", + "Bash(del \"c:\\\\Users\\\\prdcg\\\\Documents\\\\Git\\\\FieldOps\\\\apps\\\\operator-pwa\\\\app\\\\ping-client.tsx\")" ] } } diff --git a/apps/operator-pwa/app/page.tsx b/apps/operator-pwa/app/page.tsx index 8d5da9c..a76523a 100644 --- a/apps/operator-pwa/app/page.tsx +++ b/apps/operator-pwa/app/page.tsx @@ -1,90 +1,72 @@ -import { TRPCError } from '@trpc/server'; -import { CheckCircle2, AlertCircle } from 'lucide-react'; -import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@repo/ui'; -import { Alert, AlertDescription, AlertTitle } from '@repo/ui'; -import { api } from '@/lib/trpc/server'; +import Link from 'next/link'; +import { Wrench } from 'lucide-react'; import { resolveUser } from '@/lib/auth'; -import { PingClient } from './ping-client'; +import { api } from '@/lib/trpc/server'; import { SignOutButton } from './sign-out-button'; +import { StatusBadge } from './status-badge'; export default async function HomePage() { const user = await resolveUser(); - let result: - | { ok: true; payload: Awaited> } - | { ok: false; message: string; code: string } = { - ok: false, - message: 'init', - code: 'INIT', - }; - + // myRecent is a protectedProcedure — fails gracefully when there is no session. + type RecentItem = Awaited>[number]; + let recent: RecentItem[] = []; try { - const payload = await api.ping.ping(); - result = { ok: true, payload }; - } catch (err) { - if (err instanceof TRPCError) { - result = { ok: false, message: err.message, code: err.code }; - } else if (err instanceof Error) { - result = { ok: false, message: err.message, code: 'UNKNOWN' }; - } else { - result = { ok: false, message: String(err), code: 'UNKNOWN' }; - } + recent = await api.maintenanceRequest.myRecent({ limit: 5 }); + } catch { + // No session or other error — show empty list without crashing. } return ( -
- {user && ( -
- {user.email} - +
+ {/* ── Header ── */} +
+
+

Operador

+

+ {user?.email ?? '—'} +

- )} - -
-

FieldOps Operator

-

Scaffold smoke test

+
- {result.ok ? ( - - - - - Connected - - - End-to-end path verified: RSC → tRPC → Prisma → Postgres. - - - -
- Tenant: - {result.payload.tenant.name} -
-
- id: {result.payload.tenant.id} -
-
- at: {result.payload.timestamp} -
-
-
- ) : ( - - - Ping failed ({result.code}) - -

{result.message}

-

- If this says UNAUTHORIZED, set{' '} - AUTH_DEV_AUTOLOGIN=true in .env for local dev, - or sign in via the operator picker. -

-
-
- )} +
+ {/* ── Primary CTA ── */} + + + Pedir manutenção + - + {/* ── Recent requests ── */} +
+

Os meus pedidos

+ + {recent.length === 0 ? ( +

Nenhum pedido ainda.

+ ) : ( +
    + {recent.map((req) => ( +
  • +
    +

    + {req.workstation.code} — {req.workstation.name} +

    +

    {req.description}

    +
    + +
  • + ))} +
+ )} +
+
); } diff --git a/apps/operator-pwa/app/ping-client.tsx b/apps/operator-pwa/app/ping-client.tsx deleted file mode 100644 index f16e25f..0000000 --- a/apps/operator-pwa/app/ping-client.tsx +++ /dev/null @@ -1,43 +0,0 @@ -'use client'; - -import { CheckCircle2, AlertCircle, Loader2 } from 'lucide-react'; -import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@repo/ui'; -import { trpc } from '@/lib/trpc/client'; - -/** - * Client-side ping. Demonstrates the second tRPC path: client hooks + - * TanStack Query. The RSC caller above the fold and this hook hit the same - * procedure — both must succeed for the hybrid wiring to be considered green. - */ -export function PingClient() { - const query = trpc.ping.ping.useQuery(); - - return ( - - - - {query.isPending ? ( - - ) : query.isError ? ( - - ) : ( - - )} - Client-side ping (useQuery) - - Round-trips through /api/trpc. - - - {query.isPending && Loading…} - {query.isError && ( - - {query.error.message} - - )} - {query.data && ( - tenant: {query.data.tenant.name} - )} - - - ); -} diff --git a/apps/operator-pwa/app/status-badge.tsx b/apps/operator-pwa/app/status-badge.tsx new file mode 100644 index 0000000..88ccf29 --- /dev/null +++ b/apps/operator-pwa/app/status-badge.tsx @@ -0,0 +1,14 @@ +const CONFIG = { + OPEN: { label: 'Aberto', className: 'bg-orange-100 text-orange-700 dark:bg-orange-900/30 dark:text-orange-400' }, + CLAIMED: { label: 'Em curso', className: 'bg-blue-100 text-blue-700 dark:bg-blue-900/30 dark:text-blue-400' }, + RESOLVED: { label: 'Resolvido',className: 'bg-green-100 text-green-700 dark:bg-green-900/30 dark:text-green-400' }, +} as const; + +export function StatusBadge({ status }: { status: keyof typeof CONFIG }) { + const { label, className } = CONFIG[status]; + return ( + + {label} + + ); +}