feat: add per-doctor permissions management in clinics
- Implement DoctorPermissionsModal for managing doctor permissions in clinics. - Create usePermissions hook to handle user permissions context. - Add migration for clinic_doctor_permissions table with default permissions. - Develop ClinicDoctorPermissionController for handling permissions API. - Create ClinicDoctorPermission entity to manage permissions data. - Implement ClinicDoctorPermissionRepository for database interactions. - Add ClinicDoctorPermissionChecker for permission validation logic. - Write tests for clinic doctor permissions functionality.
This commit is contained in:
+18
-8
@@ -1,6 +1,7 @@
|
||||
import React, { useEffect } from 'react';
|
||||
import { Routes, Route, Navigate, useLocation } from 'react-router-dom';
|
||||
import { useAuthStore } from './stores/authStore';
|
||||
import { usePermissions } from './hooks/usePermissions';
|
||||
import AdminLayout from './components/layout/AdminLayout';
|
||||
import LoginPage from './pages/LoginPage';
|
||||
import DashboardPage from './pages/DashboardPage';
|
||||
@@ -114,14 +115,23 @@ function PublicRoute({ children }: { children: React.ReactNode }) {
|
||||
return isAuthenticated ? <Navigate to="/admin/dashboard" replace /> : <>{children}</>;
|
||||
}
|
||||
|
||||
function RoleRoute({ roles, blockClinicScope, children }: { roles: string[]; blockClinicScope?: boolean; children: React.ReactNode }) {
|
||||
function RoleRoute({ roles, blockClinicScope, permission, children }: {
|
||||
roles: string[];
|
||||
blockClinicScope?: boolean;
|
||||
/** [resource, action] — پزشکِ مهمان با داشتن این مجوز از blockClinicScope مستثنا میشود. */
|
||||
permission?: [string, string];
|
||||
children: React.ReactNode;
|
||||
}) {
|
||||
const primaryRole = useAuthStore((s) => s.primaryRole);
|
||||
const context = useAuthStore((s) => s.context);
|
||||
const { can } = usePermissions();
|
||||
if (!primaryRole) return <div style={{ padding: 40, textAlign: 'center' }}>در حال بارگذاری...</div>;
|
||||
if (!roles.includes(primaryRole)) return <Navigate to="/admin/dashboard" replace />;
|
||||
// پزشکِ مهمان در محیط کلینیک به ابزارهای مدیریتی دسترسی ندارد.
|
||||
// پزشکِ مهمان در محیط کلینیک فقط تا جایی که کلینیک مجوز داده دسترسی دارد.
|
||||
if (blockClinicScope && primaryRole === 'doctor' && context?.scope === 'clinic') {
|
||||
return <Navigate to="/admin/dashboard" replace />;
|
||||
if (!permission || !can(permission[0], permission[1])) {
|
||||
return <Navigate to="/admin/dashboard" replace />;
|
||||
}
|
||||
}
|
||||
return <>{children}</>;
|
||||
}
|
||||
@@ -210,11 +220,11 @@ export default function App() {
|
||||
<Route path="my-payments" element={<RoleRoute roles={['doctor', 'secretary', 'clinic']} blockClinicScope><MyPaymentsPage /></RoleRoute>} />
|
||||
<Route path="my-payments/:patientUuid" element={<RoleRoute roles={['doctor', 'secretary', 'clinic']} blockClinicScope><MyPaymentDetailPage /></RoleRoute>} />
|
||||
|
||||
<Route path="patients" element={<RoleRoute roles={['doctor', 'secretary', 'clinic']} blockClinicScope><PatientsListPage /></RoleRoute>} />
|
||||
<Route path="patients/new" element={<RoleRoute roles={['doctor', 'secretary', 'clinic']} blockClinicScope><PatientRecordFormPage /></RoleRoute>} />
|
||||
<Route path="patients/:uuid/edit" element={<RoleRoute roles={['doctor', 'secretary', 'clinic']} blockClinicScope><PatientRecordFormPage /></RoleRoute>} />
|
||||
<Route path="patients/:uuid" element={<RoleRoute roles={['doctor', 'secretary', 'clinic']} blockClinicScope><PatientDetailPage /></RoleRoute>} />
|
||||
<Route path="patients/:recordUuid/session/new" element={<RoleRoute roles={['doctor', 'secretary', 'clinic']} blockClinicScope><NewSessionPage /></RoleRoute>} />
|
||||
<Route path="patients" element={<RoleRoute roles={['doctor', 'secretary', 'clinic']} blockClinicScope permission={['patients', 'view']}><PatientsListPage /></RoleRoute>} />
|
||||
<Route path="patients/new" element={<RoleRoute roles={['doctor', 'secretary', 'clinic']} blockClinicScope permission={['patients', 'create']}><PatientRecordFormPage /></RoleRoute>} />
|
||||
<Route path="patients/:uuid/edit" element={<RoleRoute roles={['doctor', 'secretary', 'clinic']} blockClinicScope permission={['patients', 'update']}><PatientRecordFormPage /></RoleRoute>} />
|
||||
<Route path="patients/:uuid" element={<RoleRoute roles={['doctor', 'secretary', 'clinic']} blockClinicScope permission={['patients', 'view']}><PatientDetailPage /></RoleRoute>} />
|
||||
<Route path="patients/:recordUuid/session/new" element={<RoleRoute roles={['doctor', 'secretary', 'clinic']} blockClinicScope permission={['patients', 'create']}><NewSessionPage /></RoleRoute>} />
|
||||
<Route path="my-patients/:recordUuid/session/new" element={<RoleRoute roles={['doctor', 'secretary', 'clinic']} blockClinicScope><NewSessionPage /></RoleRoute>} />
|
||||
<Route path="patients/:recordUuid/session/:sessionUuid/pay" element={<RoleRoute roles={['doctor', 'secretary', 'clinic']} blockClinicScope><SessionPaymentPage /></RoleRoute>} />
|
||||
<Route path="my-patients/:recordUuid/session/:sessionUuid/pay" element={<RoleRoute roles={['doctor', 'secretary', 'clinic']} blockClinicScope><SessionPaymentPage /></RoleRoute>} />
|
||||
|
||||
Reference in New Issue
Block a user