This commit is contained in:
Marwan Alwali 2025-01-01 19:01:53 +03:00
parent c396960eaf
commit ec05b88720
35 changed files with 838 additions and 404 deletions

BIN
db.sqlite

Binary file not shown.

View File

@ -30,6 +30,7 @@ admin.site.register(models.VatRate)
admin.site.register(models.Customer) admin.site.register(models.Customer)
admin.site.register(models.Opportunity) admin.site.register(models.Opportunity)
admin.site.register(models.Notification) admin.site.register(models.Notification)
admin.site.register(models.OpportunityLog)
@admin.register(models.CarMake) @admin.register(models.CarMake)
class CarMakeAdmin(admin.ModelAdmin): class CarMakeAdmin(admin.ModelAdmin):

View File

@ -1,4 +1,4 @@
# Generated by Django 5.1.4 on 2024-12-31 15:48 # Generated by Django 5.1.4 on 2024-12-31 16:13
import django.db.models.deletion import django.db.models.deletion
from django.conf import settings from django.conf import settings
@ -14,7 +14,7 @@ class Migration(migrations.Migration):
operations = [ operations = [
migrations.CreateModel( migrations.CreateModel(
name='Log', name='OpportunityLog',
fields=[ fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('action', models.CharField(choices=[('create', 'Create'), ('update', 'Update'), ('delete', 'Delete'), ('status_change', 'Status Change')], max_length=50, verbose_name='Action')), ('action', models.CharField(choices=[('create', 'Create'), ('update', 'Update'), ('delete', 'Delete'), ('status_change', 'Status Change')], max_length=50, verbose_name='Action')),

View File

@ -0,0 +1,18 @@
# Generated by Django 5.1.4 on 2024-12-31 21:00
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('inventory', '0021_opportunitylog'),
]
operations = [
migrations.AlterField(
model_name='customer',
name='is_lead',
field=models.BooleanField(default=False, verbose_name='Is Lead'),
),
]

View File

@ -1,19 +0,0 @@
# Generated by Django 5.1.4 on 2024-12-31 15:49
from django.conf import settings
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('inventory', '0021_log'),
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]
operations = [
migrations.RenameModel(
old_name='Log',
new_name='OportunityLog',
),
]

View File

@ -0,0 +1,23 @@
# Generated by Django 5.1.4 on 2025-01-01 01:24
import django.db.models.deletion
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('inventory', '0022_alter_customer_is_lead'),
]
operations = [
migrations.RemoveField(
model_name='opportunitylog',
name='user',
),
migrations.AddField(
model_name='opportunitylog',
name='staff',
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='inventory.staff', verbose_name='Staff'),
),
]

View File

@ -260,6 +260,11 @@ class Car(models.Model):
active_reservations = self.reservations.filter(reserved_until__gt=now()) active_reservations = self.reservations.filter(reserved_until__gt=now())
return active_reservations.exists() return active_reservations.exists()
@property
def get_car_group(self):
return f"{self.id_car_make.get_local_name} {self.id_car_model.get_local_name}"
# class CarData(models.Model): # class CarData(models.Model):
# vin = models.CharField(max_length=17, unique=True, verbose_name=_("VIN")) # vin = models.CharField(max_length=17, unique=True, verbose_name=_("VIN"))
# make = models.CharField(max_length=255, verbose_name=_("Make")) # make = models.CharField(max_length=255, verbose_name=_("Make"))
@ -623,7 +628,7 @@ class Staff(models.Model, LocalizedNameMixin):
permissions = [] permissions = []
def __str__(self): def __str__(self):
return f"{self.name} - {self.dealer}" return f"{self.name} - {self.get_staff_type_display()}"
# Vendor Model # Vendor Model
@ -677,7 +682,7 @@ class Customer(models.Model):
max_length=200, blank=True, null=True, verbose_name=_("Address") max_length=200, blank=True, null=True, verbose_name=_("Address")
) )
created = models.DateTimeField(auto_now_add=True, verbose_name=_("Created")) created = models.DateTimeField(auto_now_add=True, verbose_name=_("Created"))
is_lead = models.BooleanField(default=True, verbose_name=_("Is Lead")) is_lead = models.BooleanField(default=False, verbose_name=_("Is Lead"))
class Meta: class Meta:
verbose_name = _("Customer") verbose_name = _("Customer")
@ -753,10 +758,10 @@ class ActionChoices(models.TextChoices):
STATUS_CHANGE = "status_change", _("Status Change") STATUS_CHANGE = "status_change", _("Status Change")
class OportunityLog(models.Model): class OpportunityLog(models.Model):
opportunity = models.ForeignKey(Opportunity, on_delete=models.CASCADE, related_name="logs") opportunity = models.ForeignKey(Opportunity, on_delete=models.CASCADE, related_name="logs")
action = models.CharField(max_length=50, choices=ActionChoices.choices, verbose_name=_("Action")) action = models.CharField(max_length=50, choices=ActionChoices.choices, verbose_name=_("Action"))
user = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, verbose_name=_("User")) staff = models.ForeignKey(Staff, on_delete=models.SET_NULL, null=True, verbose_name=_("Staff"))
old_status = models.CharField(max_length=50, choices=DealStatus.choices, null=True, blank=True, verbose_name=_("Old Status")) old_status = models.CharField(max_length=50, choices=DealStatus.choices, null=True, blank=True, verbose_name=_("Old Status"))
new_status = models.CharField(max_length=50, choices=DealStatus.choices, null=True, blank=True, verbose_name=_("New Status")) new_status = models.CharField(max_length=50, choices=DealStatus.choices, null=True, blank=True, verbose_name=_("New Status"))
details = models.TextField(blank=True, null=True, verbose_name=_("Details")) details = models.TextField(blank=True, null=True, verbose_name=_("Details"))

View File

@ -5,6 +5,7 @@ from django.contrib.auth import get_user_model
from django_ledger.io import roles from django_ledger.io import roles
from django_ledger.models import EntityModel,AccountModel,ItemModel,ItemModelAbstract,UnitOfMeasureModel, VendorModel from django_ledger.models import EntityModel,AccountModel,ItemModel,ItemModelAbstract,UnitOfMeasureModel, VendorModel
from . import models from . import models
from .models import OpportunityLog
User = get_user_model() User = get_user_model()
@ -342,3 +343,35 @@ def notify_staff_on_deal_status_change(sender, instance, **kwargs):
message = f"Deal '{instance.deal_name}' status changed from {previous.deal_status} to {instance.deal_status}." message = f"Deal '{instance.deal_name}' status changed from {previous.deal_status} to {instance.deal_status}."
models.Notification.objects.create(staff=instance.created_by, message=message) models.Notification.objects.create(staff=instance.created_by, message=message)
@receiver(post_save, sender=models.Opportunity)
def log_opportunity_creation(sender, instance, created, **kwargs):
if created:
models.OpportunityLog.objects.create(
opportunity=instance,
action='create',
user=instance.created_by,
details=f"Opportunity '{instance.deal_name}' was created."
)
@receiver(pre_save, sender=models.Opportunity)
def log_opportunity_update(sender, instance, **kwargs):
if instance.pk:
previous = models.Opportunity.objects.get(pk=instance.pk)
if previous.deal_status != instance.deal_status:
models.OpportunityLog.objects.create(
opportunity=instance,
action='status_change',
user=instance.created_by,
old_status=previous.deal_status,
new_status=instance.deal_status,
details=f"Status changed from {previous.deal_status} to {instance.deal_status}."
)
else:
models.OpportunityLog.objects.create(
opportunity=instance,
action='update',
user=instance.created_by,
details=f"Opportunity '{instance.deal_name}' was updated."
)

View File

@ -27,7 +27,6 @@ urlpatterns = [
path('login/code/', allauth_views.RequestLoginCodeView.as_view(template_name='account/request_login_code.html')), path('login/code/', allauth_views.RequestLoginCodeView.as_view(template_name='account/request_login_code.html')),
#Dashboards #Dashboards
path('dashboards/accounting/', views.AccountingDashboard.as_view(), name='accounting'), path('dashboards/accounting/', views.AccountingDashboard.as_view(), name='accounting'),
path('dashboards/crm/', views.notifications_view, name='staff_dashboard'),
# Dealer URLs # Dealer URLs
path('dealers/<int:pk>/', views.DealerDetailView.as_view(), name='dealer_detail'), path('dealers/<int:pk>/', views.DealerDetailView.as_view(), name='dealer_detail'),
@ -48,7 +47,9 @@ urlpatterns = [
path('opportunities/<int:pk>/edit/', views.OpportunityUpdateView.as_view(), name='update_opportunity'), path('opportunities/<int:pk>/edit/', views.OpportunityUpdateView.as_view(), name='update_opportunity'),
path('opportunities/', views.OpportunityListView.as_view(), name='opportunity_list'), path('opportunities/', views.OpportunityListView.as_view(), name='opportunity_list'),
path('opportunities/<int:pk>/delete/', views.delete_opportunity, name='delete_opportunity'), path('opportunities/<int:pk>/delete/', views.delete_opportunity, name='delete_opportunity'),
path('opportunities/<int:pk>/logs/', views.OpportunityLogsView.as_view(), name='opportunity_logs'),
path('notifications/', views.NotificationListView.as_view(), name='notifications_history'), path('notifications/', views.NotificationListView.as_view(), name='notifications_history'),
path('fetch_notifications/', views.fetch_notifications, name='fetch_notifications'),
path('notifications/<int:pk>/mark_as_read/', views.mark_notification_as_read, name='mark_notification_as_read'), path('notifications/<int:pk>/mark_as_read/', views.mark_notification_as_read, name='mark_notification_as_read'),
#Vendor URLs #Vendor URLs

View File

@ -674,8 +674,10 @@ class CustomerListView(LoginRequiredMixin, PermissionRequiredMixin, ListView):
def get_queryset(self): def get_queryset(self):
query = self.request.GET.get("q") query = self.request.GET.get("q")
if self.request.user.is_staff:
dealer = self.request.user.staff.dealer
customers = models.Customer.objects.filter( customers = models.Customer.objects.filter(
dealer=self.request.user.dealer dealer=dealer,
) )
if query: if query:
@ -2059,9 +2061,19 @@ def delete_opportunity(request, pk):
return redirect("opportunity_list") return redirect("opportunity_list")
def notifications_view(request): class OpportunityLogsView(LoginRequiredMixin, ListView):
notifications = models.Notification.objects.filter(user=request.user, is_read=False).order_by('-created_at') model = models.OpportunityLog
return render(request, 'notifications.html', {'notifications': notifications}) template_name = 'crm/opportunity_logs.html'
context_object_name = 'logs'
def get_queryset(self):
opportunity_id = self.kwargs['pk']
return models.OpportunityLog.objects.filter(opportunity_id=opportunity_id).order_by('-created_at')
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['opportunity'] = models.Opportunity.objects.get(pk=self.kwargs['pk'])
return context
class NotificationListView(LoginRequiredMixin, ListView): class NotificationListView(LoginRequiredMixin, ListView):
@ -2074,10 +2086,25 @@ class NotificationListView(LoginRequiredMixin, ListView):
return models.Notification.objects.filter(user=self.request.user).order_by('-created_at') return models.Notification.objects.filter(user=self.request.user).order_by('-created_at')
@login_required
def mark_notification_as_read(request, pk): def mark_notification_as_read(request, pk):
notification = get_object_or_404(models.Notification, pk=pk) notification = get_object_or_404(models.Notification, pk=pk, user=request.user)
notification.is_read = True notification.is_read = True
notification.save() notification.save()
messages.success(request, _("Notification marked as read."))
return redirect('notifications_history') return redirect('notifications_history')
@login_required
def fetch_notifications(request):
notifications = models.Notification.objects.filter(user=request.user, is_read=False).order_by('-created_at')
notifications_data = [
{
'id': notification.id,
'message': notification.message,
'created_at': notification.created_at.strftime('%Y-%m-%d %H:%M:%S'),
}
for notification in notifications
]
return JsonResponse({'notifications': notifications_data})

BIN
static/.DS_Store vendored

Binary file not shown.

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 110 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.2 KiB

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 KiB

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 7.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 5.6 KiB

View File

@ -15,11 +15,209 @@ function getCookie(name) {
} }
const getDataTableInit = () => {
const togglePaginationButtonDisable = (button, disabled) => {
button.disabled = disabled;
button.classList[disabled ? 'add' : 'remove']('disabled');
};
// Selectors
const table = document.getElementById('opportunityTable');
if (table) {
const options = {
page: 10,
pagination: {
item: "<li><button class='page' type='button'></button></li>"
},
item: values => {
const {
orderId,
id,
customer,
date,
address,
deliveryType,
status,
badge,
amount
} = values;
return `
<tr class="btn-reveal-trigger">
<td class="order py-2 ps-3 align-middle white-space-nowrap">
<a class="fw-semibold" href="https://prium.github.io/phoenix/v1.12.0/apps/e-commerce/admin/order-details.html">
${orderId}
</a>
</td>
<td class="py-2 align-middle fw-bold">
<a class="fw-semibold text-body" href="#!">
${customer}
</a>
</td>
<td class="py-2 align-middle">
${date}
</td>
<td class="py-2 align-middle white-space-nowrap">
${address}
</td>
<td class="py-2 align-middle white-space-nowrap">
<p class="mb-0">${deliveryType}</p>
</td>
<td class="py-2 align-middle text-center fs-8 white-space-nowrap">
<span class="badge fs-10 badge-phoenix badge-phoenix-${badge.type}">
${status}
<span class="ms-1 ${badge.icon}" data-fa-transform="shrink-2"></span>
</span>
</td>
<td class="py-2 align-middle text-end fs-8 fw-medium">
${amount}
</td>
<td class="py-2 align-middle white-space-nowrap text-end">
<div class="dropstart position-static d-inline-block">
<button class="btn btn-link text-body btn-sm dropdown-toggle btn-reveal" type='button' id="order-dropdown-${id}" data-bs-toggle="dropdown" data-boundary="window" aria-haspopup="true" aria-expanded="false" data-bs-reference="parent">
<span class="fas fa-ellipsis-h fs-9"></span>
</button>
<div class="dropdown-menu dropdown-menu-end border py-2" aria-labelledby="order-dropdown-${id}">
<a href="#!" class="dropdown-item">View</a>
<a href="#!" class="dropdown-item">Edit</a>
<div class"dropdown-divider"></div>
<a href="#!" class="dropdown-item text-warning">Archive</a>
</div>
</div>
</td>
</tr>
`;
}
};
const paginationButtonNext = table.querySelector(
'[data-list-pagination="next"]'
);
const paginationButtonPrev = table.querySelector(
'[data-list-pagination="prev"]'
);
const viewAll = table.querySelector('[data-list-view="*"]');
const viewLess = table.querySelector('[data-list-view="less"]');
const listInfo = table.querySelector('[data-list-info]');
const listFilter = document.querySelector('[data-list-filter]');
function notify(tag,msg){ const orderList = new window.List(table, options, orders);
Toast.fire({
icon: tag, // Fallback
titleText: msg orderList.on('updated', item => {
const fallback =
table.querySelector('.fallback') ||
document.getElementById(options.fallback);
if (fallback) {
if (item.matchingItems.length === 0) {
fallback.classList.remove('d-none');
} else {
fallback.classList.add('d-none');
}
}
});
const totalItem = orderList.items.length;
const itemsPerPage = orderList.page;
const btnDropdownClose =
orderList.listContainer.querySelector('.btn-close');
let pageQuantity = Math.ceil(totalItem / itemsPerPage);
let numberOfcurrentItems = orderList.visibleItems.length;
let pageCount = 1;
btnDropdownClose &&
btnDropdownClose.addEventListener('search.close', () =>
orderList.fuzzySearch('')
);
const updateListControls = () => {
listInfo &&
(listInfo.innerHTML = `${orderList.i} to ${numberOfcurrentItems} of ${totalItem}`);
paginationButtonPrev &&
togglePaginationButtonDisable(paginationButtonPrev, pageCount === 1);
paginationButtonNext &&
togglePaginationButtonDisable(
paginationButtonNext,
pageCount === pageQuantity
);
if (pageCount > 1 && pageCount < pageQuantity) {
togglePaginationButtonDisable(paginationButtonNext, false);
togglePaginationButtonDisable(paginationButtonPrev, false);
}
};
updateListControls();
if (paginationButtonNext) {
paginationButtonNext.addEventListener('click', e => {
e.preventDefault();
pageCount += 1;
const nextInitialIndex = orderList.i + itemsPerPage;
nextInitialIndex <= orderList.size() &&
orderList.show(nextInitialIndex, itemsPerPage);
numberOfcurrentItems += orderList.visibleItems.length;
updateListControls();
}); });
} }
if (paginationButtonPrev) {
paginationButtonPrev.addEventListener('click', e => {
e.preventDefault();
pageCount -= 1;
numberOfcurrentItems -= orderList.visibleItems.length;
const prevItem = orderList.i - itemsPerPage;
prevItem > 0 && orderList.show(prevItem, itemsPerPage);
updateListControls();
});
}
const toggleViewBtn = () => {
viewLess.classList.toggle('d-none');
viewAll.classList.toggle('d-none');
};
if (viewAll) {
viewAll.addEventListener('click', () => {
orderList.show(1, totalItem);
pageQuantity = 1;
pageCount = 1;
numberOfcurrentItems = totalItem;
updateListControls();
toggleViewBtn();
});
}
if (viewLess) {
viewLess.addEventListener('click', () => {
orderList.show(1, itemsPerPage);
pageQuantity = Math.ceil(totalItem / itemsPerPage);
pageCount = 1;
numberOfcurrentItems = orderList.visibleItems.length;
updateListControls();
toggleViewBtn();
});
}
if (options.pagination) {
table.querySelector('.pagination').addEventListener('click', e => {
if (e.target.classList[0] === 'page') {
pageCount = Number(e.target.innerText);
updateListControls();
}
});
}
if (options.filter) {
const { key } = options.filter;
listFilter.addEventListener('change', e => {
orderList.filter(item => {
if (e.target.value === '') {
return true;
}
return item
.values()
[key].toLowerCase()
.includes(e.target.value.toLowerCase());
});
});
}
}
};

View File

@ -42,7 +42,7 @@
<body> <body>
<main class="main" id="top"> <main class="main" id="top">
{% include 'messages.html' %}
{% include 'header.html' %} {% include 'header.html' %}
<div class="content"> <div class="content">
@ -77,6 +77,42 @@
<script src="{% static 'vendors/mapbox-gl/mapbox-gl.js' %}"></script> <script src="{% static 'vendors/mapbox-gl/mapbox-gl.js' %}"></script>
<script src="https://unpkg.com/@turf/turf@6/turf.min.js"></script> <script src="https://unpkg.com/@turf/turf@6/turf.min.js"></script>
<script src="{% static 'vendors/swiper/swiper-bundle.min.js' %}"></script> <script src="{% static 'vendors/swiper/swiper-bundle.min.js' %}"></script>
<script>
{% if messages %}
{% for message in messages %}
const Toast = Swal.mixin({
toast: true,
position: "top-end",
showConfirmButton: false,
timer: 2000,
timerProgressBar: false,
didOpen: (toast) => {
toast.onmouseenter = Swal.stopTimer;
toast.onmouseleave = Swal.resumeTimer;
}
});
Toast.fire({
icon: "{{ message.tags }}",
titleText: "{{ message| safe }}"
});
{% endfor %}
{% endif %}
function notify(tag,msg){
Toast.fire({
icon: tag,
titleText: msg
});
}
</script>
</body> </body>
</html> </html>

View File

@ -0,0 +1,35 @@
{% extends 'base.html' %}
{% block content %}
<h1>Logs for {{ opportunity.deal_name }}</h1>
<div class="table-list" id="opportunityTable">
</div>
<table>
<thead>
<tr>
<th>Action</th>
<th>User</th>
<th>Old Status</th>
<th>New Status</th>
<th>Details</th>
<th>Date</th>
</tr>
</thead>
<tbody>
{% for log in logs %}
<tr>
<td>{{ log.get_action_display }}</td>
<td>{{ log.user }}</td>
<td>{{ log.get_old_status_display }}</td>
<td>{{ log.get_new_status_display }}</td>
<td>{{ log.details }}</td>
<td>{{ log.created_at }}</td>
</tr>
{% empty %}
<tr>
<td colspan="6">No logs found.</td>
</tr>
{% endfor %}
</tbody>
</table>
{% endblock %}

View File

@ -6,17 +6,13 @@
{% block content %} {% block content %}
<section class="pt-5 pb-9"> <section class="pt-5 pb-9">
<div class="container"> <div class="container">
<h2 class="mb-4">{{ _("Customers")|capfirst }}</h2> <h2 class="mb-4">{{ _("Customers")|capfirst }}</h2>
<div class="row g-3 justify-content-between mb-4"> <div class="row g-3 justify-content-between mb-4">
<div class="col-auto"> <div class="col-auto">
<div class="d-md-flex justify-content-between"> <div class="d-md-flex justify-content-between">
<div> <div>
<a href="{% url 'customer_create' %}" class="btn btn-primary me-4"><span class="fas fa-plus me-2"></span>{{ _("Add Customer") }}</a> <a href="{% url 'customer_create' %}" class="btn btn-primary me-4"><span class="fas fa-plus me-2"></span>{{ _("Add Customer") }}</a>
</div> </div>
</div> </div>
</div> </div>
@ -24,12 +20,12 @@
<div class="d-flex"> <div class="d-flex">
<div class="search-box me-2"> <div class="search-box me-2">
<form method="get" class="d-inline-block position-relative"> <form method="get" class="d-inline-block position-relative">
<input name="q" class="form-control search-input search" type="search" placeholder="{{ _('Enter customer name') }}" aria-label="Search" value="{{ request.GET.q }}"/> <div class="input-group">
<span class="fas fa-search search-box-icon"></span> <button type="submit" class="btn btn-phoenix-primary"><span class="fas fa-search search-box-icon"></span></button>
<input name="q" class="form-control search-input search" type="search" placeholder="{{ _('Enter customer name') }}" value="{{ request.GET.q }}"/>
{% if request.GET.q %} {% if request.GET.q %}
<a href="{% url request.resolver_match.view_name %}" class="btn btn-outline-danger ms-1"> <a href="{% url request.resolver_match.view_name %}" class="btn btn-close"></a>
<i class="bi bi-x-lg"></i> </div>
</a>
{% endif %} {% endif %}
</form> </form>
</div> </div>
@ -43,6 +39,7 @@
<table class="table fs-9 mb-0 border-top border-translucent"> <table class="table fs-9 mb-0 border-top border-translucent">
<thead> <thead>
<tr> <tr>
<th></th>
<th class="sort white-space-nowrap align-middle text-uppercase ps-0" scope="col" data-sort="name" style="width:25%;">{{ _("Name")|capfirst }}</th> <th class="sort white-space-nowrap align-middle text-uppercase ps-0" scope="col" data-sort="name" style="width:25%;">{{ _("Name")|capfirst }}</th>
<th class="sort align-middle ps-4 pe-5 text-uppercase border-end border-translucent" scope="col" data-sort="email" style="width:15%;"> <th class="sort align-middle ps-4 pe-5 text-uppercase border-end border-translucent" scope="col" data-sort="email" style="width:15%;">
<div class="d-inline-flex flex-center"> <div class="d-inline-flex flex-center">
@ -73,7 +70,7 @@
{% for customer in customers %} {% for customer in customers %}
<!-- Delete Modal --> <!-- Delete Modal -->
<div class="modal fade" id="deleteModal" <div class="modal fade" id="deleteModal"
data-bs-backdrop="static" data-bs-backdrop="static"
data-bs-keyboard="false" data-bs-keyboard="false"
tabindex="-1" tabindex="-1"
@ -105,7 +102,14 @@
</div> </div>
</div> </div>
<tr class="hover-actions-trigger btn-reveal-trigger position-static"> <tr class="hover-actions-trigger btn-reveal-trigger position-static">
<td>
{% if customer.is_lead %}
<span class="badge badge-phoenix fs-10 badge-phoenix-success">
<span class="badge-label">{{ _("Lead") }}</span>
<span class="ms-1" data-feather="check" style="height:13px;width:13px;"></span>
</span>
{% endif %}
</td>
<td class="name align-middle white-space-nowrap ps-0"> <td class="name align-middle white-space-nowrap ps-0">
<div class="d-flex align-items-center"> <div class="d-flex align-items-center">
<div><a class="fs-8 fw-bold" href="{% url 'customer_detail' customer.id %}">{{ customer.first_name }} {{ customer.middle_name }} {{ customer.last_name }}</a> <div><a class="fs-8 fw-bold" href="{% url 'customer_detail' customer.id %}">{{ customer.first_name }} {{ customer.middle_name }} {{ customer.last_name }}</a>
@ -123,9 +127,13 @@
<td class="align-middle white-space-nowrap text-end pe-0 ps-4"> <td class="align-middle white-space-nowrap text-end pe-0 ps-4">
<div class="btn-reveal-trigger position-static"> <div class="btn-reveal-trigger position-static">
<button class="btn btn-sm dropdown-toggle dropdown-caret-none transition-none btn-reveal fs-10" type="button" data-bs-toggle="dropdown" data-boundary="window" aria-haspopup="true" aria-expanded="false" data-bs-reference="parent"><span class="fas fa-ellipsis-h fs-10"></span></button> <button class="btn btn-sm dropdown-toggle dropdown-caret-none transition-none btn-reveal fs-10" type="button" data-bs-toggle="dropdown" data-boundary="window" aria-haspopup="true" aria-expanded="false" data-bs-reference="parent"><span class="fas fa-ellipsis-h fs-10"></span></button>
<div class="dropdown-menu dropdown-menu-end py-2"><a href="{% url 'customer_update' customer.id %}" class="dropdown-item text-success-dark"> <div class="dropdown-menu dropdown-menu-end py-2">
{% trans "Edit" %} <a href="{% url 'customer_update' customer.id %}" class="dropdown-item text-success-dark">{% trans "Edit" %}</a>
</a> {% if customer.is_lead %}
<a href="{% url 'create_opportunity' customer.pk %}" class="dropdown-item text-warning-dark">{{_("Opportunity")}}</a>
{% else %}
<a href="{% url 'create_lead' customer.pk %}" class="dropdown-item text-success-dark">{{ _("Mark as Lead")}}</a>
{% endif %}
<div class="dropdown-divider"></div><button class="dropdown-item text-danger" data-bs-toggle="modal" data-bs-target="#deleteModal">{% trans "Delete" %}</button> <div class="dropdown-divider"></div><button class="dropdown-item text-danger" data-bs-toggle="modal" data-bs-target="#deleteModal">{% trans "Delete" %}</button>
</div> </div>
</div> </div>

View File

@ -52,11 +52,7 @@
</div> </div>
<div class="col-auto"> <div class="col-auto">
<a href="{% url 'customer_update' customer.pk %}" class="btn btn-phoenix-warning"><span class="fa-solid fa-pen-to-square me-2"></span>{{_("Update")}}</a> <a href="{% url 'customer_update' customer.pk %}" class="btn btn-phoenix-warning"><span class="fa-solid fa-pen-to-square me-2"></span>{{_("Update")}}</a>
{% if not customer.is_lead %}
<a href="{% url 'create_lead' customer.pk %}" class="btn btn-phoenix-success"><span class="fa-solid far fa-plus-square me-2"></span>{{ _("Mark as Lead")}}</a>
{% else %}
<a href="{% url 'create_opportunity' customer.pk %}" class="btn btn-phoenix-primary"><span class="fa-solid far fa-plus-square me-2"></span>{{_("Opportunity")}}</a>
{% endif %}
</div> </div>
</div> </div>
</div> </div>

View File

@ -1,4 +1,5 @@
{% load i18n %} {% load i18n %}
<footer class="footer position-absolute"> <footer class="footer position-absolute">
<div class="row g-0 justify-content-between align-items-center h-100"> <div class="row g-0 justify-content-between align-items-center h-100">
<div class="col-12 col-sm-auto text-center"> <div class="col-12 col-sm-auto text-center">

View File

@ -1,197 +1,248 @@
{% load i18n %} {% load i18n static %}
{% load static %}
<nav class="navbar navbar-vertical navbar-expand-lg">
<div class="collapse navbar-collapse" id="navbarVerticalCollapse">
<!-- scrollbar removed-->
<div class="navbar-vertical-content">
<ul class="navbar-nav flex-column" id="navbarVerticalNav">
<li class="nav-item">
<!-- parent pages-->
<div class="nav-item-wrapper"><a class="nav-link dropdown-indicator label-1" href="#nv-dashboards" role="button" data-bs-toggle="collapse" aria-expanded="false" aria-controls="nv-dashboards">
<div class="d-flex align-items-center">
<div class="dropdown-indicator-icon-wrapper"><span class="fas fa-caret-right dropdown-indicator-icon"></span></div><span class="nav-link-icon"><span data-feather="pie-chart"></span></span><span class="nav-link-text">Dashboards</span>
</div>
</a>
<div class="parent-wrapper label-1">
<ul class="nav collapse parent" data-bs-parent="#navbarVerticalCollapse" id="nv-dashboards">
<li class="collapsed-nav-item-title d-none">Dashboards
</li>
<li class="nav-item"><a class="nav-link" href="{% url 'accounting' %}">
<div class="d-flex align-items-center"><span class="nav-link-text">Accounting</span>
</div>
</a>
</li>
<li class="nav-item"><a class="nav-link" href="#"> <nav class="navbar navbar-vertical navbar-expand-lg">
<div class="d-flex align-items-center"><span class="nav-link-text">Inventory</span> <div class="collapse navbar-collapse" id="navbarVerticalCollapse">
</div> <!-- scrollbar removed-->
</a> <div class="navbar-vertical-content">
</li> <ul class="navbar-nav flex-column" id="navbarVerticalNav">
<li class="nav-item"><a class="nav-link" href="#"> <li class="nav-item">
<div class="d-flex align-items-center"><span class="nav-link-text">Sales</span> <!-- parent pages-->
</div> <div class="nav-item-wrapper">
</a> <a class="nav-link dropdown-indicator label-1" href="#nv-dashboards" role="button" data-bs-toggle="collapse" aria-expanded="false" aria-controls="nv-dashboards">
</li>
<li class="nav-item"><a class="nav-link" href="#">
<div class="d-flex align-items-center"><span class="nav-link-text">Leads</span>
</div>
</a>
</li>
</ul>
</div>
</div>
</li>
<hr class="my-0" />
<li class="nav-item">
<!-- label-->
<p class="navbar-vertical-label">Apps</p>
<hr class="navbar-vertical-line" />
<!-- parent pages-->
<div class="nav-item-wrapper"><a class="nav-link dropdown-indicator label-1" href="#nv-inventory" role="button" data-bs-toggle="collapse" aria-expanded="false" aria-controls="nv-inventory">
<div class="d-flex align-items-center">
<div class="dropdown-indicator-icon-wrapper"><span class="fas fa-caret-right dropdown-indicator-icon"></span></div><span class="nav-link-icon"><span class="fas fa-warehouse"></span></span><span class="nav-link-text">{% trans "Inventory"|capfirst %}</span>
</div>
</a>
<div class="parent-wrapper label-1">
<ul class="nav collapse parent" data-bs-parent="#navbarVerticalCollapse" id="nv-inventory">
<li class="collapsed-nav-item-title d-none">{% trans "Inventory"|capfirst %}
</li>
<li class="nav-item"><a class="nav-link" href="{% url 'car_add' %}">
<div class="d-flex align-items-center"><span class="nav-link-icon"><span class="fas fa-plus-circle"></span></span><span class="nav-link-text">{% trans "add car"|capfirst %}</span>
</div>
</a>
<!-- more inner pages-->
</li>
<li class="nav-item"><a class="nav-link" href="{% url 'inventory_stats' %}">
<div class="d-flex align-items-center"><span class="nav-link-icon"><span class="fas fa-car-side"></span></span><span class="nav-link-text">{% trans 'Cars'|capfirst %}</span>
</div>
</a>
<!-- more inner pages-->
</li>
</ul>
</div>
</div>
<!-- parent pages-->
<!-- parent pages-->
<!-- parent pages-->
<div class="nav-item-wrapper"><a class="nav-link dropdown-indicator label-1" href="#nv-sales" role="button" data-bs-toggle="collapse" aria-expanded="false" aria-controls="nv-sales">
<div class="d-flex align-items-center">
<div class="dropdown-indicator-icon-wrapper"><span class="fas fa-caret-right dropdown-indicator-icon"></span></div><span class="nav-link-icon"><span data-feather="shopping-cart"></span></span><span class="nav-link-text">{% trans 'sales'|capfirst %}</span>
</div>
</a>
<div class="parent-wrapper label-1">
<ul class="nav collapse parent" data-bs-parent="#navbarVerticalCollapse" id="nv-sales">
<li class="collapsed-nav-item-title d-none">{% trans 'sales'|capfirst %}
</li>
<li class="nav-item"><a class="nav-link" href="{% url 'vendor_list' %}">
<div class="d-flex align-items-center"><span class="nav-link-icon"><span data-feather="package"></span></span><span class="nav-link-text">{% trans 'vendors'|capfirst %}</span>
</div>
</a>
</li>
<li class="nav-item"><a class="nav-link" href="{% url 'customer_list' %}">
<div class="d-flex align-items-center"><span class="nav-link-icon"><span data-feather="users"></span></span><span class="nav-link-text">{% trans 'customers'|capfirst %}</span>
</div>
</a>
</li>
<li class="nav-item"><a class="nav-link" href="{% url 'organization_list' %}">
<div class="d-flex align-items-center"><span class="nav-link-icon"><span data-feather="activity"></span></span><span class="nav-link-text">{% trans "Organizations"|capfirst %}</span>
</div>
</a>
<!-- more inner pages-->
</li>
<li class="nav-item"><a class="nav-link" href="{% url 'representative_list' %}">
<div class="d-flex align-items-center"><span class="nav-link-icon"><span class="fas fa-users-cog"></span></span><span class="nav-link-text">{% trans "Representatives"|capfirst %}</span>
</div>
</a>
<!-- more inner pages-->
</li>
<li class="nav-item"><a class="nav-link" href="{% url 'estimate_create' %}">
<div class="d-flex align-items-center"><span class="nav-link-icon"><span class="fas fa-list-ul"></span></span><span class="nav-link-text">{% trans "create quotation"|capfirst %}</span>
</div>
</a>
<!-- more inner pages-->
</li>
<li class="nav-item"><a class="nav-link" href="{% url 'estimate_list' %}">
<div class="d-flex align-items-center"><span class="nav-link-icon"><span class="fas fa-clipboard-list"></span></span><span class="nav-link-text">{% trans "quotations"|capfirst %}</span>
</div>
</a>
<!-- more inner pages-->
</li>
<li class="nav-item"><a class="nav-link" href="#">
<div class="d-flex align-items-center"><span class="nav-link-icon"><span class="fas fa-cart-plus"></span></span><span class="nav-link-text">{% trans "orders"|capfirst %}</span>
</div>
</a>
<!-- more inner pages-->
</li>
<li class="nav-item"><a class="nav-link" href="{% url 'invoice_list' %}">
<div class="d-flex align-items-center"><span class="nav-link-icon"><span class="fas fa-file-invoice"></span></span><span class="nav-link-text">{% trans "invoices"|capfirst %}</span>
</div>
</a>
<!-- more inner pages-->
</li>
<li class="nav-item"><a class="nav-link" href="{% url 'payment_list' %}">
<div class="d-flex align-items-center"><span class="nav-link-icon"><span class="fas fa-money-check"></span></span><span class="nav-link-text">{% trans "payments"|capfirst %}</span>
</div>
</a>
<!-- more inner pages-->
</li>
</ul>
</div>
</div>
<!--Add Above -->
</li>
</ul>
</div>
</div>
<div class="navbar-vertical-footer">
<button class="btn navbar-vertical-toggle border-0 fw-semibold w-100 white-space-nowrap d-flex align-items-center"><span class="uil uil-left-arrow-to-left fs-8"></span><span class="uil uil-arrow-from-right fs-8"></span><span class="navbar-vertical-footer-text ms-2">Collapsed View</span></button>
</div>
</nav>
<nav class="navbar navbar-top fixed-top navbar-expand" id="navbarDefault">
<div class="collapse navbar-collapse justify-content-between">
<div class="navbar-logo">
<button class="btn navbar-toggler navbar-toggler-humburger-icon hover-bg-transparent" type="button" data-bs-toggle="collapse" data-bs-target="#navbarVerticalCollapse" aria-controls="navbarVerticalCollapse" aria-expanded="false" aria-label="Toggle Navigation"><span class="navbar-toggle-icon"><span class="toggle-line"></span></span></button>
<a class="navbar-brand me-1 me-sm-3" href="{% url 'landing_page' %}">
<div class="d-flex align-items-center"> <div class="d-flex align-items-center">
<img class="logo-img d-dark-none" src="{% static 'images/logos/logo-d.png' %}" alt="haikal" width="27" /> <div class="dropdown-indicator-icon-wrapper"><span class="fas fa-caret-right dropdown-indicator-icon"></span></div>
<img class="logo-img d-light-none" src="{% static 'images/logos/logo.png' %}" alt="haikal" width="27" /> <span class="nav-link-icon"><span data-feather="pie-chart"></span></span><span class="nav-link-text">Dashboards</span>
<h5 class="logo-text ms-2 d-none d-sm-block">{% trans 'Haikal' %}</h5>
</div> </div>
</a> </a>
<div class="parent-wrapper label-1">
<ul class="nav collapse parent" data-bs-parent="#navbarVerticalCollapse" id="nv-dashboards">
<li class="collapsed-nav-item-title d-none">Dashboards</li>
<li class="nav-item">
<a class="nav-link" href="{% url 'accounting' %}">
<div class="d-flex align-items-center"><span class="nav-link-text">Accounting</span></div>
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">
<div class="d-flex align-items-center"><span class="nav-link-text">Inventory</span></div>
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">
<div class="d-flex align-items-center"><span class="nav-link-text">Sales</span></div>
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">
<div class="d-flex align-items-center"><span class="nav-link-text">Leads</span></div>
</a>
</li>
</ul>
</div>
</div> </div>
</li>
<hr class="my-0" />
<li class="nav-item">
<!-- label-->
<p class="navbar-vertical-label">Apps</p>
<hr class="navbar-vertical-line" />
<!-- parent pages-->
<div class="nav-item-wrapper">
<a class="nav-link dropdown-indicator label-1" href="#nv-inventory" role="button" data-bs-toggle="collapse" aria-expanded="false" aria-controls="nv-inventory">
<div class="d-flex align-items-center">
<div class="dropdown-indicator-icon-wrapper"><span class="fas fa-caret-right dropdown-indicator-icon"></span></div>
<span class="nav-link-icon"><span class="fas fa-warehouse"></span></span><span class="nav-link-text">{% trans "Inventory"|capfirst %}</span>
</div>
</a>
<div class="parent-wrapper label-1">
<ul class="nav collapse parent" data-bs-parent="#navbarVerticalCollapse" id="nv-inventory">
<li class="collapsed-nav-item-title d-none">{% trans "Inventory"|capfirst %}</li>
<li class="nav-item">
<a class="nav-link" href="{% url 'car_add' %}">
<div class="d-flex align-items-center">
<span class="nav-link-icon"><span class="fas fa-plus-circle"></span></span><span class="nav-link-text">{% trans "add car"|capfirst %}</span>
</div>
</a>
<!-- more inner pages-->
</li>
<li class="nav-item">
<a class="nav-link" href="{% url 'inventory_stats' %}">
<div class="d-flex align-items-center">
<span class="nav-link-icon"><span class="fas fa-car-side"></span></span><span class="nav-link-text">{% trans 'Cars'|capfirst %}</span>
</div>
</a>
<!-- more inner pages-->
</li>
</ul>
</div>
</div>
<!-- parent pages-->
<ul class="navbar-nav navbar-nav-icons flex-row"> <!-- parent pages-->
<li class="nav-item">
<div class="theme-control-toggle fa-icon-wait px-2">
<input class="form-check-input ms-0 theme-control-toggle-input" type="checkbox" data-theme-control="phoenixTheme" value="dark" id="themeControlToggle" /> <!-- parent pages-->
<label class="mb-0 theme-control-toggle-label theme-control-toggle-light" for="themeControlToggle" data-bs-theme-value="light" data-bs-toggle="tooltip" data-bs-placement="left" data-bs-title="Switch theme" style="height:32px;width:32px;"><span class="icon" data-feather="moon"></span></label> <div class="nav-item-wrapper">
<label class="mb-0 theme-control-toggle-label theme-control-toggle-dark" for="themeControlToggle" data-bs-theme-value="dark" data-bs-toggle="tooltip" data-bs-placement="left" data-bs-title="Switch theme" style="height:32px;width:32px;"><span class="icon" data-feather="sun"></span></label> <a class="nav-link dropdown-indicator label-1" href="#nv-sales" role="button" data-bs-toggle="collapse" aria-expanded="false" aria-controls="nv-sales">
</div> <div class="d-flex align-items-center">
</li> <div class="dropdown-indicator-icon-wrapper"><span class="fas fa-caret-right dropdown-indicator-icon"></span></div>
<li class="nav-item dropdown"> <span class="nav-link-icon"><span data-feather="shopping-cart"></span></span><span class="nav-link-text">{% trans 'sales'|capfirst %}</span>
<a class="nav-link" href="#" style="min-width: 2.25rem" role="button" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false" data-bs-auto-close="outside"><span class="d-block" style="height:20px;width:20px;"><span data-feather="bell" style="height:20px;width:20px;"></span></span></a> </div>
</a>
{% include 'notifications.html' %} <div class="parent-wrapper label-1">
</li> <ul class="nav collapse parent" data-bs-parent="#navbarVerticalCollapse" id="nv-sales">
<li class="nav-item dropdown"> <li class="collapsed-nav-item-title d-none">{% trans 'sales'|capfirst %}</li>
<a class="nav-link dropdown-toggle" href="#" id="languageDropdown" role="button" data-bs-toggle="dropdown" aria-expanded="false" data-bs-auto-close="outside" aria-haspopup="true"> <li class="nav-item">
{% if request.LANGUAGE_CODE == 'ar' %} <a class="nav-link" href="{% url 'vendor_list' %}">
<span class="me-1 text-body" data-feather="globe"></span><span class="ms-1">اللغة</span> <div class="d-flex align-items-center">
{% else %} <span class="nav-link-icon"><span data-feather="package"></span></span><span class="nav-link-text">{% trans 'vendors'|capfirst %}</span>
<span class="me-1 text-body" data-feather="globe"></span><span class="ms-1">Language</span> </div>
{% endif %} </a>
</a> </li>
<div class="dropdown-menu dropdown-menu-end navbar-dropdown-caret py-0 dropdown-profile shadow border" aria-labelledby="languageDropdown"> <li class="nav-item">
<div class="card position-relative border-0"> <a class="nav-link" href="{% url 'customer_list' %}">
<div class="card-body p-0"> <div class="d-flex align-items-center">
<span class="nav-link-icon"><span data-feather="users"></span></span><span class="nav-link-text">{% trans 'customers'|capfirst %}</span>
</div>
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="{% url 'organization_list' %}">
<div class="d-flex align-items-center">
<span class="nav-link-icon"><span data-feather="activity"></span></span><span class="nav-link-text">{% trans "Organizations"|capfirst %}</span>
</div>
</a>
<!-- more inner pages-->
</li>
<li class="nav-item">
<a class="nav-link" href="{% url 'representative_list' %}">
<div class="d-flex align-items-center">
<span class="nav-link-icon"><span class="fas fa-users-cog"></span></span><span class="nav-link-text">{% trans "Representatives"|capfirst %}</span>
</div>
</a>
<!-- more inner pages-->
</li>
<li class="nav-item">
<a class="nav-link" href="{% url 'estimate_create' %}">
<div class="d-flex align-items-center">
<span class="nav-link-icon"><span class="fas fa-list-ul"></span></span><span class="nav-link-text">{% trans "create quotation"|capfirst %}</span>
</div>
</a>
<!-- more inner pages-->
</li>
<li class="nav-item">
<a class="nav-link" href="{% url 'estimate_list' %}">
<div class="d-flex align-items-center">
<span class="nav-link-icon"><span class="fas fa-clipboard-list"></span></span><span class="nav-link-text">{% trans "quotations"|capfirst %}</span>
</div>
</a>
<!-- more inner pages-->
</li>
<li class="nav-item">
<a class="nav-link" href="#">
<div class="d-flex align-items-center">
<span class="nav-link-icon"><span class="fas fa-cart-plus"></span></span><span class="nav-link-text">{% trans "orders"|capfirst %}</span>
</div>
</a>
<!-- more inner pages-->
</li>
<li class="nav-item">
<a class="nav-link" href="{% url 'invoice_list' %}">
<div class="d-flex align-items-center">
<span class="nav-link-icon"><span class="fas fa-file-invoice"></span></span><span class="nav-link-text">{% trans "invoices"|capfirst %}</span>
</div>
</a>
<!-- more inner pages-->
</li>
<li class="nav-item">
<a class="nav-link" href="{% url 'payment_list' %}">
<div class="d-flex align-items-center">
<span class="nav-link-icon"><span class="fas fa-money-check"></span></span><span class="nav-link-text">{% trans "payments"|capfirst %}</span>
</div>
</a>
<!-- more inner pages-->
</li>
</ul>
</div>
</div>
<!--Add Above -->
</li>
</ul>
</div>
</div>
<div class="navbar-vertical-footer">
<button class="btn navbar-vertical-toggle border-0 fw-semibold w-100 white-space-nowrap d-flex align-items-center">
<span class="uil uil-left-arrow-to-left fs-8"></span><span class="uil uil-arrow-from-right fs-8"></span><span class="navbar-vertical-footer-text ms-2">Collapsed View</span>
</button>
</div>
</nav>
<nav class="navbar navbar-top fixed-top navbar-expand" id="navbarDefault">
<div class="collapse navbar-collapse justify-content-between">
<div class="navbar-logo">
<button
class="btn navbar-toggler navbar-toggler-humburger-icon hover-bg-transparent"
type="button"
data-bs-toggle="collapse"
data-bs-target="#navbarVerticalCollapse"
aria-controls="navbarVerticalCollapse"
aria-expanded="false"
aria-label="Toggle Navigation"
>
<span class="navbar-toggle-icon"><span class="toggle-line"></span></span>
</button>
<a class="navbar-brand me-1 me-sm-3" href="{% url 'landing_page' %}">
<div class="d-flex align-items-center">
<img class="logo-img d-dark-none" src="{% static 'images/logos/logo-d.png' %}" alt="haikal" width="27" />
<img class="logo-img d-light-none" src="{% static 'images/logos/logo.png' %}" alt="haikal" width="27" />
<h5 class="logo-text ms-2 d-none d-sm-block">{% trans 'Haikal' %}</h5>
</div>
</a>
</div>
<ul class="navbar-nav navbar-nav-icons flex-row">
<li class="nav-item">
<div class="theme-control-toggle fa-icon-wait px-2">
<input class="form-check-input ms-0 theme-control-toggle-input" type="checkbox" data-theme-control="phoenixTheme" value="dark" id="themeControlToggle" />
<label
class="mb-0 theme-control-toggle-label theme-control-toggle-light"
for="themeControlToggle"
data-bs-theme-value="light"
data-bs-toggle="tooltip"
data-bs-placement="left"
data-bs-title="Switch theme"
style="height: 32px; width: 32px;"
>
<span class="icon" data-feather="moon"></span>
</label>
<label
class="mb-0 theme-control-toggle-label theme-control-toggle-dark"
for="themeControlToggle"
data-bs-theme-value="dark"
data-bs-toggle="tooltip"
data-bs-placement="left"
data-bs-title="Switch theme"
style="height: 32px; width: 32px;"
>
<span class="icon" data-feather="sun"></span>
</label>
</div>
</li>
<li class="nav-item dropdown">
<a class="nav-link" href="#" style="min-width: 2.25rem;" role="button" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false" data-bs-auto-close="outside">
<span class="d-block" style="height: 20px; width: 20px;"><span data-feather="bell" style="height: 20px; width: 20px;"></span></span>
</a>
</li>
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" id="languageDropdown" role="button" data-bs-toggle="dropdown" aria-expanded="false" data-bs-auto-close="outside" aria-haspopup="true">
{% if request.LANGUAGE_CODE == 'ar' %}
<span class="me-1 text-body" data-feather="globe"></span><span class="ms-1">اللغة</span>
{% else %}
<span class="me-1 text-body" data-feather="globe"></span><span class="ms-1">Language</span>
{% endif %}
</a>
<div class="dropdown-menu dropdown-menu-end navbar-dropdown-caret py-0 dropdown-profile shadow border" aria-labelledby="languageDropdown">
<div class="card position-relative border-0">
<div class="card-body p-0">
<ul class="nav d-flex flex-column mb-2 pb-1"> <ul class="nav d-flex flex-column mb-2 pb-1">
<li> <li>
<a class="dropdown-item fw-lighter" href="{% url 'switch_language' %}?language=en">English</a> <a class="dropdown-item fw-lighter" href="{% url 'switch_language' %}?language=en">English</a>
@ -200,58 +251,82 @@
<a class="dropdown-item fw-lighter" href="{% url 'switch_language' %}?language=ar">العربية</a> <a class="dropdown-item fw-lighter" href="{% url 'switch_language' %}?language=ar">العربية</a>
</li> </li>
</ul> </ul>
</div> </div>
</div>
</div>
</div>
</li>
{% if user.is_authenticated and user.dealer or user.staff%}
<li class="nav-item dropdown"><a class="nav-link lh-1 pe-0" id="navbarDropdownUser" role="button" data-bs-toggle="dropdown" data-bs-auto-close="outside" aria-haspopup="true" aria-expanded="false">
<div class="avatar avatar-l ">
{% if user.dealer.logo %}
<img class="rounded-circle " src="{{ user.dealer.logo.url }}" alt="" />
{% endif %}
</div>
</a>
<div class="dropdown-menu dropdown-menu-end navbar-dropdown-caret py-0 dropdown-profile shadow border" aria-labelledby="navbarDropdownUser">
<div class="card position-relative border-0">
<div class="card-body p-0">
<div class="text-center pt-4 pb-3">
<div class="avatar avatar-xl ">
{% if user.dealer.logo %}
<img class="rounded-circle " src="{{ user.dealer.logo.url }}" alt="" />
{% endif %}
</div>
<h6 class="mt-2 text-body-emphasis">{{ user.dealer.get_local_name }}</h6>
</div>
</div>
<div class="overflow-auto scrollbar" style="height: 10rem;">
<ul class="nav d-flex flex-column mb-2 pb-1">
<li class="nav-item"><a class="nav-link px-3 d-block" href="{% url 'dealer_detail' user.dealer.pk %}"> <span class="me-2 text-body align-bottom" data-feather="user"></span><span>{% translate 'profile'|capfirst %}</span></a></li>
<li class="nav-item"><a class="nav-link px-3 d-block" href="{% url 'user_list' %}"><span class="me-2 text-body align-bottom" data-feather="users"></span>{{ _("Staff") }}</a></li>
<li class="nav-item"><a class="nav-link px-3 d-block" href="{% url 'dealer_activity' %}"> <span class="me-2 text-body align-bottom" data-feather="lock"></span>{{ _("Activity") }}</a></li>
<li class="nav-item"><a class="nav-link px-3 d-block" href="#!"> <span class="me-2 text-body align-bottom" data-feather="settings"></span>Settings &amp; Privacy </a></li>
<li class="nav-item"><a class="nav-link px-3 d-block" href="#!"> <span class="me-2 text-body align-bottom" data-feather="help-circle"></span>Help Center</a></li>
<li class="nav-item"><a class="nav-link px-3 d-block" href="#!"> Language</a></li>
</ul>
</div>
<div class="card-footer p-0 border-top border-translucent">
<ul class="nav d-flex flex-column my-3">
<li class="nav-item"><a class="nav-link px-3 d-block" href="#!"> <span class="me-2 text-body align-bottom" data-feather="user-plus"></span>Add another account</a></li>
</ul>
<hr />
<div class="px-3"> <a class="btn btn-phoenix-secondary d-flex flex-center w-100" href="{% url 'account_logout' %}"> <span class="me-2" data-feather="log-out"> </span>{% trans 'Sign Out' %}</a></div>
<div class="my-2 text-center fw-bold fs-10 text-body-quaternary"><a class="text-body-quaternary me-1" href="#!">Privacy policy</a>&bull;<a class="text-body-quaternary mx-1" href="#!">Terms</a>&bull;<a class="text-body-quaternary ms-1" href="#!">Cookies</a></div>
{% else %}
<div class="px-3"> <a class="btn btn-phoenix-secondary d-flex flex-center w-100" href="{% url 'account_login' %}"> <span class="me-2" data-feather="log-in"> </span>{% trans 'Sign In' %}</a></div>
<div class="px-3"> <a class="btn btn-phoenix-secondary d-flex flex-center w-100" href="{% url 'account_signup' %}"> <span class="me-2" data-feather="user-plus"> </span>{% trans 'Sign Up' %}</a></div>
{% endif %}
</div>
</div>
</div>
</li>
</ul>
</div> </div>
</nav> </li>
{% if user.is_authenticated and user.dealer or user.staff %}
<li class="nav-item dropdown">
<a class="nav-link lh-1 pe-0" id="navbarDropdownUser" role="button" data-bs-toggle="dropdown" data-bs-auto-close="outside" aria-haspopup="true" aria-expanded="false">
<div class="avatar avatar-l">
{% if user.dealer.logo %}
<img class="rounded-circle" src="{{ user.dealer.logo.url }}" alt="" />
{% endif %}
</div>
</a>
<div class="dropdown-menu dropdown-menu-end navbar-dropdown-caret py-0 dropdown-profile shadow border" aria-labelledby="navbarDropdownUser">
<div class="card position-relative border-0">
<div class="card-body p-0">
<div class="text-center pt-4 pb-3">
<div class="avatar avatar-xl">
{% if user.dealer.logo %}
<img class="rounded-circle" src="{{ user.dealer.logo.url }}" alt="" />
{% endif %}
</div>
<h6 class="mt-2 text-body-emphasis">{{ user.dealer.get_local_name }}</h6>
</div>
</div>
<div class="overflow-auto scrollbar" style="height: 10rem;">
<ul class="nav d-flex flex-column mb-2 pb-1">
{% if user.dealer %}
<li class="nav-item">
<a class="nav-link px-3 d-block" href="{% url 'dealer_detail' user.dealer.pk %}"> <span class="me-2 text-body align-bottom" data-feather="user"></span><span>{% translate 'profile'|capfirst %}</span></a>
</li>
{% else %}
<li class="nav-item">
<a class="nav-link px-3 d-block" href="{% url 'user_detail' user.staff.pk %}"> <span class="me-2 text-body align-bottom" data-feather="user"></span><span>{% translate 'profile'|capfirst %}</span></a>
</li>
{% endif %}
<li class="nav-item">
<a class="nav-link px-3 d-block" href="{% url 'user_list' %}"><span class="me-2 text-body align-bottom" data-feather="users"></span>{{ _("Staff") }}</a>
</li>
<li class="nav-item">
<a class="nav-link px-3 d-block" href="{% url 'dealer_activity' %}"> <span class="me-2 text-body align-bottom" data-feather="lock"></span>{{ _("Activity") }}</a>
</li>
<li class="nav-item">
<a class="nav-link px-3 d-block" href="#!"> <span class="me-2 text-body align-bottom" data-feather="settings"></span>Settings &amp; Privacy </a>
</li>
<li class="nav-item">
<a class="nav-link px-3 d-block" href="#!"> <span class="me-2 text-body align-bottom" data-feather="help-circle"></span>Help Center</a>
</li>
<li class="nav-item"><a class="nav-link px-3 d-block" href="#!"> Language</a></li>
</ul>
</div>
<div class="card-footer p-0 border-top border-translucent">
<ul class="nav d-flex flex-column my-3">
<li class="nav-item">
<a class="nav-link px-3 d-block" href="#!"> <span class="me-2 text-body align-bottom" data-feather="user-plus"></span>Add another account</a>
</li>
</ul>
<hr />
<div class="px-3">
<a class="btn btn-phoenix-secondary d-flex flex-center w-100" href="{% url 'account_logout' %}"> <span class="me-2" data-feather="log-out"> </span>{% trans 'Sign Out' %}</a>
</div>
<div class="my-2 text-center fw-bold fs-10 text-body-quaternary">
<a class="text-body-quaternary me-1" href="#!">Privacy policy</a>&bull;<a class="text-body-quaternary mx-1" href="#!">Terms</a>&bull;<a class="text-body-quaternary ms-1" href="#!">Cookies</a>
</div>
{% else %}
<div class="px-3">
<a class="btn btn-phoenix-secondary d-flex flex-center w-100" href="{% url 'account_login' %}"> <span class="me-2" data-feather="log-in"> </span>{% trans 'Sign In' %}</a>
</div>
<div class="px-3">
<a class="btn btn-phoenix-secondary d-flex flex-center w-100" href="{% url 'account_signup' %}"> <span class="me-2" data-feather="user-plus"> </span>{% trans 'Sign Up' %}</a>
</div>
{% endif %}
</div>
</div>
</div>
</li>
</ul>
</div>
</nav>

View File

@ -10,7 +10,7 @@
height: 32px; height: 32px;
border-radius: 50px; border-radius: 50px;
border-style: solid; border-style: solid;
border-color: #000; border-color: #fff;
} }
</style> </style>
<div class="container"> <div class="container">
@ -43,15 +43,15 @@
</div> </div>
<div class="modal-footer"> <div class="modal-footer">
<button type="button" <button type="button"
class="btn btn-sm btn-danger" class="btn btn-sm btn-phoenix-danger"
data-bs-dismiss="modal"> data-bs-dismiss="modal">
{% trans 'No' %} {% trans 'No' %}
</button> </button>
<form method="POST" action="{% url 'reserve_car' car.id %}" class="d-inline"> <form method="POST" action="{% url 'reserve_car' car.id %}" class="d-inline">
{% csrf_token %} {% csrf_token %}
<button type="submit" class="btn btn-success btn-sm">{% trans "Yes" %}</button> <button type="submit" class="btn btn-phoenix-success btn-sm">{% trans "Yes" %}</button>
</form> </form>
</div> </div>
</div> </div>
</div> </div>
@ -70,7 +70,7 @@
<div id="specificationsContent"></div> <div id="specificationsContent"></div>
</div> </div>
<div class="modal-footer"> <div class="modal-footer">
<button class="btn btn-outline-primary" type="button" data-bs-dismiss="modal">{% trans 'Close' %}</button> <button class="btn btn-phoenix-primary" type="button" data-bs-dismiss="modal">{% trans 'Close' %}</button>
</div> </div>
</div> </div>
</div> </div>
@ -85,91 +85,79 @@
<div class="card rounded shadow d-flex align-content-center"> <div class="card rounded shadow d-flex align-content-center">
<div class="card overflow-hidden m-3 " style="max-width:25rem;"> <p class="card-header rounded-top fw-bold">{% trans 'Car Details' %}</p>
<img class="card-img-top shadow-info" src="{% static 'images/generic/2022-lincoln-corsair.jpg' %}" alt="...">
<div class="card-img-overlay d-flex align-items-end">
<div>
<h4 class="card-title">{{ car.year }} - {{ car.id_car_make.get_local_name }}</h4>
<p class="card-text">{{ car.id_car_model.get_local_name }} - {{ car.id_car_serie.name }} - {{ car.id_car_trim.name }}</p>
</div>
</div>
</div>
<div class="card-body"> <div class="card-body">
<div class="table-responsive">
<table class="table fs-9 mb-0"> <table class="table fs-9 mb-0">
<tr> <tr>
<th>{% trans "VIN" %}</th> <th>{% trans "VIN" %}</th>
<td>{{ car.vin }}</td> <td>{{ car.vin }}</td>
</tr> </tr>
<tr> <tr>
<th>{% trans "year" %}</th> <th>{% trans "year"|capfirst %}</th>
<td>{{ car.year }}</td> <td>{{ car.year }}</td>
</tr> </tr>
<tr> <tr>
<th>{% trans "make" %}</th> <th>{% trans "make"|capfirst %}</th>
<td>{{ car.id_car_make.get_local_name }}</td> <td>{{ car.id_car_make.get_local_name }}</td>
</tr> </tr>
<tr> <tr>
<th>{% trans "model" %}</th> <th>{% trans "model"|capfirst %}</th>
<td>{{ car.id_car_model.get_local_name }}</td> <td>{{ car.id_car_model.get_local_name }}</td>
</tr> </tr>
<tr> <tr>
<th>{% trans "series" %}</th> <th>{% trans "series"|capfirst %}</th>
<td>{{ car.id_car_serie.name }}</td> <td>{{ car.id_car_serie.name }}</td>
</tr> </tr>
<tr> <tr>
<th>{% trans "trim" %}</th> <th>{% trans "trim"|capfirst %}</th>
<td>{{ car.id_car_trim.name }}</td> <td>{{ car.id_car_trim.name }}</td>
</tr> </tr>
<tr> <tr>
<th>{% trans "Status" %}</th> <th>{% trans "Status"|capfirst %}</th>
<td>{{ car.get_status_display }}</td> <td>{{ car.get_status_display }}</td>
</tr> </tr>
<tr> <tr>
<th>{% trans "Stock Type" %}</th> <th>{% trans "Stock Type"|capfirst %}</th>
<td>{{ car.get_stock_type_display }}</td> <td>{{ car.get_stock_type_display }}</td>
</tr> </tr>
<tr> <tr>
<th>{% trans "Mileage" %}</th> <th>{% trans "Mileage"|capfirst %}</th>
<td>{{ car.mileage }}</td> <td>{{ car.mileage }}</td>
</tr> </tr>
<tr> <tr>
<th>{% trans "Receiving Date" %}</th> <th>{% trans "Receiving Date"|capfirst %}</th>
<td>{{ car.receiving_date|timesince }}</td> <td>{{ car.receiving_date|timesince }}</td>
</tr> </tr>
{% if car.branch %} {% if car.vendor %}
<tr> <tr>
<th>{% trans "Branch" %}</th> <th>{% trans "Vendor"|capfirst %}</th>
<td>{{ car.branch.get_local_name }}</td>
</tr>
{% endif %} {% if car.vendor %}
<tr>
<th>{% trans "Vendor" %}</th>
<td>{{ car.vendor.get_local_name }}</td> <td>{{ car.vendor.get_local_name }}</td>
</tr> </tr>
{% endif %} {% endif %}
<tr> <tr>
<th>{% trans "Remarks" %}</th> <th>{% trans "Remarks"|capfirst %}</th>
<td>{{ car.remarks }}</td> <td>{{ car.remarks }}</td>
</tr> </tr>
<tr> <tr>
<th>{% trans 'specifications' %}</th> <th>{% trans 'specifications'|capfirst %}</th>
<td> <td>
<button type="button" <button type="button"
class="btn btn-primary btn-sm" class="btn btn-phoenix-primary btn-sm"
id="specification-btn" id="specification-btn"
data-bs-toggle="modal" data-bs-toggle="modal"
data-bs-target="#specificationsModal"> data-bs-target="#specificationsModal">
{% trans 'view' %} {% trans 'view'|capfirst %}
</button> </button>
</td> </td>
</tr> </tr>
{% if car.custom_cards %} {% if car.custom_cards %}
<tr> <tr>
<th>{% trans "Custom Number" %}</th> <th>{% trans "Custom Number"|capfirst %}</th>
<td>{{ car.custom_cards.custom_number }}</td> <td>{{ car.custom_cards.custom_number }}</td>
</tr> </tr>
<tr> <tr>
<th>{% trans "Custom Date" %}</th> <th>{% trans "Custom Date"|capfirst %}</th>
<td>{{ car.custom_cards.custom_date|date }}</td> <td>{{ car.custom_cards.custom_date|date }}</td>
</tr> </tr>
{% else %} {% else %}
@ -177,7 +165,7 @@
<th>{% trans "Custom Card" %}</th> <th>{% trans "Custom Card" %}</th>
<td> <td>
<button type="button" <button type="button"
class="btn btn-sm btn-success" class="btn btn-sm btn-phoenix-success"
data-bs-toggle="modal" data-bs-toggle="modal"
data-bs-target="#customCardModal"> data-bs-target="#customCardModal">
{% trans 'Add' %} {% trans 'Add' %}
@ -186,7 +174,7 @@
</tr> </tr>
{% endif %} {% endif %}
<tr> <tr>
<th>{% trans 'Showroom Location' %}</th> <th>{% trans 'Location'|capfirst %}</th>
<td> <td>
{% if car.location %} {% if car.location %}
{% if car.location.is_owner_showroom %} {% if car.location.is_owner_showroom %}
@ -195,20 +183,21 @@
{{ car.location.showroom.get_local_name }} {{ car.location.showroom.get_local_name }}
{% endif %} {% endif %}
<a href="{% url 'transfer' car.location.pk %}" <a href="{% url 'transfer' car.location.pk %}"
class="btn btn-danger btn-sm"> class="btn btn-phoenix-danger btn-sm">
{% trans "transfer"|capfirst %} {% trans "transfer"|capfirst %}
</a> </a>
{% else %} {% trans "No location available." %} {% else %} {% trans "No location available." %}
<a href="{% url 'add_car_location' car.pk %}" <a href="{% url 'add_car_location' car.pk %}"
class="btn btn-success btn-sm ms-2"> class="btn btn-phoenix-success btn-sm ms-2">
{% trans "Add" %} {% trans "Add" %}
</a> </a>
</td> </td>
{% endif %} {% endif %}
</tr> </tr>
</table> </table>
</div>
<div> <div>
<a href="{% url 'car_update' car.pk %}" class="btn btn-warning btn-sm">{% trans "Edit" %}</a> <a href="{% url 'car_update' car.pk %}" class="btn btn-phoenix-warning btn-sm mt-1">{% trans "Edit" %}</a>
</div> </div>
</div> </div>
</div> </div>
@ -217,28 +206,28 @@
<div class="col-lg-6 col-xl-6"> <div class="col-lg-6 col-xl-6">
<div class="card rounded shadow"> <div class="card rounded shadow">
<p class="card-header rounded-top fw-bold">{% trans 'Financial Details' %}</p> <p class="card-header rounded-top fw-bold">{% trans 'Financial Details' %}</p>
<div class="card-body">
{% if car.finances %}
<div class="card-body">
{% if car.finances %}
<div class="table-responsive">
<table class="table fs-9 mb-0"> <table class="table fs-9 mb-0">
{% if perms.inventory.view_carfinance %} {% if perms.inventory.view_carfinance %}
<tr> <tr>
<th>{% trans "Cost Price" %}</th> <th>{% trans "Cost Price"|capfirst %}</th>
<td>{{ car.finances.cost_price }}</td> <td>{{ car.finances.cost_price }}</td>
</tr> </tr>
{% endif %} {% endif %}
<tr> <tr>
<th>{% trans "Selling Price" %}</th> <th>{% trans "Selling Price"|capfirst %}</th>
<td>{{ car.finances.selling_price }}</td> <td>{{ car.finances.selling_price }}</td>
</tr> </tr>
<tr> <tr>
<th>{% trans "Discount Amount" %}</th> <th>{% trans "Discount Amount"|capfirst %}</th>
<td>{{ car.finances.discount_amount }} -</td> <td>{{ car.finances.discount_amount }} -</td>
</tr> </tr>
<tr> <tr>
<th>{% trans "Additional Fee" %}</th> <th>{% trans "Additional Fee"|capfirst %}</th>
<td></td> <td></td>
</tr> </tr>
{% if car.finances.additional_services.first.pk %} {% if car.finances.additional_services.first.pk %}
@ -250,37 +239,39 @@
{% endfor %} {% endfor %}
{% endif %} {% endif %}
<tr> <tr>
<th>{% trans "VAT Amount" %}</th> <th>{% trans "VAT Amount"|capfirst %}</th>
<td>{{ car.finances.vat_amount }}</td> <td>{{ car.finances.vat_amount }}</td>
</tr> </tr>
<tr> <tr>
<th>{% trans "Total" %}</th> <th>{% trans "Total"|capfirst %}</th>
<td>{{ car.finances.total }}</td> <td>{{ car.finances.total }}</td>
</tr> </tr>
<tr> <tr>
<td colspan="2"> <td colspan="2">
{% if perms.inventory.change_carfinance %} {% if perms.inventory.change_carfinance %}
<a href="{% url 'car_finance_update' car.finances.pk %}" <a href="{% url 'car_finance_update' car.finances.pk %}"
class="btn btn-warning btn-sm mb-3"> class="btn btn-phoenix-warning btn-sm mb-3">
{% trans "Edit Finance Details" %} {% trans "Edit" %}
</a> </a>
{% endif %} {% endif %}
{% else %} {% else %}
<p>{% trans "No finance details available." %}</p> <p>{% trans "No finance details available." %}</p>
<a href="{% url 'car_finance_create' car.pk %}" <a href="{% url 'car_finance_create' car.pk %}"
class="btn btn-success btn-sm mb-3"> class="btn btn-phoenix-success btn-sm mb-3">
{% trans "Add Finance Details" %} {% trans "Add" %}
</a> </a>
</td> </td>
</tr> </tr>
{% endif %} {% endif %}
</table> </table>
</div>
</div> </div>
</div> </div>
<div class="card rounded shadow mt-3"> <div class="card rounded shadow mt-3">
<p class="card-header rounded-top fw-bold">{% trans 'Colors Details' %}</p> <p class="card-header rounded-top fw-bold">{% trans 'Colors Details' %}</p>
<div class="card-body"> <div class="card-body">
<div class="table-responsive">
<table class="table fs-9 mb-0"> <table class="table fs-9 mb-0">
<tbody class="align-middle"> <tbody class="align-middle">
{% if car.colors.exists %} {% if car.colors.exists %}
@ -307,7 +298,7 @@
</div> </div>
</td> </td>
</tr> </tr>
{% endfor %} {% endfor %}
{% else %} {% else %}
<tr> <tr>
<td colspan="2"> <td colspan="2">
@ -316,8 +307,8 @@
</tr> </tr>
<tr> <tr>
<td colspan="2"> <td colspan="2">
<a href="{% url 'add_color' car.pk %}" class="btn btn-success btn-sm"> <a href="{% url 'add_color' car.pk %}" class="btn btn-phoenix-success btn-sm">
{% trans "Get Colors" %} {% trans "Add" %}
</a> </a>
</td> </td>
</tr> </tr>
@ -325,11 +316,13 @@
</tbody> </tbody>
</table> </table>
</div> </div>
</div>
</div> </div>
<div class="card rounded shadow mt-3"> <div class="card rounded shadow mt-3">
<p class="card-header rounded-top fw-bold">{% trans 'Reservations Details' %}</p> <p class="card-header rounded-top fw-bold">{% trans 'Reservations Details' %}</p>
<div class="card-body"> <div class="card-body">
<div class="table-responsive">
{% if car.is_reserved %} {% if car.is_reserved %}
<table class="table fs-9 mb-0"> <table class="table fs-9 mb-0">
<thead> <thead>
@ -351,13 +344,13 @@
<button type="submit" <button type="submit"
name="action" name="action"
value="renew" value="renew"
class="btn btn-sm btn-success"> class="btn btn-sm btn-phoenix-success">
{% trans "Renew" %} {% trans "Renew" %}
</button> </button>
<button type="submit" <button type="submit"
name="action" name="action"
value="cancel" value="cancel"
class="btn btn-sm btn-secondary"> class="btn btn-sm btn-phoenix-secondary">
{% trans "Cancel" %} {% trans "Cancel" %}
</button> </button>
</form> </form>
@ -374,7 +367,7 @@
<tr> <tr>
<td> <td>
<button type="button" <button type="button"
class="btn btn-sm btn-success" class="btn btn-sm btn-phoenix-success"
data-bs-toggle="modal" data-bs-toggle="modal"
data-bs-target="#reserveModal"> data-bs-target="#reserveModal">
{% trans 'Reserve' %} {% trans 'Reserve' %}
@ -384,6 +377,7 @@
</tr> </tr>
</tbody> </tbody>
</table> </table>
<div class="table-responsive">
</div> </div>
</div> </div>
</div> </div>
@ -409,7 +403,7 @@
return cookieValue; return cookieValue;
} }
const csrfToken = getCookie("csrftoken");
const ajaxUrl = "{% url 'ajax_handler' %}"; const ajaxUrl = "{% url 'ajax_handler' %}";
const modal = document.getElementById("customCardModal"); const modal = document.getElementById("customCardModal");
@ -442,7 +436,7 @@
fetch(`${ajaxUrl}?action=get_specifications&trim_id={{ car.id_car_trim.id_car_trim }}`, { fetch(`${ajaxUrl}?action=get_specifications&trim_id={{ car.id_car_trim.id_car_trim }}`, {
headers: { headers: {
"X-Requested-With": "XMLHttpRequest", "X-Requested-With": "XMLHttpRequest",
"X-CSRFToken": csrfToken, "X-CSRFToken": {% csrf_token %},
}, },
}) })
.then((response) => response.json()) .then((response) => response.json())
@ -478,7 +472,7 @@
const response = await fetch(`{% url 'reserve_car' car.pk %}`, { const response = await fetch(`{% url 'reserve_car' car.pk %}`, {
method: "POST", method: "POST",
headers: { headers: {
"X-CSRFToken": csrfToken, "X-CSRFToken": {% csrf_token %},
"X-Requested-With": "XMLHttpRequest", "X-Requested-With": "XMLHttpRequest",
}, },
}); });

View File

@ -1,5 +1,5 @@
{% extends 'base.html' %} {% extends 'base.html' %}
{% load i18n %} {% load i18n static%}
{% block title %} {% block title %}
{% trans 'inventory'|capfirst %} {% trans 'inventory'|capfirst %}
{% endblock %} {% endblock %}
@ -20,9 +20,39 @@
</style> </style>
<div class="container"> <div class="container">
<div class="row g-3 justify-content-between mb-4"> <div class="row g-3 justify-content-between mb-4">
<div class="col-sm-12">
<!---->
<div class="card border h-100 w-100 overflow-hidden">
<div class="bg-holder d-block bg-card" style="background-image:url({% static 'images/spot-illustrations/32.png' %});background-position: top right;">
</div>
<!--/.bg-holder-->
<div class="d-dark-none">
<div class="bg-holder d-none d-sm-block d-xl-none d-xxl-block bg-card" style="background-image:url({% static 'images/spot-illustrations/dark_21.png' %});background-position: bottom right; background-size: auto;">
</div>
<!--/.bg-holder-->
</div>
<div class="d-light-none">
<div class="bg-holder d-none d-sm-block d-xl-none d-xxl-block bg-card" style="background-image:url({% static 'images/spot-illustrations/21.png' %});background-position: bottom right; background-size: auto;">
</div>
<!--/.bg-holder-->
</div>
<div class="card-body px-5 position-relative">
<div class="badge badge-phoenix fs-10 badge-phoenix-warning mb-2">{{ _("Year") }}<span class="ms-1 fw-bold">{{ cars.first.year }}</span></div>
<h3 class="mb-2">{{ cars.first.id_car_make.get_local_name }}<span class="ms-2 text-body-tertiary fw-semibold">{{ cars.first.id_car_model.get_local_name }}</span></h3>
</div>
<div class="card-footer border-0 py-0 px-5 z-1">
<p class="text-body-tertiary fw-semibold">{{ cars.first.id_car_serie.name }}, <span class="fs-10">{{ cars.first.id_car_trim.name }}</span></p>
</div>
</div>
<!---->
</div>
</div>
<div class="row g-3 justify-content-between mb-4">
<div class="col-sm-12"> <div class="col-sm-12">
<div class="table-responsive scrollbar mx-n1 px-1"> <div class="table-responsive scrollbar mx-n1 px-1">
<table class="table fs-9 mb-0 leads-table border-top border-translucent"> <table class="table fs-9 mb-0 leads-table border-top border-translucent">
<thead> <thead>
<tr> <tr>
@ -67,7 +97,7 @@
{% endif %} {% endif %}
<td> <td>
<a href="{% url 'car_detail' car.pk %}" class="btn btn-success"> <a href="{% url 'car_detail' car.pk %}" class="btn btn-success">
{% trans "view" %} {% trans "view"|capfirst %}
</a> </a>
</td> </td>
</tr> </tr>

View File

@ -1,25 +0,0 @@
<script>
{% if messages %}
{% for message in messages %}
const Toast = Swal.mixin({
toast: true,
position: "top-end",
showConfirmButton: false,
timer: 2000,
timerProgressBar: true,
didOpen: (toast) => {
toast.onmouseenter = Swal.stopTimer;
toast.onmouseleave = Swal.resumeTimer;
}
});
Toast.fire({
icon: "{{ message.tags }}",
titleText: "{{ message| safe }}"
});
{% endfor %}
{% endif %}
</script>

View File

@ -9,33 +9,26 @@
</div> </div>
<div class="card-body p-0"> <div class="card-body p-0">
<div class="scrollbar-overlay" style="height: 27rem;"> <div class="scrollbar-overlay" style="height: 27rem;">
{% for notification in notifications %}
{% if not notification.is_read %}
<div class="px-2 px-sm-3 py-3 notification-card position-relative border-bottom"> <div class="px-2 px-sm-3 py-3 notification-card position-relative border-bottom">
<div class="d-flex align-items-center justify-content-between position-relative"> <div class="d-flex align-items-center justify-content-between position-relative">
<div class="d-flex"> <div class="d-flex">
<div class="flex-1 me-sm-3"> <div class="flex-1 me-sm-3">
<h4 class="fs-9 text-body-emphasis">{{ _("System") }}</h4> <h4 class="fs-9 text-body-emphasis">{{ _("System") }}</h4>
<p class="fs-9 text-body-highlight mb-2 mb-sm-3 fw-normal"><span class='me-1 fs-10'><span class=""></span></span>{{ notification.message }}<span class="ms-2 text-body-quaternary text-opacity-75 fw-bold fs-10">{{ notification.created_at|timesince }}</span></p> <ul id="notification-list">
<p class="text-body-secondary fs-9 mb-0"><span class="me-1 far fa-clock"></span>{{ notification.created_at }}</p>
</ul>
</div> </div>
</div> </div>
<div class="dropdown notification-dropdown"> <div class="dropdown notification-dropdown">
<button class="btn fs-10 btn-sm dropdown-toggle dropdown-caret-none transition-none" type="button" data-bs-toggle="dropdown" data-boundary="window" aria-haspopup="true" aria-expanded="false" data-bs-reference="parent"><span class="fas fa-ellipsis-h fs-10 text-body"></span></button> <button class="btn fs-10 btn-sm dropdown-toggle dropdown-caret-none transition-none" type="button" data-bs-toggle="dropdown" data-boundary="window" aria-haspopup="true" aria-expanded="false" data-bs-reference="parent"><span class="fas fa-ellipsis-h fs-10 text-body"></span></button>
<div class="dropdown-menu py-2"><a class="dropdown-item" href="{% url 'mark_notification_as_read' notification.pk %}">Mark as Read</a></div> <div class="dropdown-menu py-2"><a class="dropdown-item">Mark as Read</a></div>
</div> </div>
</div> </div>
</div> </div>
{% endif %}
{% empty %}
<p>No new notifications.</p>
{% endfor %}
</div> </div>
</div> </div>
<div class="card-footer p-0 border-top border-translucent border-0"> <div class="card-footer p-0 border-top border-translucent border-0">
<div class="my-2 text-center fw-bold fs-10 text-body-tertiary text-opactity-85"><a class="fw-bolder" href="{% url 'notifications_history' %}">Notification history</a></div> <div class="my-2 text-center fw-bold fs-10 text-body-tertiary text-opactity-85"><a class="fw-bolder" href="{% url 'notifications_history' %}">Notification history</a></div>
</div> </div>
</div> </div>
</div> </div>

View File

@ -4,6 +4,7 @@
<div class="content"> <div class="content">
<h2 class="mb-5">{{ _("Notifications") }}</h2> <h2 class="mb-5">{{ _("Notifications") }}</h2>
{% if notifications %} {% if notifications %}
<div class="mx-n4 mx-lg-n6 mb-5 border-bottom"> <div class="mx-n4 mx-lg-n6 mb-5 border-bottom">
{% for notification in notifications %} {% for notification in notifications %}
@ -47,5 +48,8 @@
{% else %} {% else %}
<p>No notifications found.</p> <p>No notifications found.</p>
{% endif %} {% endif %}
{% endblock %} {% endblock %}