add client 2
CI / ci (push) Canceled after 0s

now auto shows after being added.
This commit is contained in:
Stefan Lazic committed 2026-09-14 13:17:07 +01:00
1 parent 0d821ce1f8
commit 410aa07596
2 files changed
+25 -11

No files matched your search

+24 -9
View File
@@ -31,14 +31,29 @@ export default async function StaffClientsPage({
// Scoped via the appointment relation, not "every CustomerProfile row" —
// a real business boundary even though this is a single-business v1 app
// (see docs/phase-5-summary.md). `select`-scoped rather than the full
// row + full appointment `include` this used to fetch — the card only
// ever reads status/startAt off each appointment, never the service
// lines/notes/discount that a full include would also pull down for
// every appointment of every client on every page view (see the Phase 7
// performance pass).
// (see docs/phase-5-summary.md). A registered client with NO appointment
// anywhere yet (freshly added via /staff/clients/add, or self-registered
// but never booked) is also included — otherwise a client staff just
// added would be invisible here until their first booking, which reads
// as "did that even work?". A registered client with appointments only
// at some other business (not reachable in this single-business-per-
// deployment app, but kept as a real predicate rather than an assumption)
// is correctly excluded either way. Guests are never included by this
// second branch — a guest profile is only ever created alongside an
// appointment (see resolveGuestCustomer), so one with zero appointments
// shouldn't exist, but isGuest: false is there as a real guard, not a
// guess. `select`-scoped rather than the full row + full appointment
// `include` this used to fetch — the card only ever reads status/startAt
// off each appointment, never the service lines/notes/discount that a
// full include would also pull down for every appointment of every
// client on every page view (see the Phase 7 performance pass).
const customers = await prisma.customerProfile.findMany({
where: { appointments: { some: { businessId: context.businessId } } },
where: {
OR: [
{ appointments: { some: { businessId: context.businessId } } },
{ isGuest: false, appointments: { none: {} } },
],
},
select: {
id: true,
firstName: true,
@@ -72,7 +87,7 @@ export default async function StaffClientsPage({
const now = new Date();
return (
<div className="pb-8 lg:max-w-5xl">
<div className="pb-8">
<TopNav
title="Clients"
sticky
@@ -141,7 +156,7 @@ export default async function StaffClientsPage({
}
/>
) : (
<div className="grid gap-3 lg:grid-cols-2">
<div className="grid gap-3 lg:grid-cols-2 xl:grid-cols-3 2xl:grid-cols-4">
{sorted.map((customer) => {
const completedVisits = customer.appointments.filter(
(a) => a.status === "COMPLETED",
@@ -41,8 +41,7 @@ export function AddClientForm() {
<div className="space-y-4 rounded-md border-line border bg-white p-6">
<p className="text-sm font-bold">{added.name} has been added.</p>
<p className="text-muted text-sm">
They can sign in anytime with just their email — no password, no invite email sent. They&apos;ll show up
in Clients once they have an appointment.
They can sign in anytime with just their email — no password, no invite email sent.
</p>
<div className="flex gap-3">
<Button variant="secondary" className="flex-1" onClick={() => router.push("/staff/clients")}>