diff --git a/apps/accounts/services.py b/apps/accounts/services.py index 91509d9..2f24816 100644 --- a/apps/accounts/services.py +++ b/apps/accounts/services.py @@ -44,12 +44,19 @@ class OnboardingService: user.set_unusable_password() user.save() - # Log creation + # Log creation (only store simple data, not objects) + log_metadata = { + 'email': user.email, + 'first_name': user.first_name, + 'last_name': user.last_name, + 'hospital_id': str(user.hospital_id) if user.hospital_id else None, + 'department_id': str(user.department_id) if user.department_id else None, + } UserProvisionalLog.objects.create( user=user, event_type='created', description=f"Provisional user created", - metadata=user_data + metadata=log_metadata ) return user diff --git a/apps/accounts/ui_views.py b/apps/accounts/ui_views.py index bbe2062..db14917 100644 --- a/apps/accounts/ui_views.py +++ b/apps/accounts/ui_views.py @@ -196,6 +196,9 @@ def provisional_user_list(request): user_data = serializer.validated_data.copy() roles = request.POST.getlist('roles', []) + # Remove roles from user_data (not a User model field) + user_data.pop('roles', None) + # Create provisional user user = OnboardingService.create_provisional_user(user_data) @@ -221,14 +224,29 @@ def provisional_user_list(request): is_provisional=True ).select_related('hospital', 'department').order_by('-created_at') + # Calculate statistics + total_count = provisional_users.count() + completed_count = provisional_users.filter(acknowledgement_completed_at__isnull=False).count() + in_progress_count = total_count - completed_count + # Get available roles from .models import Role roles = Role.objects.all() + # Get hospitals and departments for the form + from apps.organizations.models import Hospital, Department + hospitals = Hospital.objects.filter(status='active').order_by('name') + departments = Department.objects.filter(status='active').order_by('name') + context = { 'page_title': 'Provisional Users', 'provisional_users': provisional_users, 'roles': roles, + 'hospitals': hospitals, + 'departments': departments, + 'total_count': total_count, + 'completed_count': completed_count, + 'in_progress_count': in_progress_count, } return render(request, 'accounts/onboarding/provisional_list.html', context) @@ -253,6 +271,12 @@ def provisional_user_progress(request, user_id): is_acknowledged=True ).select_related('checklist_item') + # Create a lookup dict: checklist_item_id -> acknowledged_at timestamp + acknowledged_timestamps = {} + for ack in acknowledged_items: + if ack.checklist_item_id: + acknowledged_timestamps[ack.checklist_item_id] = ack.acknowledged_at + # Get logs from .models import UserProvisionalLog logs = UserProvisionalLog.objects.filter( @@ -265,15 +289,25 @@ def provisional_user_progress(request, user_id): checklist_item__is_required=True ).count() progress_percentage = int((acknowledged_count / total_items) * 100) if total_items > 0 else 0 + remaining_count = total_items - acknowledged_count + + # Attach acknowledged_at timestamp to each checklist item + checklist_items_with_timestamps = [] + for item in checklist_items: + item_dict = { + 'item': item, + 'acknowledged_at': acknowledged_timestamps.get(item.id), + } + checklist_items_with_timestamps.append(item_dict) context = { 'page_title': f'Onboarding Progress - {user.email}', 'user': user, - 'checklist_items': checklist_items, - 'acknowledged_items': acknowledged_items, + 'checklist_items': checklist_items_with_timestamps, 'logs': logs, 'total_items': total_items, 'acknowledged_count': acknowledged_count, + 'remaining_count': remaining_count, 'progress_percentage': progress_percentage, } return render(request, 'accounts/onboarding/progress_detail.html', context) diff --git a/apps/accounts/urls.py b/apps/accounts/urls.py index 4db95a5..100f5e3 100644 --- a/apps/accounts/urls.py +++ b/apps/accounts/urls.py @@ -48,7 +48,7 @@ urlpatterns = [ # Provisional User Management path('onboarding/provisional/', provisional_user_list, name='provisional-user-list'), - path('onboarding/provisional//progress/', provisional_user_progress, name='provisional-user-progress'), + path('onboarding/provisional//progress/', provisional_user_progress, name='provisional-user-progress'), # Acknowledgement Management path('onboarding/content/', acknowledgement_content_list, name='acknowledgement-content-list'), diff --git a/apps/core/context_processors.py b/apps/core/context_processors.py index e5b1908..3efebe9 100644 --- a/apps/core/context_processors.py +++ b/apps/core/context_processors.py @@ -12,6 +12,7 @@ def sidebar_counts(request): - Active complaints - Pending feedback - Open PX actions + - Provisional users (PX Admin only) """ if not request.user.is_authenticated: return {} @@ -33,6 +34,12 @@ def sidebar_counts(request): action_count = PXAction.objects.filter( status__in=['open', 'in_progress'] ).count() + # Count provisional users for PX Admin + from apps.accounts.models import User + provisional_user_count = User.objects.filter( + is_provisional=True, + acknowledgement_completed=False + ).count() elif user.hospital: complaint_count = Complaint.objects.filter( hospital=user.hospital, @@ -46,13 +53,16 @@ def sidebar_counts(request): hospital=user.hospital, status__in=['open', 'in_progress'] ).count() + provisional_user_count = 0 else: complaint_count = 0 feedback_count = 0 action_count = 0 + provisional_user_count = 0 return { 'complaint_count': complaint_count, 'feedback_count': feedback_count, 'action_count': action_count, + 'provisional_user_count': provisional_user_count, } diff --git a/config/settings/base.py b/config/settings/base.py index fb88287..54588e4 100644 --- a/config/settings/base.py +++ b/config/settings/base.py @@ -154,7 +154,13 @@ LOCALE_PATHS = [ # https://docs.djangoproject.com/en/5.0/howto/static-files/ STATIC_URL = '/static/' STATIC_ROOT = BASE_DIR / 'staticfiles' -STATICFILES_DIRS = [BASE_DIR / 'static'] +STATICFILES_DIRS = [ + BASE_DIR / 'static', +] + +# Media files +MEDIA_URL = '/media/' +MEDIA_ROOT = BASE_DIR / 'media' # WhiteNoise configuration STORAGES = { @@ -166,9 +172,7 @@ STORAGES = { }, } -# Media files -MEDIA_URL = '/media/' -MEDIA_ROOT = BASE_DIR / 'media' + # Default primary key field type # https://docs.djangoproject.com/en/5.0/ref/settings/#default-auto-field diff --git a/docs/ALHAMMADI_THEME_GUIDE.md b/docs/ALHAMMADI_THEME_GUIDE.md new file mode 100644 index 0000000..70d96e7 --- /dev/null +++ b/docs/ALHAMMADI_THEME_GUIDE.md @@ -0,0 +1,314 @@ +# Al Hammadi Hospital Theme - PX360 Implementation Guide + +## Overview + +This document describes the Al Hammadi Hospital theme implementation for the PX360 Patient Experience Management System. The theme reflects the visual identity of Al Hammadi Hospital (https://alhammadi.med.sa). + +## Color Palette + +### Primary Colors + +| Color Name | Hex Code | CSS Variable | Usage | +|------------|----------|--------------|-------| +| Primary Teal | `#0097a7` | `--hh-primary` | Main brand color, buttons, links | +| Primary Dark | `#00838f` | `--hh-primary-dark` | Hover states, gradients | +| Primary Light | `#4dd0e1` | `--hh-primary-light` | Info badges, highlights | +| Primary Lighter | `#b2ebf2` | `--hh-primary-lighter` | Progress bar backgrounds | +| Primary BG | `rgba(0, 151, 167, 0.1)` | `--hh-primary-bg` | Soft backgrounds, hover states | + +### Secondary Colors + +| Color Name | Hex Code | CSS Variable | Usage | +|------------|----------|--------------|-------| +| Secondary Blue | `#1a237e` | `--hh-secondary` | Secondary buttons, accents | +| Secondary Dark | `#0d1642` | `--hh-secondary-dark` | Hover states | +| Secondary Light | `#283593` | `--hh-secondary-light` | Gradients | + +### Accent Colors + +| Color Name | Hex Code | CSS Variable | Usage | +|------------|----------|--------------|-------| +| Red Accent | `#c62828` | `--hh-accent` | Danger, alerts, logo crescent | +| Red Light | `#d32f2f` | `--hh-accent-light` | Gradients | +| Red Dark | `#b71c1c` | `--hh-accent-dark` | Hover states | + +### Semantic Colors + +| Color Name | Hex Code | CSS Variable | Usage | +|------------|----------|--------------|-------| +| Success | `#00897b` | `--hh-success` | Success states, positive indicators | +| Warning | `#f9a825` | `--hh-warning` | Warning states, caution indicators | +| Danger | `#c62828` | `--hh-danger` | Error states, critical alerts | +| Info | `#0097a7` | `--hh-info` | Information, tips | + +### Text Colors + +| Color Name | Hex Code | CSS Variable | Usage | +|------------|----------|--------------|-------| +| Dark Text | `#263238` | `--hh-text-dark` | Headings, primary text | +| Muted Text | `#607d8b` | `--hh-text-muted` | Secondary text, labels | +| Light Text | `#90a4ae` | `--hh-text-light` | Placeholder text | + +### Background Colors + +| Color Name | Hex Code | CSS Variable | Usage | +|------------|----------|--------------|-------| +| Light BG | `#f5f7fa` | `--hh-bg-light` | Page background | +| White BG | `#ffffff` | `--hh-bg-white` | Cards, panels | +| Border | `#e0e6ed` | `--hh-border` | Borders, dividers | + +## Typography + +### Font Families + +- **English**: Open Sans (Google Fonts) +- **Arabic**: Cairo (Google Fonts) + +### Font Weights + +- Light: 300 +- Regular: 400 +- Medium: 500 +- Semi-Bold: 600 +- Bold: 700 + +## Component Styling + +### Sidebar + +The sidebar uses a teal gradient background with the Al Hammadi brand colors: + +```css +background: linear-gradient(180deg, var(--hh-primary-dark) 0%, var(--hh-primary) 50%, var(--hh-primary-dark) 100%); +``` + +- Active items have a red accent border (matching the logo crescent) +- Badges use theme colors for different states + +### Cards + +Cards feature: +- No border (border: none) +- Subtle shadow (--hh-shadow-sm) +- Hover effect with increased shadow +- Teal gradient headers for primary cards + +### Buttons + +| Button Type | Background | Border | Text | +|-------------|------------|--------|------| +| Primary | Teal | Teal | White | +| Secondary | Dark Blue | Dark Blue | White | +| Danger | Red | Red | White | +| Success | Teal-Green | Teal-Green | White | +| Warning | Gold | Gold | Dark | +| Soft Primary | Light Teal BG | None | Teal | + +### Tables + +- Header: Light gray background with uppercase text +- Rows: Hover effect with light teal background +- Striped: Alternating very light teal + +### Forms + +- Focus state: Teal border with light teal shadow +- Checkboxes/Radio: Teal when checked +- Select2: Bootstrap 5 theme with teal accents + +### Modals + +- Header: Teal gradient background +- Close button: White (inverted) +- Footer: Light border + +### Alerts + +All alerts use soft backgrounds with matching text colors: +- Primary/Info: Light teal background +- Success: Light green background +- Danger: Light red background +- Warning: Light gold background + +## Utility Classes + +### Text Colors +- `.text-teal` - Primary teal +- `.text-teal-dark` - Dark teal +- `.text-red` - Red accent +- `.text-blue` - Secondary blue + +### Background Colors +- `.bg-teal` - Primary teal +- `.bg-teal-light` - Light teal (10% opacity) +- `.bg-red` - Red accent +- `.bg-blue` - Secondary blue + +### Gradients +- `.bg-gradient-teal` - Teal gradient +- `.bg-gradient-red` - Red gradient +- `.bg-gradient-blue` - Blue gradient + +### Effects +- `.hover-lift` - Lift effect on hover + +### Stat Card Icons +- `.stat-icon.bg-teal` - Teal icon background +- `.stat-icon.bg-red` - Red icon background +- `.stat-icon.bg-blue` - Blue icon background +- `.stat-icon.bg-green` - Green icon background + +### Avatars +- `.avatar-teal` - Teal avatar +- `.avatar-red` - Red avatar +- `.avatar-blue` - Blue avatar + +### Badges (Soft) +- `.badge-soft-primary` - Soft teal badge +- `.badge-soft-danger` - Soft red badge +- `.badge-soft-success` - Soft green badge +- `.badge-soft-warning` - Soft gold badge + +## RTL Support + +The theme includes full RTL (Right-to-Left) support for Arabic: + +- Sidebar moves to right side +- Border accents switch sides +- Icon margins adjust +- Timeline reverses direction +- All spacing and alignment adapts + +## Responsive Design + +### Breakpoints + +- Mobile: < 576px +- Tablet: 576px - 991px +- Desktop: ≥ 992px + +### Mobile Behavior + +- Sidebar collapses off-screen +- Topbar spans full width +- Main content removes margins +- Stat cards adjust sizing + +## Usage Examples + +### Creating a Stat Card + +```html +
+
+
+ +
+

Total Users

+

1,234

+

+ 12% from last month +

+
+
+``` + +### Creating a Teal Header Card + +```html +
+
+
Card Title
+
+
+ Content here... +
+
+``` + +### Using Soft Buttons + +```html + + + +``` + +### Using Soft Badges + +```html +Active +Overdue +Completed +Pending +``` + +## ApexCharts Theme Colors + +When using ApexCharts, use these colors for consistency: + +```javascript +const chartColors = { + primary: '#0097a7', + secondary: '#1a237e', + success: '#00897b', + danger: '#c62828', + warning: '#f9a825', + info: '#4dd0e1' +}; + +// Example chart options +const options = { + colors: [chartColors.primary, chartColors.success, chartColors.warning, chartColors.danger], + // ... other options +}; +``` + +## File Structure + +``` +templates/ +├── layouts/ +│ ├── base.html # Main template with theme CSS +│ └── partials/ +│ ├── sidebar.html # Sidebar navigation +│ ├── topbar.html # Top navigation bar +│ └── ... +docs/ +└── ALHAMMADI_THEME_GUIDE.md # This file +``` + +## Browser Support + +The theme supports: +- Chrome (latest) +- Firefox (latest) +- Safari (latest) +- Edge (latest) +- Mobile browsers (iOS Safari, Chrome for Android) + +## Maintenance + +### Updating Colors + +To update the color palette, modify the CSS variables in `:root` section of `templates/layouts/base.html`. + +### Adding New Components + +When adding new components: +1. Use existing CSS variables for colors +2. Follow the established naming conventions +3. Include RTL support +4. Test on mobile devices + +## Version History + +| Version | Date | Changes | +|---------|------|---------| +| 1.0.0 | January 2026 | Initial Al Hammadi theme implementation | + +--- + +**Theme Based On**: Al Hammadi Hospital Website (https://alhammadi.med.sa) +**Implemented For**: PX360 Patient Experience Management System +**Last Updated**: January 2026 diff --git a/static/img/2024930115554.jpg b/static/img/2024930115554.jpg new file mode 100644 index 0000000..39fbb65 Binary files /dev/null and b/static/img/2024930115554.jpg differ diff --git a/static/img/logo.png b/static/img/logo.png new file mode 100644 index 0000000..28259a0 Binary files /dev/null and b/static/img/logo.png differ diff --git a/templates/accounts/onboarding/checklist_list.html b/templates/accounts/onboarding/checklist_list.html new file mode 100644 index 0000000..1bed803 --- /dev/null +++ b/templates/accounts/onboarding/checklist_list.html @@ -0,0 +1,169 @@ +{% extends "layouts/base.html" %} +{% load i18n %} + +{% block title %}{% trans "Acknowledgement Checklist Items" %}{% endblock %} + +{% block content %} +
+ +
+
+
+
+

+ + {% trans "Checklist Items Management" %} +

+

+ {% trans "Manage acknowledgement checklist items" %} +

+
+ +
+
+
+ + +
+
+
+
+ + {% trans "Checklist Items" %} +
+
+ + +
+
+
+
+
+ + + + + + + + + + + + + + + {% for item in checklist_items %} + + + + + + + + + + + {% empty %} + + + + {% endfor %} + +
{% trans "Item Text" %}{% trans "Role" %}{% trans "Linked Content" %}{% trans "Required" %}{% trans "Order" %}{% trans "Status" %}{% trans "Created" %}{% trans "Actions" %}
+ {{ item.text_en }} + {% if item.code %} + {{ item.code }} + {% endif %} + {% if item.description_en %} +

{{ item.description_en }}

+ {% endif %} +
+ {% if item.role %} + + {{ item.get_role_display }} + + {% else %} + {% trans "All Roles" %} + {% endif %} + + {% if item.content %} + + {{ item.content.title_en }} + + {% else %} + - + {% endif %} + + {% if item.is_required %} + + + {% trans "Yes" %} + + {% else %} + {% trans "No" %} + {% endif %} + {{ item.order }} + {% if item.is_active %} + + + {% trans "Active" %} + + {% else %} + + + {% trans "Inactive" %} + + {% endif %} + + {{ item.created_at|date:"M d, Y" }} + +
+ + +
+
+ +

+ {% trans "No checklist items found" %} +

+
+
+
+
+
+ + +{% endblock %} diff --git a/templates/accounts/onboarding/content_list.html b/templates/accounts/onboarding/content_list.html new file mode 100644 index 0000000..7cde9be --- /dev/null +++ b/templates/accounts/onboarding/content_list.html @@ -0,0 +1,153 @@ +{% extends "layouts/base.html" %} +{% load i18n %} + +{% block title %}{% trans "Acknowledgement Content" %}{% endblock %} + +{% block content %} +
+ +
+
+
+
+

+ + {% trans "Acknowledgement Content Management" %} +

+

+ {% trans "Manage educational content for onboarding wizard" %} +

+
+ +
+
+
+ + +
+
+
+
+ + {% trans "Content Sections" %} +
+
+ + +
+
+
+
+
+ + + + + + + + + + + + + + {% for content in content_list %} + + + + + + + + + + {% empty %} + + + + {% endfor %} + +
{% trans "Icon" %}{% trans "Title" %}{% trans "Role" %}{% trans "Order" %}{% trans "Status" %}{% trans "Created" %}{% trans "Actions" %}
+ {% if content.icon %} + + {% else %} + + {% endif %} + + {{ content.title_en }} + {% if content.code %} + {{ content.code }} + {% endif %} + + {% if content.role %} + + {{ content.get_role_display }} + + {% else %} + {% trans "All Roles" %} + {% endif %} + {{ content.order }} + {% if content.is_active %} + + + {% trans "Active" %} + + {% else %} + + + {% trans "Inactive" %} + + {% endif %} + + {{ content.created_at|date:"M d, Y" }} + +
+ + +
+
+ +

+ {% trans "No content found" %} +

+
+
+
+
+
+ + +{% endblock %} diff --git a/templates/accounts/onboarding/progress_detail.html b/templates/accounts/onboarding/progress_detail.html new file mode 100644 index 0000000..ecf2bdd --- /dev/null +++ b/templates/accounts/onboarding/progress_detail.html @@ -0,0 +1,249 @@ +{% extends "layouts/base.html" %} +{% load i18n %} + +{% block title %}{% trans page_title %}{% endblock %} + +{% block content %} +
+ +
+
+
+
+ + + {% trans "Back to Provisional Users" %} + +

+ + {% trans "Onboarding Progress" %} +

+

{{ user.email }}

+
+
+
+
+ + +
+
+
+
+
{% trans "Overall Progress" %}
+
+
+ {% trans "Required Items" %} + {{ acknowledged_count }} / {{ total_items }} +
+
+
+ {{ progress_percentage }}% +
+
+
+ {% if progress_percentage == 100 %} +
+ + {% trans "All required acknowledgements completed!" %} +
+ {% else %} +
+ + {{ remaining_count }} {% trans "items remaining" %} +
+ {% endif %} +
+
+
+
+
+
+
{% trans "User Details" %}
+
+ {% trans "Name:" %} {{ user.get_full_name }} +
+
+ {% trans "Email:" %} {{ user.email }} +
+
+ {% trans "Hospital:" %} {{ user.hospital.name|default:"-" }} +
+
+ {% trans "Department:" %} {{ user.department.name|default:"-" }} +
+
+ {% trans "Roles:" %} + {% for group in user.groups.all %} + {{ group.name }} + {% empty %} + - + {% endfor %} +
+
+
+
+
+ + +
+
+
+
+
+ + {% trans "Acknowledgement Checklist" %} +
+
+
+
+ + + + + + + + + + + + {% for checklist_item in checklist_items %} + + + + + + + + {% empty %} + + + + {% endfor %} + +
{% trans "Status" %}{% trans "Item" %}{% trans "Role" %}{% trans "Required" %}{% trans "Acknowledged At" %}
+ {% if checklist_item.acknowledged_at %} + + {% else %} + + {% endif %} + + {{ checklist_item.item.text_en }} + {% if checklist_item.item.description_en %} +

{{ checklist_item.item.description_en }}

+ {% endif %} +
+ + {% if checklist_item.item.role %}{{ checklist_item.item.role }}{% else %}All Roles{% endif %} + + + {% if checklist_item.item.is_required %} + {% trans "Yes" %} + {% else %} + {% trans "No" %} + {% endif %} + + {% if checklist_item.acknowledged_at %} + {{ checklist_item.acknowledged_at|date:"M d, Y H:i" }} + {% else %} + - + {% endif %} +
+

+ {% trans "No checklist items found for this user's role" %} +

+
+
+
+
+
+
+ + +
+
+
+
+
+ + {% trans "Activity Log" %} +
+
+
+
+ {% for log in logs %} +
+
+
+
+ +
+
+
+
+
+
+
{{ log.get_event_type_display }}
+ {{ log.created_at|date:"M d, Y H:i" }} +
+

{{ log.description }}

+ {% if log.ip_address %} + + + {{ log.ip_address }} + + {% endif %} +
+
+
+
+
+ {% empty %} +
+ +

+ {% trans "No activity recorded yet" %} +

+
+ {% endfor %} +
+
+
+
+
+
+ + + +{% comment %} +Template filter to get event type icon +{% endcomment %} + + +{% endblock %} diff --git a/templates/accounts/onboarding/provisional_list.html b/templates/accounts/onboarding/provisional_list.html new file mode 100644 index 0000000..7c88ddb --- /dev/null +++ b/templates/accounts/onboarding/provisional_list.html @@ -0,0 +1,338 @@ +{% extends "layouts/base.html" %} +{% load i18n %} + +{% block title %}{% trans "Provisional Users" %}{% endblock %} + +{% block content %} +
+ +
+
+
+
+

+ + {% trans "Provisional Users Management" %} +

+

+ {% trans "Manage and monitor provisional user onboarding" %} +

+
+ +
+
+
+ + +
+
+
+
+
+
+ +
+
+
{% trans "Total Provisional" %}
+

{{ total_count }}

+
+
+
+
+
+
+
+
+
+
+ +
+
+
{% trans "Completed" %}
+

{{ completed_count }}

+
+
+
+
+
+
+
+
+
+
+ +
+
+
{% trans "In Progress" %}
+

{{ in_progress_count }}

+
+
+
+
+
+
+ + +
+
+
+
+ + {% trans "Provisional Users List" %} +
+
+ + +
+
+
+
+
+ + + + + + + + + + + + + + {% for user in provisional_users %} + + + + + + + + + + {% empty %} + + + + {% endfor %} + +
{% trans "User" %}{% trans "Hospital" %}{% trans "Department" %}{% trans "Roles" %}{% trans "Status" %}{% trans "Created" %}{% trans "Actions" %}
+
+
+
+ {{ user.email|first|upper }} +
+
+
+
{{ user.email }}
+ {{ user.first_name }} {{ user.last_name }} +
+
+
{{ user.hospital.name|default:"-" }}{{ user.department.name|default:"-" }} + {% for group in user.groups.all %} + {{ group.name }} + {% empty %} + - + {% endfor %} + + {% if user.acknowledgement_completed_at %} + + + {% trans "Completed" %} + + {% else %} + + + {% trans "In Progress" %} + + {% endif %} + + {{ user.created_at|date:"M d, Y" }} + + + + + + + + +
+ +

+ {% trans "No provisional users found" %} +

+
+
+
+
+
+ + + + + + + +{% endblock %} diff --git a/templates/analytics/command_center.html b/templates/analytics/command_center.html index f068f5d..52fef45 100644 --- a/templates/analytics/command_center.html +++ b/templates/analytics/command_center.html @@ -5,28 +5,37 @@ {% block extra_css %} {% endblock %} @@ -632,6 +667,9 @@ function renderChart(elementId, chartData, chartType) { charts[elementId].destroy(); } + // Al Hammadi Theme Colors for Charts + const hhChartColors = ['#0097a7', '#00897b', '#f9a825', '#c62828', '#1a237e', '#4dd0e1']; + const options = { series: chartData.series || [], chart: { @@ -639,10 +677,11 @@ function renderChart(elementId, chartData, chartType) { height: 350, toolbar: { show: true - } + }, + fontFamily: 'Open Sans, Cairo, sans-serif' }, labels: chartData.labels || [], - colors: ['#4472C4', '#4BC0C0', '#FF6384', '#36A2EB', '#FFCE56', '#9966FF'], + colors: hhChartColors, dataLabels: { enabled: chartType === 'donut' }, diff --git a/templates/layouts/base.html b/templates/layouts/base.html index e51a601..c9de3ff 100644 --- a/templates/layouts/base.html +++ b/templates/layouts/base.html @@ -5,6 +5,7 @@ + {% block title %}{% trans "PX360 - Patient Experience Management" %}{% endblock %} @@ -13,6 +14,9 @@ + + + @@ -23,37 +27,116 @@ - + diff --git a/templates/layouts/partials/sidebar.html b/templates/layouts/partials/sidebar.html index fc96c2e..d67235a 100644 --- a/templates/layouts/partials/sidebar.html +++ b/templates/layouts/partials/sidebar.html @@ -1,4 +1,4 @@ -{% load i18n %} +{% load i18n static%}