import Link from "next/link"; import { requireOperator } from "@/lib/auth"; import { prisma } from "@/lib/prisma"; /** * Operator dashboard. Because phones often have the browser open between scans, * we want this page to answer one question fast: "what am I currently working * on?" Active claims are the headline list; below that we show a generic * "scan a card to start" hint so a fresh operator knows what to do. */ const OP_INCLUDE = { machine: { select: { name: true } }, part: { select: { code: true, name: true, qty: true, assembly: { select: { code: true, qty: true, project: { select: { code: true, name: true } }, }, }, }, }, } as const; export default async function OperatorHomePage() { const user = await requireOperator(); const [claims, resumable] = await Promise.all([ prisma.operation.findMany({ where: { claimedByUserId: user.id, status: "in_progress" }, orderBy: { claimedAt: "desc" }, include: OP_INCLUDE, }), // B1: partial ops are unclaimed after a release and only re-surface when // someone physically re-scans the card. List them here so any operator // can pick up where the last shift left off. prisma.operation.findMany({ where: { status: "partial", claimedByUserId: null }, orderBy: { updatedAt: "desc" }, take: 50, include: OP_INCLUDE, }), ]); return (
Scan a QR card with your phone camera to start a step, or continue an active one below.
Previously started and released with units still to run. Tap to pick up where the last shift left off.
{resumable.map((c) => { const total = c.part.qty * c.part.assembly.qty; const remaining = Math.max(total - c.unitsCompleted, 0); return (