diff --git a/core/__pycache__/admin.cpython-311.pyc b/core/__pycache__/admin.cpython-311.pyc index 39feadc..3e79ad8 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 b16cdd3..c579958 100644 --- a/core/admin.py +++ b/core/admin.py @@ -23,6 +23,11 @@ class ProfileInline(admin.StackedInline): class CustomUserAdmin(UserAdmin): inlines = (ProfileInline,) + def get_inline_instances(self, request, obj=None): + if not obj: + return list() + return super(CustomUserAdmin, self).get_inline_instances(request, obj) + class ParcelAdmin(admin.ModelAdmin): list_display = ('tracking_number', 'shipper', 'carrier', 'price', 'status', 'payment_status', 'created_at') list_filter = ('status', 'payment_status', 'created_at') @@ -166,4 +171,4 @@ admin.site.register(Country, CountryAdmin) admin.site.register(Governate) admin.site.register(City) admin.site.register(PlatformProfile, PlatformProfileAdmin) -admin.site.register(Testimonial, TestimonialAdmin) \ No newline at end of file +admin.site.register(Testimonial, TestimonialAdmin) diff --git a/core/templates/admin/index.html b/core/templates/admin/index.html new file mode 100644 index 0000000..fe1ab63 --- /dev/null +++ b/core/templates/admin/index.html @@ -0,0 +1,295 @@ +{% extends "admin/index.html" %} +{% load i18n static dashboard_stats %} + +{% block extrastyle %} +{{ block.super }} + + +{% endblock %} + +{% block content %} +{% get_dashboard_stats as stats %} + +
+ + +
+
+
+ {% trans "Total Revenue" %} +
💰
+
+
{{ stats.total_revenue|floatform:2 }} OMR
+
+ +
+
+ {% trans "Total Parcels" %} +
📦
+
+
{{ stats.total_parcels }}
+
+ {{ stats.delivered_parcels }} Delivered +
+
+ +
+
+ {% trans "Active Drivers" %} +
🚚
+
+
{{ stats.drivers_count }}
+
+ +
+
+ {% trans "Pending Orders" %} +
+
+
{{ stats.pending_parcels }}
+
+
+ + +
+
+

{% trans "Shipments Overview (Last 7 Days)" %}

+ +
+ +
+

{% trans "Recent Activity" %}

+
    + {% for parcel in stats.recent_parcels %} +
  • +
    + {{ parcel.shipper.username|slice:":1"|upper }} +
    +
    +
    {% trans "New Parcel" %} #{{ parcel.tracking_number|slice:":8" }}...
    +
    {{ parcel.created_at|timesince }} {% trans "ago" %}
    +
    + + {{ parcel.get_status_display }} + +
  • + {% empty %} +
  • {% trans "No recent activity." %}
  • + {% endfor %} +
+
+
+ +
+ + +{{ block.super }} + + + + +{% endblock %} \ No newline at end of file diff --git a/core/templatetags/__pycache__/dashboard_stats.cpython-311.pyc b/core/templatetags/__pycache__/dashboard_stats.cpython-311.pyc new file mode 100644 index 0000000..03b1a63 Binary files /dev/null and b/core/templatetags/__pycache__/dashboard_stats.cpython-311.pyc differ diff --git a/core/templatetags/dashboard_stats.py b/core/templatetags/dashboard_stats.py new file mode 100644 index 0000000..d61e43e --- /dev/null +++ b/core/templatetags/dashboard_stats.py @@ -0,0 +1,49 @@ +from django import template +from django.contrib.auth.models import User +from core.models import Parcel, Profile +from django.db.models import Sum, Count +from django.utils import timezone +from datetime import timedelta +import json + +register = template.Library() + +@register.simple_tag +def get_dashboard_stats(): + # User Stats + total_users = User.objects.count() + drivers_count = Profile.objects.filter(role='driver').count() + shippers_count = Profile.objects.filter(role='shipper').count() + + # Parcel Stats + total_parcels = Parcel.objects.count() + delivered_parcels = Parcel.objects.filter(status='delivered').count() + pending_parcels = Parcel.objects.filter(status='pending').count() + + # Financials + total_revenue = Parcel.objects.filter(status='delivered').aggregate(Sum('price'))['price__sum'] or 0 + + # Recent Activity + recent_parcels = Parcel.objects.select_related('shipper', 'shipper__profile').order_by('-created_at')[:5] + + # Chart Data (Last 7 Days) + today = timezone.now().date() + dates = [(today - timedelta(days=i)).strftime('%Y-%m-%d') for i in range(6, -1, -1)] + + daily_counts = [] + for date_str in dates: + count = Parcel.objects.filter(created_at__date=date_str).count() + daily_counts.append(count) + + return { + 'total_users': total_users, + 'drivers_count': drivers_count, + 'shippers_count': shippers_count, + 'total_parcels': total_parcels, + 'delivered_parcels': delivered_parcels, + 'pending_parcels': pending_parcels, + 'total_revenue': total_revenue, + 'recent_parcels': recent_parcels, + 'chart_labels': json.dumps(dates), + 'chart_data': json.dumps(daily_counts), + } \ No newline at end of file diff --git a/locale/ar/LC_MESSAGES/django.mo b/locale/ar/LC_MESSAGES/django.mo index 3ae2ad1..4e3a693 100644 Binary files a/locale/ar/LC_MESSAGES/django.mo and b/locale/ar/LC_MESSAGES/django.mo differ diff --git a/locale/ar/LC_MESSAGES/django.po b/locale/ar/LC_MESSAGES/django.po index 7cc2de5..d69c812 100644 --- a/locale/ar/LC_MESSAGES/django.po +++ b/locale/ar/LC_MESSAGES/django.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-01-26 05:03+0000\n" +"POT-Creation-Date: 2026-01-26 05:21+0000\n" "PO-Revision-Date: 2026-01-25 07:13+0000\n" "Last-Translator: Gemini\n" "Language-Team: Arabic\n" @@ -22,46 +22,46 @@ msgstr "" msgid "Profiles" msgstr "الملفات الشخصية" -#: core/admin.py:52 +#: core/admin.py:57 msgid "Export Selected to CSV" msgstr "تصدير المحدد إلى CSV" -#: core/admin.py:56 +#: core/admin.py:61 msgid "General Info" msgstr "معلومات عامة" -#: core/admin.py:59 +#: core/admin.py:64 msgid "Policies" msgstr "السياسات" -#: core/admin.py:62 +#: core/admin.py:67 msgid "Payment Configuration" msgstr "إعدادات الدفع" -#: core/admin.py:65 +#: core/admin.py:70 msgid "WhatsApp Configuration (Wablas Gateway)" msgstr "إعدادات واتساب (بوابة Wablas)" -#: core/admin.py:67 +#: core/admin.py:72 msgid "" "Configure your Wablas API connection. Use \"Test WhatsApp Configuration\" to " "verify." msgstr "" "قم بتكوين اتصال Wablas API الخاص بك. استخدم \"اختبار إعدادات واتساب\" للتحقق." -#: core/admin.py:134 +#: core/admin.py:139 msgid "Test WhatsApp" msgstr "اختبار واتساب" -#: core/admin.py:136 +#: core/admin.py:141 msgid "Test Email" msgstr "اختبار البريد الإلكتروني" -#: core/admin.py:138 +#: core/admin.py:143 msgid "Actions" msgstr "إجراءات" -#: core/admin.py:149 +#: core/admin.py:154 msgid "Tools" msgstr "أدوات" @@ -376,7 +376,7 @@ msgstr "حدث في" msgid "Parcel" msgstr "طرد" -#: core/models.py:165 +#: core/models.py:165 core/templates/admin/index.html:258 msgid "Parcels" msgstr "طرود" @@ -506,6 +506,42 @@ msgstr "تقييمات السائق" msgid "Home" msgstr "الرئيسية" +#: core/templates/admin/index.html:180 +msgid "Total Revenue" +msgstr "إجمالي الإيرادات" + +#: core/templates/admin/index.html:188 +msgid "Total Parcels" +msgstr "إجمالي الطرود" + +#: core/templates/admin/index.html:199 +msgid "Active Drivers" +msgstr "السائقون النشطون" + +#: core/templates/admin/index.html:207 +msgid "Pending Orders" +msgstr "طلبات قيد الانتظار" + +#: core/templates/admin/index.html:217 +msgid "Shipments Overview (Last 7 Days)" +msgstr "نظرة عامة على الشحنات (آخر 7 أيام)" + +#: core/templates/admin/index.html:222 +msgid "Recent Activity" +msgstr "النشاط الأخير" + +#: core/templates/admin/index.html:230 +msgid "New Parcel" +msgstr "طرد جديد" + +#: core/templates/admin/index.html:231 +msgid "ago" +msgstr "مضت" + +#: core/templates/admin/index.html:238 +msgid "No recent activity." +msgstr "لا يوجد نشاط حديث." + #: core/templates/base.html:9 core/templates/base.html:204 msgid "Small Shipments, Smart Delivery" msgstr "شحنات صغيرة، توصيل ذكي" @@ -1279,4 +1315,4 @@ msgstr "شكراً لملاحظاتك!" #~ msgstr "لم ترسل أي شحنات بعد." #~ msgid "Find Loads" -#~ msgstr "البحث عن شحنات" +#~ msgstr "البحث عن شحنات" \ No newline at end of file