Files
clinicpro/assets/admin/hooks/useDoctorBookingServices.ts
T
hamedandClaude Opus 4.8 e00fe997f9 feat: section-based service picker + per-appointment duration override (service mode)
Service-booking mode now selects services by section like slot mode:
appointment-booking-services returns service_section per item; ServiceSlotPicker
groups by section (SearchableSelect), accumulates picks across sections into a
removable 'section -> service' chip list.

Secretaries can override a service's duration for a single appointment without
changing the service default: appointment-service-slots accepts durations[uuid]
and both create endpoints accept service_durations; the override drives total
duration and slot_end. Online (patient) booking is unaffected — it never sends
overrides. Backend + frontend tests and docs updated.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-16 10:41:15 +03:30

38 lines
1.2 KiB
TypeScript

import { useQuery } from '@tanstack/react-query';
import { api } from '../lib/api';
import type { ApiResponse } from '../lib/api';
export interface BookingService {
uuid: string;
name: string;
duration_minutes: number | null;
price_rials: number;
service_section: { uuid: string; name: string };
}
interface BookingServicesData {
booking_mode: 'slot' | 'service';
buffer_minutes: number;
services: BookingService[];
}
/**
* روش نوبت‌دهی و سرویس‌های قابل‌انتخابِ یک پزشک — از endpoint عمومیِ
* `appointment-booking-services`. برای سرویس‌محور کردن فرم‌های ثبت نوبت پنل.
*/
export function useDoctorBookingServices(doctorUuid: string | null | undefined) {
const q = useQuery<ApiResponse<BookingServicesData>>({
queryKey: ['booking-services', doctorUuid],
queryFn: () => api.get(`/api/v1/appointment-booking-services/${doctorUuid}`),
enabled: !!doctorUuid,
});
const data = q.data?.data as BookingServicesData | undefined;
return {
bookingMode: (data?.booking_mode === 'service' ? 'service' : 'slot') as 'slot' | 'service',
bufferMinutes: data?.buffer_minutes ?? 0,
services: data?.services ?? [],
isLoading: q.isLoading,
};
}