feat: add staff role functionality with dashboard access and service management
- Implemented SidebarStaff component tests to ensure staff users see only their dashboard and services. - Created StaffMyServicesPage to display assigned services for staff users. - Added migration to link clinic staff rows to user accounts for ROLE_STAFF access. - Defined StaffPermissions class for static permissions related to staff role. - Introduced StaffRouteGuardSubscriber to restrict API access for staff users. - Developed StaffAccountService for managing staff user accounts and linking them to clinic staff. - Added comprehensive tests for StaffAccountService to validate user creation, mobile number handling, and account attachment. - Implemented tests for staff dashboard access to ensure proper permissions and access control. - Created tests for staff login context to verify correct environment visibility based on user roles.
This commit is contained in:
@@ -0,0 +1,79 @@
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
import { WrenchScrewdriverIcon } from '@heroicons/react/24/outline';
|
||||
import { api } from '../lib/api';
|
||||
import type { ApiResponse } from '../lib/api';
|
||||
import type { StaffAssignedService } from '../types';
|
||||
import { formatRial } from '../lib/utils';
|
||||
import DataTable, { type Column } from '../components/ui/DataTable';
|
||||
import PageHeader from '../components/ui/PageHeader';
|
||||
|
||||
interface StaffDashboardData {
|
||||
services: StaffAssignedService[];
|
||||
}
|
||||
|
||||
const EMPTY: StaffAssignedService[] = [];
|
||||
|
||||
/**
|
||||
* سرویسهای تخصیصیافته به پرسنل — فقط خواندنی.
|
||||
* داده از همان اندپوینت داشبورد پرسنل میآید؛ نقش staff اندپوینت دیگری ندارد.
|
||||
*/
|
||||
export default function StaffMyServicesPage() {
|
||||
const { data, isLoading } = useQuery({
|
||||
queryKey: ['dashboard-staff'],
|
||||
queryFn: () => api.get<ApiResponse<StaffDashboardData>>('/api/v1/dashboard/staff'),
|
||||
staleTime: 60_000,
|
||||
});
|
||||
|
||||
const services = data?.data?.services ?? EMPTY;
|
||||
|
||||
const columns: Column<StaffAssignedService>[] = [
|
||||
{
|
||||
key: 'name',
|
||||
header: 'سرویس',
|
||||
render: (s) => (
|
||||
<div>
|
||||
<div style={{ fontWeight: 600, fontSize: 14 }}>{s.name}</div>
|
||||
<div style={{ fontSize: 12, color: 'var(--text-3)', marginTop: 2 }}>{s.section_name}</div>
|
||||
</div>
|
||||
),
|
||||
},
|
||||
{
|
||||
key: 'price_rials',
|
||||
header: 'تعرفه',
|
||||
render: (s) => <span style={{ fontSize: 13 }}>{formatRial(s.price_rials)}</span>,
|
||||
},
|
||||
{
|
||||
key: 'duration_minutes',
|
||||
header: 'مدت',
|
||||
render: (s) => (
|
||||
<span style={{ fontSize: 13, color: 'var(--text-3)' }}>
|
||||
{s.duration_minutes ? `${s.duration_minutes} دقیقه` : '—'}
|
||||
</span>
|
||||
),
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<>
|
||||
<PageHeader
|
||||
title="سرویسهای من"
|
||||
description="سرویسهایی که به شما تخصیص داده شده است"
|
||||
backTo="/admin/dashboard"
|
||||
/>
|
||||
|
||||
<div className="card">
|
||||
{services.length === 0 && !isLoading ? (
|
||||
<div style={{ textAlign: 'center', padding: '60px 24px', color: 'var(--text-3)' }}>
|
||||
<WrenchScrewdriverIcon style={{ width: 48, margin: '0 auto 16px', display: 'block', opacity: 0.4 }} />
|
||||
<div style={{ fontWeight: 600, fontSize: 15, marginBottom: 8, color: 'var(--text-2)' }}>
|
||||
هنوز سرویسی به شما تخصیص نیافته
|
||||
</div>
|
||||
<div style={{ fontSize: 13 }}>پس از تخصیص سرویس توسط مطب/کلینیک، اینجا نمایش داده میشود.</div>
|
||||
</div>
|
||||
) : (
|
||||
<DataTable columns={columns} data={services} loading={isLoading} />
|
||||
)}
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user