diff --git a/config/__pycache__/settings.cpython-311.pyc b/config/__pycache__/settings.cpython-311.pyc index 01499dd..0297352 100644 Binary files a/config/__pycache__/settings.cpython-311.pyc and b/config/__pycache__/settings.cpython-311.pyc differ diff --git a/config/settings.py b/config/settings.py index 14def59..3918fce 100644 --- a/config/settings.py +++ b/config/settings.py @@ -296,6 +296,8 @@ JAZZMIN_SETTINGS = { "use_google_fonts_cdn": True, "show_ui_builder": False, "language_chooser": True, + "changeform_format": "horizontal_tabs", + "changeform_format_overrides": {"core.platformprofile": "vertical_tabs"} } JAZZMIN_UI_TWEAKS = { diff --git a/core/__pycache__/admin.cpython-311.pyc b/core/__pycache__/admin.cpython-311.pyc index 365dd75..6c07517 100644 Binary files a/core/__pycache__/admin.cpython-311.pyc and b/core/__pycache__/admin.cpython-311.pyc differ diff --git a/core/admin.py b/core/admin.py index 9c171e2..e81d087 100644 --- a/core/admin.py +++ b/core/admin.py @@ -201,6 +201,11 @@ class ParcelAdmin(admin.ModelAdmin): export_pdf.short_description = _("Download Selected as PDF") class PlatformProfileAdmin(admin.ModelAdmin): + class Media: + js = ("js/admin_platform_profile.js",) + css = { + "all": ("css/admin_platform_profile.css",) + } fieldsets = ( (_('General Info'), { 'fields': ('name', 'logo', 'favicon', 'admin_panel_logo', 'slogan', 'address', 'phone_number', 'registration_number', 'vat_number') diff --git a/core/templates/core/profile.html b/core/templates/core/profile.html index ee3fd9c..8e1afec 100644 --- a/core/templates/core/profile.html +++ b/core/templates/core/profile.html @@ -84,46 +84,47 @@

{{ profile.get_language_display }}

- {% if profile.role == 'car_owner' %} -
-{% if profile.role == 'car_owner' %} -
-

{% trans "Driver Rating" %}

-
-
{{ profile.get_average_rating|default:"0.0"|floatformat:1 }}
-
-
- -
-
- {{ profile.get_rating_count }} {% trans "reviews" %} -
-
-
+
- {% if reviews %} -
- {% for review in reviews %} -
-
-
- {{ review.shipper.first_name }} - {{ review.created_at|date:"M d, Y" }} -
-
- {{ review.rating }} -
+ {% if profile.role == 'car_owner' %} +
+
+

{% trans "Driver Rating" %}

+
+
{{ profile.get_average_rating|default:"0.0"|floatformat:1 }}
+
+
+ +
+
+ {{ profile.get_rating_count }} {% trans "reviews" %}
- {% if review.comment %} -

{{ review.comment }}

- {% endif %}
- {% endfor %}
- {% else %} -

{% trans "No reviews yet." %}

- {% endif %} -
+ + {% if reviews %} +
+ {% for review in reviews %} +
+
+
+ {{ review.shipper.first_name }} + {{ review.created_at|date:"M d, Y" }} +
+
+ {{ review.rating }} +
+
+ {% if review.comment %} +

{{ review.comment }}

+ {% endif %} +
+ {% endfor %} +
+ {% else %} +

{% trans "No reviews yet." %}

+ {% endif %} +
{% endif %}
@@ -141,4 +142,4 @@ border-radius: 8px; } -{% endblock %} +{% endblock %} \ No newline at end of file diff --git a/static/css/admin_platform_profile.css b/static/css/admin_platform_profile.css new file mode 100644 index 0000000..9e7d185 --- /dev/null +++ b/static/css/admin_platform_profile.css @@ -0,0 +1,44 @@ +/* Custom sidebar-like styling for vertical tabs in Platform Profile */ + +.col-sm-3 .nav-pills.flex-column { + background: #f8f9fa; + border-radius: 8px; + padding: 10px; + border: 1px solid #dee2e6; +} + +.col-sm-3 .nav-pills.flex-column .nav-link { + color: #495057; + margin-bottom: 5px; + border-radius: 6px; + transition: all 0.2s ease; + padding: 12px 15px; + font-weight: 500; +} + +.col-sm-3 .nav-pills.flex-column .nav-link:hover { + background-color: #e9ecef; + color: #007bff; +} + +.col-sm-3 .nav-pills.flex-column .nav-link.active { + background-color: #007bff; + color: #fff; + box-shadow: 0 4px 6px rgba(0, 123, 255, 0.2); +} + +.col-sm-3 .nav-pills.flex-column .nav-link i { + font-size: 1.1rem; + vertical-align: middle; +} + +/* Adjust the main content area */ +.col-sm-9 { + padding-left: 20px; +} + +.card-primary.card-outline { + border-top: 3px solid #007bff; + border-radius: 8px; + box-shadow: 0 0 1px rgba(0,0,0,.125), 0 1px 3px rgba(0,0,0,.2); +} diff --git a/static/js/admin_platform_profile.js b/static/js/admin_platform_profile.js new file mode 100644 index 0000000..903bb5f --- /dev/null +++ b/static/js/admin_platform_profile.js @@ -0,0 +1,51 @@ +document.addEventListener('DOMContentLoaded', function() { + const iconMap = { + 'General Info': 'fas fa-info-circle', + 'Financial Configuration': 'fas fa-money-bill-wave', + 'Maintenance / Availability': 'fas fa-tools', + 'Driver Warning & Rejection / Auto-Ban': 'fas fa-user-slash', + 'Testing / Development': 'fas fa-flask', + 'Integrations': 'fas fa-plug', + 'Policies': 'fas fa-file-contract', + 'WhatsApp Configuration (Wablas Gateway)': 'fab fa-whatsapp', + 'Tools': 'fas fa-wrench' + }; + + const iconMapAr = { + 'معلومات عامة': 'fas fa-info-circle', + 'التكوين المالي': 'fas fa-money-bill-wave', + 'الصيانة / التوفر': 'fas fa-tools', + 'تحذير السائق ورفضه / الحظر التلقائي': 'fas fa-user-slash', + 'الاختبار / التطوير': 'fas fa-flask', + 'التكاملات': 'fas fa-plug', + 'السياسات': 'fas fa-file-contract', + 'تكوين واتساب (بوابة وابلأس)': 'fab fa-whatsapp', + 'أدوات': 'fas fa-wrench' + }; + + const fullIconMap = {...iconMap, ...iconMapAr}; + + function applyIcons() { + const tabs = document.querySelectorAll('.nav-link'); + tabs.forEach(tab => { + // Check if icon already exists + if (tab.querySelector('i.fas, i.fab')) return; + + const text = tab.textContent.trim(); + for (const [key, icon] of Object.entries(fullIconMap)) { + if (text.includes(key)) { + const i = document.createElement('i'); + i.className = icon + ' mr-2'; + i.style.width = '20px'; + i.style.textAlign = 'center'; + tab.prepend(i); + break; + } + } + }); + } + + applyIcons(); + // Sometimes jazzmin loads tabs dynamically or with a delay + setTimeout(applyIcons, 500); +}); diff --git a/staticfiles/css/admin_platform_profile.css b/staticfiles/css/admin_platform_profile.css new file mode 100644 index 0000000..9e7d185 --- /dev/null +++ b/staticfiles/css/admin_platform_profile.css @@ -0,0 +1,44 @@ +/* Custom sidebar-like styling for vertical tabs in Platform Profile */ + +.col-sm-3 .nav-pills.flex-column { + background: #f8f9fa; + border-radius: 8px; + padding: 10px; + border: 1px solid #dee2e6; +} + +.col-sm-3 .nav-pills.flex-column .nav-link { + color: #495057; + margin-bottom: 5px; + border-radius: 6px; + transition: all 0.2s ease; + padding: 12px 15px; + font-weight: 500; +} + +.col-sm-3 .nav-pills.flex-column .nav-link:hover { + background-color: #e9ecef; + color: #007bff; +} + +.col-sm-3 .nav-pills.flex-column .nav-link.active { + background-color: #007bff; + color: #fff; + box-shadow: 0 4px 6px rgba(0, 123, 255, 0.2); +} + +.col-sm-3 .nav-pills.flex-column .nav-link i { + font-size: 1.1rem; + vertical-align: middle; +} + +/* Adjust the main content area */ +.col-sm-9 { + padding-left: 20px; +} + +.card-primary.card-outline { + border-top: 3px solid #007bff; + border-radius: 8px; + box-shadow: 0 0 1px rgba(0,0,0,.125), 0 1px 3px rgba(0,0,0,.2); +} diff --git a/staticfiles/js/admin_platform_profile.js b/staticfiles/js/admin_platform_profile.js new file mode 100644 index 0000000..903bb5f --- /dev/null +++ b/staticfiles/js/admin_platform_profile.js @@ -0,0 +1,51 @@ +document.addEventListener('DOMContentLoaded', function() { + const iconMap = { + 'General Info': 'fas fa-info-circle', + 'Financial Configuration': 'fas fa-money-bill-wave', + 'Maintenance / Availability': 'fas fa-tools', + 'Driver Warning & Rejection / Auto-Ban': 'fas fa-user-slash', + 'Testing / Development': 'fas fa-flask', + 'Integrations': 'fas fa-plug', + 'Policies': 'fas fa-file-contract', + 'WhatsApp Configuration (Wablas Gateway)': 'fab fa-whatsapp', + 'Tools': 'fas fa-wrench' + }; + + const iconMapAr = { + 'معلومات عامة': 'fas fa-info-circle', + 'التكوين المالي': 'fas fa-money-bill-wave', + 'الصيانة / التوفر': 'fas fa-tools', + 'تحذير السائق ورفضه / الحظر التلقائي': 'fas fa-user-slash', + 'الاختبار / التطوير': 'fas fa-flask', + 'التكاملات': 'fas fa-plug', + 'السياسات': 'fas fa-file-contract', + 'تكوين واتساب (بوابة وابلأس)': 'fab fa-whatsapp', + 'أدوات': 'fas fa-wrench' + }; + + const fullIconMap = {...iconMap, ...iconMapAr}; + + function applyIcons() { + const tabs = document.querySelectorAll('.nav-link'); + tabs.forEach(tab => { + // Check if icon already exists + if (tab.querySelector('i.fas, i.fab')) return; + + const text = tab.textContent.trim(); + for (const [key, icon] of Object.entries(fullIconMap)) { + if (text.includes(key)) { + const i = document.createElement('i'); + i.className = icon + ' mr-2'; + i.style.width = '20px'; + i.style.textAlign = 'center'; + tab.prepend(i); + break; + } + } + }); + } + + applyIcons(); + // Sometimes jazzmin loads tabs dynamically or with a delay + setTimeout(applyIcons, 500); +});