feat: add ROLE_REPRESENTATION access to admin panel for managing doctors and clinics

- Updated authStore to include 'representation' role.
- Modified DoctorFormPage and DoctorsPage to handle different endpoints based on user role.
- Created new RepresentationActionController for handling doctor and clinic creation by representatives.
- Added new API endpoints for representatives to manage doctors, clinics, and view appointments.
- Updated documentation to reflect new role and API changes.
This commit is contained in:
hamed
2026-06-19 13:20:40 +03:30
parent a8d36d7455
commit fe73fa1a05
14 changed files with 778 additions and 19 deletions
+13 -5
View File
@@ -15,6 +15,7 @@ import { z } from 'zod';
import { api } from '../lib/api';
import type { ApiResponse, PaginatedResponse } from '../lib/api';
import type { Clinic } from '../types';
import { useAuthStore } from '../stores/authStore';
import { formatDate, formatNumber } from '../lib/utils';
import Pagination from '../components/ui/Pagination';
import ConfirmDialog from '../components/ui/ConfirmDialog';
@@ -31,6 +32,8 @@ type AddForm = z.infer<typeof addSchema>;
export default function ClinicsPage() {
const navigate = useNavigate();
const qc = useQueryClient();
const primaryRole = useAuthStore(s => s.primaryRole);
const isRepresentation = primaryRole === 'representation';
const [page, setPage] = useState(1);
const [search, setSearch] = useState('');
const [statusFilter, setStatusFilter] = useState('');
@@ -38,13 +41,14 @@ export default function ClinicsPage() {
const [addOpen, setAddOpen] = useState(false);
const limit = 15;
const listBase = isRepresentation ? '/api/v1/clinics' : '/api/v1/admin/clinics';
const { data, isLoading } = useQuery({
queryKey: ['admin-clinics', page, search, statusFilter],
queryKey: ['admin-clinics', page, search, statusFilter, isRepresentation],
queryFn: () =>
api.get<PaginatedResponse<Clinic>>(
`/api/v1/admin/clinics?page=${page}&limit=${limit}` +
`${listBase}?page=${page}&limit=${limit}` +
(search ? `&search=${encodeURIComponent(search)}` : '') +
(statusFilter !== '' ? `&status=${statusFilter}` : ''),
(!isRepresentation && statusFilter !== '' ? `&status=${statusFilter}` : ''),
),
});
@@ -70,13 +74,17 @@ export default function ClinicsPage() {
const addForm = useForm<AddForm>({ resolver: zodResolver(addSchema) });
const addMutation = useMutation({
mutationFn: (d: AddForm) => api.post<ApiResponse<{ uuid: string }>>('/api/v1/admin/clinic', d),
mutationFn: (d: AddForm) =>
api.post<ApiResponse<{ uuid: string }>>(
isRepresentation ? '/api/v1/representation/clinic' : '/api/v1/admin/clinic',
d,
),
onSuccess: (res) => {
toast.success('کلینیک اضافه شد');
setAddOpen(false);
addForm.reset();
qc.invalidateQueries({ queryKey: ['admin-clinics'] });
if (res?.data?.uuid) navigate(`/admin/clinics/${res.data.uuid}`);
if (!isRepresentation && res?.data?.uuid) navigate(`/admin/clinics/${res.data.uuid}`);
},
onError: (err: Error) => toast.error(err.message),
});