diff --git a/inventory/urls.py b/inventory/urls.py index cca5ab0a..29affe5b 100644 --- a/inventory/urls.py +++ b/inventory/urls.py @@ -40,12 +40,15 @@ urlpatterns = [ views.assign_car_makes, name="assign_car_makes", ), - path( - "dashboards/manager/", - views.ManagerDashboard.as_view(), - name="manager_dashboard", - ), + + + #dashboards + path("dashboards/dealer/", views.DealerDashboard.as_view(),name="dealer_dashboard"), + path( "dashboards/manager/", views.ManagerDashboard.as_view(),name="manager_dashboard"), path("dashboards/sales/", views.SalesDashboard.as_view(), name="sales_dashboard"), + path("dashboards/accountant/", views.AccountantDashboard.as_view(), name="accountant_dashboard"), + path("dashboards/inventory/", views.InventoryDashboard.as_view(), name="inventory_dashboard"), + path("cars/inventory/table/", views.CarListViewTable.as_view(), name="car_table"), path("export/format/", TableExport.export, name="export"), diff --git a/inventory/views.py b/inventory/views.py index 212dcad3..6b36b60a 100644 --- a/inventory/views.py +++ b/inventory/views.py @@ -386,7 +386,101 @@ class TestView(TemplateView): template_name = "inventory/cars_list_api.html" +class DealerDashboard(LoginRequiredMixin, TemplateView): + """ + ManagerDashboard class is a view handling the dashboard for a manager. + Provides functionality to manage and view various statistics and data specific + to the dealer associated with the authenticated manager. It uses a specific + template and ensures authentication before granting access. The class + aggregates data about cars, leads, financial statistics, and other related + business information for display in the manager's dashboard. + + :ivar template_name: Path to the template used for rendering the manager's dashboard. + :type template_name: str + """ + + template_name = "dashboards/dealer_dashbaord.html" + + # def dispatch(self, request, *args, **kwargs): + # if not request.user.is_authenticated: + # return redirect("welcome") + # if not getattr(request.user, "dealer", False): + # return HttpResponseForbidden( + # "You are not authorized to view this dashboard." + # ) + # return super().dispatch(request, *args, **kwargs) + + def get_context_data(self, **kwargs): + context = super().get_context_data(**kwargs) + dealer = get_user_type(self.request) + entity = dealer.entity + + qs = models.Car.objects.filter(dealer=dealer) + total_cars = qs.count() + + stats = models.CarFinance.objects.filter(car__dealer=dealer).aggregate( + total_cost_price=Sum("cost_price"), + total_selling_price=Sum("selling_price"), + ) + total_cost_price = stats["total_cost_price"] or 0 + total_selling_price = stats["total_selling_price"] or 0 + total_profit = total_selling_price - total_cost_price + + new_leads = models.Lead.objects.filter( + dealer=dealer, status=models.Status.NEW + ).count() + pending_leads = models.Lead.objects.filter( + dealer=dealer, status=models.Status.CONTACTED + ).count() + canceled_leads = models.Lead.objects.filter( + dealer=dealer, status=models.Status.UNQUALIFIED + ).count() + + car_status_qs = qs.values("status").annotate(count=Count("status")) + car_status = {status: count for status, count in car_status_qs} + + car_by_make_qs = qs.values("id_car_make__name").annotate(count=Count("id")) + car_by_make = list(car_by_make_qs) + + context["dealer"] = dealer + context["total_activity"] = models.UserActivityLog.objects.filter( + user=dealer.user + ).count() + context["total_cars"] = total_cars + context["total_reservations"] = models.CarReservation.objects.filter( + reserved_until__gte=timezone.now() + ).count() + context["total_cost_price"] = total_cost_price + context["total_selling_price"] = total_selling_price + context["total_profit"] = total_profit + context["new_leads"] = new_leads + context["pending_leads"] = pending_leads + context["canceled_leads"] = canceled_leads + context["car"] = json.dumps(car_by_make) + + + context["available_cars"] =qs.filter(status='available').count() + context["sold_cars"] = qs.filter(status='sold').count() + context["reserved_cars"] = qs.filter(status='reserved').count() + context["hold_cars"] =qs.filter(status='hold').count() + context["damaged_cars"] = qs.filter(status='damaged').count() + context["transfer_cars"] = qs.filter(status='transfer').count() + context["present_inventory_count"]=total_cars-context["sold_cars"]-context["damaged_cars"] + cars_sold=qs.filter(status='sold') + # cars_sold.aggregate(total_inventory_value=sum()) + + + context["customers"] = entity.get_customers().count() + context["staff"] = models.Staff.objects.filter(dealer=dealer).count() + context["total_leads"] = models.Lead.objects.filter(dealer=dealer).count() + context["invoices"] = entity.get_invoices().count() + context["estimates"] = entity.get_estimates().count() + context["purchase_orders"] = entity.get_purchase_orders().count() + + + + return context class ManagerDashboard(LoginRequiredMixin, TemplateView): """ @@ -402,7 +496,7 @@ class ManagerDashboard(LoginRequiredMixin, TemplateView): :type template_name: str """ - template_name = "dashboards/manager.html" + template_name = "dashboards/manager_dashboard.html" # def dispatch(self, request, *args, **kwargs): # if not request.user.is_authenticated: @@ -485,6 +579,9 @@ class ManagerDashboard(LoginRequiredMixin, TemplateView): return context + + + class SalesDashboard(LoginRequiredMixin, TemplateView): """ SalesDashboard class provides a view for the sales dashboard. @@ -503,7 +600,152 @@ class SalesDashboard(LoginRequiredMixin, TemplateView): :type template_name: str """ - template_name = "dashboards/sales.html" + template_name = "dashboards/sales_dashboard.html" + + def get_context_data(self, **kwargs): + context = super().get_context_data(**kwargs) + dealer = self.request.dealer + staff = getattr(self.request, "staff", None) + total_cars = models.Car.objects.filter(dealer=dealer).count() + total_reservations = models.CarReservation.objects.filter( + reserved_by=self.request.user, reserved_until__gte=timezone.now() + ).count() + + available_cars = models.Car.objects.filter( + dealer=dealer, status=models.CarStatusChoices.AVAILABLE + ).count() + sold_cars = models.Car.objects.filter( + dealer=dealer, status=models.CarStatusChoices.SOLD + ).count() + reserved_cars = models.Car.objects.filter( + dealer=dealer, status=models.CarStatusChoices.RESERVED + ).count() + hold_cars = models.Car.objects.filter( + dealer=dealer, status=models.CarStatusChoices.HOLD + ).count() + damaged_cars = models.Car.objects.filter( + dealer=dealer, status=models.CarStatusChoices.DAMAGED + ).count() + transfer_cars = models.Car.objects.filter( + dealer=dealer, status=models.CarStatusChoices.TRANSFER + ).count() + reserved_percentage = reserved_cars / total_cars * 100 + sold_percentage = sold_cars / total_cars * 100 + qs = ( + models.Car.objects.values("id_car_make__name") + .annotate(count=Count("id")) + .order_by("id_car_make__name") + ) + car_by_make = list(qs) + + context["dealer"] = dealer + context["staff"] = staff + context["total_cars"] = total_cars + context["total_reservations"] = total_reservations + context["reserved_percentage"] = reserved_percentage + context["sold_percentage"] = sold_percentage + context["available_cars"] = available_cars + context["sold_cars"] = sold_cars + context["reserved_cars"] = reserved_cars + context["hold_cars"] = hold_cars + context["damaged_cars"] = damaged_cars + context["transfer_cars"] = transfer_cars + context["car"] = json.dumps(car_by_make) + + return context + + +class InventoryDashboard(LoginRequiredMixin, TemplateView): + """ + SalesDashboard class provides a view for the sales dashboard. + + This class is responsible for generating the context data required to + display various statistics and information on the sales dashboard. It + inherits from `LoginRequiredMixin` and `TemplateView`, ensuring only + authenticated users can access the view. The dashboard includes data + such as the total number of cars, reservations, sold percentages, + reserved percentages, and cars categorized by various statuses. The + purpose of this dashboard is to provide dealership staff an overview + of their inventory and related sales metrics. + + :ivar template_name: The name of the HTML template used for rendering + the sales dashboard. + :type template_name: str + """ + + template_name = "dashboards/inventory_dashboard.html" + + def get_context_data(self, **kwargs): + context = super().get_context_data(**kwargs) + dealer = self.request.dealer + staff = getattr(self.request, "staff", None) + total_cars = models.Car.objects.filter(dealer=dealer).count() + total_reservations = models.CarReservation.objects.filter( + reserved_by=self.request.user, reserved_until__gte=timezone.now() + ).count() + + available_cars = models.Car.objects.filter( + dealer=dealer, status=models.CarStatusChoices.AVAILABLE + ).count() + sold_cars = models.Car.objects.filter( + dealer=dealer, status=models.CarStatusChoices.SOLD + ).count() + reserved_cars = models.Car.objects.filter( + dealer=dealer, status=models.CarStatusChoices.RESERVED + ).count() + hold_cars = models.Car.objects.filter( + dealer=dealer, status=models.CarStatusChoices.HOLD + ).count() + damaged_cars = models.Car.objects.filter( + dealer=dealer, status=models.CarStatusChoices.DAMAGED + ).count() + transfer_cars = models.Car.objects.filter( + dealer=dealer, status=models.CarStatusChoices.TRANSFER + ).count() + reserved_percentage = reserved_cars / total_cars * 100 + sold_percentage = sold_cars / total_cars * 100 + qs = ( + models.Car.objects.values("id_car_make__name") + .annotate(count=Count("id")) + .order_by("id_car_make__name") + ) + car_by_make = list(qs) + + context["dealer"] = dealer + context["staff"] = staff + context["total_cars"] = total_cars + context["total_reservations"] = total_reservations + context["reserved_percentage"] = reserved_percentage + context["sold_percentage"] = sold_percentage + context["available_cars"] = available_cars + context["sold_cars"] = sold_cars + context["reserved_cars"] = reserved_cars + context["hold_cars"] = hold_cars + context["damaged_cars"] = damaged_cars + context["transfer_cars"] = transfer_cars + context["car"] = json.dumps(car_by_make) + + return context + +class AccountantDashboard(LoginRequiredMixin, TemplateView): + """ + SalesDashboard class provides a view for the sales dashboard. + + This class is responsible for generating the context data required to + display various statistics and information on the sales dashboard. It + inherits from `LoginRequiredMixin` and `TemplateView`, ensuring only + authenticated users can access the view. The dashboard includes data + such as the total number of cars, reservations, sold percentages, + reserved percentages, and cars categorized by various statuses. The + purpose of this dashboard is to provide dealership staff an overview + of their inventory and related sales metrics. + + :ivar template_name: The name of the HTML template used for rendering + the sales dashboard. + :type template_name: str + """ + + template_name = "dashboards/accountant_dashboard.html" def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) @@ -10559,7 +10801,7 @@ def upload_cars(request, dealer_slug, pk=None): response = redirect("upload_cars", dealer_slug=dealer_slug, pk=pk) if po_item.status == "uploaded": - messages.add_message(request, messages.ERROR, "Item already uploaded.") + messages.add_message(request, messages.SUCCESS, "Item uploaded Sucessfully.") return redirect( "view_items_inventory", dealer_slug=dealer_slug, diff --git a/templates/dashboards/accountant_dashboard.html b/templates/dashboards/accountant_dashboard.html new file mode 100644 index 00000000..0bf03d0f --- /dev/null +++ b/templates/dashboards/accountant_dashboard.html @@ -0,0 +1,218 @@ +{% extends 'base.html' %} +{% block content %} + +
+
+

Accountant Dashboard

+ +
+ +
+
+
+
+
+

Total Revenue

+

$1.25M

+
+ + +8% from last month + +
+
+
+
+
+
+
+

Net Profit

+

$1.25M

+
+ + +8% from last month + +
+
+
+
+
+
+
+

Gross Profit

+

$1.25M

+
+ + +8% from last month + +
+
+
+
+
+
+
+

Total Expense

+

$1.25M

+
+ + +8% from last month + +
+
+
+
+ +

Breakdown by Vehicle Type

+
+
+
+

New Cars

+

$1.25M

+

Total Revenue

+
+
+
+
+

Used Cars

+

$0.75M

+

Total Revenue

+
+
+
+
+

New Cars

+

$0.25M

+

Net Profit

+
+
+
+
+

Used Cars

+

$0.15M

+

Net Profit

+
+
+
+ +
+
+
+
+
Monthly Revenue & Profit
+
+
+ +
+
+
+
+
+ + +{% endblock %} + +{% block customJS %} + +{% endblock %} \ No newline at end of file diff --git a/templates/dashboards/dealer_dashbaord.html b/templates/dashboards/dealer_dashbaord.html new file mode 100644 index 00000000..12753d7f --- /dev/null +++ b/templates/dashboards/dealer_dashbaord.html @@ -0,0 +1,243 @@ +{% extends 'base.html' %} +{% block content %} + +
+
+

Business Health Dashboard

+ +
+ +
+
+
+
+
+

Total Revenue

+

$1.25M

+
+ + +8% from last month + +
+
+
+
+
+
+
+

Net Profit

+

$1.25M

+
+ + +8% from last month + +
+
+
+
+
+
+
+

Gross Profit

+

$1.25M

+
+ + +8% from last month + +
+
+
+
+
+
+
+

Total Expense

+

$1.25M

+
+ + -2% from last month + +
+
+
+
+
+
+
+

Total VAT Collected

+

$1.25M

+
+ + +8% from last month + +
+
+
+
+
+
+
+

Total Cars Sold

+

{{ sold_cars }}

+
+ + +5 units from last month + +
+
+
+
+ +
+
+
+
+
Monthly Revenue & Profit
+
+
+ +
+
+
+
+
+
+
Monthly Cars Sold
+
+
+ +
+
+
+
+
+ + +{% endblock content %} + + +{% block customJS %} + +{% endblock %} \ No newline at end of file diff --git a/templates/dashboards/inventory_dashboard.html b/templates/dashboards/inventory_dashboard.html new file mode 100644 index 00000000..e5a8cac9 --- /dev/null +++ b/templates/dashboards/inventory_dashboard.html @@ -0,0 +1,300 @@ +{% extends 'base.html' %} +{% block content %} + +
+
+

Inventory Dashboard

+ +
+ +
+
+
+
+
+

Total Cars in Inventory

+

{{ total_cars_in_inventory }}

+
+ + +5 units from last month + +
+
+
+
+
+
+
+

New Cars in Inventory

+

{{ new_cars_in_inventory }}

+
+ + +5 units from last month + +
+
+
+
+
+
+
+

Used Cars in Inventory

+

{{ old_cars_in_inventory }}

+
+ + +5 units from last month + +
+
+
+
+
+
+
+

Inventory Value

+

$5.8M

+
+ + -2% from last month + +
+
+
+
+ +
+
+
+

New Car Value

+

$3.2M

+

Total new cars value

+
+
+
+
+

Used Car Value

+

$2.6M

+

Total used cars value

+
+
+
+
+

Average Time on Lot

+

10 days

+

Average for all vehicles

+
+
+
+
+

Aging Inventory

+

12 cars

+ + -4 cars from last month + +
+
+
+ + +
+
+
+
+
Inventory by Make
+
+
+ +
+
+
+ +
+
+
+
Car Models by Make in Inventory
+
+
+
+ + +
+
+
+ +
+
+
+ +
+ + +
+ + +{% endblock content %} + +{% block customJS %} + +{% endblock %} \ No newline at end of file diff --git a/templates/dashboards/manager.html b/templates/dashboards/manager.html deleted file mode 100644 index 962f274b..00000000 --- a/templates/dashboards/manager.html +++ /dev/null @@ -1,641 +0,0 @@ -{% extends 'base.html' %} -{% block content %} -
-
-

Dashboard Overview

- -
- -
-
-
-
-
Total Revenue
-

$1.25M

- +8% from last month -
-
-
-
-
-
-
Net Profit
-

$1.25M

- +8% from last month -
-
-
-
-
-
-
Gross Profit
-

$1.25M

- +8% from last month -
-
-
-
-
-
-
Total Expense
-

$1.25M

- +8% from last month -
-
-
-
-
-
-
Total VAT collected
-

$1.25M

- +8% from last month -
-
-
-
-
-
-
Cars Sold
-

{{sold_cars}}

- +5 units from last month -
-
-
-
-
-
-
Average Time on Lot
-

10 days

-
-
-
-
-
-
-
Inventory Value
-

$5.8M

- -2% from last month -
-
-
-
-
-
-
Aging Inventory
-

12

- -4 cars from last month -
-
-
-
- -
-
-
-
Monthly Revenue & Profit
-
- -
-
-
-
-
-
Monthly Cars Sold
-
- -
-
-
-
-
-
Inventory By Make
-
- -
-
-
-
-
-
Sales By Make
-
- -
-
-
- -
-
-
Salesperson Performance
-
- -
-
-
-
-
-
Top 5 Lead Sources
-
- -
-
-
-
-
-
Appointments by Weekday
-
- -
-
-
- -
-
-
Lead Conversion Funnel
-
- -
-
-
-
-
- -{% endblock content %} - - -{% block customJS%} - - -{% endblock %} \ No newline at end of file diff --git a/templates/dashboards/manager_dashboard.html b/templates/dashboards/manager_dashboard.html new file mode 100644 index 00000000..0d6c30ad --- /dev/null +++ b/templates/dashboards/manager_dashboard.html @@ -0,0 +1,367 @@ +{% extends 'base.html' %} +{% block content %} + +
+
+

Manager Dashboard

+ +
+ +
+
+
+
+
+

Total Revenue

+

$1.25M

+
+ + +8% from last month + +
+
+
+
+
+
+
+

Net Profit

+

$1.25M

+
+ + +8% from last month + +
+
+
+
+
+
+
+

Total Expense

+

$1.25M

+
+ + +3% from last month + +
+
+
+
+
+
+
+

Total Cars Sold

+

{{ sold_cars }}

+
+ + +5 units from last month + +
+
+
+
+
+
+
+

Avg. Time on Lot

+

10 days

+
+ + +2 days from last month + +
+
+
+
+
+
+
+

Inventory Value

+

$5.8M

+
+ + -2% from last month + +
+
+
+
+
+
+
+

Aging Inventory

+

12 units

+
+ + -4 cars from last month + +
+
+
+
+
+
+
+

Gross Profit

+

$1.25M

+
+ + +8% from last month + +
+
+
+
+ +
+
+
+
+
Monthly Revenue & Profit
+
+
+ +
+
+
+
+
+
+
Monthly Cars Sold
+
+
+ +
+
+
+
+ +
+
+
+
+
Sales by Make
+
+
+ +
+
+
+
+
+
+
Top Salesperson Performance
+
+
+ +
+
+
+
+ +
+ +{% endblock content %} + + +{% block customJS %} + +{% endblock %} \ No newline at end of file diff --git a/templates/dashboards/sales_dashboard.html b/templates/dashboards/sales_dashboard.html new file mode 100644 index 00000000..211fa9e7 --- /dev/null +++ b/templates/dashboards/sales_dashboard.html @@ -0,0 +1,356 @@ +{% extends 'base.html' %} +{% block content %} + +
+
+

Sales & Leads Dashboard

+ +
+ +
+
+
+
+
+

Total Cars Sold

+

{{ sold_cars }}

+
+ + +5 units from last month + +
+
+
+
+
+
+
+

Used Cars Sold

+

{{ sold_used_cars }}

+
+ + +5 units from last month + +
+
+
+
+
+
+
+

New Cars Sold

+

{{ sold_new_cars }}

+
+ + +5 units from last month + +
+
+
+
+ +
+
+
+
+
Monthly Cars Sold
+
+
+ +
+
+
+
+
+
+
Sales by Make
+
+
+ +
+
+
+
+ +
+
+
+
+
Top 5 Lead Sources
+
+
+ +
+
+
+
+
+
+
Appointments by Weekday
+
+
+ +
+
+
+
+ +
+
+
+
+
Lead Conversion Funnel
+
+
+ +
+
+
+
+
+ + +{% endblock content %} + + +{% block customJS%} + +{% endblock %} \ No newline at end of file diff --git a/templates/index.html b/templates/index.html index b91b35d6..c12821e9 100644 --- a/templates/index.html +++ b/templates/index.html @@ -3,10 +3,16 @@ {% block content %} {% if request.user.is_authenticated %}
-
- - {{ _("Select All") }} -
+ {% for car in cars %}
-
-
- -
-
+
@@ -322,68 +311,5 @@ {% endblock %} - {% block customJS %} - - {% endblock customJS %} + + \ No newline at end of file diff --git a/templates/purchase_orders/car_inventory_item_form.html b/templates/purchase_orders/car_inventory_item_form.html index 74a5e4bb..727fd542 100644 --- a/templates/purchase_orders/car_inventory_item_form.html +++ b/templates/purchase_orders/car_inventory_item_form.html @@ -36,13 +36,13 @@ } .color-radio:checked + .color-display { - border: 2px solid #0d6efd; - box-shadow: 0 0 0 3px rgba(13, 110, 253, 0.25); + border: 3px solid rgb(44, 229, 44); + box-shadow: 0 0 10px rgba(44, 123, 229, 0.5); } .color-radio:focus + .color-display { - border-color: #86b7fe; - box-shadow: 0 0 0 3px rgba(13, 110, 253, 0.25); + border: 3px solid rgb(44, 229, 44); + box-shadow: 0 0 10px rgba(44, 123, 229, 0.5); } .color-display { diff --git a/templates/sales/estimates/estimate_detail.html b/templates/sales/estimates/estimate_detail.html index 439a2f42..8b9a1f8f 100644 --- a/templates/sales/estimates/estimate_detail.html +++ b/templates/sales/estimates/estimate_detail.html @@ -112,7 +112,7 @@ onclick="setFormAction('review')" data-bs-toggle="modal" data-bs-target="#confirmModal"> - {% trans 'Mark As Review' %} + {% trans 'Mark As Review' %} {% endif %} {% elif estimate.status == 'in_review' %} @@ -122,45 +122,46 @@ class="btn btn-phoenix-secondary" data-bs-toggle="modal" data-bs-target="#confirmModal"> - {% trans 'Mark As Approved' %} + {% trans 'Mark As Approved' %} {% endif %} {% if estimate.can_approve and not request.is_manager %} {% endif %} {% elif estimate.status == 'approved' %} {% if perms.django_ledger.change_estimatemodel %} {% trans 'Send Quotation' %} + class="btn btn-phoenix-primary me-2">{% trans 'Send Quotation' %} {% endif %} {% if estimate.sale_orders.first %} {% if perms.django_ledger.add_invoicemodel %} {% trans 'Create Invoice' %} + class="btn btn-phoenix-primary"> {% trans 'Create Invoice' %} {% endif %} {% if perms.inventory.view_saleorder %} {{ _("Preview Sale Order") }} + class="btn btn-phoenix-primary">{{ _("Preview Sale Order") }} {% endif %} {% else %} {% if perms.inventory.add_saleorder %} {% trans 'Create Sale Order' %} + class="btn btn-phoenix-primary"> {% trans 'Create Sale Order' %} {% endif %} {% endif %} {% elif estimate.status == 'completed' %} {% if perms.inventory.view_saleorder %} {{ _("Preview Sale Order") }} + class="btn btn-phoenix-primary">{{ _("Preview Sale Order") }} {% endif %} {% if perms.django_ledger.view_invoicemodel %} - {{ _("View Invoice") }} + type="button"> + {{ _("View Invoice") }} + {% endif %} {% endif %} {% if estimate.can_cancel %} @@ -168,7 +169,7 @@ {% endif %} {% endif %} @@ -178,31 +179,31 @@
- {% trans 'Quotation Number' %}: + {% trans 'Quotation Number' %}:

{{ estimate.estimate_number }}

- {% trans 'Quotation Date' %}: + {% trans 'Quotation Date' %}:

{{ estimate.created }}

- {% trans 'Customer' %}: + {% trans 'Customer' %}:

{{ estimate.customer.customer_name }}

- {% trans 'Email' %}: + {% trans 'Email' %}:

{{ estimate.customer.email }}

- {% trans "Quotation Status" %}: + {% trans "Quotation Status" %}:
{% if estimate.status == 'draft' %} diff --git a/templates/users/user_detail.html b/templates/users/user_detail.html index a1a980e8..9344e151 100644 --- a/templates/users/user_detail.html +++ b/templates/users/user_detail.html @@ -2,108 +2,107 @@ {% load static %} {% load i18n %} {% block title %} - {{ _("View Staff") }} + {{ user_.name }} {% endblock title %} {% block content %} -
-
-
-

- {{ _("User Details") }} -

+
+
+
+ + {% trans "Back to Staffs" %} + +

{% trans "Staff Profile" %}

-
-
-
- {% if user_.logo %} - User Image - {% else %} - Default User Image - {% endif %} -
-
-

- {{ _("Name") }}: {{ user_.name }} -

-

- {{ _("Arabic Name") }}: {{ user_.arabic_name }} -

-

- {{ _("Email") }}: {{ user_.email }} -

-
-
-

- {{ _("Phone Number") }}: {{ user_.phone_number }} -

-
- {{ _("Roles") }}: - {% for group in user_.groups %} - {{ group.name }} - {% if not forloop.last %}&{% endif %} - {% endfor %} +
+ + {% trans "Edit" %} + + +
+
+ +
+
+
+
+
+ {% if user_.logo %} + {{ user_.name }} + {% else %} +
+ {{ user_.name|first|upper }} +
+ {% endif %} +
+

{{ user_.name }}

+

{{ user_.email }}

+
-
-
-

Groups

- Manage Groups - - - - - - - - {% for group in user_.groups %} - - - - {% empty %} - - - - {% endfor %} - -
{% trans 'name'|capfirst %}
{{ group }}
{% trans "No Group" %}
-
-
{% include 'modal/delete_modal.html' %} -{% endblock %} +{% endblock %} \ No newline at end of file diff --git a/templates/users/user_group_form.html b/templates/users/user_group_form.html index b60c5ad5..91c71bfd 100644 --- a/templates/users/user_group_form.html +++ b/templates/users/user_group_form.html @@ -5,32 +5,37 @@ {% trans "Group" %} {% endblock title %} {% block content %} -
-
-
-
-

{{ _("Manage Groups") }}

+ +
+ +
+
+
+

+ {{ _("Manage Groups") }} +

+
+
+
+ {% csrf_token %} + {{ redirect_field }} + {{ form|crispy }} + {% for error in form.errors %}
{{ error }}
{% endfor %} +
+
+ + {% trans "Cancel" %} +
+
+ +
-
-
-
-
- {% csrf_token %} - {{ redirect_field }} - {{ form|crispy }} - {% for error in form.errors %} -
{{ error }}
- {% endfor %} -
- {% trans "Cancel" %} - -
-
-
-
-
+ + {% endblock %} + + + + + \ No newline at end of file diff --git a/templates/users/user_list.html b/templates/users/user_list.html index 28a7e1d9..4b810bc8 100644 --- a/templates/users/user_list.html +++ b/templates/users/user_list.html @@ -1,94 +1,100 @@ {% extends "base.html" %} {% load i18n %} {% load render_table from django_tables2 %} + {% block title %} {% trans "Staffs" %} {% endblock title %} + {% block content %} -{%if users or request.GET.q%} -
-
-
-
-
- {% if request.user.userplan %} - {% trans "Add New Staff" %} - {% trans "Manage Groups & Permissions" %} - {% else %} + {%if users or request.GET.q%} +
+
+

{% trans "Staffs" %}

+ {% if request.user.userplan %} + + {% endif %} +
- {% url "pricing_page" request.dealer.slug as pricing_page_url %} - {% include "message-illustration.html" with value1="No Active Plan, please create your subscription plan." value2="Manage Subscription" url=pricing_page_url %} - - {% endif %} -
+
+
+
+ + + + + + + + + + + + {% for user in users %} + + + + + + + + {% endfor %} + +
{% trans 'name'|capfirst %}{% trans 'email'|capfirst %}{% trans 'phone number'|capfirst %}{% trans 'role'|capfirst %}{% trans 'actions'|capfirst %}
+
+
+ {% if user.logo %} + {{ user.name }}'s logo + {% else %} +
+ {{ user.name|first|upper }} +
+ {% endif %} +
+ + {{ user.name }} + +
+
{{ user.email }}{{ user.phone_number }} + {% for group in user.groups %} + {{ group.name|title }} + {% endfor %} + + + {% trans 'View' %} + +
-
- - - - - - - - - - - - {% for user in users %} - - - - - - - - {% endfor %} - -
{% trans 'name'|capfirst %}{% trans 'email'|capfirst %}{% trans 'phone number'|capfirst %}{% trans 'role'|capfirst %}{% trans 'actions'|capfirst %}
-
-
- {% if user.logo %} - Logo - {% endif %} -
- {{ user.arabic_name }} -
-
{{ user.email }}{{ user.phone_number }} - {% for group in user.groups %} - {% trans group.name|title %} - {% endfor %} - - - - {% trans 'view'|capfirst %} - -
-
-
- {% if is_paginated %} + + {% if is_paginated %} +
{% include 'partials/pagination.html' %} - {% endif %} -
+
+ {% endif %}
-
{% else %} {% if request.user.userplan %} - {% url "user_create" request.dealer.slug as create_staff_url %} + {% url "user_create" request.dealer.slug as create_staff_url %} {% include "empty-illustration-page.html" with value="staff" url=create_staff_url %} - {% else %} {% url "pricing_page" request.dealer.slug as pricing_page_url %} {% include "message-illustration.html" with value1=_("No active plan, Please create a subscription plan.") value2=_("Buy Plan") url=pricing_page_url %} {% endif %} {% endif %} -{% endblock %} + +{% endblock %} \ No newline at end of file