feat(admin): let the secretary pre-assign an operator when booking
The backend already accepted staff_uuid on POST /api/v1/my/appointment; only the booking modal never sent it, so the pre-assignment half of the operator model had no way in. The field sits in step 1 next to the section select and is optional by design: left empty, the session stays in the shared queue that every allowed operator sees. Its placeholder says so rather than leaving the blank state unexplained. The section select is no longer the only combobox in the modal, so the tests target it by its label instead of by role. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -4,10 +4,12 @@ import { useMutation, useQuery } from '@tanstack/react-query';
|
||||
import { ChevronDownIcon, ClockIcon, MagnifyingGlassIcon, CheckCircleIcon, CpuChipIcon, ExclamationCircleIcon } from '@heroicons/react/24/outline';
|
||||
import { toast } from 'sonner';
|
||||
import { api } from '../../lib/api';
|
||||
import type { ApiResponse } from '../../lib/api';
|
||||
import { digitsOnly, sanitizeMobileInput, rialToToman, tomanToRial, formatRial, formatDate } from '../../lib/utils';
|
||||
import { useAuthStore } from '../../stores/authStore';
|
||||
import Modal from '../ui/Modal';
|
||||
import PriceInput from '../ui/PriceInput';
|
||||
import SearchableSelect from '../ui/SearchableSelect';
|
||||
import ServiceSlotPicker from './ServiceSlotPicker';
|
||||
import type { ServicePick } from './ServiceSlotPicker';
|
||||
import type { BookingService } from '../../hooks/useDoctorBookingServices';
|
||||
@@ -57,6 +59,9 @@ export default function NewAppointmentModal({
|
||||
// معیار جستجوی بیمار: کد ملی (پیشفرض) یا موبایل.
|
||||
const [searchBy, setSearchBy] = useState<'mobile' | 'national'>('national');
|
||||
const [pick, setPick] = useState<ServicePick>({ serviceUuids: [], durations: {}, slot: null });
|
||||
// اپراتور اختیاری است: خالی گذاشتنش جلسه را در صفِ مشترکِ پرسنلِ مجاز میگذارد،
|
||||
// پر کردنش آن را از قبل به یک نفر میدهد.
|
||||
const [staffUuid, setStaffUuid] = useState('');
|
||||
|
||||
const role = useAuthStore(s => s.primaryRole);
|
||||
// نوبتِ منبع فقط مسیر پنل را دارد؛ اندپوینت ادمین `resource_uuid` نمیشناسد.
|
||||
@@ -81,6 +86,13 @@ export default function NewAppointmentModal({
|
||||
enabled: !!slot.doctor_uuid,
|
||||
retry: false,
|
||||
});
|
||||
const staffQ = useQuery<ApiResponse<{ uuid: string; full_name: string }[]>>({
|
||||
queryKey: ['staff-list'],
|
||||
queryFn: () => api.get('/api/v1/staff'),
|
||||
enabled: pickerMode,
|
||||
staleTime: 60_000,
|
||||
});
|
||||
|
||||
const selfPricingQ = useQuery<Pricing>({
|
||||
queryKey: ['insurance-pricing'],
|
||||
queryFn: () => api.get('/api/v1/insurance-pricing'),
|
||||
@@ -145,6 +157,7 @@ export default function NewAppointmentModal({
|
||||
patient_name: effectiveName,
|
||||
patient_national_code: effectiveNationalCode,
|
||||
...(clinicUuid ? { clinic_uuid: clinicUuid } : {}),
|
||||
...(staffUuid ? { staff_uuid: staffUuid } : {}),
|
||||
...(pickerMode ? { service_item_uuids: pick.serviceUuids } : {}),
|
||||
// منبع: مدت را سرور از سرویسهای همین منبع میسازد، پس ساعت پایان حدس نیست.
|
||||
...(resource ? {
|
||||
@@ -264,6 +277,22 @@ export default function NewAppointmentModal({
|
||||
onSelect={setPick}
|
||||
clinicUuidOverride={clinicUuid}
|
||||
/>
|
||||
|
||||
{/* اختیاری بهعمد: پیشفرضِ سیستم صفِ مشترک است و منشی فقط وقتی دخالت
|
||||
میکند که بیمار اپراتور مشخصی خواسته باشد. */}
|
||||
<div className="field-block" style={{ marginTop: 12 }}>
|
||||
<label htmlFor="appt-operator">اپراتور <span className="opt">(اختیاری)</span></label>
|
||||
<SearchableSelect
|
||||
inputId="appt-operator"
|
||||
options={(staffQ.data?.data ?? []).map(s => ({ value: s.uuid, label: s.full_name }))}
|
||||
value={staffUuid || null}
|
||||
onChange={v => setStaffUuid(v ? String(v) : '')}
|
||||
placeholder="در صف مشترک پرسنل بماند"
|
||||
isLoading={staffQ.isLoading}
|
||||
isClearable
|
||||
height={40}
|
||||
/>
|
||||
</div>
|
||||
</Step>
|
||||
)}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user