- Implemented PATCH endpoints for changing the login mobile number of doctors and clinics. - Added ChangeLoginMobileModal component for handling mobile number updates in the UI. - Updated ClinicsPage and DoctorsPage to include buttons for changing mobile numbers. - Enhanced AdminApiController to manage mobile number changes with validation. - Created tests to ensure proper functionality and validation for mobile number changes. - Updated API documentation to reflect new endpoints and their usage.
82 lines
3.0 KiB
TypeScript
82 lines
3.0 KiB
TypeScript
import { useEffect, useState } from 'react';
|
|
import { useMutation, useQueryClient } from '@tanstack/react-query';
|
|
import { toast } from 'sonner';
|
|
import { api } from '../lib/api';
|
|
import { digitsOnly } from '../lib/utils';
|
|
import Modal from './ui/Modal';
|
|
|
|
interface Props {
|
|
/** `null` یعنی مودال بسته است. */
|
|
target: { uuid: string; name: string; mobile_number?: string | null } | null;
|
|
/** `doctors` → /api/v1/admin/doctors/{uuid}/mobile · `clinic` → /api/v1/admin/clinic/{uuid}/mobile */
|
|
resource: 'doctors' | 'clinic';
|
|
/** کلید کوئریِ لیستی که بعد از تغییر باید invalidate شود. */
|
|
queryKey: unknown[];
|
|
onClose: () => void;
|
|
}
|
|
|
|
/**
|
|
* تغییر شمارهٔ **ورود** پزشک/کلینیک توسط مدیر کل. شماره هویتِ ورود کاربر است، پس
|
|
* سرور یکتا بودن را کنترل میکند و اینجا فقط قالبِ ۰۹ + ۱۱ رقم اعتبارسنجی میشود.
|
|
*/
|
|
export default function ChangeLoginMobileModal({ target, resource, queryKey, onClose }: Props) {
|
|
const qc = useQueryClient();
|
|
const [mobile, setMobile] = useState('');
|
|
|
|
useEffect(() => {
|
|
setMobile(target?.mobile_number ?? '');
|
|
}, [target]);
|
|
|
|
const save = useMutation({
|
|
mutationFn: () => api.patch(`/api/v1/admin/${resource}/${target!.uuid}/mobile`, { mobile_number: mobile }),
|
|
onSuccess: () => {
|
|
toast.success('شماره موبایل تغییر کرد');
|
|
qc.invalidateQueries({ queryKey });
|
|
onClose();
|
|
},
|
|
onError: (e: Error) => toast.error(e.message),
|
|
});
|
|
|
|
const invalid = !/^09\d{9}$/.test(mobile);
|
|
|
|
return (
|
|
<Modal
|
|
open={target !== null}
|
|
title={`تغییر شماره ورود — ${target?.name ?? ''}`}
|
|
size="sm"
|
|
onClose={onClose}
|
|
footer={
|
|
<>
|
|
<button onClick={onClose} className="btn ghost sm">لغو</button>
|
|
<button
|
|
onClick={() => save.mutate()}
|
|
disabled={save.isPending || invalid}
|
|
className="btn primary sm"
|
|
>
|
|
{save.isPending ? 'در حال ذخیره...' : 'ذخیره'}
|
|
</button>
|
|
</>
|
|
}
|
|
>
|
|
<p style={{ margin: '0 0 14px', fontSize: 12, lineHeight: 1.9, color: 'var(--text-2)' }}>
|
|
این شماره، شمارهٔ <b>ورود به پنل</b> است. پس از تغییر، ورود فقط با شمارهٔ جدید ممکن
|
|
خواهد بود و شماره باید در کل سامانه یکتا باشد.
|
|
</p>
|
|
|
|
<div className="form-row">
|
|
<label>شماره موبایل</label>
|
|
<input
|
|
className="input"
|
|
dir="ltr"
|
|
inputMode="numeric"
|
|
aria-label="شماره موبایل"
|
|
placeholder="09xxxxxxxxx"
|
|
value={mobile}
|
|
onChange={(e) => setMobile(digitsOnly(e.target.value, 11))}
|
|
/>
|
|
{mobile !== '' && invalid && <p className="err-text">شماره باید با ۰۹ شروع شود و ۱۱ رقم باشد</p>}
|
|
</div>
|
|
</Modal>
|
|
);
|
|
}
|