feat: Add kiosk management, artist selection, and schedule management

- Add KiosksManagement component with full CRUD for kiosks
- Add ScheduleManagement for staff schedules with break reminders
- Update booking flow to allow artist selection by customers
- Add staff_services API for assigning services to artists
- Update staff management UI with service assignment dialog
- Add auto-break reminder when schedule >= 8 hours
- Update availability API to filter artists by service
- Add kiosk management to Aperture dashboard
- Clean up ralphy artifacts and logs
This commit is contained in:
Marco Gallegos
2026-01-21 13:02:06 -06:00
parent 24e5af3860
commit d27354fd5a
71 changed files with 3353 additions and 2701 deletions

49
lib/calendar-utils.ts Normal file
View File

@@ -0,0 +1,49 @@
/**
* Calendar utilities for drag & drop operations
* Handles staff service validation, conflict checking, and booking rescheduling
*/
export const checkStaffCanPerformService = async (staffId: string, serviceId: string): Promise<boolean> => {
try {
const response = await fetch(`/api/aperture/staff/${staffId}/services`);
const data = await response.json();
return data.success && data.services.some((s: any) => s.services?.id === serviceId);
} catch (error) {
console.error('Error checking staff services:', error);
return false;
}
};
export const checkForConflicts = async (bookingId: string, staffId: string, startTime: string, duration: number): Promise<boolean> => {
try {
const endTime = new Date(new Date(startTime).getTime() + duration * 60 * 1000).toISOString();
// Check staff availability
const response = await fetch('/api/aperture/staff-unavailable', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ staff_id: staffId, start_time: startTime, end_time: endTime, exclude_booking_id: bookingId })
});
const data = await response.json();
return !data.available; // If not available, there's a conflict
} catch (error) {
console.error('Error checking conflicts:', error);
return true; // Assume conflict on error
}
};
export const rescheduleBooking = async (bookingId: string, updates: any) => {
try {
const response = await fetch(`/api/aperture/bookings/${bookingId}/reschedule`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(updates)
});
return await response.json();
} catch (error) {
console.error('Error rescheduling booking:', error);
return { success: false, error: 'Network error' };
}
};