feat: Implement Jalali calendar support for dashboard charts

- Added support for Jalali calendar in the dashboard, allowing charts to display data based on the current Jalali month and year.
- Updated the API to return `patients_year`, `patients_month`, and `revenue_year` parameters for the dashboard charts.
- Refactored the dashboard controller to handle Jalali date calculations and queries.
- Modified the frontend components to utilize the new Jalali date parameters and reflect changes in the UI.
- Removed the status column from the NewAppointmentsTable as status management is now handled on the appointments page.
- Added tests to ensure the correct functioning of the new Jalali chart period features.
This commit is contained in:
hamed
2026-07-18 21:44:01 +03:30
parent 7921407f33
commit 62a9fd87c3
7 changed files with 479 additions and 100 deletions
+36 -4
View File
@@ -10,6 +10,10 @@ vi.mock('../lib/api', () => ({
import { api } from '../lib/api';
import { useAuthStore } from '../stores/authStore';
import DashboardPage from './DashboardPage';
import { JALALI_MONTHS } from '../components/dashboard/TauriDashboardView';
// eslint-disable-next-line @typescript-eslint/no-var-requires
const jalaali = require('jalaali-js') as { toJalaali: (d: Date) => { jy: number; jm: number } };
const get = api.get as ReturnType<typeof vi.fn>;
@@ -33,12 +37,18 @@ const clinicPayload = {
{ label: '۸ خرداد', amount_rials: 160_000 },
{ label: '۹ خرداد', amount_rials: 90_000 },
],
revenue_by_month: [
{ label: 'فروردین', amount_rials: 60_000 },
{ label: 'اردیبهشت', amount_rials: 160_000 },
{ label: 'خرداد', amount_rials: 90_000 },
],
appointments_by_day: [
{ label: '۷ خرداد', count: 15 },
{ label: '۸ خرداد', count: 40 },
{ label: '۹ خرداد', count: 48 },
{ label: '۱', count: 15 },
{ label: '۲', count: 40 },
{ label: '۳', count: 48 },
],
},
charts_period: { patients_year: 1405, patients_month: 4, revenue_year: 1405 },
today_appointments: [
{
uuid: 'appt-1',
@@ -84,7 +94,10 @@ describe('DashboardPage (ported clinic dashboard)', () => {
expect(screen.getByText('دنیا خلیلی')).toBeInTheDocument();
expect(screen.getByText('09136549874')).toBeInTheDocument();
expect(screen.getByText('ویزیت عمومی')).toBeInTheDocument();
expect(screen.getByText('ویزیت شده')).toBeInTheDocument();
// ستون «وضعیت» از داشبورد حذف شده — تغییر وضعیت فقط در صفحه نوبت‌هاست
expect(screen.queryByText('وضعیت')).not.toBeInTheDocument();
expect(screen.queryByText('ویزیت شده')).not.toBeInTheDocument();
});
it('calls the real clinic dashboard endpoint', async () => {
@@ -92,4 +105,23 @@ describe('DashboardPage (ported clinic dashboard)', () => {
await screen.findByText('تعداد کل مراجعین');
expect(get).toHaveBeenCalledWith(expect.stringContaining('/api/v1/dashboard/clinic'));
});
it('نمودارها را روی ماه و سال شمسی جاری درخواست می‌کند', async () => {
renderWithProviders(<DashboardPage />, { route: '/admin/dashboard' });
await screen.findByText('تعداد کل مراجعین');
const url = get.mock.calls.map(c => String(c[0])).find(u => u.startsWith('/api/v1/dashboard/clinic'))!;
const params = new URLSearchParams(url.split('?')[1]);
const now = jalaali.toJalaali(new Date());
expect(params.get('patients_year')).toBe(String(now.jy));
expect(params.get('patients_month')).toBe(String(now.jm));
expect(params.get('revenue_year')).toBe(String(now.jy));
// سلکتورها همان دوره را نشان می‌دهند
expect(screen.getByText(JALALI_MONTHS[now.jm - 1])).toBeInTheDocument();
expect(
screen.getByText(`سال ${new Intl.NumberFormat('fa-IR', { useGrouping: false }).format(now.jy)}`)
).toBeInTheDocument();
});
});