+ Moving over from another system?{" "} + + Import clients from a spreadsheet + +
+ )}+ Moving over from another system?{" "} + + Import clients from a spreadsheet + +
+ )}+ {toSend} to send · {sentCount} sent + {noPhoneCount > 0 && ` · ${noPhoneCount} with no usable phone number`} +
+ )} + + {rows.length === 0 ? ( +{row.time}
++ {row.serviceNames} + {canSeeEveryone && ` · ${row.staffName}`} +
++ Tap Send on WhatsApp, and WhatsApp opens on this phone with the reminder already written — you + press send there. It's marked as sent here so nobody messages the same customer twice. The app can't + see inside WhatsApp, so a booking is marked when you open the message, not when it's delivered. +
+npm run prisma:seed first.
- - {business.name} · {business.timezone} · not a real feature page, see docs/phase-3-summary.md -
-Selectable dates are ones the engine reports as having openings.
-No available slots this day for this selection.
- ) : ( -None yet.
} - {appointments.map((a) => ( -- {a.staff.user.name} · {a.services.map((s: { service: { name: string } }) => s.service.name).join(" + ")} -
-Importing clients…
++ {stage.done.toLocaleString()} of {stage.total.toLocaleString()} — keep this page open until it finishes. +
+{stage.stoppedEarly ? "Import stopped" : "Import complete"}
+{stage.stoppedEarly}
} ++ Nobody was emailed. Clients can sign in any time with just their email address, and any bookings they made + as a guest under it are attached to their account automatically. +
+Rows that weren't imported
+ +Showing the first 200 — download the file for the full list.
+ )} +Match each of these to a column in your file. We've guessed — check them.
+{blocker}
+ ) : ( + <> ++ {importable.toLocaleString()} of {analysis.total.toLocaleString()} rows are ready to import. +
+ {(analysis.problems.length > 0 || analysis.repeats > 0) && ( ++ {analysis.problems.length > 0 && `${analysis.problems.length.toLocaleString()} can't be imported (listed afterwards). `} + {analysis.repeats > 0 && `${analysis.repeats.toLocaleString()} repeat an email that's already earlier in the file and will be skipped.`} +
+ )} + {importable > 0 && ( +| Name | +Phone | +|
|---|---|---|
| {`${row.firstName} ${row.lastName}`.trim()} | +{row.email} | +{row.phone} | +
Bring your existing clients across
++ Upload a CSV file with one client per row. You need an email address for each client — that's how they sign + in and how their bookings are matched to them. Name and phone come along too. +
++ {error} +
+ )} +