+
+
Booking availability
+ {services.data && services.data.length > 1 && (
+
+ )}
+
+
+ Unchecked days show no times on the public booking page. Times are Eastern
+ (America/New_York) and are converted per visitor.
+
+
+ {availability.isLoading ? (
+
Loading…
+ ) : (
+
+ {DAYS.map((day, i) => {
+ const row = rows[i]!;
+ return (
+
+ );
+ })}
+
+ )}
+
+
+
+ {save.isSuccess && !save.isPending && (
+
+ Saved
+
+ )}
+ {save.error && {save.error.message}}
+
+
+ );
+}
diff --git a/server/trpc/routers/scheduling.ts b/server/trpc/routers/scheduling.ts
index 3c179cc..025628f 100644
--- a/server/trpc/routers/scheduling.ts
+++ b/server/trpc/routers/scheduling.ts
@@ -88,6 +88,17 @@ export const schedulingRouter = createTRPCRouter({
// ── Availability ─────────────────────────────────────────────────────────
+ getAvailability: staffProcedure
+ .input(z.object({ serviceId: z.string().cuid().optional() }))
+ .query(({ ctx, input }) =>
+ ctx.db.staffAvailability.findMany({
+ // Scope must mirror setAvailability's replace-scope exactly, or the
+ // editor would show one set of hours and overwrite a different one.
+ where: { userId: ctx.session.user.id, serviceId: input.serviceId ?? null },
+ orderBy: { dayOfWeek: "asc" },
+ })
+ ),
+
setAvailability: staffProcedure
.input(
z.object({