feat: enhance DoctorAddress entity to support clinic addresses and types
- Added `clinic_id` and `type` fields to `DoctorAddress` entity to differentiate between personal and clinic addresses. - Updated constructor to support creation of addresses for both doctors and clinics. - Modified repository methods to handle new address types and added methods for counting and finding addresses by clinic. - Implemented migration to update the database schema accordingly. - Removed deprecated endpoint for creating addresses from clinics and updated related controller methods. - Added new endpoints for managing clinic addresses, including CRUD operations. - Updated frontend components to handle new address types and display accordingly.
This commit is contained in:
@@ -57,7 +57,11 @@ interface CityOpt { id: number; uuid: string; name: string; }
|
||||
interface ImageFileData { fid: number; uuid: string; url: string; filename: string; filemime: string; filesize: number; }
|
||||
|
||||
interface AddressData {
|
||||
id: string; uuid: string; name: string | null; address: string | null;
|
||||
id: string; uuid: string;
|
||||
type: 'personal' | 'clinic';
|
||||
clinic_id: string | null;
|
||||
clinic_name: string | null;
|
||||
name: string | null; address: string | null;
|
||||
telephone: string | null;
|
||||
map: { latitude: string | null; longitude: string | null };
|
||||
city: { id: string; name: string } | null;
|
||||
@@ -1061,9 +1065,22 @@ function SessionEditor({ session, onChange, onRemove, addresses }: {
|
||||
<select value={session.location_id ?? ''}
|
||||
onChange={e => upd('location_id', e.target.value ? Number(e.target.value) : null)}>
|
||||
<option value="">انتخاب کنید</option>
|
||||
{addresses.map(a => (
|
||||
<option key={a.id} value={a.id}>{a.name ?? a.address ?? `مطب ${a.id}`}</option>
|
||||
))}
|
||||
{addresses.filter(a => a.type === 'personal').length > 0 && (
|
||||
<optgroup label="مطب شخصی">
|
||||
{addresses.filter(a => a.type === 'personal').map(a => (
|
||||
<option key={a.id} value={a.id}>{a.name ?? a.address ?? `مطب ${a.id}`}</option>
|
||||
))}
|
||||
</optgroup>
|
||||
)}
|
||||
{addresses.filter(a => a.type === 'clinic').length > 0 && (
|
||||
<optgroup label="کلینیکها">
|
||||
{addresses.filter(a => a.type === 'clinic').map(a => (
|
||||
<option key={a.id} value={a.id}>
|
||||
{a.clinic_name ? `${a.clinic_name}${a.name ? ` — ${a.name}` : ''}` : (a.name ?? a.address ?? `کلینیک ${a.id}`)}
|
||||
</option>
|
||||
))}
|
||||
</optgroup>
|
||||
)}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1736,8 +1753,17 @@ const SCHEDULE_TABS = [
|
||||
{ id: 'holidays' as const, label: 'تعطیلات' },
|
||||
];
|
||||
|
||||
function ScheduleSection({ doctorUuid, addresses }: { doctorUuid: string; addresses: AddressData[] }) {
|
||||
function ScheduleSection({ doctorUuid }: { doctorUuid: string }) {
|
||||
const [tab, setTab] = useState<'weekly' | 'overrides' | 'holidays'>('weekly');
|
||||
|
||||
const locationsQ = useQuery({
|
||||
queryKey: ['available-locations', doctorUuid],
|
||||
queryFn: () => api.get<ApiResponse<AddressData[]>>(`/api/v1/appointment-settings/available-locations/${doctorUuid}`),
|
||||
enabled: !!doctorUuid,
|
||||
staleTime: 30_000,
|
||||
});
|
||||
const availableLocations: AddressData[] = locationsQ.data?.data ?? [];
|
||||
|
||||
return (
|
||||
<div className="cp-card p-6">
|
||||
<h2 className="text-sm font-semibold text-slate-700 dark:text-slate-300 mb-4">برنامه کاری</h2>
|
||||
@@ -1753,8 +1779,8 @@ function ScheduleSection({ doctorUuid, addresses }: { doctorUuid: string; addres
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
{tab === 'weekly' && <WeeklyScheduleTab doctorUuid={doctorUuid} addresses={addresses} />}
|
||||
{tab === 'overrides' && <DateOverridesTab doctorUuid={doctorUuid} addresses={addresses} />}
|
||||
{tab === 'weekly' && <WeeklyScheduleTab doctorUuid={doctorUuid} addresses={availableLocations} />}
|
||||
{tab === 'overrides' && <DateOverridesTab doctorUuid={doctorUuid} addresses={availableLocations} />}
|
||||
{tab === 'holidays' && <HolidaysTab doctorUuid={doctorUuid} />}
|
||||
</div>
|
||||
);
|
||||
@@ -2136,7 +2162,7 @@ export default function DoctorDetailPage({ isOwnProfile = false }: { isOwnProfil
|
||||
)}
|
||||
</div>
|
||||
|
||||
{uuid && <ScheduleSection doctorUuid={uuid} addresses={doctor.address ?? []} />}
|
||||
{uuid && <ScheduleSection doctorUuid={uuid} />}
|
||||
|
||||
{doctor.clinics && doctor.clinics.length > 0 && (
|
||||
<div className="cp-card p-6">
|
||||
|
||||
Reference in New Issue
Block a user