- Add NewAppointmentsTable for displaying today's appointments with status chips and formatted time. - Implement TauriCharts for bar and line charts representing patient counts and revenue. - Create TauriDashboardView to combine stat cards, charts, and new appointments list. - Introduce TauriStatCards for displaying key statistics with icons. - Add dashboardIcons for SVG icons used in stat cards. - Implement tests for DashboardPage to ensure correct rendering and API calls. - Create DashboardTodayAppointmentsTest to validate extended fields in today's appointments API response.
7.4 KiB
7.4 KiB
Dashboard API
Role-specific dashboard endpoints. Each endpoint requires the corresponding role JWT.
GET /api/v1/dashboard/clinic
Returns stats and today's schedule for the authenticated clinic owner.
Auth: ROLE_CLINIC required
Query params
| Param | Type | Default | Description |
|---|---|---|---|
from |
int (unix) | start of current month | Period start for patient/revenue stats |
to |
int (unix) | now | Period end for patient/revenue stats |
Response 200
{
"success": true,
"data": {
"clinic": {
"uuid": "string",
"name": "string",
"is_active": true,
"logo": "string | null"
},
"stats": {
"total_doctors": 5,
"today_appointments": 12,
"this_month_appointments": 87,
"pending_invitations": 2,
"sms_wallet_balance": 50000,
"unique_patients_count": 34,
"total_patients": 210,
"revenue_period_rials": 12500000,
"today_payments_rials": 5225000,
"week_payments_rials": 560000200
},
"charts": {
"revenue_by_day": [
{ "label": "۷ خرداد", "amount_rials": 3200000 }
],
"appointments_by_day": [
{ "label": "۷ خرداد", "count": 9 }
]
},
"period": { "from": 1717200000, "to": 1719792000 },
"today_appointments": [
{
"uuid": "string",
"patient_name": "string | null",
"patient_mobile": "string | null",
"doctor_name": "string",
"service_name": "string | null",
"slot_start": 1700000000,
"slot_end": 1700001800,
"status": "reserved"
}
],
"doctors": [
{
"uuid": "string",
"name": "string",
"today_count": 3
}
]
}
}
Field notes:
sms_wallet_balance— current SMS wallet balance in Rials (0 if wallet not yet created)unique_patients_count— distinct patients with at least one session in thefrom–toperiodtotal_patients— distinct patients ever (no period filter)revenue_period_rials— sum offinal_price_rialsfrom all patient sessions in the periodtoday_payments_rials/week_payments_rials— revenue for today / the last 7 dayscharts.revenue_by_day/charts.appointments_by_day— last 7 days series (Jalali day label); revenue drives the «میزان درآمد» area chart, appointments the «نمودار تعداد مراجعین» bar charttoday_appointments— up to 5 records, ordered byslot_start ASC; each row carriespatient_mobile,doctor_name(personnel),service_name(nullable — booked service item), andslot_endfor the «لیست نوبتهای جدید» dashboard tabledoctors— all doctors belonging to this clinic; each includes their appointment count for today
Errors
| Code | HTTP | Description |
|---|---|---|
ERR_NOT_FOUND_001 |
404 | Clinic not found for this user |
GET /api/v1/dashboard/doctor
Returns stats and today's schedule for the authenticated doctor.
Auth: ROLE_DOCTOR required
Query params
| Param | Type | Default | Description |
|---|---|---|---|
from |
int (unix) | start of current month | Period start for patient/revenue stats |
to |
int (unix) | now | Period end for patient/revenue stats |
Response 200
{
"success": true,
"data": {
"doctor": {
"uuid": "string",
"name": "string",
"degree": "string | null"
},
"stats": {
"today_appointments": 8,
"tomorrow_appointments": 5,
"this_month_appointments": 62,
"avg_rating": 4.6,
"total_ratings": 34,
"sms_wallet_balance": 25000,
"unique_patients_count": 18,
"total_patients": 140,
"revenue_period_rials": 6800000,
"today_payments_rials": 5225000,
"week_payments_rials": 42000000
},
"charts": {
"revenue_by_day": [ { "label": "۷ خرداد", "amount_rials": 3200000 } ],
"appointments_by_day": [ { "label": "۷ خرداد", "count": 4 } ]
},
"period": { "from": 1717200000, "to": 1719792000 },
"today_appointments": [
{
"uuid": "string",
"patient_name": "string | null",
"patient_mobile": "string",
"doctor_name": "string",
"service_name": "string | null",
"slot_start": 1700000000,
"slot_end": 1700001800,
"status": "reserved"
}
],
"clinics": [
{
"uuid": "string",
"name": "string",
"logo": "string | null"
}
]
}
}
Field notes:
today_appointments— up to 10 records, ordered byslot_start ASC; each row carriespatient_mobile,doctor_name,service_name(nullable), andslot_endfor the dashboard appointments tableavg_rating— rounded to 1 decimal;nullif no ratings yetclinics— all clinics the doctor belongs tosms_wallet_balance,unique_patients_count,revenue_period_rials— same semantics as clinic dashboard
Errors
| Code | HTTP | Description |
|---|---|---|
ERR_NOT_FOUND_001 |
404 | Doctor profile not found for this user |
GET /api/v1/dashboard/secretary
Returns stats for the authenticated secretary and (conditionally) today's appointments.
Auth: ROLE_SECRETARY required
Response 200
{
"success": true,
"data": {
"doctor": {
"uuid": "string",
"name": "string",
"degree": "string | null"
},
"permissions": {
"resources": {
"appointments": {
"view": true,
"edit": false
}
}
},
"stats": {
"today_appointments": 8,
"tomorrow_appointments": 5
},
"today_appointments": [
{
"uuid": "string",
"patient_name": "string | null",
"patient_mobile": "string",
"slot_start": 1700000000,
"status": "reserved"
}
]
}
}
today_appointments — only populated when permissions.resources.appointments.view === true; up to 10 records when visible.
Errors
| Code | HTTP | Description |
|---|---|---|
ERR_FORBIDDEN_001 |
403 | Secretary relation not configured or inactive |
GET /api/v1/admin/dashboard/charts
Returns time-series chart data for admin dashboard. All series are filtered to the given from–to window.
Auth: ROLE_ADMIN required
Query params
| Param | Type | Default | Description |
|---|---|---|---|
from |
int (unix) | 30 days ago | Period start |
to |
int (unix) | now | Period end |
Response 200
{
"success": true,
"data": {
"appointments_by_day": [
{ "date": "06/01", "count": 12 }
],
"revenue_by_day": [
{ "date": "06/01", "amount": 3500000 }
],
"appointment_status": [
{ "status": "confirmed", "count": 320 }
],
"top_specialties": [
{ "name": "قلب و عروق", "count": 85 }
],
"subscription_sales_by_plan": [
{ "plan": "basic", "count": 14, "revenue": 4060000 }
],
"period": { "from": 1717200000, "to": 1719792000 }
}
}
Field notes:
appointments_by_day/revenue_by_day— one entry per calendar day in the period; days with no data appear ascount: 0/amount: 0appointment_status— all-time counts, not filtered by periodtop_specialties— top 8 by appointment volume, all-timesubscription_sales_by_plan— subscriptions created in period, grouped by plan;revenuesums only payments with statusreceived