668 lines
16 KiB
Markdown
668 lines
16 KiB
Markdown
# Admin Dashboard Implementation - Complete Guide
|
|
|
|
## Overview
|
|
|
|
This document provides a comprehensive guide to the enhanced admin dashboard implementation for the AgdarCentre Multidisciplinary Healthcare Platform.
|
|
|
|
## Implementation Summary
|
|
|
|
### Date: October 28, 2025
|
|
### Status: ✅ Phases 1 & 2 Complete
|
|
### Files Modified:
|
|
- `core/views.py` - Backend statistics and analytics methods
|
|
- `core/templates/core/partials/dashboard_admin.html` - Frontend dashboard template
|
|
|
|
---
|
|
|
|
## Backend Implementation (core/views.py)
|
|
|
|
### 1. Enhanced `_get_admin_widgets()` Method
|
|
|
|
**Purpose**: Main method that aggregates all dashboard statistics for admin users.
|
|
|
|
**Returns**:
|
|
```python
|
|
{
|
|
'todays_appointments': QuerySet, # Today's appointments (limited to 10)
|
|
'recent_patients': QuerySet, # Recent patients (limited to 10)
|
|
'appointment_stats': dict, # Appointment status breakdown
|
|
'financial_summary': dict, # Financial metrics
|
|
'hr_summary': dict, # HR metrics
|
|
'clinical_summary': dict, # Clinical documents summary
|
|
'system_health': dict, # System health indicators
|
|
'quick_stats': dict, # Quick overview statistics
|
|
}
|
|
```
|
|
|
|
**Key Features**:
|
|
- Efficient database queries with `select_related()` and `prefetch_related()`
|
|
- Aggregated statistics across all system modules
|
|
- Real-time data calculation
|
|
- Tenant-filtered data
|
|
|
|
### 2. Analytics Helper Methods
|
|
|
|
#### `_get_clinical_summary(tenant, today)`
|
|
|
|
**Purpose**: Aggregates clinical documents across all disciplines.
|
|
|
|
**Returns**:
|
|
```python
|
|
{
|
|
'total_documents': int,
|
|
'nursing_count': int,
|
|
'medical_count': int,
|
|
'aba_count': int,
|
|
'ot_count': int,
|
|
'slp_count': int,
|
|
'unsigned_count': int,
|
|
}
|
|
```
|
|
|
|
**Disciplines Tracked**:
|
|
- Medical (Consultations + Follow-ups)
|
|
- Nursing (Encounters)
|
|
- ABA (Consultations)
|
|
- OT (Consultations + Sessions)
|
|
- SLP (Consultations + Assessments + Interventions)
|
|
|
|
#### `_get_system_health(tenant)`
|
|
|
|
**Purpose**: Monitors system health and compliance status.
|
|
|
|
**Returns**:
|
|
```python
|
|
{
|
|
'zatca_compliant': bool,
|
|
'csid_status': str, # 'active', 'needs_renewal', 'expiring_soon', 'expired', 'none'
|
|
'csid_expiry_days': int,
|
|
'alerts': [
|
|
{
|
|
'level': str, # 'danger', 'warning', 'info'
|
|
'message': str
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
**Alert Levels**:
|
|
- **Critical (danger)**: CSID expired or expiring within 7 days
|
|
- **Warning**: CSID expiring within 30 days
|
|
- **Info**: General system notifications
|
|
|
|
#### `_get_revenue_trends(tenant, today)`
|
|
|
|
**Purpose**: Calculates revenue trends for visualization.
|
|
|
|
**Returns**:
|
|
```python
|
|
{
|
|
'daily': [
|
|
{'date': date, 'revenue': float}, # Last 7 days
|
|
...
|
|
],
|
|
'monthly': [
|
|
{'month': str, 'revenue': float}, # Last 12 months
|
|
...
|
|
]
|
|
}
|
|
```
|
|
|
|
**Use Case**: Ready for Chart.js integration in Phase 3.
|
|
|
|
#### `_get_patient_analytics(tenant, today)`
|
|
|
|
**Purpose**: Provides patient demographics and growth analytics.
|
|
|
|
**Returns**:
|
|
```python
|
|
{
|
|
'growth': [
|
|
{'month': str, 'count': int}, # Last 12 months
|
|
...
|
|
],
|
|
'gender': {
|
|
'male': int,
|
|
'female': int,
|
|
'male_percent': float,
|
|
'female_percent': float
|
|
},
|
|
'age_groups': {
|
|
'0-5': int,
|
|
'6-12': int,
|
|
'13-18': int,
|
|
'19-30': int,
|
|
'31-50': int,
|
|
'51+': int
|
|
},
|
|
'total': int
|
|
}
|
|
```
|
|
|
|
#### `_get_appointment_analytics(tenant, today)`
|
|
|
|
**Purpose**: Detailed appointment performance metrics.
|
|
|
|
**Returns**:
|
|
```python
|
|
{
|
|
'completion_rate': float, # Percentage
|
|
'no_show_rate': float, # Percentage
|
|
'cancellation_rate': float, # Percentage
|
|
'by_clinic': [
|
|
{'clinic': str, 'count': int},
|
|
...
|
|
],
|
|
'provider_workload': [
|
|
{'provider': str, 'total': int, 'completed': int},
|
|
...
|
|
],
|
|
'total_month': int,
|
|
'completed_month': int,
|
|
'no_shows_month': int,
|
|
'cancelled_month': int
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Frontend Implementation (dashboard_admin.html)
|
|
|
|
### Layout Structure
|
|
|
|
```
|
|
┌─────────────────────────────────────────────────────────────┐
|
|
│ Top Statistics Cards (4) │
|
|
│ [Patients] [Appointments] [Revenue] [Staff] │
|
|
└─────────────────────────────────────────────────────────────┘
|
|
┌─────────────────────────────────────────────────────────────┐
|
|
│ Secondary Statistics Row (4) │
|
|
│ [Appt Status] [Financial] [Clinical] [System Health] │
|
|
└─────────────────────────────────────────────────────────────┘
|
|
┌─────────────────────────────────────────────────────────────┐
|
|
│ System Alerts │
|
|
│ [Critical] [Warning] [Info] alerts displayed here │
|
|
└─────────────────────────────────────────────────────────────┘
|
|
┌─────────────────────────────────────────────────────────────┐
|
|
│ Today's Appointments (8 cols) │ Quick Actions (4 cols) │
|
|
│ [Table with appointments] │ [Action buttons] │
|
|
│ │ [Recent patients] │
|
|
└─────────────────────────────────────────────────────────────┘
|
|
```
|
|
|
|
### Component Breakdown
|
|
|
|
#### 1. Top Statistics Cards
|
|
|
|
**Patients Card**
|
|
- Total patients count
|
|
- New patients this month (with up arrow)
|
|
- Primary color theme
|
|
|
|
**Appointments Card**
|
|
- Today's appointments count
|
|
- This week's appointments count
|
|
- Info color theme
|
|
|
|
**Revenue Card**
|
|
- Today's revenue
|
|
- This month's revenue
|
|
- Success color theme (green)
|
|
|
|
**Staff Card**
|
|
- Total active staff
|
|
- Present today count
|
|
- On leave today count
|
|
- Warning color theme (yellow)
|
|
|
|
#### 2. Secondary Statistics Cards
|
|
|
|
**Appointment Status Breakdown**
|
|
- Completed (green progress bar)
|
|
- In Progress (blue progress bar)
|
|
- Confirmed (info progress bar)
|
|
- Pending (warning progress bar)
|
|
- Each with count badge and percentage bar
|
|
|
|
**Financial Summary**
|
|
- Pending invoices (count + amount)
|
|
- Overdue invoices (count + amount in red)
|
|
- Month revenue (in green)
|
|
|
|
**Clinical Documents**
|
|
- Medical (primary badge)
|
|
- Nursing (info badge)
|
|
- ABA (success badge)
|
|
- OT (warning badge)
|
|
- SLP (secondary badge)
|
|
- Unsigned documents alert (if any)
|
|
|
|
**System Health**
|
|
- ZATCA compliance status badge
|
|
- CSID status badge with expiry countdown
|
|
- HR alerts count
|
|
|
|
#### 3. Alert System
|
|
|
|
**Alert Types**:
|
|
```html
|
|
<!-- Critical Alert -->
|
|
<div class="alert alert-danger alert-dismissible fade show">
|
|
<i class="fas fa-exclamation-circle"></i> Message
|
|
</div>
|
|
|
|
<!-- Warning Alert -->
|
|
<div class="alert alert-warning alert-dismissible fade show">
|
|
<i class="fas fa-exclamation-triangle"></i> Message
|
|
</div>
|
|
|
|
<!-- Info Alert -->
|
|
<div class="alert alert-info alert-dismissible fade show">
|
|
<i class="fas fa-info-circle"></i> Message
|
|
</div>
|
|
```
|
|
|
|
**Triggers**:
|
|
- CSID expiry warnings
|
|
- Overdue invoices
|
|
- Pending invoices
|
|
- Pending leave requests
|
|
|
|
#### 4. Appointments Table
|
|
|
|
**Columns**:
|
|
- Time (HH:MM format)
|
|
- Patient (name + MRN)
|
|
- Clinic (specialty)
|
|
- Provider (full name)
|
|
- Status (color-coded badge)
|
|
- Actions (view button)
|
|
|
|
**Features**:
|
|
- Responsive table
|
|
- Hover effects
|
|
- Empty state message
|
|
- Link to full appointments list
|
|
|
|
#### 5. Quick Actions & Recent Patients
|
|
|
|
**Quick Actions**:
|
|
- New Patient (primary button)
|
|
- New Appointment (info button)
|
|
- New Invoice (success button)
|
|
- Search Patients (outline button)
|
|
|
|
**Recent Patients**:
|
|
- Patient name
|
|
- MRN
|
|
- Time since registration
|
|
- Link to patient detail
|
|
|
|
---
|
|
|
|
## Color Coding System
|
|
|
|
### Status Colors
|
|
```css
|
|
.bg-primary /* Blue - General/Patients */
|
|
.bg-info /* Light Blue - Appointments */
|
|
.bg-success /* Green - Revenue/Completed */
|
|
.bg-warning /* Yellow - Staff/Pending */
|
|
.bg-danger /* Red - Overdue/Critical */
|
|
.bg-secondary /* Gray - Other */
|
|
```
|
|
|
|
### Appointment Status Colors
|
|
```python
|
|
'BOOKED': 'theme',
|
|
'CONFIRMED': 'blue',
|
|
'RESCHEDULED': 'warning',
|
|
'CANCELLED': 'info',
|
|
'NO_SHOW': 'secondary',
|
|
'ARRIVED': 'green',
|
|
'IN_PROGRESS': 'orange',
|
|
'COMPLETED': 'lightgreen',
|
|
```
|
|
|
|
---
|
|
|
|
## Data Flow
|
|
|
|
```
|
|
User Request
|
|
↓
|
|
DashboardView.get_context_data()
|
|
↓
|
|
_get_admin_widgets()
|
|
├→ Query Appointments
|
|
├→ Query Patients
|
|
├→ Query Financial Data
|
|
├→ Query HR Data
|
|
├→ _get_clinical_summary()
|
|
├→ _get_system_health()
|
|
└→ Aggregate Statistics
|
|
↓
|
|
Context Data
|
|
↓
|
|
dashboard_admin.html Template
|
|
↓
|
|
Rendered Dashboard
|
|
```
|
|
|
|
---
|
|
|
|
## Performance Considerations
|
|
|
|
### Database Query Optimization
|
|
|
|
1. **Use select_related() for ForeignKey**:
|
|
```python
|
|
todays_appointments = Appointment.objects.filter(
|
|
tenant=tenant,
|
|
scheduled_date=today
|
|
).select_related('patient', 'provider', 'clinic')
|
|
```
|
|
|
|
2. **Use prefetch_related() for ManyToMany**:
|
|
```python
|
|
files = File.objects.filter(
|
|
patient=patient
|
|
).prefetch_related('subfiles')
|
|
```
|
|
|
|
3. **Use aggregate() for calculations**:
|
|
```python
|
|
revenue = Payment.objects.filter(
|
|
invoice__tenant=tenant,
|
|
payment_date__date=today,
|
|
status=Payment.Status.COMPLETED
|
|
).aggregate(total=Sum('amount'))['total'] or 0
|
|
```
|
|
|
|
4. **Limit QuerySets**:
|
|
```python
|
|
recent_patients = Patient.objects.filter(
|
|
tenant=tenant
|
|
).order_by('-created_at')[:10] # Only fetch 10
|
|
```
|
|
|
|
### Caching Strategy (Future Enhancement)
|
|
|
|
```python
|
|
from django.core.cache import cache
|
|
|
|
def _get_admin_widgets(self):
|
|
cache_key = f'admin_dashboard_{self.request.user.tenant.id}'
|
|
cached_data = cache.get(cache_key)
|
|
|
|
if cached_data:
|
|
return cached_data
|
|
|
|
# Calculate statistics...
|
|
data = {...}
|
|
|
|
# Cache for 5 minutes
|
|
cache.set(cache_key, data, 300)
|
|
return data
|
|
```
|
|
|
|
---
|
|
|
|
## Internationalization (i18n)
|
|
|
|
All text is wrapped in translation tags:
|
|
|
|
```django
|
|
{% trans "Total Patients" %}
|
|
{% trans "Today's Appointments" %}
|
|
{% trans "Revenue" %}
|
|
```
|
|
|
|
**Translation Files**:
|
|
- `locale/ar/LC_MESSAGES/django.po` - Arabic translations
|
|
- `locale/en/LC_MESSAGES/django.po` - English translations
|
|
|
|
---
|
|
|
|
## Responsive Design
|
|
|
|
### Breakpoints
|
|
|
|
```css
|
|
/* Extra Large (Desktop) */
|
|
.col-xl-3 /* 4 cards per row */
|
|
|
|
/* Medium (Tablet) */
|
|
.col-md-6 /* 2 cards per row */
|
|
|
|
/* Small (Mobile) */
|
|
.col-12 /* 1 card per row (default) */
|
|
```
|
|
|
|
### Mobile Optimizations
|
|
|
|
- Stack cards vertically on mobile
|
|
- Responsive tables with horizontal scroll
|
|
- Touch-friendly buttons
|
|
- Optimized font sizes
|
|
|
|
---
|
|
|
|
## Future Enhancements (Phases 3-5)
|
|
|
|
### Phase 3: Advanced Visualizations
|
|
|
|
**Chart.js Integration**:
|
|
```javascript
|
|
// Revenue Trend Chart
|
|
const revenueChart = new Chart(ctx, {
|
|
type: 'line',
|
|
data: {
|
|
labels: {{ revenue_trends.daily|safe }},
|
|
datasets: [{
|
|
label: 'Daily Revenue',
|
|
data: {{ revenue_trends.daily|safe }}
|
|
}]
|
|
}
|
|
});
|
|
|
|
// Patient Demographics Chart
|
|
const demographicsChart = new Chart(ctx, {
|
|
type: 'pie',
|
|
data: {
|
|
labels: ['Male', 'Female'],
|
|
datasets: [{
|
|
data: [
|
|
{{ patient_analytics.gender.male }},
|
|
{{ patient_analytics.gender.female }}
|
|
]
|
|
}]
|
|
}
|
|
});
|
|
```
|
|
|
|
### Phase 4: Real-Time Updates
|
|
|
|
**HTMX Integration**:
|
|
```html
|
|
<div hx-get="{% url 'dashboard_stats' %}"
|
|
hx-trigger="every 30s"
|
|
hx-swap="innerHTML">
|
|
<!-- Stats will auto-refresh every 30 seconds -->
|
|
</div>
|
|
```
|
|
|
|
### Phase 5: Customization
|
|
|
|
**User Preferences**:
|
|
- Drag-and-drop widget arrangement
|
|
- Show/hide specific widgets
|
|
- Custom date ranges
|
|
- Export to PDF/Excel
|
|
- Save dashboard layouts per user
|
|
|
|
---
|
|
|
|
## Testing Checklist
|
|
|
|
### Unit Tests
|
|
- [ ] Test `_get_admin_widgets()` with various data scenarios
|
|
- [ ] Test `_get_clinical_summary()` with different disciplines
|
|
- [ ] Test `_get_system_health()` with different CSID states
|
|
- [ ] Test `_get_revenue_trends()` date calculations
|
|
- [ ] Test `_get_patient_analytics()` age grouping
|
|
- [ ] Test `_get_appointment_analytics()` percentage calculations
|
|
|
|
### Integration Tests
|
|
- [ ] Test dashboard loads for admin users
|
|
- [ ] Test dashboard loads for front desk users
|
|
- [ ] Test with empty database
|
|
- [ ] Test with large datasets (performance)
|
|
- [ ] Test with different tenant configurations
|
|
|
|
### UI/UX Tests
|
|
- [ ] Test responsive design on mobile
|
|
- [ ] Test responsive design on tablet
|
|
- [ ] Test responsive design on desktop
|
|
- [ ] Test color contrast for accessibility
|
|
- [ ] Test with screen readers
|
|
- [ ] Test alert dismissal
|
|
- [ ] Test all links and buttons
|
|
|
|
---
|
|
|
|
## Troubleshooting
|
|
|
|
### Common Issues
|
|
|
|
**Issue**: Dashboard loads slowly
|
|
**Solution**:
|
|
- Check database indexes
|
|
- Implement caching
|
|
- Optimize queries with select_related/prefetch_related
|
|
|
|
**Issue**: Statistics show incorrect data
|
|
**Solution**:
|
|
- Verify tenant filtering
|
|
- Check date range calculations
|
|
- Verify status field values
|
|
|
|
**Issue**: Alerts not showing
|
|
**Solution**:
|
|
- Check CSID exists in database
|
|
- Verify alert conditions in `_get_system_health()`
|
|
- Check template conditional logic
|
|
|
|
---
|
|
|
|
## Maintenance
|
|
|
|
### Regular Tasks
|
|
|
|
**Daily**:
|
|
- Monitor dashboard load times
|
|
- Check for error logs
|
|
|
|
**Weekly**:
|
|
- Review alert accuracy
|
|
- Verify statistics calculations
|
|
|
|
**Monthly**:
|
|
- Update documentation
|
|
- Review and optimize queries
|
|
- Check for new requirements
|
|
|
|
---
|
|
|
|
## API Reference
|
|
|
|
### Context Variables Available in Template
|
|
|
|
```python
|
|
{
|
|
# Quick Stats
|
|
'quick_stats': {
|
|
'total_patients': int,
|
|
'new_patients_month': int,
|
|
'total_appointments_today': int,
|
|
'total_appointments_week': int,
|
|
'active_providers': int,
|
|
},
|
|
|
|
# Appointment Stats
|
|
'appointment_stats': {
|
|
'total_today': int,
|
|
'booked': int,
|
|
'confirmed': int,
|
|
'arrived': int,
|
|
'in_progress': int,
|
|
'completed': int,
|
|
'cancelled': int,
|
|
'no_show': int,
|
|
},
|
|
|
|
# Financial Summary
|
|
'financial_summary': {
|
|
'pending_invoices_count': int,
|
|
'pending_amount': Decimal,
|
|
'overdue_count': int,
|
|
'overdue_amount': Decimal,
|
|
'revenue_today': Decimal,
|
|
'revenue_month': Decimal,
|
|
},
|
|
|
|
# HR Summary
|
|
'hr_summary': {
|
|
'total_staff': int,
|
|
'present_today': int,
|
|
'late_today': int,
|
|
'absent_today': int,
|
|
'on_leave_today': int,
|
|
'pending_leave_requests': int,
|
|
},
|
|
|
|
# Clinical Summary
|
|
'clinical_summary': {
|
|
'total_documents': int,
|
|
'nursing_count': int,
|
|
'medical_count': int,
|
|
'aba_count': int,
|
|
'ot_count': int,
|
|
'slp_count': int,
|
|
'unsigned_count': int,
|
|
},
|
|
|
|
# System Health
|
|
'system_health': {
|
|
'zatca_compliant': bool,
|
|
'csid_status': str,
|
|
'csid_expiry_days': int,
|
|
'alerts': list,
|
|
},
|
|
|
|
# Data Lists
|
|
'todays_appointments': QuerySet,
|
|
'recent_patients': QuerySet,
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Conclusion
|
|
|
|
The enhanced admin dashboard provides a comprehensive, real-time view of all critical aspects of the AgdarCentre healthcare system. It enables administrators to:
|
|
|
|
✅ Monitor daily operations at a glance
|
|
✅ Identify issues proactively
|
|
✅ Track key performance indicators
|
|
✅ Ensure system compliance
|
|
✅ Make data-driven decisions
|
|
|
|
The modular architecture allows for easy extension and customization to meet evolving business needs.
|
|
|
|
---
|
|
|
|
**Last Updated**: October 28, 2025
|
|
**Version**: 2.0
|
|
**Author**: Development Team
|