feat(resources): one tabbed page per resource
In the resource-first model a resource is the unit of capacity, so its
working hours, holidays, services, skills and categories belong to it — not
scattered across a list page's modals plus a separate calendar page.
/admin/resources/{uuid} now carries six tabs and the active tab lives in the
query string, so back and refresh land on the same view. The old
/calendar URL redirects to ?tab=hours instead of 404ing.
The skills and services modal bodies became panels the tab renders directly;
the modals are now thin wrappers, so the list page keeps working unchanged
and there is still one implementation of each editor.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
+11
-3
@@ -1,5 +1,5 @@
|
||||
import React, { useEffect } from 'react';
|
||||
import { Routes, Route, Navigate, useLocation } from 'react-router-dom';
|
||||
import { Routes, Route, Navigate, useLocation, useParams } from 'react-router-dom';
|
||||
import { useAuthStore } from './stores/authStore';
|
||||
import { usePermissions } from './hooks/usePermissions';
|
||||
import AdminLayout from './components/layout/AdminLayout';
|
||||
@@ -84,7 +84,7 @@ import ResourceTypesPage from './pages/ResourceTypesPage';
|
||||
import CatalogCategoriesPage from './pages/CatalogCategoriesPage';
|
||||
import SkillsPage from './pages/SkillsPage';
|
||||
import ResourcePoolsPage from './pages/ResourcePoolsPage';
|
||||
import ResourceCalendarPage from './pages/ResourceCalendarPage';
|
||||
import ResourceDetailPage from './pages/ResourceDetailPage';
|
||||
import HolidaysSettingsPage from './pages/HolidaysSettingsPage';
|
||||
import PatientRecordFormPage from './pages/PatientRecordFormPage';
|
||||
import PatientDetailPage from './pages/PatientDetailPage';
|
||||
@@ -132,6 +132,12 @@ function PrivateRoute({ children }: { children: React.ReactNode }) {
|
||||
return <>{children}</>;
|
||||
}
|
||||
|
||||
/** `/resources/{uuid}/calendar` قدیمی → تب «ساعات کاری» صفحهٔ منبع. */
|
||||
function ResourceCalendarRedirect() {
|
||||
const { resourceUuid } = useParams<{ resourceUuid: string }>();
|
||||
return <Navigate to={`/admin/resources/${resourceUuid}?tab=hours`} replace />;
|
||||
}
|
||||
|
||||
function PublicRoute({ children }: { children: React.ReactNode }) {
|
||||
const isAuthenticated = useAuthStore((s) => s.isAuthenticated);
|
||||
return isAuthenticated ? <Navigate to="/admin/dashboard" replace /> : <>{children}</>;
|
||||
@@ -297,7 +303,9 @@ export default function App() {
|
||||
<Route path="resources/types" element={<RoleRoute roles={['doctor', 'clinic', 'secretary']} blockClinicScope permission={['appointment_settings', 'view']}><ResourceTypesPage /></RoleRoute>} />
|
||||
<Route path="resources/skills" element={<RoleRoute roles={['doctor', 'clinic', 'secretary']} blockClinicScope permission={['appointment_settings', 'view']}><SkillsPage /></RoleRoute>} />
|
||||
<Route path="resources/pools" element={<RoleRoute roles={['doctor', 'clinic', 'secretary']} blockClinicScope permission={['appointment_settings', 'view']}><ResourcePoolsPage /></RoleRoute>} />
|
||||
<Route path="resources/:resourceUuid/calendar" element={<RoleRoute roles={['doctor', 'clinic', 'secretary']} blockClinicScope permission={['appointment_settings', 'view']}><ResourceCalendarPage /></RoleRoute>} />
|
||||
<Route path="resources/:resourceUuid" element={<RoleRoute roles={['doctor', 'clinic', 'secretary']} blockClinicScope permission={['appointment_settings', 'view']}><ResourceDetailPage /></RoleRoute>} />
|
||||
{/* تقویم منبع در تب «ساعات کاری» همان صفحه حل شده؛ لینکهای قدیمی نباید بشکنند. */}
|
||||
<Route path="resources/:resourceUuid/calendar" element={<ResourceCalendarRedirect />} />
|
||||
<Route path="holidays" element={<RoleRoute roles={['doctor', 'clinic', 'secretary']} blockClinicScope permission={['appointment_settings', 'view']}><HolidaysSettingsPage /></RoleRoute>} />
|
||||
<Route path="sms-wallet" element={<RoleRoute roles={['doctor', 'clinic', 'secretary']} blockClinicScope permission={['sms', 'view']}><SmsWalletPage /></RoleRoute>} />
|
||||
<Route path="my-secretaries" element={<RoleRoute roles={['doctor', 'clinic']} blockClinicScope><MySecretariesPage /></RoleRoute>} />
|
||||
|
||||
Reference in New Issue
Block a user