From 7338c9d9e2ebe864f85f543f7058314ebca4bf87 Mon Sep 17 00:00:00 2001 From: Stefan Lazic Date: Fri, 18 Sep 2026 21:07:37 +0100 Subject: [PATCH] Update page.tsx --- src/app/(staff)/staff/clients/[id]/page.tsx | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/src/app/(staff)/staff/clients/[id]/page.tsx b/src/app/(staff)/staff/clients/[id]/page.tsx index 2aff4d0..3394ba5 100644 --- a/src/app/(staff)/staff/clients/[id]/page.tsx +++ b/src/app/(staff)/staff/clients/[id]/page.tsx @@ -51,12 +51,18 @@ export default async function StaffCustomerDetailsPage({ }); if (!customer) notFound(); - // "Belongs to this business" is via the appointment relation — see - // docs/phase-5-summary.md, same reasoning as the clients list query. - const belongsToBusiness = await prisma.appointment.findFirst({ - where: { customerId: id, businessId: context.businessId }, - select: { id: true }, - }); + // "Belongs to this business" mirrors the Clients list query exactly + // (see (staff)/staff/clients/page.tsx) — either a real appointment here, + // or a registered client with no appointment anywhere yet (added via + // /staff/clients/add, or self-registered but never booked). Without the + // second branch, a client visible in the list because of that same + // broadening would 404 the moment staff actually clicked into them — + // confirmed live, this exact gap. + const [appointmentsHereCount, totalAppointmentCount] = await Promise.all([ + prisma.appointment.count({ where: { customerId: id, businessId: context.businessId } }), + prisma.appointment.count({ where: { customerId: id } }), + ]); + const belongsToBusiness = appointmentsHereCount > 0 || (!customer.isGuest && totalAppointmentCount === 0); if (!belongsToBusiness) notFound(); const [upcoming, past, cancelled, notesRaw, loyalty] = await Promise.all([