The public doctor payload built `active`/`free_turn`/`hours_of_work` from the personal schedule alone, so a doctor bookable only at a clinic was reported as "نوبتدهی غیرفعال". Aggregate over every schedule instead: any schedule with online booking on and an active day makes the doctor bookable, and the disabled label only appears when all of them are off. Three admin-panel fixes for the same class of bug: - AppointmentsPage took the selected doctor from `dbUuid`, which is the clinic's uuid inside a clinic context — the slots request 404'd. Use `doctorUuid`. - TurnsTimeline rendered any error or unknown empty_reason as "این روز شیفت کاری ندارد". Errors now surface as errors and unknown reasons get a neutral message; the day-off wording is reserved for an explicit day_off from the backend. - Admins have no clinic context, so slots fell back to the personal schedule. They now pick a location from `appointment-booking-locations` and that choice drives the slot, service and create-appointment requests. Adds `app:schedule:normalize-format` for legacy rows stored as a bare JSON list covering only Saturday, which read as day-off for the rest of the week. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
51 lines
1.8 KiB
TypeScript
51 lines
1.8 KiB
TypeScript
import { useQuery } from '@tanstack/react-query';
|
|
import { api } from '../lib/api';
|
|
import type { ApiResponse } from '../lib/api';
|
|
import { useClinicContext } from './useClinicContext';
|
|
|
|
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`. برای سرویسمحور کردن فرمهای ثبت نوبت پنل.
|
|
*
|
|
* clinicUuidOverride: `undefined` یعنی context محیط جاری؛ مقدار صریح (شامل null =
|
|
* مطب شخصی) وقتی که انتخاب محل خارج از context انجام شده (مثلاً ادمین).
|
|
*/
|
|
export function useDoctorBookingServices(
|
|
doctorUuid: string | null | undefined,
|
|
clinicUuidOverride?: string | null,
|
|
) {
|
|
const contextClinicUuid = useClinicContext();
|
|
const clinicUuid = clinicUuidOverride === undefined ? contextClinicUuid : clinicUuidOverride;
|
|
|
|
const q = useQuery<ApiResponse<BookingServicesData>>({
|
|
queryKey: ['booking-services', doctorUuid, clinicUuid],
|
|
queryFn: () => api.get(
|
|
`/api/v1/appointment-booking-services/${doctorUuid}`
|
|
+ (clinicUuid ? `?clinic_uuid=${encodeURIComponent(clinicUuid)}` : '')
|
|
),
|
|
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,
|
|
};
|
|
}
|