Phase 8
This commit is contained in:
82 files changed
+4903
-287
No files matched your search
@@ -16,6 +16,7 @@ import {
|
||||
} from "@/services/scheduling/appointment.service";
|
||||
import { awardStampForCompletedAppointment } from "@/services/loyalty/loyalty.service";
|
||||
import { notifyAppointmentNoShow, notifyBookingApproved, notifyBookingBarberChanged, notifyBookingCompleted } from "@/services/scheduling/booking-notifications";
|
||||
import { syncAppointmentSafely } from "@/services/calendar/calendar-sync.service";
|
||||
import { writeAuditLog } from "@/lib/audit/write-audit-log";
|
||||
import type { StaffAppointmentActionResult } from "@/features/staff/actions/appointment-actions";
|
||||
|
||||
@@ -79,6 +80,7 @@ export async function ownerConfirmAppointmentAction(appointmentId: string): Prom
|
||||
return { success: false, error: friendlyTransitionMessage(result.validation.issues[0]?.code) };
|
||||
}
|
||||
await notifyBookingApproved(prisma, result.appointment);
|
||||
await syncAppointmentSafely(prisma, appointmentId);
|
||||
return { success: true };
|
||||
}
|
||||
|
||||
@@ -125,6 +127,7 @@ export async function ownerMarkNoShowAction(appointmentId: string): Promise<Staf
|
||||
return { success: false, error: friendlyTransitionMessage(result.validation.issues[0]?.code) };
|
||||
}
|
||||
await notifyAppointmentNoShow(prisma, result.appointment);
|
||||
await syncAppointmentSafely(prisma, appointmentId);
|
||||
return { success: true };
|
||||
}
|
||||
|
||||
@@ -140,9 +143,11 @@ export async function ownerCancelAppointmentAction(params: {
|
||||
cancelledByUserId: owner.userId,
|
||||
reason: params.reason,
|
||||
});
|
||||
return result.success
|
||||
? { success: true }
|
||||
: { success: false, error: result.validation.issues[0]?.message ?? "Couldn't cancel this appointment." };
|
||||
if (!result.success) {
|
||||
return { success: false, error: result.validation.issues[0]?.message ?? "Couldn't cancel this appointment." };
|
||||
}
|
||||
await syncAppointmentSafely(prisma, params.appointmentId);
|
||||
return { success: true };
|
||||
}
|
||||
|
||||
export interface OwnerRescheduleResult {
|
||||
@@ -181,5 +186,6 @@ export async function ownerRescheduleAppointmentAction(params: {
|
||||
await notifyBookingBarberChanged(prisma, result.appointment);
|
||||
}
|
||||
|
||||
await syncAppointmentSafely(prisma, params.appointmentId);
|
||||
return { success: true };
|
||||
}
|
||||
@@ -136,8 +136,8 @@ export function BookingRulesForm({ initial }: { initial: BookingRuleInput }) {
|
||||
onCheckedChange={(v) => set("customerCanChooseStaff", v)}
|
||||
/>
|
||||
<Switch
|
||||
label="Allow guest bookings"
|
||||
description="Let customers book without an account."
|
||||
label="Allow customers to book as guests"
|
||||
description="When enabled, customers can book without creating an account. When disabled, customers must sign in or create an account before confirming their booking."
|
||||
checked={form.allowGuestBooking}
|
||||
onCheckedChange={(v) => set("allowGuestBooking", v)}
|
||||
/>
|
||||
|
||||
Reference in new issue
Block a user