everything before new pull
This commit is contained in:
commit
043d885ece
@ -34,9 +34,7 @@ application = ProtocolTypeRouter(
|
|||||||
URLRouter(
|
URLRouter(
|
||||||
[
|
[
|
||||||
path("sse/notifications/", NotificationSSEApp()),
|
path("sse/notifications/", NotificationSSEApp()),
|
||||||
re_path(
|
re_path(r"", app),
|
||||||
r"", app
|
|
||||||
),
|
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
@ -45,4 +43,4 @@ application = ProtocolTypeRouter(
|
|||||||
|
|
||||||
|
|
||||||
# if django.conf.settings.DEBUG:
|
# if django.conf.settings.DEBUG:
|
||||||
# application = ASGIStaticFilesHandler(app)
|
# application = ASGIStaticFilesHandler(app)
|
||||||
|
|||||||
@ -35,5 +35,4 @@ urlpatterns += i18n_patterns(
|
|||||||
|
|
||||||
if settings.DEBUG:
|
if settings.DEBUG:
|
||||||
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
|
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
|
||||||
urlpatterns += static(settings.STATIC_URL, document_root = settings.STATIC_ROOT)
|
urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
|
||||||
|
|
||||||
|
|||||||
@ -3,6 +3,7 @@ from django.contrib import admin
|
|||||||
from . import models
|
from . import models
|
||||||
from django_ledger import models as ledger_models
|
from django_ledger import models as ledger_models
|
||||||
from django.contrib import messages
|
from django.contrib import messages
|
||||||
|
|
||||||
# from django_pdf_actions.actions import export_to_pdf_landscape, export_to_pdf_portrait
|
# from django_pdf_actions.actions import export_to_pdf_landscape, export_to_pdf_portrait
|
||||||
# from appointment import models as appointment_models
|
# from appointment import models as appointment_models
|
||||||
from import_export.admin import ExportMixin
|
from import_export.admin import ExportMixin
|
||||||
@ -177,55 +178,52 @@ class CarOptionAdmin(admin.ModelAdmin):
|
|||||||
# actions = [export_to_pdf_landscape, export_to_pdf_portrait]
|
# actions = [export_to_pdf_landscape, export_to_pdf_portrait]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@admin.register(models.UserRegistration)
|
@admin.register(models.UserRegistration)
|
||||||
class UserRegistrationAdmin(admin.ModelAdmin):
|
class UserRegistrationAdmin(admin.ModelAdmin):
|
||||||
# Fields to display in the list view
|
# Fields to display in the list view
|
||||||
list_display = [
|
list_display = [
|
||||||
'name',
|
"name",
|
||||||
'arabic_name',
|
"arabic_name",
|
||||||
'email',
|
"email",
|
||||||
'crn',
|
"crn",
|
||||||
'vrn',
|
"vrn",
|
||||||
'phone_number',
|
"phone_number",
|
||||||
'is_created',
|
"is_created",
|
||||||
'created_at',
|
"created_at",
|
||||||
]
|
]
|
||||||
|
|
||||||
# Filters in the right sidebar
|
# Filters in the right sidebar
|
||||||
list_filter = [
|
list_filter = [
|
||||||
'is_created',
|
"is_created",
|
||||||
'created_at',
|
"created_at",
|
||||||
]
|
]
|
||||||
|
|
||||||
# Searchable fields
|
# Searchable fields
|
||||||
search_fields = [
|
search_fields = ["name", "arabic_name", "email", "crn", "vrn", "phone_number"]
|
||||||
'name', 'arabic_name', 'email', 'crn', 'vrn', 'phone_number'
|
|
||||||
]
|
|
||||||
|
|
||||||
# Read-only fields in detail view
|
# Read-only fields in detail view
|
||||||
readonly_fields = [
|
readonly_fields = ["created_at", "updated_at", "is_created", "password"]
|
||||||
'created_at', 'updated_at', 'is_created', 'password'
|
|
||||||
]
|
|
||||||
|
|
||||||
# Organize form layout
|
# Organize form layout
|
||||||
fieldsets = [
|
fieldsets = [
|
||||||
('Account Information', {
|
(
|
||||||
'fields': ('name', 'arabic_name', 'email', 'phone_number')
|
"Account Information",
|
||||||
}),
|
{"fields": ("name", "arabic_name", "email", "phone_number")},
|
||||||
('Business Details', {
|
),
|
||||||
'fields': ('crn', 'vrn', 'address')
|
("Business Details", {"fields": ("crn", "vrn", "address")}),
|
||||||
}),
|
(
|
||||||
('Status', {
|
"Status",
|
||||||
'fields': ('is_created', 'password', 'created_at', 'updated_at'),
|
{
|
||||||
'classes': ('collapse',)
|
"fields": ("is_created", "password", "created_at", "updated_at"),
|
||||||
}),
|
"classes": ("collapse",),
|
||||||
|
},
|
||||||
|
),
|
||||||
]
|
]
|
||||||
|
|
||||||
# Custom action to create accounts
|
# Custom action to create accounts
|
||||||
actions = ['create_dealer_accounts']
|
actions = ["create_dealer_accounts"]
|
||||||
|
|
||||||
@admin.action(description='Create dealer account(s) for selected registrations')
|
@admin.action(description="Create dealer account(s) for selected registrations")
|
||||||
def create_dealer_accounts(self, request, queryset):
|
def create_dealer_accounts(self, request, queryset):
|
||||||
created_count = 0
|
created_count = 0
|
||||||
already_created_count = 0
|
already_created_count = 0
|
||||||
@ -242,7 +240,7 @@ class UserRegistrationAdmin(admin.ModelAdmin):
|
|||||||
self.message_user(
|
self.message_user(
|
||||||
request,
|
request,
|
||||||
f"Error creating account for {registration.name}: {str(e)}",
|
f"Error creating account for {registration.name}: {str(e)}",
|
||||||
level=messages.ERROR
|
level=messages.ERROR,
|
||||||
)
|
)
|
||||||
failed_count += 1
|
failed_count += 1
|
||||||
|
|
||||||
@ -251,17 +249,17 @@ class UserRegistrationAdmin(admin.ModelAdmin):
|
|||||||
self.message_user(
|
self.message_user(
|
||||||
request,
|
request,
|
||||||
f"Successfully created {created_count} account(s).",
|
f"Successfully created {created_count} account(s).",
|
||||||
level=messages.SUCCESS
|
level=messages.SUCCESS,
|
||||||
)
|
)
|
||||||
if already_created_count > 0:
|
if already_created_count > 0:
|
||||||
self.message_user(
|
self.message_user(
|
||||||
request,
|
request,
|
||||||
f"{already_created_count} registration(s) were already created.",
|
f"{already_created_count} registration(s) were already created.",
|
||||||
level=messages.INFO
|
level=messages.INFO,
|
||||||
)
|
)
|
||||||
if failed_count > 0:
|
if failed_count > 0:
|
||||||
self.message_user(
|
self.message_user(
|
||||||
request,
|
request,
|
||||||
f"Failed to create {failed_count} account(s). Check logs.",
|
f"Failed to create {failed_count} account(s). Check logs.",
|
||||||
level=messages.ERROR
|
level=messages.ERROR,
|
||||||
)
|
)
|
||||||
|
|||||||
@ -2,6 +2,7 @@ from django.core.cache import cache
|
|||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from luhnchecker.luhn import Luhn
|
from luhnchecker.luhn import Luhn
|
||||||
from django.contrib.auth.models import Permission
|
from django.contrib.auth.models import Permission
|
||||||
|
|
||||||
# from appointment.models import Service
|
# from appointment.models import Service
|
||||||
from django.core.validators import MinLengthValidator
|
from django.core.validators import MinLengthValidator
|
||||||
from django import forms
|
from django import forms
|
||||||
@ -57,7 +58,7 @@ from .models import (
|
|||||||
Tasks,
|
Tasks,
|
||||||
Recall,
|
Recall,
|
||||||
Ticket,
|
Ticket,
|
||||||
UserRegistration
|
UserRegistration,
|
||||||
)
|
)
|
||||||
from django_ledger import models as ledger_models
|
from django_ledger import models as ledger_models
|
||||||
from django.forms import (
|
from django.forms import (
|
||||||
@ -364,7 +365,14 @@ class CarForm(
|
|||||||
"receiving_date",
|
"receiving_date",
|
||||||
"vendor",
|
"vendor",
|
||||||
]
|
]
|
||||||
required_fields = ["vin","id_car_make", "id_car_model", "id_car_serie", "id_car_trim", "vendor"]
|
required_fields = [
|
||||||
|
"vin",
|
||||||
|
"id_car_make",
|
||||||
|
"id_car_model",
|
||||||
|
"id_car_serie",
|
||||||
|
"id_car_trim",
|
||||||
|
"vendor",
|
||||||
|
]
|
||||||
widgets = {
|
widgets = {
|
||||||
"id_car_make": forms.Select(attrs={"class": "form-select form-select-sm"}),
|
"id_car_make": forms.Select(attrs={"class": "form-select form-select-sm"}),
|
||||||
"receiving_date": forms.DateTimeInput(attrs={"type": "datetime-local"}),
|
"receiving_date": forms.DateTimeInput(attrs={"type": "datetime-local"}),
|
||||||
@ -2123,8 +2131,7 @@ class AdditionalFinancesForm(forms.Form):
|
|||||||
for field in self.fields.values():
|
for field in self.fields.values():
|
||||||
if isinstance(field, forms.ModelMultipleChoiceField):
|
if isinstance(field, forms.ModelMultipleChoiceField):
|
||||||
field.widget.choices = [
|
field.widget.choices = [
|
||||||
(obj.pk, f"{obj.name} - {obj.price:.2f}")
|
(obj.pk, f"{obj.name} - {obj.price:.2f}") for obj in field.queryset
|
||||||
for obj in field.queryset
|
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
@ -2141,6 +2148,7 @@ class VatRateForm(forms.ModelForm):
|
|||||||
model = VatRate
|
model = VatRate
|
||||||
fields = ["rate"]
|
fields = ["rate"]
|
||||||
|
|
||||||
|
|
||||||
class CustomSetPasswordForm(SetPasswordForm):
|
class CustomSetPasswordForm(SetPasswordForm):
|
||||||
new_password1 = forms.CharField(
|
new_password1 = forms.CharField(
|
||||||
label="New Password",
|
label="New Password",
|
||||||
@ -2258,13 +2266,21 @@ class TicketResolutionForm(forms.ModelForm):
|
|||||||
self.fields["status"].choices = [("resolved", "Resolved"), ("closed", "Closed")]
|
self.fields["status"].choices = [("resolved", "Resolved"), ("closed", "Closed")]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class CarDealershipRegistrationForm(forms.ModelForm):
|
class CarDealershipRegistrationForm(forms.ModelForm):
|
||||||
# Add additional fields for the registration form
|
# Add additional fields for the registration form
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = UserRegistration
|
model = UserRegistration
|
||||||
fields = ("name","arabic_name", "email","phone_number", "crn", "vrn", "address")
|
fields = (
|
||||||
|
"name",
|
||||||
|
"arabic_name",
|
||||||
|
"email",
|
||||||
|
"phone_number",
|
||||||
|
"crn",
|
||||||
|
"vrn",
|
||||||
|
"address",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class CarDetailsEstimateCreate(forms.Form):
|
class CarDetailsEstimateCreate(forms.Form):
|
||||||
customer = forms.ModelChoiceField(
|
customer = forms.ModelChoiceField(
|
||||||
@ -2272,4 +2288,4 @@ class CarDetailsEstimateCreate(forms.Form):
|
|||||||
required=True,
|
required=True,
|
||||||
label="Customer",
|
label="Customer",
|
||||||
widget=forms.Select(attrs={"class": "form-control"}),
|
widget=forms.Select(attrs={"class": "form-control"}),
|
||||||
)
|
)
|
||||||
|
|||||||
@ -18,10 +18,10 @@ def check_create_coa_accounts(task):
|
|||||||
logger.warning("Account creation task failed, checking status...")
|
logger.warning("Account creation task failed, checking status...")
|
||||||
|
|
||||||
try:
|
try:
|
||||||
dealer_id = task.kwargs.get('dealer_id',None)
|
dealer_id = task.kwargs.get("dealer_id", None)
|
||||||
coa_slug = task.kwargs.get('coa_slug', None)
|
coa_slug = task.kwargs.get("coa_slug", None)
|
||||||
logger.info(f"Checking accounts for dealer {dealer_id}")
|
logger.info(f"Checking accounts for dealer {dealer_id}")
|
||||||
logger.info(f"COA slug: {coa_slug}")
|
logger.info(f"COA slug: {coa_slug}")
|
||||||
if not dealer_id:
|
if not dealer_id:
|
||||||
logger.error("No dealer_id in task kwargs")
|
logger.error("No dealer_id in task kwargs")
|
||||||
return
|
return
|
||||||
@ -37,7 +37,9 @@ def check_create_coa_accounts(task):
|
|||||||
try:
|
try:
|
||||||
coa = entity.get_coa_model_qs().get(slug=coa_slug)
|
coa = entity.get_coa_model_qs().get(slug=coa_slug)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"COA with slug {coa_slug} not found for entity {entity.pk}: {e}")
|
logger.error(
|
||||||
|
f"COA with slug {coa_slug} not found for entity {entity.pk}: {e}"
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
coa = entity.get_default_coa()
|
coa = entity.get_default_coa()
|
||||||
if not coa:
|
if not coa:
|
||||||
@ -49,7 +51,11 @@ def check_create_coa_accounts(task):
|
|||||||
|
|
||||||
missing_accounts = []
|
missing_accounts = []
|
||||||
for account_data in get_accounts_data():
|
for account_data in get_accounts_data():
|
||||||
if not entity.get_all_accounts().filter(coa_model=coa,code=account_data["code"]).exists():
|
if (
|
||||||
|
not entity.get_all_accounts()
|
||||||
|
.filter(coa_model=coa, code=account_data["code"])
|
||||||
|
.exists()
|
||||||
|
):
|
||||||
missing_accounts.append(account_data)
|
missing_accounts.append(account_data)
|
||||||
logger.info(f"Missing account: {account_data['code']}")
|
logger.info(f"Missing account: {account_data['code']}")
|
||||||
|
|
||||||
@ -62,6 +68,8 @@ def check_create_coa_accounts(task):
|
|||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"Error in check_create_coa_accounts hook: {e}")
|
logger.error(f"Error in check_create_coa_accounts hook: {e}")
|
||||||
|
|
||||||
|
|
||||||
# def check_create_coa_accounts(task):
|
# def check_create_coa_accounts(task):
|
||||||
# logger.info("Checking if all accounts are created")
|
# logger.info("Checking if all accounts are created")
|
||||||
# instance = task.kwargs["dealer"]
|
# instance = task.kwargs["dealer"]
|
||||||
|
|||||||
@ -8,19 +8,23 @@ from django.core.management.base import BaseCommand
|
|||||||
|
|
||||||
User = get_user_model()
|
User = get_user_model()
|
||||||
|
|
||||||
|
|
||||||
class Command(BaseCommand):
|
class Command(BaseCommand):
|
||||||
help = "Deactivates expired user plans"
|
help = "Deactivates expired user plans"
|
||||||
|
|
||||||
def handle(self, *args, **options):
|
def handle(self, *args, **options):
|
||||||
users_without_plan = User.objects.filter(
|
users_without_plan = User.objects.filter(
|
||||||
is_active=True, userplan=None, dealer__isnull=False, date_joined__lte=timezone.now()-timedelta(days=7)
|
is_active=True,
|
||||||
|
userplan=None,
|
||||||
|
dealer__isnull=False,
|
||||||
|
date_joined__lte=timezone.now() - timedelta(days=7),
|
||||||
)
|
)
|
||||||
|
|
||||||
count = users_without_plan.count()
|
count = users_without_plan.count()
|
||||||
for user in users_without_plan:
|
for user in users_without_plan:
|
||||||
user.is_active = False
|
user.is_active = False
|
||||||
user.save()
|
user.save()
|
||||||
subject = 'Your account has been deactivated'
|
subject = "Your account has been deactivated"
|
||||||
message = """
|
message = """
|
||||||
Hello {},\n
|
Hello {},\n
|
||||||
Your account has been deactivated, please contact us at {} if you have any questions.
|
Your account has been deactivated, please contact us at {} if you have any questions.
|
||||||
@ -30,7 +34,7 @@ class Command(BaseCommand):
|
|||||||
""".format(user.dealer.name, settings.DEFAULT_FROM_EMAIL)
|
""".format(user.dealer.name, settings.DEFAULT_FROM_EMAIL)
|
||||||
from_email = settings.DEFAULT_FROM_EMAIL
|
from_email = settings.DEFAULT_FROM_EMAIL
|
||||||
recipient_list = user.email
|
recipient_list = user.email
|
||||||
send_email(from_email, recipient_list,subject, message)
|
send_email(from_email, recipient_list, subject, message)
|
||||||
|
|
||||||
self.stdout.write(
|
self.stdout.write(
|
||||||
self.style.SUCCESS(
|
self.style.SUCCESS(
|
||||||
|
|||||||
@ -63,14 +63,14 @@ class Command(BaseCommand):
|
|||||||
|
|
||||||
for plan in expired_plans:
|
for plan in expired_plans:
|
||||||
# try:
|
# try:
|
||||||
if dealer := getattr(plan.user,"dealer", None):
|
if dealer := getattr(plan.user, "dealer", None):
|
||||||
dealer.user.is_active = False
|
dealer.user.is_active = False
|
||||||
dealer.user.save()
|
dealer.user.save()
|
||||||
for staff in dealer.get_staff():
|
for staff in dealer.get_staff():
|
||||||
staff.deactivate_account()
|
staff.deactivate_account()
|
||||||
count = expired_plans.update(active=False)
|
count = expired_plans.update(active=False)
|
||||||
# except:
|
# except:
|
||||||
# logger.warning(f"User {plan.user_id} does not exist")
|
# logger.warning(f"User {plan.user_id} does not exist")
|
||||||
self.stdout.write(f"Deactivated {count} expired plans")
|
self.stdout.write(f"Deactivated {count} expired plans")
|
||||||
|
|
||||||
def cleanup_old_orders(self):
|
def cleanup_old_orders(self):
|
||||||
|
|||||||
@ -7,16 +7,16 @@ from django_ledger.models import EstimateModel, BillModel, AccountModel, LedgerM
|
|||||||
|
|
||||||
class Command(BaseCommand):
|
class Command(BaseCommand):
|
||||||
def handle(self, *args, **kwargs):
|
def handle(self, *args, **kwargs):
|
||||||
Permission.objects.get_or_create(
|
# Permission.objects.get_or_create(
|
||||||
name="Can view crm",
|
# name="Can view crm",
|
||||||
codename="can_view_crm",
|
# codename="can_view_crm",
|
||||||
content_type=ContentType.objects.get_for_model(Lead),
|
# content_type=ContentType.objects.get_for_model(Lead),
|
||||||
)
|
# )
|
||||||
Permission.objects.get_or_create(
|
# Permission.objects.get_or_create(
|
||||||
name="Can reassign lead",
|
# name="Can reassign lead",
|
||||||
codename="can_reassign_lead",
|
# codename="can_reassign_lead",
|
||||||
content_type=ContentType.objects.get_for_model(Lead),
|
# content_type=ContentType.objects.get_for_model(Lead),
|
||||||
)
|
# )
|
||||||
Permission.objects.get_or_create(
|
Permission.objects.get_or_create(
|
||||||
name="Can view sales",
|
name="Can view sales",
|
||||||
codename="can_view_sales",
|
codename="can_view_sales",
|
||||||
@ -47,4 +47,3 @@ class Command(BaseCommand):
|
|||||||
codename="can_approve_estimatemodel",
|
codename="can_approve_estimatemodel",
|
||||||
content_type=ContentType.objects.get_for_model(EstimateModel),
|
content_type=ContentType.objects.get_for_model(EstimateModel),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@ -23,19 +23,19 @@ class Command(BaseCommand):
|
|||||||
# Note: Deleting plans and quotas should cascade to related objects like PlanQuota and PlanPricing.
|
# Note: Deleting plans and quotas should cascade to related objects like PlanQuota and PlanPricing.
|
||||||
self.stdout.write(self.style.SUCCESS("Data reset complete."))
|
self.stdout.write(self.style.SUCCESS("Data reset complete."))
|
||||||
else:
|
else:
|
||||||
self.stdout.write(self.style.NOTICE("Creating or updating default plans and quotas..."))
|
self.stdout.write(
|
||||||
|
self.style.NOTICE("Creating or updating default plans and quotas...")
|
||||||
|
)
|
||||||
|
|
||||||
# Create or get quotas
|
# Create or get quotas
|
||||||
users_quota, created_u = Quota.objects.get_or_create(
|
users_quota, created_u = Quota.objects.get_or_create(
|
||||||
codename="Users",
|
codename="Users", defaults={"name": "Users", "unit": "number"}
|
||||||
defaults={"name": "Users", "unit": "number"}
|
|
||||||
)
|
)
|
||||||
if created_u:
|
if created_u:
|
||||||
self.stdout.write(self.style.SUCCESS('Created quota: "Users"'))
|
self.stdout.write(self.style.SUCCESS('Created quota: "Users"'))
|
||||||
|
|
||||||
cars_quota, created_c = Quota.objects.get_or_create(
|
cars_quota, created_c = Quota.objects.get_or_create(
|
||||||
codename="Cars",
|
codename="Cars", defaults={"name": "Cars", "unit": "number"}
|
||||||
defaults={"name": "Cars", "unit": "number"}
|
|
||||||
)
|
)
|
||||||
if created_c:
|
if created_c:
|
||||||
self.stdout.write(self.style.SUCCESS('Created quota: "Cars"'))
|
self.stdout.write(self.style.SUCCESS('Created quota: "Cars"'))
|
||||||
@ -43,90 +43,81 @@ class Command(BaseCommand):
|
|||||||
# Create or get plans
|
# Create or get plans
|
||||||
basic_plan, created_bp = Plan.objects.get_or_create(
|
basic_plan, created_bp = Plan.objects.get_or_create(
|
||||||
name="Basic",
|
name="Basic",
|
||||||
defaults={"description": "basic plan", "available": True, "visible": True}
|
defaults={"description": "basic plan", "available": True, "visible": True},
|
||||||
)
|
)
|
||||||
if created_bp:
|
if created_bp:
|
||||||
self.stdout.write(self.style.SUCCESS('Created plan: "Basic"'))
|
self.stdout.write(self.style.SUCCESS('Created plan: "Basic"'))
|
||||||
|
|
||||||
pro_plan, created_pp = Plan.objects.get_or_create(
|
pro_plan, created_pp = Plan.objects.get_or_create(
|
||||||
name="Pro",
|
name="Pro",
|
||||||
defaults={"description": "Pro plan", "available": True, "visible": True}
|
defaults={"description": "Pro plan", "available": True, "visible": True},
|
||||||
)
|
)
|
||||||
if created_pp:
|
if created_pp:
|
||||||
self.stdout.write(self.style.SUCCESS('Created plan: "Pro"'))
|
self.stdout.write(self.style.SUCCESS('Created plan: "Pro"'))
|
||||||
|
|
||||||
enterprise_plan, created_ep = Plan.objects.get_or_create(
|
enterprise_plan, created_ep = Plan.objects.get_or_create(
|
||||||
name="Enterprise",
|
name="Enterprise",
|
||||||
defaults={"description": "Enterprise plan", "available": True, "visible": True}
|
defaults={
|
||||||
|
"description": "Enterprise plan",
|
||||||
|
"available": True,
|
||||||
|
"visible": True,
|
||||||
|
},
|
||||||
)
|
)
|
||||||
if created_ep:
|
if created_ep:
|
||||||
self.stdout.write(self.style.SUCCESS('Created plan: "Enterprise"'))
|
self.stdout.write(self.style.SUCCESS('Created plan: "Enterprise"'))
|
||||||
|
|
||||||
# Assign quotas to plans using get_or_create to prevent duplicates
|
# Assign quotas to plans using get_or_create to prevent duplicates
|
||||||
PlanQuota.objects.get_or_create(
|
PlanQuota.objects.get_or_create(
|
||||||
plan=basic_plan,
|
plan=basic_plan, quota=users_quota, defaults={"value": 10000000}
|
||||||
quota=users_quota,
|
|
||||||
defaults={"value": 10000000}
|
|
||||||
)
|
)
|
||||||
PlanQuota.objects.get_or_create(
|
PlanQuota.objects.get_or_create(
|
||||||
plan=basic_plan,
|
plan=basic_plan, quota=cars_quota, defaults={"value": 10000000}
|
||||||
quota=cars_quota,
|
|
||||||
defaults={"value": 10000000}
|
|
||||||
)
|
)
|
||||||
|
|
||||||
# Pro plan quotas
|
# Pro plan quotas
|
||||||
PlanQuota.objects.get_or_create(
|
PlanQuota.objects.get_or_create(
|
||||||
plan=pro_plan,
|
plan=pro_plan, quota=users_quota, defaults={"value": 10000000}
|
||||||
quota=users_quota,
|
|
||||||
defaults={"value": 10000000}
|
|
||||||
)
|
)
|
||||||
PlanQuota.objects.get_or_create(
|
PlanQuota.objects.get_or_create(
|
||||||
plan=pro_plan,
|
plan=pro_plan, quota=cars_quota, defaults={"value": 10000000}
|
||||||
quota=cars_quota,
|
|
||||||
defaults={"value": 10000000}
|
|
||||||
)
|
)
|
||||||
|
|
||||||
# Enterprise plan quotas
|
# Enterprise plan quotas
|
||||||
PlanQuota.objects.get_or_create(
|
PlanQuota.objects.get_or_create(
|
||||||
plan=enterprise_plan,
|
plan=enterprise_plan, quota=users_quota, defaults={"value": 10000000}
|
||||||
quota=users_quota,
|
|
||||||
defaults={"value": 10000000}
|
|
||||||
)
|
)
|
||||||
PlanQuota.objects.get_or_create(
|
PlanQuota.objects.get_or_create(
|
||||||
plan=enterprise_plan,
|
plan=enterprise_plan, quota=cars_quota, defaults={"value": 10000000}
|
||||||
quota=cars_quota,
|
|
||||||
defaults={"value": 10000000}
|
|
||||||
)
|
)
|
||||||
|
|
||||||
# Create or get pricing
|
# Create or get pricing
|
||||||
basic_pricing, created_bp_p = Pricing.objects.get_or_create(
|
basic_pricing, created_bp_p = Pricing.objects.get_or_create(
|
||||||
name="3 Months",
|
name="3 Months", defaults={"period": 90}
|
||||||
defaults={"period": 90}
|
|
||||||
)
|
)
|
||||||
pro_pricing, created_pp_p = Pricing.objects.get_or_create(
|
pro_pricing, created_pp_p = Pricing.objects.get_or_create(
|
||||||
name="6 Months",
|
name="6 Months", defaults={"period": 180}
|
||||||
defaults={"period": 180}
|
|
||||||
)
|
)
|
||||||
enterprise_pricing, created_ep_p = Pricing.objects.get_or_create(
|
enterprise_pricing, created_ep_p = Pricing.objects.get_or_create(
|
||||||
name="1 Year",
|
name="1 Year", defaults={"period": 365}
|
||||||
defaults={"period": 365}
|
|
||||||
)
|
)
|
||||||
|
|
||||||
# Assign pricing to plans
|
# Assign pricing to plans
|
||||||
PlanPricing.objects.get_or_create(
|
PlanPricing.objects.get_or_create(
|
||||||
plan=basic_plan,
|
plan=basic_plan,
|
||||||
pricing=basic_pricing,
|
pricing=basic_pricing,
|
||||||
defaults={"price": Decimal("2997.00")}
|
defaults={"price": Decimal("2997.00")},
|
||||||
)
|
)
|
||||||
PlanPricing.objects.get_or_create(
|
PlanPricing.objects.get_or_create(
|
||||||
plan=pro_plan,
|
plan=pro_plan, pricing=pro_pricing, defaults={"price": Decimal("5395.00")}
|
||||||
pricing=pro_pricing,
|
|
||||||
defaults={"price": Decimal("5395.00")}
|
|
||||||
)
|
)
|
||||||
PlanPricing.objects.get_or_create(
|
PlanPricing.objects.get_or_create(
|
||||||
plan=enterprise_plan,
|
plan=enterprise_plan,
|
||||||
pricing=enterprise_pricing,
|
pricing=enterprise_pricing,
|
||||||
defaults={"price": Decimal("9590.00")}
|
defaults={"price": Decimal("9590.00")},
|
||||||
)
|
)
|
||||||
|
|
||||||
self.stdout.write(self.style.SUCCESS("Subscription plans structure successfully created or updated."))
|
self.stdout.write(
|
||||||
|
self.style.SUCCESS(
|
||||||
|
"Subscription plans structure successfully created or updated."
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|||||||
@ -3,12 +3,13 @@ from django.core.management.base import BaseCommand
|
|||||||
from django.contrib.sites.models import Site
|
from django.contrib.sites.models import Site
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
|
|
||||||
|
|
||||||
class Command(BaseCommand):
|
class Command(BaseCommand):
|
||||||
help = 'Update the default site domain'
|
help = "Update the default site domain"
|
||||||
|
|
||||||
def handle(self, *args, **options):
|
def handle(self, *args, **options):
|
||||||
site = Site.objects.get_current()
|
site = Site.objects.get_current()
|
||||||
site.domain = settings.SITE_DOMAIN
|
site.domain = settings.SITE_DOMAIN
|
||||||
site.name = settings.SITE_NAME
|
site.name = settings.SITE_NAME
|
||||||
site.save()
|
site.save()
|
||||||
self.stdout.write(self.style.SUCCESS(f'Site updated to: {site.domain}'))
|
self.stdout.write(self.style.SUCCESS(f"Site updated to: {site.domain}"))
|
||||||
|
|||||||
@ -10,7 +10,7 @@ from django.urls import reverse
|
|||||||
# from django.utils.text import slugify
|
# from django.utils.text import slugify
|
||||||
from slugify import slugify
|
from slugify import slugify
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
from django.core.validators import MinValueValidator,MaxValueValidator
|
from django.core.validators import MinValueValidator, MaxValueValidator
|
||||||
import hashlib
|
import hashlib
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from datetime import timedelta
|
from datetime import timedelta
|
||||||
@ -57,15 +57,17 @@ from encrypted_model_fields.fields import (
|
|||||||
EncryptedEmailField,
|
EncryptedEmailField,
|
||||||
EncryptedTextField,
|
EncryptedTextField,
|
||||||
)
|
)
|
||||||
|
|
||||||
# from plans.models import AbstractPlan
|
# from plans.models import AbstractPlan
|
||||||
# from simple_history.models import HistoricalRecords
|
# from simple_history.models import HistoricalRecords
|
||||||
from plans.models import Invoice
|
from plans.models import Invoice
|
||||||
|
|
||||||
from django_extensions.db.fields import RandomCharField,AutoSlugField
|
from django_extensions.db.fields import RandomCharField, AutoSlugField
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
logging.basicConfig(level=logging.INFO)
|
logging.basicConfig(level=logging.INFO)
|
||||||
|
|
||||||
|
|
||||||
class Base(models.Model):
|
class Base(models.Model):
|
||||||
id = models.UUIDField(
|
id = models.UUIDField(
|
||||||
unique=True,
|
unique=True,
|
||||||
@ -206,11 +208,8 @@ class VatRate(models.Model):
|
|||||||
max_digits=5,
|
max_digits=5,
|
||||||
decimal_places=2,
|
decimal_places=2,
|
||||||
default=Decimal("0.15"),
|
default=Decimal("0.15"),
|
||||||
validators=[
|
validators=[MinValueValidator(0.0), MaxValueValidator(1.0)],
|
||||||
MinValueValidator(0.0),
|
help_text=_("VAT rate as decimal between 0 and 1 (e.g., 0.2 for 20%)"),
|
||||||
MaxValueValidator(1.0)
|
|
||||||
],
|
|
||||||
help_text=_("VAT rate as decimal between 0 and 1 (e.g., 0.2 for 20%)")
|
|
||||||
)
|
)
|
||||||
is_active = models.BooleanField(default=True)
|
is_active = models.BooleanField(default=True)
|
||||||
created_at = models.DateTimeField(auto_now_add=True)
|
created_at = models.DateTimeField(auto_now_add=True)
|
||||||
@ -776,7 +775,7 @@ class Car(Base):
|
|||||||
make = self.id_car_make.name if self.id_car_make else "Unknown Make"
|
make = self.id_car_make.name if self.id_car_make else "Unknown Make"
|
||||||
model = self.id_car_model.name if self.id_car_model else "Unknown Model"
|
model = self.id_car_model.name if self.id_car_model else "Unknown Model"
|
||||||
trim = self.id_car_trim.name if self.id_car_trim else "Unknown Trim"
|
trim = self.id_car_trim.name if self.id_car_trim else "Unknown Trim"
|
||||||
vin=self.vin if self.vin else None
|
vin = self.vin if self.vin else None
|
||||||
return f"{self.year} - {make} - {model} - {trim}-{vin}"
|
return f"{self.year} - {make} - {model} - {trim}-{vin}"
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@ -843,7 +842,7 @@ class Car(Base):
|
|||||||
def mark_as_sold(self):
|
def mark_as_sold(self):
|
||||||
self.cancel_reservation()
|
self.cancel_reservation()
|
||||||
self.status = CarStatusChoices.SOLD
|
self.status = CarStatusChoices.SOLD
|
||||||
self.sold_date=timezone.now()
|
self.sold_date = timezone.now()
|
||||||
self.save()
|
self.save()
|
||||||
|
|
||||||
def cancel_reservation(self):
|
def cancel_reservation(self):
|
||||||
@ -904,16 +903,23 @@ class Car(Base):
|
|||||||
|
|
||||||
def get_active_estimates(self):
|
def get_active_estimates(self):
|
||||||
try:
|
try:
|
||||||
qs = self.item_model.itemtransactionmodel_set.exclude(ce_model__status="canceled")
|
qs = self.item_model.itemtransactionmodel_set.exclude(
|
||||||
|
ce_model__status="canceled"
|
||||||
|
)
|
||||||
|
|
||||||
data = []
|
data = []
|
||||||
for item in qs:
|
for item in qs:
|
||||||
x = ExtraInfo.objects.filter(object_id=item.ce_model.pk,content_type=ContentType.objects.get_for_model(EstimateModel)).first()
|
x = ExtraInfo.objects.filter(
|
||||||
|
object_id=item.ce_model.pk,
|
||||||
|
content_type=ContentType.objects.get_for_model(EstimateModel),
|
||||||
|
).first()
|
||||||
if x:
|
if x:
|
||||||
data.append(x)
|
data.append(x)
|
||||||
return data
|
return data
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"Error getting active estimates for car {self.vin} error: {e}")
|
logger.error(
|
||||||
|
f"Error getting active estimates for car {self.vin} error: {e}"
|
||||||
|
)
|
||||||
return []
|
return []
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@ -1389,7 +1395,11 @@ class Dealer(models.Model, LocalizedNameMixin):
|
|||||||
options={"quality": 80},
|
options={"quality": 80},
|
||||||
)
|
)
|
||||||
entity = models.ForeignKey(
|
entity = models.ForeignKey(
|
||||||
EntityModel, on_delete=models.SET_NULL, null=True, blank=True,related_name="dealers"
|
EntityModel,
|
||||||
|
on_delete=models.SET_NULL,
|
||||||
|
null=True,
|
||||||
|
blank=True,
|
||||||
|
related_name="dealers",
|
||||||
)
|
)
|
||||||
joined_at = models.DateTimeField(auto_now_add=True, verbose_name=_("Joined At"))
|
joined_at = models.DateTimeField(auto_now_add=True, verbose_name=_("Joined At"))
|
||||||
updated_at = models.DateTimeField(auto_now=True, verbose_name=_("Updated At"))
|
updated_at = models.DateTimeField(auto_now=True, verbose_name=_("Updated At"))
|
||||||
@ -1421,6 +1431,7 @@ class Dealer(models.Model, LocalizedNameMixin):
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(e)
|
print(e)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def is_plan_expired(self):
|
def is_plan_expired(self):
|
||||||
try:
|
try:
|
||||||
@ -1455,6 +1466,7 @@ class Dealer(models.Model, LocalizedNameMixin):
|
|||||||
|
|
||||||
def get_vendors(self):
|
def get_vendors(self):
|
||||||
return VendorModel.objects.filter(entity_model=self.entity)
|
return VendorModel.objects.filter(entity_model=self.entity)
|
||||||
|
|
||||||
def get_staff(self):
|
def get_staff(self):
|
||||||
return Staff.objects.filter(dealer=self)
|
return Staff.objects.filter(dealer=self)
|
||||||
|
|
||||||
@ -1505,7 +1517,9 @@ class Staff(models.Model):
|
|||||||
first_name = models.CharField(max_length=255, verbose_name=_("First Name"))
|
first_name = models.CharField(max_length=255, verbose_name=_("First Name"))
|
||||||
last_name = models.CharField(max_length=255, verbose_name=_("Last Name"))
|
last_name = models.CharField(max_length=255, verbose_name=_("Last Name"))
|
||||||
|
|
||||||
arabic_name = models.CharField(max_length=255, verbose_name=_("Arabic Name"),null=True,blank=True)
|
arabic_name = models.CharField(
|
||||||
|
max_length=255, verbose_name=_("Arabic Name"), null=True, blank=True
|
||||||
|
)
|
||||||
phone_number = EncryptedCharField(
|
phone_number = EncryptedCharField(
|
||||||
max_length=255,
|
max_length=255,
|
||||||
verbose_name=_("Phone Number"),
|
verbose_name=_("Phone Number"),
|
||||||
@ -1794,7 +1808,7 @@ class Customer(models.Model):
|
|||||||
commit=False,
|
commit=False,
|
||||||
customer_model_kwargs={
|
customer_model_kwargs={
|
||||||
"customer_name": self.full_name,
|
"customer_name": self.full_name,
|
||||||
"address_1": "",#self.address,
|
"address_1": "", # self.address,
|
||||||
# "phone": self.phone_number,
|
# "phone": self.phone_number,
|
||||||
# "email": self.email,
|
# "email": self.email,
|
||||||
},
|
},
|
||||||
@ -2120,6 +2134,10 @@ class Lead(models.Model):
|
|||||||
slug = RandomCharField(length=8, unique=True)
|
slug = RandomCharField(length=8, unique=True)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
|
permissions = [
|
||||||
|
("can_view_crm", _("Can view CRM")),
|
||||||
|
("can_reassign_lead", _("Can reassign lead")),
|
||||||
|
]
|
||||||
verbose_name = _("Lead")
|
verbose_name = _("Lead")
|
||||||
verbose_name_plural = _("Leads")
|
verbose_name_plural = _("Leads")
|
||||||
indexes = [
|
indexes = [
|
||||||
@ -2305,10 +2323,14 @@ class Schedule(models.Model):
|
|||||||
help_text=_("What is the status of this schedule?"),
|
help_text=_("What is the status of this schedule?"),
|
||||||
)
|
)
|
||||||
created_at = models.DateTimeField(
|
created_at = models.DateTimeField(
|
||||||
auto_now_add=True, verbose_name=_("Created Date"), help_text=_("When was this schedule created?")
|
auto_now_add=True,
|
||||||
|
verbose_name=_("Created Date"),
|
||||||
|
help_text=_("When was this schedule created?"),
|
||||||
)
|
)
|
||||||
updated_at = models.DateTimeField(
|
updated_at = models.DateTimeField(
|
||||||
auto_now=True, verbose_name=_("Updated Date"), help_text=_("When was this schedule last updated?")
|
auto_now=True,
|
||||||
|
verbose_name=_("Updated Date"),
|
||||||
|
help_text=_("When was this schedule last updated?"),
|
||||||
)
|
)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
@ -2495,13 +2517,12 @@ class Opportunity(models.Model):
|
|||||||
def __str__(self):
|
def __str__(self):
|
||||||
try:
|
try:
|
||||||
if self.customer:
|
if self.customer:
|
||||||
return (
|
return f"Opportunity for {self.customer.first_name} {self.customer.last_name}"
|
||||||
f"Opportunity for {self.customer.first_name} {self.customer.last_name}"
|
|
||||||
)
|
|
||||||
return f"Opportunity for {self.organization.name}"
|
return f"Opportunity for {self.organization.name}"
|
||||||
except Exception:
|
except Exception:
|
||||||
return f"Opportunity for car :{self.car}"
|
return f"Opportunity for car :{self.car}"
|
||||||
|
|
||||||
|
|
||||||
class Notes(models.Model):
|
class Notes(models.Model):
|
||||||
dealer = models.ForeignKey(Dealer, on_delete=models.CASCADE, related_name="notes")
|
dealer = models.ForeignKey(Dealer, on_delete=models.CASCADE, related_name="notes")
|
||||||
content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE)
|
content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE)
|
||||||
@ -2765,7 +2786,6 @@ class Vendor(models.Model, LocalizedNameMixin):
|
|||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.name
|
return self.name
|
||||||
|
|
||||||
@ -3155,7 +3175,7 @@ class CustomGroup(models.Model):
|
|||||||
"notes",
|
"notes",
|
||||||
"tasks",
|
"tasks",
|
||||||
"activity",
|
"activity",
|
||||||
"additionalservices"
|
"additionalservices",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
self.set_permissions(
|
self.set_permissions(
|
||||||
@ -3272,7 +3292,7 @@ class CustomGroup(models.Model):
|
|||||||
"payment",
|
"payment",
|
||||||
"vendor",
|
"vendor",
|
||||||
"additionalservices",
|
"additionalservices",
|
||||||
'customer'
|
"customer",
|
||||||
],
|
],
|
||||||
other_perms=[
|
other_perms=[
|
||||||
"view_car",
|
"view_car",
|
||||||
@ -3340,7 +3360,9 @@ class DealerSettings(models.Model):
|
|||||||
on_delete=models.SET_NULL,
|
on_delete=models.SET_NULL,
|
||||||
null=True,
|
null=True,
|
||||||
blank=True,
|
blank=True,
|
||||||
help_text=_("Cash account to track cash transactions when an invoice is created."),
|
help_text=_(
|
||||||
|
"Cash account to track cash transactions when an invoice is created."
|
||||||
|
),
|
||||||
verbose_name=_("Invoice Cash Account"),
|
verbose_name=_("Invoice Cash Account"),
|
||||||
)
|
)
|
||||||
invoice_prepaid_account = models.ForeignKey(
|
invoice_prepaid_account = models.ForeignKey(
|
||||||
@ -3349,7 +3371,9 @@ class DealerSettings(models.Model):
|
|||||||
on_delete=models.SET_NULL,
|
on_delete=models.SET_NULL,
|
||||||
null=True,
|
null=True,
|
||||||
blank=True,
|
blank=True,
|
||||||
help_text=_("Prepaid Revenue account to track prepaid revenue when an invoice is created."),
|
help_text=_(
|
||||||
|
"Prepaid Revenue account to track prepaid revenue when an invoice is created."
|
||||||
|
),
|
||||||
verbose_name=_("Invoice Prepaid Account"),
|
verbose_name=_("Invoice Prepaid Account"),
|
||||||
)
|
)
|
||||||
invoice_unearned_account = models.ForeignKey(
|
invoice_unearned_account = models.ForeignKey(
|
||||||
@ -3358,7 +3382,9 @@ class DealerSettings(models.Model):
|
|||||||
on_delete=models.SET_NULL,
|
on_delete=models.SET_NULL,
|
||||||
null=True,
|
null=True,
|
||||||
blank=True,
|
blank=True,
|
||||||
help_text=_("Unearned Revenue account to track unearned revenue when an invoice is created."),
|
help_text=_(
|
||||||
|
"Unearned Revenue account to track unearned revenue when an invoice is created."
|
||||||
|
),
|
||||||
verbose_name=_("Invoice Unearned Account"),
|
verbose_name=_("Invoice Unearned Account"),
|
||||||
)
|
)
|
||||||
invoice_tax_payable_account = models.ForeignKey(
|
invoice_tax_payable_account = models.ForeignKey(
|
||||||
@ -3367,7 +3393,9 @@ class DealerSettings(models.Model):
|
|||||||
on_delete=models.SET_NULL,
|
on_delete=models.SET_NULL,
|
||||||
null=True,
|
null=True,
|
||||||
blank=True,
|
blank=True,
|
||||||
help_text=_("Tax Payable account to track tax liabilities when an invoice is created."),
|
help_text=_(
|
||||||
|
"Tax Payable account to track tax liabilities when an invoice is created."
|
||||||
|
),
|
||||||
verbose_name=_("Invoice Tax Payable Account"),
|
verbose_name=_("Invoice Tax Payable Account"),
|
||||||
)
|
)
|
||||||
invoice_vehicle_sale_account = models.ForeignKey(
|
invoice_vehicle_sale_account = models.ForeignKey(
|
||||||
@ -3376,7 +3404,9 @@ class DealerSettings(models.Model):
|
|||||||
on_delete=models.SET_NULL,
|
on_delete=models.SET_NULL,
|
||||||
null=True,
|
null=True,
|
||||||
blank=True,
|
blank=True,
|
||||||
help_text=_("Vehicle Sales account to track vehicle sales revenue when an invoice is created."),
|
help_text=_(
|
||||||
|
"Vehicle Sales account to track vehicle sales revenue when an invoice is created."
|
||||||
|
),
|
||||||
verbose_name=_("Invoice Vehicle Sale Account"),
|
verbose_name=_("Invoice Vehicle Sale Account"),
|
||||||
)
|
)
|
||||||
invoice_additional_services_account = models.ForeignKey(
|
invoice_additional_services_account = models.ForeignKey(
|
||||||
@ -3385,7 +3415,9 @@ class DealerSettings(models.Model):
|
|||||||
on_delete=models.SET_NULL,
|
on_delete=models.SET_NULL,
|
||||||
null=True,
|
null=True,
|
||||||
blank=True,
|
blank=True,
|
||||||
help_text=_("Additional Services account to track additional services revenue when an invoice is created."),
|
help_text=_(
|
||||||
|
"Additional Services account to track additional services revenue when an invoice is created."
|
||||||
|
),
|
||||||
verbose_name=_("Invoice Additional Services Account"),
|
verbose_name=_("Invoice Additional Services Account"),
|
||||||
)
|
)
|
||||||
invoice_cost_of_good_sold_account = models.ForeignKey(
|
invoice_cost_of_good_sold_account = models.ForeignKey(
|
||||||
@ -3394,7 +3426,9 @@ class DealerSettings(models.Model):
|
|||||||
on_delete=models.SET_NULL,
|
on_delete=models.SET_NULL,
|
||||||
null=True,
|
null=True,
|
||||||
blank=True,
|
blank=True,
|
||||||
help_text=_("Cost of Goods Sold account to track the cost of goods sold when an invoice is created."),
|
help_text=_(
|
||||||
|
"Cost of Goods Sold account to track the cost of goods sold when an invoice is created."
|
||||||
|
),
|
||||||
verbose_name=_("Invoice Cost of Goods Sold Account"),
|
verbose_name=_("Invoice Cost of Goods Sold Account"),
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -3404,7 +3438,9 @@ class DealerSettings(models.Model):
|
|||||||
on_delete=models.SET_NULL,
|
on_delete=models.SET_NULL,
|
||||||
null=True,
|
null=True,
|
||||||
blank=True,
|
blank=True,
|
||||||
help_text=_("Inventory account to track the cost of goods sold when an invoice is created."),
|
help_text=_(
|
||||||
|
"Inventory account to track the cost of goods sold when an invoice is created."
|
||||||
|
),
|
||||||
verbose_name=_("Invoice Inventory Account"),
|
verbose_name=_("Invoice Inventory Account"),
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -3423,7 +3459,9 @@ class DealerSettings(models.Model):
|
|||||||
on_delete=models.SET_NULL,
|
on_delete=models.SET_NULL,
|
||||||
null=True,
|
null=True,
|
||||||
blank=True,
|
blank=True,
|
||||||
help_text=_("Prepaid account to track prepaid expenses when a bill is created."),
|
help_text=_(
|
||||||
|
"Prepaid account to track prepaid expenses when a bill is created."
|
||||||
|
),
|
||||||
verbose_name=_("Bill Prepaid Account"),
|
verbose_name=_("Bill Prepaid Account"),
|
||||||
)
|
)
|
||||||
bill_unearned_account = models.ForeignKey(
|
bill_unearned_account = models.ForeignKey(
|
||||||
@ -3432,10 +3470,14 @@ class DealerSettings(models.Model):
|
|||||||
on_delete=models.SET_NULL,
|
on_delete=models.SET_NULL,
|
||||||
null=True,
|
null=True,
|
||||||
blank=True,
|
blank=True,
|
||||||
help_text=_("Unearned account to track unearned expenses when a bill is created."),
|
help_text=_(
|
||||||
|
"Unearned account to track unearned expenses when a bill is created."
|
||||||
|
),
|
||||||
verbose_name=_("Bill Unearned Account"),
|
verbose_name=_("Bill Unearned Account"),
|
||||||
)
|
)
|
||||||
additional_info = models.JSONField(default=dict, null=True, blank=True, help_text=_("Additional information"))
|
additional_info = models.JSONField(
|
||||||
|
default=dict, null=True, blank=True, help_text=_("Additional information")
|
||||||
|
)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return f"Settings for {self.dealer}"
|
return f"Settings for {self.dealer}"
|
||||||
@ -3790,7 +3832,10 @@ class Ticket(models.Model):
|
|||||||
]
|
]
|
||||||
|
|
||||||
dealer = models.ForeignKey(
|
dealer = models.ForeignKey(
|
||||||
Dealer, on_delete=models.CASCADE, related_name="tickets", verbose_name=_("Dealer")
|
Dealer,
|
||||||
|
on_delete=models.CASCADE,
|
||||||
|
related_name="tickets",
|
||||||
|
verbose_name=_("Dealer"),
|
||||||
)
|
)
|
||||||
subject = models.CharField(
|
subject = models.CharField(
|
||||||
max_length=200, verbose_name=_("Subject"), help_text=_("Short description")
|
max_length=200, verbose_name=_("Subject"), help_text=_("Short description")
|
||||||
@ -3882,7 +3927,6 @@ class CarImage(models.Model):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class UserRegistration(models.Model):
|
class UserRegistration(models.Model):
|
||||||
name = models.CharField(_("Name"), max_length=255)
|
name = models.CharField(_("Name"), max_length=255)
|
||||||
arabic_name = models.CharField(_("Arabic Name"), max_length=255)
|
arabic_name = models.CharField(_("Arabic Name"), max_length=255)
|
||||||
@ -3892,15 +3936,24 @@ class UserRegistration(models.Model):
|
|||||||
verbose_name=_("Phone Number"),
|
verbose_name=_("Phone Number"),
|
||||||
validators=[SaudiPhoneNumberValidator()],
|
validators=[SaudiPhoneNumberValidator()],
|
||||||
)
|
)
|
||||||
crn = models.CharField(_("Commercial Registration Number"), max_length=10, unique=True)
|
crn = models.CharField(
|
||||||
|
_("Commercial Registration Number"), max_length=10, unique=True
|
||||||
|
)
|
||||||
vrn = models.CharField(_("Vehicle Registration Number"), max_length=15, unique=True)
|
vrn = models.CharField(_("Vehicle Registration Number"), max_length=15, unique=True)
|
||||||
address = models.TextField(_("Address"))
|
address = models.TextField(_("Address"))
|
||||||
password = models.CharField(_("Password"), max_length=255,null=True,blank=True)
|
password = models.CharField(_("Password"), max_length=255, null=True, blank=True)
|
||||||
is_created = models.BooleanField(default=False)
|
is_created = models.BooleanField(default=False)
|
||||||
created_at = models.DateTimeField(auto_now_add=True)
|
created_at = models.DateTimeField(auto_now_add=True)
|
||||||
updated_at = models.DateTimeField(auto_now=True)
|
updated_at = models.DateTimeField(auto_now=True)
|
||||||
|
|
||||||
REQUIRED_FIELDS = ["username", "arabic_name", "crn", "vrn", "address", "phone_number"]
|
REQUIRED_FIELDS = [
|
||||||
|
"username",
|
||||||
|
"arabic_name",
|
||||||
|
"crn",
|
||||||
|
"vrn",
|
||||||
|
"address",
|
||||||
|
"phone_number",
|
||||||
|
]
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.email
|
return self.email
|
||||||
@ -3924,7 +3977,7 @@ class UserRegistration(models.Model):
|
|||||||
phone=self.phone_number,
|
phone=self.phone_number,
|
||||||
crn=self.crn,
|
crn=self.crn,
|
||||||
vrn=self.vrn,
|
vrn=self.vrn,
|
||||||
address=self.address
|
address=self.address,
|
||||||
)
|
)
|
||||||
|
|
||||||
if dealer:
|
if dealer:
|
||||||
@ -3939,4 +3992,4 @@ class UserRegistration(models.Model):
|
|||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"Error creating account for {self.email}: {e}")
|
logger.error(f"Error creating account for {self.email}: {e}")
|
||||||
return False
|
return False
|
||||||
|
|||||||
@ -411,6 +411,22 @@ class BasePurchaseOrderActionActionView(
|
|||||||
f"while performing action '{self.action_name}' on Purchase Order ID: {po_model.pk}. "
|
f"while performing action '{self.action_name}' on Purchase Order ID: {po_model.pk}. "
|
||||||
f"Error: {e}"
|
f"Error: {e}"
|
||||||
)
|
)
|
||||||
|
except Exception as e:
|
||||||
|
print(
|
||||||
|
f"User {user_username} encountered an exception "
|
||||||
|
f"while performing action '{self.action_name}' on Purchase Order ID: {po_model.pk}. "
|
||||||
|
f"Error: {e}"
|
||||||
|
)
|
||||||
|
logger.warning(
|
||||||
|
f"User {user_username} encountered an exception "
|
||||||
|
f"while performing action '{self.action_name}' on Purchase Order ID: {po_model.pk}. "
|
||||||
|
f"Error: {e}"
|
||||||
|
)
|
||||||
|
messages.add_message(
|
||||||
|
request,
|
||||||
|
message=f"Failed to update PO {po_model.po_number}. {e}",
|
||||||
|
level=messages.ERROR,
|
||||||
|
)
|
||||||
return response
|
return response
|
||||||
|
|
||||||
|
|
||||||
@ -1129,6 +1145,7 @@ class ChartOfAccountModelCreateView(ChartOfAccountModelModelBaseViewMixIn, Creat
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class ChartOfAccountModelUpdateView(ChartOfAccountModelModelBaseViewMixIn, UpdateView):
|
class ChartOfAccountModelUpdateView(ChartOfAccountModelModelBaseViewMixIn, UpdateView):
|
||||||
context_object_name = "coa_model"
|
context_object_name = "coa_model"
|
||||||
slug_url_kwarg = "coa_slug"
|
slug_url_kwarg = "coa_slug"
|
||||||
|
|||||||
@ -5,6 +5,7 @@ from django.urls import reverse
|
|||||||
from django.contrib.auth.models import Group
|
from django.contrib.auth.models import Group
|
||||||
from django.db.models.signals import post_save, post_delete
|
from django.db.models.signals import post_save, post_delete
|
||||||
from django.dispatch import receiver
|
from django.dispatch import receiver
|
||||||
|
|
||||||
# from appointment.models import Service
|
# from appointment.models import Service
|
||||||
from django.utils.translation import gettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
from django.contrib.contenttypes.models import ContentType
|
from django.contrib.contenttypes.models import ContentType
|
||||||
@ -21,7 +22,7 @@ from django_ledger.models import (
|
|||||||
EstimateModel,
|
EstimateModel,
|
||||||
BillModel,
|
BillModel,
|
||||||
ChartOfAccountModel,
|
ChartOfAccountModel,
|
||||||
CustomerModel
|
CustomerModel,
|
||||||
)
|
)
|
||||||
from . import models
|
from . import models
|
||||||
from django.utils.timezone import now
|
from django.utils.timezone import now
|
||||||
@ -136,7 +137,6 @@ def create_car_location(sender, instance, created, **kwargs):
|
|||||||
print(f"Failed to create CarLocation for car {instance.vin}: {e}")
|
print(f"Failed to create CarLocation for car {instance.vin}: {e}")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@receiver(post_save, sender=models.Dealer)
|
@receiver(post_save, sender=models.Dealer)
|
||||||
def create_ledger_entity(sender, instance, created, **kwargs):
|
def create_ledger_entity(sender, instance, created, **kwargs):
|
||||||
if not created:
|
if not created:
|
||||||
@ -155,20 +155,22 @@ def create_ledger_entity(sender, instance, created, **kwargs):
|
|||||||
raise Exception("Entity creation failed")
|
raise Exception("Entity creation failed")
|
||||||
|
|
||||||
instance.entity = entity
|
instance.entity = entity
|
||||||
instance.save(update_fields=['entity'])
|
instance.save(update_fields=["entity"])
|
||||||
|
|
||||||
# Create default COA
|
# Create default COA
|
||||||
entity.create_chart_of_accounts(
|
entity.create_chart_of_accounts(
|
||||||
assign_as_default=True,
|
assign_as_default=True, commit=True, coa_name=f"{entity.name}-COA"
|
||||||
commit=True,
|
|
||||||
coa_name=f"{entity.name}-COA"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
logger.info(f"✅ Setup complete for dealer {instance.id}: entity & COA ready.")
|
logger.info(
|
||||||
|
f"✅ Setup complete for dealer {instance.id}: entity & COA ready."
|
||||||
|
)
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"💥 Failed setup for dealer {instance.id}: {e}")
|
logger.error(f"💥 Failed setup for dealer {instance.id}: {e}")
|
||||||
# Optional: schedule retry or alert
|
# Optional: schedule retry or alert
|
||||||
|
|
||||||
|
|
||||||
# Create Entity
|
# Create Entity
|
||||||
# @receiver(post_save, sender=models.Dealer)
|
# @receiver(post_save, sender=models.Dealer)
|
||||||
# def create_ledger_entity(sender, instance, created, **kwargs):
|
# def create_ledger_entity(sender, instance, created, **kwargs):
|
||||||
@ -218,10 +220,10 @@ def create_ledger_entity(sender, instance, created, **kwargs):
|
|||||||
# dealer=instance,
|
# dealer=instance,
|
||||||
# hook="inventory.hooks.check_create_coa_accounts",
|
# hook="inventory.hooks.check_create_coa_accounts",
|
||||||
# )
|
# )
|
||||||
# async_task('inventory.tasks.check_create_coa_accounts', instance, schedule_type='O', schedule_time=timedelta(seconds=20))
|
# async_task('inventory.tasks.check_create_coa_accounts', instance, schedule_type='O', schedule_time=timedelta(seconds=20))
|
||||||
|
|
||||||
# create_settings(instance.pk)
|
# create_settings(instance.pk)
|
||||||
# create_accounts_for_make(instance.pk)
|
# create_accounts_for_make(instance.pk)
|
||||||
|
|
||||||
|
|
||||||
@receiver(post_save, sender=models.Dealer)
|
@receiver(post_save, sender=models.Dealer)
|
||||||
@ -998,25 +1000,27 @@ def save_po(sender, instance, created, **kwargs):
|
|||||||
instance.itemtransactionmodel_set.first().po_model.save()
|
instance.itemtransactionmodel_set.first().po_model.save()
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
@receiver(post_save, sender=PurchaseOrderModel)
|
@receiver(post_save, sender=PurchaseOrderModel)
|
||||||
def create_po_item_upload(sender, instance, created, **kwargs):
|
def create_po_item_upload(sender, instance, created, **kwargs):
|
||||||
if instance.po_status == "fulfilled" or instance.po_status == 'approved':
|
if instance.po_status == "fulfilled" or instance.po_status == "approved":
|
||||||
for item in instance.get_itemtxs_data()[0]:
|
for item in instance.get_itemtxs_data()[0]:
|
||||||
dealer = models.Dealer.objects.get(entity=instance.entity)
|
dealer = models.Dealer.objects.get(entity=instance.entity)
|
||||||
if item.bill_model and item.bill_model.is_paid():
|
if item.bill_model and item.bill_model.is_paid():
|
||||||
models.PoItemsUploaded.objects.update_or_create(
|
models.PoItemsUploaded.objects.update_or_create(
|
||||||
dealer=dealer, po=instance, item=item,
|
dealer=dealer,
|
||||||
defaults={
|
po=instance,
|
||||||
"status":instance.po_status
|
item=item,
|
||||||
}
|
defaults={"status": instance.po_status},
|
||||||
)
|
)
|
||||||
|
|
||||||
# po_item = models.PoItemsUploaded.objects.get_or_create(
|
# po_item = models.PoItemsUploaded.objects.get_or_create(
|
||||||
# dealer=dealer, po=instance, item=item,
|
# dealer=dealer, po=instance, item=item,
|
||||||
# defaults={
|
# defaults={
|
||||||
# "status":instance.po_status
|
# "status":instance.po_status
|
||||||
# }
|
# }
|
||||||
# )
|
# )
|
||||||
|
|
||||||
|
|
||||||
# @receiver(post_save, sender=models.Staff)
|
# @receiver(post_save, sender=models.Staff)
|
||||||
@ -1364,7 +1368,9 @@ def handle_car_image(sender, instance, created, **kwargs):
|
|||||||
# )
|
# )
|
||||||
|
|
||||||
# Check for existing image with same hash
|
# Check for existing image with same hash
|
||||||
existing = os.path.exists(os.path.join(settings.MEDIA_ROOT, "car_images",car.get_hash + ".png"))
|
existing = os.path.exists(
|
||||||
|
os.path.join(settings.MEDIA_ROOT, "car_images", car.get_hash + ".png")
|
||||||
|
)
|
||||||
# existing = (
|
# existing = (
|
||||||
# models.CarImage.objects.filter(
|
# models.CarImage.objects.filter(
|
||||||
# image_hash=car.get_hash, image__isnull=False
|
# image_hash=car.get_hash, image__isnull=False
|
||||||
@ -1406,7 +1412,7 @@ def handle_user_registration(sender, instance, created, **kwargs):
|
|||||||
"""
|
"""
|
||||||
Thank you for registering with us. We will contact you shortly to complete your application.
|
Thank you for registering with us. We will contact you shortly to complete your application.
|
||||||
شكرا لمراسلتنا. سوف نتصل بك قريبا لاستكمال طلبك.
|
شكرا لمراسلتنا. سوف نتصل بك قريبا لاستكمال طلبك.
|
||||||
"""
|
""",
|
||||||
)
|
)
|
||||||
|
|
||||||
if instance.is_created:
|
if instance.is_created:
|
||||||
@ -1430,7 +1436,8 @@ def handle_user_registration(sender, instance, created, **kwargs):
|
|||||||
يرجى تسجيل الدخول إلى الموقع لاستكمال الملف الشخصي والبدء في استخدام خدماتنا.
|
يرجى تسجيل الدخول إلى الموقع لاستكمال الملف الشخصي والبدء في استخدام خدماتنا.
|
||||||
|
|
||||||
شكرا لاختيارك لنا.
|
شكرا لاختيارك لنا.
|
||||||
""")
|
""",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@receiver(post_save, sender=ChartOfAccountModel)
|
@receiver(post_save, sender=ChartOfAccountModel)
|
||||||
@ -1463,4 +1470,4 @@ def handle_chart_of_account(sender, instance, created, **kwargs):
|
|||||||
# sync=False # Explicitly set to async
|
# sync=False # Explicitly set to async
|
||||||
# )
|
# )
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"Error handling chart of account: {e}")
|
logger.error(f"Error handling chart of account: {e}")
|
||||||
|
|||||||
@ -12,12 +12,14 @@ from django.db import transaction
|
|||||||
from django_ledger.io import roles
|
from django_ledger.io import roles
|
||||||
from django_q.tasks import async_task
|
from django_q.tasks import async_task
|
||||||
from django.core.mail import send_mail
|
from django.core.mail import send_mail
|
||||||
|
|
||||||
# from appointment.models import StaffMember
|
# from appointment.models import StaffMember
|
||||||
from django.utils.translation import activate
|
from django.utils.translation import activate
|
||||||
from django.core.files.base import ContentFile
|
from django.core.files.base import ContentFile
|
||||||
from django.contrib.auth import get_user_model
|
from django.contrib.auth import get_user_model
|
||||||
from allauth.account.models import EmailAddress
|
from allauth.account.models import EmailAddress
|
||||||
from django.core.mail import EmailMultiAlternatives
|
from django.core.mail import EmailMultiAlternatives
|
||||||
|
|
||||||
# from .utils import get_accounts_data, create_account
|
# from .utils import get_accounts_data, create_account
|
||||||
from django.template.loader import render_to_string
|
from django.template.loader import render_to_string
|
||||||
from django.utils.translation import gettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
@ -30,7 +32,7 @@ from inventory.models import (
|
|||||||
CarReservation,
|
CarReservation,
|
||||||
CarStatusChoices,
|
CarStatusChoices,
|
||||||
CarImage,
|
CarImage,
|
||||||
Car
|
Car,
|
||||||
)
|
)
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
@ -63,17 +65,18 @@ def create_settings(pk):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def create_coa_accounts(dealer_id,**kwargs):
|
def create_coa_accounts(dealer_id, **kwargs):
|
||||||
"""
|
"""
|
||||||
Idempotent: Creates only missing default accounts.
|
Idempotent: Creates only missing default accounts.
|
||||||
Safe to retry. Returns True if all done.
|
Safe to retry. Returns True if all done.
|
||||||
"""
|
"""
|
||||||
from .models import Dealer
|
from .models import Dealer
|
||||||
from .utils import get_accounts_data, create_account
|
from .utils import get_accounts_data, create_account
|
||||||
|
|
||||||
try:
|
try:
|
||||||
dealer = Dealer.objects.get(pk=dealer_id)
|
dealer = Dealer.objects.get(pk=dealer_id)
|
||||||
entity = dealer.entity
|
entity = dealer.entity
|
||||||
coa_slug = kwargs.get('coa_slug', None)
|
coa_slug = kwargs.get("coa_slug", None)
|
||||||
if not entity:
|
if not entity:
|
||||||
logger.error(f"❌ No entity for dealer {dealer_id}")
|
logger.error(f"❌ No entity for dealer {dealer_id}")
|
||||||
return False
|
return False
|
||||||
@ -82,7 +85,9 @@ def create_coa_accounts(dealer_id,**kwargs):
|
|||||||
try:
|
try:
|
||||||
coa = entity.get_coa_model_qs().get(slug=coa_slug)
|
coa = entity.get_coa_model_qs().get(slug=coa_slug)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"COA with slug {coa_slug} not found for entity {entity.pk}: {e}")
|
logger.error(
|
||||||
|
f"COA with slug {coa_slug} not found for entity {entity.pk}: {e}"
|
||||||
|
)
|
||||||
return False
|
return False
|
||||||
else:
|
else:
|
||||||
coa = entity.get_default_coa()
|
coa = entity.get_default_coa()
|
||||||
@ -92,10 +97,13 @@ def create_coa_accounts(dealer_id,**kwargs):
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
# Get missing accounts
|
# Get missing accounts
|
||||||
existing_codes = set(entity.get_all_accounts().filter(coa_model=coa).values_list('code', flat=True))
|
existing_codes = set(
|
||||||
|
entity.get_all_accounts()
|
||||||
|
.filter(coa_model=coa)
|
||||||
|
.values_list("code", flat=True)
|
||||||
|
)
|
||||||
accounts_to_create = [
|
accounts_to_create = [
|
||||||
acc for acc in get_accounts_data()
|
acc for acc in get_accounts_data() if acc["code"] not in existing_codes
|
||||||
if acc["code"] not in existing_codes
|
|
||||||
]
|
]
|
||||||
|
|
||||||
if not accounts_to_create:
|
if not accounts_to_create:
|
||||||
@ -122,6 +130,7 @@ def create_coa_accounts(dealer_id,**kwargs):
|
|||||||
logger.error(f"💥 Task failed for dealer {dealer_id}: {e}")
|
logger.error(f"💥 Task failed for dealer {dealer_id}: {e}")
|
||||||
raise # Let Django-Q handle retry if configured
|
raise # Let Django-Q handle retry if configured
|
||||||
|
|
||||||
|
|
||||||
def retry_entity_creation(dealer_id, retry_count=0):
|
def retry_entity_creation(dealer_id, retry_count=0):
|
||||||
"""
|
"""
|
||||||
Retry entity creation if initial attempt failed
|
Retry entity creation if initial attempt failed
|
||||||
@ -164,8 +173,10 @@ def retry_entity_creation(dealer_id, retry_count=0):
|
|||||||
async_task(
|
async_task(
|
||||||
"inventory.tasks.retry_entity_creation",
|
"inventory.tasks.retry_entity_creation",
|
||||||
dealer_id=dealer_id,
|
dealer_id=dealer_id,
|
||||||
retry_count=retry_count + 1
|
retry_count=retry_count + 1,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
# def create_coa_accounts(**kwargs):
|
# def create_coa_accounts(**kwargs):
|
||||||
# logger.info("creating all accounts are created")
|
# logger.info("creating all accounts are created")
|
||||||
# instance = kwargs.get("dealer")
|
# instance = kwargs.get("dealer")
|
||||||
|
|||||||
@ -13,6 +13,7 @@ from django.db.models import Case, Value, When, IntegerField
|
|||||||
|
|
||||||
register = template.Library()
|
register = template.Library()
|
||||||
|
|
||||||
|
|
||||||
@register.filter
|
@register.filter
|
||||||
def is_negative(value):
|
def is_negative(value):
|
||||||
"""
|
"""
|
||||||
@ -23,6 +24,7 @@ def is_negative(value):
|
|||||||
except (ValueError, TypeError):
|
except (ValueError, TypeError):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
@register.filter
|
@register.filter
|
||||||
def get_percentage(value, total):
|
def get_percentage(value, total):
|
||||||
try:
|
try:
|
||||||
@ -501,8 +503,16 @@ def bill_item_formset_table(context, item_formset):
|
|||||||
for item in item_formset:
|
for item in item_formset:
|
||||||
if item:
|
if item:
|
||||||
print(item.fields["item_model"])
|
print(item.fields["item_model"])
|
||||||
item.initial["quantity"] = item.instance.po_quantity if item.instance.po_quantity else item.instance.quantity
|
item.initial["quantity"] = (
|
||||||
item.initial["unit_cost"] = item.instance.po_unit_cost if item.instance.po_unit_cost else item.instance.unit_cost
|
item.instance.po_quantity
|
||||||
|
if item.instance.po_quantity
|
||||||
|
else item.instance.quantity
|
||||||
|
)
|
||||||
|
item.initial["unit_cost"] = (
|
||||||
|
item.instance.po_unit_cost
|
||||||
|
if item.instance.po_unit_cost
|
||||||
|
else item.instance.unit_cost
|
||||||
|
)
|
||||||
# print(item.instance.po_quantity)
|
# print(item.instance.po_quantity)
|
||||||
# print(item.instance.po_unit_cost)
|
# print(item.instance.po_unit_cost)
|
||||||
# print(item.instance.po_total_amount)
|
# print(item.instance.po_total_amount)
|
||||||
|
|||||||
@ -2,7 +2,7 @@ from inventory.utils import get_user_type
|
|||||||
from . import views
|
from . import views
|
||||||
from django.urls import path
|
from django.urls import path
|
||||||
from django.urls import reverse_lazy
|
from django.urls import reverse_lazy
|
||||||
from django.views.generic import RedirectView,TemplateView
|
from django.views.generic import RedirectView, TemplateView
|
||||||
from django_tables2.export.export import TableExport
|
from django_tables2.export.export import TableExport
|
||||||
from django.conf.urls import handler403, handler400, handler404, handler500
|
from django.conf.urls import handler403, handler400, handler404, handler500
|
||||||
|
|
||||||
@ -10,14 +10,17 @@ urlpatterns = [
|
|||||||
# main URLs
|
# main URLs
|
||||||
path("", views.WelcomeView, name="welcome"),
|
path("", views.WelcomeView, name="welcome"),
|
||||||
# path("signup/", views.dealer_signup, name="account_signup"),
|
# path("signup/", views.dealer_signup, name="account_signup"),
|
||||||
path('signup/', views.CarDealershipSignUpView.as_view(), name='account_signup'),
|
path("signup/", views.CarDealershipSignUpView.as_view(), name="account_signup"),
|
||||||
path('success/', TemplateView.as_view(template_name='account/success.html'), name='registration_success'),
|
path(
|
||||||
|
"success/",
|
||||||
|
TemplateView.as_view(template_name="account/success.html"),
|
||||||
|
name="registration_success",
|
||||||
|
),
|
||||||
path("", views.HomeView, name="home"),
|
path("", views.HomeView, name="home"),
|
||||||
# path('refund-policy/',views.refund_policy,name='refund_policy'),
|
# path('refund-policy/',views.refund_policy,name='refund_policy'),
|
||||||
path("<slug:dealer_slug>/", views.HomeView, name="home"),
|
path("<slug:dealer_slug>/", views.HomeView, name="home"),
|
||||||
# Tasks
|
# Tasks
|
||||||
path("legal/", views.terms_and_privacy, name="terms_and_privacy"),
|
path("legal/", views.terms_and_privacy, name="terms_and_privacy"),
|
||||||
|
|
||||||
# path('tasks/<int:task_id>/detail/', views.task_detail, name='task_detail'),
|
# path('tasks/<int:task_id>/detail/', views.task_detail, name='task_detail'),
|
||||||
# Dashboards
|
# Dashboards
|
||||||
# path("user/<int:pk>/settings/", views.UserSettingsView.as_view(), name="user_settings"),
|
# path("user/<int:pk>/settings/", views.UserSettingsView.as_view(), name="user_settings"),
|
||||||
@ -44,13 +47,18 @@ urlpatterns = [
|
|||||||
views.assign_car_makes,
|
views.assign_car_makes,
|
||||||
name="assign_car_makes",
|
name="assign_car_makes",
|
||||||
),
|
),
|
||||||
|
# dashboards for manager, dealer, inventory and accounatant
|
||||||
|
path(
|
||||||
#dashboards for manager, dealer, inventory and accounatant
|
"dashboards/<slug:dealer_slug>/general/",
|
||||||
path("dashboards/<slug:dealer_slug>/general/", views.general_dashboard,name="general_dashboard"),
|
views.general_dashboard,
|
||||||
#dashboard for sales
|
name="general_dashboard",
|
||||||
path("dashboards/<slug:dealer_slug>/sales/", views.sales_dashboard, name="sales_dashboard"),
|
),
|
||||||
|
# dashboard for sales
|
||||||
|
path(
|
||||||
|
"dashboards/<slug:dealer_slug>/sales/",
|
||||||
|
views.sales_dashboard,
|
||||||
|
name="sales_dashboard",
|
||||||
|
),
|
||||||
path(
|
path(
|
||||||
"<slug:dealer_slug>/cars/aging-inventory/list",
|
"<slug:dealer_slug>/cars/aging-inventory/list",
|
||||||
views.aging_inventory_list_view,
|
views.aging_inventory_list_view,
|
||||||
@ -786,7 +794,11 @@ urlpatterns = [
|
|||||||
views.EstimateDetailView.as_view(),
|
views.EstimateDetailView.as_view(),
|
||||||
name="estimate_detail",
|
name="estimate_detail",
|
||||||
),
|
),
|
||||||
path('<slug:dealer_slug>/sales/estimates/print/<uuid:pk>/', views.EstimatePrintView.as_view(), name='estimate_print'),
|
path(
|
||||||
|
"<slug:dealer_slug>/sales/estimates/print/<uuid:pk>/",
|
||||||
|
views.EstimatePrintView.as_view(),
|
||||||
|
name="estimate_print",
|
||||||
|
),
|
||||||
path(
|
path(
|
||||||
"<slug:dealer_slug>/sales/estimates/create/",
|
"<slug:dealer_slug>/sales/estimates/create/",
|
||||||
views.create_estimate,
|
views.create_estimate,
|
||||||
@ -943,7 +955,6 @@ urlpatterns = [
|
|||||||
views.ItemServiceUpdateView.as_view(),
|
views.ItemServiceUpdateView.as_view(),
|
||||||
name="item_service_update",
|
name="item_service_update",
|
||||||
),
|
),
|
||||||
|
|
||||||
path(
|
path(
|
||||||
"<slug:dealer_slug>/items/services/<int:pk>/detail/",
|
"<slug:dealer_slug>/items/services/<int:pk>/detail/",
|
||||||
views.ItemServiceDetailView.as_view(),
|
views.ItemServiceDetailView.as_view(),
|
||||||
@ -1112,32 +1123,47 @@ urlpatterns = [
|
|||||||
name="entity-ic-date",
|
name="entity-ic-date",
|
||||||
),
|
),
|
||||||
# Chart of Accounts...
|
# Chart of Accounts...
|
||||||
path('<slug:dealer_slug>/chart-of-accounts/<slug:entity_slug>/list/',
|
path(
|
||||||
|
"<slug:dealer_slug>/chart-of-accounts/<slug:entity_slug>/list/",
|
||||||
views.ChartOfAccountModelListView.as_view(),
|
views.ChartOfAccountModelListView.as_view(),
|
||||||
name='coa-list'),
|
name="coa-list",
|
||||||
path('<slug:dealer_slug>/chart-of-accounts/<slug:entity_slug>/list/inactive/',
|
),
|
||||||
views.ChartOfAccountModelListView.as_view(inactive=True),
|
path(
|
||||||
name='coa-list-inactive'),
|
"<slug:dealer_slug>/chart-of-accounts/<slug:entity_slug>/list/inactive/",
|
||||||
path('<slug:dealer_slug>/<slug:entity_slug>/create/',
|
views.ChartOfAccountModelListView.as_view(inactive=True),
|
||||||
views.ChartOfAccountModelCreateView.as_view(),
|
name="coa-list-inactive",
|
||||||
name='coa-create'),
|
),
|
||||||
path('<slug:dealer_slug>/<slug:entity_slug>/detail/<slug:coa_slug>/',
|
path(
|
||||||
views.ChartOfAccountModelListView.as_view(),
|
"<slug:dealer_slug>/<slug:entity_slug>/create/",
|
||||||
name='coa-detail'),
|
views.ChartOfAccountModelCreateView.as_view(),
|
||||||
path('<slug:dealer_slug>/<slug:entity_slug>/update/<slug:coa_slug>/',
|
name="coa-create",
|
||||||
views.ChartOfAccountModelUpdateView.as_view(),
|
),
|
||||||
name='coa-update'),
|
path(
|
||||||
|
"<slug:dealer_slug>/<slug:entity_slug>/detail/<slug:coa_slug>/",
|
||||||
|
views.ChartOfAccountModelListView.as_view(),
|
||||||
|
name="coa-detail",
|
||||||
|
),
|
||||||
|
path(
|
||||||
|
"<slug:dealer_slug>/<slug:entity_slug>/update/<slug:coa_slug>/",
|
||||||
|
views.ChartOfAccountModelUpdateView.as_view(),
|
||||||
|
name="coa-update",
|
||||||
|
),
|
||||||
# ACTIONS....
|
# ACTIONS....
|
||||||
path('<slug:dealer_slug>/<slug:entity_slug>/action/<slug:coa_slug>/mark-as-default/',
|
path(
|
||||||
views.CharOfAccountModelActionView.as_view(action_name='mark_as_default'),
|
"<slug:dealer_slug>/<slug:entity_slug>/action/<slug:coa_slug>/mark-as-default/",
|
||||||
name='coa-action-mark-as-default'),
|
views.CharOfAccountModelActionView.as_view(action_name="mark_as_default"),
|
||||||
path('<slug:dealer_slug>/<slug:entity_slug>/action/<slug:coa_slug>/mark-as-active/',
|
name="coa-action-mark-as-default",
|
||||||
views.CharOfAccountModelActionView.as_view(action_name='mark_as_active'),
|
),
|
||||||
name='coa-action-mark-as-active'),
|
path(
|
||||||
path('<slug:dealer_slug>/<slug:entity_slug>/action/<slug:coa_slug>/mark-as-inactive/',
|
"<slug:dealer_slug>/<slug:entity_slug>/action/<slug:coa_slug>/mark-as-active/",
|
||||||
views.CharOfAccountModelActionView.as_view(action_name='mark_as_inactive'),
|
views.CharOfAccountModelActionView.as_view(action_name="mark_as_active"),
|
||||||
name='coa-action-mark-as-inactive'),
|
name="coa-action-mark-as-active",
|
||||||
|
),
|
||||||
|
path(
|
||||||
|
"<slug:dealer_slug>/<slug:entity_slug>/action/<slug:coa_slug>/mark-as-inactive/",
|
||||||
|
views.CharOfAccountModelActionView.as_view(action_name="mark_as_inactive"),
|
||||||
|
name="coa-action-mark-as-inactive",
|
||||||
|
),
|
||||||
# CASH FLOW STATEMENTS...
|
# CASH FLOW STATEMENTS...
|
||||||
# Entities...
|
# Entities...
|
||||||
path(
|
path(
|
||||||
@ -1313,42 +1339,80 @@ urlpatterns = [
|
|||||||
views.PurchaseOrderMarkAsVoidView.as_view(),
|
views.PurchaseOrderMarkAsVoidView.as_view(),
|
||||||
name="po-action-mark-as-void",
|
name="po-action-mark-as-void",
|
||||||
),
|
),
|
||||||
|
|
||||||
# reports
|
# reports
|
||||||
path(
|
path(
|
||||||
"<slug:dealer_slug>/purchase-report/",
|
"<slug:dealer_slug>/purchase-report/",
|
||||||
views.purchase_report_view,
|
views.purchase_report_view,
|
||||||
name="po-report",
|
name="po-report",
|
||||||
),
|
),
|
||||||
path('purchase-report/<slug:dealer_slug>/csv/', views.purchase_report_csv_export, name='purchase-report-csv-export'),
|
path(
|
||||||
|
"purchase-report/<slug:dealer_slug>/csv/",
|
||||||
path(
|
views.purchase_report_csv_export,
|
||||||
|
name="purchase-report-csv-export",
|
||||||
|
),
|
||||||
|
path(
|
||||||
"<slug:dealer_slug>/car-sale-report/",
|
"<slug:dealer_slug>/car-sale-report/",
|
||||||
views.car_sale_report_view,
|
views.car_sale_report_view,
|
||||||
name="car-sale-report",
|
name="car-sale-report",
|
||||||
),
|
),
|
||||||
path('<slug:dealer_slug>/car-sale-report/get_filtered_choices/',views.get_filtered_choices,name='get_filtered_choices'),
|
path(
|
||||||
path('car-sale-report/<slug:dealer_slug>/csv/', views.car_sale_report_csv_export, name='car-sale-report-csv-export'),
|
"<slug:dealer_slug>/car-sale-report/get_filtered_choices/",
|
||||||
|
views.get_filtered_choices,
|
||||||
path('feature/recall/', views.RecallListView.as_view(), name='recall_list'),
|
name="get_filtered_choices",
|
||||||
path('feature/recall/filter/', views.RecallFilterView, name='recall_filter'),
|
),
|
||||||
path('feature/recall/<int:pk>/view/', views.RecallDetailView.as_view(), name='recall_detail'),
|
path(
|
||||||
path('feature/recall/create/', views.RecallCreateView.as_view(), name='recall_create'),
|
"car-sale-report/<slug:dealer_slug>/csv/",
|
||||||
path('feature/recall/success/', views.RecallSuccessView.as_view(), name='recall_success'),
|
views.car_sale_report_csv_export,
|
||||||
|
name="car-sale-report-csv-export",
|
||||||
path('<slug:dealer_slug>/schedules/calendar/', views.schedule_calendar, name='schedule_calendar'),
|
),
|
||||||
|
path("feature/recall/", views.RecallListView.as_view(), name="recall_list"),
|
||||||
|
path("feature/recall/filter/", views.RecallFilterView, name="recall_filter"),
|
||||||
|
path(
|
||||||
|
"feature/recall/<int:pk>/view/",
|
||||||
|
views.RecallDetailView.as_view(),
|
||||||
|
name="recall_detail",
|
||||||
|
),
|
||||||
|
path(
|
||||||
|
"feature/recall/create/", views.RecallCreateView.as_view(), name="recall_create"
|
||||||
|
),
|
||||||
|
path(
|
||||||
|
"feature/recall/success/",
|
||||||
|
views.RecallSuccessView.as_view(),
|
||||||
|
name="recall_success",
|
||||||
|
),
|
||||||
|
path(
|
||||||
|
"<slug:dealer_slug>/schedules/calendar/",
|
||||||
|
views.schedule_calendar,
|
||||||
|
name="schedule_calendar",
|
||||||
|
),
|
||||||
# staff profile
|
# staff profile
|
||||||
path('<slug:dealer_slug>/staff/<slug:slug>detail/', views.StaffDetailView.as_view(), name='staff_detail'),
|
path(
|
||||||
|
"<slug:dealer_slug>/staff/<slug:slug>detail/",
|
||||||
|
views.StaffDetailView.as_view(),
|
||||||
|
name="staff_detail",
|
||||||
|
),
|
||||||
# tickets
|
# tickets
|
||||||
path('help_center/view/', views.help_center, name='help_center'),
|
path("help_center/view/", views.help_center, name="help_center"),
|
||||||
path('<slug:dealer_slug>/help_center/tickets/', views.ticket_list, name='ticket_list'),
|
path(
|
||||||
path('help_center/tickets/<slug:dealer_slug>/create/', views.create_ticket, name='create_ticket'),
|
"<slug:dealer_slug>/help_center/tickets/", views.ticket_list, name="ticket_list"
|
||||||
path('<slug:dealer_slug>/help_center/tickets/<int:ticket_id>/', views.ticket_detail, name='ticket_detail'),
|
),
|
||||||
path('help_center/tickets/<int:ticket_id>/update/', views.ticket_update, name='ticket_update'),
|
path(
|
||||||
|
"help_center/tickets/<slug:dealer_slug>/create/",
|
||||||
|
views.create_ticket,
|
||||||
|
name="create_ticket",
|
||||||
|
),
|
||||||
|
path(
|
||||||
|
"<slug:dealer_slug>/help_center/tickets/<int:ticket_id>/",
|
||||||
|
views.ticket_detail,
|
||||||
|
name="ticket_detail",
|
||||||
|
),
|
||||||
|
path(
|
||||||
|
"help_center/tickets/<int:ticket_id>/update/",
|
||||||
|
views.ticket_update,
|
||||||
|
name="ticket_update",
|
||||||
|
),
|
||||||
# path('help_center/tickets/<int:ticket_id>/ticket_mark_resolved/', views.ticket_mark_resolved, name='ticket_mark_resolved'),
|
# path('help_center/tickets/<int:ticket_id>/ticket_mark_resolved/', views.ticket_mark_resolved, name='ticket_mark_resolved'),
|
||||||
path('payment_results/', views.payment_result, name='payment_result'),
|
path("payment_results/", views.payment_result, name="payment_result"),
|
||||||
|
|
||||||
]
|
]
|
||||||
|
|
||||||
handler404 = "inventory.views.custom_page_not_found_view"
|
handler404 = "inventory.views.custom_page_not_found_view"
|
||||||
|
|||||||
@ -27,7 +27,7 @@ from django_ledger.models import (
|
|||||||
VendorModel,
|
VendorModel,
|
||||||
AccountModel,
|
AccountModel,
|
||||||
EntityModel,
|
EntityModel,
|
||||||
ChartOfAccountModel
|
ChartOfAccountModel,
|
||||||
)
|
)
|
||||||
from django.core.files.base import ContentFile
|
from django.core.files.base import ContentFile
|
||||||
from django_ledger.models.items import ItemModel
|
from django_ledger.models.items import ItemModel
|
||||||
@ -1329,9 +1329,9 @@ def get_finance_data(estimate, dealer):
|
|||||||
additional_services = car.get_additional_services()
|
additional_services = car.get_additional_services()
|
||||||
discounted_price = Decimal(car.marked_price) - discount
|
discounted_price = Decimal(car.marked_price) - discount
|
||||||
vat_amount = discounted_price * vat.rate
|
vat_amount = discounted_price * vat.rate
|
||||||
total_services_amount=additional_services.get("total")
|
total_services_amount = additional_services.get("total")
|
||||||
total_services_vat = sum([x[1] for x in additional_services.get("services")])
|
total_services_vat = sum([x[1] for x in additional_services.get("services")])
|
||||||
total_services_amount_=additional_services.get("total_")
|
total_services_amount_ = additional_services.get("total_")
|
||||||
total_vat = vat_amount + total_services_vat
|
total_vat = vat_amount + total_services_vat
|
||||||
return {
|
return {
|
||||||
"car": car,
|
"car": car,
|
||||||
@ -1342,16 +1342,11 @@ def get_finance_data(estimate, dealer):
|
|||||||
"discount_amount": discount,
|
"discount_amount": discount,
|
||||||
"additional_services": additional_services,
|
"additional_services": additional_services,
|
||||||
"final_price": discounted_price + vat_amount,
|
"final_price": discounted_price + vat_amount,
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
"total_services_vat": total_services_vat,
|
"total_services_vat": total_services_vat,
|
||||||
"total_services_amount":total_services_amount,
|
"total_services_amount": total_services_amount,
|
||||||
"total_services_amount_":total_services_amount_,
|
"total_services_amount_": total_services_amount_,
|
||||||
|
|
||||||
"total_vat": total_vat,
|
"total_vat": total_vat,
|
||||||
"grand_total": discounted_price + total_vat + additional_services.get("total"),
|
"grand_total": discounted_price + total_vat + additional_services.get("total"),
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# totals = self.calculate_totals()
|
# totals = self.calculate_totals()
|
||||||
@ -1605,43 +1600,69 @@ def _post_sale_and_cogs(invoice, dealer):
|
|||||||
1) Cash / A-R / VAT / Revenue journal
|
1) Cash / A-R / VAT / Revenue journal
|
||||||
2) COGS / Inventory journal
|
2) COGS / Inventory journal
|
||||||
"""
|
"""
|
||||||
entity:EntityModel = invoice.ledger.entity
|
entity: EntityModel = invoice.ledger.entity
|
||||||
# calc = CarFinanceCalculator(invoice)
|
# calc = CarFinanceCalculator(invoice)
|
||||||
data = get_finance_data(invoice, dealer)
|
data = get_finance_data(invoice, dealer)
|
||||||
|
|
||||||
car = data.get("car")
|
car = data.get("car")
|
||||||
|
|
||||||
coa:ChartOfAccountModel = entity.get_default_coa()
|
coa: ChartOfAccountModel = entity.get_default_coa()
|
||||||
cash_acc = invoice.cash_account or dealer.settings.invoice_cash_account
|
cash_acc = invoice.cash_account or dealer.settings.invoice_cash_account
|
||||||
|
|
||||||
vat_acc = dealer.settings.invoice_tax_payable_account or entity.get_default_coa_accounts().filter(role_default=True, role=roles.LIABILITY_CL_TAXES_PAYABLE).first()
|
vat_acc = (
|
||||||
|
dealer.settings.invoice_tax_payable_account
|
||||||
|
or entity.get_default_coa_accounts()
|
||||||
|
.filter(role_default=True, role=roles.LIABILITY_CL_TAXES_PAYABLE)
|
||||||
|
.first()
|
||||||
|
)
|
||||||
|
|
||||||
car_rev = dealer.settings.invoice_vehicle_sale_account or entity.get_default_coa_accounts().filter(role_default=True, role=roles.INCOME_OPERATIONAL).first()
|
car_rev = (
|
||||||
|
dealer.settings.invoice_vehicle_sale_account
|
||||||
|
or entity.get_default_coa_accounts()
|
||||||
|
.filter(role_default=True, role=roles.INCOME_OPERATIONAL)
|
||||||
|
.first()
|
||||||
|
)
|
||||||
|
|
||||||
add_rev = dealer.settings.invoice_additional_services_account
|
add_rev = dealer.settings.invoice_additional_services_account
|
||||||
|
|
||||||
if not add_rev:
|
if not add_rev:
|
||||||
try:
|
try:
|
||||||
add_rev = entity.get_default_coa_accounts().filter(name="After-Sales Services", active=True).first()
|
add_rev = (
|
||||||
|
entity.get_default_coa_accounts()
|
||||||
|
.filter(name="After-Sales Services", active=True)
|
||||||
|
.first()
|
||||||
|
)
|
||||||
if not add_rev:
|
if not add_rev:
|
||||||
add_rev = coa.create_account(
|
add_rev = coa.create_account(
|
||||||
code="4020",
|
code="4020",
|
||||||
name="After-Sales Services",
|
name="After-Sales Services",
|
||||||
role=roles.INCOME_OPERATIONAL,
|
role=roles.INCOME_OPERATIONAL,
|
||||||
balance_type=roles.CREDIT,
|
balance_type=roles.CREDIT,
|
||||||
active=True,
|
active=True,
|
||||||
)
|
)
|
||||||
add_rev.role_default = False
|
add_rev.role_default = False
|
||||||
add_rev.save(update_fields=['role_default'])
|
add_rev.save(update_fields=["role_default"])
|
||||||
dealer.settings.invoice_additional_services_account = add_rev
|
dealer.settings.invoice_additional_services_account = add_rev
|
||||||
dealer.settings.save()
|
dealer.settings.save()
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"error find or create additional services account {e}")
|
logger.error(f"error find or create additional services account {e}")
|
||||||
if car.get_additional_services_amount > 0 and not add_rev:
|
if car.get_additional_services_amount > 0 and not add_rev:
|
||||||
raise Exception("additional services exist but not account found,please create account for the additional services and set as default in the settings")
|
raise Exception(
|
||||||
cogs_acc = dealer.settings.invoice_cost_of_good_sold_account or entity.get_default_coa_accounts().filter(role_default=True, role=roles.COGS).first()
|
"additional services exist but not account found,please create account for the additional services and set as default in the settings"
|
||||||
|
)
|
||||||
|
cogs_acc = (
|
||||||
|
dealer.settings.invoice_cost_of_good_sold_account
|
||||||
|
or entity.get_default_coa_accounts()
|
||||||
|
.filter(role_default=True, role=roles.COGS)
|
||||||
|
.first()
|
||||||
|
)
|
||||||
|
|
||||||
inv_acc = dealer.settings.invoice_inventory_account or entity.get_default_coa_accounts().filter(role_default=True, role=roles.ASSET_CA_INVENTORY).first()
|
inv_acc = (
|
||||||
|
dealer.settings.invoice_inventory_account
|
||||||
|
or entity.get_default_coa_accounts()
|
||||||
|
.filter(role_default=True, role=roles.ASSET_CA_INVENTORY)
|
||||||
|
.first()
|
||||||
|
)
|
||||||
|
|
||||||
net_car_price = Decimal(data["discounted_price"])
|
net_car_price = Decimal(data["discounted_price"])
|
||||||
net_additionals_price = Decimal(data["additional_services"]["total"])
|
net_additionals_price = Decimal(data["additional_services"]["total"])
|
||||||
@ -1696,11 +1717,12 @@ def _post_sale_and_cogs(invoice, dealer):
|
|||||||
# tx_type='credit'
|
# tx_type='credit'
|
||||||
# )
|
# )
|
||||||
|
|
||||||
|
|
||||||
if car.get_additional_services_amount > 0:
|
if car.get_additional_services_amount > 0:
|
||||||
# Cr Sales – Additional Services
|
# Cr Sales – Additional Services
|
||||||
if not add_rev:
|
if not add_rev:
|
||||||
logger.warning(f"Additional Services account not set for dealer {dealer}. Skipping additional services revenue entry.")
|
logger.warning(
|
||||||
|
f"Additional Services account not set for dealer {dealer}. Skipping additional services revenue entry."
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
TransactionModel.objects.create(
|
TransactionModel.objects.create(
|
||||||
journal_entry=je_sale,
|
journal_entry=je_sale,
|
||||||
@ -1938,7 +1960,7 @@ def handle_payment(request, dealer):
|
|||||||
}
|
}
|
||||||
|
|
||||||
# Get selected plan from session
|
# Get selected plan from session
|
||||||
selected_plan_id = request.session.get('pending_plan_id')
|
selected_plan_id = request.session.get("pending_plan_id")
|
||||||
if not selected_plan_id:
|
if not selected_plan_id:
|
||||||
raise ValueError("No pending plan found in session")
|
raise ValueError("No pending plan found in session")
|
||||||
from plans.models import PlanPricing
|
from plans.models import PlanPricing
|
||||||
@ -1956,25 +1978,27 @@ def handle_payment(request, dealer):
|
|||||||
"dealer_slug": dealer.slug,
|
"dealer_slug": dealer.slug,
|
||||||
}
|
}
|
||||||
|
|
||||||
payload = json.dumps({
|
payload = json.dumps(
|
||||||
"amount": total,
|
{
|
||||||
"currency": "SAR",
|
"amount": total,
|
||||||
"description": f"Payment for plan {pp.plan.name}",
|
"currency": "SAR",
|
||||||
"callback_url": callback_url,
|
"description": f"Payment for plan {pp.plan.name}",
|
||||||
"source": {
|
"callback_url": callback_url,
|
||||||
"type": "creditcard",
|
"source": {
|
||||||
"name": card_name,
|
"type": "creditcard",
|
||||||
"number": card_number,
|
"name": card_name,
|
||||||
"month": month,
|
"number": card_number,
|
||||||
"year": year,
|
"month": month,
|
||||||
"cvc": cvv,
|
"year": year,
|
||||||
"statement_descriptor": "Century Store",
|
"cvc": cvv,
|
||||||
"3ds": True,
|
"statement_descriptor": "Century Store",
|
||||||
"manual": False,
|
"3ds": True,
|
||||||
"save_card": False,
|
"manual": False,
|
||||||
},
|
"save_card": False,
|
||||||
"metadata": metadata,
|
},
|
||||||
})
|
"metadata": metadata,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
headers = {"Content-Type": "application/json", "Accept": "application/json"}
|
headers = {"Content-Type": "application/json", "Accept": "application/json"}
|
||||||
auth = (settings.MOYASAR_SECRET_KEY, "")
|
auth = (settings.MOYASAR_SECRET_KEY, "")
|
||||||
@ -1998,7 +2022,9 @@ def handle_payment(request, dealer):
|
|||||||
gateway_response=data,
|
gateway_response=data,
|
||||||
)
|
)
|
||||||
logger.info(f"Payment initiated: {data}")
|
logger.info(f"Payment initiated: {data}")
|
||||||
return data["source"]["transaction_url"],None
|
return data["source"]["transaction_url"], None
|
||||||
|
|
||||||
|
|
||||||
# def handle_payment(request, order):
|
# def handle_payment(request, order):
|
||||||
# logger.info(f"Handling payment for order {order}")
|
# logger.info(f"Handling payment for order {order}")
|
||||||
# url = "https://api.moyasar.com/v1/payments"
|
# url = "https://api.moyasar.com/v1/payments"
|
||||||
@ -2518,10 +2544,9 @@ def create_account(entity, coa, account_data):
|
|||||||
logger.info(f"Created account: {account}")
|
logger.info(f"Created account: {account}")
|
||||||
if account:
|
if account:
|
||||||
account.role_default = account_data.get("default", False)
|
account.role_default = account_data.get("default", False)
|
||||||
account.save(update_fields=['role_default'])
|
account.save(update_fields=["role_default"])
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
except IntegrityError:
|
except IntegrityError:
|
||||||
return True # Already created by race condition
|
return True # Already created by race condition
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@ -2529,6 +2554,7 @@ def create_account(entity, coa, account_data):
|
|||||||
|
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
# def create_account(entity, coa, account_data):
|
# def create_account(entity, coa, account_data):
|
||||||
# try:
|
# try:
|
||||||
# account = entity.create_account(
|
# account = entity.create_account(
|
||||||
@ -2810,7 +2836,9 @@ def generate_car_image_simple(car):
|
|||||||
# Save the resized image
|
# Save the resized image
|
||||||
logger.info(f" {car.vin}")
|
logger.info(f" {car.vin}")
|
||||||
with open(
|
with open(
|
||||||
os.path.join(settings.MEDIA_ROOT, f"car_images/{car.get_hash}.{file_extension}"),
|
os.path.join(
|
||||||
|
settings.MEDIA_ROOT, f"car_images/{car.get_hash}.{file_extension}"
|
||||||
|
),
|
||||||
"wb",
|
"wb",
|
||||||
) as f:
|
) as f:
|
||||||
f.write(resized_data)
|
f.write(resized_data)
|
||||||
@ -2826,9 +2854,7 @@ def generate_car_image_simple(car):
|
|||||||
return {"success": False, "error": error_msg}
|
return {"success": False, "error": error_msg}
|
||||||
|
|
||||||
|
|
||||||
|
def create_estimate_(dealer, car, customer):
|
||||||
|
|
||||||
def create_estimate_(dealer,car,customer):
|
|
||||||
entity = dealer.entity
|
entity = dealer.entity
|
||||||
title = f"Estimate for {car.vin}-{car.id_car_make.name}-{car.id_car_model.name}-{car.year} for customer {customer.first_name} {customer.last_name}"
|
title = f"Estimate for {car.vin}-{car.id_car_make.name}-{car.id_car_model.name}-{car.year} for customer {customer.first_name} {customer.last_name}"
|
||||||
estimate = entity.create_estimate(
|
estimate = entity.create_estimate(
|
||||||
@ -2856,4 +2882,4 @@ def create_estimate_(dealer,car,customer):
|
|||||||
estimate.delete()
|
estimate.delete()
|
||||||
raise e
|
raise e
|
||||||
|
|
||||||
return estimate
|
return estimate
|
||||||
|
|||||||
@ -16,9 +16,10 @@ class SaudiPhoneNumberValidator(RegexValidator):
|
|||||||
cleaned_value = re.sub(r"[\s\-\(\)\.]", "", str(value))
|
cleaned_value = re.sub(r"[\s\-\(\)\.]", "", str(value))
|
||||||
super().__call__(cleaned_value)
|
super().__call__(cleaned_value)
|
||||||
|
|
||||||
|
|
||||||
def vat_rate_validator(value):
|
def vat_rate_validator(value):
|
||||||
if value < 0 or value > 1:
|
if value < 0 or value > 1:
|
||||||
raise ValidationError(
|
raise ValidationError(
|
||||||
_('%(value)s is not a valid VAT rate. It must be between 0 and 1.'),
|
_("%(value)s is not a valid VAT rate. It must be between 0 and 1."),
|
||||||
params={'value': value},
|
params={"value": value},
|
||||||
)
|
)
|
||||||
|
|||||||
2119
inventory/views.py
2119
inventory/views.py
File diff suppressed because it is too large
Load Diff
@ -7,7 +7,9 @@ autobahn==24.4.2
|
|||||||
Automat==25.4.16
|
Automat==25.4.16
|
||||||
Babel==2.15.0
|
Babel==2.15.0
|
||||||
beautifulsoup4==4.13.4
|
beautifulsoup4==4.13.4
|
||||||
|
blacknoise==1.2.0
|
||||||
blessed==1.21.0
|
blessed==1.21.0
|
||||||
|
Brotli==1.1.0
|
||||||
cattrs==25.1.1
|
cattrs==25.1.1
|
||||||
certifi==2025.7.9
|
certifi==2025.7.9
|
||||||
cffi==1.17.1
|
cffi==1.17.1
|
||||||
@ -19,15 +21,13 @@ constantly==23.10.4
|
|||||||
crispy-bootstrap5==2025.6
|
crispy-bootstrap5==2025.6
|
||||||
cryptography==45.0.5
|
cryptography==45.0.5
|
||||||
cssbeautifier==1.15.4
|
cssbeautifier==1.15.4
|
||||||
daphne==4.2.1
|
cssselect2==0.8.0
|
||||||
defusedxml==0.7.1
|
defusedxml==0.7.1
|
||||||
diff-match-patch==20241021
|
diff-match-patch==20241021
|
||||||
distro==1.9.0
|
distro==1.9.0
|
||||||
Django==5.2.4
|
Django==5.2.4
|
||||||
django-allauth==65.10.0
|
django-allauth==65.10.0
|
||||||
django-appconf==1.1.0
|
django-appconf==1.1.0
|
||||||
django-appointment==3.8.0
|
|
||||||
django-background-tasks==1.2.8
|
|
||||||
django-bootstrap5==25.1
|
django-bootstrap5==25.1
|
||||||
django-ckeditor==6.7.3
|
django-ckeditor==6.7.3
|
||||||
django-cors-headers==4.7.0
|
django-cors-headers==4.7.0
|
||||||
@ -35,6 +35,7 @@ django-countries==7.6.1
|
|||||||
django-crispy-forms==2.4
|
django-crispy-forms==2.4
|
||||||
django-debug-toolbar==5.2.0
|
django-debug-toolbar==5.2.0
|
||||||
django-easy-audit==1.3.7
|
django-easy-audit==1.3.7
|
||||||
|
django-encrypted-model-fields==0.6.5
|
||||||
django-extensions==4.1
|
django-extensions==4.1
|
||||||
django-filter==25.1
|
django-filter==25.1
|
||||||
django-imagekit==5.0.0
|
django-imagekit==5.0.0
|
||||||
@ -47,7 +48,6 @@ django-ordered-model==3.7.4
|
|||||||
django-phonenumber-field==8.0.0
|
django-phonenumber-field==8.0.0
|
||||||
django-picklefield==3.3
|
django-picklefield==3.3
|
||||||
django-plans==2.0.0
|
django-plans==2.0.0
|
||||||
django-prometheus==2.4.1
|
|
||||||
django-q2==1.8.0
|
django-q2==1.8.0
|
||||||
django-query-builder==3.2.0
|
django-query-builder==3.2.0
|
||||||
django-schema-graph==3.1.0
|
django-schema-graph==3.1.0
|
||||||
@ -56,8 +56,6 @@ django-tables2==2.7.5
|
|||||||
django-treebeard==4.7.1
|
django-treebeard==4.7.1
|
||||||
django-widget-tweaks==1.5.0
|
django-widget-tweaks==1.5.0
|
||||||
djangorestframework==3.16.0
|
djangorestframework==3.16.0
|
||||||
djhtml==3.0.8
|
|
||||||
djlint==1.36.4
|
|
||||||
dnspython==2.7.0
|
dnspython==2.7.0
|
||||||
docopt==0.6.2
|
docopt==0.6.2
|
||||||
EditorConfig==0.17.1
|
EditorConfig==0.17.1
|
||||||
@ -78,8 +76,6 @@ hyperlink==21.0.0
|
|||||||
icalendar==6.3.1
|
icalendar==6.3.1
|
||||||
idna==3.10
|
idna==3.10
|
||||||
incremental==24.7.2
|
incremental==24.7.2
|
||||||
iron-core==1.2.1
|
|
||||||
iron-mq==0.9
|
|
||||||
jiter==0.10.0
|
jiter==0.10.0
|
||||||
jsbeautifier==1.15.4
|
jsbeautifier==1.15.4
|
||||||
json5==0.12.0
|
json5==0.12.0
|
||||||
@ -109,16 +105,17 @@ phonenumbers==8.13.42
|
|||||||
pilkit==3.0
|
pilkit==3.0
|
||||||
pillow==10.4.0
|
pillow==10.4.0
|
||||||
priority==1.3.0
|
priority==1.3.0
|
||||||
prometheus_client==0.22.1
|
|
||||||
psycopg2-binary==2.9.10
|
psycopg2-binary==2.9.10
|
||||||
pyasn1==0.6.1
|
pyasn1==0.6.1
|
||||||
pyasn1_modules==0.4.2
|
pyasn1_modules==0.4.2
|
||||||
pycparser==2.22
|
pycparser==2.22
|
||||||
pydantic==2.11.7
|
pydantic==2.11.7
|
||||||
pydantic_core==2.33.2
|
pydantic_core==2.33.2
|
||||||
|
pydyf==0.11.0
|
||||||
Pygments==2.19.2
|
Pygments==2.19.2
|
||||||
pymongo==4.14.1
|
pymongo==4.14.1
|
||||||
pyOpenSSL==25.1.0
|
pyOpenSSL==25.1.0
|
||||||
|
pyphen==0.17.2
|
||||||
python-dateutil==2.9.0.post0
|
python-dateutil==2.9.0.post0
|
||||||
python-dotenv==1.1.1
|
python-dotenv==1.1.1
|
||||||
python-slugify==8.0.4
|
python-slugify==8.0.4
|
||||||
@ -131,8 +128,6 @@ redis==6.2.0
|
|||||||
regex==2024.11.6
|
regex==2024.11.6
|
||||||
requests==2.32.4
|
requests==2.32.4
|
||||||
requests-toolbelt==1.0.0
|
requests-toolbelt==1.0.0
|
||||||
rich==14.0.0
|
|
||||||
ruff==0.12.2
|
|
||||||
service-identity==24.2.0
|
service-identity==24.2.0
|
||||||
setuptools==80.9.0
|
setuptools==80.9.0
|
||||||
six==1.17.0
|
six==1.17.0
|
||||||
@ -140,11 +135,15 @@ sniffio==1.3.1
|
|||||||
soupsieve==2.7
|
soupsieve==2.7
|
||||||
SQLAlchemy==2.0.41
|
SQLAlchemy==2.0.41
|
||||||
sqlparse==0.5.3
|
sqlparse==0.5.3
|
||||||
|
starlette==0.47.3
|
||||||
|
static3==0.7.0
|
||||||
suds==1.2.0
|
suds==1.2.0
|
||||||
swapper==1.3.0
|
swapper==1.3.0
|
||||||
tablib==3.8.0
|
tablib==3.8.0
|
||||||
tenacity==9.1.2
|
tenacity==9.1.2
|
||||||
text-unidecode==1.3
|
text-unidecode==1.3
|
||||||
|
tinycss2==1.4.0
|
||||||
|
tinyhtml5==2.0.0
|
||||||
tqdm==4.67.1
|
tqdm==4.67.1
|
||||||
Twisted==25.5.0
|
Twisted==25.5.0
|
||||||
txaio==25.6.1
|
txaio==25.6.1
|
||||||
@ -156,6 +155,8 @@ urllib3==2.5.0
|
|||||||
uvicorn==0.35.0
|
uvicorn==0.35.0
|
||||||
uvicorn-worker==0.3.0
|
uvicorn-worker==0.3.0
|
||||||
wcwidth==0.2.13
|
wcwidth==0.2.13
|
||||||
whitenoise==6.9.0
|
weasyprint==66.0
|
||||||
|
webencodings==0.5.1
|
||||||
zope.interface==7.2
|
zope.interface==7.2
|
||||||
|
zopfli==0.2.3.post1
|
||||||
zstandard==0.23.0
|
zstandard==0.23.0
|
||||||
|
|||||||
@ -6,9 +6,9 @@
|
|||||||
{% endblock head_title %}
|
{% endblock head_title %}
|
||||||
{% block content %}
|
{% block content %}
|
||||||
{% element h1 %}
|
{% element h1 %}
|
||||||
{% translate "Account Inactive" %}
|
{% translate "Account Inactive" %}
|
||||||
{% endelement %}
|
{% endelement %}
|
||||||
{% element p %}
|
{% element p %}
|
||||||
{% translate "This account is inactive." %}
|
{% translate "This account is inactive." %}
|
||||||
{% endelement %}
|
{% endelement %}
|
||||||
{% endblock content %}
|
{% endblock content %}
|
||||||
|
|||||||
@ -6,43 +6,43 @@
|
|||||||
{% endblock head_title %}
|
{% endblock head_title %}
|
||||||
{% block content %}
|
{% block content %}
|
||||||
{% element h1 %}
|
{% element h1 %}
|
||||||
{% translate "Enter Email Verification Code" %}
|
{% translate "Enter Email Verification Code" %}
|
||||||
{% endelement %}
|
{% endelement %}
|
||||||
{% setvar email_link %}
|
{% setvar email_link %}
|
||||||
<a href="mailto:{{ email }}">{{ email }}</a>
|
<a href="mailto:{{ email }}">{{ email }}</a>
|
||||||
{% endsetvar %}
|
{% endsetvar %}
|
||||||
{% element p %}
|
{% element p %}
|
||||||
{% blocktranslate %}We’ve sent a code to {{ email_link }}. The code expires shortly, so please enter it soon.{% endblocktranslate %}
|
{% blocktranslate %}We’ve sent a code to {{ email_link }}. The code expires shortly, so please enter it soon.{% endblocktranslate %}
|
||||||
{% endelement %}
|
{% endelement %}
|
||||||
{% url 'account_email_verification_sent' as action_url %}
|
{% url 'account_email_verification_sent' as action_url %}
|
||||||
{% element form form=form method="post" action=action_url tags="entrance,email,verification" %}
|
{% element form form=form method="post" action=action_url tags="entrance,email,verification" %}
|
||||||
{% slot body %}
|
{% slot body %}
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
{% element fields form=form unlabeled=True %}
|
{% element fields form=form unlabeled=True %}
|
||||||
{% endelement %}
|
{% endelement %}
|
||||||
{{ redirect_field }}
|
{{ redirect_field }}
|
||||||
{% endslot %}
|
{% endslot %}
|
||||||
{% slot actions %}
|
{% slot actions %}
|
||||||
{% element button type="submit" tags="prominent,confirm" %}
|
{% element button type="submit" tags="prominent,confirm" %}
|
||||||
{% translate "Confirm" %}
|
{% translate "Confirm" %}
|
||||||
{% endelement %}
|
{% endelement %}
|
||||||
{% if cancel_url %}
|
{% if cancel_url %}
|
||||||
{% element button href=cancel_url tags="link,cancel" %}
|
{% element button href=cancel_url tags="link,cancel" %}
|
||||||
{% translate "Cancel" %}
|
{% translate "Cancel" %}
|
||||||
{% endelement %}
|
{% endelement %}
|
||||||
{% else %}
|
{% else %}
|
||||||
{% element button type="submit" form="logout-from-stage" tags="link,cancel" %}
|
{% element button type="submit" form="logout-from-stage" tags="link,cancel" %}
|
||||||
{% translate "Cancel" %}
|
{% translate "Cancel" %}
|
||||||
{% endelement %}
|
{% endelement %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endslot %}
|
{% endslot %}
|
||||||
{% endelement %}
|
{% endelement %}
|
||||||
{% if not cancel_url %}
|
{% if not cancel_url %}
|
||||||
<form id="logout-from-stage"
|
<form id="logout-from-stage"
|
||||||
method="post"
|
method="post"
|
||||||
action="{% url 'account_logout' %}">
|
action="{% url 'account_logout' %}">
|
||||||
<input type="hidden" name="next" value="{% url 'account_login' %}">
|
<input type="hidden" name="next" value="{% url 'account_login' %}">
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
</form>
|
</form>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endblock content %}
|
{% endblock content %}
|
||||||
|
|||||||
@ -28,30 +28,30 @@
|
|||||||
<h3 class="mb-4">{% translate "Enter Sign-In Code" %}</h3>
|
<h3 class="mb-4">{% translate "Enter Sign-In Code" %}</h3>
|
||||||
</div>
|
</div>
|
||||||
{% setvar email_link %}
|
{% setvar email_link %}
|
||||||
<a href="mailto:{{ email }}">{{ email }}</a>
|
<a href="mailto:{{ email }}">{{ email }}</a>
|
||||||
{% endsetvar %}
|
{% endsetvar %}
|
||||||
<p>
|
<p>
|
||||||
{% blocktranslate %}We’ve sent a code to {{ email_link }}. The code expires shortly, so please enter it soon.{% endblocktranslate %}
|
{% blocktranslate %}We’ve sent a code to {{ email_link }}. The code expires shortly, so please enter it soon.{% endblocktranslate %}
|
||||||
</p>
|
</p>
|
||||||
<form method="post"
|
<form method="post"
|
||||||
action="{% url 'account_confirm_login_code' %}"
|
action="{% url 'account_confirm_login_code' %}"
|
||||||
class="form needs-validation"
|
class="form needs-validation"
|
||||||
novalidate>
|
novalidate>
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
{{ redirect_field }}
|
{{ redirect_field }}
|
||||||
{{ form|crispy }}
|
{{ form|crispy }}
|
||||||
<button type="submit" class="btn btn-phoenix-primary btn-sm w-100">{% trans "Sign In" %}</button>
|
<button type="submit" class="btn btn-phoenix-primary btn-sm w-100">{% trans "Sign In" %}</button>
|
||||||
</form>
|
</form>
|
||||||
{% element button type="submit" form="logout-from-stage" tags="link" %}
|
{% element button type="submit" form="logout-from-stage" tags="link" %}
|
||||||
{% translate "Cancel" %}
|
{% translate "Cancel" %}
|
||||||
{% endelement %}
|
{% endelement %}
|
||||||
<form id="logout-from-stage"
|
<form id="logout-from-stage"
|
||||||
method="post"
|
method="post"
|
||||||
action="{% url 'account_logout' %}">
|
action="{% url 'account_logout' %}">
|
||||||
<input type="hidden" name="next" value="{% url 'account_login' %}">
|
<input type="hidden" name="next" value="{% url 'account_login' %}">
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
</form>
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% endblock content %}
|
{% endblock content %}
|
||||||
|
|||||||
@ -50,7 +50,7 @@
|
|||||||
{% if emailaddress.primary %}
|
{% if emailaddress.primary %}
|
||||||
<span class="badge badge-phoenix badge-phoenix-primary email">{% translate "Primary" %}</span>
|
<span class="badge badge-phoenix badge-phoenix-primary email">{% translate "Primary" %}</span>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endwith %}
|
{% endwith %}
|
||||||
</label>
|
</label>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -6,63 +6,63 @@
|
|||||||
{% endblock head_title %}
|
{% endblock head_title %}
|
||||||
{% block content %}
|
{% block content %}
|
||||||
{% element h1 %}
|
{% element h1 %}
|
||||||
{% trans "Email Address" %}
|
{% trans "Email Address" %}
|
||||||
{% endelement %}
|
{% endelement %}
|
||||||
{% if not emailaddresses %}
|
{% if not emailaddresses %}
|
||||||
{% include "account/snippets/warn_no_email.html" %}
|
{% include "account/snippets/warn_no_email.html" %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% url 'account_email' as action_url %}
|
{% url 'account_email' as action_url %}
|
||||||
{% element form method="post" action=action_url %}
|
{% element form method="post" action=action_url %}
|
||||||
{% slot body %}
|
{% slot body %}
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
{% if current_emailaddress %}
|
{% if current_emailaddress %}
|
||||||
{% element field id="current_email" disabled=True type="email" value=current_emailaddress.email %}
|
{% element field id="current_email" disabled=True type="email" value=current_emailaddress.email %}
|
||||||
{% slot label %}
|
{% slot label %}
|
||||||
{% translate "Current email" %}:
|
{% translate "Current email" %}:
|
||||||
{% endslot %}
|
{% endslot %}
|
||||||
{% endelement %}
|
{% endelement %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if new_emailaddress %}
|
{% if new_emailaddress %}
|
||||||
{% element field id="new_email" value=new_emailaddress.email disabled=True type="email" %}
|
{% element field id="new_email" value=new_emailaddress.email disabled=True type="email" %}
|
||||||
{% slot label %}
|
{% slot label %}
|
||||||
{% if not current_emailaddress %}
|
{% if not current_emailaddress %}
|
||||||
{% translate "Current email" %}:
|
{% translate "Current email" %}:
|
||||||
{% else %}
|
{% else %}
|
||||||
{% translate "Changing to" %}:
|
{% translate "Changing to" %}:
|
||||||
|
{% endif %}
|
||||||
|
{% endslot %}
|
||||||
|
{% slot help_text %}
|
||||||
|
{% blocktranslate %}Your email address is still pending verification.{% endblocktranslate %}
|
||||||
|
{% element button form="pending-email" type="submit" name="action_send" tags="minor,secondary" %}
|
||||||
|
{% trans 'Re-send Verification' %}
|
||||||
|
{% endelement %}
|
||||||
|
{% if current_emailaddress %}
|
||||||
|
{% element button form="pending-email" type="submit" name="action_remove" tags="danger,minor" %}
|
||||||
|
{% trans 'Cancel Change' %}
|
||||||
|
{% endelement %}
|
||||||
|
{% endif %}
|
||||||
|
{% endslot %}
|
||||||
|
{% endelement %}
|
||||||
|
{% endif %}
|
||||||
|
{% element field id=form.email.auto_id name="email" value=form.email.value errors=form.email.errors type="email" %}
|
||||||
|
{% slot label %}
|
||||||
|
{% translate "Change to" %}:
|
||||||
|
{% endslot %}
|
||||||
|
{% endelement %}
|
||||||
|
{% endslot %}
|
||||||
|
{% slot actions %}
|
||||||
|
{% element button name="action_add" type="submit" %}
|
||||||
|
{% trans "Change Email" %}
|
||||||
|
{% endelement %}
|
||||||
|
{% endslot %}
|
||||||
|
{% endelement %}
|
||||||
|
{% if new_emailaddress %}
|
||||||
|
<form style="display: none"
|
||||||
|
id="pending-email"
|
||||||
|
method="post"
|
||||||
|
action="{% url 'account_email' %}">
|
||||||
|
{% csrf_token %}
|
||||||
|
<input type="hidden" name="email" value="{{ new_emailaddress.email }}">
|
||||||
|
</form>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endslot %}
|
|
||||||
{% slot help_text %}
|
|
||||||
{% blocktranslate %}Your email address is still pending verification.{% endblocktranslate %}
|
|
||||||
{% element button form="pending-email" type="submit" name="action_send" tags="minor,secondary" %}
|
|
||||||
{% trans 'Re-send Verification' %}
|
|
||||||
{% endelement %}
|
|
||||||
{% if current_emailaddress %}
|
|
||||||
{% element button form="pending-email" type="submit" name="action_remove" tags="danger,minor" %}
|
|
||||||
{% trans 'Cancel Change' %}
|
|
||||||
{% endelement %}
|
|
||||||
{% endif %}
|
|
||||||
{% endslot %}
|
|
||||||
{% endelement %}
|
|
||||||
{% endif %}
|
|
||||||
{% element field id=form.email.auto_id name="email" value=form.email.value errors=form.email.errors type="email" %}
|
|
||||||
{% slot label %}
|
|
||||||
{% translate "Change to" %}:
|
|
||||||
{% endslot %}
|
|
||||||
{% endelement %}
|
|
||||||
{% endslot %}
|
|
||||||
{% slot actions %}
|
|
||||||
{% element button name="action_add" type="submit" %}
|
|
||||||
{% trans "Change Email" %}
|
|
||||||
{% endelement %}
|
|
||||||
{% endslot %}
|
|
||||||
{% endelement %}
|
|
||||||
{% if new_emailaddress %}
|
|
||||||
<form style="display: none"
|
|
||||||
id="pending-email"
|
|
||||||
method="post"
|
|
||||||
action="{% url 'account_email' %}">
|
|
||||||
{% csrf_token %}
|
|
||||||
<input type="hidden" name="email" value="{{ new_emailaddress.email }}">
|
|
||||||
</form>
|
|
||||||
{% endif %}
|
|
||||||
{% endblock content %}
|
{% endblock content %}
|
||||||
|
|||||||
@ -153,437 +153,437 @@
|
|||||||
<p class="mb-0 fw-semibold fs-9">I need help with something</p>
|
<p class="mb-0 fw-semibold fs-9">I need help with something</p>
|
||||||
<span class="fa-solid fa-paper-plane text-primary fs-9 ms-3"></span>
|
<span class="fa-solid fa-paper-plane text-primary fs-9 ms-3"></span>
|
||||||
</a><a class="mb-2 d-inline-flex align-items-center text-decoration-none text-body-emphasis bg-body-hover rounded-pill border border-primary py-2 ps-4 pe-3"
|
</a><a class="mb-2 d-inline-flex align-items-center text-decoration-none text-body-emphasis bg-body-hover rounded-pill border border-primary py-2 ps-4 pe-3"
|
||||||
href="#!">
|
href="#!">
|
||||||
<p class="mb-0 fw-semibold fs-9">I can’t reorder a product I previously ordered</p>
|
<p class="mb-0 fw-semibold fs-9">I can’t reorder a product I previously ordered</p>
|
||||||
<span class="fa-solid fa-paper-plane text-primary fs-9 ms-3"></span>
|
<span class="fa-solid fa-paper-plane text-primary fs-9 ms-3"></span>
|
||||||
</a><a class="mb-2 d-inline-flex align-items-center text-decoration-none text-body-emphasis bg-body-hover rounded-pill border border-primary py-2 ps-4 pe-3"
|
</a><a class="mb-2 d-inline-flex align-items-center text-decoration-none text-body-emphasis bg-body-hover rounded-pill border border-primary py-2 ps-4 pe-3"
|
||||||
href="#!">
|
href="#!">
|
||||||
<p class="mb-0 fw-semibold fs-9">How do I place an order?</p>
|
<p class="mb-0 fw-semibold fs-9">How do I place an order?</p>
|
||||||
<span class="fa-solid fa-paper-plane text-primary fs-9 ms-3"></span>
|
<span class="fa-solid fa-paper-plane text-primary fs-9 ms-3"></span>
|
||||||
</a><a class="false d-inline-flex align-items-center text-decoration-none text-body-emphasis bg-body-hover rounded-pill border border-primary py-2 ps-4 pe-3"
|
</a><a class="false d-inline-flex align-items-center text-decoration-none text-body-emphasis bg-body-hover rounded-pill border border-primary py-2 ps-4 pe-3"
|
||||||
href="#!">
|
href="#!">
|
||||||
<p class="mb-0 fw-semibold fs-9">My payment method not working</p>
|
<p class="mb-0 fw-semibold fs-9">My payment method not working</p>
|
||||||
<span class="fa-solid fa-paper-plane text-primary fs-9 ms-3"></span>
|
<span class="fa-solid fa-paper-plane text-primary fs-9 ms-3"></span>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="text-center mt-auto">
|
<div class="text-center mt-auto">
|
||||||
<div class="avatar avatar-3xl status-online">
|
<div class="avatar avatar-3xl status-online">
|
||||||
<img class="rounded-circle border border-3 border-light-subtle"
|
<img class="rounded-circle border border-3 border-light-subtle"
|
||||||
src="../../../assets/img/team/30.webp"
|
src="../../../assets/img/team/30.webp"
|
||||||
alt="" />
|
alt="" />
|
||||||
|
</div>
|
||||||
|
<h5 class="mt-2 mb-3">Eric</h5>
|
||||||
|
<p class="text-center text-body-emphasis mb-0">
|
||||||
|
Ask us anything – we’ll get back to you here or by email within 24 hours.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="card-footer d-flex align-items-center gap-2 border-top border-translucent ps-3 pe-4 py-3">
|
||||||
|
<div class="d-flex align-items-center flex-1 gap-3 border border-translucent rounded-pill px-4">
|
||||||
|
<input class="form-control outline-none border-0 flex-1 fs-9 px-0"
|
||||||
|
type="text"
|
||||||
|
placeholder="Write message" />
|
||||||
|
<label class="btn btn-link d-flex p-0 text-body-quaternary fs-9 border-0"
|
||||||
|
for="supportChatPhotos">
|
||||||
|
<span class="fa-solid fa-image"></span>
|
||||||
|
</label>
|
||||||
|
<input class="d-none" type="file" accept="image/*" id="supportChatPhotos" />
|
||||||
|
<label class="btn btn-link d-flex p-0 text-body-quaternary fs-9 border-0"
|
||||||
|
for="supportChatAttachment">
|
||||||
|
<span class="fa-solid fa-paperclip"></span>
|
||||||
|
</label>
|
||||||
|
<input class="d-none" type="file" id="supportChatAttachment" />
|
||||||
|
</div>
|
||||||
|
<button class="btn p-0 border-0 send-btn">
|
||||||
|
<span class="fa-solid fa-paper-plane fs-9"></span>
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<h5 class="mt-2 mb-3">Eric</h5>
|
|
||||||
<p class="text-center text-body-emphasis mb-0">
|
|
||||||
Ask us anything – we’ll get back to you here or by email within 24 hours.
|
|
||||||
</p>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<button class="btn btn-support-chat p-0 border border-translucent">
|
||||||
<div class="card-footer d-flex align-items-center gap-2 border-top border-translucent ps-3 pe-4 py-3">
|
<span class="fs-8 btn-text text-primary text-nowrap">Chat demo</span><span class="ping-icon-wrapper mt-n4 ms-n6 mt-sm-0 ms-sm-2 position-absolute position-sm-relative"><span class="ping-icon-bg"></span><span class="fa-solid fa-circle ping-icon"></span></span><span class="fa-solid fa-headset text-primary fs-8 d-sm-none"></span><span class="fa-solid fa-chevron-down text-primary fs-7"></span>
|
||||||
<div class="d-flex align-items-center flex-1 gap-3 border border-translucent rounded-pill px-4">
|
|
||||||
<input class="form-control outline-none border-0 flex-1 fs-9 px-0"
|
|
||||||
type="text"
|
|
||||||
placeholder="Write message" />
|
|
||||||
<label class="btn btn-link d-flex p-0 text-body-quaternary fs-9 border-0"
|
|
||||||
for="supportChatPhotos">
|
|
||||||
<span class="fa-solid fa-image"></span>
|
|
||||||
</label>
|
|
||||||
<input class="d-none" type="file" accept="image/*" id="supportChatPhotos" />
|
|
||||||
<label class="btn btn-link d-flex p-0 text-body-quaternary fs-9 border-0"
|
|
||||||
for="supportChatAttachment">
|
|
||||||
<span class="fa-solid fa-paperclip"></span>
|
|
||||||
</label>
|
|
||||||
<input class="d-none" type="file" id="supportChatAttachment" />
|
|
||||||
</div>
|
|
||||||
<button class="btn p-0 border-0 send-btn">
|
|
||||||
<span class="fa-solid fa-paper-plane fs-9"></span>
|
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</main>
|
||||||
</div>
|
|
||||||
<button class="btn btn-support-chat p-0 border border-translucent">
|
|
||||||
<span class="fs-8 btn-text text-primary text-nowrap">Chat demo</span><span class="ping-icon-wrapper mt-n4 ms-n6 mt-sm-0 ms-sm-2 position-absolute position-sm-relative"><span class="ping-icon-bg"></span><span class="fa-solid fa-circle ping-icon"></span></span><span class="fa-solid fa-headset text-primary fs-8 d-sm-none"></span><span class="fa-solid fa-chevron-down text-primary fs-7"></span>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</main>
|
|
||||||
<!-- ===============================================-->
|
<!-- ===============================================-->
|
||||||
<!-- End of Main Content-->
|
<!-- End of Main Content-->
|
||||||
<!-- ===============================================-->
|
<!-- ===============================================-->
|
||||||
<div class="offcanvas offcanvas-end settings-panel border-0"
|
<div class="offcanvas offcanvas-end settings-panel border-0"
|
||||||
id="settings-offcanvas"
|
id="settings-offcanvas"
|
||||||
tabindex="-1"
|
tabindex="-1"
|
||||||
aria-labelledby="settings-offcanvas">
|
aria-labelledby="settings-offcanvas">
|
||||||
<div class="offcanvas-header align-items-start border-bottom flex-column border-translucent">
|
<div class="offcanvas-header align-items-start border-bottom flex-column border-translucent">
|
||||||
<div class="pt-1 w-100 mb-6 d-flex justify-content-between align-items-start">
|
<div class="pt-1 w-100 mb-6 d-flex justify-content-between align-items-start">
|
||||||
<div>
|
<div>
|
||||||
<h5 class="mb-2 me-2 lh-sm">
|
<h5 class="mb-2 me-2 lh-sm">
|
||||||
<span class="fas fa-palette me-2 fs-8"></span>Theme Customizer
|
<span class="fas fa-palette me-2 fs-8"></span>Theme Customizer
|
||||||
</h5>
|
</h5>
|
||||||
<p class="mb-0 fs-9">Explore different styles according to your preferences</p>
|
<p class="mb-0 fs-9">Explore different styles according to your preferences</p>
|
||||||
|
</div>
|
||||||
|
<button class="btn p-1 fw-bolder"
|
||||||
|
type="button"
|
||||||
|
data-bs-dismiss="offcanvas"
|
||||||
|
aria-label="Close">
|
||||||
|
<span class="fas fa-times fs-8"></span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<button class="btn btn-phoenix-secondary w-100" data-theme-control="reset">
|
||||||
|
<span class="fas fa-arrows-rotate me-2 fs-10"></span>Reset to default
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<button class="btn p-1 fw-bolder"
|
<div class="offcanvas-body scrollbar px-card" id="themeController">
|
||||||
type="button"
|
<div class="setting-panel-item mt-0">
|
||||||
data-bs-dismiss="offcanvas"
|
<h5 class="setting-panel-item-title">Color Scheme</h5>
|
||||||
aria-label="Close">
|
<div class="row gx-2">
|
||||||
<span class="fas fa-times fs-8"></span>
|
<div class="col-4">
|
||||||
</button>
|
<input class="btn-check"
|
||||||
</div>
|
id="themeSwitcherLight"
|
||||||
<button class="btn btn-phoenix-secondary w-100" data-theme-control="reset">
|
name="theme-color"
|
||||||
<span class="fas fa-arrows-rotate me-2 fs-10"></span>Reset to default
|
type="radio"
|
||||||
</button>
|
value="light"
|
||||||
</div>
|
data-theme-control="phoenixTheme" />
|
||||||
<div class="offcanvas-body scrollbar px-card" id="themeController">
|
<label class="btn d-inline-block btn-navbar-style fs-9"
|
||||||
<div class="setting-panel-item mt-0">
|
for="themeSwitcherLight">
|
||||||
<h5 class="setting-panel-item-title">Color Scheme</h5>
|
<span class="mb-2 rounded d-block">
|
||||||
<div class="row gx-2">
|
<img class="img-fluid img-prototype mb-0"
|
||||||
<div class="col-4">
|
src="../../../assets/img/generic/default-light.png"
|
||||||
<input class="btn-check"
|
alt="" />
|
||||||
id="themeSwitcherLight"
|
</span><span class="label-text">Light</span>
|
||||||
name="theme-color"
|
</label>
|
||||||
type="radio"
|
</div>
|
||||||
value="light"
|
<div class="col-4">
|
||||||
data-theme-control="phoenixTheme" />
|
<input class="btn-check"
|
||||||
<label class="btn d-inline-block btn-navbar-style fs-9"
|
id="themeSwitcherDark"
|
||||||
for="themeSwitcherLight">
|
name="theme-color"
|
||||||
<span class="mb-2 rounded d-block">
|
type="radio"
|
||||||
<img class="img-fluid img-prototype mb-0"
|
value="dark"
|
||||||
src="../../../assets/img/generic/default-light.png"
|
data-theme-control="phoenixTheme" />
|
||||||
alt="" />
|
<label class="btn d-inline-block btn-navbar-style fs-9"
|
||||||
</span><span class="label-text">Light</span>
|
for="themeSwitcherDark">
|
||||||
</label>
|
<span class="mb-2 rounded d-block">
|
||||||
|
<img class="img-fluid img-prototype mb-0"
|
||||||
|
src="../../../assets/img/generic/default-dark.png"
|
||||||
|
alt="" />
|
||||||
|
</span><span class="label-text">Dark</span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div class="col-4">
|
||||||
|
<input class="btn-check"
|
||||||
|
id="themeSwitcherAuto"
|
||||||
|
name="theme-color"
|
||||||
|
type="radio"
|
||||||
|
value="auto"
|
||||||
|
data-theme-control="phoenixTheme" />
|
||||||
|
<label class="btn d-inline-block btn-navbar-style fs-9"
|
||||||
|
for="themeSwitcherAuto">
|
||||||
|
<span class="mb-2 rounded d-block">
|
||||||
|
<img class="img-fluid img-prototype mb-0"
|
||||||
|
src="../../../assets/img/generic/auto.png"
|
||||||
|
alt="" />
|
||||||
|
</span><span class="label-text">Auto</span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-4">
|
<div class="border border-translucent rounded-3 p-4 setting-panel-item bg-body-emphasis">
|
||||||
<input class="btn-check"
|
<div class="d-flex justify-content-between align-items-center">
|
||||||
id="themeSwitcherDark"
|
<h5 class="setting-panel-item-title mb-1">RTL</h5>
|
||||||
name="theme-color"
|
<div class="form-check form-switch mb-0">
|
||||||
type="radio"
|
<input class="form-check-input ms-auto"
|
||||||
value="dark"
|
type="checkbox"
|
||||||
data-theme-control="phoenixTheme" />
|
data-theme-control="phoenixIsRTL" />
|
||||||
<label class="btn d-inline-block btn-navbar-style fs-9"
|
</div>
|
||||||
for="themeSwitcherDark">
|
</div>
|
||||||
<span class="mb-2 rounded d-block">
|
<p class="mb-0 text-body-tertiary">Change text direction</p>
|
||||||
<img class="img-fluid img-prototype mb-0"
|
|
||||||
src="../../../assets/img/generic/default-dark.png"
|
|
||||||
alt="" />
|
|
||||||
</span><span class="label-text">Dark</span>
|
|
||||||
</label>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="col-4">
|
<div class="border border-translucent rounded-3 p-4 setting-panel-item bg-body-emphasis">
|
||||||
<input class="btn-check"
|
<div class="d-flex justify-content-between align-items-center">
|
||||||
id="themeSwitcherAuto"
|
<h5 class="setting-panel-item-title mb-1">Support Chat</h5>
|
||||||
name="theme-color"
|
<div class="form-check form-switch mb-0">
|
||||||
type="radio"
|
<input class="form-check-input ms-auto"
|
||||||
value="auto"
|
type="checkbox"
|
||||||
data-theme-control="phoenixTheme" />
|
data-theme-control="phoenixSupportChat" />
|
||||||
<label class="btn d-inline-block btn-navbar-style fs-9"
|
</div>
|
||||||
for="themeSwitcherAuto">
|
</div>
|
||||||
<span class="mb-2 rounded d-block">
|
<p class="mb-0 text-body-tertiary">Toggle support chat</p>
|
||||||
<img class="img-fluid img-prototype mb-0"
|
|
||||||
src="../../../assets/img/generic/auto.png"
|
|
||||||
alt="" />
|
|
||||||
</span><span class="label-text">Auto</span>
|
|
||||||
</label>
|
|
||||||
</div>
|
</div>
|
||||||
|
<div class="setting-panel-item">
|
||||||
|
<h5 class="setting-panel-item-title">Navigation Type</h5>
|
||||||
|
<div class="row gx-2">
|
||||||
|
<div class="col-6">
|
||||||
|
<input class="btn-check"
|
||||||
|
id="navbarPositionVertical"
|
||||||
|
name="navigation-type"
|
||||||
|
type="radio"
|
||||||
|
value="vertical"
|
||||||
|
data-theme-control="phoenixNavbarPosition"
|
||||||
|
data-page-url="../../../documentation/layouts/vertical-navbar.html"
|
||||||
|
disabled="disabled" />
|
||||||
|
<label class="btn d-inline-block btn-navbar-style fs-9"
|
||||||
|
for="navbarPositionVertical">
|
||||||
|
<span class="rounded d-block">
|
||||||
|
<img class="img-fluid img-prototype d-dark-none"
|
||||||
|
src="../../../assets/img/generic/default-light.png"
|
||||||
|
alt="" />
|
||||||
|
<img class="img-fluid img-prototype d-light-none"
|
||||||
|
src="../../../assets/img/generic/default-dark.png"
|
||||||
|
alt="" />
|
||||||
|
</span><span class="label-text">Vertical</span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div class="col-6">
|
||||||
|
<input class="btn-check"
|
||||||
|
id="navbarPositionHorizontal"
|
||||||
|
name="navigation-type"
|
||||||
|
type="radio"
|
||||||
|
value="horizontal"
|
||||||
|
data-theme-control="phoenixNavbarPosition"
|
||||||
|
data-page-url="../../../documentation/layouts/horizontal-navbar.html"
|
||||||
|
disabled="disabled" />
|
||||||
|
<label class="btn d-inline-block btn-navbar-style fs-9"
|
||||||
|
for="navbarPositionHorizontal">
|
||||||
|
<span class="rounded d-block">
|
||||||
|
<img class="img-fluid img-prototype d-dark-none"
|
||||||
|
src="../../../assets/img/generic/top-default.png"
|
||||||
|
alt="" />
|
||||||
|
<img class="img-fluid img-prototype d-light-none"
|
||||||
|
src="../../../assets/img/generic/top-default-dark.png"
|
||||||
|
alt="" />
|
||||||
|
</span><span class="label-text">Horizontal</span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div class="col-6">
|
||||||
|
<input class="btn-check"
|
||||||
|
id="navbarPositionCombo"
|
||||||
|
name="navigation-type"
|
||||||
|
type="radio"
|
||||||
|
value="combo"
|
||||||
|
data-theme-control="phoenixNavbarPosition"
|
||||||
|
disabled="disabled"
|
||||||
|
data-page-url="../../../documentation/layouts/combo-navbar.html" />
|
||||||
|
<label class="btn d-inline-block btn-navbar-style fs-9"
|
||||||
|
for="navbarPositionCombo">
|
||||||
|
<span class="rounded d-block">
|
||||||
|
<img class="img-fluid img-prototype d-dark-none"
|
||||||
|
src="../../../assets/img/generic/nav-combo-light.png"
|
||||||
|
alt="" />
|
||||||
|
<img class="img-fluid img-prototype d-light-none"
|
||||||
|
src="../../../assets/img/generic/nav-combo-dark.png"
|
||||||
|
alt="" />
|
||||||
|
</span><span class="label-text">Combo</span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div class="col-6">
|
||||||
|
<input class="btn-check"
|
||||||
|
id="navbarPositionTopDouble"
|
||||||
|
name="navigation-type"
|
||||||
|
type="radio"
|
||||||
|
value="dual-nav"
|
||||||
|
data-theme-control="phoenixNavbarPosition"
|
||||||
|
disabled="disabled"
|
||||||
|
data-page-url="../../../documentation/layouts/dual-nav.html" />
|
||||||
|
<label class="btn d-inline-block btn-navbar-style fs-9"
|
||||||
|
for="navbarPositionTopDouble">
|
||||||
|
<span class="rounded d-block">
|
||||||
|
<img class="img-fluid img-prototype d-dark-none"
|
||||||
|
src="../../../assets/img/generic/dual-light.png"
|
||||||
|
alt="" />
|
||||||
|
<img class="img-fluid img-prototype d-light-none"
|
||||||
|
src="../../../assets/img/generic/dual-dark.png"
|
||||||
|
alt="" />
|
||||||
|
</span><span class="label-text">Dual nav</span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<p class="text-warning-dark font-medium">
|
||||||
|
<span class="fa-solid fa-triangle-exclamation me-2 text-warning"></span>You can't update navigation type in this page
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="setting-panel-item">
|
||||||
|
<h5 class="setting-panel-item-title">Vertical Navbar Appearance</h5>
|
||||||
|
<div class="row gx-2">
|
||||||
|
<div class="col-6">
|
||||||
|
<input class="btn-check"
|
||||||
|
id="navbar-style-default"
|
||||||
|
type="radio"
|
||||||
|
name="config.name"
|
||||||
|
value="default"
|
||||||
|
data-theme-control="phoenixNavbarVerticalStyle"
|
||||||
|
disabled="disabled" />
|
||||||
|
<label class="btn d-block w-100 btn-navbar-style fs-9"
|
||||||
|
for="navbar-style-default">
|
||||||
|
<img class="img-fluid img-prototype d-dark-none"
|
||||||
|
src="../../../assets/img/generic/default-light.png"
|
||||||
|
alt="" />
|
||||||
|
<img class="img-fluid img-prototype d-light-none"
|
||||||
|
src="../../../assets/img/generic/default-dark.png"
|
||||||
|
alt="" />
|
||||||
|
<span class="label-text d-dark-none">Default</span><span class="label-text d-light-none">Default</span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div class="col-6">
|
||||||
|
<input class="btn-check"
|
||||||
|
id="navbar-style-dark"
|
||||||
|
type="radio"
|
||||||
|
name="config.name"
|
||||||
|
value="darker"
|
||||||
|
data-theme-control="phoenixNavbarVerticalStyle"
|
||||||
|
disabled="disabled" />
|
||||||
|
<label class="btn d-block w-100 btn-navbar-style fs-9"
|
||||||
|
for="navbar-style-dark">
|
||||||
|
<img class="img-fluid img-prototype d-dark-none"
|
||||||
|
src="../../../assets/img/generic/vertical-darker.png"
|
||||||
|
alt="" />
|
||||||
|
<img class="img-fluid img-prototype d-light-none"
|
||||||
|
src="../../../assets/img/generic/vertical-lighter.png"
|
||||||
|
alt="" />
|
||||||
|
<span class="label-text d-dark-none">Darker</span><span class="label-text d-light-none">Lighter</span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<p class="text-warning-dark font-medium">
|
||||||
|
<span class="fa-solid fa-triangle-exclamation me-2 text-warning"></span>You can't update vertical navbar appearance in this page
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="setting-panel-item">
|
||||||
|
<h5 class="setting-panel-item-title">Horizontal Navbar Shape</h5>
|
||||||
|
<div class="row gx-2">
|
||||||
|
<div class="col-6">
|
||||||
|
<input class="btn-check"
|
||||||
|
id="navbarShapeDefault"
|
||||||
|
name="navbar-shape"
|
||||||
|
type="radio"
|
||||||
|
value="default"
|
||||||
|
data-theme-control="phoenixNavbarTopShape"
|
||||||
|
data-page-url="../../../documentation/layouts/horizontal-navbar.html"
|
||||||
|
disabled="disabled" />
|
||||||
|
<label class="btn d-inline-block btn-navbar-style fs-9"
|
||||||
|
for="navbarShapeDefault">
|
||||||
|
<span class="mb-2 rounded d-block">
|
||||||
|
<img class="img-fluid img-prototype d-dark-none mb-0"
|
||||||
|
src="../../../assets/img/generic/top-default.png"
|
||||||
|
alt="" />
|
||||||
|
<img class="img-fluid img-prototype d-light-none mb-0"
|
||||||
|
src="../../../assets/img/generic/top-default-dark.png"
|
||||||
|
alt="" />
|
||||||
|
</span><span class="label-text">Default</span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div class="col-6">
|
||||||
|
<input class="btn-check"
|
||||||
|
id="navbarShapeSlim"
|
||||||
|
name="navbar-shape"
|
||||||
|
type="radio"
|
||||||
|
value="slim"
|
||||||
|
data-theme-control="phoenixNavbarTopShape"
|
||||||
|
data-page-url="../../../documentation/layouts/horizontal-navbar.html#horizontal-navbar-slim"
|
||||||
|
disabled="disabled" />
|
||||||
|
<label class="btn d-inline-block btn-navbar-style fs-9"
|
||||||
|
for="navbarShapeSlim">
|
||||||
|
<span class="mb-2 rounded d-block">
|
||||||
|
<img class="img-fluid img-prototype d-dark-none mb-0"
|
||||||
|
src="../../../assets/img/generic/top-slim.png"
|
||||||
|
alt="" />
|
||||||
|
<img class="img-fluid img-prototype d-light-none mb-0"
|
||||||
|
src="../../../assets/img/generic/top-slim-dark.png"
|
||||||
|
alt="" />
|
||||||
|
</span><span class="label-text">Slim</span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<p class="text-warning-dark font-medium">
|
||||||
|
<span class="fa-solid fa-triangle-exclamation me-2 text-warning"></span>You can't update horizontal navbar shape in this page
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="setting-panel-item">
|
||||||
|
<h5 class="setting-panel-item-title">Horizontal Navbar Appearance</h5>
|
||||||
|
<div class="row gx-2">
|
||||||
|
<div class="col-6">
|
||||||
|
<input class="btn-check"
|
||||||
|
id="navbarTopDefault"
|
||||||
|
name="navbar-top-style"
|
||||||
|
type="radio"
|
||||||
|
value="default"
|
||||||
|
data-theme-control="phoenixNavbarTopStyle"
|
||||||
|
disabled="disabled" />
|
||||||
|
<label class="btn d-inline-block btn-navbar-style fs-9"
|
||||||
|
for="navbarTopDefault">
|
||||||
|
<span class="mb-2 rounded d-block">
|
||||||
|
<img class="img-fluid img-prototype d-dark-none mb-0"
|
||||||
|
src="../../../assets/img/generic/top-default.png"
|
||||||
|
alt="" />
|
||||||
|
<img class="img-fluid img-prototype d-light-none mb-0"
|
||||||
|
src="../../../assets/img/generic/top-style-darker.png"
|
||||||
|
alt="" />
|
||||||
|
</span><span class="label-text">Default</span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div class="col-6">
|
||||||
|
<input class="btn-check"
|
||||||
|
id="navbarTopDarker"
|
||||||
|
name="navbar-top-style"
|
||||||
|
type="radio"
|
||||||
|
value="darker"
|
||||||
|
data-theme-control="phoenixNavbarTopStyle"
|
||||||
|
disabled="disabled" />
|
||||||
|
<label class="btn d-inline-block btn-navbar-style fs-9"
|
||||||
|
for="navbarTopDarker">
|
||||||
|
<span class="mb-2 rounded d-block">
|
||||||
|
<img class="img-fluid img-prototype d-dark-none mb-0"
|
||||||
|
src="../../../assets/img/generic/navbar-top-style-light.png"
|
||||||
|
alt="" />
|
||||||
|
<img class="img-fluid img-prototype d-light-none mb-0"
|
||||||
|
src="../../../assets/img/generic/top-style-lighter.png"
|
||||||
|
alt="" />
|
||||||
|
</span><span class="label-text d-dark-none">Darker</span><span class="label-text d-light-none">Lighter</span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<p class="text-warning-dark font-medium">
|
||||||
|
<span class="fa-solid fa-triangle-exclamation me-2 text-warning"></span>You can't update horizontal navbar appearance in this page
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<a class="bun btn-primary d-grid mb-3 text-white mt-5 btn btn-primary"
|
||||||
|
href="https://themes.getbootstrap.com/product/phoenix-admin-dashboard-webapp-template/"
|
||||||
|
target="_blank">Purchase template</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="border border-translucent rounded-3 p-4 setting-panel-item bg-body-emphasis">
|
<a class="card setting-toggle"
|
||||||
<div class="d-flex justify-content-between align-items-center">
|
href="#settings-offcanvas"
|
||||||
<h5 class="setting-panel-item-title mb-1">RTL</h5>
|
data-bs-toggle="offcanvas">
|
||||||
<div class="form-check form-switch mb-0">
|
<div class="card-body d-flex align-items-center px-2 py-1">
|
||||||
<input class="form-check-input ms-auto"
|
<div class="position-relative rounded-start"
|
||||||
type="checkbox"
|
style="height:34px;
|
||||||
data-theme-control="phoenixIsRTL" />
|
width:28px">
|
||||||
|
<div class="settings-popover">
|
||||||
|
<span class="ripple"><span class="fa-spin position-absolute all-0 d-flex flex-center"><span class="icon-spin position-absolute all-0 d-flex flex-center">
|
||||||
|
<svg width="20"
|
||||||
|
height="20"
|
||||||
|
viewBox="0 0 20 20"
|
||||||
|
fill="#ffffff"
|
||||||
|
xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M19.7369 12.3941L19.1989 12.1065C18.4459 11.7041 18.0843 10.8487 18.0843 9.99495C18.0843 9.14118 18.4459 8.28582 19.1989 7.88336L19.7369 7.59581C19.9474 7.47484 20.0316 7.23291 19.9474 7.03131C19.4842 5.57973 18.6843 4.28943 17.6738 3.20075C17.5053 3.03946 17.2527 2.99914 17.0422 3.12011L16.393 3.46714C15.6883 3.84379 14.8377 3.74529 14.1476 3.3427C14.0988 3.31422 14.0496 3.28621 14.0002 3.25868C13.2568 2.84453 12.7055 2.10629 12.7055 1.25525V0.70081C12.7055 0.499202 12.5371 0.297594 12.2845 0.257272C10.7266 -0.105622 9.16879 -0.0653007 7.69516 0.257272C7.44254 0.297594 7.31623 0.499202 7.31623 0.70081V1.23474C7.31623 2.09575 6.74999 2.8362 5.99824 3.25599C5.95774 3.27861 5.91747 3.30159 5.87744 3.32493C5.15643 3.74527 4.26453 3.85902 3.53534 3.45302L2.93743 3.12011C2.72691 2.99914 2.47429 3.03946 2.30587 3.20075C1.29538 4.28943 0.495411 5.57973 0.0322686 7.03131C-0.051939 7.23291 0.0322686 7.47484 0.242788 7.59581L0.784376 7.8853C1.54166 8.29007 1.92694 9.13627 1.92694 9.99495C1.92694 10.8536 1.54166 11.6998 0.784375 12.1046L0.242788 12.3941C0.0322686 12.515 -0.051939 12.757 0.0322686 12.9586C0.495411 14.4102 1.29538 15.7005 2.30587 16.7891C2.47429 16.9504 2.72691 16.9907 2.93743 16.8698L3.58669 16.5227C4.29133 16.1461 5.14131 16.2457 5.8331 16.6455C5.88713 16.6767 5.94159 16.7074 5.99648 16.7375C6.75162 17.1511 7.31623 17.8941 7.31623 18.7552V19.2891C7.31623 19.4425 7.41373 19.5959 7.55309 19.696C7.64066 19.7589 7.74815 19.7843 7.85406 19.8046C9.35884 20.0925 10.8609 20.0456 12.2845 19.7729C12.5371 19.6923 12.7055 19.4907 12.7055 19.2891V18.7346C12.7055 17.8836 13.2568 17.1454 14.0002 16.7312C14.0496 16.7037 14.0988 16.6757 14.1476 16.6472C14.8377 16.2446 15.6883 16.1461 16.393 16.5227L17.0422 16.8698C17.2527 16.9907 17.5053 16.9504 17.6738 16.7891C18.7264 15.7005 19.4842 14.4102 19.9895 12.9586C20.0316 12.757 19.9474 12.515 19.7369 12.3941ZM10.0109 13.2005C8.1162 13.2005 6.64257 11.7893 6.64257 9.97478C6.64257 8.20063 8.1162 6.74905 10.0109 6.74905C11.8634 6.74905 13.3792 8.20063 13.3792 9.97478C13.3792 11.7893 11.8634 13.2005 10.0109 13.2005Z" fill="#2A7BE4">
|
||||||
|
</path>
|
||||||
|
</svg>
|
||||||
|
</span></span></span>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<small class="text-uppercase text-body-tertiary fw-bold py-2 pe-2 ps-1 rounded-end">customize</small>
|
||||||
</div>
|
</div>
|
||||||
<p class="mb-0 text-body-tertiary">Change text direction</p>
|
</a>
|
||||||
</div>
|
|
||||||
<div class="border border-translucent rounded-3 p-4 setting-panel-item bg-body-emphasis">
|
|
||||||
<div class="d-flex justify-content-between align-items-center">
|
|
||||||
<h5 class="setting-panel-item-title mb-1">Support Chat</h5>
|
|
||||||
<div class="form-check form-switch mb-0">
|
|
||||||
<input class="form-check-input ms-auto"
|
|
||||||
type="checkbox"
|
|
||||||
data-theme-control="phoenixSupportChat" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<p class="mb-0 text-body-tertiary">Toggle support chat</p>
|
|
||||||
</div>
|
|
||||||
<div class="setting-panel-item">
|
|
||||||
<h5 class="setting-panel-item-title">Navigation Type</h5>
|
|
||||||
<div class="row gx-2">
|
|
||||||
<div class="col-6">
|
|
||||||
<input class="btn-check"
|
|
||||||
id="navbarPositionVertical"
|
|
||||||
name="navigation-type"
|
|
||||||
type="radio"
|
|
||||||
value="vertical"
|
|
||||||
data-theme-control="phoenixNavbarPosition"
|
|
||||||
data-page-url="../../../documentation/layouts/vertical-navbar.html"
|
|
||||||
disabled="disabled" />
|
|
||||||
<label class="btn d-inline-block btn-navbar-style fs-9"
|
|
||||||
for="navbarPositionVertical">
|
|
||||||
<span class="rounded d-block">
|
|
||||||
<img class="img-fluid img-prototype d-dark-none"
|
|
||||||
src="../../../assets/img/generic/default-light.png"
|
|
||||||
alt="" />
|
|
||||||
<img class="img-fluid img-prototype d-light-none"
|
|
||||||
src="../../../assets/img/generic/default-dark.png"
|
|
||||||
alt="" />
|
|
||||||
</span><span class="label-text">Vertical</span>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
<div class="col-6">
|
|
||||||
<input class="btn-check"
|
|
||||||
id="navbarPositionHorizontal"
|
|
||||||
name="navigation-type"
|
|
||||||
type="radio"
|
|
||||||
value="horizontal"
|
|
||||||
data-theme-control="phoenixNavbarPosition"
|
|
||||||
data-page-url="../../../documentation/layouts/horizontal-navbar.html"
|
|
||||||
disabled="disabled" />
|
|
||||||
<label class="btn d-inline-block btn-navbar-style fs-9"
|
|
||||||
for="navbarPositionHorizontal">
|
|
||||||
<span class="rounded d-block">
|
|
||||||
<img class="img-fluid img-prototype d-dark-none"
|
|
||||||
src="../../../assets/img/generic/top-default.png"
|
|
||||||
alt="" />
|
|
||||||
<img class="img-fluid img-prototype d-light-none"
|
|
||||||
src="../../../assets/img/generic/top-default-dark.png"
|
|
||||||
alt="" />
|
|
||||||
</span><span class="label-text">Horizontal</span>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
<div class="col-6">
|
|
||||||
<input class="btn-check"
|
|
||||||
id="navbarPositionCombo"
|
|
||||||
name="navigation-type"
|
|
||||||
type="radio"
|
|
||||||
value="combo"
|
|
||||||
data-theme-control="phoenixNavbarPosition"
|
|
||||||
disabled="disabled"
|
|
||||||
data-page-url="../../../documentation/layouts/combo-navbar.html" />
|
|
||||||
<label class="btn d-inline-block btn-navbar-style fs-9"
|
|
||||||
for="navbarPositionCombo">
|
|
||||||
<span class="rounded d-block">
|
|
||||||
<img class="img-fluid img-prototype d-dark-none"
|
|
||||||
src="../../../assets/img/generic/nav-combo-light.png"
|
|
||||||
alt="" />
|
|
||||||
<img class="img-fluid img-prototype d-light-none"
|
|
||||||
src="../../../assets/img/generic/nav-combo-dark.png"
|
|
||||||
alt="" />
|
|
||||||
</span><span class="label-text">Combo</span>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
<div class="col-6">
|
|
||||||
<input class="btn-check"
|
|
||||||
id="navbarPositionTopDouble"
|
|
||||||
name="navigation-type"
|
|
||||||
type="radio"
|
|
||||||
value="dual-nav"
|
|
||||||
data-theme-control="phoenixNavbarPosition"
|
|
||||||
disabled="disabled"
|
|
||||||
data-page-url="../../../documentation/layouts/dual-nav.html" />
|
|
||||||
<label class="btn d-inline-block btn-navbar-style fs-9"
|
|
||||||
for="navbarPositionTopDouble">
|
|
||||||
<span class="rounded d-block">
|
|
||||||
<img class="img-fluid img-prototype d-dark-none"
|
|
||||||
src="../../../assets/img/generic/dual-light.png"
|
|
||||||
alt="" />
|
|
||||||
<img class="img-fluid img-prototype d-light-none"
|
|
||||||
src="../../../assets/img/generic/dual-dark.png"
|
|
||||||
alt="" />
|
|
||||||
</span><span class="label-text">Dual nav</span>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<p class="text-warning-dark font-medium">
|
|
||||||
<span class="fa-solid fa-triangle-exclamation me-2 text-warning"></span>You can't update navigation type in this page
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<div class="setting-panel-item">
|
|
||||||
<h5 class="setting-panel-item-title">Vertical Navbar Appearance</h5>
|
|
||||||
<div class="row gx-2">
|
|
||||||
<div class="col-6">
|
|
||||||
<input class="btn-check"
|
|
||||||
id="navbar-style-default"
|
|
||||||
type="radio"
|
|
||||||
name="config.name"
|
|
||||||
value="default"
|
|
||||||
data-theme-control="phoenixNavbarVerticalStyle"
|
|
||||||
disabled="disabled" />
|
|
||||||
<label class="btn d-block w-100 btn-navbar-style fs-9"
|
|
||||||
for="navbar-style-default">
|
|
||||||
<img class="img-fluid img-prototype d-dark-none"
|
|
||||||
src="../../../assets/img/generic/default-light.png"
|
|
||||||
alt="" />
|
|
||||||
<img class="img-fluid img-prototype d-light-none"
|
|
||||||
src="../../../assets/img/generic/default-dark.png"
|
|
||||||
alt="" />
|
|
||||||
<span class="label-text d-dark-none">Default</span><span class="label-text d-light-none">Default</span>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
<div class="col-6">
|
|
||||||
<input class="btn-check"
|
|
||||||
id="navbar-style-dark"
|
|
||||||
type="radio"
|
|
||||||
name="config.name"
|
|
||||||
value="darker"
|
|
||||||
data-theme-control="phoenixNavbarVerticalStyle"
|
|
||||||
disabled="disabled" />
|
|
||||||
<label class="btn d-block w-100 btn-navbar-style fs-9"
|
|
||||||
for="navbar-style-dark">
|
|
||||||
<img class="img-fluid img-prototype d-dark-none"
|
|
||||||
src="../../../assets/img/generic/vertical-darker.png"
|
|
||||||
alt="" />
|
|
||||||
<img class="img-fluid img-prototype d-light-none"
|
|
||||||
src="../../../assets/img/generic/vertical-lighter.png"
|
|
||||||
alt="" />
|
|
||||||
<span class="label-text d-dark-none">Darker</span><span class="label-text d-light-none">Lighter</span>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<p class="text-warning-dark font-medium">
|
|
||||||
<span class="fa-solid fa-triangle-exclamation me-2 text-warning"></span>You can't update vertical navbar appearance in this page
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<div class="setting-panel-item">
|
|
||||||
<h5 class="setting-panel-item-title">Horizontal Navbar Shape</h5>
|
|
||||||
<div class="row gx-2">
|
|
||||||
<div class="col-6">
|
|
||||||
<input class="btn-check"
|
|
||||||
id="navbarShapeDefault"
|
|
||||||
name="navbar-shape"
|
|
||||||
type="radio"
|
|
||||||
value="default"
|
|
||||||
data-theme-control="phoenixNavbarTopShape"
|
|
||||||
data-page-url="../../../documentation/layouts/horizontal-navbar.html"
|
|
||||||
disabled="disabled" />
|
|
||||||
<label class="btn d-inline-block btn-navbar-style fs-9"
|
|
||||||
for="navbarShapeDefault">
|
|
||||||
<span class="mb-2 rounded d-block">
|
|
||||||
<img class="img-fluid img-prototype d-dark-none mb-0"
|
|
||||||
src="../../../assets/img/generic/top-default.png"
|
|
||||||
alt="" />
|
|
||||||
<img class="img-fluid img-prototype d-light-none mb-0"
|
|
||||||
src="../../../assets/img/generic/top-default-dark.png"
|
|
||||||
alt="" />
|
|
||||||
</span><span class="label-text">Default</span>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
<div class="col-6">
|
|
||||||
<input class="btn-check"
|
|
||||||
id="navbarShapeSlim"
|
|
||||||
name="navbar-shape"
|
|
||||||
type="radio"
|
|
||||||
value="slim"
|
|
||||||
data-theme-control="phoenixNavbarTopShape"
|
|
||||||
data-page-url="../../../documentation/layouts/horizontal-navbar.html#horizontal-navbar-slim"
|
|
||||||
disabled="disabled" />
|
|
||||||
<label class="btn d-inline-block btn-navbar-style fs-9"
|
|
||||||
for="navbarShapeSlim">
|
|
||||||
<span class="mb-2 rounded d-block">
|
|
||||||
<img class="img-fluid img-prototype d-dark-none mb-0"
|
|
||||||
src="../../../assets/img/generic/top-slim.png"
|
|
||||||
alt="" />
|
|
||||||
<img class="img-fluid img-prototype d-light-none mb-0"
|
|
||||||
src="../../../assets/img/generic/top-slim-dark.png"
|
|
||||||
alt="" />
|
|
||||||
</span><span class="label-text">Slim</span>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<p class="text-warning-dark font-medium">
|
|
||||||
<span class="fa-solid fa-triangle-exclamation me-2 text-warning"></span>You can't update horizontal navbar shape in this page
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<div class="setting-panel-item">
|
|
||||||
<h5 class="setting-panel-item-title">Horizontal Navbar Appearance</h5>
|
|
||||||
<div class="row gx-2">
|
|
||||||
<div class="col-6">
|
|
||||||
<input class="btn-check"
|
|
||||||
id="navbarTopDefault"
|
|
||||||
name="navbar-top-style"
|
|
||||||
type="radio"
|
|
||||||
value="default"
|
|
||||||
data-theme-control="phoenixNavbarTopStyle"
|
|
||||||
disabled="disabled" />
|
|
||||||
<label class="btn d-inline-block btn-navbar-style fs-9"
|
|
||||||
for="navbarTopDefault">
|
|
||||||
<span class="mb-2 rounded d-block">
|
|
||||||
<img class="img-fluid img-prototype d-dark-none mb-0"
|
|
||||||
src="../../../assets/img/generic/top-default.png"
|
|
||||||
alt="" />
|
|
||||||
<img class="img-fluid img-prototype d-light-none mb-0"
|
|
||||||
src="../../../assets/img/generic/top-style-darker.png"
|
|
||||||
alt="" />
|
|
||||||
</span><span class="label-text">Default</span>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
<div class="col-6">
|
|
||||||
<input class="btn-check"
|
|
||||||
id="navbarTopDarker"
|
|
||||||
name="navbar-top-style"
|
|
||||||
type="radio"
|
|
||||||
value="darker"
|
|
||||||
data-theme-control="phoenixNavbarTopStyle"
|
|
||||||
disabled="disabled" />
|
|
||||||
<label class="btn d-inline-block btn-navbar-style fs-9"
|
|
||||||
for="navbarTopDarker">
|
|
||||||
<span class="mb-2 rounded d-block">
|
|
||||||
<img class="img-fluid img-prototype d-dark-none mb-0"
|
|
||||||
src="../../../assets/img/generic/navbar-top-style-light.png"
|
|
||||||
alt="" />
|
|
||||||
<img class="img-fluid img-prototype d-light-none mb-0"
|
|
||||||
src="../../../assets/img/generic/top-style-lighter.png"
|
|
||||||
alt="" />
|
|
||||||
</span><span class="label-text d-dark-none">Darker</span><span class="label-text d-light-none">Lighter</span>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<p class="text-warning-dark font-medium">
|
|
||||||
<span class="fa-solid fa-triangle-exclamation me-2 text-warning"></span>You can't update horizontal navbar appearance in this page
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<a class="bun btn-primary d-grid mb-3 text-white mt-5 btn btn-primary"
|
|
||||||
href="https://themes.getbootstrap.com/product/phoenix-admin-dashboard-webapp-template/"
|
|
||||||
target="_blank">Purchase template</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<a class="card setting-toggle"
|
|
||||||
href="#settings-offcanvas"
|
|
||||||
data-bs-toggle="offcanvas">
|
|
||||||
<div class="card-body d-flex align-items-center px-2 py-1">
|
|
||||||
<div class="position-relative rounded-start"
|
|
||||||
style="height:34px;
|
|
||||||
width:28px">
|
|
||||||
<div class="settings-popover">
|
|
||||||
<span class="ripple"><span class="fa-spin position-absolute all-0 d-flex flex-center"><span class="icon-spin position-absolute all-0 d-flex flex-center">
|
|
||||||
<svg width="20"
|
|
||||||
height="20"
|
|
||||||
viewBox="0 0 20 20"
|
|
||||||
fill="#ffffff"
|
|
||||||
xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<path d="M19.7369 12.3941L19.1989 12.1065C18.4459 11.7041 18.0843 10.8487 18.0843 9.99495C18.0843 9.14118 18.4459 8.28582 19.1989 7.88336L19.7369 7.59581C19.9474 7.47484 20.0316 7.23291 19.9474 7.03131C19.4842 5.57973 18.6843 4.28943 17.6738 3.20075C17.5053 3.03946 17.2527 2.99914 17.0422 3.12011L16.393 3.46714C15.6883 3.84379 14.8377 3.74529 14.1476 3.3427C14.0988 3.31422 14.0496 3.28621 14.0002 3.25868C13.2568 2.84453 12.7055 2.10629 12.7055 1.25525V0.70081C12.7055 0.499202 12.5371 0.297594 12.2845 0.257272C10.7266 -0.105622 9.16879 -0.0653007 7.69516 0.257272C7.44254 0.297594 7.31623 0.499202 7.31623 0.70081V1.23474C7.31623 2.09575 6.74999 2.8362 5.99824 3.25599C5.95774 3.27861 5.91747 3.30159 5.87744 3.32493C5.15643 3.74527 4.26453 3.85902 3.53534 3.45302L2.93743 3.12011C2.72691 2.99914 2.47429 3.03946 2.30587 3.20075C1.29538 4.28943 0.495411 5.57973 0.0322686 7.03131C-0.051939 7.23291 0.0322686 7.47484 0.242788 7.59581L0.784376 7.8853C1.54166 8.29007 1.92694 9.13627 1.92694 9.99495C1.92694 10.8536 1.54166 11.6998 0.784375 12.1046L0.242788 12.3941C0.0322686 12.515 -0.051939 12.757 0.0322686 12.9586C0.495411 14.4102 1.29538 15.7005 2.30587 16.7891C2.47429 16.9504 2.72691 16.9907 2.93743 16.8698L3.58669 16.5227C4.29133 16.1461 5.14131 16.2457 5.8331 16.6455C5.88713 16.6767 5.94159 16.7074 5.99648 16.7375C6.75162 17.1511 7.31623 17.8941 7.31623 18.7552V19.2891C7.31623 19.4425 7.41373 19.5959 7.55309 19.696C7.64066 19.7589 7.74815 19.7843 7.85406 19.8046C9.35884 20.0925 10.8609 20.0456 12.2845 19.7729C12.5371 19.6923 12.7055 19.4907 12.7055 19.2891V18.7346C12.7055 17.8836 13.2568 17.1454 14.0002 16.7312C14.0496 16.7037 14.0988 16.6757 14.1476 16.6472C14.8377 16.2446 15.6883 16.1461 16.393 16.5227L17.0422 16.8698C17.2527 16.9907 17.5053 16.9504 17.6738 16.7891C18.7264 15.7005 19.4842 14.4102 19.9895 12.9586C20.0316 12.757 19.9474 12.515 19.7369 12.3941ZM10.0109 13.2005C8.1162 13.2005 6.64257 11.7893 6.64257 9.97478C6.64257 8.20063 8.1162 6.74905 10.0109 6.74905C11.8634 6.74905 13.3792 8.20063 13.3792 9.97478C13.3792 11.7893 11.8634 13.2005 10.0109 13.2005Z" fill="#2A7BE4">
|
|
||||||
</path>
|
|
||||||
</svg>
|
|
||||||
</span></span></span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<small class="text-uppercase text-body-tertiary fw-bold py-2 pe-2 ps-1 rounded-end">customize</small>
|
|
||||||
</div>
|
|
||||||
</a>
|
|
||||||
<!-- ===============================================-->
|
<!-- ===============================================-->
|
||||||
<!-- JavaScripts-->
|
<!-- JavaScripts-->
|
||||||
<!-- ===============================================-->
|
<!-- ===============================================-->
|
||||||
<script src="../../../vendors/popper/popper.min.js"></script>
|
<script src="../../../vendors/popper/popper.min.js"></script>
|
||||||
<script src="../../../vendors/bootstrap/bootstrap.min.js"></script>
|
<script src="../../../vendors/bootstrap/bootstrap.min.js"></script>
|
||||||
<script src="../../../vendors/anchorjs/anchor.min.js"></script>
|
<script src="../../../vendors/anchorjs/anchor.min.js"></script>
|
||||||
<script src="../../../vendors/is/is.min.js"></script>
|
<script src="../../../vendors/is/is.min.js"></script>
|
||||||
<script src="../../../vendors/fontawesome/all.min.js"></script>
|
<script src="../../../vendors/fontawesome/all.min.js"></script>
|
||||||
<script src="../../../vendors/lodash/lodash.min.js"></script>
|
<script src="../../../vendors/lodash/lodash.min.js"></script>
|
||||||
<script src="../../../vendors/list.js/list.min.js"></script>
|
<script src="../../../vendors/list.js/list.min.js"></script>
|
||||||
<script src="../../../vendors/feather-icons/feather.min.js"></script>
|
<script src="../../../vendors/feather-icons/feather.min.js"></script>
|
||||||
<script src="../../../vendors/dayjs/dayjs.min.js"></script>
|
<script src="../../../vendors/dayjs/dayjs.min.js"></script>
|
||||||
<script src="../../../assets/js/phoenix.js"></script>
|
<script src="../../../assets/js/phoenix.js"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@ -77,25 +77,25 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
{% if LOGIN_BY_CODE_ENABLED or PASSKEY_LOGIN_ENABLED %}
|
{% if LOGIN_BY_CODE_ENABLED or PASSKEY_LOGIN_ENABLED %}
|
||||||
<hr>
|
<hr>
|
||||||
{% element button_group vertical=True %}
|
{% element button_group vertical=True %}
|
||||||
{% if PASSKEY_LOGIN_ENABLED %}
|
{% if PASSKEY_LOGIN_ENABLED %}
|
||||||
{% element button type="submit" form="mfa_login" id="passkey_login" tags="prominent,login,outline,primary" %}
|
{% element button type="submit" form="mfa_login" id="passkey_login" tags="prominent,login,outline,primary" %}
|
||||||
{% trans "Sign in with a passkey" %}
|
{% trans "Sign in with a passkey" %}
|
||||||
|
{% endelement %}
|
||||||
|
{% endif %}
|
||||||
|
{% if LOGIN_BY_CODE_ENABLED %}
|
||||||
|
{% element button href=request_login_code_url tags="prominent,login,outline,primary" %}
|
||||||
|
{% trans "Mail me a sign-in code" %}
|
||||||
|
{% endelement %}
|
||||||
|
{% endif %}
|
||||||
{% endelement %}
|
{% endelement %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if LOGIN_BY_CODE_ENABLED %}
|
{% if SOCIALACCOUNT_ENABLED %}
|
||||||
{% element button href=request_login_code_url tags="prominent,login,outline,primary" %}
|
{% include "socialaccount/snippets/login.html" with page_layout="entrance" %}
|
||||||
{% trans "Mail me a sign-in code" %}
|
{% endif %}
|
||||||
{% endelement %}
|
|
||||||
{% endif %}
|
|
||||||
{% endelement %}
|
|
||||||
{% endif %}
|
|
||||||
{% if SOCIALACCOUNT_ENABLED %}
|
|
||||||
{% include "socialaccount/snippets/login.html" with page_layout="entrance" %}
|
|
||||||
{% endif %}
|
|
||||||
{% endblock content %}
|
{% endblock content %}
|
||||||
{% block extra_body %}
|
{% block extra_body %}
|
||||||
{{ block.super }}
|
{{ block.super }}
|
||||||
|
|||||||
@ -27,7 +27,7 @@
|
|||||||
<h3 class="mb-4">{% trans "Change Password" %}</h3>
|
<h3 class="mb-4">{% trans "Change Password" %}</h3>
|
||||||
</div>
|
</div>
|
||||||
<form method="post"
|
<form method="post"
|
||||||
|
|
||||||
action="{% url 'account_change_password' %}"
|
action="{% url 'account_change_password' %}"
|
||||||
class="form needs-validation"
|
class="form needs-validation"
|
||||||
novalidate>
|
novalidate>
|
||||||
|
|||||||
@ -6,20 +6,20 @@
|
|||||||
{% endblock head_title %}
|
{% endblock head_title %}
|
||||||
{% block content %}
|
{% block content %}
|
||||||
{% element h1 %}
|
{% element h1 %}
|
||||||
{% trans "Set Password" %}
|
{% trans "Set Password" %}
|
||||||
{% endelement %}
|
{% endelement %}
|
||||||
{% url 'account_set_password' as action_url %}
|
{% url 'account_set_password' as action_url %}
|
||||||
{% element form method="post" action=action_url %}
|
{% element form method="post" action=action_url %}
|
||||||
{% slot body %}
|
{% slot body %}
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
{{ redirect_field }}
|
{{ redirect_field }}
|
||||||
{% element fields form=form %}
|
{% element fields form=form %}
|
||||||
{% endelement %}
|
{% endelement %}
|
||||||
{% endslot %}
|
{% endslot %}
|
||||||
{% slot actions %}
|
{% slot actions %}
|
||||||
{% element button type="submit" name="action" %}
|
{% element button type="submit" name="action" %}
|
||||||
{% trans 'Set Password' %}
|
{% trans 'Set Password' %}
|
||||||
{% endelement %}
|
{% endelement %}
|
||||||
{% endslot %}
|
{% endslot %}
|
||||||
{% endelement %}
|
{% endelement %}
|
||||||
{% endblock content %}
|
{% endblock content %}
|
||||||
|
|||||||
@ -3,20 +3,20 @@
|
|||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
{% block reauthenticate_content %}
|
{% block reauthenticate_content %}
|
||||||
{% element p %}
|
{% element p %}
|
||||||
{% blocktranslate %}Enter your password:{% endblocktranslate %}
|
{% blocktranslate %}Enter your password:{% endblocktranslate %}
|
||||||
{% endelement %}
|
{% endelement %}
|
||||||
{% url 'account_reauthenticate' as action_url %}
|
{% url 'account_reauthenticate' as action_url %}
|
||||||
{% element form form=form method="post" action=action_url %}
|
{% element form form=form method="post" action=action_url %}
|
||||||
{% slot body %}
|
{% slot body %}
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
{% element fields form=form unlabeled=True %}
|
{% element fields form=form unlabeled=True %}
|
||||||
{% endelement %}
|
{% endelement %}
|
||||||
{{ redirect_field }}
|
{{ redirect_field }}
|
||||||
{% endslot %}
|
{% endslot %}
|
||||||
{% slot actions %}
|
{% slot actions %}
|
||||||
{% element button type="submit" tags="primary,reauthenticate" %}
|
{% element button type="submit" tags="primary,reauthenticate" %}
|
||||||
{% trans "Confirm" %}
|
{% trans "Confirm" %}
|
||||||
{% endelement %}
|
{% endelement %}
|
||||||
{% endslot %}
|
{% endslot %}
|
||||||
{% endelement %}
|
{% endelement %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|||||||
@ -6,27 +6,27 @@
|
|||||||
{% endblock head_title %}
|
{% endblock head_title %}
|
||||||
{% block content %}
|
{% block content %}
|
||||||
{% element h1 %}
|
{% element h1 %}
|
||||||
{% translate "Mail me a sign-in code" %}
|
{% translate "Mail me a sign-in code" %}
|
||||||
{% endelement %}
|
{% endelement %}
|
||||||
{% element p %}
|
{% element p %}
|
||||||
{% blocktranslate %}You will receive an email containing a special code for a password-free sign-in.{% endblocktranslate %}
|
{% blocktranslate %}You will receive an email containing a special code for a password-free sign-in.{% endblocktranslate %}
|
||||||
{% endelement %}
|
{% endelement %}
|
||||||
{% url 'account_request_login_code' as login_url %}
|
{% url 'account_request_login_code' as login_url %}
|
||||||
{% element form form=form method="post" action=login_url tags="entrance,login" %}
|
{% element form form=form method="post" action=login_url tags="entrance,login" %}
|
||||||
{% slot body %}
|
{% slot body %}
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
{% element fields form=form unlabeled=True %}
|
{% element fields form=form unlabeled=True %}
|
||||||
{% endelement %}
|
{% endelement %}
|
||||||
{{ redirect_field }}
|
{{ redirect_field }}
|
||||||
{% endslot %}
|
{% endslot %}
|
||||||
{% slot actions %}
|
{% slot actions %}
|
||||||
{% element button type="submit" tags="prominent,login" %}
|
{% element button type="submit" tags="prominent,login" %}
|
||||||
{% translate "Request Code" %}
|
{% translate "Request Code" %}
|
||||||
{% endelement %}
|
{% endelement %}
|
||||||
{% endslot %}
|
{% endslot %}
|
||||||
{% endelement %}
|
{% endelement %}
|
||||||
{% url 'account_login' as login_url %}
|
{% url 'account_login' as login_url %}
|
||||||
{% element button href=login_url tags="link" %}
|
{% element button href=login_url tags="link" %}
|
||||||
{% translate "Other sign-in options" %}
|
{% translate "Other sign-in options" %}
|
||||||
{% endelement %}
|
{% endelement %}
|
||||||
{% endblock content %}
|
{% endblock content %}
|
||||||
|
|||||||
@ -25,7 +25,7 @@
|
|||||||
<p class="text-body-tertiary fs-9">{% trans 'Create your dealership account today' %}</p>
|
<p class="text-body-tertiary fs-9">{% trans 'Create your dealership account today' %}</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="mx-auto mt-4 text-center">
|
<div class="mx-auto mt-4 text-center">
|
||||||
</div>
|
</div>
|
||||||
<form method="post" action="{% url 'account_signup' %}" class="needs-validation">
|
<form method="post" action="{% url 'account_signup' %}" class="needs-validation">
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
<div class="card theme-wizard">
|
<div class="card theme-wizard">
|
||||||
@ -55,16 +55,16 @@
|
|||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
{% include 'haikal_policy/refund_policy.html' %}
|
{% include 'haikal_policy/refund_policy.html' %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
{% endblock content %}
|
{% endblock content %}
|
||||||
|
|
||||||
{% block customJS %}
|
{% block customJS %}
|
||||||
<script src="{% static 'js/phoenix.js' %}"></script>
|
<script src="{% static 'js/phoenix.js' %}"></script>
|
||||||
<script src="{% static 'js/main.js' %}"></script>
|
<script src="{% static 'js/main.js' %}"></script>
|
||||||
<script src="{% static 'js/sweetalert2.all.min.js' %}"></script>
|
<script src="{% static 'js/sweetalert2.all.min.js' %}"></script>
|
||||||
<script type="module"
|
<script type="module"
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
{% load i18n allauth %}
|
{% load i18n allauth %}
|
||||||
{% element p %}
|
{% element p %}
|
||||||
<strong>{% trans 'Warning:' %}</strong> {% trans "You currently do not have any email address set up. You should really add an email address so you can receive notifications, reset your password, etc." %}
|
<strong>{% trans 'Warning:' %}</strong> {% trans "You currently do not have any email address set up. You should really add an email address so you can receive notifications, reset your password, etc." %}
|
||||||
{% endelement %}
|
{% endelement %}
|
||||||
|
|||||||
@ -24,8 +24,8 @@
|
|||||||
<h3 class="text-body-highlight">{% trans 'Registration Successful!' %}</h3>
|
<h3 class="text-body-highlight">{% trans 'Registration Successful!' %}</h3>
|
||||||
<p class="text-body-tertiary fs-9">
|
<p class="text-body-tertiary fs-9">
|
||||||
{% blocktrans %}
|
{% blocktrans %}
|
||||||
|
|
||||||
Thank you for registering at Haikal. We've received your information and a member of our team will contact you shortly to confirm your account details.
|
Thank you for registering at Haikal. We've received your information and a member of our team will contact you shortly to confirm your account details.
|
||||||
{% endblocktrans %}
|
{% endblocktrans %}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -35,7 +35,7 @@
|
|||||||
{{ form.bill_cash_account|as_crispy_field }}
|
{{ form.bill_cash_account|as_crispy_field }}
|
||||||
{{ form.bill_prepaid_account|as_crispy_field }}
|
{{ form.bill_prepaid_account|as_crispy_field }}
|
||||||
{{ form.bill_unearned_account|as_crispy_field }}
|
{{ form.bill_unearned_account|as_crispy_field }}
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<hr class="my-4">
|
<hr class="my-4">
|
||||||
|
|||||||
@ -5,7 +5,7 @@
|
|||||||
{% trans "Activate Account" %}
|
{% trans "Activate Account" %}
|
||||||
{% endblock title %}
|
{% endblock title %}
|
||||||
{% block content %}
|
{% block content %}
|
||||||
|
|
||||||
<div class="row justify-content-center mt-5 mb-3">
|
<div class="row justify-content-center mt-5 mb-3">
|
||||||
<div class="col-lg-8 col-md-10">
|
<div class="col-lg-8 col-md-10">
|
||||||
<div class="card shadow-sm border-0 rounded-3">
|
<div class="card shadow-sm border-0 rounded-3">
|
||||||
|
|||||||
@ -5,42 +5,42 @@
|
|||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
{% if request.user.is_superuser %}
|
{% if request.user.is_superuser %}
|
||||||
<div class="container py-5">
|
<div class="container py-5">
|
||||||
<header class="mb-5">
|
<header class="mb-5">
|
||||||
<h1 class="display-4 fw-bold">
|
<h1 class="display-4 fw-bold">
|
||||||
<i class="fas fa-user-cog text-primary me-3"></i>
|
<i class="fas fa-user-cog text-primary me-3"></i>
|
||||||
{% trans "Admin Dashboard" %}
|
{% trans "Admin Dashboard" %}
|
||||||
</h1>
|
</h1>
|
||||||
<p class="lead mt-3">
|
<p class="lead mt-3">
|
||||||
{% trans "Manage user accounts and review system logs." %}
|
{% trans "Manage user accounts and review system logs." %}
|
||||||
</p>
|
</p>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
<div class="row row-cols-1 row-cols-md-2 row-cols-lg-3 g-4">
|
<div class="row row-cols-1 row-cols-md-2 row-cols-lg-3 g-4">
|
||||||
<div class="col">
|
<div class="col">
|
||||||
<a href="{% url 'user_management' request.dealer.slug %}" class="text-decoration-none">
|
<a href="{% url 'user_management' request.dealer.slug %}" class="text-decoration-none">
|
||||||
<div class="card h-100 shadow-sm border-0 rounded-3">
|
<div class="card h-100 shadow-sm border-0 rounded-3">
|
||||||
<div class="card-body text-center p-4">
|
<div class="card-body text-center p-4">
|
||||||
<i class="fas fa-users fa-3x text-primary mb-3"></i>
|
<i class="fas fa-users fa-3x text-primary mb-3"></i>
|
||||||
<h5 class="card-title fw-bold ">{{ _("User Management") }}</h5>
|
<h5 class="card-title fw-bold ">{{ _("User Management") }}</h5>
|
||||||
<p class="card-text text-muted">{% trans "View, edit, and manage all user accounts within the system." %}</p>
|
<p class="card-text text-muted">{% trans "View, edit, and manage all user accounts within the system." %}</p>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</a>
|
||||||
</a>
|
</div>
|
||||||
</div>
|
<div class="col">
|
||||||
<div class="col">
|
<a href="{% url 'audit_log_dashboard' request.dealer.slug %}" class="text-decoration-none">
|
||||||
<a href="{% url 'audit_log_dashboard' request.dealer.slug %}" class="text-decoration-none">
|
<div class="card h-100 shadow-sm border-0 rounded-3">
|
||||||
<div class="card h-100 shadow-sm border-0 rounded-3">
|
<div class="card-body text-center p-4">
|
||||||
<div class="card-body text-center p-4">
|
<i class="fas fa-history fa-3x text-primary mb-3"></i>
|
||||||
<i class="fas fa-history fa-3x text-primary mb-3"></i>
|
<h5 class="card-title fw-bold ">{{ _("Audit Log") }}</h5>
|
||||||
<h5 class="card-title fw-bold ">{{ _("Audit Log") }}</h5>
|
<p class="card-text text-muted">{% trans "Review a detailed history of all critical system activities and changes." %}</p>
|
||||||
<p class="card-text text-muted">{% trans "Review a detailed history of all critical system activities and changes." %}</p>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</a>
|
||||||
</a>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
{% endif %}
|
||||||
{% endif %}
|
|
||||||
{% endblock content %}
|
{% endblock content %}
|
||||||
@ -91,7 +91,7 @@
|
|||||||
<script src="{% static 'js/app_admin/staff_index.js' %}"></script>
|
<script src="{% static 'js/app_admin/staff_index.js' %}"></script>
|
||||||
<script src="{% static 'js/modal/show_modal.js' %}"></script>
|
<script src="{% static 'js/modal/show_modal.js' %}"></script>
|
||||||
<script src="{% static 'js/js-utils.js' %}"></script>
|
<script src="{% static 'js/js-utils.js' %}"></script>
|
||||||
<script>
|
<script>
|
||||||
function createCommonInputFields(appointment, servicesDropdown, isEditMode, defaultStartTime, staffDropdown) {
|
function createCommonInputFields(appointment, servicesDropdown, isEditMode, defaultStartTime, staffDropdown) {
|
||||||
const startTimeValue = isEditMode ? moment(appointment.start_time).format('HH:mm:ss') : defaultStartTime;
|
const startTimeValue = isEditMode ? moment(appointment.start_time).format('HH:mm:ss') : defaultStartTime;
|
||||||
const disabledAttribute = isEditMode ? '' : 'disabled';
|
const disabledAttribute = isEditMode ? '' : 'disabled';
|
||||||
|
|||||||
@ -97,7 +97,7 @@
|
|||||||
{{ form.as_p }} <!-- Renders the form fields -->
|
{{ form.as_p }} <!-- Renders the form fields -->
|
||||||
<button type="submit">{% trans 'Reset Password' %}</button>
|
<button type="submit">{% trans 'Reset Password' %}</button>
|
||||||
</form>
|
</form>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
{% block customJS %}
|
{% block customJS %}
|
||||||
<script src="{% static 'js/js-utils.js' %}"></script>
|
<script src="{% static 'js/js-utils.js' %}"></script>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|||||||
@ -94,7 +94,7 @@
|
|||||||
<th class="sort white-space-nowrap align-middle " scope="col">{% trans 'PO' %}</th>
|
<th class="sort white-space-nowrap align-middle " scope="col">{% trans 'PO' %}</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
|
|
||||||
<tbody class="list fs-9" id="project-list-table-body">
|
<tbody class="list fs-9" id="project-list-table-body">
|
||||||
{% for bill_item in itemtxs_qs %}
|
{% for bill_item in itemtxs_qs %}
|
||||||
<tr>
|
<tr>
|
||||||
@ -162,4 +162,4 @@
|
|||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
{% include "bill/includes/mark_as.html" %}
|
{% include "bill/includes/mark_as.html" %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|||||||
@ -55,8 +55,8 @@
|
|||||||
class="btn btn-sm btn-phoenix-primary me-md-2">{% trans 'View' %}</a>
|
class="btn btn-sm btn-phoenix-primary me-md-2">{% trans 'View' %}</a>
|
||||||
{% if perms.django_ledger.change_billmodel %}
|
{% if perms.django_ledger.change_billmodel %}
|
||||||
<a
|
<a
|
||||||
href="{% url 'django_ledger:bill-update' entity_slug=entity_slug bill_pk=bill.uuid %}"
|
href="{% url 'django_ledger:bill-update' entity_slug=entity_slug bill_pk=bill.uuid %}"
|
||||||
class="btn btn-sm btn-phoenix-warning me-md-2">{% trans 'Update' %}</a>
|
class="btn btn-sm btn-phoenix-warning me-md-2">{% trans 'Update' %}</a>
|
||||||
{% if bill.can_pay %}
|
{% if bill.can_pay %}
|
||||||
<button onclick="djLedger.toggleModal('{{ bill.get_html_id }}')"
|
<button onclick="djLedger.toggleModal('{{ bill.get_html_id }}')"
|
||||||
class="btn btn-sm btn-phoenix-info">{% trans 'Mark as Paid' %}</button>
|
class="btn btn-sm btn-phoenix-info">{% trans 'Mark as Paid' %}</button>
|
||||||
@ -203,8 +203,8 @@
|
|||||||
<!-- Update Button -->
|
<!-- Update Button -->
|
||||||
{% if perms.django_ledger.change_billmodel %}
|
{% if perms.django_ledger.change_billmodel %}
|
||||||
{% if "update" not in request.path %}
|
{% if "update" not in request.path %}
|
||||||
<a
|
<a
|
||||||
href="{% url 'bill-update' dealer_slug=dealer_slug entity_slug=entity_slug bill_pk=bill.uuid %}">
|
href="{% url 'bill-update' dealer_slug=dealer_slug entity_slug=entity_slug bill_pk=bill.uuid %}">
|
||||||
<button class="btn btn-phoenix-primary">
|
<button class="btn btn-phoenix-primary">
|
||||||
<i class="fas fa-edit me-2"></i>{% trans 'Update' %}
|
<i class="fas fa-edit me-2"></i>{% trans 'Update' %}
|
||||||
</button>
|
</button>
|
||||||
|
|||||||
@ -2,119 +2,119 @@
|
|||||||
{% load static %}
|
{% load static %}
|
||||||
{% load django_ledger %}
|
{% load django_ledger %}
|
||||||
{% load widget_tweaks %}
|
{% load widget_tweaks %}
|
||||||
<form id="bill-update-form"
|
<form id="bill-update-form"
|
||||||
action="{% url 'bill-update-items' dealer_slug=dealer_slug entity_slug=entity_slug bill_pk=bill_pk %}"
|
action="{% url 'bill-update-items' dealer_slug=dealer_slug entity_slug=entity_slug bill_pk=bill_pk %}"
|
||||||
method="post">
|
method="post">
|
||||||
<div class="container-fluid py-4">
|
<div class="container-fluid py-4">
|
||||||
<!-- Page Header -->
|
<!-- Page Header -->
|
||||||
<div class="row mb-4">
|
<div class="row mb-4">
|
||||||
<div class="col-12">
|
<div class="col-12">
|
||||||
<h2 class="text-primary mb-0 d-flex align-items-center">
|
<h2 class="text-primary mb-0 d-flex align-items-center">
|
||||||
<i class="fas fa-receipt me-2"></i>
|
<i class="fas fa-receipt me-2"></i>
|
||||||
{% trans 'Bill Items' %}
|
{% trans 'Bill Items' %}
|
||||||
</h2>
|
</h2>
|
||||||
<hr class="my-3">
|
<hr class="my-3">
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
<!-- Form Content -->
|
<!-- Form Content -->
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-12">
|
<div class="col-12">
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
{{ item_formset.non_form_errors }}
|
{{ item_formset.non_form_errors }}
|
||||||
{{ item_formset.management_form }}
|
{{ item_formset.management_form }}
|
||||||
<!-- Card Container -->
|
<!-- Card Container -->
|
||||||
<div class="card shadow-sm">
|
<div class="card shadow-sm">
|
||||||
<div class="card-body p-0">
|
<div class="card-body p-0">
|
||||||
<!-- Responsive Table -->
|
<!-- Responsive Table -->
|
||||||
<div class="table-responsive">
|
<div class="table-responsive">
|
||||||
<table class="table table-hover align-middle mb-0">
|
<table class="table table-hover align-middle mb-0">
|
||||||
<thead class="table-light">
|
<thead class="table-light">
|
||||||
<tr>
|
<tr>
|
||||||
<th class="text-uppercase text-xxs font-weight-bolder">{% trans 'Item' %}</th>
|
<th class="text-uppercase text-xxs font-weight-bolder">{% trans 'Item' %}</th>
|
||||||
<th class="text-uppercase text-xxs font-weight-bolder text-center">{% trans 'PO Qty' %}</th>
|
<th class="text-uppercase text-xxs font-weight-bolder text-center">{% trans 'PO Qty' %}</th>
|
||||||
<th class="text-uppercase text-xxs font-weight-bolder text-center">{% trans 'PO Amount' %}</th>
|
<th class="text-uppercase text-xxs font-weight-bolder text-center">{% trans 'PO Amount' %}</th>
|
||||||
<th class="text-uppercase text-xxs font-weight-bolder text-center">{% trans 'Quantity' %}</th>
|
<th class="text-uppercase text-xxs font-weight-bolder text-center">{% trans 'Quantity' %}</th>
|
||||||
<th class="text-uppercase text-xxs font-weight-bolder text-center">{% trans 'Unit Cost' %}</th>
|
<th class="text-uppercase text-xxs font-weight-bolder text-center">{% trans 'Unit Cost' %}</th>
|
||||||
<th class="text-uppercase text-xxs font-weight-bolder text-center">{% trans 'Unit' %}</th>
|
<th class="text-uppercase text-xxs font-weight-bolder text-center">{% trans 'Unit' %}</th>
|
||||||
<th class="text-uppercase text-xxs font-weight-bolder text-end">{% trans 'Total' %}</th>
|
<th class="text-uppercase text-xxs font-weight-bolder text-end">{% trans 'Total' %}</th>
|
||||||
<th class="text-uppercase text-xxs font-weight-bolder text-center">{% trans 'Delete' %}</th>
|
<th class="text-uppercase text-xxs font-weight-bolder text-center">{% trans 'Delete' %}</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{% for f in item_formset %}
|
{% for f in item_formset %}
|
||||||
<tr class="align-middle">
|
<tr class="align-middle">
|
||||||
<!-- Item Column -->
|
<!-- Item Column -->
|
||||||
<td>
|
<td>
|
||||||
<div class="d-flex flex-column ms-2">
|
<div class="d-flex flex-column ms-2">
|
||||||
{% for hidden_field in f.hidden_fields %}{{ hidden_field }}{% endfor %}
|
{% for hidden_field in f.hidden_fields %}{{ hidden_field }}{% endfor %}
|
||||||
{{ f.item_model|add_class:"form-control" }}
|
{{ f.item_model|add_class:"form-control" }}
|
||||||
{% if f.errors %}<span class="text-danger text-xs">{{ f.errors }}</span>{% endif %}
|
{% if f.errors %}<span class="text-danger text-xs">{{ f.errors }}</span>{% endif %}
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<!-- PO Quantity -->
|
<!-- PO Quantity -->
|
||||||
<td class="text-center">
|
<td class="text-center">
|
||||||
<span class="text-muted text-xs">
|
<span class="text-muted text-xs">
|
||||||
{% if f.instance.po_quantity %}{{ f.instance.po_quantity }}{% endif %}
|
{% if f.instance.po_quantity %}{{ f.instance.po_quantity }}{% endif %}
|
||||||
</span>
|
</span>
|
||||||
</td>
|
</td>
|
||||||
<!-- PO Amount -->
|
<!-- PO Amount -->
|
||||||
<td class="text-center">
|
<td class="text-center">
|
||||||
{% if f.instance.po_total_amount %}
|
{% if f.instance.po_total_amount %}
|
||||||
<div class="d-flex flex-column">
|
<div class="d-flex flex-column">
|
||||||
<span class="text-xs font-weight-bold">{{ f.instance.po_total_amount | currency_format }}<span class="icon-saudi_riyal"></span></span>
|
<span class="text-xs font-weight-bold">{{ f.instance.po_total_amount | currency_format }}<span class="icon-saudi_riyal"></span></span>
|
||||||
<a class="btn btn-sm btn-phoenix-info mt-1"
|
<a class="btn btn-sm btn-phoenix-info mt-1"
|
||||||
href="{% url 'purchase_order_detail' dealer_slug entity_slug f.instance.po_model_id %}">
|
href="{% url 'purchase_order_detail' dealer_slug entity_slug f.instance.po_model_id %}">
|
||||||
{% trans 'View PO' %}
|
{% trans 'View PO' %}
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</td>
|
</td>
|
||||||
<!-- Quantity -->
|
<!-- Quantity -->
|
||||||
<td class="text-center">
|
<td class="text-center">
|
||||||
<div class="input-group input-group-sm w-100">{{ f.quantity|add_class:"form-control" }}</div>
|
<div class="input-group input-group-sm w-100">{{ f.quantity|add_class:"form-control" }}</div>
|
||||||
</td>
|
</td>
|
||||||
<!-- Unit Cost -->
|
<!-- Unit Cost -->
|
||||||
<td class="text-center">
|
<td class="text-center">
|
||||||
<div class="input-group input-group-sm w-100">{{ f.unit_cost|add_class:"form-control" }}</div>
|
<div class="input-group input-group-sm w-100">{{ f.unit_cost|add_class:"form-control" }}</div>
|
||||||
</td>
|
</td>
|
||||||
<!-- Entity Unit -->
|
<!-- Entity Unit -->
|
||||||
<td class="text-center">{{ f.entity_unit|add_class:"form-control" }}</td>
|
<td class="text-center">{{ f.entity_unit|add_class:"form-control" }}</td>
|
||||||
<!-- Total Amount -->
|
<!-- Total Amount -->
|
||||||
<td class="text-end">
|
<td class="text-end">
|
||||||
<span class="text-xs font-weight-bold">
|
<span class="text-xs font-weight-bold">
|
||||||
<span></span>{{ f.instance.total_amount | currency_format }}<span class="icon-saudi_riyal"></span>
|
<span></span>{{ f.instance.total_amount | currency_format }}<span class="icon-saudi_riyal"></span>
|
||||||
</span>
|
</span>
|
||||||
</td>
|
</td>
|
||||||
<!-- Delete Checkbox -->
|
<!-- Delete Checkbox -->
|
||||||
<td class="text-center">
|
<td class="text-center">
|
||||||
{% if item_formset.can_delete %}<div class="form-check d-flex justify-content-center">{{ f.DELETE }}</div>{% endif %}
|
{% if item_formset.can_delete %}<div class="form-check d-flex justify-content-center">{{ f.DELETE }}</div>{% endif %}
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
{% endfor %}
|
|
||||||
</tbody>
|
|
||||||
<!-- Footer Total -->
|
|
||||||
<tfoot class="total-row">
|
|
||||||
<tr>
|
|
||||||
<td colspan="5"></td>
|
|
||||||
<td class="text-end">
|
|
||||||
<strong>{% trans 'Total' %}</strong>
|
|
||||||
</td>
|
</td>
|
||||||
<td class="text-end">
|
|
||||||
<strong>{{ total_amount__sum | currency_format }}<span class="icon-saudi_riyal"></span></strong>
|
|
||||||
</td>
|
|
||||||
<td></td>
|
|
||||||
</tr>
|
</tr>
|
||||||
</tfoot>
|
{% endfor %}
|
||||||
</table>
|
</tbody>
|
||||||
</div>
|
<!-- Footer Total -->
|
||||||
|
<tfoot class="total-row">
|
||||||
|
<tr>
|
||||||
|
<td colspan="5"></td>
|
||||||
|
<td class="text-end">
|
||||||
|
<strong>{% trans 'Total' %}</strong>
|
||||||
|
</td>
|
||||||
|
<td class="text-end">
|
||||||
|
<strong>{{ total_amount__sum | currency_format }}<span class="icon-saudi_riyal"></span></strong>
|
||||||
|
</td>
|
||||||
|
<td></td>
|
||||||
|
</tr>
|
||||||
|
</tfoot>
|
||||||
|
</table>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
<!-- Action Buttons -->
|
<!-- Action Buttons -->
|
||||||
<div class="row mt-4">
|
<div class="row mt-4">
|
||||||
<div class="col-12">
|
<div class="col-12">
|
||||||
<div class="d-flex justify-content-start gap-2">
|
<div class="d-flex justify-content-start gap-2">
|
||||||
{% comment %} {% if not item_formset.has_po %}
|
{% comment %} {% if not item_formset.has_po %}
|
||||||
<a href="{% url 'django_ledger:product-create' entity_slug=entity_slug %}"
|
<a href="{% url 'django_ledger:product-create' entity_slug=entity_slug %}"
|
||||||
class="btn btn-phoenix-primary">
|
class="btn btn-phoenix-primary">
|
||||||
@ -122,12 +122,12 @@
|
|||||||
{% trans 'New Item' %}
|
{% trans 'New Item' %}
|
||||||
</a>
|
</a>
|
||||||
{% endif %} {% endcomment %}
|
{% endif %} {% endcomment %}
|
||||||
<button type="submit" class="btn btn-phoenix-primary">
|
<button type="submit" class="btn btn-phoenix-primary">
|
||||||
<i class="fas fa-save me-1"></i>
|
<i class="fas fa-save me-1"></i>
|
||||||
{% trans 'Save Changes' %}
|
{% trans 'Save Changes' %}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</div>
|
||||||
|
</form>
|
||||||
|
|||||||
@ -38,7 +38,7 @@
|
|||||||
<td class=" white-space-nowrap align-middle" colspan="3"></td>
|
<td class=" white-space-nowrap align-middle" colspan="3"></td>
|
||||||
<td class=" white-space-nowrap align-middle" scope="col">{% trans 'Total' %}</td>
|
<td class=" white-space-nowrap align-middle" scope="col">{% trans 'Total' %}</td>
|
||||||
<td class=" white-space-nowrap align-middle" scope="col">
|
<td class=" white-space-nowrap align-middle" scope="col">
|
||||||
{{ total_credits | currency_format }}<span class="icon-saudi_riyal"></span>
|
{{ total_credits | currency_format }}<span class="icon-saudi_riyal"></span>
|
||||||
</td>
|
</td>
|
||||||
<td class=" white-space-nowrap align-middle" scope="col">{{ total_debits | currency_format }}<span class="icon-saudi_riyal"></span></td>
|
<td class=" white-space-nowrap align-middle" scope="col">{{ total_debits | currency_format }}<span class="icon-saudi_riyal"></span></td>
|
||||||
<td class=" white-space-nowrap align-middle" scope="col"></td>
|
<td class=" white-space-nowrap align-middle" scope="col"></td>
|
||||||
|
|||||||
@ -3,7 +3,7 @@
|
|||||||
{% load django_ledger %}
|
{% load django_ledger %}
|
||||||
{% load widget_tweaks %}
|
{% load widget_tweaks %}
|
||||||
{% block title %}
|
{% block title %}
|
||||||
{% trans "Create Chart of Accounts" %}
|
{% trans "Create Chart of Accounts" %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<main class="d-flex align-items-center justify-content-center min-vh-80 py-5">
|
<main class="d-flex align-items-center justify-content-center min-vh-80 py-5">
|
||||||
@ -12,7 +12,7 @@
|
|||||||
<div class="card-header bg-gradient py-4 border-0 rounded-top-4">
|
<div class="card-header bg-gradient py-4 border-0 rounded-top-4">
|
||||||
<h3 class="mb-0 fs-4 fw-bold text-center">
|
<h3 class="mb-0 fs-4 fw-bold text-center">
|
||||||
{% trans 'Create Chart of Accounts' %}
|
{% trans 'Create Chart of Accounts' %}
|
||||||
<i class="fa-solid fa-chart-pie ms-2"></i>
|
<i class="fa-solid fa-chart-pie ms-2"></i>
|
||||||
</h3>
|
</h3>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-body p-4 p-md-5">
|
<div class="card-body p-4 p-md-5">
|
||||||
|
|||||||
@ -3,7 +3,7 @@
|
|||||||
{% load static %}
|
{% load static %}
|
||||||
{% load icon from django_ledger %}
|
{% load icon from django_ledger %}
|
||||||
{% block title %}
|
{% block title %}
|
||||||
{% trans "Chart of Accounts" %}
|
{% trans "Chart of Accounts" %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div class="card mb-4">
|
<div class="card mb-4">
|
||||||
|
|||||||
@ -3,7 +3,7 @@
|
|||||||
{% load static %}
|
{% load static %}
|
||||||
{% load widget_tweaks %}
|
{% load widget_tweaks %}
|
||||||
{% block title %}
|
{% block title %}
|
||||||
{% trans "Update chart of Account"%}
|
{% trans "Update chart of Account"%}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div class="row justify-content-center">
|
<div class="row justify-content-center">
|
||||||
|
|||||||
@ -9,7 +9,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="flex-grow-1">
|
<div class="flex-grow-1">
|
||||||
<h5 class="fw-bold mb-0">
|
<h5 class="fw-bold mb-0">
|
||||||
|
|
||||||
{% if coa_model.is_default %}
|
{% if coa_model.is_default %}
|
||||||
<span class="badge bg-light text-primary ms-2 d-none d-sm-inline">{% trans 'DEFAULT' %}</span>
|
<span class="badge bg-light text-primary ms-2 d-none d-sm-inline">{% trans 'DEFAULT' %}</span>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|||||||
@ -30,55 +30,55 @@
|
|||||||
<p class="mb-0 fw-semibold fs-9">I need help with something</p>
|
<p class="mb-0 fw-semibold fs-9">I need help with something</p>
|
||||||
<span class="fa-solid fa-paper-plane text-primary fs-9 ms-3"></span>
|
<span class="fa-solid fa-paper-plane text-primary fs-9 ms-3"></span>
|
||||||
</a><a class="mb-2 d-inline-flex align-items-center text-decoration-none text-body-emphasis bg-body-hover rounded-pill border border-primary py-2 ps-4 pe-3"
|
</a><a class="mb-2 d-inline-flex align-items-center text-decoration-none text-body-emphasis bg-body-hover rounded-pill border border-primary py-2 ps-4 pe-3"
|
||||||
href="#!">
|
href="#!">
|
||||||
<p class="mb-0 fw-semibold fs-9">I can’t reorder a product I previously ordered</p>
|
<p class="mb-0 fw-semibold fs-9">I can’t reorder a product I previously ordered</p>
|
||||||
<span class="fa-solid fa-paper-plane text-primary fs-9 ms-3"></span>
|
<span class="fa-solid fa-paper-plane text-primary fs-9 ms-3"></span>
|
||||||
</a><a class="mb-2 d-inline-flex align-items-center text-decoration-none text-body-emphasis bg-body-hover rounded-pill border border-primary py-2 ps-4 pe-3"
|
</a><a class="mb-2 d-inline-flex align-items-center text-decoration-none text-body-emphasis bg-body-hover rounded-pill border border-primary py-2 ps-4 pe-3"
|
||||||
href="#!">
|
href="#!">
|
||||||
<p class="mb-0 fw-semibold fs-9">How do I place an order?</p>
|
<p class="mb-0 fw-semibold fs-9">How do I place an order?</p>
|
||||||
<span class="fa-solid fa-paper-plane text-primary fs-9 ms-3"></span>
|
<span class="fa-solid fa-paper-plane text-primary fs-9 ms-3"></span>
|
||||||
</a><a class="false d-inline-flex align-items-center text-decoration-none text-body-emphasis bg-body-hover rounded-pill border border-primary py-2 ps-4 pe-3"
|
</a><a class="false d-inline-flex align-items-center text-decoration-none text-body-emphasis bg-body-hover rounded-pill border border-primary py-2 ps-4 pe-3"
|
||||||
href="#!">
|
href="#!">
|
||||||
<p class="mb-0 fw-semibold fs-9">My payment method not working</p>
|
<p class="mb-0 fw-semibold fs-9">My payment method not working</p>
|
||||||
<span class="fa-solid fa-paper-plane text-primary fs-9 ms-3"></span>
|
<span class="fa-solid fa-paper-plane text-primary fs-9 ms-3"></span>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="text-center mt-auto">
|
<div class="text-center mt-auto">
|
||||||
<div class="avatar avatar-3xl status-online">
|
<div class="avatar avatar-3xl status-online">
|
||||||
<img class="rounded-circle border border-3 border-light-subtle"
|
<img class="rounded-circle border border-3 border-light-subtle"
|
||||||
src="{% static 'images/team/40x40/30.webp' %}"
|
src="{% static 'images/team/40x40/30.webp' %}"
|
||||||
alt="" />
|
alt="" />
|
||||||
|
</div>
|
||||||
|
<h5 class="mt-2 mb-3">Eric</h5>
|
||||||
|
<p class="text-center text-body-emphasis mb-0">
|
||||||
|
Ask us anything – we’ll get back to you here or by email within 24 hours.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="card-footer d-flex align-items-center gap-2 border-top border-translucent ps-3 pe-4 py-3">
|
||||||
|
<div class="d-flex align-items-center flex-1 gap-3 border border-translucent rounded-pill px-4">
|
||||||
|
<input class="form-control outline-none border-0 flex-1 fs-9 px-0"
|
||||||
|
type="text"
|
||||||
|
placeholder="Write message" />
|
||||||
|
<label class="btn btn-link d-flex p-0 text-body-quaternary fs-9 border-0"
|
||||||
|
for="supportChatPhotos">
|
||||||
|
<span class="fa-solid fa-image"></span>
|
||||||
|
</label>
|
||||||
|
<input class="d-none" type="file" accept="image/*" id="supportChatPhotos" />
|
||||||
|
<label class="btn btn-link d-flex p-0 text-body-quaternary fs-9 border-0"
|
||||||
|
for="supportChatAttachment">
|
||||||
|
<span class="fa-solid fa-paperclip"></span>
|
||||||
|
</label>
|
||||||
|
<input class="d-none" type="file" id="supportChatAttachment" />
|
||||||
|
</div>
|
||||||
|
<button class="btn p-0 border-0 send-btn">
|
||||||
|
<span class="fa-solid fa-paper-plane fs-9"></span>
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<h5 class="mt-2 mb-3">Eric</h5>
|
|
||||||
<p class="text-center text-body-emphasis mb-0">
|
|
||||||
Ask us anything – we’ll get back to you here or by email within 24 hours.
|
|
||||||
</p>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<button class="btn btn-support-chat p-0 border border-translucent">
|
||||||
<div class="card-footer d-flex align-items-center gap-2 border-top border-translucent ps-3 pe-4 py-3">
|
<span class="fs-8 btn-text text-primary text-nowrap">Chat demo</span><span class="ping-icon-wrapper mt-n4 ms-n6 mt-sm-0 ms-sm-2 position-absolute position-sm-relative"><span class="ping-icon-bg"></span><span class="fa-solid fa-circle ping-icon"></span></span><span class="fa-solid fa-headset text-primary fs-8 d-sm-none"></span><span class="fa-solid fa-chevron-down text-primary fs-7"></span>
|
||||||
<div class="d-flex align-items-center flex-1 gap-3 border border-translucent rounded-pill px-4">
|
|
||||||
<input class="form-control outline-none border-0 flex-1 fs-9 px-0"
|
|
||||||
type="text"
|
|
||||||
placeholder="Write message" />
|
|
||||||
<label class="btn btn-link d-flex p-0 text-body-quaternary fs-9 border-0"
|
|
||||||
for="supportChatPhotos">
|
|
||||||
<span class="fa-solid fa-image"></span>
|
|
||||||
</label>
|
|
||||||
<input class="d-none" type="file" accept="image/*" id="supportChatPhotos" />
|
|
||||||
<label class="btn btn-link d-flex p-0 text-body-quaternary fs-9 border-0"
|
|
||||||
for="supportChatAttachment">
|
|
||||||
<span class="fa-solid fa-paperclip"></span>
|
|
||||||
</label>
|
|
||||||
<input class="d-none" type="file" id="supportChatAttachment" />
|
|
||||||
</div>
|
|
||||||
<button class="btn p-0 border-0 send-btn">
|
|
||||||
<span class="fa-solid fa-paper-plane fs-9"></span>
|
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<button class="btn btn-support-chat p-0 border border-translucent">
|
|
||||||
<span class="fs-8 btn-text text-primary text-nowrap">Chat demo</span><span class="ping-icon-wrapper mt-n4 ms-n6 mt-sm-0 ms-sm-2 position-absolute position-sm-relative"><span class="ping-icon-bg"></span><span class="fa-solid fa-circle ping-icon"></span></span><span class="fa-solid fa-headset text-primary fs-8 d-sm-none"></span><span class="fa-solid fa-chevron-down text-primary fs-7"></span>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
|
|||||||
@ -16,12 +16,13 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
<form id="noteForm"
|
<form id="noteForm"
|
||||||
hx-boost="true"
|
hx-boost="true"
|
||||||
action="{% url 'add_note' request.dealer.slug content_type slug %}"
|
action="{% url 'add_note' request.dealer.slug content_type slug %}"
|
||||||
hx-select="#notesTable"
|
hx-select="#notesTable"
|
||||||
hx-target="#notesTable"
|
hx-target="#notesTable"
|
||||||
hx-on::after-request="{ resetSubmitButton(document.querySelector('.add_note_form button[type=submit]')); $('#noteModal').modal('hide'); }"
|
hx-on::after-request="{ resetSubmitButton(document.querySelector('.add_note_form button[type=submit]')); $('#noteModal').modal('hide'); }"
|
||||||
hx-swap="outerHTML show:window.top"
|
hx-swap="outerHTML show:window.top"
|
||||||
|
hx-select-oob="#timeline"
|
||||||
method="post"
|
method="post"
|
||||||
class="add_note_form">
|
class="add_note_form">
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
|
|||||||
@ -22,7 +22,7 @@
|
|||||||
hx-target=".taskTable"
|
hx-target=".taskTable"
|
||||||
hx-on::after-request="{ resetSubmitButton(document.querySelector('.add_schedule_form button[type=submit]')); $('#scheduleModal').modal('hide'); }"
|
hx-on::after-request="{ resetSubmitButton(document.querySelector('.add_schedule_form button[type=submit]')); $('#scheduleModal').modal('hide'); }"
|
||||||
hx-swap="outerHTML"
|
hx-swap="outerHTML"
|
||||||
hx-select-oob="#toast-container:outerHTML"
|
hx-select-oob="#toast-container:outerHTML,#timeline:outerHTML"
|
||||||
method="post"
|
method="post"
|
||||||
class="add_schedule_form">
|
class="add_schedule_form">
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
|
|||||||
@ -28,7 +28,7 @@
|
|||||||
hx-post="{% url 'add_task' request.dealer.slug content_type slug %}"
|
hx-post="{% url 'add_task' request.dealer.slug content_type slug %}"
|
||||||
hx-target="#your-content-container"
|
hx-target="#your-content-container"
|
||||||
hx-swap="innerHTML"
|
hx-swap="innerHTML"
|
||||||
>
|
>
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
{{ staff_task_form|crispy }}
|
{{ staff_task_form|crispy }}
|
||||||
<button type="submit" class="btn btn-phoenix-success w-100">{% trans 'Save' %}</button>
|
<button type="submit" class="btn btn-phoenix-success w-100">{% trans 'Save' %}</button>
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
{% extends 'base.html' %}
|
{% extends 'base.html' %}
|
||||||
{% load static %}
|
{% load static %}
|
||||||
{% block title %}
|
{% block title %}
|
||||||
{% trans "Calender Events" %}
|
{% trans "Calender Events" %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div class="row">
|
<div class="row">
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
{% load i18n static humanize %}
|
{% load i18n static humanize %}
|
||||||
{% load crispy_forms_tags %}
|
{% load crispy_forms_tags %}
|
||||||
{% block title %}
|
{% block title %}
|
||||||
{% trans "Lead Detail" %}
|
{% trans "Lead Detail" %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
{% block customCSS %}
|
{% block customCSS %}
|
||||||
<style>
|
<style>
|
||||||
@ -335,7 +335,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="row justify-content-between align-items-md-center hover-actions-trigger btn-reveal-trigger border-translucent py-3 gx-0 border-top">
|
<div class="row justify-content-between align-items-md-center hover-actions-trigger btn-reveal-trigger border-translucent py-3 gx-0 border-top">
|
||||||
<div class="col-12 col-lg-auto">
|
<div class="col-12 col-lg-auto">
|
||||||
<div class="timeline-basic mb-9">
|
<div id="timeline" class="timeline-basic mb-9">
|
||||||
{% for activity in activities %}
|
{% for activity in activities %}
|
||||||
<div class="timeline-item">
|
<div class="timeline-item">
|
||||||
<div class="row g-3">
|
<div class="row g-3">
|
||||||
@ -354,6 +354,8 @@
|
|||||||
<span class="fa-solid fa-users text-danger fs-8"></span>
|
<span class="fa-solid fa-users text-danger fs-8"></span>
|
||||||
{% elif activity.activity_type == "whatsapp" %}
|
{% elif activity.activity_type == "whatsapp" %}
|
||||||
<span class="fab fa-whatsapp text-success-dark fs-7"></span>
|
<span class="fab fa-whatsapp text-success-dark fs-7"></span>
|
||||||
|
{% elif activity.activity_type == "meeting" %}
|
||||||
|
<span class="fa-solid fa-users text-danger fs-8"></span>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
{% if forloop.last %}
|
{% if forloop.last %}
|
||||||
@ -806,18 +808,18 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{% include 'modal/delete_modal.html' %}
|
{% include 'modal/delete_modal.html' %}
|
||||||
<!-- add update Modal -->
|
<!-- add update Modal -->
|
||||||
{% include "components/email_modal.html" %}
|
{% include "components/email_modal.html" %}
|
||||||
<!-- task Modal -->
|
<!-- task Modal -->
|
||||||
{% include "components/task_modal.html" with content_type="lead" slug=lead.slug %}
|
{% include "components/task_modal.html" with content_type="lead" slug=lead.slug %}
|
||||||
<!-- note Modal -->
|
<!-- note Modal -->
|
||||||
{% include "components/note_modal.html" with content_type="lead" slug=lead.slug %}
|
{% include "components/note_modal.html" with content_type="lead" slug=lead.slug %}
|
||||||
<!-- schedule Modal -->
|
<!-- schedule Modal -->
|
||||||
{% include "components/schedule_modal.html" with content_type="lead" slug=lead.slug %}
|
{% include "components/schedule_modal.html" with content_type="lead" slug=lead.slug %}
|
||||||
{% endblock content %}
|
{% endblock content %}
|
||||||
{% block customJS %}
|
{% block customJS %}
|
||||||
<script>
|
<script>
|
||||||
function reset_form() {
|
function reset_form() {
|
||||||
document.querySelector('#id_note').value = ""
|
document.querySelector('#id_note').value = ""
|
||||||
let form = document.querySelector('.add_note_form')
|
let form = document.querySelector('.add_note_form')
|
||||||
@ -872,5 +874,5 @@
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
{% endblock customJS %}
|
{% endblock customJS %}
|
||||||
|
|||||||
@ -239,25 +239,25 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
{% empty %}
|
{% empty %}
|
||||||
<tr>
|
<tr>
|
||||||
<td colspan="6" class="text-center">{% trans "No Leads found." %}</td>
|
<td colspan="6" class="text-center">{% trans "No Leads found." %}</td>
|
||||||
</tr>
|
</tr>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
</div>
|
||||||
|
{% if page_obj.paginator.num_pages > 1 %}
|
||||||
|
<div class="d-flex justify-content-end mt-3">
|
||||||
|
<div class="d-flex">{% include 'partials/pagination.html' %}</div>
|
||||||
</div>
|
</div>
|
||||||
{% if page_obj.paginator.num_pages > 1 %}
|
|
||||||
<div class="d-flex justify-content-end mt-3">
|
|
||||||
<div class="d-flex">{% include 'partials/pagination.html' %}</div>
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% else %}
|
</div>
|
||||||
{% url 'lead_create' request.dealer.slug as create_lead_url %}
|
{% else %}
|
||||||
{% include "empty-illustration-page.html" with value=empty_state_value url=create_lead_url %}
|
{% url 'lead_create' request.dealer.slug as create_lead_url %}
|
||||||
{% endif %}
|
{% include "empty-illustration-page.html" with value=empty_state_value url=create_lead_url %}
|
||||||
{% endblock %}
|
{% endif %}
|
||||||
|
{% endblock %}
|
||||||
|
|||||||
@ -49,8 +49,8 @@
|
|||||||
<div class="d-flex gap-2">
|
<div class="d-flex gap-2">
|
||||||
{% comment %} <a href="{{ request.META.HTTP_REFERER }}" class="btn btn-phoenix-danger">Discard</a> {% endcomment %}
|
{% comment %} <a href="{{ request.META.HTTP_REFERER }}" class="btn btn-phoenix-danger">Discard</a> {% endcomment %}
|
||||||
<a
|
<a
|
||||||
href="{% url 'send_lead_email' request.dealer.slug lead.slug %}?status=draft"
|
href="{% url 'send_lead_email' request.dealer.slug lead.slug %}?status=draft"
|
||||||
class="btn btn-phoenix-success">{% trans "Save as Draft" %}</a>
|
class="btn btn-phoenix-success">{% trans "Save as Draft" %}</a>
|
||||||
<button class="btn btn-phoenix-primary fs-10" type="submit">
|
<button class="btn btn-phoenix-primary fs-10" type="submit">
|
||||||
{% trans "Send" %}<span class="fa-solid fa-paper-plane ms-1"></span>
|
{% trans "Send" %}<span class="fa-solid fa-paper-plane ms-1"></span>
|
||||||
</button>
|
</button>
|
||||||
@ -59,6 +59,6 @@
|
|||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endblock content %}
|
{% endblock content %}
|
||||||
|
|||||||
@ -3,16 +3,16 @@
|
|||||||
<form method="post"
|
<form method="post"
|
||||||
action="{% url 'update_note_to_lead' note.pk %}"
|
action="{% url 'update_note_to_lead' note.pk %}"
|
||||||
enctype="multipart/form-data">
|
enctype="multipart/form-data">
|
||||||
{% else %}
|
{% else %}
|
||||||
<form method="post"
|
<form method="post"
|
||||||
action="{% url 'add_note_to_lead' lead.slug %}"
|
action="{% url 'add_note_to_lead' lead.slug %}"
|
||||||
enctype="multipart/form-data">
|
enctype="multipart/form-data">
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
{{ form|crispy }}
|
{{ form|crispy }}
|
||||||
{% if form.instance.pk %}
|
{% if form.instance.pk %}
|
||||||
<button type="submit" class="btn btn-sm btn-phoenix-primary w-100">{{ _("Update") }}</button>
|
<button type="submit" class="btn btn-sm btn-phoenix-primary w-100">{{ _("Update") }}</button>
|
||||||
{% else %}
|
{% else %}
|
||||||
<button type="submit" class="btn btn-sm btn-phoenix-success w-100">{{ _("Add") }}</button>
|
<button type="submit" class="btn btn-sm btn-phoenix-success w-100">{{ _("Add") }}</button>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</form>
|
</form>
|
||||||
|
|||||||
@ -7,24 +7,24 @@
|
|||||||
|
|
||||||
{% block customeCSS %}
|
{% block customeCSS %}
|
||||||
|
|
||||||
/* General Layout */
|
/* General Layout */
|
||||||
body {
|
body {
|
||||||
background-color: #f8f9fa; /* Light gray background for contrast */
|
background-color: #f8f9fa; /* Light gray background for contrast */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* List Item Styling */
|
/* List Item Styling */
|
||||||
.list-item {
|
.list-item {
|
||||||
transition: background-color 0.2s ease-in-out, transform 0.2s ease-in-out;
|
transition: background-color 0.2s ease-in-out, transform 0.2s ease-in-out;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
.list-item:hover {
|
.list-item:hover {
|
||||||
background-color: #f1f3f5;
|
background-color: #f1f3f5;
|
||||||
transform: translateY(-2px); /* Subtle lift on hover */
|
transform: translateY(-2px); /* Subtle lift on hover */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Unread Notification Dot */
|
/* Unread Notification Dot */
|
||||||
.unread-dot {
|
.unread-dot {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: 0;
|
left: 0;
|
||||||
top: 50%;
|
top: 50%;
|
||||||
@ -32,12 +32,12 @@ body {
|
|||||||
width: 8px;
|
width: 8px;
|
||||||
height: 8px;
|
height: 8px;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* HTMX Loading Indicator */
|
/* HTMX Loading Indicator */
|
||||||
.htmx-request #loading-indicator {
|
.htmx-request #loading-indicator {
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<main class="container-fluid p-5">
|
<main class="container-fluid p-5">
|
||||||
@ -61,17 +61,17 @@ body {
|
|||||||
{% for notification in notifications %}
|
{% for notification in notifications %}
|
||||||
<div class="list-item d-flex align-items-start py-4 border-bottom position-relative">
|
<div class="list-item d-flex align-items-start py-4 border-bottom position-relative">
|
||||||
{% if not notification.is_read %}
|
{% if not notification.is_read %}
|
||||||
|
|
||||||
<div class="me-4 mt-1">
|
<div class="me-4 mt-1">
|
||||||
<i class="fas fa-info-circle fa-2x text-primary"></i>
|
<i class="fas fa-info-circle fa-2x text-primary"></i>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{% else %}
|
{% else %}
|
||||||
<div class="me-4 mt-1">
|
<div class="me-4 mt-1">
|
||||||
<i class="fas fa-info-circle fa-2x text-secondary"></i>
|
<i class="fas fa-info-circle fa-2x text-secondary"></i>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
<div class="flex-grow-1">
|
<div class="flex-grow-1">
|
||||||
<h5 class="mb-1 fw-normal">
|
<h5 class="mb-1 fw-normal">
|
||||||
{{ notification.message|safe }}
|
{{ notification.message|safe }}
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -181,37 +181,37 @@
|
|||||||
</div>
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
{% block customJS %}
|
{% block customJS %}
|
||||||
<script>
|
<script>
|
||||||
function updateProbabilityValue(value) {
|
function updateProbabilityValue(value) {
|
||||||
const amount = document.getElementById('id_amount');
|
const amount = document.getElementById('id_amount');
|
||||||
const expectedRevenue = document.getElementById('id_expected_revenue');
|
const expectedRevenue = document.getElementById('id_expected_revenue');
|
||||||
|
|
||||||
// Check if amount and expectedRevenue fields exist before using them
|
// Check if amount and expectedRevenue fields exist before using them
|
||||||
if (amount && expectedRevenue) {
|
if (amount && expectedRevenue) {
|
||||||
expectedRevenue.value = (parseFloat(amount.value) * value / 100).toFixed(2);
|
expectedRevenue.value = (parseFloat(amount.value) * value / 100).toFixed(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
const badge = document.getElementById('probability-value');
|
const badge = document.getElementById('probability-value');
|
||||||
if (badge) {
|
if (badge) {
|
||||||
badge.textContent = value + '%';
|
badge.textContent = value + '%';
|
||||||
// Update badge color based on value
|
// Update badge color based on value
|
||||||
if (value >= 75) {
|
if (value >= 75) {
|
||||||
badge.className = 'badge badge-phoenix fs-6 badge-phoenix-success';
|
badge.className = 'badge badge-phoenix fs-6 badge-phoenix-success';
|
||||||
} else if (value >= 50) {
|
} else if (value >= 50) {
|
||||||
badge.className = 'badge badge-phoenix fs-6 badge-phoenix-warning';
|
badge.className = 'badge badge-phoenix fs-6 badge-phoenix-warning';
|
||||||
} else {
|
} else {
|
||||||
badge.className = 'badge badge-phoenix fs-6 badge-phoenix-danger';
|
badge.className = 'badge badge-phoenix fs-6 badge-phoenix-danger';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize on load
|
// Initialize on load
|
||||||
document.addEventListener('DOMContentLoaded', function() {
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
const rangeInput = document.getElementById('{{ form.probability.id_for_label }}');
|
const rangeInput = document.getElementById('{{ form.probability.id_for_label }}');
|
||||||
// Check if rangeInput exists before calling the function
|
// Check if rangeInput exists before calling the function
|
||||||
if (rangeInput) {
|
if (rangeInput) {
|
||||||
updateProbabilityValue(rangeInput.value);
|
updateProbabilityValue(rangeInput.value);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
@ -128,12 +128,12 @@
|
|||||||
document.addEventListener("DOMContentLoaded", function() {
|
document.addEventListener("DOMContentLoaded", function() {
|
||||||
const searchInput = document.getElementById("search-input");
|
const searchInput = document.getElementById("search-input");
|
||||||
const clearButton = document.getElementById("clear-search");
|
const clearButton = document.getElementById("clear-search");
|
||||||
|
|
||||||
if (clearButton) {
|
if (clearButton) {
|
||||||
clearButton.addEventListener("click", function() {
|
clearButton.addEventListener("click", function() {
|
||||||
// Clear the input field
|
// Clear the input field
|
||||||
searchInput.value = "";
|
searchInput.value = "";
|
||||||
|
|
||||||
// Trigger HTMX search with a 'search' event
|
// Trigger HTMX search with a 'search' event
|
||||||
// This uses the hx-trigger="search" on the form
|
// This uses the hx-trigger="search" on the form
|
||||||
// and prevents a full page reload.
|
// and prevents a full page reload.
|
||||||
|
|||||||
@ -32,45 +32,45 @@
|
|||||||
<div class="d-flex gap-2">
|
<div class="d-flex gap-2">
|
||||||
{% if opportunity.stage == "qualification" %}
|
{% if opportunity.stage == "qualification" %}
|
||||||
<span class="badge badge-phoenix fs-10 badge-phoenix-primary">
|
<span class="badge badge-phoenix fs-10 badge-phoenix-primary">
|
||||||
{% elif opportunity.stage == "test_drive" %}
|
{% elif opportunity.stage == "test_drive" %}
|
||||||
<span class="badge badge-phoenix fs-10 badge-phoenix-info">
|
<span class="badge badge-phoenix fs-10 badge-phoenix-info">
|
||||||
{% elif opportunity.stage == "quotation" %}
|
{% elif opportunity.stage == "quotation" %}
|
||||||
<span class="badge badge-phoenix fs-10 badge-phoenix-warning">
|
<span class="badge badge-phoenix fs-10 badge-phoenix-warning">
|
||||||
{% elif opportunity.stage == "negotiation" %}
|
{% elif opportunity.stage == "negotiation" %}
|
||||||
<span class="badge badge-phoenix fs-10 badge-phoenix-warning">
|
<span class="badge badge-phoenix fs-10 badge-phoenix-warning">
|
||||||
{% elif opportunity.stage == "financing" %}
|
{% elif opportunity.stage == "financing" %}
|
||||||
<span class="badge badge-phoenix fs-10 badge-phoenix-warning">
|
<span class="badge badge-phoenix fs-10 badge-phoenix-warning">
|
||||||
{% elif opportunity.stage == "closed_won" %}
|
{% elif opportunity.stage == "closed_won" %}
|
||||||
<span class="badge badge-phoenix fs-10 badge-phoenix-success">
|
<span class="badge badge-phoenix fs-10 badge-phoenix-success">
|
||||||
{% elif opportunity.stage == "closed_lost" %}
|
{% elif opportunity.stage == "closed_lost" %}
|
||||||
<span class="badge badge-phoenix fs-10 badge-phoenix-danger">
|
<span class="badge badge-phoenix fs-10 badge-phoenix-danger">
|
||||||
{% elif opportunity.stage == "on_hold" %}
|
{% elif opportunity.stage == "on_hold" %}
|
||||||
<span class="badge badge-phoenix fs-10 badge-phoenix-secondary">
|
<span class="badge badge-phoenix fs-10 badge-phoenix-secondary">
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{{ opportunity.stage }}</span>
|
{{ opportunity.stage }}</span>
|
||||||
<span class="badge badge-phoenix fs-10 {% if opportunity.get_stage_display == 'Won' %} badge-phoenix-success {% elif opportunity.get_stage_display == 'Lost' %} badge-phoenix-danger {% endif %}">
|
<span class="badge badge-phoenix fs-10 {% if opportunity.get_stage_display == 'Won' %} badge-phoenix-success {% elif opportunity.get_stage_display == 'Lost' %} badge-phoenix-danger {% endif %}">
|
||||||
{{ opportunity.get_status_display }}
|
{{ opportunity.get_status_display }}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="d-flex align-items-center">
|
<div class="d-flex align-items-center">
|
||||||
<i class="fa-regular fa-clock"></i>
|
<i class="fa-regular fa-clock"></i>
|
||||||
<p class="mb-0 fs-9 fw-semibold text-body-tertiary">{{ opportunity.created|naturalday|capfirst }}</p>
|
<p class="mb-0 fs-9 fw-semibold text-body-tertiary">{{ opportunity.created|naturalday|capfirst }}</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="deals-company-agent d-flex justify-content-between mb-3">
|
<div class="deals-company-agent d-flex justify-content-between mb-3">
|
||||||
<div class="d-flex align-items-center">
|
<div class="d-flex align-items-center">
|
||||||
<span class="uil uil-user me-2"></span>
|
<span class="uil uil-user me-2"></span>
|
||||||
<p class="text-body-secondary fw-bold fs-10 mb-0">
|
<p class="text-body-secondary fw-bold fs-10 mb-0">
|
||||||
{{ _("Assigned To") }}
|
{{ _("Assigned To") }}
|
||||||
{% if request.user.email == opportunity.staff.email %}
|
{% if request.user.email == opportunity.staff.email %}
|
||||||
{{ _("You") }}
|
{{ _("You") }}
|
||||||
{% else %}
|
{% else %}
|
||||||
{{ opportunity.staff.fullname }}
|
{{ opportunity.staff.fullname }}
|
||||||
</p>
|
</p>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<table class="mb-3 w-100">
|
<table class="mb-3 w-100">
|
||||||
{% comment %} <tr>
|
{% comment %} <tr>
|
||||||
<td class="py-1">
|
<td class="py-1">
|
||||||
<div class="d-flex align-items-center">
|
<div class="d-flex align-items-center">
|
||||||
@ -84,81 +84,81 @@
|
|||||||
</p>
|
</p>
|
||||||
</td>
|
</td>
|
||||||
</tr> {% endcomment %}
|
</tr> {% endcomment %}
|
||||||
<tr>
|
<tr>
|
||||||
<td class="py-1">
|
<td class="py-1">
|
||||||
<div class="d-flex align-items-center">
|
<div class="d-flex align-items-center">
|
||||||
<p class="fw-semibold fs-9 mb-0 text-body-tertiary">
|
<p class="fw-semibold fs-9 mb-0 text-body-tertiary">
|
||||||
{% trans "Marked Price" %}
|
{% trans "Marked Price" %}
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td class="text-end">
|
<td class="text-end">
|
||||||
<p class="fw-semibold fs-9 mb-0 text-body-emphasis">
|
<p class="fw-semibold fs-9 mb-0 text-body-emphasis">
|
||||||
<span class="icon-saudi_riyal"></span>{{ opportunity.car.marked_price }}
|
<span class="icon-saudi_riyal"></span>{{ opportunity.car.marked_price }}
|
||||||
</p>
|
</p>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td class="py-1">
|
<td class="py-1">
|
||||||
<div class="d-flex align-items-center">
|
<div class="d-flex align-items-center">
|
||||||
<i class="uil uil-calendar-alt"></i>
|
<i class="uil uil-calendar-alt"></i>
|
||||||
<p class="fw-semibold fs-9 mb-0 text-body-tertiary">{{ _("Closing Date") }}</p>
|
<p class="fw-semibold fs-9 mb-0 text-body-tertiary">{{ _("Closing Date") }}</p>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td class="text-end">
|
<td class="text-end">
|
||||||
{% if opportunity.expected_close_date %}
|
{% if opportunity.expected_close_date %}
|
||||||
<p class="fw-semibold fs-9 mb-0 text-body-emphasis">{{ opportunity.expected_close_date|naturalday|capfirst }}</p>
|
<p class="fw-semibold fs-9 mb-0 text-body-emphasis">{{ opportunity.expected_close_date|naturalday|capfirst }}</p>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
<p class="fs-9 mb-1 fw-bold">{{ _("Probability") }}: {{ opportunity.probability }}%</p>
|
<p class="fs-9 mb-1 fw-bold">{{ _("Probability") }}: {{ opportunity.probability }}%</p>
|
||||||
<div class="progress mb-3" style="height:16px">
|
<div class="progress mb-3" style="height:16px">
|
||||||
{% if opportunity.probability >= 25 and opportunity.probability < 49 %}
|
{% if opportunity.probability >= 25 and opportunity.probability < 49 %}
|
||||||
<div class="progress-bar rounded-pill bg-danger-dark"
|
<div class="progress-bar rounded-pill bg-danger-dark"
|
||||||
role="progressbar"
|
role="progressbar"
|
||||||
style="width: {{ opportunity.probability }}%"
|
style="width: {{ opportunity.probability }}%"
|
||||||
aria-valuenow="{{ opportunity.probability }}"
|
aria-valuenow="{{ opportunity.probability }}"
|
||||||
aria-valuemin="0"
|
aria-valuemin="0"
|
||||||
aria-valuemax="100">
|
aria-valuemax="100">
|
||||||
<span class="fw-bolder fs-9 text-sm-end me-1">{{ opportunity.probability }}</span>
|
<span class="fw-bolder fs-9 text-sm-end me-1">{{ opportunity.probability }}</span>
|
||||||
</div>
|
</div>
|
||||||
{% elif opportunity.probability >= 50 and opportunity.probability <= 74 %}
|
{% elif opportunity.probability >= 50 and opportunity.probability <= 74 %}
|
||||||
<div class="progress-bar rounded-pill bg-warning-dark"
|
<div class="progress-bar rounded-pill bg-warning-dark"
|
||||||
role="progressbar"
|
role="progressbar"
|
||||||
style="width: {{ opportunity.probability }}%"
|
style="width: {{ opportunity.probability }}%"
|
||||||
aria-valuenow="{{ opportunity.probability }}"
|
aria-valuenow="{{ opportunity.probability }}"
|
||||||
aria-valuemin="0"
|
aria-valuemin="0"
|
||||||
aria-valuemax="100">
|
aria-valuemax="100">
|
||||||
<span class="fw-bolder fs-9 text-sm-end me-1">{{ opportunity.probability }}</span>
|
<span class="fw-bolder fs-9 text-sm-end me-1">{{ opportunity.probability }}</span>
|
||||||
</div>
|
</div>
|
||||||
{% elif opportunity.probability >= 75 and opportunity.probability <= 100 %}
|
{% elif opportunity.probability >= 75 and opportunity.probability <= 100 %}
|
||||||
<div class="progress-bar rounded-pill bg-success-dark"
|
<div class="progress-bar rounded-pill bg-success-dark"
|
||||||
role="progressbar"
|
role="progressbar"
|
||||||
style="width: {{ opportunity.probability }}%"
|
style="width: {{ opportunity.probability }}%"
|
||||||
aria-valuenow="{{ opportunity.probability }}"
|
aria-valuenow="{{ opportunity.probability }}"
|
||||||
aria-valuemin="0"
|
aria-valuemin="0"
|
||||||
aria-valuemax="100">
|
aria-valuemax="100">
|
||||||
<span class="fw-bolder fs-9 text-sm-end me-1">{{ opportunity.probability }}</span>
|
<span class="fw-bolder fs-9 text-sm-end me-1">{{ opportunity.probability }}</span>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
<div class="d-flex gap-2">
|
<div class="d-flex gap-2">
|
||||||
{% if perms.inventory.view_opportunity %}
|
{% if perms.inventory.view_opportunity %}
|
||||||
<a class="btn btn-sm btn-phoenix-primary"
|
<a class="btn btn-sm btn-phoenix-primary"
|
||||||
href="{% url 'opportunity_detail' request.dealer.slug opportunity.slug %}">
|
href="{% url 'opportunity_detail' request.dealer.slug opportunity.slug %}">
|
||||||
<i class="fa-solid fa-eye ms-2"></i>{{ _("View") }}
|
<i class="fa-solid fa-eye ms-2"></i>{{ _("View") }}
|
||||||
</a>
|
</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if perms.inventory.change_opportunity %}
|
{% if perms.inventory.change_opportunity %}
|
||||||
<a class="btn btn-sm btn-phoenix-success"
|
<a class="btn btn-sm btn-phoenix-success"
|
||||||
href="{% url 'update_opportunity' request.dealer.slug opportunity.slug %}">
|
href="{% url 'update_opportunity' request.dealer.slug opportunity.slug %}">
|
||||||
<i class="fa-solid fa-pen ms-2"></i> {{ _("Update") }}
|
<i class="fa-solid fa-pen ms-2"></i> {{ _("Update") }}
|
||||||
</a>
|
</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|||||||
@ -176,7 +176,7 @@
|
|||||||
class="form-control"
|
class="form-control"
|
||||||
id="marked_price"
|
id="marked_price"
|
||||||
name="marked_price"
|
name="marked_price"
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<label for="csv_file" class="form-label">{% trans "CSV File" %}</label>
|
<label for="csv_file" class="form-label">{% trans "CSV File" %}</label>
|
||||||
|
|||||||
@ -151,16 +151,16 @@
|
|||||||
</tr>
|
</tr>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</tbody>
|
</tbody>
|
||||||
{% endif %}
|
|
||||||
</table>
|
|
||||||
{% if page_obj.paginator.num_pages > 1 %}
|
|
||||||
<div class="d-flex justify-content-end mt-3">
|
|
||||||
<div class="d-flex">{% include 'partials/pagination.html' %}</div>
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
{% include 'modal/delete_modal.html' %}
|
|
||||||
{% else %}
|
|
||||||
{% url "customer_create" request.dealer.slug as create_customer_url %}
|
|
||||||
{% include "empty-illustration-page.html" with value=empty_state_value url=create_customer_url %}
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endblock %}
|
</table>
|
||||||
|
{% if page_obj.paginator.num_pages > 1 %}
|
||||||
|
<div class="d-flex justify-content-end mt-3">
|
||||||
|
<div class="d-flex">{% include 'partials/pagination.html' %}</div>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
{% include 'modal/delete_modal.html' %}
|
||||||
|
{% else %}
|
||||||
|
{% url "customer_create" request.dealer.slug as create_customer_url %}
|
||||||
|
{% include "empty-illustration-page.html" with value=empty_state_value url=create_customer_url %}
|
||||||
|
{% endif %}
|
||||||
|
{% endblock %}
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
<form method="post"
|
<form method="post"
|
||||||
action="{% url 'add_note_to_customer' request.dealer.slug customer.slug %}"
|
action="{% url 'add_note_to_customer' request.dealer.slug customer.slug %}"
|
||||||
enctype="multipart/form-data">
|
enctype="multipart/form-data">
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
{{ form|crispy }}
|
{{ form|crispy }}
|
||||||
<button type="submit" class="btn btn-sm btn-phoenix-success w-100">{{ _("Add") }}</button>
|
<button type="submit" class="btn btn-sm btn-phoenix-success w-100">{{ _("Add") }}</button>
|
||||||
</form>
|
</form>
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
{% load tenhal_tag %}
|
{% load tenhal_tag %}
|
||||||
{% block title %}
|
{% block title %}
|
||||||
{% trans "Aging Inventory" %}
|
{% trans "Aging Inventory" %}
|
||||||
{% endblock title %}
|
{% endblock title %}
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div class="main-content flex-grow-1 container-fluid mt-4 mb-3">
|
<div class="main-content flex-grow-1 container-fluid mt-4 mb-3">
|
||||||
@ -118,11 +118,11 @@
|
|||||||
<div>{% trans "Excellent! There are no cars in the aging inventory at the moment." %}</div>
|
<div>{% trans "Excellent! There are no cars in the aging inventory at the moment." %}</div>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% if is_paginated %}
|
{% if is_paginated %}
|
||||||
{% include 'partials/pagination.html' %}
|
{% include 'partials/pagination.html' %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
{% endblock content %}
|
{% endblock content %}
|
||||||
|
|||||||
@ -15,7 +15,7 @@
|
|||||||
{% elif request.is_inventory and not request.is_dealer and not request.is_manager %}
|
{% elif request.is_inventory and not request.is_dealer and not request.is_manager %}
|
||||||
{% trans "Inventory Dashboard" %}
|
{% trans "Inventory Dashboard" %}
|
||||||
{% else %}
|
{% else %}
|
||||||
{% trans "Manager Dashboard" %}
|
{% trans "Manager Dashboard" %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<i class="fas fa-chart-area text-primary ms-2"></i>
|
<i class="fas fa-chart-area text-primary ms-2"></i>
|
||||||
</h2>
|
</h2>
|
||||||
@ -49,10 +49,10 @@
|
|||||||
<div class="row g-4 mb-5">{% include 'dashboards/partials//financial_data_cards.html' %}</div>
|
<div class="row g-4 mb-5">{% include 'dashboards/partials//financial_data_cards.html' %}</div>
|
||||||
<div class="row g-4 mb-5">{% include 'dashboards/partials/chart.html' %}</div>
|
<div class="row g-4 mb-5">{% include 'dashboards/partials/chart.html' %}</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{% endblock content %}
|
{% endblock content %}
|
||||||
{% block customJS %}
|
{% block customJS %}
|
||||||
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
|
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
|
||||||
<script>
|
<script>
|
||||||
// Define a color palette that aligns with the Phoenix template
|
// Define a color palette that aligns with the Phoenix template
|
||||||
const primaryColor = '#7249b6';
|
const primaryColor = '#7249b6';
|
||||||
@ -60,18 +60,18 @@
|
|||||||
const successColor = '#00d074';
|
const successColor = '#00d074';
|
||||||
const dangerColor = '#e63757';
|
const dangerColor = '#e63757';
|
||||||
const chartColors = [
|
const chartColors = [
|
||||||
'#7249b6', '#00d074', '#e63757', '#17a2b8', '#ffc107',
|
'#7249b6', '#00d074', '#e63757', '#17a2b8', '#ffc107',
|
||||||
'#8193a6', '#28a745', '#6c757d', '#fd7e14', '#dc3545',
|
'#8193a6', '#28a745', '#6c757d', '#fd7e14', '#dc3545',
|
||||||
'#20c997', '#6f42c1', '#e83e8c', '#6610f2', '#007bff',
|
'#20c997', '#6f42c1', '#e83e8c', '#6610f2', '#007bff',
|
||||||
'#495057', '#0d6efd', '#6610f2', '#6f42c1', '#d63384',
|
'#495057', '#0d6efd', '#6610f2', '#6f42c1', '#d63384',
|
||||||
'#dc3545', '#fd7e14', '#ffc107', '#198754', '#20c997',
|
'#dc3545', '#fd7e14', '#ffc107', '#198754', '#20c997',
|
||||||
'#0dcaf0', '#0d6efd', '#6c757d', '#adb5bd', '#6c757d',
|
'#0dcaf0', '#0d6efd', '#6c757d', '#adb5bd', '#6c757d',
|
||||||
'#5a5c69', '#36b9cc', '#1cc88a', '#f6c23e', '#e74a3b',
|
'#5a5c69', '#36b9cc', '#1cc88a', '#f6c23e', '#e74a3b',
|
||||||
'#858796', '#f8f9fc', '#2c9faf', '#4e73df', '#845ef2',
|
'#858796', '#f8f9fc', '#2c9faf', '#4e73df', '#845ef2',
|
||||||
'#39e6a9', '#4d4f79', '#9f1d35', '#2a5a5b', '#f77f00',
|
'#39e6a9', '#4d4f79', '#9f1d35', '#2a5a5b', '#f77f00',
|
||||||
'#3282b8', '#00bcd4', '#009688', '#4caf50', '#8bc34a',
|
'#3282b8', '#00bcd4', '#009688', '#4caf50', '#8bc34a',
|
||||||
'#ffeb3b', '#ff9800', '#ff5722', '#795548', '#9e9e9e'
|
'#ffeb3b', '#ff9800', '#ff5722', '#795548', '#9e9e9e'
|
||||||
];
|
];
|
||||||
|
|
||||||
// Pass translated strings from Django to JavaScript
|
// Pass translated strings from Django to JavaScript
|
||||||
const translatedStrings = {
|
const translatedStrings = {
|
||||||
@ -97,7 +97,7 @@
|
|||||||
cars: "{% trans 'cars' %}"
|
cars: "{% trans 'cars' %}"
|
||||||
};
|
};
|
||||||
|
|
||||||
function getChartColors(count) {
|
function getChartColors(count) {
|
||||||
const colors = [];
|
const colors = [];
|
||||||
for (let i = 0; i < count; i++) {
|
for (let i = 0; i < count; i++) {
|
||||||
colors.push(chartColors[i % chartColors.length]);
|
colors.push(chartColors[i % chartColors.length]);
|
||||||
@ -107,334 +107,334 @@
|
|||||||
|
|
||||||
|
|
||||||
// Monthly Cars Sold (Bar Chart)
|
// Monthly Cars Sold (Bar Chart)
|
||||||
{% if request.is_dealer or request.is_manager or request.is_accountant %}
|
{% if request.is_dealer or request.is_manager or request.is_accountant %}
|
||||||
const ctx1 = document.getElementById('CarsSoldByMonthChart').getContext('2d');
|
const ctx1 = document.getElementById('CarsSoldByMonthChart').getContext('2d');
|
||||||
new Chart(ctx1, {
|
new Chart(ctx1, {
|
||||||
type: 'bar',
|
type: 'bar',
|
||||||
data: {
|
data: {
|
||||||
labels: [
|
labels: [
|
||||||
translatedStrings.jan, translatedStrings.feb, translatedStrings.mar, translatedStrings.apr,
|
translatedStrings.jan, translatedStrings.feb, translatedStrings.mar, translatedStrings.apr,
|
||||||
translatedStrings.may, translatedStrings.jun, translatedStrings.jul, translatedStrings.aug,
|
translatedStrings.may, translatedStrings.jun, translatedStrings.jul, translatedStrings.aug,
|
||||||
translatedStrings.sep, translatedStrings.oct, translatedStrings.nov, translatedStrings.dec
|
translatedStrings.sep, translatedStrings.oct, translatedStrings.nov, translatedStrings.dec
|
||||||
],
|
],
|
||||||
datasets: [{
|
datasets: [{
|
||||||
label: translatedStrings.monthlyCarsSoldLabel,
|
label: translatedStrings.monthlyCarsSoldLabel,
|
||||||
data: {{ monthly_cars_sold_json|safe }},
|
data: {{ monthly_cars_sold_json|safe }},
|
||||||
backgroundColor: primaryColor,
|
backgroundColor: primaryColor,
|
||||||
borderColor: primaryColor,
|
borderColor: primaryColor,
|
||||||
borderWidth: 1,
|
borderWidth: 1,
|
||||||
}]
|
}]
|
||||||
},
|
|
||||||
options: {
|
|
||||||
responsive: true,
|
|
||||||
maintainAspectRatio: false,
|
|
||||||
plugins: {
|
|
||||||
legend: { display: false }
|
|
||||||
},
|
},
|
||||||
scales: {
|
options: {
|
||||||
y: {
|
responsive: true,
|
||||||
beginAtZero: true,
|
maintainAspectRatio: false,
|
||||||
grid: { color: 'rgba(0, 0, 0, 0.05)' },
|
plugins: {
|
||||||
ticks: {
|
legend: { display: false }
|
||||||
color: secondaryColor,
|
},
|
||||||
callback: function(value) {
|
scales: {
|
||||||
if (Number.isInteger(value)) {
|
y: {
|
||||||
return value;
|
beginAtZero: true,
|
||||||
|
grid: { color: 'rgba(0, 0, 0, 0.05)' },
|
||||||
|
ticks: {
|
||||||
|
color: secondaryColor,
|
||||||
|
callback: function(value) {
|
||||||
|
if (Number.isInteger(value)) {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
x: {
|
||||||
|
grid: { display: false },
|
||||||
|
ticks: { color: secondaryColor }
|
||||||
}
|
}
|
||||||
},
|
|
||||||
x: {
|
|
||||||
grid: { display: false },
|
|
||||||
ticks: { color: secondaryColor }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
});
|
|
||||||
|
|
||||||
// Monthly Revenue & Profit (Line Chart)
|
// Monthly Revenue & Profit (Line Chart)
|
||||||
const ctx2 = document.getElementById('revenueProfitChart').getContext('2d');
|
const ctx2 = document.getElementById('revenueProfitChart').getContext('2d');
|
||||||
new Chart(ctx2, {
|
new Chart(ctx2, {
|
||||||
type: 'line',
|
type: 'line',
|
||||||
data: {
|
data: {
|
||||||
labels: [
|
labels: [
|
||||||
translatedStrings.jan, translatedStrings.feb, translatedStrings.mar, translatedStrings.apr,
|
translatedStrings.jan, translatedStrings.feb, translatedStrings.mar, translatedStrings.apr,
|
||||||
translatedStrings.may, translatedStrings.jun, translatedStrings.jul, translatedStrings.aug,
|
translatedStrings.may, translatedStrings.jun, translatedStrings.jul, translatedStrings.aug,
|
||||||
translatedStrings.sep, translatedStrings.oct, translatedStrings.nov, translatedStrings.dec
|
translatedStrings.sep, translatedStrings.oct, translatedStrings.nov, translatedStrings.dec
|
||||||
],
|
],
|
||||||
datasets: [
|
datasets: [
|
||||||
{
|
{
|
||||||
label: translatedStrings.monthlyRevenueLabel,
|
label: translatedStrings.monthlyRevenueLabel,
|
||||||
data: {{ monthly_revenue_json|safe }},
|
data: {{ monthly_revenue_json|safe }},
|
||||||
borderColor: primaryColor,
|
borderColor: primaryColor,
|
||||||
backgroundColor: 'rgba(114, 73, 182, 0.1)', // Using primaryColor with transparency
|
backgroundColor: 'rgba(114, 73, 182, 0.1)', // Using primaryColor with transparency
|
||||||
tension: 0.4,
|
tension: 0.4,
|
||||||
fill: true,
|
fill: true,
|
||||||
pointBackgroundColor: primaryColor,
|
pointBackgroundColor: primaryColor,
|
||||||
pointRadius: 5,
|
pointRadius: 5,
|
||||||
pointHoverRadius: 8
|
pointHoverRadius: 8
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: translatedStrings.monthlyNetProfitLabel,
|
label: translatedStrings.monthlyNetProfitLabel,
|
||||||
data: {{ monthly_net_profit_json|safe }},
|
data: {{ monthly_net_profit_json|safe }},
|
||||||
borderColor: successColor,
|
borderColor: successColor,
|
||||||
backgroundColor: 'rgba(0, 208, 116, 0.1)', // Using successColor with transparency
|
backgroundColor: 'rgba(0, 208, 116, 0.1)', // Using successColor with transparency
|
||||||
tension: 0.4,
|
tension: 0.4,
|
||||||
fill: true,
|
fill: true,
|
||||||
pointBackgroundColor: successColor,
|
pointBackgroundColor: successColor,
|
||||||
pointRadius: 5,
|
pointRadius: 5,
|
||||||
pointHoverRadius: 8
|
pointHoverRadius: 8
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
options: {
|
|
||||||
responsive: true,
|
|
||||||
maintainAspectRatio: false,
|
|
||||||
plugins: {
|
|
||||||
legend: {
|
|
||||||
display: true,
|
|
||||||
labels: { boxWidth: 20 }
|
|
||||||
},
|
|
||||||
tooltip: {
|
|
||||||
backgroundColor: 'rgba(33, 37, 41, 0.9)',
|
|
||||||
titleColor: 'white',
|
|
||||||
bodyColor: 'white',
|
|
||||||
padding: 10,
|
|
||||||
callbacks: {
|
|
||||||
label: function(context) {
|
|
||||||
let label = context.dataset.label || '';
|
|
||||||
if (label) {
|
|
||||||
label += ': ';
|
|
||||||
}
|
|
||||||
if (context.parsed.y !== null) {
|
|
||||||
label += new Intl.NumberFormat('en-US', { style: 'currency', currency: 'SAR' }).format(context.parsed.y);
|
|
||||||
}
|
|
||||||
return label;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
]
|
||||||
},
|
},
|
||||||
scales: {
|
options: {
|
||||||
x: {
|
responsive: true,
|
||||||
grid: { color: 'rgba(0, 0, 0, 0.05)' },
|
maintainAspectRatio: false,
|
||||||
ticks: { color: secondaryColor },
|
plugins: {
|
||||||
border: { color: secondaryColor }
|
legend: {
|
||||||
|
display: true,
|
||||||
|
labels: { boxWidth: 20 }
|
||||||
|
},
|
||||||
|
tooltip: {
|
||||||
|
backgroundColor: 'rgba(33, 37, 41, 0.9)',
|
||||||
|
titleColor: 'white',
|
||||||
|
bodyColor: 'white',
|
||||||
|
padding: 10,
|
||||||
|
callbacks: {
|
||||||
|
label: function(context) {
|
||||||
|
let label = context.dataset.label || '';
|
||||||
|
if (label) {
|
||||||
|
label += ': ';
|
||||||
|
}
|
||||||
|
if (context.parsed.y !== null) {
|
||||||
|
label += new Intl.NumberFormat('en-US', { style: 'currency', currency: 'SAR' }).format(context.parsed.y);
|
||||||
|
}
|
||||||
|
return label;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
y: {
|
scales: {
|
||||||
grid: { color: 'rgba(0, 0, 0, 0.05)' },
|
x: {
|
||||||
ticks: { color: secondaryColor },
|
grid: { color: 'rgba(0, 0, 0, 0.05)' },
|
||||||
border: { color: secondaryColor }
|
ticks: { color: secondaryColor },
|
||||||
|
border: { color: secondaryColor }
|
||||||
|
},
|
||||||
|
y: {
|
||||||
|
grid: { color: 'rgba(0, 0, 0, 0.05)' },
|
||||||
|
ticks: { color: secondaryColor },
|
||||||
|
border: { color: secondaryColor }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
});
|
|
||||||
|
|
||||||
// Sales by Make (Pie Chart)
|
|
||||||
|
|
||||||
|
|
||||||
const ctx3 = document.getElementById('salesByBrandChart').getContext('2d');
|
// Sales by Make (Pie Chart)
|
||||||
new Chart(ctx3, {
|
|
||||||
type: 'pie',
|
|
||||||
data: {
|
const ctx3 = document.getElementById('salesByBrandChart').getContext('2d');
|
||||||
labels: {{ sales_by_make_labels_json|safe }},
|
new Chart(ctx3, {
|
||||||
datasets: [{
|
type: 'pie',
|
||||||
label: translatedStrings.salesByMakeLabel,
|
data: {
|
||||||
data: {{ sales_by_make_counts_json|safe }},
|
labels: {{ sales_by_make_labels_json|safe }},
|
||||||
backgroundColor: getChartColors({{ sales_by_make_counts_json|safe }}.length),
|
datasets: [{
|
||||||
hoverOffset: 15,
|
label: translatedStrings.salesByMakeLabel,
|
||||||
}]
|
data: {{ sales_by_make_counts_json|safe }},
|
||||||
},
|
backgroundColor: getChartColors({{ sales_by_make_counts_json|safe }}.length),
|
||||||
options: {
|
hoverOffset: 15,
|
||||||
responsive: true,
|
}]
|
||||||
maintainAspectRatio: false,
|
},
|
||||||
plugins: {
|
options: {
|
||||||
legend: {
|
responsive: true,
|
||||||
position: 'right',
|
maintainAspectRatio: false,
|
||||||
labels: { font: { size: 14 } }
|
plugins: {
|
||||||
},
|
legend: {
|
||||||
tooltip: {
|
position: 'right',
|
||||||
backgroundColor: 'rgba(33, 37, 41, 0.9)',
|
labels: { font: { size: 14 } }
|
||||||
titleColor: '#fff',
|
},
|
||||||
bodyColor: '#fff',
|
tooltip: {
|
||||||
callbacks: {
|
backgroundColor: 'rgba(33, 37, 41, 0.9)',
|
||||||
label: function(context) {
|
titleColor: '#fff',
|
||||||
const label = context.label || '';
|
bodyColor: '#fff',
|
||||||
const value = context.parsed || 0;
|
callbacks: {
|
||||||
const total = context.dataset.data.reduce((a, b) => a + b, 0);
|
label: function(context) {
|
||||||
const percentage = ((value / total) * 100).toFixed(2);
|
const label = context.label || '';
|
||||||
return `${label}: ${value} ${translatedStrings.cars} (${percentage}%)`;
|
const value = context.parsed || 0;
|
||||||
|
const total = context.dataset.data.reduce((a, b) => a + b, 0);
|
||||||
|
const percentage = ((value / total) * 100).toFixed(2);
|
||||||
|
return `${label}: ${value} ${translatedStrings.cars} (${percentage}%)`;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
});
|
|
||||||
|
|
||||||
// -----------------------------------------------------------
|
// -----------------------------------------------------------
|
||||||
// 4. Sales by Model (Bar Chart)
|
// 4. Sales by Model (Bar Chart)
|
||||||
// -----------------------------------------------------------
|
// -----------------------------------------------------------
|
||||||
const salesDataByModel = JSON.parse('{{ sales_data_by_model_json|safe }}');
|
const salesDataByModel = JSON.parse('{{ sales_data_by_model_json|safe }}');
|
||||||
const canvasElementSales = document.getElementById('salesChartByModel');
|
const canvasElementSales = document.getElementById('salesChartByModel');
|
||||||
let chartInstanceSales = null;
|
let chartInstanceSales = null;
|
||||||
|
|
||||||
if (salesDataByModel.length > 0) {
|
if (salesDataByModel.length > 0) {
|
||||||
const labels = salesDataByModel.map(item => item.id_car_model__name);
|
const labels = salesDataByModel.map(item => item.id_car_model__name);
|
||||||
const counts = salesDataByModel.map(item => item.count);
|
const counts = salesDataByModel.map(item => item.count);
|
||||||
const backgroundColor = labels.map((_, index) => getChartColors(labels.length)[index]);
|
const backgroundColor = labels.map((_, index) => getChartColors(labels.length)[index]);
|
||||||
|
|
||||||
chartInstanceSales = new Chart(canvasElementSales, {
|
chartInstanceSales = new Chart(canvasElementSales, {
|
||||||
type: 'bar',
|
type: 'bar',
|
||||||
|
data: {
|
||||||
|
labels: labels,
|
||||||
|
datasets: [{
|
||||||
|
label: `${translatedStrings.salesByModelPrefix} {{ selected_make_sales }}`,
|
||||||
|
data: counts,
|
||||||
|
backgroundColor: backgroundColor,
|
||||||
|
borderColor: backgroundColor,
|
||||||
|
borderWidth: 1
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
options: {
|
||||||
|
responsive: true,
|
||||||
|
maintainAspectRatio: false,
|
||||||
|
scales: {
|
||||||
|
y: {
|
||||||
|
beginAtZero: true,
|
||||||
|
ticks: {
|
||||||
|
callback: function(value) {
|
||||||
|
if (Number.isInteger(value)) {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
plugins: {
|
||||||
|
tooltip: {
|
||||||
|
callbacks: {
|
||||||
|
label: function(context) {
|
||||||
|
let label = context.dataset.label || '';
|
||||||
|
if (label) {
|
||||||
|
label += ': ';
|
||||||
|
}
|
||||||
|
label += Math.round(context.parsed.y);
|
||||||
|
return label;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
{% endif %}
|
||||||
|
// -----------------------------------------------------------
|
||||||
|
// 5. Inventory by Make (Pie Chart)
|
||||||
|
// -----------------------------------------------------------
|
||||||
|
{% if request.is_dealer or request.is_manager or request.is_inventory %}
|
||||||
|
const ctxInventoryMake = document.getElementById('inventoryByMakeChart').getContext('2d');
|
||||||
|
new Chart(ctxInventoryMake, {
|
||||||
|
type: 'pie',
|
||||||
data: {
|
data: {
|
||||||
labels: labels,
|
labels: {{ inventory_by_make_labels_json|safe }},
|
||||||
datasets: [{
|
datasets: [{
|
||||||
label: `${translatedStrings.salesByModelPrefix} {{ selected_make_sales }}`,
|
label: translatedStrings.inventoryByMakeLabel,
|
||||||
data: counts,
|
data: {{ inventory_by_make_counts_json|safe }},
|
||||||
backgroundColor: backgroundColor,
|
backgroundColor: getChartColors({{ inventory_by_make_counts_json|safe }}.length),
|
||||||
borderColor: backgroundColor,
|
hoverOffset: 15,
|
||||||
borderWidth: 1
|
|
||||||
}]
|
}]
|
||||||
},
|
},
|
||||||
options: {
|
options: {
|
||||||
responsive: true,
|
responsive: true,
|
||||||
maintainAspectRatio: false,
|
maintainAspectRatio: false,
|
||||||
scales: {
|
|
||||||
y: {
|
|
||||||
beginAtZero: true,
|
|
||||||
ticks: {
|
|
||||||
callback: function(value) {
|
|
||||||
if (Number.isInteger(value)) {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
plugins: {
|
plugins: {
|
||||||
|
legend: {
|
||||||
|
position: 'right',
|
||||||
|
labels: { font: { size: 14 } }
|
||||||
|
},
|
||||||
tooltip: {
|
tooltip: {
|
||||||
|
backgroundColor: 'rgba(33, 37, 41, 0.9)',
|
||||||
|
titleColor: '#fff',
|
||||||
|
bodyColor: '#fff',
|
||||||
callbacks: {
|
callbacks: {
|
||||||
label: function(context) {
|
label: function(context) {
|
||||||
let label = context.dataset.label || '';
|
const label = context.label || '';
|
||||||
if (label) {
|
const value = context.parsed || 0;
|
||||||
label += ': ';
|
const total = context.dataset.data.reduce((a, b) => a + b, 0);
|
||||||
}
|
const percentage = ((value / total) * 100).toFixed(2);
|
||||||
label += Math.round(context.parsed.y);
|
return `${label}: ${value} ${translatedStrings.cars} (${percentage}%)`;
|
||||||
return label;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
|
||||||
{% endif %}
|
|
||||||
// -----------------------------------------------------------
|
|
||||||
// 5. Inventory by Make (Pie Chart)
|
|
||||||
// -----------------------------------------------------------
|
|
||||||
{% if request.is_dealer or request.is_manager or request.is_inventory %}
|
|
||||||
const ctxInventoryMake = document.getElementById('inventoryByMakeChart').getContext('2d');
|
|
||||||
new Chart(ctxInventoryMake, {
|
|
||||||
type: 'pie',
|
|
||||||
data: {
|
|
||||||
labels: {{ inventory_by_make_labels_json|safe }},
|
|
||||||
datasets: [{
|
|
||||||
label: translatedStrings.inventoryByMakeLabel,
|
|
||||||
data: {{ inventory_by_make_counts_json|safe }},
|
|
||||||
backgroundColor: getChartColors({{ inventory_by_make_counts_json|safe }}.length),
|
|
||||||
hoverOffset: 15,
|
|
||||||
}]
|
|
||||||
},
|
|
||||||
options: {
|
|
||||||
responsive: true,
|
|
||||||
maintainAspectRatio: false,
|
|
||||||
plugins: {
|
|
||||||
legend: {
|
|
||||||
position: 'right',
|
|
||||||
labels: { font: { size: 14 } }
|
|
||||||
},
|
|
||||||
tooltip: {
|
|
||||||
backgroundColor: 'rgba(33, 37, 41, 0.9)',
|
|
||||||
titleColor: '#fff',
|
|
||||||
bodyColor: '#fff',
|
|
||||||
callbacks: {
|
|
||||||
label: function(context) {
|
|
||||||
const label = context.label || '';
|
|
||||||
const value = context.parsed || 0;
|
|
||||||
const total = context.dataset.data.reduce((a, b) => a + b, 0);
|
|
||||||
const percentage = ((value / total) * 100).toFixed(2);
|
|
||||||
return `${label}: ${value} ${translatedStrings.cars} (${percentage}%)`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// -----------------------------------------------------------
|
// -----------------------------------------------------------
|
||||||
// 6. Inventory by Model (Bar Chart)
|
// 6. Inventory by Model (Bar Chart)
|
||||||
// -----------------------------------------------------------
|
// -----------------------------------------------------------
|
||||||
const inventoryDataByModel = JSON.parse('{{ inventory_data_by_model_json|safe }}');
|
const inventoryDataByModel = JSON.parse('{{ inventory_data_by_model_json|safe }}');
|
||||||
const canvasInventoryModel = document.getElementById('inventoryByModelChart');
|
const canvasInventoryModel = document.getElementById('inventoryByModelChart');
|
||||||
const messageInventoryModel = document.getElementById('inventoryByModelMessage');
|
const messageInventoryModel = document.getElementById('inventoryByModelMessage');
|
||||||
|
|
||||||
if (inventoryDataByModel.length > 0) {
|
if (inventoryDataByModel.length > 0) {
|
||||||
canvasInventoryModel.style.display = 'block';
|
canvasInventoryModel.style.display = 'block';
|
||||||
if (messageInventoryModel) {
|
if (messageInventoryModel) {
|
||||||
messageInventoryModel.style.display = 'none';
|
messageInventoryModel.style.display = 'none';
|
||||||
}
|
}
|
||||||
|
|
||||||
const labels = inventoryDataByModel.map(item => item.id_car_model__name);
|
const labels = inventoryDataByModel.map(item => item.id_car_model__name);
|
||||||
const counts = inventoryDataByModel.map(item => item.count);
|
const counts = inventoryDataByModel.map(item => item.count);
|
||||||
const backgroundColor = getChartColors(labels.length);
|
const backgroundColor = getChartColors(labels.length);
|
||||||
|
|
||||||
new Chart(canvasInventoryModel, {
|
new Chart(canvasInventoryModel, {
|
||||||
type: 'bar',
|
type: 'bar',
|
||||||
data: {
|
data: {
|
||||||
labels: labels,
|
labels: labels,
|
||||||
datasets: [{
|
datasets: [{
|
||||||
label: translatedStrings.inventoryByModelLabel,
|
label: translatedStrings.inventoryByModelLabel,
|
||||||
data: counts,
|
data: counts,
|
||||||
backgroundColor: backgroundColor,
|
backgroundColor: backgroundColor,
|
||||||
borderColor: backgroundColor,
|
borderColor: backgroundColor,
|
||||||
borderWidth: 1
|
borderWidth: 1
|
||||||
}]
|
}]
|
||||||
},
|
},
|
||||||
options: {
|
options: {
|
||||||
responsive: true,
|
responsive: true,
|
||||||
maintainAspectRatio: false,
|
maintainAspectRatio: false,
|
||||||
scales: {
|
scales: {
|
||||||
y: {
|
y: {
|
||||||
beginAtZero: true,
|
beginAtZero: true,
|
||||||
ticks: {
|
ticks: {
|
||||||
callback: function(value) {
|
callback: function(value) {
|
||||||
if (Number.isInteger(value)) {
|
if (Number.isInteger(value)) {
|
||||||
return value;
|
return value;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
},
|
plugins: {
|
||||||
plugins: {
|
tooltip: {
|
||||||
tooltip: {
|
callbacks: {
|
||||||
callbacks: {
|
label: function(context) {
|
||||||
label: function(context) {
|
let label = context.dataset.label || '';
|
||||||
let label = context.dataset.label || '';
|
if (label) {
|
||||||
if (label) {
|
label += ': ';
|
||||||
label += ': ';
|
}
|
||||||
|
label += Math.round(context.parsed.y);
|
||||||
|
return label;
|
||||||
}
|
}
|
||||||
label += Math.round(context.parsed.y);
|
|
||||||
return label;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
canvasInventoryModel.style.display = 'none';
|
||||||
|
if (messageInventoryModel) {
|
||||||
|
messageInventoryModel.style.display = 'flex';
|
||||||
}
|
}
|
||||||
});
|
|
||||||
} else {
|
|
||||||
canvasInventoryModel.style.display = 'none';
|
|
||||||
if (messageInventoryModel) {
|
|
||||||
messageInventoryModel.style.display = 'flex';
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</script>
|
</script>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|||||||
@ -64,13 +64,13 @@
|
|||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
{%if selected_make_sales%}
|
{%if selected_make_sales%}
|
||||||
<div class="card-body" style="height: 400px;">
|
<div class="card-body" style="height: 400px;">
|
||||||
<canvas id="salesChartByModel"></canvas>
|
<canvas id="salesChartByModel"></canvas>
|
||||||
</div>
|
</div>
|
||||||
{% else %}
|
{% else %}
|
||||||
<div class="card-body" style="height: 400px;">
|
<div class="card-body" style="height: 400px;">
|
||||||
<p class="ms-2">{% trans "Please Select a Make from above to see the Statistics" %}</p>
|
<p class="ms-2">{% trans "Please Select a Make from above to see the Statistics" %}</p>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -126,4 +126,4 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
|
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
|
||||||
@ -303,15 +303,15 @@
|
|||||||
<div class="card h-100 shadow-sm border-0">
|
<div class="card h-100 shadow-sm border-0">
|
||||||
<div class="card-body p-4">
|
<div class="card-body p-4">
|
||||||
<p class="text-uppercase text-muted fw-bold small mb-1">{% trans "Gross Profit" %}</p>
|
<p class="text-uppercase text-muted fw-bold small mb-1">{% trans "Gross Profit" %}</p>
|
||||||
|
|
||||||
{% if gross_profit|is_negative %}
|
{% if gross_profit|is_negative %}
|
||||||
<h4 class="fw-bolder text-danger mb-3">
|
<h4 class="fw-bolder text-danger mb-3">
|
||||||
{{ gross_profit|floatformat:'2g' }}<span class="icon-saudi_riyal"></span>
|
{{ gross_profit|floatformat:'2g' }}<span class="icon-saudi_riyal"></span>
|
||||||
</h4>
|
</h4>
|
||||||
{% else %}
|
{% else %}
|
||||||
<h4 class="fw-bolder text-success mb-3">
|
<h4 class="fw-bolder text-success mb-3">
|
||||||
{{ gross_profit|floatformat:'2g' }}<span class="icon-saudi_riyal"></span>
|
{{ gross_profit|floatformat:'2g' }}<span class="icon-saudi_riyal"></span>
|
||||||
</h4>
|
</h4>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
{% extends 'base.html' %}
|
{% extends 'base.html' %}
|
||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
{% block title %}
|
{% block title %}
|
||||||
{% trans "Sales Dashboard" %}
|
{% trans "Sales Dashboard" %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div class="main-content flex-grow-1 container-fluid mt-4 mb-3">
|
<div class="main-content flex-grow-1 container-fluid mt-4 mb-3">
|
||||||
|
|||||||
@ -35,8 +35,8 @@
|
|||||||
<p class="fs-9 mb-0">{{ log.action }}</p>
|
<p class="fs-9 mb-0">{{ log.action }}</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="border-bottom border-translucent py-4">{% endfor %}</div>
|
<div class="border-bottom border-translucent py-4">{% endfor %}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -150,31 +150,31 @@
|
|||||||
<div class="d-flex align-items-center justify-content-between mb-3">
|
<div class="d-flex align-items-center justify-content-between mb-3">
|
||||||
<h3 class="mb-0">{{ dealer.user.userplan.plan|capfirst }}</h3>
|
<h3 class="mb-0">{{ dealer.user.userplan.plan|capfirst }}</h3>
|
||||||
{% if dealer.user.userplan and not dealer.user.userplan.is_expired %}
|
{% if dealer.user.userplan and not dealer.user.userplan.is_expired %}
|
||||||
<span class="badge bg-success-subtle text-success">{{ _("Active") }}</span>
|
<span class="badge bg-success-subtle text-success">{{ _("Active") }}</span>
|
||||||
{% elif dealer.user.userplan and dealer.user.userplan.is_expired %}
|
{% elif dealer.user.userplan and dealer.user.userplan.is_expired %}
|
||||||
<span class="badge bg-danger-subtle text-danger">{{ _("Expired") }}</span>
|
<span class="badge bg-danger-subtle text-danger">{{ _("Expired") }}</span>
|
||||||
{% else %}
|
{% else %}
|
||||||
<span class="badge bg-warning-subtle text-warning">{{ _("No Active Plan") }}</span>
|
<span class="badge bg-warning-subtle text-warning">{{ _("No Active Plan") }}</span>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
<p class="fs-9 text-body-secondary">
|
<p class="fs-9 text-body-secondary">
|
||||||
{% if dealer.user.userplan and not dealer.user.userplan.is_expired %}
|
{% if dealer.user.userplan and not dealer.user.userplan.is_expired %}
|
||||||
{% trans 'Active until' %}: {{ dealer.user.userplan.expire }} <small>{% trans 'Days left' %}: {{ dealer.user.userplan.days_left }}</small>
|
{% trans 'Active until' %}: {{ dealer.user.userplan.expire }} <small>{% trans 'Days left' %}: {{ dealer.user.userplan.days_left }}</small>
|
||||||
{% else %}
|
{% else %}
|
||||||
{% trans 'Please subscribe or renew your plan to continue using our services.' %}
|
{% trans 'Please subscribe or renew your plan to continue using our services.' %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</p>
|
</p>
|
||||||
<div class="d-flex align-items-end mb-3">
|
<div class="d-flex align-items-end mb-3">
|
||||||
<h4 class="fw-bolder me-1">
|
<h4 class="fw-bolder me-1">
|
||||||
{{ dealer.user.userplan.plan.planpricing_set.first.price }} <span class="icon-saudi_riyal"></span>
|
{{ dealer.user.userplan.plan.planpricing_set.first.price }} <span class="icon-saudi_riyal"></span>
|
||||||
</h4>
|
</h4>
|
||||||
</div>
|
</div>
|
||||||
<ul class="list-unstyled mb-4">
|
<ul class="list-unstyled mb-4">
|
||||||
{% for line in dealer.user.userplan.plan.description|splitlines %}
|
{% for line in dealer.user.userplan.plan.description|splitlines %}
|
||||||
<li class="d-flex align-items-center mb-1">
|
<li class="d-flex align-items-center mb-1">
|
||||||
<span class="uil uil-check-circle text-success me-2"></span>
|
<span class="uil uil-check-circle text-success me-2"></span>
|
||||||
<span class="text-body-secondary">{{ line }}</span>
|
<span class="text-body-secondary">{{ line }}</span>
|
||||||
</li>
|
</li>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</ul>
|
</ul>
|
||||||
{% comment %} <div class="d-flex justify-content-end gap-2">
|
{% comment %} <div class="d-flex justify-content-end gap-2">
|
||||||
@ -189,16 +189,16 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
</div> {% endcomment %}
|
</div> {% endcomment %}
|
||||||
<div class="d-flex justify-content-end gap-2">
|
<div class="d-flex justify-content-end gap-2">
|
||||||
{% if not dealer.user.userplan %}
|
{% if not dealer.user.userplan %}
|
||||||
<a href="{% url 'pricing_page' request.dealer.slug %}"
|
<a href="{% url 'pricing_page' request.dealer.slug %}"
|
||||||
class="btn btn-outline-primary"><span class="fas fa-cart-plus me-2"></span>{{ _("Subscribe Now") }}</a>
|
class="btn btn-outline-primary"><span class="fas fa-cart-plus me-2"></span>{{ _("Subscribe Now") }}</a>
|
||||||
{% elif dealer.user.userplan.is_expired %}
|
{% elif dealer.user.userplan.is_expired %}
|
||||||
<a href="{% url 'pricing_page' request.dealer.slug %}"
|
<a href="{% url 'pricing_page' request.dealer.slug %}"
|
||||||
class="btn btn-outline-warning"><span class="fas fa-redo-alt me-2"></span>{{ _("Renew") }}</a>
|
class="btn btn-outline-warning"><span class="fas fa-redo-alt me-2"></span>{{ _("Renew") }}</a>
|
||||||
{% elif dealer.user.userplan.plan.name != "Enterprise" %}
|
{% elif dealer.user.userplan.plan.name != "Enterprise" %}
|
||||||
<a href="{% url 'pricing_page' request.dealer.slug %}"
|
<a href="{% url 'pricing_page' request.dealer.slug %}"
|
||||||
class="btn btn-outline-primary"><span class="fas fa-rocket me-2"></span>{{ _("Upgrade Plan") }}</a>
|
class="btn btn-outline-primary"><span class="fas fa-rocket me-2"></span>{{ _("Upgrade Plan") }}</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -220,7 +220,7 @@
|
|||||||
aria-valuemax="100"></div>
|
aria-valuemax="100"></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="d-flex justify-content-between text-body-secondary fs-9 mt-2">
|
<div class="d-flex justify-content-between text-body-secondary fs-9 mt-2">
|
||||||
<span>{{ _("Used") }}: {{ dealer.staff_count }}</span>
|
<span>{{ _("Used") }}: {{ dealer.staff_count }}</span>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -235,7 +235,7 @@
|
|||||||
aria-valuemax="100"></div>
|
aria-valuemax="100"></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="d-flex justify-content-between text-body-secondary fs-9 mt-2">
|
<div class="d-flex justify-content-between text-body-secondary fs-9 mt-2">
|
||||||
<span>{{ _("Used") }}: {{ cars_count }}</span>
|
<span>{{ _("Used") }}: {{ cars_count }}</span>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -257,22 +257,22 @@
|
|||||||
<div class="d-flex align-items-center mb-3">
|
<div class="d-flex align-items-center mb-3">
|
||||||
<span class="fas fa-location-dot me-3 text-primary"></span>
|
<span class="fas fa-location-dot me-3 text-primary"></span>
|
||||||
<div>
|
<div>
|
||||||
<h6 class="mb-0">{% trans 'Address' %}</h6>
|
<h6 class="mb-0">{% trans 'Address' %}</h6>
|
||||||
<p class="mb-0 text-body-secondary">{{ dealer.address }}</p>
|
<p class="mb-0 text-body-secondary">{{ dealer.address }}</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="d-flex align-items-center mb-3">
|
<div class="d-flex align-items-center mb-3">
|
||||||
<span class="fas fa-envelope me-3 text-info"></span>
|
<span class="fas fa-envelope me-3 text-info"></span>
|
||||||
<div>
|
<div>
|
||||||
<h6 class="mb-0">{% trans 'Email' %}</h6>
|
<h6 class="mb-0">{% trans 'Email' %}</h6>
|
||||||
<p class="mb-0 text-body-secondary">{{ dealer.user.email }}</p>
|
<p class="mb-0 text-body-secondary">{{ dealer.user.email }}</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="d-flex align-items-center">
|
<div class="d-flex align-items-center">
|
||||||
<span class="fas fa-phone me-3 text-success"></span>
|
<span class="fas fa-phone me-3 text-success"></span>
|
||||||
<div>
|
<div>
|
||||||
<h6 class="mb-0">{% trans 'Phone' %}</h6>
|
<h6 class="mb-0">{% trans 'Phone' %}</h6>
|
||||||
<p class="mb-0 text-body-secondary" dir="ltr">{{ dealer.phone_number }}</p>
|
<p class="mb-0 text-body-secondary" dir="ltr">{{ dealer.phone_number }}</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -284,11 +284,11 @@
|
|||||||
<h5 class="mb-3">{{ _("VAT Information") }}</h5>
|
<h5 class="mb-3">{{ _("VAT Information") }}</h5>
|
||||||
<form action="{% url 'dealer_vat_rate_update' request.dealer.slug %}"
|
<form action="{% url 'dealer_vat_rate_update' request.dealer.slug %}"
|
||||||
method="post">
|
method="post">
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
{{ vatform|crispy }}
|
{{ vatform|crispy }}
|
||||||
<button class="btn btn-phoenix-primary mt-3" type="submit">
|
<button class="btn btn-phoenix-primary mt-3" type="submit">
|
||||||
<i class="fa-solid fa-pen-to-square me-1"></i>{% trans 'Update VAT' %}
|
<i class="fa-solid fa-pen-to-square me-1"></i>{% trans 'Update VAT' %}
|
||||||
</button>
|
</button>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -303,21 +303,21 @@
|
|||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<h5 class="mb-4">{{ _("Makes you are selling") }}</h5>
|
<h5 class="mb-4">{{ _("Makes you are selling") }}</h5>
|
||||||
<div class="d-flex flex-wrap gap-3 mb-4">
|
<div class="d-flex flex-wrap gap-3 mb-4">
|
||||||
{% for make in car_makes %}
|
{% for make in car_makes %}
|
||||||
<div class="text-center p-2 border rounded-3">
|
<div class="text-center p-2 border rounded-3">
|
||||||
{% if make.logo %}
|
{% if make.logo %}
|
||||||
<img src="{{ make.logo.url }}"
|
<img src="{{ make.logo.url }}"
|
||||||
alt="{{ make.get_local_name }}"
|
alt="{{ make.get_local_name }}"
|
||||||
class="rounded"
|
class="rounded"
|
||||||
style="height: 48px;
|
style="height: 48px;
|
||||||
width: auto;
|
width: auto;
|
||||||
background-color:white" />
|
background-color:white" />
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<p class="fs-8 text-body-secondary mt-1 mb-0">{{ make.get_local_name }}</p>
|
<p class="fs-8 text-body-secondary mt-1 mb-0">{{ make.get_local_name }}</p>
|
||||||
</div>
|
</div>
|
||||||
{% empty %}
|
{% empty %}
|
||||||
<p class="text-body-secondary">{{ _("No car makes selected.") }}</p>
|
<p class="text-body-secondary">{{ _("No car makes selected.") }}</p>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
<a class="btn btn-phoenix-warning"
|
<a class="btn btn-phoenix-warning"
|
||||||
href="{% url 'assign_car_makes' request.dealer.slug %}"><span class="fas fa-plus me-2"></span>{{ _("Select Makes") }}</a>
|
href="{% url 'assign_car_makes' request.dealer.slug %}"><span class="fas fa-plus me-2"></span>{{ _("Select Makes") }}</a>
|
||||||
|
|||||||
@ -15,11 +15,11 @@
|
|||||||
</h3>
|
</h3>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-body p-4 p-md-5">
|
<div class="card-body p-4 p-md-5">
|
||||||
<form
|
<form
|
||||||
method="post"
|
method="post"
|
||||||
enctype="multipart/form-data"
|
enctype="multipart/form-data"
|
||||||
class="needs-validation"
|
class="needs-validation"
|
||||||
novalidate>
|
novalidate>
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
{{ form|crispy }}
|
{{ form|crispy }}
|
||||||
<hr class="my-4">
|
<hr class="my-4">
|
||||||
|
|||||||
@ -233,111 +233,111 @@
|
|||||||
</p>
|
</p>
|
||||||
</td>
|
</td>
|
||||||
<tr>{% endif %}</tr>
|
<tr>{% endif %}</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td align="left"
|
<td align="left"
|
||||||
valign="top"
|
valign="top"
|
||||||
style="font-family: Open Sans, Helvetica, Arial, sans-serif;
|
style="font-family: Open Sans, Helvetica, Arial, sans-serif;
|
||||||
padding-top: 0">
|
padding-top: 0">
|
||||||
<h3>{% trans "Account Information" %}</h3>
|
<h3>{% trans "Account Information" %}</h3>
|
||||||
<div style="color: #000000; font-size: 14px; line-height: 24px;">
|
<div style="color: #000000; font-size: 14px; line-height: 24px;">
|
||||||
<ul>
|
<ul>
|
||||||
{% for key, value in account_details.items %}<li>{{ key }}: {{ value }}</li>{% endfor %}
|
{% for key, value in account_details.items %}<li>{{ key }}: {{ value }}</li>{% endfor %}
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if more_details %}
|
{% if more_details %}
|
||||||
<tr>
|
<tr>
|
||||||
<td align="left"
|
<td align="left"
|
||||||
valign="top"
|
valign="top"
|
||||||
style="font-family: Open Sans, Helvetica, Arial, sans-serif;
|
style="font-family: Open Sans, Helvetica, Arial, sans-serif;
|
||||||
padding-top: 0">
|
padding-top: 0">
|
||||||
<h3>{% trans "Appointment Details" %}</h3>
|
<h3>{% trans "Appointment Details" %}</h3>
|
||||||
<div style="color: #000000; font-size: 14px; line-height: 24px;">
|
<div style="color: #000000; font-size: 14px; line-height: 24px;">
|
||||||
<ul>
|
<ul>
|
||||||
{% for key, value in more_details.items %}<li>{{ key }}: {{ value }}</li>{% endfor %}
|
{% for key, value in more_details.items %}<li>{{ key }}: {{ value }}</li>{% endfor %}
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if reschedule_link %}
|
{% if reschedule_link %}
|
||||||
<tr>
|
|
||||||
<td align="left"
|
|
||||||
valign="top"
|
|
||||||
style="padding: 0;
|
|
||||||
font-family: Open Sans, Helvetica, Arial, sans-serif">
|
|
||||||
<h3>{% trans 'Rescheduling' %}</h3>
|
|
||||||
<p style="margin-top: 15px !important; font-size: 14px">
|
|
||||||
{% translate 'If your plans change and you need to reschedule your appointment, you can easily do so by following this link: ' %}
|
|
||||||
<a href="{{ reschedule_link }}">{% translate 'Reschedule Appointment' %}</a>
|
|
||||||
</p>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
{% endif %}
|
|
||||||
<tr>
|
<tr>
|
||||||
<td align="left"
|
<td align="left"
|
||||||
valign="top"
|
valign="top"
|
||||||
style="padding: 0;
|
style="padding: 0;
|
||||||
font-family: Open Sans, Helvetica, Arial, sans-serif">
|
font-family: Open Sans, Helvetica, Arial, sans-serif">
|
||||||
<h3>{% trans 'Support' %}</h3>
|
<h3>{% trans 'Rescheduling' %}</h3>
|
||||||
<p style="margin-top: 15px !important; font-size: 14px">
|
<p style="margin-top: 15px !important; font-size: 14px">
|
||||||
{% blocktranslate %}
|
{% translate 'If your plans change and you need to reschedule your appointment, you can easily do so by following this link: ' %}
|
||||||
|
<a href="{{ reschedule_link }}">{% translate 'Reschedule Appointment' %}</a>
|
||||||
|
</p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{% endif %}
|
||||||
|
<tr>
|
||||||
|
<td align="left"
|
||||||
|
valign="top"
|
||||||
|
style="padding: 0;
|
||||||
|
font-family: Open Sans, Helvetica, Arial, sans-serif">
|
||||||
|
<h3>{% trans 'Support' %}</h3>
|
||||||
|
<p style="margin-top: 15px !important; font-size: 14px">
|
||||||
|
{% blocktranslate %}
|
||||||
Should you have any inquiries or require further assistance, our support team is here to
|
Should you have any inquiries or require further assistance, our support team is here to
|
||||||
help. You can reach us anytime.
|
help. You can reach us anytime.
|
||||||
{% endblocktranslate %}
|
{% endblocktranslate %}
|
||||||
</p>
|
</p>
|
||||||
<p style="margin-top: 15px !important; font-size: 14px">
|
<p style="margin-top: 15px !important; font-size: 14px">
|
||||||
{% trans "We look forward to serving you and ensuring that your experience with us is both rewarding and satisfactory." %}
|
{% trans "We look forward to serving you and ensuring that your experience with us is both rewarding and satisfactory." %}
|
||||||
</p>
|
</p>
|
||||||
<p style="margin-top: 15px !important; font-size: 14px">{% trans "Warm regards" %},</p>
|
<p style="margin-top: 15px !important; font-size: 14px">{% trans "Warm regards" %},</p>
|
||||||
<p style="margin-top: 15px !important; font-size: 14px">{% trans "The Team" %}</p>
|
<p style="margin-top: 15px !important; font-size: 14px">{% trans "The Team" %}</p>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
<!--[if (gte mso 9)|(IE)]>
|
<!--[if (gte mso 9)|(IE)]>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
<![endif]-->
|
<![endif]-->
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td align="center"
|
<td align="center"
|
||||||
height="100%"
|
height="100%"
|
||||||
valign="top"
|
valign="top"
|
||||||
width="100%"
|
width="100%"
|
||||||
bgcolor="#f6f6f6"
|
bgcolor="#f6f6f6"
|
||||||
style="padding: 40px 15px">
|
style="padding: 40px 15px">
|
||||||
<!--[if (gte mso 9)|(IE)]>
|
<!--[if (gte mso 9)|(IE)]>
|
||||||
<table align="center" border="0" cellspacing="0" cellpadding="0" width="600">
|
<table align="center" border="0" cellspacing="0" cellpadding="0" width="600">
|
||||||
<tr>
|
<tr>
|
||||||
<td align="center" valign="top" width="600">
|
<td align="center" valign="top" width="600">
|
||||||
<![endif]-->
|
<![endif]-->
|
||||||
<table align="center"
|
<table align="center"
|
||||||
border="0"
|
border="0"
|
||||||
cellpadding="0"
|
cellpadding="0"
|
||||||
cellspacing="0"
|
cellspacing="0"
|
||||||
width="100%"
|
width="100%"
|
||||||
style="max-width:600px">
|
style="max-width:600px">
|
||||||
<tr>
|
<tr>
|
||||||
<td align="center"
|
<td align="center"
|
||||||
valign="top"
|
valign="top"
|
||||||
style="padding: 0;
|
style="padding: 0;
|
||||||
font-family: Open Sans, Helvetica, Arial, sans-serif;
|
font-family: Open Sans, Helvetica, Arial, sans-serif;
|
||||||
color: #999999">
|
color: #999999">
|
||||||
© {{ current_year }} {{ company }}. {% trans "All rights reserved" %}.
|
© {{ current_year }} {{ company }}. {% trans "All rights reserved" %}.
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
<!--[if (gte mso 9)|(IE)]>
|
<!--[if (gte mso 9)|(IE)]>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
<![endif]-->
|
<![endif]-->
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@ -159,415 +159,415 @@
|
|||||||
<p class="mb-0 fw-semibold fs-9">I need help with something</p>
|
<p class="mb-0 fw-semibold fs-9">I need help with something</p>
|
||||||
<span class="fa-solid fa-paper-plane text-primary fs-9 ms-3"></span>
|
<span class="fa-solid fa-paper-plane text-primary fs-9 ms-3"></span>
|
||||||
</a><a class="mb-2 d-inline-flex align-items-center text-decoration-none text-body-emphasis bg-body-hover rounded-pill border border-primary py-2 ps-4 pe-3"
|
</a><a class="mb-2 d-inline-flex align-items-center text-decoration-none text-body-emphasis bg-body-hover rounded-pill border border-primary py-2 ps-4 pe-3"
|
||||||
href="#!">
|
href="#!">
|
||||||
<p class="mb-0 fw-semibold fs-9">I can’t reorder a product I previously ordered</p>
|
<p class="mb-0 fw-semibold fs-9">I can’t reorder a product I previously ordered</p>
|
||||||
<span class="fa-solid fa-paper-plane text-primary fs-9 ms-3"></span>
|
<span class="fa-solid fa-paper-plane text-primary fs-9 ms-3"></span>
|
||||||
</a><a class="mb-2 d-inline-flex align-items-center text-decoration-none text-body-emphasis bg-body-hover rounded-pill border border-primary py-2 ps-4 pe-3"
|
</a><a class="mb-2 d-inline-flex align-items-center text-decoration-none text-body-emphasis bg-body-hover rounded-pill border border-primary py-2 ps-4 pe-3"
|
||||||
href="#!">
|
href="#!">
|
||||||
<p class="mb-0 fw-semibold fs-9">How do I place an order?</p>
|
<p class="mb-0 fw-semibold fs-9">How do I place an order?</p>
|
||||||
<span class="fa-solid fa-paper-plane text-primary fs-9 ms-3"></span>
|
<span class="fa-solid fa-paper-plane text-primary fs-9 ms-3"></span>
|
||||||
</a><a class="false d-inline-flex align-items-center text-decoration-none text-body-emphasis bg-body-hover rounded-pill border border-primary py-2 ps-4 pe-3"
|
</a><a class="false d-inline-flex align-items-center text-decoration-none text-body-emphasis bg-body-hover rounded-pill border border-primary py-2 ps-4 pe-3"
|
||||||
href="#!">
|
href="#!">
|
||||||
<p class="mb-0 fw-semibold fs-9">My payment method not working</p>
|
<p class="mb-0 fw-semibold fs-9">My payment method not working</p>
|
||||||
<span class="fa-solid fa-paper-plane text-primary fs-9 ms-3"></span>
|
<span class="fa-solid fa-paper-plane text-primary fs-9 ms-3"></span>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="text-center mt-auto">
|
<div class="text-center mt-auto">
|
||||||
<div class="avatar avatar-3xl status-online">
|
<div class="avatar avatar-3xl status-online">
|
||||||
<img class="rounded-circle border border-3 border-light-subtle"
|
<img class="rounded-circle border border-3 border-light-subtle"
|
||||||
src="../../web_assets/img/team/30.webp"
|
src="../../web_assets/img/team/30.webp"
|
||||||
alt="" />
|
alt="" />
|
||||||
|
</div>
|
||||||
|
<h5 class="mt-2 mb-3">Eric</h5>
|
||||||
|
<p class="text-center text-body-emphasis mb-0">
|
||||||
|
Ask us anything – we’ll get back to you here or by email within 24 hours.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="card-footer d-flex align-items-center gap-2 border-top border-translucent ps-3 pe-4 py-3">
|
||||||
|
<div class="d-flex align-items-center flex-1 gap-3 border border-translucent rounded-pill px-4">
|
||||||
|
<input class="form-control outline-none border-0 flex-1 fs-9 px-0"
|
||||||
|
type="text"
|
||||||
|
placeholder="Write message" />
|
||||||
|
<label class="btn btn-link d-flex p-0 text-body-quaternary fs-9 border-0"
|
||||||
|
for="supportChatPhotos">
|
||||||
|
<span class="fa-solid fa-image"></span>
|
||||||
|
</label>
|
||||||
|
<input class="d-none" type="file" accept="image/*" id="supportChatPhotos" />
|
||||||
|
<label class="btn btn-link d-flex p-0 text-body-quaternary fs-9 border-0"
|
||||||
|
for="supportChatAttachment">
|
||||||
|
<span class="fa-solid fa-paperclip"></span>
|
||||||
|
</label>
|
||||||
|
<input class="d-none" type="file" id="supportChatAttachment" />
|
||||||
|
</div>
|
||||||
|
<button class="btn p-0 border-0 send-btn">
|
||||||
|
<span class="fa-solid fa-paper-plane fs-9"></span>
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<h5 class="mt-2 mb-3">Eric</h5>
|
|
||||||
<p class="text-center text-body-emphasis mb-0">
|
|
||||||
Ask us anything – we’ll get back to you here or by email within 24 hours.
|
|
||||||
</p>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<button class="btn btn-support-chat p-0 border border-translucent">
|
||||||
<div class="card-footer d-flex align-items-center gap-2 border-top border-translucent ps-3 pe-4 py-3">
|
<span class="fs-8 btn-text text-primary text-nowrap">Chat demo</span><span class="ping-icon-wrapper mt-n4 ms-n6 mt-sm-0 ms-sm-2 position-absolute position-sm-relative"><span class="ping-icon-bg"></span><span class="fa-solid fa-circle ping-icon"></span></span><span class="fa-solid fa-headset text-primary fs-8 d-sm-none"></span><span class="fa-solid fa-chevron-down text-primary fs-7"></span>
|
||||||
<div class="d-flex align-items-center flex-1 gap-3 border border-translucent rounded-pill px-4">
|
|
||||||
<input class="form-control outline-none border-0 flex-1 fs-9 px-0"
|
|
||||||
type="text"
|
|
||||||
placeholder="Write message" />
|
|
||||||
<label class="btn btn-link d-flex p-0 text-body-quaternary fs-9 border-0"
|
|
||||||
for="supportChatPhotos">
|
|
||||||
<span class="fa-solid fa-image"></span>
|
|
||||||
</label>
|
|
||||||
<input class="d-none" type="file" accept="image/*" id="supportChatPhotos" />
|
|
||||||
<label class="btn btn-link d-flex p-0 text-body-quaternary fs-9 border-0"
|
|
||||||
for="supportChatAttachment">
|
|
||||||
<span class="fa-solid fa-paperclip"></span>
|
|
||||||
</label>
|
|
||||||
<input class="d-none" type="file" id="supportChatAttachment" />
|
|
||||||
</div>
|
|
||||||
<button class="btn p-0 border-0 send-btn">
|
|
||||||
<span class="fa-solid fa-paper-plane fs-9"></span>
|
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</main>
|
||||||
</div>
|
|
||||||
<button class="btn btn-support-chat p-0 border border-translucent">
|
|
||||||
<span class="fs-8 btn-text text-primary text-nowrap">Chat demo</span><span class="ping-icon-wrapper mt-n4 ms-n6 mt-sm-0 ms-sm-2 position-absolute position-sm-relative"><span class="ping-icon-bg"></span><span class="fa-solid fa-circle ping-icon"></span></span><span class="fa-solid fa-headset text-primary fs-8 d-sm-none"></span><span class="fa-solid fa-chevron-down text-primary fs-7"></span>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</main>
|
|
||||||
<!-- ===============================================-->
|
<!-- ===============================================-->
|
||||||
<!-- End of Main Content-->
|
<!-- End of Main Content-->
|
||||||
<!-- ===============================================-->
|
<!-- ===============================================-->
|
||||||
<div class="offcanvas offcanvas-end settings-panel border-0"
|
<div class="offcanvas offcanvas-end settings-panel border-0"
|
||||||
id="settings-offcanvas"
|
id="settings-offcanvas"
|
||||||
tabindex="-1"
|
tabindex="-1"
|
||||||
aria-labelledby="settings-offcanvas">
|
aria-labelledby="settings-offcanvas">
|
||||||
<div class="offcanvas-header align-items-start border-bottom flex-column border-translucent">
|
<div class="offcanvas-header align-items-start border-bottom flex-column border-translucent">
|
||||||
<div class="pt-1 w-100 mb-6 d-flex justify-content-between align-items-start">
|
<div class="pt-1 w-100 mb-6 d-flex justify-content-between align-items-start">
|
||||||
<div>
|
<div>
|
||||||
<h5 class="mb-2 me-2 lh-sm">
|
<h5 class="mb-2 me-2 lh-sm">
|
||||||
<span class="fas fa-palette me-2 fs-8"></span>Theme Customizer
|
<span class="fas fa-palette me-2 fs-8"></span>Theme Customizer
|
||||||
</h5>
|
</h5>
|
||||||
<p class="mb-0 fs-9">Explore different styles according to your preferences</p>
|
<p class="mb-0 fs-9">Explore different styles according to your preferences</p>
|
||||||
|
</div>
|
||||||
|
<button class="btn p-1 fw-bolder"
|
||||||
|
type="button"
|
||||||
|
data-bs-dismiss="offcanvas"
|
||||||
|
aria-label="Close">
|
||||||
|
<span class="fas fa-times fs-8"></span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<button class="btn btn-phoenix-secondary w-100" data-theme-control="reset">
|
||||||
|
<span class="fas fa-arrows-rotate me-2 fs-10"></span>Reset to default
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<button class="btn p-1 fw-bolder"
|
<div class="offcanvas-body scrollbar px-card" id="themeController">
|
||||||
type="button"
|
<div class="setting-panel-item mt-0">
|
||||||
data-bs-dismiss="offcanvas"
|
<h5 class="setting-panel-item-title">Color Scheme</h5>
|
||||||
aria-label="Close">
|
<div class="row gx-2">
|
||||||
<span class="fas fa-times fs-8"></span>
|
<div class="col-4">
|
||||||
</button>
|
<input class="btn-check"
|
||||||
</div>
|
id="themeSwitcherLight"
|
||||||
<button class="btn btn-phoenix-secondary w-100" data-theme-control="reset">
|
name="theme-color"
|
||||||
<span class="fas fa-arrows-rotate me-2 fs-10"></span>Reset to default
|
type="radio"
|
||||||
</button>
|
value="light"
|
||||||
</div>
|
data-theme-control="phoenixTheme" />
|
||||||
<div class="offcanvas-body scrollbar px-card" id="themeController">
|
<label class="btn d-inline-block btn-navbar-style fs-9"
|
||||||
<div class="setting-panel-item mt-0">
|
for="themeSwitcherLight">
|
||||||
<h5 class="setting-panel-item-title">Color Scheme</h5>
|
<span class="mb-2 rounded d-block">
|
||||||
<div class="row gx-2">
|
<img class="img-fluid img-prototype mb-0"
|
||||||
<div class="col-4">
|
src="../../web_assets/img/generic/default-light.png"
|
||||||
<input class="btn-check"
|
alt="" />
|
||||||
id="themeSwitcherLight"
|
</span><span class="label-text">Light</span>
|
||||||
name="theme-color"
|
</label>
|
||||||
type="radio"
|
</div>
|
||||||
value="light"
|
<div class="col-4">
|
||||||
data-theme-control="phoenixTheme" />
|
<input class="btn-check"
|
||||||
<label class="btn d-inline-block btn-navbar-style fs-9"
|
id="themeSwitcherDark"
|
||||||
for="themeSwitcherLight">
|
name="theme-color"
|
||||||
<span class="mb-2 rounded d-block">
|
type="radio"
|
||||||
<img class="img-fluid img-prototype mb-0"
|
value="dark"
|
||||||
src="../../web_assets/img/generic/default-light.png"
|
data-theme-control="phoenixTheme" />
|
||||||
alt="" />
|
<label class="btn d-inline-block btn-navbar-style fs-9"
|
||||||
</span><span class="label-text">Light</span>
|
for="themeSwitcherDark">
|
||||||
</label>
|
<span class="mb-2 rounded d-block">
|
||||||
|
<img class="img-fluid img-prototype mb-0"
|
||||||
|
src="../../web_assets/img/generic/default-dark.png"
|
||||||
|
alt="" />
|
||||||
|
</span><span class="label-text">Dark</span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div class="col-4">
|
||||||
|
<input class="btn-check"
|
||||||
|
id="themeSwitcherAuto"
|
||||||
|
name="theme-color"
|
||||||
|
type="radio"
|
||||||
|
value="auto"
|
||||||
|
data-theme-control="phoenixTheme" />
|
||||||
|
<label class="btn d-inline-block btn-navbar-style fs-9"
|
||||||
|
for="themeSwitcherAuto">
|
||||||
|
<span class="mb-2 rounded d-block">
|
||||||
|
<img class="img-fluid img-prototype mb-0"
|
||||||
|
src="../../web_assets/img/generic/auto.png"
|
||||||
|
alt="" />
|
||||||
|
</span><span class="label-text">Auto</span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-4">
|
<div class="border border-translucent rounded-3 p-4 setting-panel-item bg-body-emphasis">
|
||||||
<input class="btn-check"
|
<div class="d-flex justify-content-between align-items-center">
|
||||||
id="themeSwitcherDark"
|
<h5 class="setting-panel-item-title mb-1">RTL</h5>
|
||||||
name="theme-color"
|
<div class="form-check form-switch mb-0">
|
||||||
type="radio"
|
<input class="form-check-input ms-auto"
|
||||||
value="dark"
|
type="checkbox"
|
||||||
data-theme-control="phoenixTheme" />
|
data-theme-control="phoenixIsRTL" />
|
||||||
<label class="btn d-inline-block btn-navbar-style fs-9"
|
</div>
|
||||||
for="themeSwitcherDark">
|
</div>
|
||||||
<span class="mb-2 rounded d-block">
|
<p class="mb-0 text-body-tertiary">Change text direction</p>
|
||||||
<img class="img-fluid img-prototype mb-0"
|
|
||||||
src="../../web_assets/img/generic/default-dark.png"
|
|
||||||
alt="" />
|
|
||||||
</span><span class="label-text">Dark</span>
|
|
||||||
</label>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="col-4">
|
<div class="border border-translucent rounded-3 p-4 setting-panel-item bg-body-emphasis">
|
||||||
<input class="btn-check"
|
<div class="d-flex justify-content-between align-items-center">
|
||||||
id="themeSwitcherAuto"
|
<h5 class="setting-panel-item-title mb-1">Support Chat</h5>
|
||||||
name="theme-color"
|
<div class="form-check form-switch mb-0">
|
||||||
type="radio"
|
<input class="form-check-input ms-auto"
|
||||||
value="auto"
|
type="checkbox"
|
||||||
data-theme-control="phoenixTheme" />
|
data-theme-control="phoenixSupportChat" />
|
||||||
<label class="btn d-inline-block btn-navbar-style fs-9"
|
</div>
|
||||||
for="themeSwitcherAuto">
|
</div>
|
||||||
<span class="mb-2 rounded d-block">
|
<p class="mb-0 text-body-tertiary">Toggle support chat</p>
|
||||||
<img class="img-fluid img-prototype mb-0"
|
|
||||||
src="../../web_assets/img/generic/auto.png"
|
|
||||||
alt="" />
|
|
||||||
</span><span class="label-text">Auto</span>
|
|
||||||
</label>
|
|
||||||
</div>
|
</div>
|
||||||
|
<div class="setting-panel-item">
|
||||||
|
<h5 class="setting-panel-item-title">Navigation Type</h5>
|
||||||
|
<div class="row gx-2">
|
||||||
|
<div class="col-6">
|
||||||
|
<input class="btn-check"
|
||||||
|
id="navbarPositionVertical"
|
||||||
|
name="navigation-type"
|
||||||
|
type="radio"
|
||||||
|
value="vertical"
|
||||||
|
data-theme-control="phoenixNavbarPosition"
|
||||||
|
data-page-url="../../documentation/layouts/vertical-navbar.html" />
|
||||||
|
<label class="btn d-inline-block btn-navbar-style fs-9"
|
||||||
|
for="navbarPositionVertical">
|
||||||
|
<span class="rounded d-block">
|
||||||
|
<img class="img-fluid img-prototype d-dark-none"
|
||||||
|
src="../../web_assets/img/generic/default-light.png"
|
||||||
|
alt="" />
|
||||||
|
<img class="img-fluid img-prototype d-light-none"
|
||||||
|
src="../../web_assets/img/generic/default-dark.png"
|
||||||
|
alt="" />
|
||||||
|
</span><span class="label-text">Vertical</span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div class="col-6">
|
||||||
|
<input class="btn-check"
|
||||||
|
id="navbarPositionHorizontal"
|
||||||
|
name="navigation-type"
|
||||||
|
type="radio"
|
||||||
|
value="horizontal"
|
||||||
|
data-theme-control="phoenixNavbarPosition"
|
||||||
|
data-page-url="../../documentation/layouts/horizontal-navbar.html" />
|
||||||
|
<label class="btn d-inline-block btn-navbar-style fs-9"
|
||||||
|
for="navbarPositionHorizontal">
|
||||||
|
<span class="rounded d-block">
|
||||||
|
<img class="img-fluid img-prototype d-dark-none"
|
||||||
|
src="../../web_assets/img/generic/top-default.png"
|
||||||
|
alt="" />
|
||||||
|
<img class="img-fluid img-prototype d-light-none"
|
||||||
|
src="../../web_assets/img/generic/top-default-dark.png"
|
||||||
|
alt="" />
|
||||||
|
</span><span class="label-text">Horizontal</span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div class="col-6">
|
||||||
|
<input class="btn-check"
|
||||||
|
id="navbarPositionCombo"
|
||||||
|
name="navigation-type"
|
||||||
|
type="radio"
|
||||||
|
value="combo"
|
||||||
|
data-theme-control="phoenixNavbarPosition"
|
||||||
|
data-page-url="../../documentation/layouts/combo-navbar.html" />
|
||||||
|
<label class="btn d-inline-block btn-navbar-style fs-9"
|
||||||
|
for="navbarPositionCombo">
|
||||||
|
<span class="rounded d-block">
|
||||||
|
<img class="img-fluid img-prototype d-dark-none"
|
||||||
|
src="../../web_assets/img/generic/nav-combo-light.png"
|
||||||
|
alt="" />
|
||||||
|
<img class="img-fluid img-prototype d-light-none"
|
||||||
|
src="../../web_assets/img/generic/nav-combo-dark.png"
|
||||||
|
alt="" />
|
||||||
|
</span><span class="label-text">Combo</span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div class="col-6">
|
||||||
|
<input class="btn-check"
|
||||||
|
id="navbarPositionTopDouble"
|
||||||
|
name="navigation-type"
|
||||||
|
type="radio"
|
||||||
|
value="dual-nav"
|
||||||
|
data-theme-control="phoenixNavbarPosition"
|
||||||
|
data-page-url="../../documentation/layouts/dual-nav.html" />
|
||||||
|
<label class="btn d-inline-block btn-navbar-style fs-9"
|
||||||
|
for="navbarPositionTopDouble">
|
||||||
|
<span class="rounded d-block">
|
||||||
|
<img class="img-fluid img-prototype d-dark-none"
|
||||||
|
src="../../web_assets/img/generic/dual-light.png"
|
||||||
|
alt="" />
|
||||||
|
<img class="img-fluid img-prototype d-light-none"
|
||||||
|
src="../../web_assets/img/generic/dual-dark.png"
|
||||||
|
alt="" />
|
||||||
|
</span><span class="label-text">Dual nav</span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="setting-panel-item">
|
||||||
|
<h5 class="setting-panel-item-title">Vertical Navbar Appearance</h5>
|
||||||
|
<div class="row gx-2">
|
||||||
|
<div class="col-6">
|
||||||
|
<input class="btn-check"
|
||||||
|
id="navbar-style-default"
|
||||||
|
type="radio"
|
||||||
|
name="config.name"
|
||||||
|
value="default"
|
||||||
|
data-theme-control="phoenixNavbarVerticalStyle" />
|
||||||
|
<label class="btn d-block w-100 btn-navbar-style fs-9"
|
||||||
|
for="navbar-style-default">
|
||||||
|
<img class="img-fluid img-prototype d-dark-none"
|
||||||
|
src="../../web_assets/img/generic/default-light.png"
|
||||||
|
alt="" />
|
||||||
|
<img class="img-fluid img-prototype d-light-none"
|
||||||
|
src="../../web_assets/img/generic/default-dark.png"
|
||||||
|
alt="" />
|
||||||
|
<span class="label-text d-dark-none">Default</span><span class="label-text d-light-none">Default</span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div class="col-6">
|
||||||
|
<input class="btn-check"
|
||||||
|
id="navbar-style-dark"
|
||||||
|
type="radio"
|
||||||
|
name="config.name"
|
||||||
|
value="darker"
|
||||||
|
data-theme-control="phoenixNavbarVerticalStyle" />
|
||||||
|
<label class="btn d-block w-100 btn-navbar-style fs-9"
|
||||||
|
for="navbar-style-dark">
|
||||||
|
<img class="img-fluid img-prototype d-dark-none"
|
||||||
|
src="../../web_assets/img/generic/vertical-darker.png"
|
||||||
|
alt="" />
|
||||||
|
<img class="img-fluid img-prototype d-light-none"
|
||||||
|
src="../../assets/img/generic/vertical-lighter.png"
|
||||||
|
alt="" />
|
||||||
|
<span class="label-text d-dark-none">Darker</span><span class="label-text d-light-none">Lighter</span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="setting-panel-item">
|
||||||
|
<h5 class="setting-panel-item-title">Horizontal Navbar Shape</h5>
|
||||||
|
<div class="row gx-2">
|
||||||
|
<div class="col-6">
|
||||||
|
<input class="btn-check"
|
||||||
|
id="navbarShapeDefault"
|
||||||
|
name="navbar-shape"
|
||||||
|
type="radio"
|
||||||
|
value="default"
|
||||||
|
data-theme-control="phoenixNavbarTopShape"
|
||||||
|
data-page-url="../../documentation/layouts/horizontal-navbar.html" />
|
||||||
|
<label class="btn d-inline-block btn-navbar-style fs-9"
|
||||||
|
for="navbarShapeDefault">
|
||||||
|
<span class="mb-2 rounded d-block">
|
||||||
|
<img class="img-fluid img-prototype d-dark-none mb-0"
|
||||||
|
src="../../assets/img/generic/top-default.png"
|
||||||
|
alt="" />
|
||||||
|
<img class="img-fluid img-prototype d-light-none mb-0"
|
||||||
|
src="../../assets/img/generic/top-default-dark.png"
|
||||||
|
alt="" />
|
||||||
|
</span><span class="label-text">Default</span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div class="col-6">
|
||||||
|
<input class="btn-check"
|
||||||
|
id="navbarShapeSlim"
|
||||||
|
name="navbar-shape"
|
||||||
|
type="radio"
|
||||||
|
value="slim"
|
||||||
|
data-theme-control="phoenixNavbarTopShape"
|
||||||
|
data-page-url="../../documentation/layouts/horizontal-navbar.html#horizontal-navbar-slim" />
|
||||||
|
<label class="btn d-inline-block btn-navbar-style fs-9"
|
||||||
|
for="navbarShapeSlim">
|
||||||
|
<span class="mb-2 rounded d-block">
|
||||||
|
<img class="img-fluid img-prototype d-dark-none mb-0"
|
||||||
|
src="../../assets/img/generic/top-slim.png"
|
||||||
|
alt="" />
|
||||||
|
<img class="img-fluid img-prototype d-light-none mb-0"
|
||||||
|
src="../../assets/img/generic/top-slim-dark.png"
|
||||||
|
alt="" />
|
||||||
|
</span><span class="label-text">Slim</span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="setting-panel-item">
|
||||||
|
<h5 class="setting-panel-item-title">Horizontal Navbar Appearance</h5>
|
||||||
|
<div class="row gx-2">
|
||||||
|
<div class="col-6">
|
||||||
|
<input class="btn-check"
|
||||||
|
id="navbarTopDefault"
|
||||||
|
name="navbar-top-style"
|
||||||
|
type="radio"
|
||||||
|
value="default"
|
||||||
|
data-theme-control="phoenixNavbarTopStyle" />
|
||||||
|
<label class="btn d-inline-block btn-navbar-style fs-9"
|
||||||
|
for="navbarTopDefault">
|
||||||
|
<span class="mb-2 rounded d-block">
|
||||||
|
<img class="img-fluid img-prototype d-dark-none mb-0"
|
||||||
|
src="../../assets/img/generic/top-default.png"
|
||||||
|
alt="" />
|
||||||
|
<img class="img-fluid img-prototype d-light-none mb-0"
|
||||||
|
src="../../assets/img/generic/top-style-darker.png"
|
||||||
|
alt="" />
|
||||||
|
</span><span class="label-text">Default</span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div class="col-6">
|
||||||
|
<input class="btn-check"
|
||||||
|
id="navbarTopDarker"
|
||||||
|
name="navbar-top-style"
|
||||||
|
type="radio"
|
||||||
|
value="darker"
|
||||||
|
data-theme-control="phoenixNavbarTopStyle" />
|
||||||
|
<label class="btn d-inline-block btn-navbar-style fs-9"
|
||||||
|
for="navbarTopDarker">
|
||||||
|
<span class="mb-2 rounded d-block">
|
||||||
|
<img class="img-fluid img-prototype d-dark-none mb-0"
|
||||||
|
src="../../assets/img/generic/navbar-top-style-light.png"
|
||||||
|
alt="" />
|
||||||
|
<img class="img-fluid img-prototype d-light-none mb-0"
|
||||||
|
src="../../assets/img/generic/top-style-lighter.png"
|
||||||
|
alt="" />
|
||||||
|
</span><span class="label-text d-dark-none">Darker</span><span class="label-text d-light-none">Lighter</span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<a class="bun btn-primary d-grid mb-3 text-white mt-5 btn btn-primary"
|
||||||
|
href="https://themes.getbootstrap.com/product/phoenix-admin-dashboard-webapp-template/"
|
||||||
|
target="_blank">Purchase template</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="border border-translucent rounded-3 p-4 setting-panel-item bg-body-emphasis">
|
<a class="card setting-toggle"
|
||||||
<div class="d-flex justify-content-between align-items-center">
|
href="#settings-offcanvas"
|
||||||
<h5 class="setting-panel-item-title mb-1">RTL</h5>
|
data-bs-toggle="offcanvas">
|
||||||
<div class="form-check form-switch mb-0">
|
<div class="card-body d-flex align-items-center px-2 py-1">
|
||||||
<input class="form-check-input ms-auto"
|
<div class="position-relative rounded-start"
|
||||||
type="checkbox"
|
style="height:34px;
|
||||||
data-theme-control="phoenixIsRTL" />
|
width:28px">
|
||||||
|
<div class="settings-popover">
|
||||||
|
<span class="ripple"><span class="fa-spin position-absolute all-0 d-flex flex-center"><span class="icon-spin position-absolute all-0 d-flex flex-center">
|
||||||
|
<svg width="20"
|
||||||
|
height="20"
|
||||||
|
viewBox="0 0 20 20"
|
||||||
|
fill="#ffffff"
|
||||||
|
xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M19.7369 12.3941L19.1989 12.1065C18.4459 11.7041 18.0843 10.8487 18.0843 9.99495C18.0843 9.14118 18.4459 8.28582 19.1989 7.88336L19.7369 7.59581C19.9474 7.47484 20.0316 7.23291 19.9474 7.03131C19.4842 5.57973 18.6843 4.28943 17.6738 3.20075C17.5053 3.03946 17.2527 2.99914 17.0422 3.12011L16.393 3.46714C15.6883 3.84379 14.8377 3.74529 14.1476 3.3427C14.0988 3.31422 14.0496 3.28621 14.0002 3.25868C13.2568 2.84453 12.7055 2.10629 12.7055 1.25525V0.70081C12.7055 0.499202 12.5371 0.297594 12.2845 0.257272C10.7266 -0.105622 9.16879 -0.0653007 7.69516 0.257272C7.44254 0.297594 7.31623 0.499202 7.31623 0.70081V1.23474C7.31623 2.09575 6.74999 2.8362 5.99824 3.25599C5.95774 3.27861 5.91747 3.30159 5.87744 3.32493C5.15643 3.74527 4.26453 3.85902 3.53534 3.45302L2.93743 3.12011C2.72691 2.99914 2.47429 3.03946 2.30587 3.20075C1.29538 4.28943 0.495411 5.57973 0.0322686 7.03131C-0.051939 7.23291 0.0322686 7.47484 0.242788 7.59581L0.784376 7.8853C1.54166 8.29007 1.92694 9.13627 1.92694 9.99495C1.92694 10.8536 1.54166 11.6998 0.784375 12.1046L0.242788 12.3941C0.0322686 12.515 -0.051939 12.757 0.0322686 12.9586C0.495411 14.4102 1.29538 15.7005 2.30587 16.7891C2.47429 16.9504 2.72691 16.9907 2.93743 16.8698L3.58669 16.5227C4.29133 16.1461 5.14131 16.2457 5.8331 16.6455C5.88713 16.6767 5.94159 16.7074 5.99648 16.7375C6.75162 17.1511 7.31623 17.8941 7.31623 18.7552V19.2891C7.31623 19.4425 7.41373 19.5959 7.55309 19.696C7.64066 19.7589 7.74815 19.7843 7.85406 19.8046C9.35884 20.0925 10.8609 20.0456 12.2845 19.7729C12.5371 19.6923 12.7055 19.4907 12.7055 19.2891V18.7346C12.7055 17.8836 13.2568 17.1454 14.0002 16.7312C14.0496 16.7037 14.0988 16.6757 14.1476 16.6472C14.8377 16.2446 15.6883 16.1461 16.393 16.5227L17.0422 16.8698C17.2527 16.9907 17.5053 16.9504 17.6738 16.7891C18.7264 15.7005 19.4842 14.4102 19.9895 12.9586C20.0316 12.757 19.9474 12.515 19.7369 12.3941ZM10.0109 13.2005C8.1162 13.2005 6.64257 11.7893 6.64257 9.97478C6.64257 8.20063 8.1162 6.74905 10.0109 6.74905C11.8634 6.74905 13.3792 8.20063 13.3792 9.97478C13.3792 11.7893 11.8634 13.2005 10.0109 13.2005Z" fill="#2A7BE4">
|
||||||
|
</path>
|
||||||
|
</svg>
|
||||||
|
</span></span></span>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<small class="text-uppercase text-body-tertiary fw-bold py-2 pe-2 ps-1 rounded-end">customize</small>
|
||||||
</div>
|
</div>
|
||||||
<p class="mb-0 text-body-tertiary">Change text direction</p>
|
</a>
|
||||||
</div>
|
|
||||||
<div class="border border-translucent rounded-3 p-4 setting-panel-item bg-body-emphasis">
|
|
||||||
<div class="d-flex justify-content-between align-items-center">
|
|
||||||
<h5 class="setting-panel-item-title mb-1">Support Chat</h5>
|
|
||||||
<div class="form-check form-switch mb-0">
|
|
||||||
<input class="form-check-input ms-auto"
|
|
||||||
type="checkbox"
|
|
||||||
data-theme-control="phoenixSupportChat" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<p class="mb-0 text-body-tertiary">Toggle support chat</p>
|
|
||||||
</div>
|
|
||||||
<div class="setting-panel-item">
|
|
||||||
<h5 class="setting-panel-item-title">Navigation Type</h5>
|
|
||||||
<div class="row gx-2">
|
|
||||||
<div class="col-6">
|
|
||||||
<input class="btn-check"
|
|
||||||
id="navbarPositionVertical"
|
|
||||||
name="navigation-type"
|
|
||||||
type="radio"
|
|
||||||
value="vertical"
|
|
||||||
data-theme-control="phoenixNavbarPosition"
|
|
||||||
data-page-url="../../documentation/layouts/vertical-navbar.html" />
|
|
||||||
<label class="btn d-inline-block btn-navbar-style fs-9"
|
|
||||||
for="navbarPositionVertical">
|
|
||||||
<span class="rounded d-block">
|
|
||||||
<img class="img-fluid img-prototype d-dark-none"
|
|
||||||
src="../../web_assets/img/generic/default-light.png"
|
|
||||||
alt="" />
|
|
||||||
<img class="img-fluid img-prototype d-light-none"
|
|
||||||
src="../../web_assets/img/generic/default-dark.png"
|
|
||||||
alt="" />
|
|
||||||
</span><span class="label-text">Vertical</span>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
<div class="col-6">
|
|
||||||
<input class="btn-check"
|
|
||||||
id="navbarPositionHorizontal"
|
|
||||||
name="navigation-type"
|
|
||||||
type="radio"
|
|
||||||
value="horizontal"
|
|
||||||
data-theme-control="phoenixNavbarPosition"
|
|
||||||
data-page-url="../../documentation/layouts/horizontal-navbar.html" />
|
|
||||||
<label class="btn d-inline-block btn-navbar-style fs-9"
|
|
||||||
for="navbarPositionHorizontal">
|
|
||||||
<span class="rounded d-block">
|
|
||||||
<img class="img-fluid img-prototype d-dark-none"
|
|
||||||
src="../../web_assets/img/generic/top-default.png"
|
|
||||||
alt="" />
|
|
||||||
<img class="img-fluid img-prototype d-light-none"
|
|
||||||
src="../../web_assets/img/generic/top-default-dark.png"
|
|
||||||
alt="" />
|
|
||||||
</span><span class="label-text">Horizontal</span>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
<div class="col-6">
|
|
||||||
<input class="btn-check"
|
|
||||||
id="navbarPositionCombo"
|
|
||||||
name="navigation-type"
|
|
||||||
type="radio"
|
|
||||||
value="combo"
|
|
||||||
data-theme-control="phoenixNavbarPosition"
|
|
||||||
data-page-url="../../documentation/layouts/combo-navbar.html" />
|
|
||||||
<label class="btn d-inline-block btn-navbar-style fs-9"
|
|
||||||
for="navbarPositionCombo">
|
|
||||||
<span class="rounded d-block">
|
|
||||||
<img class="img-fluid img-prototype d-dark-none"
|
|
||||||
src="../../web_assets/img/generic/nav-combo-light.png"
|
|
||||||
alt="" />
|
|
||||||
<img class="img-fluid img-prototype d-light-none"
|
|
||||||
src="../../web_assets/img/generic/nav-combo-dark.png"
|
|
||||||
alt="" />
|
|
||||||
</span><span class="label-text">Combo</span>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
<div class="col-6">
|
|
||||||
<input class="btn-check"
|
|
||||||
id="navbarPositionTopDouble"
|
|
||||||
name="navigation-type"
|
|
||||||
type="radio"
|
|
||||||
value="dual-nav"
|
|
||||||
data-theme-control="phoenixNavbarPosition"
|
|
||||||
data-page-url="../../documentation/layouts/dual-nav.html" />
|
|
||||||
<label class="btn d-inline-block btn-navbar-style fs-9"
|
|
||||||
for="navbarPositionTopDouble">
|
|
||||||
<span class="rounded d-block">
|
|
||||||
<img class="img-fluid img-prototype d-dark-none"
|
|
||||||
src="../../web_assets/img/generic/dual-light.png"
|
|
||||||
alt="" />
|
|
||||||
<img class="img-fluid img-prototype d-light-none"
|
|
||||||
src="../../web_assets/img/generic/dual-dark.png"
|
|
||||||
alt="" />
|
|
||||||
</span><span class="label-text">Dual nav</span>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="setting-panel-item">
|
|
||||||
<h5 class="setting-panel-item-title">Vertical Navbar Appearance</h5>
|
|
||||||
<div class="row gx-2">
|
|
||||||
<div class="col-6">
|
|
||||||
<input class="btn-check"
|
|
||||||
id="navbar-style-default"
|
|
||||||
type="radio"
|
|
||||||
name="config.name"
|
|
||||||
value="default"
|
|
||||||
data-theme-control="phoenixNavbarVerticalStyle" />
|
|
||||||
<label class="btn d-block w-100 btn-navbar-style fs-9"
|
|
||||||
for="navbar-style-default">
|
|
||||||
<img class="img-fluid img-prototype d-dark-none"
|
|
||||||
src="../../web_assets/img/generic/default-light.png"
|
|
||||||
alt="" />
|
|
||||||
<img class="img-fluid img-prototype d-light-none"
|
|
||||||
src="../../web_assets/img/generic/default-dark.png"
|
|
||||||
alt="" />
|
|
||||||
<span class="label-text d-dark-none">Default</span><span class="label-text d-light-none">Default</span>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
<div class="col-6">
|
|
||||||
<input class="btn-check"
|
|
||||||
id="navbar-style-dark"
|
|
||||||
type="radio"
|
|
||||||
name="config.name"
|
|
||||||
value="darker"
|
|
||||||
data-theme-control="phoenixNavbarVerticalStyle" />
|
|
||||||
<label class="btn d-block w-100 btn-navbar-style fs-9"
|
|
||||||
for="navbar-style-dark">
|
|
||||||
<img class="img-fluid img-prototype d-dark-none"
|
|
||||||
src="../../web_assets/img/generic/vertical-darker.png"
|
|
||||||
alt="" />
|
|
||||||
<img class="img-fluid img-prototype d-light-none"
|
|
||||||
src="../../assets/img/generic/vertical-lighter.png"
|
|
||||||
alt="" />
|
|
||||||
<span class="label-text d-dark-none">Darker</span><span class="label-text d-light-none">Lighter</span>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="setting-panel-item">
|
|
||||||
<h5 class="setting-panel-item-title">Horizontal Navbar Shape</h5>
|
|
||||||
<div class="row gx-2">
|
|
||||||
<div class="col-6">
|
|
||||||
<input class="btn-check"
|
|
||||||
id="navbarShapeDefault"
|
|
||||||
name="navbar-shape"
|
|
||||||
type="radio"
|
|
||||||
value="default"
|
|
||||||
data-theme-control="phoenixNavbarTopShape"
|
|
||||||
data-page-url="../../documentation/layouts/horizontal-navbar.html" />
|
|
||||||
<label class="btn d-inline-block btn-navbar-style fs-9"
|
|
||||||
for="navbarShapeDefault">
|
|
||||||
<span class="mb-2 rounded d-block">
|
|
||||||
<img class="img-fluid img-prototype d-dark-none mb-0"
|
|
||||||
src="../../assets/img/generic/top-default.png"
|
|
||||||
alt="" />
|
|
||||||
<img class="img-fluid img-prototype d-light-none mb-0"
|
|
||||||
src="../../assets/img/generic/top-default-dark.png"
|
|
||||||
alt="" />
|
|
||||||
</span><span class="label-text">Default</span>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
<div class="col-6">
|
|
||||||
<input class="btn-check"
|
|
||||||
id="navbarShapeSlim"
|
|
||||||
name="navbar-shape"
|
|
||||||
type="radio"
|
|
||||||
value="slim"
|
|
||||||
data-theme-control="phoenixNavbarTopShape"
|
|
||||||
data-page-url="../../documentation/layouts/horizontal-navbar.html#horizontal-navbar-slim" />
|
|
||||||
<label class="btn d-inline-block btn-navbar-style fs-9"
|
|
||||||
for="navbarShapeSlim">
|
|
||||||
<span class="mb-2 rounded d-block">
|
|
||||||
<img class="img-fluid img-prototype d-dark-none mb-0"
|
|
||||||
src="../../assets/img/generic/top-slim.png"
|
|
||||||
alt="" />
|
|
||||||
<img class="img-fluid img-prototype d-light-none mb-0"
|
|
||||||
src="../../assets/img/generic/top-slim-dark.png"
|
|
||||||
alt="" />
|
|
||||||
</span><span class="label-text">Slim</span>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="setting-panel-item">
|
|
||||||
<h5 class="setting-panel-item-title">Horizontal Navbar Appearance</h5>
|
|
||||||
<div class="row gx-2">
|
|
||||||
<div class="col-6">
|
|
||||||
<input class="btn-check"
|
|
||||||
id="navbarTopDefault"
|
|
||||||
name="navbar-top-style"
|
|
||||||
type="radio"
|
|
||||||
value="default"
|
|
||||||
data-theme-control="phoenixNavbarTopStyle" />
|
|
||||||
<label class="btn d-inline-block btn-navbar-style fs-9"
|
|
||||||
for="navbarTopDefault">
|
|
||||||
<span class="mb-2 rounded d-block">
|
|
||||||
<img class="img-fluid img-prototype d-dark-none mb-0"
|
|
||||||
src="../../assets/img/generic/top-default.png"
|
|
||||||
alt="" />
|
|
||||||
<img class="img-fluid img-prototype d-light-none mb-0"
|
|
||||||
src="../../assets/img/generic/top-style-darker.png"
|
|
||||||
alt="" />
|
|
||||||
</span><span class="label-text">Default</span>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
<div class="col-6">
|
|
||||||
<input class="btn-check"
|
|
||||||
id="navbarTopDarker"
|
|
||||||
name="navbar-top-style"
|
|
||||||
type="radio"
|
|
||||||
value="darker"
|
|
||||||
data-theme-control="phoenixNavbarTopStyle" />
|
|
||||||
<label class="btn d-inline-block btn-navbar-style fs-9"
|
|
||||||
for="navbarTopDarker">
|
|
||||||
<span class="mb-2 rounded d-block">
|
|
||||||
<img class="img-fluid img-prototype d-dark-none mb-0"
|
|
||||||
src="../../assets/img/generic/navbar-top-style-light.png"
|
|
||||||
alt="" />
|
|
||||||
<img class="img-fluid img-prototype d-light-none mb-0"
|
|
||||||
src="../../assets/img/generic/top-style-lighter.png"
|
|
||||||
alt="" />
|
|
||||||
</span><span class="label-text d-dark-none">Darker</span><span class="label-text d-light-none">Lighter</span>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<a class="bun btn-primary d-grid mb-3 text-white mt-5 btn btn-primary"
|
|
||||||
href="https://themes.getbootstrap.com/product/phoenix-admin-dashboard-webapp-template/"
|
|
||||||
target="_blank">Purchase template</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<a class="card setting-toggle"
|
|
||||||
href="#settings-offcanvas"
|
|
||||||
data-bs-toggle="offcanvas">
|
|
||||||
<div class="card-body d-flex align-items-center px-2 py-1">
|
|
||||||
<div class="position-relative rounded-start"
|
|
||||||
style="height:34px;
|
|
||||||
width:28px">
|
|
||||||
<div class="settings-popover">
|
|
||||||
<span class="ripple"><span class="fa-spin position-absolute all-0 d-flex flex-center"><span class="icon-spin position-absolute all-0 d-flex flex-center">
|
|
||||||
<svg width="20"
|
|
||||||
height="20"
|
|
||||||
viewBox="0 0 20 20"
|
|
||||||
fill="#ffffff"
|
|
||||||
xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<path d="M19.7369 12.3941L19.1989 12.1065C18.4459 11.7041 18.0843 10.8487 18.0843 9.99495C18.0843 9.14118 18.4459 8.28582 19.1989 7.88336L19.7369 7.59581C19.9474 7.47484 20.0316 7.23291 19.9474 7.03131C19.4842 5.57973 18.6843 4.28943 17.6738 3.20075C17.5053 3.03946 17.2527 2.99914 17.0422 3.12011L16.393 3.46714C15.6883 3.84379 14.8377 3.74529 14.1476 3.3427C14.0988 3.31422 14.0496 3.28621 14.0002 3.25868C13.2568 2.84453 12.7055 2.10629 12.7055 1.25525V0.70081C12.7055 0.499202 12.5371 0.297594 12.2845 0.257272C10.7266 -0.105622 9.16879 -0.0653007 7.69516 0.257272C7.44254 0.297594 7.31623 0.499202 7.31623 0.70081V1.23474C7.31623 2.09575 6.74999 2.8362 5.99824 3.25599C5.95774 3.27861 5.91747 3.30159 5.87744 3.32493C5.15643 3.74527 4.26453 3.85902 3.53534 3.45302L2.93743 3.12011C2.72691 2.99914 2.47429 3.03946 2.30587 3.20075C1.29538 4.28943 0.495411 5.57973 0.0322686 7.03131C-0.051939 7.23291 0.0322686 7.47484 0.242788 7.59581L0.784376 7.8853C1.54166 8.29007 1.92694 9.13627 1.92694 9.99495C1.92694 10.8536 1.54166 11.6998 0.784375 12.1046L0.242788 12.3941C0.0322686 12.515 -0.051939 12.757 0.0322686 12.9586C0.495411 14.4102 1.29538 15.7005 2.30587 16.7891C2.47429 16.9504 2.72691 16.9907 2.93743 16.8698L3.58669 16.5227C4.29133 16.1461 5.14131 16.2457 5.8331 16.6455C5.88713 16.6767 5.94159 16.7074 5.99648 16.7375C6.75162 17.1511 7.31623 17.8941 7.31623 18.7552V19.2891C7.31623 19.4425 7.41373 19.5959 7.55309 19.696C7.64066 19.7589 7.74815 19.7843 7.85406 19.8046C9.35884 20.0925 10.8609 20.0456 12.2845 19.7729C12.5371 19.6923 12.7055 19.4907 12.7055 19.2891V18.7346C12.7055 17.8836 13.2568 17.1454 14.0002 16.7312C14.0496 16.7037 14.0988 16.6757 14.1476 16.6472C14.8377 16.2446 15.6883 16.1461 16.393 16.5227L17.0422 16.8698C17.2527 16.9907 17.5053 16.9504 17.6738 16.7891C18.7264 15.7005 19.4842 14.4102 19.9895 12.9586C20.0316 12.757 19.9474 12.515 19.7369 12.3941ZM10.0109 13.2005C8.1162 13.2005 6.64257 11.7893 6.64257 9.97478C6.64257 8.20063 8.1162 6.74905 10.0109 6.74905C11.8634 6.74905 13.3792 8.20063 13.3792 9.97478C13.3792 11.7893 11.8634 13.2005 10.0109 13.2005Z" fill="#2A7BE4">
|
|
||||||
</path>
|
|
||||||
</svg>
|
|
||||||
</span></span></span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<small class="text-uppercase text-body-tertiary fw-bold py-2 pe-2 ps-1 rounded-end">customize</small>
|
|
||||||
</div>
|
|
||||||
</a>
|
|
||||||
<!-- ===============================================-->
|
<!-- ===============================================-->
|
||||||
<!-- JavaScripts-->
|
<!-- JavaScripts-->
|
||||||
<!-- ===============================================-->
|
<!-- ===============================================-->
|
||||||
<script src="../../vendors/popper/popper.min.js"></script>
|
<script src="../../vendors/popper/popper.min.js"></script>
|
||||||
<script src="../../vendors/bootstrap/bootstrap.min.js"></script>
|
<script src="../../vendors/bootstrap/bootstrap.min.js"></script>
|
||||||
<script src="../../vendors/anchorjs/anchor.min.js"></script>
|
<script src="../../vendors/anchorjs/anchor.min.js"></script>
|
||||||
<script src="../../vendors/is/is.min.js"></script>
|
<script src="../../vendors/is/is.min.js"></script>
|
||||||
<script src="../../vendors/fontawesome/all.min.js"></script>
|
<script src="../../vendors/fontawesome/all.min.js"></script>
|
||||||
<script src="../../vendors/lodash/lodash.min.js"></script>
|
<script src="../../vendors/lodash/lodash.min.js"></script>
|
||||||
<script src="../../vendors/list.js/list.min.js"></script>
|
<script src="../../vendors/list.js/list.min.js"></script>
|
||||||
<script src="../../vendors/feather-icons/feather.min.js"></script>
|
<script src="../../vendors/feather-icons/feather.min.js"></script>
|
||||||
<script src="../../vendors/dayjs/dayjs.min.js"></script>
|
<script src="../../vendors/dayjs/dayjs.min.js"></script>
|
||||||
<script src="../../assets/js/phoenix.js"></script>
|
<script src="../../assets/js/phoenix.js"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@ -155,415 +155,415 @@
|
|||||||
<p class="mb-0 fw-semibold fs-9">I need help with something</p>
|
<p class="mb-0 fw-semibold fs-9">I need help with something</p>
|
||||||
<span class="fa-solid fa-paper-plane text-primary fs-9 ms-3"></span>
|
<span class="fa-solid fa-paper-plane text-primary fs-9 ms-3"></span>
|
||||||
</a><a class="mb-2 d-inline-flex align-items-center text-decoration-none text-body-emphasis bg-body-hover rounded-pill border border-primary py-2 ps-4 pe-3"
|
</a><a class="mb-2 d-inline-flex align-items-center text-decoration-none text-body-emphasis bg-body-hover rounded-pill border border-primary py-2 ps-4 pe-3"
|
||||||
href="#!">
|
href="#!">
|
||||||
<p class="mb-0 fw-semibold fs-9">I can’t reorder a product I previously ordered</p>
|
<p class="mb-0 fw-semibold fs-9">I can’t reorder a product I previously ordered</p>
|
||||||
<span class="fa-solid fa-paper-plane text-primary fs-9 ms-3"></span>
|
<span class="fa-solid fa-paper-plane text-primary fs-9 ms-3"></span>
|
||||||
</a><a class="mb-2 d-inline-flex align-items-center text-decoration-none text-body-emphasis bg-body-hover rounded-pill border border-primary py-2 ps-4 pe-3"
|
</a><a class="mb-2 d-inline-flex align-items-center text-decoration-none text-body-emphasis bg-body-hover rounded-pill border border-primary py-2 ps-4 pe-3"
|
||||||
href="#!">
|
href="#!">
|
||||||
<p class="mb-0 fw-semibold fs-9">How do I place an order?</p>
|
<p class="mb-0 fw-semibold fs-9">How do I place an order?</p>
|
||||||
<span class="fa-solid fa-paper-plane text-primary fs-9 ms-3"></span>
|
<span class="fa-solid fa-paper-plane text-primary fs-9 ms-3"></span>
|
||||||
</a><a class="false d-inline-flex align-items-center text-decoration-none text-body-emphasis bg-body-hover rounded-pill border border-primary py-2 ps-4 pe-3"
|
</a><a class="false d-inline-flex align-items-center text-decoration-none text-body-emphasis bg-body-hover rounded-pill border border-primary py-2 ps-4 pe-3"
|
||||||
href="#!">
|
href="#!">
|
||||||
<p class="mb-0 fw-semibold fs-9">My payment method not working</p>
|
<p class="mb-0 fw-semibold fs-9">My payment method not working</p>
|
||||||
<span class="fa-solid fa-paper-plane text-primary fs-9 ms-3"></span>
|
<span class="fa-solid fa-paper-plane text-primary fs-9 ms-3"></span>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="text-center mt-auto">
|
<div class="text-center mt-auto">
|
||||||
<div class="avatar avatar-3xl status-online">
|
<div class="avatar avatar-3xl status-online">
|
||||||
<img class="rounded-circle border border-3 border-light-subtle"
|
<img class="rounded-circle border border-3 border-light-subtle"
|
||||||
src="../../web_assets/img/team/30.webp"
|
src="../../web_assets/img/team/30.webp"
|
||||||
alt="" />
|
alt="" />
|
||||||
|
</div>
|
||||||
|
<h5 class="mt-2 mb-3">Eric</h5>
|
||||||
|
<p class="text-center text-body-emphasis mb-0">
|
||||||
|
Ask us anything – we’ll get back to you here or by email within 24 hours.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="card-footer d-flex align-items-center gap-2 border-top border-translucent ps-3 pe-4 py-3">
|
||||||
|
<div class="d-flex align-items-center flex-1 gap-3 border border-translucent rounded-pill px-4">
|
||||||
|
<input class="form-control outline-none border-0 flex-1 fs-9 px-0"
|
||||||
|
type="text"
|
||||||
|
placeholder="Write message" />
|
||||||
|
<label class="btn btn-link d-flex p-0 text-body-quaternary fs-9 border-0"
|
||||||
|
for="supportChatPhotos">
|
||||||
|
<span class="fa-solid fa-image"></span>
|
||||||
|
</label>
|
||||||
|
<input class="d-none" type="file" accept="image/*" id="supportChatPhotos" />
|
||||||
|
<label class="btn btn-link d-flex p-0 text-body-quaternary fs-9 border-0"
|
||||||
|
for="supportChatAttachment">
|
||||||
|
<span class="fa-solid fa-paperclip"></span>
|
||||||
|
</label>
|
||||||
|
<input class="d-none" type="file" id="supportChatAttachment" />
|
||||||
|
</div>
|
||||||
|
<button class="btn p-0 border-0 send-btn">
|
||||||
|
<span class="fa-solid fa-paper-plane fs-9"></span>
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<h5 class="mt-2 mb-3">Eric</h5>
|
|
||||||
<p class="text-center text-body-emphasis mb-0">
|
|
||||||
Ask us anything – we’ll get back to you here or by email within 24 hours.
|
|
||||||
</p>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<button class="btn btn-support-chat p-0 border border-translucent">
|
||||||
<div class="card-footer d-flex align-items-center gap-2 border-top border-translucent ps-3 pe-4 py-3">
|
<span class="fs-8 btn-text text-primary text-nowrap">Chat demo</span><span class="ping-icon-wrapper mt-n4 ms-n6 mt-sm-0 ms-sm-2 position-absolute position-sm-relative"><span class="ping-icon-bg"></span><span class="fa-solid fa-circle ping-icon"></span></span><span class="fa-solid fa-headset text-primary fs-8 d-sm-none"></span><span class="fa-solid fa-chevron-down text-primary fs-7"></span>
|
||||||
<div class="d-flex align-items-center flex-1 gap-3 border border-translucent rounded-pill px-4">
|
|
||||||
<input class="form-control outline-none border-0 flex-1 fs-9 px-0"
|
|
||||||
type="text"
|
|
||||||
placeholder="Write message" />
|
|
||||||
<label class="btn btn-link d-flex p-0 text-body-quaternary fs-9 border-0"
|
|
||||||
for="supportChatPhotos">
|
|
||||||
<span class="fa-solid fa-image"></span>
|
|
||||||
</label>
|
|
||||||
<input class="d-none" type="file" accept="image/*" id="supportChatPhotos" />
|
|
||||||
<label class="btn btn-link d-flex p-0 text-body-quaternary fs-9 border-0"
|
|
||||||
for="supportChatAttachment">
|
|
||||||
<span class="fa-solid fa-paperclip"></span>
|
|
||||||
</label>
|
|
||||||
<input class="d-none" type="file" id="supportChatAttachment" />
|
|
||||||
</div>
|
|
||||||
<button class="btn p-0 border-0 send-btn">
|
|
||||||
<span class="fa-solid fa-paper-plane fs-9"></span>
|
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</main>
|
||||||
</div>
|
|
||||||
<button class="btn btn-support-chat p-0 border border-translucent">
|
|
||||||
<span class="fs-8 btn-text text-primary text-nowrap">Chat demo</span><span class="ping-icon-wrapper mt-n4 ms-n6 mt-sm-0 ms-sm-2 position-absolute position-sm-relative"><span class="ping-icon-bg"></span><span class="fa-solid fa-circle ping-icon"></span></span><span class="fa-solid fa-headset text-primary fs-8 d-sm-none"></span><span class="fa-solid fa-chevron-down text-primary fs-7"></span>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</main>
|
|
||||||
<!-- ===============================================-->
|
<!-- ===============================================-->
|
||||||
<!-- End of Main Content-->
|
<!-- End of Main Content-->
|
||||||
<!-- ===============================================-->
|
<!-- ===============================================-->
|
||||||
<div class="offcanvas offcanvas-end settings-panel border-0"
|
<div class="offcanvas offcanvas-end settings-panel border-0"
|
||||||
id="settings-offcanvas"
|
id="settings-offcanvas"
|
||||||
tabindex="-1"
|
tabindex="-1"
|
||||||
aria-labelledby="settings-offcanvas">
|
aria-labelledby="settings-offcanvas">
|
||||||
<div class="offcanvas-header align-items-start border-bottom flex-column border-translucent">
|
<div class="offcanvas-header align-items-start border-bottom flex-column border-translucent">
|
||||||
<div class="pt-1 w-100 mb-6 d-flex justify-content-between align-items-start">
|
<div class="pt-1 w-100 mb-6 d-flex justify-content-between align-items-start">
|
||||||
<div>
|
<div>
|
||||||
<h5 class="mb-2 me-2 lh-sm">
|
<h5 class="mb-2 me-2 lh-sm">
|
||||||
<span class="fas fa-palette me-2 fs-8"></span>Theme Customizer
|
<span class="fas fa-palette me-2 fs-8"></span>Theme Customizer
|
||||||
</h5>
|
</h5>
|
||||||
<p class="mb-0 fs-9">Explore different styles according to your preferences</p>
|
<p class="mb-0 fs-9">Explore different styles according to your preferences</p>
|
||||||
|
</div>
|
||||||
|
<button class="btn p-1 fw-bolder"
|
||||||
|
type="button"
|
||||||
|
data-bs-dismiss="offcanvas"
|
||||||
|
aria-label="Close">
|
||||||
|
<span class="fas fa-times fs-8"></span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<button class="btn btn-phoenix-secondary w-100" data-theme-control="reset">
|
||||||
|
<span class="fas fa-arrows-rotate me-2 fs-10"></span>Reset to default
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<button class="btn p-1 fw-bolder"
|
<div class="offcanvas-body scrollbar px-card" id="themeController">
|
||||||
type="button"
|
<div class="setting-panel-item mt-0">
|
||||||
data-bs-dismiss="offcanvas"
|
<h5 class="setting-panel-item-title">Color Scheme</h5>
|
||||||
aria-label="Close">
|
<div class="row gx-2">
|
||||||
<span class="fas fa-times fs-8"></span>
|
<div class="col-4">
|
||||||
</button>
|
<input class="btn-check"
|
||||||
</div>
|
id="themeSwitcherLight"
|
||||||
<button class="btn btn-phoenix-secondary w-100" data-theme-control="reset">
|
name="theme-color"
|
||||||
<span class="fas fa-arrows-rotate me-2 fs-10"></span>Reset to default
|
type="radio"
|
||||||
</button>
|
value="light"
|
||||||
</div>
|
data-theme-control="phoenixTheme" />
|
||||||
<div class="offcanvas-body scrollbar px-card" id="themeController">
|
<label class="btn d-inline-block btn-navbar-style fs-9"
|
||||||
<div class="setting-panel-item mt-0">
|
for="themeSwitcherLight">
|
||||||
<h5 class="setting-panel-item-title">Color Scheme</h5>
|
<span class="mb-2 rounded d-block">
|
||||||
<div class="row gx-2">
|
<img class="img-fluid img-prototype mb-0"
|
||||||
<div class="col-4">
|
src="../../web_assets/img/generic/default-light.png"
|
||||||
<input class="btn-check"
|
alt="" />
|
||||||
id="themeSwitcherLight"
|
</span><span class="label-text">Light</span>
|
||||||
name="theme-color"
|
</label>
|
||||||
type="radio"
|
</div>
|
||||||
value="light"
|
<div class="col-4">
|
||||||
data-theme-control="phoenixTheme" />
|
<input class="btn-check"
|
||||||
<label class="btn d-inline-block btn-navbar-style fs-9"
|
id="themeSwitcherDark"
|
||||||
for="themeSwitcherLight">
|
name="theme-color"
|
||||||
<span class="mb-2 rounded d-block">
|
type="radio"
|
||||||
<img class="img-fluid img-prototype mb-0"
|
value="dark"
|
||||||
src="../../web_assets/img/generic/default-light.png"
|
data-theme-control="phoenixTheme" />
|
||||||
alt="" />
|
<label class="btn d-inline-block btn-navbar-style fs-9"
|
||||||
</span><span class="label-text">Light</span>
|
for="themeSwitcherDark">
|
||||||
</label>
|
<span class="mb-2 rounded d-block">
|
||||||
|
<img class="img-fluid img-prototype mb-0"
|
||||||
|
src="../../web_assets/img/generic/default-dark.png"
|
||||||
|
alt="" />
|
||||||
|
</span><span class="label-text">Dark</span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div class="col-4">
|
||||||
|
<input class="btn-check"
|
||||||
|
id="themeSwitcherAuto"
|
||||||
|
name="theme-color"
|
||||||
|
type="radio"
|
||||||
|
value="auto"
|
||||||
|
data-theme-control="phoenixTheme" />
|
||||||
|
<label class="btn d-inline-block btn-navbar-style fs-9"
|
||||||
|
for="themeSwitcherAuto">
|
||||||
|
<span class="mb-2 rounded d-block">
|
||||||
|
<img class="img-fluid img-prototype mb-0"
|
||||||
|
src="../../web_assets/img/generic/auto.png"
|
||||||
|
alt="" />
|
||||||
|
</span><span class="label-text">Auto</span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-4">
|
<div class="border border-translucent rounded-3 p-4 setting-panel-item bg-body-emphasis">
|
||||||
<input class="btn-check"
|
<div class="d-flex justify-content-between align-items-center">
|
||||||
id="themeSwitcherDark"
|
<h5 class="setting-panel-item-title mb-1">RTL</h5>
|
||||||
name="theme-color"
|
<div class="form-check form-switch mb-0">
|
||||||
type="radio"
|
<input class="form-check-input ms-auto"
|
||||||
value="dark"
|
type="checkbox"
|
||||||
data-theme-control="phoenixTheme" />
|
data-theme-control="phoenixIsRTL" />
|
||||||
<label class="btn d-inline-block btn-navbar-style fs-9"
|
</div>
|
||||||
for="themeSwitcherDark">
|
</div>
|
||||||
<span class="mb-2 rounded d-block">
|
<p class="mb-0 text-body-tertiary">Change text direction</p>
|
||||||
<img class="img-fluid img-prototype mb-0"
|
|
||||||
src="../../web_assets/img/generic/default-dark.png"
|
|
||||||
alt="" />
|
|
||||||
</span><span class="label-text">Dark</span>
|
|
||||||
</label>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="col-4">
|
<div class="border border-translucent rounded-3 p-4 setting-panel-item bg-body-emphasis">
|
||||||
<input class="btn-check"
|
<div class="d-flex justify-content-between align-items-center">
|
||||||
id="themeSwitcherAuto"
|
<h5 class="setting-panel-item-title mb-1">Support Chat</h5>
|
||||||
name="theme-color"
|
<div class="form-check form-switch mb-0">
|
||||||
type="radio"
|
<input class="form-check-input ms-auto"
|
||||||
value="auto"
|
type="checkbox"
|
||||||
data-theme-control="phoenixTheme" />
|
data-theme-control="phoenixSupportChat" />
|
||||||
<label class="btn d-inline-block btn-navbar-style fs-9"
|
</div>
|
||||||
for="themeSwitcherAuto">
|
</div>
|
||||||
<span class="mb-2 rounded d-block">
|
<p class="mb-0 text-body-tertiary">Toggle support chat</p>
|
||||||
<img class="img-fluid img-prototype mb-0"
|
|
||||||
src="../../web_assets/img/generic/auto.png"
|
|
||||||
alt="" />
|
|
||||||
</span><span class="label-text">Auto</span>
|
|
||||||
</label>
|
|
||||||
</div>
|
</div>
|
||||||
|
<div class="setting-panel-item">
|
||||||
|
<h5 class="setting-panel-item-title">Navigation Type</h5>
|
||||||
|
<div class="row gx-2">
|
||||||
|
<div class="col-6">
|
||||||
|
<input class="btn-check"
|
||||||
|
id="navbarPositionVertical"
|
||||||
|
name="navigation-type"
|
||||||
|
type="radio"
|
||||||
|
value="vertical"
|
||||||
|
data-theme-control="phoenixNavbarPosition"
|
||||||
|
data-page-url="../../documentation/layouts/vertical-navbar.html" />
|
||||||
|
<label class="btn d-inline-block btn-navbar-style fs-9"
|
||||||
|
for="navbarPositionVertical">
|
||||||
|
<span class="rounded d-block">
|
||||||
|
<img class="img-fluid img-prototype d-dark-none"
|
||||||
|
src="../../web_assets/img/generic/default-light.png"
|
||||||
|
alt="" />
|
||||||
|
<img class="img-fluid img-prototype d-light-none"
|
||||||
|
src="../../assets/img/generic/default-dark.png"
|
||||||
|
alt="" />
|
||||||
|
</span><span class="label-text">Vertical</span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div class="col-6">
|
||||||
|
<input class="btn-check"
|
||||||
|
id="navbarPositionHorizontal"
|
||||||
|
name="navigation-type"
|
||||||
|
type="radio"
|
||||||
|
value="horizontal"
|
||||||
|
data-theme-control="phoenixNavbarPosition"
|
||||||
|
data-page-url="../../documentation/layouts/horizontal-navbar.html" />
|
||||||
|
<label class="btn d-inline-block btn-navbar-style fs-9"
|
||||||
|
for="navbarPositionHorizontal">
|
||||||
|
<span class="rounded d-block">
|
||||||
|
<img class="img-fluid img-prototype d-dark-none"
|
||||||
|
src="../../assets/img/generic/top-default.png"
|
||||||
|
alt="" />
|
||||||
|
<img class="img-fluid img-prototype d-light-none"
|
||||||
|
src="../../assets/img/generic/top-default-dark.png"
|
||||||
|
alt="" />
|
||||||
|
</span><span class="label-text">Horizontal</span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div class="col-6">
|
||||||
|
<input class="btn-check"
|
||||||
|
id="navbarPositionCombo"
|
||||||
|
name="navigation-type"
|
||||||
|
type="radio"
|
||||||
|
value="combo"
|
||||||
|
data-theme-control="phoenixNavbarPosition"
|
||||||
|
data-page-url="../../documentation/layouts/combo-navbar.html" />
|
||||||
|
<label class="btn d-inline-block btn-navbar-style fs-9"
|
||||||
|
for="navbarPositionCombo">
|
||||||
|
<span class="rounded d-block">
|
||||||
|
<img class="img-fluid img-prototype d-dark-none"
|
||||||
|
src="../../assets/img/generic/nav-combo-light.png"
|
||||||
|
alt="" />
|
||||||
|
<img class="img-fluid img-prototype d-light-none"
|
||||||
|
src="../../assets/img/generic/nav-combo-dark.png"
|
||||||
|
alt="" />
|
||||||
|
</span><span class="label-text">Combo</span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div class="col-6">
|
||||||
|
<input class="btn-check"
|
||||||
|
id="navbarPositionTopDouble"
|
||||||
|
name="navigation-type"
|
||||||
|
type="radio"
|
||||||
|
value="dual-nav"
|
||||||
|
data-theme-control="phoenixNavbarPosition"
|
||||||
|
data-page-url="../../documentation/layouts/dual-nav.html" />
|
||||||
|
<label class="btn d-inline-block btn-navbar-style fs-9"
|
||||||
|
for="navbarPositionTopDouble">
|
||||||
|
<span class="rounded d-block">
|
||||||
|
<img class="img-fluid img-prototype d-dark-none"
|
||||||
|
src="../../assets/img/generic/dual-light.png"
|
||||||
|
alt="" />
|
||||||
|
<img class="img-fluid img-prototype d-light-none"
|
||||||
|
src="../../assets/img/generic/dual-dark.png"
|
||||||
|
alt="" />
|
||||||
|
</span><span class="label-text">Dual nav</span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="setting-panel-item">
|
||||||
|
<h5 class="setting-panel-item-title">Vertical Navbar Appearance</h5>
|
||||||
|
<div class="row gx-2">
|
||||||
|
<div class="col-6">
|
||||||
|
<input class="btn-check"
|
||||||
|
id="navbar-style-default"
|
||||||
|
type="radio"
|
||||||
|
name="config.name"
|
||||||
|
value="default"
|
||||||
|
data-theme-control="phoenixNavbarVerticalStyle" />
|
||||||
|
<label class="btn d-block w-100 btn-navbar-style fs-9"
|
||||||
|
for="navbar-style-default">
|
||||||
|
<img class="img-fluid img-prototype d-dark-none"
|
||||||
|
src="../../assets/img/generic/default-light.png"
|
||||||
|
alt="" />
|
||||||
|
<img class="img-fluid img-prototype d-light-none"
|
||||||
|
src="../../assets/img/generic/default-dark.png"
|
||||||
|
alt="" />
|
||||||
|
<span class="label-text d-dark-none">Default</span><span class="label-text d-light-none">Default</span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div class="col-6">
|
||||||
|
<input class="btn-check"
|
||||||
|
id="navbar-style-dark"
|
||||||
|
type="radio"
|
||||||
|
name="config.name"
|
||||||
|
value="darker"
|
||||||
|
data-theme-control="phoenixNavbarVerticalStyle" />
|
||||||
|
<label class="btn d-block w-100 btn-navbar-style fs-9"
|
||||||
|
for="navbar-style-dark">
|
||||||
|
<img class="img-fluid img-prototype d-dark-none"
|
||||||
|
src="../../assets/img/generic/vertical-darker.png"
|
||||||
|
alt="" />
|
||||||
|
<img class="img-fluid img-prototype d-light-none"
|
||||||
|
src="../../assets/img/generic/vertical-lighter.png"
|
||||||
|
alt="" />
|
||||||
|
<span class="label-text d-dark-none">Darker</span><span class="label-text d-light-none">Lighter</span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="setting-panel-item">
|
||||||
|
<h5 class="setting-panel-item-title">Horizontal Navbar Shape</h5>
|
||||||
|
<div class="row gx-2">
|
||||||
|
<div class="col-6">
|
||||||
|
<input class="btn-check"
|
||||||
|
id="navbarShapeDefault"
|
||||||
|
name="navbar-shape"
|
||||||
|
type="radio"
|
||||||
|
value="default"
|
||||||
|
data-theme-control="phoenixNavbarTopShape"
|
||||||
|
data-page-url="../../documentation/layouts/horizontal-navbar.html" />
|
||||||
|
<label class="btn d-inline-block btn-navbar-style fs-9"
|
||||||
|
for="navbarShapeDefault">
|
||||||
|
<span class="mb-2 rounded d-block">
|
||||||
|
<img class="img-fluid img-prototype d-dark-none mb-0"
|
||||||
|
src="../../assets/img/generic/top-default.png"
|
||||||
|
alt="" />
|
||||||
|
<img class="img-fluid img-prototype d-light-none mb-0"
|
||||||
|
src="../../assets/img/generic/top-default-dark.png"
|
||||||
|
alt="" />
|
||||||
|
</span><span class="label-text">Default</span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div class="col-6">
|
||||||
|
<input class="btn-check"
|
||||||
|
id="navbarShapeSlim"
|
||||||
|
name="navbar-shape"
|
||||||
|
type="radio"
|
||||||
|
value="slim"
|
||||||
|
data-theme-control="phoenixNavbarTopShape"
|
||||||
|
data-page-url="../../documentation/layouts/horizontal-navbar.html#horizontal-navbar-slim" />
|
||||||
|
<label class="btn d-inline-block btn-navbar-style fs-9"
|
||||||
|
for="navbarShapeSlim">
|
||||||
|
<span class="mb-2 rounded d-block">
|
||||||
|
<img class="img-fluid img-prototype d-dark-none mb-0"
|
||||||
|
src="../../assets/img/generic/top-slim.png"
|
||||||
|
alt="" />
|
||||||
|
<img class="img-fluid img-prototype d-light-none mb-0"
|
||||||
|
src="../../assets/img/generic/top-slim-dark.png"
|
||||||
|
alt="" />
|
||||||
|
</span><span class="label-text">Slim</span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="setting-panel-item">
|
||||||
|
<h5 class="setting-panel-item-title">Horizontal Navbar Appearance</h5>
|
||||||
|
<div class="row gx-2">
|
||||||
|
<div class="col-6">
|
||||||
|
<input class="btn-check"
|
||||||
|
id="navbarTopDefault"
|
||||||
|
name="navbar-top-style"
|
||||||
|
type="radio"
|
||||||
|
value="default"
|
||||||
|
data-theme-control="phoenixNavbarTopStyle" />
|
||||||
|
<label class="btn d-inline-block btn-navbar-style fs-9"
|
||||||
|
for="navbarTopDefault">
|
||||||
|
<span class="mb-2 rounded d-block">
|
||||||
|
<img class="img-fluid img-prototype d-dark-none mb-0"
|
||||||
|
src="../../assets/img/generic/top-default.png"
|
||||||
|
alt="" />
|
||||||
|
<img class="img-fluid img-prototype d-light-none mb-0"
|
||||||
|
src="../../assets/img/generic/top-style-darker.png"
|
||||||
|
alt="" />
|
||||||
|
</span><span class="label-text">Default</span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div class="col-6">
|
||||||
|
<input class="btn-check"
|
||||||
|
id="navbarTopDarker"
|
||||||
|
name="navbar-top-style"
|
||||||
|
type="radio"
|
||||||
|
value="darker"
|
||||||
|
data-theme-control="phoenixNavbarTopStyle" />
|
||||||
|
<label class="btn d-inline-block btn-navbar-style fs-9"
|
||||||
|
for="navbarTopDarker">
|
||||||
|
<span class="mb-2 rounded d-block">
|
||||||
|
<img class="img-fluid img-prototype d-dark-none mb-0"
|
||||||
|
src="../../assets/img/generic/navbar-top-style-light.png"
|
||||||
|
alt="" />
|
||||||
|
<img class="img-fluid img-prototype d-light-none mb-0"
|
||||||
|
src="../../assets/img/generic/top-style-lighter.png"
|
||||||
|
alt="" />
|
||||||
|
</span><span class="label-text d-dark-none">Darker</span><span class="label-text d-light-none">Lighter</span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<a class="bun btn-primary d-grid mb-3 text-white mt-5 btn btn-primary"
|
||||||
|
href="https://themes.getbootstrap.com/product/phoenix-admin-dashboard-webapp-template/"
|
||||||
|
target="_blank">Purchase template</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="border border-translucent rounded-3 p-4 setting-panel-item bg-body-emphasis">
|
<a class="card setting-toggle"
|
||||||
<div class="d-flex justify-content-between align-items-center">
|
href="#settings-offcanvas"
|
||||||
<h5 class="setting-panel-item-title mb-1">RTL</h5>
|
data-bs-toggle="offcanvas">
|
||||||
<div class="form-check form-switch mb-0">
|
<div class="card-body d-flex align-items-center px-2 py-1">
|
||||||
<input class="form-check-input ms-auto"
|
<div class="position-relative rounded-start"
|
||||||
type="checkbox"
|
style="height:34px;
|
||||||
data-theme-control="phoenixIsRTL" />
|
width:28px">
|
||||||
|
<div class="settings-popover">
|
||||||
|
<span class="ripple"><span class="fa-spin position-absolute all-0 d-flex flex-center"><span class="icon-spin position-absolute all-0 d-flex flex-center">
|
||||||
|
<svg width="20"
|
||||||
|
height="20"
|
||||||
|
viewBox="0 0 20 20"
|
||||||
|
fill="#ffffff"
|
||||||
|
xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M19.7369 12.3941L19.1989 12.1065C18.4459 11.7041 18.0843 10.8487 18.0843 9.99495C18.0843 9.14118 18.4459 8.28582 19.1989 7.88336L19.7369 7.59581C19.9474 7.47484 20.0316 7.23291 19.9474 7.03131C19.4842 5.57973 18.6843 4.28943 17.6738 3.20075C17.5053 3.03946 17.2527 2.99914 17.0422 3.12011L16.393 3.46714C15.6883 3.84379 14.8377 3.74529 14.1476 3.3427C14.0988 3.31422 14.0496 3.28621 14.0002 3.25868C13.2568 2.84453 12.7055 2.10629 12.7055 1.25525V0.70081C12.7055 0.499202 12.5371 0.297594 12.2845 0.257272C10.7266 -0.105622 9.16879 -0.0653007 7.69516 0.257272C7.44254 0.297594 7.31623 0.499202 7.31623 0.70081V1.23474C7.31623 2.09575 6.74999 2.8362 5.99824 3.25599C5.95774 3.27861 5.91747 3.30159 5.87744 3.32493C5.15643 3.74527 4.26453 3.85902 3.53534 3.45302L2.93743 3.12011C2.72691 2.99914 2.47429 3.03946 2.30587 3.20075C1.29538 4.28943 0.495411 5.57973 0.0322686 7.03131C-0.051939 7.23291 0.0322686 7.47484 0.242788 7.59581L0.784376 7.8853C1.54166 8.29007 1.92694 9.13627 1.92694 9.99495C1.92694 10.8536 1.54166 11.6998 0.784375 12.1046L0.242788 12.3941C0.0322686 12.515 -0.051939 12.757 0.0322686 12.9586C0.495411 14.4102 1.29538 15.7005 2.30587 16.7891C2.47429 16.9504 2.72691 16.9907 2.93743 16.8698L3.58669 16.5227C4.29133 16.1461 5.14131 16.2457 5.8331 16.6455C5.88713 16.6767 5.94159 16.7074 5.99648 16.7375C6.75162 17.1511 7.31623 17.8941 7.31623 18.7552V19.2891C7.31623 19.4425 7.41373 19.5959 7.55309 19.696C7.64066 19.7589 7.74815 19.7843 7.85406 19.8046C9.35884 20.0925 10.8609 20.0456 12.2845 19.7729C12.5371 19.6923 12.7055 19.4907 12.7055 19.2891V18.7346C12.7055 17.8836 13.2568 17.1454 14.0002 16.7312C14.0496 16.7037 14.0988 16.6757 14.1476 16.6472C14.8377 16.2446 15.6883 16.1461 16.393 16.5227L17.0422 16.8698C17.2527 16.9907 17.5053 16.9504 17.6738 16.7891C18.7264 15.7005 19.4842 14.4102 19.9895 12.9586C20.0316 12.757 19.9474 12.515 19.7369 12.3941ZM10.0109 13.2005C8.1162 13.2005 6.64257 11.7893 6.64257 9.97478C6.64257 8.20063 8.1162 6.74905 10.0109 6.74905C11.8634 6.74905 13.3792 8.20063 13.3792 9.97478C13.3792 11.7893 11.8634 13.2005 10.0109 13.2005Z" fill="#2A7BE4">
|
||||||
|
</path>
|
||||||
|
</svg>
|
||||||
|
</span></span></span>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<small class="text-uppercase text-body-tertiary fw-bold py-2 pe-2 ps-1 rounded-end">customize</small>
|
||||||
</div>
|
</div>
|
||||||
<p class="mb-0 text-body-tertiary">Change text direction</p>
|
</a>
|
||||||
</div>
|
|
||||||
<div class="border border-translucent rounded-3 p-4 setting-panel-item bg-body-emphasis">
|
|
||||||
<div class="d-flex justify-content-between align-items-center">
|
|
||||||
<h5 class="setting-panel-item-title mb-1">Support Chat</h5>
|
|
||||||
<div class="form-check form-switch mb-0">
|
|
||||||
<input class="form-check-input ms-auto"
|
|
||||||
type="checkbox"
|
|
||||||
data-theme-control="phoenixSupportChat" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<p class="mb-0 text-body-tertiary">Toggle support chat</p>
|
|
||||||
</div>
|
|
||||||
<div class="setting-panel-item">
|
|
||||||
<h5 class="setting-panel-item-title">Navigation Type</h5>
|
|
||||||
<div class="row gx-2">
|
|
||||||
<div class="col-6">
|
|
||||||
<input class="btn-check"
|
|
||||||
id="navbarPositionVertical"
|
|
||||||
name="navigation-type"
|
|
||||||
type="radio"
|
|
||||||
value="vertical"
|
|
||||||
data-theme-control="phoenixNavbarPosition"
|
|
||||||
data-page-url="../../documentation/layouts/vertical-navbar.html" />
|
|
||||||
<label class="btn d-inline-block btn-navbar-style fs-9"
|
|
||||||
for="navbarPositionVertical">
|
|
||||||
<span class="rounded d-block">
|
|
||||||
<img class="img-fluid img-prototype d-dark-none"
|
|
||||||
src="../../web_assets/img/generic/default-light.png"
|
|
||||||
alt="" />
|
|
||||||
<img class="img-fluid img-prototype d-light-none"
|
|
||||||
src="../../assets/img/generic/default-dark.png"
|
|
||||||
alt="" />
|
|
||||||
</span><span class="label-text">Vertical</span>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
<div class="col-6">
|
|
||||||
<input class="btn-check"
|
|
||||||
id="navbarPositionHorizontal"
|
|
||||||
name="navigation-type"
|
|
||||||
type="radio"
|
|
||||||
value="horizontal"
|
|
||||||
data-theme-control="phoenixNavbarPosition"
|
|
||||||
data-page-url="../../documentation/layouts/horizontal-navbar.html" />
|
|
||||||
<label class="btn d-inline-block btn-navbar-style fs-9"
|
|
||||||
for="navbarPositionHorizontal">
|
|
||||||
<span class="rounded d-block">
|
|
||||||
<img class="img-fluid img-prototype d-dark-none"
|
|
||||||
src="../../assets/img/generic/top-default.png"
|
|
||||||
alt="" />
|
|
||||||
<img class="img-fluid img-prototype d-light-none"
|
|
||||||
src="../../assets/img/generic/top-default-dark.png"
|
|
||||||
alt="" />
|
|
||||||
</span><span class="label-text">Horizontal</span>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
<div class="col-6">
|
|
||||||
<input class="btn-check"
|
|
||||||
id="navbarPositionCombo"
|
|
||||||
name="navigation-type"
|
|
||||||
type="radio"
|
|
||||||
value="combo"
|
|
||||||
data-theme-control="phoenixNavbarPosition"
|
|
||||||
data-page-url="../../documentation/layouts/combo-navbar.html" />
|
|
||||||
<label class="btn d-inline-block btn-navbar-style fs-9"
|
|
||||||
for="navbarPositionCombo">
|
|
||||||
<span class="rounded d-block">
|
|
||||||
<img class="img-fluid img-prototype d-dark-none"
|
|
||||||
src="../../assets/img/generic/nav-combo-light.png"
|
|
||||||
alt="" />
|
|
||||||
<img class="img-fluid img-prototype d-light-none"
|
|
||||||
src="../../assets/img/generic/nav-combo-dark.png"
|
|
||||||
alt="" />
|
|
||||||
</span><span class="label-text">Combo</span>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
<div class="col-6">
|
|
||||||
<input class="btn-check"
|
|
||||||
id="navbarPositionTopDouble"
|
|
||||||
name="navigation-type"
|
|
||||||
type="radio"
|
|
||||||
value="dual-nav"
|
|
||||||
data-theme-control="phoenixNavbarPosition"
|
|
||||||
data-page-url="../../documentation/layouts/dual-nav.html" />
|
|
||||||
<label class="btn d-inline-block btn-navbar-style fs-9"
|
|
||||||
for="navbarPositionTopDouble">
|
|
||||||
<span class="rounded d-block">
|
|
||||||
<img class="img-fluid img-prototype d-dark-none"
|
|
||||||
src="../../assets/img/generic/dual-light.png"
|
|
||||||
alt="" />
|
|
||||||
<img class="img-fluid img-prototype d-light-none"
|
|
||||||
src="../../assets/img/generic/dual-dark.png"
|
|
||||||
alt="" />
|
|
||||||
</span><span class="label-text">Dual nav</span>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="setting-panel-item">
|
|
||||||
<h5 class="setting-panel-item-title">Vertical Navbar Appearance</h5>
|
|
||||||
<div class="row gx-2">
|
|
||||||
<div class="col-6">
|
|
||||||
<input class="btn-check"
|
|
||||||
id="navbar-style-default"
|
|
||||||
type="radio"
|
|
||||||
name="config.name"
|
|
||||||
value="default"
|
|
||||||
data-theme-control="phoenixNavbarVerticalStyle" />
|
|
||||||
<label class="btn d-block w-100 btn-navbar-style fs-9"
|
|
||||||
for="navbar-style-default">
|
|
||||||
<img class="img-fluid img-prototype d-dark-none"
|
|
||||||
src="../../assets/img/generic/default-light.png"
|
|
||||||
alt="" />
|
|
||||||
<img class="img-fluid img-prototype d-light-none"
|
|
||||||
src="../../assets/img/generic/default-dark.png"
|
|
||||||
alt="" />
|
|
||||||
<span class="label-text d-dark-none">Default</span><span class="label-text d-light-none">Default</span>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
<div class="col-6">
|
|
||||||
<input class="btn-check"
|
|
||||||
id="navbar-style-dark"
|
|
||||||
type="radio"
|
|
||||||
name="config.name"
|
|
||||||
value="darker"
|
|
||||||
data-theme-control="phoenixNavbarVerticalStyle" />
|
|
||||||
<label class="btn d-block w-100 btn-navbar-style fs-9"
|
|
||||||
for="navbar-style-dark">
|
|
||||||
<img class="img-fluid img-prototype d-dark-none"
|
|
||||||
src="../../assets/img/generic/vertical-darker.png"
|
|
||||||
alt="" />
|
|
||||||
<img class="img-fluid img-prototype d-light-none"
|
|
||||||
src="../../assets/img/generic/vertical-lighter.png"
|
|
||||||
alt="" />
|
|
||||||
<span class="label-text d-dark-none">Darker</span><span class="label-text d-light-none">Lighter</span>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="setting-panel-item">
|
|
||||||
<h5 class="setting-panel-item-title">Horizontal Navbar Shape</h5>
|
|
||||||
<div class="row gx-2">
|
|
||||||
<div class="col-6">
|
|
||||||
<input class="btn-check"
|
|
||||||
id="navbarShapeDefault"
|
|
||||||
name="navbar-shape"
|
|
||||||
type="radio"
|
|
||||||
value="default"
|
|
||||||
data-theme-control="phoenixNavbarTopShape"
|
|
||||||
data-page-url="../../documentation/layouts/horizontal-navbar.html" />
|
|
||||||
<label class="btn d-inline-block btn-navbar-style fs-9"
|
|
||||||
for="navbarShapeDefault">
|
|
||||||
<span class="mb-2 rounded d-block">
|
|
||||||
<img class="img-fluid img-prototype d-dark-none mb-0"
|
|
||||||
src="../../assets/img/generic/top-default.png"
|
|
||||||
alt="" />
|
|
||||||
<img class="img-fluid img-prototype d-light-none mb-0"
|
|
||||||
src="../../assets/img/generic/top-default-dark.png"
|
|
||||||
alt="" />
|
|
||||||
</span><span class="label-text">Default</span>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
<div class="col-6">
|
|
||||||
<input class="btn-check"
|
|
||||||
id="navbarShapeSlim"
|
|
||||||
name="navbar-shape"
|
|
||||||
type="radio"
|
|
||||||
value="slim"
|
|
||||||
data-theme-control="phoenixNavbarTopShape"
|
|
||||||
data-page-url="../../documentation/layouts/horizontal-navbar.html#horizontal-navbar-slim" />
|
|
||||||
<label class="btn d-inline-block btn-navbar-style fs-9"
|
|
||||||
for="navbarShapeSlim">
|
|
||||||
<span class="mb-2 rounded d-block">
|
|
||||||
<img class="img-fluid img-prototype d-dark-none mb-0"
|
|
||||||
src="../../assets/img/generic/top-slim.png"
|
|
||||||
alt="" />
|
|
||||||
<img class="img-fluid img-prototype d-light-none mb-0"
|
|
||||||
src="../../assets/img/generic/top-slim-dark.png"
|
|
||||||
alt="" />
|
|
||||||
</span><span class="label-text">Slim</span>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="setting-panel-item">
|
|
||||||
<h5 class="setting-panel-item-title">Horizontal Navbar Appearance</h5>
|
|
||||||
<div class="row gx-2">
|
|
||||||
<div class="col-6">
|
|
||||||
<input class="btn-check"
|
|
||||||
id="navbarTopDefault"
|
|
||||||
name="navbar-top-style"
|
|
||||||
type="radio"
|
|
||||||
value="default"
|
|
||||||
data-theme-control="phoenixNavbarTopStyle" />
|
|
||||||
<label class="btn d-inline-block btn-navbar-style fs-9"
|
|
||||||
for="navbarTopDefault">
|
|
||||||
<span class="mb-2 rounded d-block">
|
|
||||||
<img class="img-fluid img-prototype d-dark-none mb-0"
|
|
||||||
src="../../assets/img/generic/top-default.png"
|
|
||||||
alt="" />
|
|
||||||
<img class="img-fluid img-prototype d-light-none mb-0"
|
|
||||||
src="../../assets/img/generic/top-style-darker.png"
|
|
||||||
alt="" />
|
|
||||||
</span><span class="label-text">Default</span>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
<div class="col-6">
|
|
||||||
<input class="btn-check"
|
|
||||||
id="navbarTopDarker"
|
|
||||||
name="navbar-top-style"
|
|
||||||
type="radio"
|
|
||||||
value="darker"
|
|
||||||
data-theme-control="phoenixNavbarTopStyle" />
|
|
||||||
<label class="btn d-inline-block btn-navbar-style fs-9"
|
|
||||||
for="navbarTopDarker">
|
|
||||||
<span class="mb-2 rounded d-block">
|
|
||||||
<img class="img-fluid img-prototype d-dark-none mb-0"
|
|
||||||
src="../../assets/img/generic/navbar-top-style-light.png"
|
|
||||||
alt="" />
|
|
||||||
<img class="img-fluid img-prototype d-light-none mb-0"
|
|
||||||
src="../../assets/img/generic/top-style-lighter.png"
|
|
||||||
alt="" />
|
|
||||||
</span><span class="label-text d-dark-none">Darker</span><span class="label-text d-light-none">Lighter</span>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<a class="bun btn-primary d-grid mb-3 text-white mt-5 btn btn-primary"
|
|
||||||
href="https://themes.getbootstrap.com/product/phoenix-admin-dashboard-webapp-template/"
|
|
||||||
target="_blank">Purchase template</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<a class="card setting-toggle"
|
|
||||||
href="#settings-offcanvas"
|
|
||||||
data-bs-toggle="offcanvas">
|
|
||||||
<div class="card-body d-flex align-items-center px-2 py-1">
|
|
||||||
<div class="position-relative rounded-start"
|
|
||||||
style="height:34px;
|
|
||||||
width:28px">
|
|
||||||
<div class="settings-popover">
|
|
||||||
<span class="ripple"><span class="fa-spin position-absolute all-0 d-flex flex-center"><span class="icon-spin position-absolute all-0 d-flex flex-center">
|
|
||||||
<svg width="20"
|
|
||||||
height="20"
|
|
||||||
viewBox="0 0 20 20"
|
|
||||||
fill="#ffffff"
|
|
||||||
xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<path d="M19.7369 12.3941L19.1989 12.1065C18.4459 11.7041 18.0843 10.8487 18.0843 9.99495C18.0843 9.14118 18.4459 8.28582 19.1989 7.88336L19.7369 7.59581C19.9474 7.47484 20.0316 7.23291 19.9474 7.03131C19.4842 5.57973 18.6843 4.28943 17.6738 3.20075C17.5053 3.03946 17.2527 2.99914 17.0422 3.12011L16.393 3.46714C15.6883 3.84379 14.8377 3.74529 14.1476 3.3427C14.0988 3.31422 14.0496 3.28621 14.0002 3.25868C13.2568 2.84453 12.7055 2.10629 12.7055 1.25525V0.70081C12.7055 0.499202 12.5371 0.297594 12.2845 0.257272C10.7266 -0.105622 9.16879 -0.0653007 7.69516 0.257272C7.44254 0.297594 7.31623 0.499202 7.31623 0.70081V1.23474C7.31623 2.09575 6.74999 2.8362 5.99824 3.25599C5.95774 3.27861 5.91747 3.30159 5.87744 3.32493C5.15643 3.74527 4.26453 3.85902 3.53534 3.45302L2.93743 3.12011C2.72691 2.99914 2.47429 3.03946 2.30587 3.20075C1.29538 4.28943 0.495411 5.57973 0.0322686 7.03131C-0.051939 7.23291 0.0322686 7.47484 0.242788 7.59581L0.784376 7.8853C1.54166 8.29007 1.92694 9.13627 1.92694 9.99495C1.92694 10.8536 1.54166 11.6998 0.784375 12.1046L0.242788 12.3941C0.0322686 12.515 -0.051939 12.757 0.0322686 12.9586C0.495411 14.4102 1.29538 15.7005 2.30587 16.7891C2.47429 16.9504 2.72691 16.9907 2.93743 16.8698L3.58669 16.5227C4.29133 16.1461 5.14131 16.2457 5.8331 16.6455C5.88713 16.6767 5.94159 16.7074 5.99648 16.7375C6.75162 17.1511 7.31623 17.8941 7.31623 18.7552V19.2891C7.31623 19.4425 7.41373 19.5959 7.55309 19.696C7.64066 19.7589 7.74815 19.7843 7.85406 19.8046C9.35884 20.0925 10.8609 20.0456 12.2845 19.7729C12.5371 19.6923 12.7055 19.4907 12.7055 19.2891V18.7346C12.7055 17.8836 13.2568 17.1454 14.0002 16.7312C14.0496 16.7037 14.0988 16.6757 14.1476 16.6472C14.8377 16.2446 15.6883 16.1461 16.393 16.5227L17.0422 16.8698C17.2527 16.9907 17.5053 16.9504 17.6738 16.7891C18.7264 15.7005 19.4842 14.4102 19.9895 12.9586C20.0316 12.757 19.9474 12.515 19.7369 12.3941ZM10.0109 13.2005C8.1162 13.2005 6.64257 11.7893 6.64257 9.97478C6.64257 8.20063 8.1162 6.74905 10.0109 6.74905C11.8634 6.74905 13.3792 8.20063 13.3792 9.97478C13.3792 11.7893 11.8634 13.2005 10.0109 13.2005Z" fill="#2A7BE4">
|
|
||||||
</path>
|
|
||||||
</svg>
|
|
||||||
</span></span></span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<small class="text-uppercase text-body-tertiary fw-bold py-2 pe-2 ps-1 rounded-end">customize</small>
|
|
||||||
</div>
|
|
||||||
</a>
|
|
||||||
<!-- ===============================================-->
|
<!-- ===============================================-->
|
||||||
<!-- JavaScripts-->
|
<!-- JavaScripts-->
|
||||||
<!-- ===============================================-->
|
<!-- ===============================================-->
|
||||||
<script src="../../vendors/popper/popper.min.js"></script>
|
<script src="../../vendors/popper/popper.min.js"></script>
|
||||||
<script src="../../vendors/bootstrap/bootstrap.min.js"></script>
|
<script src="../../vendors/bootstrap/bootstrap.min.js"></script>
|
||||||
<script src="../../vendors/anchorjs/anchor.min.js"></script>
|
<script src="../../vendors/anchorjs/anchor.min.js"></script>
|
||||||
<script src="../../vendors/is/is.min.js"></script>
|
<script src="../../vendors/is/is.min.js"></script>
|
||||||
<script src="../../vendors/fontawesome/all.min.js"></script>
|
<script src="../../vendors/fontawesome/all.min.js"></script>
|
||||||
<script src="../../vendors/lodash/lodash.min.js"></script>
|
<script src="../../vendors/lodash/lodash.min.js"></script>
|
||||||
<script src="../../vendors/list.js/list.min.js"></script>
|
<script src="../../vendors/list.js/list.min.js"></script>
|
||||||
<script src="../../vendors/feather-icons/feather.min.js"></script>
|
<script src="../../vendors/feather-icons/feather.min.js"></script>
|
||||||
<script src="../../vendors/dayjs/dayjs.min.js"></script>
|
<script src="../../vendors/dayjs/dayjs.min.js"></script>
|
||||||
<script src="../../assets/js/phoenix.js"></script>
|
<script src="../../assets/js/phoenix.js"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@ -92,21 +92,21 @@
|
|||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
<footer class="improved-footer">
|
<footer class="improved-footer">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<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">
|
||||||
<span class="text-body">© 2025 All rights reserved</span>
|
<span class="text-body">© 2025 All rights reserved</span>
|
||||||
<span class="fw-bold">Haikal</span> | <span class="fw-bold">هيكل</span>
|
<span class="fw-bold">Haikal</span> | <span class="fw-bold">هيكل</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-12 col-sm-auto text-center">
|
<div class="col-12 col-sm-auto text-center">
|
||||||
<span class="text-body">Powered by</span>
|
<span class="text-body">Powered by</span>
|
||||||
<span>
|
<span>
|
||||||
<a class="mx-1 text-secondary" href="https://tenhal.sa">
|
<a class="mx-1 text-secondary" href="https://tenhal.sa">
|
||||||
<span>TENHAL</span> | <span>تنحل</span>
|
<span>TENHAL</span> | <span>تنحل</span>
|
||||||
</a>
|
</a>
|
||||||
</span>
|
</span>
|
||||||
<span class="fas fa-registered fw-light"></span>
|
<span class="fas fa-registered fw-light"></span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
|
|||||||
@ -37,7 +37,7 @@
|
|||||||
<div class="card-header ">
|
<div class="card-header ">
|
||||||
<p class="mb-2">{{ _("Group Details") }}</p>
|
<p class="mb-2">{{ _("Group Details") }}</p>
|
||||||
<a class="btn btn-phoenix-secondary me-2" href="{% url 'group_list' request.dealer.slug %}">{% trans "Groups List" %}</a>
|
<a class="btn btn-phoenix-secondary me-2" href="{% url 'group_list' request.dealer.slug %}">{% trans "Groups List" %}</a>
|
||||||
<a class="btn btn-phoenix-secondary " href="{% url 'user_list' request.dealer.slug %}">{% trans "Staffs List" %}</a>
|
<a class="btn btn-phoenix-secondary " href="{% url 'user_list' request.dealer.slug %}">{% trans "Staffs List" %}</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
@ -125,4 +125,4 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|||||||
@ -2,45 +2,45 @@
|
|||||||
{% load i18n static %}
|
{% load i18n static %}
|
||||||
{% block title %}{% trans "Haikal Bot" %}{% endblock %}
|
{% block title %}{% trans "Haikal Bot" %}{% endblock %}
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
|
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/PapaParse/5.3.2/papaparse.min.js"></script>
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/PapaParse/5.3.2/papaparse.min.js"></script>
|
||||||
<div class="container mt-5">
|
<div class="container mt-5">
|
||||||
<div class="card shadow-sm">
|
<div class="card shadow-sm">
|
||||||
<div class="card-header d-flex justify-content-between align-items-center">
|
<div class="card-header d-flex justify-content-between align-items-center">
|
||||||
<h5 class="mb-0">
|
<h5 class="mb-0">
|
||||||
<i class="fas fa-robot me-2"></i>{% trans "HaikalBot" %}
|
<i class="fas fa-robot me-2"></i>{% trans "HaikalBot" %}
|
||||||
</h5>
|
</h5>
|
||||||
<div>
|
<div>
|
||||||
<button id="export-btn"
|
<button id="export-btn"
|
||||||
class="btn btn-sm btn-phoenix-secondary"
|
class="btn btn-sm btn-phoenix-secondary"
|
||||||
style="display:none">{% trans "Export CSV" %}</button>
|
style="display:none">{% trans "Export CSV" %}</button>
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="card-body"
|
|
||||||
style="max-height: 60vh;
|
|
||||||
overflow-y: auto"
|
|
||||||
id="chat-history"></div>
|
|
||||||
<div class="card-footer bg-white border-top">
|
|
||||||
<form id="chat-form" class="d-flex align-items-center gap-2">
|
|
||||||
<button type="button" class="btn btn-light" id="mic-btn">
|
|
||||||
<i class="fas fa-microphone"></i>
|
|
||||||
</button>
|
|
||||||
<input type="text"
|
|
||||||
class="form-control"
|
|
||||||
id="chat-input"
|
|
||||||
placeholder="{% trans 'Type your question...' %}"
|
|
||||||
required />
|
|
||||||
<button type="submit" class="btn btn-phoenix-primary">
|
|
||||||
<i class="fas fa-paper-plane"></i>
|
|
||||||
</button>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
<div id="chart-container" style="display:none;" class="p-4 border-top">
|
|
||||||
<canvas id="chart-canvas" height="200px"></canvas>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="card-body"
|
||||||
|
style="max-height: 60vh;
|
||||||
|
overflow-y: auto"
|
||||||
|
id="chat-history"></div>
|
||||||
|
<div class="card-footer bg-white border-top">
|
||||||
|
<form id="chat-form" class="d-flex align-items-center gap-2">
|
||||||
|
<button type="button" class="btn btn-light" id="mic-btn">
|
||||||
|
<i class="fas fa-microphone"></i>
|
||||||
|
</button>
|
||||||
|
<input type="text"
|
||||||
|
class="form-control"
|
||||||
|
id="chat-input"
|
||||||
|
placeholder="{% trans 'Type your question...' %}"
|
||||||
|
required />
|
||||||
|
<button type="submit" class="btn btn-phoenix-primary">
|
||||||
|
<i class="fas fa-paper-plane"></i>
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
<div id="chart-container" style="display:none;" class="p-4 border-top">
|
||||||
|
<canvas id="chart-canvas" height="200px"></canvas>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<script>
|
</div>
|
||||||
|
<script>
|
||||||
const chatHistory = document.getElementById('chat-history');
|
const chatHistory = document.getElementById('chat-history');
|
||||||
const chartContainer = document.getElementById('chart-container');
|
const chartContainer = document.getElementById('chart-container');
|
||||||
const chartCanvas = document.getElementById('chart-canvas');
|
const chartCanvas = document.getElementById('chart-canvas');
|
||||||
@ -193,5 +193,5 @@
|
|||||||
|
|
||||||
recognition.start();
|
recognition.start();
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|||||||
@ -5,7 +5,7 @@
|
|||||||
<div class="navbar-vertical-content d-flex flex-column">
|
<div class="navbar-vertical-content d-flex flex-column">
|
||||||
<ul class="navbar-nav flex-column"
|
<ul class="navbar-nav flex-column"
|
||||||
id="navbarVerticalNav"
|
id="navbarVerticalNav"
|
||||||
>
|
>
|
||||||
|
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
{% comment %} <p class="navbar-vertical-label text-primary fs-8 text-truncate">{{request.dealer|default:"Apps"}}</p>
|
{% comment %} <p class="navbar-vertical-label text-primary fs-8 text-truncate">{{request.dealer|default:"Apps"}}</p>
|
||||||
@ -34,9 +34,9 @@
|
|||||||
{% if perms.inventory.add_car %}
|
{% if perms.inventory.add_car %}
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a
|
<a
|
||||||
id="btn-add-car"
|
id="btn-add-car"
|
||||||
class="nav-link btn-add-car"
|
class="nav-link btn-add-car"
|
||||||
href="{% url 'car_add' request.dealer.slug %}">
|
href="{% url 'car_add' request.dealer.slug %}">
|
||||||
<div class="d-flex align-items-center">
|
<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>
|
<span class="nav-link-icon"><span class="fas fa-plus-circle"></span></span><span class="nav-link-text">{% trans "add car"|capfirst %}</span>
|
||||||
</div>
|
</div>
|
||||||
@ -438,21 +438,21 @@
|
|||||||
|
|
||||||
</ul>
|
</ul>
|
||||||
</div> {% endcomment %}
|
</div> {% endcomment %}
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="navbar-vertical-footer">
|
||||||
|
<a class="nav-link ps-2" href="{% if request.is_dealer%}{% url 'ticket_list' request.dealer.slug %} {% else %}#{%endif%}">
|
||||||
|
<div class="d-flex align-items-center">
|
||||||
|
{% if user.is_authenticated%}
|
||||||
|
|
||||||
|
<span class="nav-link-icon"><span class="fa-solid fa-gear me-1 fs-7"></span></span>
|
||||||
|
<span class="nav-link-text">{{ request.dealer.user.username }}</span>
|
||||||
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</a>
|
||||||
<div class="navbar-vertical-footer">
|
</div>
|
||||||
<a class="nav-link ps-2" href="{% if request.is_dealer%}{% url 'ticket_list' request.dealer.slug %} {% else %}#{%endif%}">
|
|
||||||
<div class="d-flex align-items-center">
|
|
||||||
{% if user.is_authenticated%}
|
|
||||||
|
|
||||||
<span class="nav-link-icon"><span class="fa-solid fa-gear me-1 fs-7"></span></span>
|
|
||||||
<span class="nav-link-text">{{ request.dealer.user.username }}</span>
|
|
||||||
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</nav>
|
</nav>
|
||||||
<nav class="navbar navbar-top fixed-top navbar-expand" id="navbarDefault">
|
<nav class="navbar navbar-top fixed-top navbar-expand" id="navbarDefault">
|
||||||
<div class="collapse navbar-collapse justify-content-between">
|
<div class="collapse navbar-collapse justify-content-between">
|
||||||
@ -499,12 +499,12 @@
|
|||||||
|
|
||||||
<div class="d-flex align-items-center">
|
<div class="d-flex align-items-center">
|
||||||
|
|
||||||
<small class="text-gray-600 ms-2 d-none d-sm-block fs-9"
|
<small class="text-gray-600 ms-2 d-none d-sm-block fs-9"
|
||||||
data-bs-toggle="tooltip"
|
data-bs-toggle="tooltip"
|
||||||
data-bs-placement="bottom"
|
data-bs-placement="bottom"
|
||||||
>
|
>
|
||||||
{% now "l, F j, Y g:i A" %}
|
{% now "l, F j, Y g:i A" %}
|
||||||
</small>
|
</small>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -562,13 +562,13 @@
|
|||||||
{% if user.is_authenticated and request.is_dealer or request.is_staff %}
|
{% if user.is_authenticated and request.is_dealer or request.is_staff %}
|
||||||
<li class="nav-item dropdown">
|
<li class="nav-item dropdown">
|
||||||
<a
|
<a
|
||||||
class="nav-link lh-1 pe-0"
|
class="nav-link lh-1 pe-0"
|
||||||
id="navbarDropdownUser"
|
id="navbarDropdownUser"
|
||||||
role="button"
|
role="button"
|
||||||
data-bs-toggle="dropdown"
|
data-bs-toggle="dropdown"
|
||||||
data-bs-auto-close="outside"
|
data-bs-auto-close="outside"
|
||||||
aria-haspopup="true"
|
aria-haspopup="true"
|
||||||
aria-expanded="false">
|
aria-expanded="false">
|
||||||
<div class="avatar avatar-l text-center align-middle">
|
<div class="avatar avatar-l text-center align-middle">
|
||||||
{% if request.is_dealer and user.dealer.logo %}
|
{% if request.is_dealer and user.dealer.logo %}
|
||||||
<img class="rounded-circle" src="{{ user.dealer.logo.url }}" alt="" />
|
<img class="rounded-circle" src="{{ user.dealer.logo.url }}" alt="" />
|
||||||
@ -610,8 +610,8 @@
|
|||||||
{% else %}
|
{% else %}
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a
|
<a
|
||||||
class="nav-link px-3 d-block"
|
class="nav-link px-3 d-block"
|
||||||
href="{% url 'staff_detail' request.dealer.slug request.staff.slug %}"> <span class="me-2 text-body align-bottom" data-feather="user"></span><span>{% translate 'profile'|capfirst %}</span></a>
|
href="{% url 'staff_detail' request.dealer.slug request.staff.slug %}"> <span class="me-2 text-body align-bottom" data-feather="user"></span><span>{% translate 'profile'|capfirst %}</span></a>
|
||||||
</li>
|
</li>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if request.is_dealer %}
|
{% if request.is_dealer %}
|
||||||
@ -636,16 +636,16 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
</li>
|
</li>
|
||||||
{% if request.is_dealer%}
|
{% if request.is_dealer%}
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a class="nav-link px-3 d-block"
|
<a class="nav-link px-3 d-block"
|
||||||
href="{% url 'ticket_list' request.dealer.slug %}"> <span class="me-2 text-body align-bottom" data-feather="help-circle"></span>{{ _("Help Center") }}</a>
|
href="{% url 'ticket_list' request.dealer.slug %}"> <span class="me-2 text-body align-bottom" data-feather="help-circle"></span>{{ _("Help Center") }}</a>
|
||||||
</li>
|
</li>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if request.is_staff %}
|
{% if request.is_staff %}
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a
|
<a
|
||||||
class="nav-link px-3 d-block"
|
class="nav-link px-3 d-block"
|
||||||
href="{% url 'schedule_calendar' request.dealer.slug %}"> <span class="me-2 text-body align-bottom" data-feather="calendar"></span>{{ _("My Calendar") }}</a>
|
href="{% url 'schedule_calendar' request.dealer.slug %}"> <span class="me-2 text-body align-bottom" data-feather="calendar"></span>{{ _("My Calendar") }}</a>
|
||||||
</li>
|
</li>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<!--<li class="nav-item"><a class="nav-link px-3 d-block" href=""> Language</a></li>-->
|
<!--<li class="nav-item"><a class="nav-link px-3 d-block" href=""> Language</a></li>-->
|
||||||
@ -657,28 +657,28 @@
|
|||||||
<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>
|
<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>-->
|
</li>-->
|
||||||
</ul>
|
</ul>
|
||||||
</hr>
|
</hr>
|
||||||
<div class="px-3">
|
<div class="px-3">
|
||||||
<a class="btn btn-sm btn-phoenix-danger d-flex flex-center w-100"
|
<a class="btn btn-sm btn-phoenix-danger d-flex flex-center w-100"
|
||||||
href="{% url 'account_logout' %}"> <span class="fas fa-power-off me-2"></span>{% trans 'Sign Out' %}</a>
|
href="{% url 'account_logout' %}"> <span class="fas fa-power-off me-2"></span>{% trans 'Sign Out' %}</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="my-2 text-center fw-bold fs-10 text-body-quaternary">
|
<div class="my-2 text-center fw-bold fs-10 text-body-quaternary">
|
||||||
<a class="text-body-quaternary me-1" href="">{% trans 'Privacy policy' %}</a>•<a class="text-body-quaternary mx-1" href="">{% trans 'Terms' %}</a>•<a class="text-body-quaternary ms-1" href="">Cookies</a>
|
<a class="text-body-quaternary me-1" href="">{% trans 'Privacy policy' %}</a>•<a class="text-body-quaternary mx-1" href="">{% trans 'Terms' %}</a>•<a class="text-body-quaternary ms-1" href="">Cookies</a>
|
||||||
</div>
|
</div>
|
||||||
{% else %}
|
{% else %}
|
||||||
<div class="px-3">
|
<div class="px-3">
|
||||||
<a class="btn btn-phoenix-succes d-flex flex-center w-100"
|
<a class="btn btn-phoenix-succes d-flex flex-center w-100"
|
||||||
href="{% url 'account_login' %}"> <span class="me-2" data-feather="log-in"></span>{% trans 'Sign In' %}</a>
|
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-primary 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>
|
||||||
</div>
|
<div class="px-3">
|
||||||
</li>
|
<a class="btn btn-phoenix-primary d-flex flex-center w-100"
|
||||||
</ul>
|
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>
|
</nav>
|
||||||
|
|||||||
@ -2,68 +2,68 @@
|
|||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
{% block title %}
|
{% block title %}
|
||||||
{% trans 'Add Colors' %} {% endblock %}
|
{% trans 'Add Colors' %} {% endblock %}
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div class="row mt-4 mb-3">
|
<div class="row mt-4 mb-3">
|
||||||
<h3 class="text-center">{% trans "Add Colors" %}</h3>
|
<h3 class="text-center">{% trans "Add Colors" %}</h3>
|
||||||
<p class="text-center">
|
<p class="text-center">
|
||||||
{% trans "Select exterior and interior colors for" %} {{ car.id_car_make.get_local_name }} {{ car.id_car_model.get_local_name }}
|
{% trans "Select exterior and interior colors for" %} {{ car.id_car_make.get_local_name }} {{ car.id_car_model.get_local_name }}
|
||||||
</p>
|
</p>
|
||||||
<form method="post">
|
<form method="post">
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
<!-- Exterior Colors -->
|
<!-- Exterior Colors -->
|
||||||
<div class="row g-4">
|
<div class="row g-4">
|
||||||
<p class="fs-5 mb-0">{% trans 'Exterior Colors' %}</p>
|
<p class="fs-5 mb-0">{% trans 'Exterior Colors' %}</p>
|
||||||
{% for color in form.fields.exterior.queryset %}
|
{% for color in form.fields.exterior.queryset %}
|
||||||
<div class="col-lg-4 col-xl-2">
|
<div class="col-lg-4 col-xl-2">
|
||||||
<div class="card rounded shadow-sm color-card">
|
<div class="card rounded shadow-sm color-card">
|
||||||
<label class="color-option">
|
<label class="color-option">
|
||||||
<input class="color-radio"
|
<input class="color-radio"
|
||||||
type="radio"
|
type="radio"
|
||||||
name="exterior"
|
name="exterior"
|
||||||
value="{{ color.id }}"
|
value="{{ color.id }}"
|
||||||
{% if color.id == form.instance.exterior.id %}checked{% endif %}>
|
{% if color.id == form.instance.exterior.id %}checked{% endif %}>
|
||||||
<div class="card-body color-display"
|
<div class="card-body color-display"
|
||||||
style="background-color: rgb({{ color.rgb }})">
|
style="background-color: rgb({{ color.rgb }})">
|
||||||
<div class="">
|
<div class="">
|
||||||
<small>{{ color.get_local_name }}</small>
|
<small>{{ color.get_local_name }}</small>
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</label>
|
</div>
|
||||||
</div>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
{% endfor %}
|
</div>
|
||||||
|
{% endfor %}
|
||||||
<!-- Interior Colors -->
|
<!-- Interior Colors -->
|
||||||
<p class="fs-5 mt-3 mb-0">{% trans 'Interior Colors' %}</p>
|
<p class="fs-5 mt-3 mb-0">{% trans 'Interior Colors' %}</p>
|
||||||
{% for color in form.fields.interior.queryset %}
|
{% for color in form.fields.interior.queryset %}
|
||||||
<div class="col-lg-4 col-xl-2">
|
<div class="col-lg-4 col-xl-2">
|
||||||
<div class="card rounded shadow-sm color-card">
|
<div class="card rounded shadow-sm color-card">
|
||||||
<label class="color-option">
|
<label class="color-option">
|
||||||
<input class="color-radio"
|
<input class="color-radio"
|
||||||
type="radio"
|
type="radio"
|
||||||
name="interior"
|
name="interior"
|
||||||
value="{{ color.id }}"
|
value="{{ color.id }}"
|
||||||
{% if color.id == form.instance.interior.id %}checked{% endif %}>
|
{% if color.id == form.instance.interior.id %}checked{% endif %}>
|
||||||
<div class="card-body color-display"
|
<div class="card-body color-display"
|
||||||
style="background-color: rgb({{ color.rgb }})">
|
style="background-color: rgb({{ color.rgb }})">
|
||||||
<div class="">
|
<div class="">
|
||||||
<small>{{ color.get_local_name }}</small>
|
<small>{{ color.get_local_name }}</small>
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</label>
|
</div>
|
||||||
</div>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
{% endfor %}
|
</div>
|
||||||
</div>
|
{% endfor %}
|
||||||
<div class="d-flex justify-content-center mt-4">
|
</div>
|
||||||
<button class="btn btn-lg btn-phoenix-primary me-2" type="submit">
|
<div class="d-flex justify-content-center mt-4">
|
||||||
<i class="fa-solid fa-floppy-disk me-1"></i>{{ _("Save") }}
|
<button class="btn btn-lg btn-phoenix-primary me-2" type="submit">
|
||||||
</button>
|
<i class="fa-solid fa-floppy-disk me-1"></i>{{ _("Save") }}
|
||||||
<a href="{% url 'car_detail' request.dealer.slug car.slug %}"
|
</button>
|
||||||
class="btn btn-lg btn-phoenix-secondary"><i class="fa-solid fa-ban me-1"></i>{% trans "Cancel" %}</a>
|
<a href="{% url 'car_detail' request.dealer.slug car.slug %}"
|
||||||
</div>
|
class="btn btn-lg btn-phoenix-secondary"><i class="fa-solid fa-ban me-1"></i>{% trans "Cancel" %}</a>
|
||||||
</form>
|
</div>
|
||||||
</div>
|
</form>
|
||||||
<style>
|
</div>
|
||||||
|
<style>
|
||||||
.color-card {
|
.color-card {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
transition: all 0.3s ease;
|
transition: all 0.3s ease;
|
||||||
@ -116,5 +116,5 @@
|
|||||||
text-align: center;
|
text-align: center;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|||||||
@ -76,30 +76,30 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
<!-- Main row -->
|
<!-- Main row -->
|
||||||
{% if car.ready and car.status != 'sold' %}
|
{% if car.ready and car.status != 'sold' %}
|
||||||
<div class="d-flex align-items-center gap-2 mb-2">
|
<div class="d-flex align-items-center gap-2 mb-2">
|
||||||
<button type="button"
|
<button type="button"
|
||||||
class="btn btn-sm btn-phoenix-success"
|
class="btn btn-sm btn-phoenix-success"
|
||||||
data-bs-toggle="modal"
|
data-bs-toggle="modal"
|
||||||
data-bs-target="#estimateModal">
|
data-bs-target="#estimateModal">
|
||||||
{% trans 'Create Estimate' %}
|
{% trans 'Create Estimate' %}
|
||||||
</button>
|
</button>
|
||||||
{% if active_estimates %}
|
{% if active_estimates %}
|
||||||
<button type="button" class="btn btn-phoenix-warning btn-sm"
|
<button type="button" class="btn btn-phoenix-warning btn-sm"
|
||||||
data-bs-toggle="modal"
|
data-bs-toggle="modal"
|
||||||
data-bs-target="#activeEstimatesModal">
|
data-bs-target="#activeEstimatesModal">
|
||||||
{% trans "Active Estimates" %}
|
{% trans "Active Estimates" %}
|
||||||
<span class="ms-2 badge rounded-pill text-bg-light">{{ active_estimates|length }}</span>
|
<span class="ms-2 badge rounded-pill text-bg-light">{{ active_estimates|length }}</span>
|
||||||
</button>
|
</button>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if perms.inventory.view_car %}
|
{% if perms.inventory.view_car %}
|
||||||
<div class="row-fluid {% if car.status == 'sold' %}disabled{% endif %}">
|
<div class="row-fluid {% if car.status == 'sold' %}disabled{% endif %}">
|
||||||
<div class="row g-3 justify-content-between">
|
<div class="row g-3 justify-content-between">
|
||||||
<div class="col-md-6">
|
<div class="col-md-6">
|
||||||
<div class="card mb-3 rounded shadow d-flex justify-content-center align-item-center{% if car.get_transfer %}disabled{% endif %}">
|
<div class="card mb-3 rounded shadow d-flex justify-content-center align-item-center{% if car.get_transfer %}disabled{% endif %}">
|
||||||
<p class="card-header rounded-top fw-bold">{% trans 'Car Details' %}</p>
|
<p class="card-header rounded-top fw-bold">{% trans 'Car Details' %}</p>
|
||||||
<div class="col-md-4 ms-4 mt-2">
|
<div class="col-md-4 ms-4 mt-2">
|
||||||
<div class="avatar avatar-6xl mb-3">
|
<div class="avatar avatar-6xl mb-3">
|
||||||
<img class="rounded"
|
<img class="rounded"
|
||||||
src="{% static 'images/car_images/' %}{{ car.get_hash }}.png"
|
src="{% static 'images/car_images/' %}{{ car.get_hash }}.png"
|
||||||
@ -219,7 +219,7 @@
|
|||||||
hx-swap="innerHTML"
|
hx-swap="innerHTML"
|
||||||
data-bs-toggle="modal"
|
data-bs-toggle="modal"
|
||||||
data-bs-target="#mainModal"
|
data-bs-target="#mainModal"
|
||||||
>{% trans 'Add' %}</button>
|
>{% trans 'Add' %}</button>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@ -283,10 +283,10 @@
|
|||||||
<tr>
|
<tr>
|
||||||
<th>{% trans "Cost Price"|capfirst %}</th>
|
<th>{% trans "Cost Price"|capfirst %}</th>
|
||||||
{% if request.is_dealer or request.is_accountant or request.manager%}
|
{% if request.is_dealer or request.is_accountant or request.manager%}
|
||||||
<td class="text-nowrap">{{ car.cost_price|floatformat:2 }}<span class="icon-saudi_riyal"></span></td>
|
<td class="text-nowrap">{{ car.cost_price|floatformat:2 }}<span class="icon-saudi_riyal"></span></td>
|
||||||
{% else %}
|
{% else %}
|
||||||
<td class="d-none text-nowrap">{{ car.cost_price|floatformat:2 }}<span class="icon-saudi_riyal"></span></td>
|
<td class="d-none text-nowrap">{{ car.cost_price|floatformat:2 }}<span class="icon-saudi_riyal"></span></td>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th>{% trans "Marked Price"|capfirst %}</th>
|
<th>{% trans "Marked Price"|capfirst %}</th>
|
||||||
@ -295,21 +295,21 @@
|
|||||||
|
|
||||||
<tr>
|
<tr>
|
||||||
{% if perms.django_ledger.change_ledgermodel %}
|
{% if perms.django_ledger.change_ledgermodel %}
|
||||||
<td colspan="2">
|
<td colspan="2">
|
||||||
{% if not car.get_transfer %}
|
{% if not car.get_transfer %}
|
||||||
<a href="{% url 'car_finance_update' request.dealer.slug car.slug %}"
|
<a href="{% url 'car_finance_update' request.dealer.slug car.slug %}"
|
||||||
class="btn btn-phoenix-warning btn-sm mb-3">{% trans "Edit" %}</a>
|
class="btn btn-phoenix-warning btn-sm mb-3">{% trans "Edit" %}</a>
|
||||||
{% else %}
|
{% else %}
|
||||||
<span class="badge bg-danger">{% trans "Cannot Edit, Car in Transfer." %}</span>
|
<span class="badge bg-danger">{% trans "Cannot Edit, Car in Transfer." %}</span>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</td>
|
</td>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</tr>
|
</tr>
|
||||||
{% else %}
|
{% else %}
|
||||||
{% if perms.inventory.add_car%}
|
{% if perms.inventory.add_car%}
|
||||||
<p>{% trans "No finance details available." %}</p>
|
<p>{% trans "No finance details available." %}</p>
|
||||||
<a href="{% url 'car_finance_update' request.dealer.slug car.slug %}"
|
<a href="{% url 'car_finance_update' request.dealer.slug car.slug %}"
|
||||||
class="btn btn-phoenix-success btn-sm mb-3">{% trans "Add" %}</a>
|
class="btn btn-phoenix-success btn-sm mb-3">{% trans "Add" %}</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</table>
|
</table>
|
||||||
@ -425,19 +425,19 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
</tr>
|
</tr>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% else %}
|
{% else %}
|
||||||
{% if perms.inventory.add_carreservation %}
|
{% if perms.inventory.add_carreservation %}
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<button type="button"
|
<button type="button"
|
||||||
class="btn btn-sm btn-phoenix-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' %}
|
||||||
</button>
|
</button>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</tbody>
|
</tbody>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</table>
|
</table>
|
||||||
@ -542,7 +542,7 @@
|
|||||||
data-bs-dismiss="modal"
|
data-bs-dismiss="modal"
|
||||||
aria-label="Close"></button>
|
aria-label="Close"></button>
|
||||||
</div>
|
</div>
|
||||||
<div id="estimateModalBody" class="main-modal-body" style="padding: 20px;">
|
<div id="estimateModalBody" style="padding: 20px;">
|
||||||
<form action="{% url 'create_estimate_for_car' request.dealer.slug car.slug %}" method="post">
|
<form action="{% url 'create_estimate_for_car' request.dealer.slug car.slug %}" method="post">
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
{{estimate_form|crispy}}
|
{{estimate_form|crispy}}
|
||||||
@ -639,28 +639,28 @@
|
|||||||
<!--active estimate modal-->
|
<!--active estimate modal-->
|
||||||
|
|
||||||
<div class="modal fade" id="activeEstimatesModal" tabindex="-1" aria-labelledby="activeEstimatesModalLabel" aria-hidden="true">
|
<div class="modal fade" id="activeEstimatesModal" tabindex="-1" aria-labelledby="activeEstimatesModalLabel" aria-hidden="true">
|
||||||
<div class="modal-dialog modal-dialog-top">
|
<div class="modal-dialog modal-dialog-top">
|
||||||
<div class="modal-content">
|
<div class="modal-content">
|
||||||
<div class="modal-header">
|
<div class="modal-header">
|
||||||
<h5 class="modal-title" id="activeEstimatesModalLabel">Active Estimates ({{ active_estimates|length }})</h5>
|
<h5 class="modal-title" id="activeEstimatesModalLabel">Active Estimates ({{ active_estimates|length }})</h5>
|
||||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
<div class="d-flex flex-column gap-3">
|
<div class="d-flex flex-column gap-3">
|
||||||
{% for e in active_estimates %}
|
{% for e in active_estimates %}
|
||||||
<div class="d-flex align-items-center gap-2 border-bottom pb-2">
|
<div class="d-flex align-items-center gap-2 border-bottom pb-2">
|
||||||
<span class="badge rounded-pill bg-primary text-light me-1">{{ e.content_object.estimate_number }}</span class="text-nowrap"><span>{% trans " created by: " %}</span>
|
<span class="badge rounded-pill bg-primary text-light me-1">{{ e.content_object.estimate_number }}</span class="text-nowrap"><span>{% trans " created by: " %}</span>
|
||||||
<div class="text-muted">{{ e.related_object }}</div>
|
<div class="text-muted">{{ e.related_object }}</div>
|
||||||
</div>
|
</div>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="button" class="btn btn-phoenix-secondary" data-bs-dismiss="modal">{% trans "Close" %}</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
<div class="modal-footer">
|
|
||||||
<button type="button" class="btn btn-phoenix-secondary" data-bs-dismiss="modal">{% trans "Close" %}</button>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
{% block customJS %}
|
{% block customJS %}
|
||||||
<script>
|
<script>
|
||||||
@ -771,16 +771,16 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
document.addEventListener('htmx:afterRequest', e => {
|
document.addEventListener('htmx:afterRequest', e => {
|
||||||
console.log('PUT Success!')
|
console.log('PUT Success!')
|
||||||
});
|
});
|
||||||
document.addEventListener('htmx:beforeSwap', e => {
|
document.addEventListener('htmx:beforeSwap', e => {
|
||||||
console.log('Before Swap!')
|
console.log('Before Swap!')
|
||||||
});
|
});
|
||||||
document.addEventListener('htmx:swapError', e => {
|
document.addEventListener('htmx:swapError', e => {
|
||||||
console.log('Swap Error!')
|
console.log('Swap Error!')
|
||||||
});
|
});
|
||||||
document.addEventListener('htmx:afterSwap', e => {
|
document.addEventListener('htmx:afterSwap', e => {
|
||||||
console.log('After Swap!')
|
console.log('After Swap!')
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|||||||
@ -25,7 +25,7 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
<!---->
|
<!---->
|
||||||
<div class="row justify-content-center mt-5 mb-3 {% if not vendor_exists %}d-none{% endif %}"
|
<div class="row justify-content-center mt-5 mb-3 {% if not vendor_exists %}d-none{% endif %}"
|
||||||
>
|
>
|
||||||
<div class="col-lg-8 col-md-10">
|
<div class="col-lg-8 col-md-10">
|
||||||
<div class="card shadow-sm border-0 rounded-3">
|
<div class="card shadow-sm border-0 rounded-3">
|
||||||
<div class="card-header bg-gray-200 py-3 border-0 rounded-top-3">
|
<div class="card-header bg-gray-200 py-3 border-0 rounded-top-3">
|
||||||
|
|||||||
@ -134,9 +134,9 @@
|
|||||||
<span class="badge badge-phoenix fs-10 badge-phoenix-primary"><span class="badge-label">{{ _("Sold") }}</span><span class="ms-1" data-feather="package" style="height:13px;width:13px;"></span></span>
|
<span class="badge badge-phoenix fs-10 badge-phoenix-primary"><span class="badge-label">{{ _("Sold") }}</span><span class="ms-1" data-feather="package" style="height:13px;width:13px;"></span></span>
|
||||||
{% elif car.status == "hold" %}
|
{% elif car.status == "hold" %}
|
||||||
<span class="badge badge-phoenix fs-10 badge-phoenix-warning"><span class="badge-label">{{ _("Hold") }}</span><span class="ms-1"
|
<span class="badge badge-phoenix fs-10 badge-phoenix-warning"><span class="badge-label">{{ _("Hold") }}</span><span class="ms-1"
|
||||||
data-feather="alert-octagon"
|
data-feather="alert-octagon"
|
||||||
style="height:13px;
|
style="height:13px;
|
||||||
width:13px"></span></span>
|
width:13px"></span></span>
|
||||||
{% elif car.status == "reserved" %}
|
{% elif car.status == "reserved" %}
|
||||||
<span class="badge badge-phoenix fs-10 badge-phoenix-danger"><span class="badge-label">{{ _("Reserved") }}</span><span class="ms-1" data-feather="info" style="height:13px;width:13px;"></span></span>
|
<span class="badge badge-phoenix fs-10 badge-phoenix-danger"><span class="badge-label">{{ _("Reserved") }}</span><span class="ms-1" data-feather="info" style="height:13px;width:13px;"></span></span>
|
||||||
{% elif car.status == "damaged" %}
|
{% elif car.status == "damaged" %}
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
{% load custom_filters %}
|
{% load custom_filters %}
|
||||||
{% block title %}
|
{% block title %}
|
||||||
{% trans "Car list" %}
|
{% trans "Car list" %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div class="row-fluid p-2">
|
<div class="row-fluid p-2">
|
||||||
|
|||||||
@ -26,287 +26,287 @@
|
|||||||
{% endblock customCSS %}
|
{% endblock customCSS %}
|
||||||
{% block content %}
|
{% block content %}
|
||||||
|
|
||||||
<div class="container-fluid" id="projectSummary">
|
<div class="container-fluid" id="projectSummary">
|
||||||
<div class="row g-3 justify-content-between align-items-end mb-4">
|
<div class="row g-3 justify-content-between align-items-end mb-4">
|
||||||
<div class="col-12 col-sm-auto">
|
<div class="col-12 col-sm-auto">
|
||||||
<h2 class="text-body-emphasis fw-bold mb-0">
|
<h2 class="text-body-emphasis fw-bold mb-0">
|
||||||
{{ _("Inventory") }}
|
{{ _("Inventory") }}
|
||||||
<li class="fas fa-store text-primary ms-2"></li>
|
<li class="fas fa-store text-primary ms-2"></li>
|
||||||
</h2>
|
</h2>
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="row g-3 justify-content-between align-items-end mb-2">
|
</div>
|
||||||
<div class="col-4 col-sm-auto">
|
<div class="row g-3 justify-content-between align-items-end mb-2">
|
||||||
<ul class="nav nav-links mx-n2"
|
<div class="col-4 col-sm-auto">
|
||||||
hx-boost="true"
|
<ul class="nav nav-links mx-n2"
|
||||||
hx-push-url="false"
|
hx-boost="true"
|
||||||
hx-target=".table-responsive"
|
hx-push-url="false"
|
||||||
hx-select=".table-responsive"
|
hx-target=".table-responsive"
|
||||||
hx-swap="innerHTML show:window:top"
|
hx-select=".table-responsive"
|
||||||
hx-indicator=".htmx-indicator"
|
hx-swap="innerHTML show:window:top"
|
||||||
hx-on::before-request="on_before_request()"
|
hx-indicator=".htmx-indicator"
|
||||||
hx-on::after-request="on_after_request()">
|
hx-on::before-request="on_before_request()"
|
||||||
<li class="nav-item">
|
hx-on::after-request="on_after_request()">
|
||||||
<a class="nav-link px-2 py-1 active"
|
<li class="nav-item">
|
||||||
aria-current="page"
|
<a class="nav-link px-2 py-1 active"
|
||||||
href="{% url 'car_list' request.dealer.slug %}"><span>{{ _("All") }}</span><span class="text-body-tertiary fw-semibold">({{ stats.all }})</span></a>
|
aria-current="page"
|
||||||
</li>
|
href="{% url 'car_list' request.dealer.slug %}"><span>{{ _("All") }}</span><span class="text-body-tertiary fw-semibold">({{ stats.all }})</span></a>
|
||||||
<li class="nav-item">
|
</li>
|
||||||
<a class="nav-link px-2 py-1"
|
<li class="nav-item">
|
||||||
href="{% url 'car_list' request.dealer.slug %}?status=available"><span>{{ _("Available") }}</span><span class="text-body-tertiary fw-semibold">({{ stats.available }})</span></a>
|
<a class="nav-link px-2 py-1"
|
||||||
</li>
|
href="{% url 'car_list' request.dealer.slug %}?status=available"><span>{{ _("Available") }}</span><span class="text-body-tertiary fw-semibold">({{ stats.available }})</span></a>
|
||||||
<li class="nav-item">
|
</li>
|
||||||
<a class="nav-link px-2 py-1"
|
<li class="nav-item">
|
||||||
href="{% url 'car_list' request.dealer.slug %}?status=reserved"><span>{{ _("Reserved") }}</span><span class="text-body-tertiary fw-semibold">({{ stats.reserved }})</span></a>
|
<a class="nav-link px-2 py-1"
|
||||||
</li>
|
href="{% url 'car_list' request.dealer.slug %}?status=reserved"><span>{{ _("Reserved") }}</span><span class="text-body-tertiary fw-semibold">({{ stats.reserved }})</span></a>
|
||||||
<li class="nav-item">
|
</li>
|
||||||
<a class="nav-link px-2 py-1"
|
<li class="nav-item">
|
||||||
href="{% url 'car_list' request.dealer.slug %}?status=transfer"><span>{{ _("Transfer") }}</span><span class="text-body-tertiary fw-semibold">({{ stats.transfer }})</span></a>
|
<a class="nav-link px-2 py-1"
|
||||||
</li>
|
href="{% url 'car_list' request.dealer.slug %}?status=transfer"><span>{{ _("Transfer") }}</span><span class="text-body-tertiary fw-semibold">({{ stats.transfer }})</span></a>
|
||||||
<li class="nav-item">
|
</li>
|
||||||
<a class="nav-link px-2 py-1"
|
<li class="nav-item">
|
||||||
href="{% url 'car_list' request.dealer.slug %}?status=sold"><span>{{ _("Sold") }}</span><span class="text-body-tertiary fw-semibold">({{ stats.sold }})</span></a>
|
<a class="nav-link px-2 py-1"
|
||||||
</li>
|
href="{% url 'car_list' request.dealer.slug %}?status=sold"><span>{{ _("Sold") }}</span><span class="text-body-tertiary fw-semibold">({{ stats.sold }})</span></a>
|
||||||
<li class="nav-item">
|
</li>
|
||||||
<button hx-on:click="toggle_filter()"
|
<li class="nav-item">
|
||||||
class="btn btn-sm btn-phoenix-primary px-2 py-1">
|
<button hx-on:click="toggle_filter()"
|
||||||
<span><span class="fa fa-filter me-1"></span>{{ _("Filter") }}</span>
|
class="btn btn-sm btn-phoenix-primary px-2 py-1">
|
||||||
<span class="fas fa-caret-down fs-9 ms-1 filter-icon"></span>
|
<span><span class="fa fa-filter me-1"></span>{{ _("Filter") }}</span>
|
||||||
</button>
|
<span class="fas fa-caret-down fs-9 ms-1 filter-icon"></span>
|
||||||
</li>
|
</button>
|
||||||
</ul>
|
</li>
|
||||||
</div>
|
</ul>
|
||||||
<div class="col-4 col-sm-auto">
|
</div>
|
||||||
<form hx-boost="true"
|
<div class="col-4 col-sm-auto">
|
||||||
action="{% url 'bulk_update_car_price' %}"
|
<form hx-boost="true"
|
||||||
method="post"
|
action="{% url 'bulk_update_car_price' %}"
|
||||||
hx-include=".car-checkbox"
|
method="post"
|
||||||
class="update-price-form d-flex flex-row align-items-center ms-auto d-none"
|
hx-include=".car-checkbox"
|
||||||
style="float: right">
|
class="update-price-form d-flex flex-row align-items-center ms-auto d-none"
|
||||||
{% csrf_token %}
|
style="float: right">
|
||||||
<div class="input-group">
|
{% csrf_token %}
|
||||||
<input class="form-control"
|
<div class="input-group">
|
||||||
type="number"
|
<input class="form-control"
|
||||||
placeholder='{{ _("Price") }}'
|
type="number"
|
||||||
name="price"
|
placeholder='{{ _("Price") }}'
|
||||||
aria-label="Price"
|
name="price"
|
||||||
id="price" />
|
aria-label="Price"
|
||||||
<button class="btn btn-sm btn-phoenix-primary" type="submit">{{ _("Update") }}</button>
|
id="price" />
|
||||||
</div>
|
<button class="btn btn-sm btn-phoenix-primary" type="submit">{{ _("Update") }}</button>
|
||||||
</form>
|
</div>
|
||||||
</div>
|
</form>
|
||||||
<div class="col-4 col-sm-auto">
|
</div>
|
||||||
<div class="d-flex align-items-center">
|
<div class="col-4 col-sm-auto">
|
||||||
<div class="spinner-border mx-3 htmx-indicator" role="status">
|
<div class="d-flex align-items-center">
|
||||||
<span class="visually-hidden">{% trans "Loading..." %}</span>
|
<div class="spinner-border mx-3 htmx-indicator" role="status">
|
||||||
</div>
|
<span class="visually-hidden">{% trans "Loading..." %}</span>
|
||||||
<div class="search-box me-3">
|
</div>
|
||||||
<form class="position-relative">
|
<div class="search-box me-3">
|
||||||
<input class="form-control search-input search"
|
<form class="position-relative">
|
||||||
name="search"
|
<input class="form-control search-input search"
|
||||||
type="search"
|
name="search"
|
||||||
placeholder="{% trans 'Search' %}"
|
type="search"
|
||||||
aria-label="Search"
|
placeholder="{% trans 'Search' %}"
|
||||||
hx-get="{% url 'car_list' request.dealer.slug %}"
|
aria-label="Search"
|
||||||
hx-trigger="keyup changed delay:500ms"
|
hx-get="{% url 'car_list' request.dealer.slug %}"
|
||||||
hx-target=".table-responsive"
|
hx-trigger="keyup changed delay:500ms"
|
||||||
hx-select=".table-responsive"
|
hx-target=".table-responsive"
|
||||||
hx-swap="innerHTML show:window:top"
|
hx-select=".table-responsive"
|
||||||
hx-indicator=".htmx-indicator"
|
hx-swap="innerHTML show:window:top"
|
||||||
hx-on::before-request="on_before_request()"
|
hx-indicator=".htmx-indicator"
|
||||||
hx-on::after-request="on_after_request()" />
|
hx-on::before-request="on_before_request()"
|
||||||
<span class="fas fa-search search-box-icon"></span>
|
hx-on::after-request="on_after_request()" />
|
||||||
</form>
|
<span class="fas fa-search search-box-icon"></span>
|
||||||
</div>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
</div>
|
||||||
<div class="d-flex align-items-center d-none filter">
|
<div class="row">
|
||||||
<select hx-get="{% url 'car_list' request.dealer.slug %}"
|
<div class="d-flex align-items-center d-none filter">
|
||||||
name="make"
|
<select hx-get="{% url 'car_list' request.dealer.slug %}"
|
||||||
hx-target=".model-select"
|
name="make"
|
||||||
hx-select=".model-select"
|
hx-target=".model-select"
|
||||||
hx-swap="outerHTML show:window:top"
|
hx-select=".model-select"
|
||||||
hx-indicator=".htmx-indicator"
|
hx-swap="outerHTML show:window:top"
|
||||||
class="form-select form-control-sm me-1 make"
|
hx-indicator=".htmx-indicator"
|
||||||
aria-label="Default select example"
|
class="form-select form-control-sm me-1 make"
|
||||||
hx-on::before-request="filter_before_request()"
|
aria-label="Default select example"
|
||||||
hx-on::after-request="filter_after_request()">
|
hx-on::before-request="filter_before_request()"
|
||||||
<option selected="" value="" disabled>{{ _("Make") }}</option>
|
hx-on::after-request="filter_after_request()">
|
||||||
{% for m in make %}<option value="{{ m.pk }}">{{ m.get_local_name|default:m.name }}</option>{% endfor %}
|
<option selected="" value="" disabled>{{ _("Make") }}</option>
|
||||||
</select>
|
{% for m in make %}<option value="{{ m.pk }}">{{ m.get_local_name|default:m.name }}</option>{% endfor %}
|
||||||
<select hx-get="{% url 'car_list' request.dealer.slug %}"
|
</select>
|
||||||
hx-include=".make"
|
<select hx-get="{% url 'car_list' request.dealer.slug %}"
|
||||||
name="model"
|
hx-include=".make"
|
||||||
hx-target=".year"
|
name="model"
|
||||||
hx-select=".year"
|
hx-target=".year"
|
||||||
hx-swap="outerHTML show:window:top"
|
hx-select=".year"
|
||||||
hx-indicator=".htmx-indicator"
|
hx-swap="outerHTML show:window:top"
|
||||||
class="form-select form-control-sm me-1 model-select"
|
hx-indicator=".htmx-indicator"
|
||||||
aria-label="Default select example"
|
class="form-select form-control-sm me-1 model-select"
|
||||||
hx-on::before-request="filter_before_request()"
|
aria-label="Default select example"
|
||||||
hx-on::after-request="filter_after_request()">
|
hx-on::before-request="filter_before_request()"
|
||||||
<option selected="" value="" disabled>{{ _("Model") }}</option>
|
hx-on::after-request="filter_after_request()">
|
||||||
{% for m in model %}<option value="{{ m.pk }}">{{ m.get_local_name|default:m.name }}</option>{% endfor %}
|
<option selected="" value="" disabled>{{ _("Model") }}</option>
|
||||||
</select>
|
{% for m in model %}<option value="{{ m.pk }}">{{ m.get_local_name|default:m.name }}</option>{% endfor %}
|
||||||
<select class="form-select form-control-sm me-1 year"
|
</select>
|
||||||
name="year"
|
<select class="form-select form-control-sm me-1 year"
|
||||||
aria-label="Default select example">
|
name="year"
|
||||||
<option selected="" value="" disabled>{{ _("Year") }}</option>
|
aria-label="Default select example">
|
||||||
{% for y in year %}<option value="{{ y.0 }}">{{ y.0 }}</option>{% endfor %}
|
<option selected="" value="" disabled>{{ _("Year") }}</option>
|
||||||
</select>
|
{% for y in year %}<option value="{{ y.0 }}">{{ y.0 }}</option>{% endfor %}
|
||||||
<select class="form-select form-control-sm me-1 car_status"
|
</select>
|
||||||
name="car_status"
|
<select class="form-select form-control-sm me-1 car_status"
|
||||||
aria-label="Default select example">
|
name="car_status"
|
||||||
<option selected="" value="">{{ _("All") }}</option>
|
aria-label="Default select example">
|
||||||
<option value="available">{{ _("Available") }}</option>
|
<option selected="" value="">{{ _("All") }}</option>
|
||||||
<option value="reserved">{{ _("Reserved") }}</option>
|
<option value="available">{{ _("Available") }}</option>
|
||||||
<option value="sold">{{ _("Sold") }}</option>
|
<option value="reserved">{{ _("Reserved") }}</option>
|
||||||
<option value="transfer">{{ _("Transfer") }}</option>
|
<option value="sold">{{ _("Sold") }}</option>
|
||||||
</select>
|
<option value="transfer">{{ _("Transfer") }}</option>
|
||||||
<button id="search"
|
</select>
|
||||||
hx-get="{% url 'car_list' request.dealer.slug %}"
|
<button id="search"
|
||||||
hx-include=".make,.model,.year,.car_status"
|
hx-get="{% url 'car_list' request.dealer.slug %}"
|
||||||
hx-indicator=".htmx-indicator"
|
hx-include=".make,.model,.year,.car_status"
|
||||||
hx-target=".table-responsive1"
|
hx-indicator=".htmx-indicator"
|
||||||
hx-select=".table-responsive1"
|
hx-target=".table-responsive1"
|
||||||
hx-swap="outerHTML show:window:top"
|
hx-select=".table-responsive1"
|
||||||
class="btn btn-sm btn-phoenix-primary ms-1"
|
hx-swap="outerHTML show:window:top"
|
||||||
hx-on::before-request="filter_before_request()"
|
class="btn btn-sm btn-phoenix-primary ms-1"
|
||||||
hx-on::after-request="filter_after_request()">{{ _("Search") }}</button>
|
hx-on::before-request="filter_before_request()"
|
||||||
</div>
|
hx-on::after-request="filter_after_request()">{{ _("Search") }}</button>
|
||||||
<div class="table-responsive1 scrollbar">
|
</div>
|
||||||
<div class="d-flex flex-wrap align-items-center justify-content-between py-3 pe-0 fs-9">
|
<div class="table-responsive1 scrollbar">
|
||||||
<div class="d-flex"
|
<div class="d-flex flex-wrap align-items-center justify-content-between py-3 pe-0 fs-9">
|
||||||
hx-boost="false"
|
<div class="d-flex"
|
||||||
hx-push-url="false"
|
hx-boost="false"
|
||||||
hx-include=".make,.model,.year,.car_status"
|
hx-push-url="false"
|
||||||
hx-target=".table-responsive"
|
hx-include=".make,.model,.year,.car_status"
|
||||||
hx-select=".table-responsive"
|
hx-target=".table-responsive"
|
||||||
hx-swap="innerHTML show:window:top"
|
hx-select=".table-responsive"
|
||||||
hx-indicator=".htmx-indicator"
|
hx-swap="innerHTML show:window:top"
|
||||||
hx-on::before-request="on_before_request()"
|
hx-indicator=".htmx-indicator"
|
||||||
hx-on::after-request="on_after_request()"></div>
|
hx-on::before-request="on_before_request()"
|
||||||
<div class="w-100 list table-responsive">
|
hx-on::after-request="on_after_request()"></div>
|
||||||
{% for car in cars %}
|
<div class="w-100 list table-responsive">
|
||||||
<div class="card border mb-3 py-0 px-0" id="project-list-table-body">
|
{% for car in cars %}
|
||||||
<div class="card-body">
|
<div class="card border mb-3 py-0 px-0" id="project-list-table-body">
|
||||||
<div class="row align-items-center">
|
<div class="card-body">
|
||||||
|
<div class="row align-items-center">
|
||||||
<!-- Vehicle Image/Icon -->
|
<!-- Vehicle Image/Icon -->
|
||||||
<div class="col-auto">
|
<div class="col-auto">
|
||||||
<div class="avatar avatar-3xl">
|
<div class="avatar avatar-3xl">
|
||||||
<img class="rounded-soft shadow shadow-lg"
|
<img class="rounded-soft shadow shadow-lg"
|
||||||
src="{% static 'images/car_images/' %}{{ car.get_hash }}.png"
|
src="{% static 'images/car_images/' %}{{ car.get_hash }}.png"
|
||||||
alt="{{ car.vin }}" />
|
alt="{{ car.vin }}" />
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
<!-- Vehicle Details -->
|
<!-- Vehicle Details -->
|
||||||
<div class="col">
|
<div class="col">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<!-- Make/Model/Specs -->
|
<!-- Make/Model/Specs -->
|
||||||
<div class="col-md-4">
|
<div class="col-md-4">
|
||||||
<h5 class="text-body-emphasis fw-bold">{{ car.year }}</h5>
|
<h5 class="text-body-emphasis fw-bold">{{ car.year }}</h5>
|
||||||
<p class="text-body-emphasis fw-bold">
|
<p class="text-body-emphasis fw-bold">
|
||||||
<a href="{% url 'car_detail' request.dealer.slug car.slug %}"
|
<a href="{% url 'car_detail' request.dealer.slug car.slug %}"
|
||||||
class="text-decoration-none text-body-emphasis">
|
class="text-decoration-none text-body-emphasis">
|
||||||
{{ car.id_car_make.get_local_name }}
|
{{ car.id_car_make.get_local_name }}
|
||||||
</a>
|
</a>
|
||||||
<small>{{ car.id_car_model.get_local_name }}</small>
|
<small>{{ car.id_car_model.get_local_name }}</small>
|
||||||
</p>
|
</p>
|
||||||
<small class="text-body-secondary" dir="ltr">{{ car.id_car_trim }}</small>
|
<small class="text-body-secondary" dir="ltr">{{ car.id_car_trim }}</small>
|
||||||
</div>
|
|
||||||
<!-- Color and Date -->
|
|
||||||
<div class="col-md-3">
|
|
||||||
<p class="text-body mb-1">{{ car.colors.exterior.get_local_name }}</p>
|
|
||||||
<small class="text-body-secondary">{{ car.receiving_date|naturalday|capfirst }}</small>
|
|
||||||
</div>
|
|
||||||
<!-- Status Badge -->
|
|
||||||
<div class="col-md-3">
|
|
||||||
{% if car.status == "available" %}
|
|
||||||
<span class="badge badge-phoenix fs-10 badge-phoenix-success text-uppercase px-3 py-2">{{ _("Available") }}</span>
|
|
||||||
{% elif car.status == "reserved" %}
|
|
||||||
<span class="badge badge-phoenix fs-10 badge-phoenix-warning text-uppercase px-3 py-2">{{ _("Reserved") }}</span>
|
|
||||||
{% elif car.status == "sold" %}
|
|
||||||
<span class="badge badge-phoenix fs-10 badge-phoenix-danger text-uppercase px-3 py-2">{{ _("Sold") }}</span>
|
|
||||||
{% elif car.status == "transfer" %}
|
|
||||||
<span class="badge badge-phoenix fs-10 badge-phoenix-info text-uppercase px-3 py-2">{{ _("Transfer") }}</span>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
<!-- Ready Status -->
|
|
||||||
<div class="col-md-2">
|
|
||||||
<div class="d-flex align-items-center">
|
|
||||||
<span class="fs-10 fw-light me-2">{{ _("Inventory Ready") }}</span>
|
|
||||||
{% if car.ready %}
|
|
||||||
<span class="badge bg-success rounded-circle p-1 me-2">
|
|
||||||
<span class="visually-hidden">{% trans "Ready" %}</span>
|
|
||||||
</span>
|
|
||||||
<span class="text-success fw-bold">{{ _("Yes") }}</span>
|
|
||||||
{% else %}
|
|
||||||
<span class="badge bg-danger rounded-circle p-1 me-2">
|
|
||||||
<span class="visually-hidden">{% trans "Not Ready" %}</span>
|
|
||||||
</span>
|
|
||||||
<span class="text-danger fw-bold">{{ _("No") }}</span>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<!-- Color and Date -->
|
||||||
<!-- Action Menu -->
|
<div class="col-md-3">
|
||||||
<div class="col-auto">
|
<p class="text-body mb-1">{{ car.colors.exterior.get_local_name }}</p>
|
||||||
<div class="btn-reveal-trigger position-static">
|
<small class="text-body-secondary">{{ car.receiving_date|naturalday|capfirst }}</small>
|
||||||
<button class="btn btn-sm dropdown-toggle dropdown-caret-none transition-none btn-reveal fs-10"
|
</div>
|
||||||
type="button"
|
<!-- Status Badge -->
|
||||||
data-bs-toggle="dropdown"
|
<div class="col-md-3">
|
||||||
data-boundary="window"
|
{% if car.status == "available" %}
|
||||||
aria-haspopup="true"
|
<span class="badge badge-phoenix fs-10 badge-phoenix-success text-uppercase px-3 py-2">{{ _("Available") }}</span>
|
||||||
aria-expanded="false"
|
{% elif car.status == "reserved" %}
|
||||||
data-bs-reference="parent">
|
<span class="badge badge-phoenix fs-10 badge-phoenix-warning text-uppercase px-3 py-2">{{ _("Reserved") }}</span>
|
||||||
<span class="fas fa-ellipsis-h fs-10"></span>
|
{% elif car.status == "sold" %}
|
||||||
</button>
|
<span class="badge badge-phoenix fs-10 badge-phoenix-danger text-uppercase px-3 py-2">{{ _("Sold") }}</span>
|
||||||
<div class="dropdown-menu dropdown-menu-end py-2">
|
{% elif car.status == "transfer" %}
|
||||||
<a class="dropdown-item"
|
<span class="badge badge-phoenix fs-10 badge-phoenix-info text-uppercase px-3 py-2">{{ _("Transfer") }}</span>
|
||||||
href="{% url 'car_detail' request.dealer.slug car.slug %}"> <span class="fas fa-eye me-2"></span>{{ _("View") }} </a>
|
{% endif %}
|
||||||
{% if perms.inventory.change_car and not car.status == 'sold' %}
|
</div>
|
||||||
<a class="dropdown-item"
|
<!-- Ready Status -->
|
||||||
href="{% url 'car_update' request.dealer.slug car.slug %}"> <span class="fas fa-edit me-2"></span>{{ _("Edit") }} </a>
|
<div class="col-md-2">
|
||||||
{% endif %}
|
<div class="d-flex align-items-center">
|
||||||
{% if perms.inventory.delete_car and not car.status == 'sold' %}
|
<span class="fs-10 fw-light me-2">{{ _("Inventory Ready") }}</span>
|
||||||
<div class="dropdown-divider"></div>
|
{% if car.ready %}
|
||||||
<a class="dropdown-item text-danger"
|
<span class="badge bg-success rounded-circle p-1 me-2">
|
||||||
href="{% url 'car_delete' request.dealer.slug car.slug %}"> <span class="fas fa-trash me-2"></span>{{ _("Remove") }} </a>
|
<span class="visually-hidden">{% trans "Ready" %}</span>
|
||||||
|
</span>
|
||||||
|
<span class="text-success fw-bold">{{ _("Yes") }}</span>
|
||||||
|
{% else %}
|
||||||
|
<span class="badge bg-danger rounded-circle p-1 me-2">
|
||||||
|
<span class="visually-hidden">{% trans "Not Ready" %}</span>
|
||||||
|
</span>
|
||||||
|
<span class="text-danger fw-bold">{{ _("No") }}</span>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<!-- Action Menu -->
|
||||||
|
<div class="col-auto">
|
||||||
|
<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>
|
||||||
|
<div class="dropdown-menu dropdown-menu-end py-2">
|
||||||
|
<a class="dropdown-item"
|
||||||
|
href="{% url 'car_detail' request.dealer.slug car.slug %}"> <span class="fas fa-eye me-2"></span>{{ _("View") }} </a>
|
||||||
|
{% if perms.inventory.change_car and not car.status == 'sold' %}
|
||||||
|
<a class="dropdown-item"
|
||||||
|
href="{% url 'car_update' request.dealer.slug car.slug %}"> <span class="fas fa-edit me-2"></span>{{ _("Edit") }} </a>
|
||||||
|
{% endif %}
|
||||||
|
{% if perms.inventory.delete_car and not car.status == 'sold' %}
|
||||||
|
<div class="dropdown-divider"></div>
|
||||||
|
<a class="dropdown-item text-danger"
|
||||||
|
href="{% url 'car_delete' request.dealer.slug car.slug %}"> <span class="fas fa-trash me-2"></span>{{ _("Remove") }} </a>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% empty %}
|
</div>
|
||||||
<div class="text-center py-5">
|
{% empty %}
|
||||||
<div class="text-body-secondary">
|
<div class="text-center py-5">
|
||||||
<span class="fas fa-car fa-4x mb-3 opacity-50"></span>
|
<div class="text-body-secondary">
|
||||||
<h4 class="text-body-secondary">{{ _("No vehicles found") }}</h4>
|
<span class="fas fa-car fa-4x mb-3 opacity-50"></span>
|
||||||
<p class="text-body-tertiary">{{ _("Try adjusting your search criteria or filters") }}</p>
|
<h4 class="text-body-secondary">{{ _("No vehicles found") }}</h4>
|
||||||
</div>
|
<p class="text-body-tertiary">{{ _("Try adjusting your search criteria or filters") }}</p>
|
||||||
</div>
|
</div>
|
||||||
{% endfor %}
|
</div>
|
||||||
</div>
|
{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
{% if page_obj.paginator.num_pages > 1 %}
|
|
||||||
<div class="d-flex justify-content-end mt-3">
|
|
||||||
<div class="d-flex">{% include 'partials/pagination.html' %}</div>
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
</div>
|
||||||
|
{% if page_obj.paginator.num_pages > 1 %}
|
||||||
|
<div class="d-flex justify-content-end mt-3">
|
||||||
|
<div class="d-flex">{% include 'partials/pagination.html' %}</div>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
{% block customJS%}
|
{% block customJS%}
|
||||||
<script>
|
<script>
|
||||||
function toggle_filter() {
|
function toggle_filter() {
|
||||||
const filterContainer = document.querySelector('.filter');
|
const filterContainer = document.querySelector('.filter');
|
||||||
filterContainer.classList.toggle('d-none');
|
filterContainer.classList.toggle('d-none');
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
@ -45,7 +45,7 @@
|
|||||||
#065535
|
#065535
|
||||||
#000000
|
#000000
|
||||||
#133337
|
#133337
|
||||||
#ffc0cb</a>
|
#ffc0cb</a>
|
||||||
<br>
|
<br>
|
||||||
<span class="glyphicon glyphicon-star"></span>707
|
<span class="glyphicon glyphicon-star"></span>707
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -3,7 +3,7 @@
|
|||||||
{% load static %}
|
{% load static %}
|
||||||
{% load custom_filters %}
|
{% load custom_filters %}
|
||||||
{% block title %}
|
{% block title %}
|
||||||
{% trans "Track Inventory" %}
|
{% trans "Track Inventory" %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div class="container-fluid px-4 py-4">
|
<div class="container-fluid px-4 py-4">
|
||||||
|
|||||||
@ -184,145 +184,145 @@
|
|||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
</main>
|
</main>
|
||||||
{% else %}
|
{% else %}
|
||||||
<div class="button-row">
|
<div class="button-row">
|
||||||
<button id="download-pdf" class="btn btn-phoenix-primary">
|
<button id="download-pdf" class="btn btn-phoenix-primary">
|
||||||
<i class="fas fa-download"></i> {% trans 'Download transfer' %}
|
<i class="fas fa-download"></i> {% trans 'Download transfer' %}
|
||||||
</button>
|
</button>
|
||||||
<button id="accept"
|
<button id="accept"
|
||||||
class="btn btn-phoenix-success"
|
class="btn btn-phoenix-success"
|
||||||
data-bs-toggle="modal"
|
data-bs-toggle="modal"
|
||||||
data-bs-target="#acceptModal">
|
data-bs-target="#acceptModal">
|
||||||
<i class="fas fa-check-circle"></i> {% trans 'Accept transfer' %}
|
<i class="fas fa-check-circle"></i> {% trans 'Accept transfer' %}
|
||||||
</button>
|
</button>
|
||||||
<button id="reject"
|
<button id="reject"
|
||||||
class="btn btn-phoenix-danger"
|
class="btn btn-phoenix-danger"
|
||||||
data-bs-toggle="modal"
|
data-bs-toggle="modal"
|
||||||
data-bs-target="#rejectModal">
|
data-bs-target="#rejectModal">
|
||||||
<i class="fas fa-times-circle"></i> {% trans 'Reject transfer' %}
|
<i class="fas fa-times-circle"></i> {% trans 'Reject transfer' %}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<!-- Accept Modal -->
|
<!-- Accept Modal -->
|
||||||
<div class="modal fade"
|
<div class="modal fade"
|
||||||
id="acceptModal"
|
id="acceptModal"
|
||||||
tabindex="-1"
|
tabindex="-1"
|
||||||
aria-labelledby="acceptModalLabel"
|
aria-labelledby="acceptModalLabel"
|
||||||
aria-hidden="true">
|
aria-hidden="true">
|
||||||
<div class="modal-dialog">
|
<div class="modal-dialog">
|
||||||
<div class="modal-content">
|
<div class="modal-content">
|
||||||
<div class="modal-header">
|
<div class="modal-header">
|
||||||
<h5 class="modal-title" id="acceptModalLabel">{% trans 'Accept transfer' %}</h5>
|
<h5 class="modal-title" id="acceptModalLabel">{% trans 'Accept transfer' %}</h5>
|
||||||
<button type="button"
|
<button type="button"
|
||||||
class="btn-close"
|
class="btn-close"
|
||||||
data-bs-dismiss="modal"
|
data-bs-dismiss="modal"
|
||||||
aria-label="Close"></button>
|
aria-label="Close"></button>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-body">{% trans 'Are you sure you want to accept this transfer?' %}</div>
|
<div class="modal-body">{% trans 'Are you sure you want to accept this transfer?' %}</div>
|
||||||
<div class="modal-footer">
|
<div class="modal-footer">
|
||||||
<button type="button"
|
<button type="button"
|
||||||
class="btn btn-phoenix-secondary"
|
class="btn btn-phoenix-secondary"
|
||||||
data-bs-dismiss="modal">{% trans 'Cancel' %}</button>
|
data-bs-dismiss="modal">{% trans 'Cancel' %}</button>
|
||||||
<a class="btn btn-phoenix-success"
|
<a class="btn btn-phoenix-success"
|
||||||
href="{% url 'transfer_accept_reject' transfer.car.pk transfer.pk %}?status=accepted">{% trans "Confirm" %}</a>
|
href="{% url 'transfer_accept_reject' transfer.car.pk transfer.pk %}?status=accepted">{% trans "Confirm" %}</a>
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
<!-- Reject Modal -->
|
<!-- Reject Modal -->
|
||||||
<div class="modal fade"
|
<div class="modal fade"
|
||||||
id="rejectModal"
|
id="rejectModal"
|
||||||
tabindex="-1"
|
tabindex="-1"
|
||||||
aria-labelledby="rejectModalLabel"
|
aria-labelledby="rejectModalLabel"
|
||||||
aria-hidden="true">
|
aria-hidden="true">
|
||||||
<div class="modal-dialog">
|
<div class="modal-dialog">
|
||||||
<div class="modal-content">
|
<div class="modal-content">
|
||||||
<div class="modal-header">
|
<div class="modal-header">
|
||||||
<h5 class="modal-title" id="rejectModalLabel">{% trans 'Reject transfer' %}</h5>
|
<h5 class="modal-title" id="rejectModalLabel">{% trans 'Reject transfer' %}</h5>
|
||||||
<button type="button"
|
<button type="button"
|
||||||
class="btn-close"
|
class="btn-close"
|
||||||
data-bs-dismiss="modal"
|
data-bs-dismiss="modal"
|
||||||
aria-label="Close"></button>
|
aria-label="Close"></button>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-body">{% trans 'Are you sure you want to reject this transfer?' %}</div>
|
<div class="modal-body">{% trans 'Are you sure you want to reject this transfer?' %}</div>
|
||||||
<div class="modal-footer">
|
<div class="modal-footer">
|
||||||
<button type="button"
|
<button type="button"
|
||||||
class="btn btn-phoenix-secondary"
|
class="btn btn-phoenix-secondary"
|
||||||
data-bs-dismiss="modal">{% trans 'Cancel' %}</button>
|
data-bs-dismiss="modal">{% trans 'Cancel' %}</button>
|
||||||
<a class="btn btn-phoenix-success"
|
<a class="btn btn-phoenix-success"
|
||||||
href="{% url 'transfer_accept_reject' transfer.car.pk transfer.pk %}?status=rejected">{% trans "Confirm" %}</a>
|
href="{% url 'transfer_accept_reject' transfer.car.pk transfer.pk %}?status=rejected">{% trans "Confirm" %}</a>
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="transfer-row" id="transfer-content">
|
</div>
|
||||||
|
<div class="transfer-row" id="transfer-content">
|
||||||
<!-- Header -->
|
<!-- Header -->
|
||||||
<div class="transfer-header">
|
<div class="transfer-header">
|
||||||
<svg width="101"
|
<svg width="101"
|
||||||
height="24"
|
height="24"
|
||||||
viewBox="0 0 101 24"
|
viewBox="0 0 101 24"
|
||||||
fill="none"
|
fill="none"
|
||||||
xmlns="http://www.w3.org/2000/svg">
|
xmlns="http://www.w3.org/2000/svg">
|
||||||
<!-- SVG Paths -->
|
<!-- SVG Paths -->
|
||||||
</svg>
|
</svg>
|
||||||
<h1 style="margin-top: 10px;">
|
<h1 style="margin-top: 10px;">
|
||||||
<b>{% trans "Transfer" %}</b>
|
<b>{% trans "Transfer" %}</b>
|
||||||
</h1>
|
</h1>
|
||||||
<p>{% trans "Thank you for choosing us. We appreciate your business" %}</p>
|
<p>{% trans "Thank you for choosing us. We appreciate your business" %}</p>
|
||||||
</div>
|
|
||||||
<!-- Details -->
|
|
||||||
<div class="transfer-details">
|
|
||||||
<p>
|
|
||||||
<strong>{% trans "Date" %} :</strong> {{ transfer.created_at }}
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
<strong>{% trans "From" %} :</strong> {{ transfer.from_dealer }}
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
<strong>{% trans "To" %} :</strong> {{ transfer.to_dealer }}
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<!-- Items Table -->
|
|
||||||
<div class="transfer-table">
|
|
||||||
<table class="table table-bordered">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th>{% trans "Item" %}</th>
|
|
||||||
<th class="text-center">{% trans "Quantity" %}</th>
|
|
||||||
<th class="text-center">{% trans "Unit Price" %}</th>
|
|
||||||
<th class="text-center">{% trans "Total" %}</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
<tr>
|
|
||||||
<td>{{ transfer.car }}</td>
|
|
||||||
<td class="text-center">{{ transfer.quantity }}</td>
|
|
||||||
<td class="text-center">{{ transfer.car.selling_price }}</td>
|
|
||||||
<td class="text-center">{{ transfer.total_price }}</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
<!-- Total -->
|
|
||||||
<div class="transfer-total">
|
|
||||||
<p>
|
|
||||||
<strong>{% trans "Total Amount" %}:</strong> <span class="highlight">${{ transfer.total_price }}</span>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<!-- Footer Note -->
|
|
||||||
<div class="footer-note">
|
|
||||||
<p>
|
|
||||||
{% trans "If you have any questions, feel free to contact us at" %} <a href="mailto:support@example.com">support@tenhal.com</a>.
|
|
||||||
</p>
|
|
||||||
<p>{% trans "Thank you for your business" %}</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
<!-- Details -->
|
||||||
|
<div class="transfer-details">
|
||||||
|
<p>
|
||||||
|
<strong>{% trans "Date" %} :</strong> {{ transfer.created_at }}
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<strong>{% trans "From" %} :</strong> {{ transfer.from_dealer }}
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<strong>{% trans "To" %} :</strong> {{ transfer.to_dealer }}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<!-- Items Table -->
|
||||||
|
<div class="transfer-table">
|
||||||
|
<table class="table table-bordered">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>{% trans "Item" %}</th>
|
||||||
|
<th class="text-center">{% trans "Quantity" %}</th>
|
||||||
|
<th class="text-center">{% trans "Unit Price" %}</th>
|
||||||
|
<th class="text-center">{% trans "Total" %}</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td>{{ transfer.car }}</td>
|
||||||
|
<td class="text-center">{{ transfer.quantity }}</td>
|
||||||
|
<td class="text-center">{{ transfer.car.selling_price }}</td>
|
||||||
|
<td class="text-center">{{ transfer.total_price }}</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<!-- Total -->
|
||||||
|
<div class="transfer-total">
|
||||||
|
<p>
|
||||||
|
<strong>{% trans "Total Amount" %}:</strong> <span class="highlight">${{ transfer.total_price }}</span>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<!-- Footer Note -->
|
||||||
|
<div class="footer-note">
|
||||||
|
<p>
|
||||||
|
{% trans "If you have any questions, feel free to contact us at" %} <a href="mailto:support@example.com">support@tenhal.com</a>.
|
||||||
|
</p>
|
||||||
|
<p>{% trans "Thank you for your business" %}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
<!-- Bootstrap JS (Optional) -->
|
<!-- Bootstrap JS (Optional) -->
|
||||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
|
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
|
||||||
<!-- jsPDF Library -->
|
<!-- jsPDF Library -->
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/2.5.1/jspdf.umd.min.js"></script>
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/2.5.1/jspdf.umd.min.js"></script>
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/html2pdf.js/0.10.1/html2pdf.bundle.min.js"></script>
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/html2pdf.js/0.10.1/html2pdf.bundle.min.js"></script>
|
||||||
<script>
|
<script>
|
||||||
document.getElementById('download-pdf').addEventListener('click', function () {
|
document.getElementById('download-pdf').addEventListener('click', function () {
|
||||||
const element = document.getElementById('transfer-content');
|
const element = document.getElementById('transfer-content');
|
||||||
|
|
||||||
@ -353,6 +353,6 @@
|
|||||||
// Handle the reject action here
|
// Handle the reject action here
|
||||||
$('#rejectModal').modal('hide');
|
$('#rejectModal').modal('hide');
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@ -7,91 +7,91 @@
|
|||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
|
|
||||||
<section class="hero-section text-center py-5">
|
<section class="hero-section text-center py-5">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<h1 class="display-4 fw-bold text-primary">{{ expense.name|title }}</h1>
|
<h1 class="display-4 fw-bold text-primary">{{ expense.name|title }}</h1>
|
||||||
<p class="lead text-muted">{% trans "Comprehensive details for your expense." %}</p>
|
<p class="lead text-muted">{% trans "Comprehensive details for your expense." %}</p>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<div class="container my-5">
|
<div class="container my-5">
|
||||||
<div class="row justify-content-center">
|
<div class="row justify-content-center">
|
||||||
<div class="col-md-11">
|
<div class="col-md-11">
|
||||||
<div class="card shadow-lg border-0 rounded-4">
|
<div class="card shadow-lg border-0 rounded-4">
|
||||||
<div class="card-body p-4 p-md-5">
|
<div class="card-body p-4 p-md-5">
|
||||||
|
|
||||||
<h2 class="h4 fw-bold mb-4">{% trans "Expense Information" %} <span class="fs-7 ms-3"><a class="btn btn-phoenix-secondary" href="{% url 'item_expense_list' request.dealer.slug %}">Back To List</a></span></h2>
|
<h2 class="h4 fw-bold mb-4">{% trans "Expense Information" %} <span class="fs-7 ms-3"><a class="btn btn-phoenix-secondary" href="{% url 'item_expense_list' request.dealer.slug %}">Back To List</a></span></h2>
|
||||||
|
|
||||||
<div class="row row-cols-1 row-cols-md-2 row-cols-lg-4 g-4 text-center text-md-start mb-5">
|
<div class="row row-cols-1 row-cols-md-2 row-cols-lg-4 g-4 text-center text-md-start mb-5">
|
||||||
<div class="col">
|
<div class="col">
|
||||||
<h6 class="text-uppercase text-muted small mb-1">SKU</h6>
|
<h6 class="text-uppercase text-muted small mb-1">SKU</h6>
|
||||||
<p class="fw-bold ">{{ expense.sku|default:"N/A" }}</p>
|
<p class="fw-bold ">{{ expense.sku|default:"N/A" }}</p>
|
||||||
|
</div>
|
||||||
|
<div class="col">
|
||||||
|
<h6 class="text-uppercase text-muted small mb-1">UPC</h6>
|
||||||
|
<p class="fw-bold ">{{ expense.upc|default:"N/A" }}</p>
|
||||||
|
</div>
|
||||||
|
<div class="col">
|
||||||
|
<h6 class="text-uppercase text-muted small mb-1">{% trans "Default Amount" %}</h6>
|
||||||
|
<p class="fw-bold">{{ expense.default_amount }}<span class="icon-saudi_riyal ms-1"></span></p>
|
||||||
|
</div>
|
||||||
|
<div class="col">
|
||||||
|
<h6 class="text-uppercase text-muted small mb-1">{% trans "Expense Account" %}</h6>
|
||||||
|
<p class="fw-boldBI">{{ expense.expense_account }}</p>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col">
|
|
||||||
<h6 class="text-uppercase text-muted small mb-1">UPC</h6>
|
|
||||||
<p class="fw-bold ">{{ expense.upc|default:"N/A" }}</p>
|
|
||||||
</div>
|
|
||||||
<div class="col">
|
|
||||||
<h6 class="text-uppercase text-muted small mb-1">{% trans "Default Amount" %}</h6>
|
|
||||||
<p class="fw-bold">{{ expense.default_amount }}<span class="icon-saudi_riyal ms-1"></span></p>
|
|
||||||
</div>
|
|
||||||
<div class="col">
|
|
||||||
<h6 class="text-uppercase text-muted small mb-1">{% trans "Expense Account" %}</h6>
|
|
||||||
<p class="fw-boldBI">{{ expense.expense_account }}</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<hr class="my-5">
|
<hr class="my-5">
|
||||||
|
|
||||||
<h2 class="h4 fw-bold mb-4">{% trans "Associated Bills" %}</h2>
|
|
||||||
|
|
||||||
|
|
||||||
{% if page_obj %}
|
<h2 class="h4 fw-bold mb-4">{% trans "Associated Bills" %}</h2>
|
||||||
<div class="table-responsive">
|
|
||||||
<table class="table table-hover align-middle">
|
|
||||||
<thead class="table-light">
|
{% if page_obj %}
|
||||||
<tr>
|
<div class="table-responsive">
|
||||||
<th scope="col">{% trans "Bill Number" %}</th>
|
<table class="table table-hover align-middle">
|
||||||
<th scope="col" class="text-center">{% trans "Status" %}</th>
|
<thead class="table-light">
|
||||||
<th scope="col" class="text-center">{% trans "Vendor" %}</th>
|
|
||||||
<th scope="col" class="text-center">{% trans "Terms" %}</th>
|
|
||||||
<th scope="col" class="text-center">{% trans "Created On" %}</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
{% for bill in page_obj%}
|
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<th scope="col">{% trans "Bill Number" %}</th>
|
||||||
<a href="{% url 'bill-detail' dealer_slug=request.dealer.slug entity_slug=entity.slug bill_pk=bill.pk %}" class="fw-bold text-decoration-none">
|
<th scope="col" class="text-center">{% trans "Status" %}</th>
|
||||||
{{ bill.bill_number }}
|
<th scope="col" class="text-center">{% trans "Vendor" %}</th>
|
||||||
</a>
|
<th scope="col" class="text-center">{% trans "Terms" %}</th>
|
||||||
</td>
|
<th scope="col" class="text-center">{% trans "Created On" %}</th>
|
||||||
|
|
||||||
<td class="text-center">
|
|
||||||
<span class="">{{ bill.get_bill_status_display }}</span>
|
|
||||||
</td>
|
|
||||||
<td class="text-center">{{ bill.vendor }}</td>
|
|
||||||
<td class="text-center">{{ bill.get_terms_display }}</td>
|
|
||||||
<td class="text-center">{{ bill.created|date:"M j, Y" }}</td>
|
|
||||||
</tr>
|
</tr>
|
||||||
{% endfor %}
|
</thead>
|
||||||
</tbody>
|
<tbody>
|
||||||
</table>
|
{% for bill in page_obj%}
|
||||||
|
<tr>
|
||||||
</div>
|
<td>
|
||||||
|
<a href="{% url 'bill-detail' dealer_slug=request.dealer.slug entity_slug=entity.slug bill_pk=bill.pk %}" class="fw-bold text-decoration-none">
|
||||||
|
{{ bill.bill_number }}
|
||||||
|
</a>
|
||||||
|
</td>
|
||||||
|
|
||||||
|
<td class="text-center">
|
||||||
|
<span class="">{{ bill.get_bill_status_display }}</span>
|
||||||
|
</td>
|
||||||
|
<td class="text-center">{{ bill.vendor }}</td>
|
||||||
|
<td class="text-center">{{ bill.get_terms_display }}</td>
|
||||||
|
<td class="text-center">{{ bill.created|date:"M j, Y" }}</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
</div>
|
||||||
{% if page_obj.paginator.num_pages > 1 %}
|
{% if page_obj.paginator.num_pages > 1 %}
|
||||||
<div class="d-flex justify-content-end mt-3">
|
<div class="d-flex justify-content-end mt-3">
|
||||||
<div class="d-flex">{% include 'partials/pagination.html' %}</div>
|
<div class="d-flex">{% include 'partials/pagination.html' %}</div>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% else %}
|
{% else %}
|
||||||
<div class="alert alert-info text-center py-4">
|
<div class="alert alert-info text-center py-4">
|
||||||
{% trans "No bills are associated with this expense yet." %}
|
{% trans "No bills are associated with this expense yet." %}
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|||||||
@ -5,7 +5,7 @@
|
|||||||
{% endblock title %}
|
{% endblock title %}
|
||||||
{% block content %}
|
{% block content %}
|
||||||
{% if expenses or request.GET.q %}
|
{% if expenses or request.GET.q %}
|
||||||
|
|
||||||
<div class="row mt-4">
|
<div class="row mt-4">
|
||||||
<div class="d-flex justify-content-between mb-2">
|
<div class="d-flex justify-content-between mb-2">
|
||||||
<h3 class="">
|
<h3 class="">
|
||||||
@ -51,10 +51,10 @@
|
|||||||
href="{% url 'item_expense_update' request.dealer.slug expense.pk %}">
|
href="{% url 'item_expense_update' request.dealer.slug expense.pk %}">
|
||||||
<i class="fa fa-edit me-2"></i>{% trans "Update" %}
|
<i class="fa fa-edit me-2"></i>{% trans "Update" %}
|
||||||
</a>
|
</a>
|
||||||
<a class="text-primary dropdown-item" href="{% url 'bill-create' request.dealer.slug request.entity.slug %}">
|
<a class="text-primary dropdown-item" href="{% url 'bill-create' request.dealer.slug request.entity.slug %}">
|
||||||
<i class="fa fa-plus me-2"></i>{% trans "Create Expense Bill" %}
|
<i class="fa fa-plus me-2"></i>{% trans "Create Expense Bill" %}
|
||||||
</a>
|
</a>
|
||||||
<a class="text-info dropdown-item" href="{% url 'item_expense_detail' request.dealer.slug expense.pk %}">
|
<a class="text-info dropdown-item" href="{% url 'item_expense_detail' request.dealer.slug expense.pk %}">
|
||||||
<i class="fa fa-eye me-2"></i>{% trans "Expense Detail" %}
|
<i class="fa fa-eye me-2"></i>{% trans "Expense Detail" %}
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -7,60 +7,60 @@
|
|||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
|
|
||||||
<section class="hero-section text-center py-5">
|
<section class="hero-section text-center py-5">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<h1 class="display-5 fw-bold">{{ service.name|title }}</h1>
|
<h1 class="display-5 fw-bold">{{ service.name|title }}</h1>
|
||||||
<p class=" mt-3">{{ service.description|default:"No description provided." }}</p>
|
<p class=" mt-3">{{ service.description|default:"No description provided." }}</p>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section class="py-5">
|
<section class="py-5">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
|
|
||||||
<div class="card mb-5 p-4 p-lg-5">
|
|
||||||
<div class="card-body">
|
|
||||||
|
|
||||||
<h2 class="card-title fw-bold mb-4">{% trans "Service Details" %}</h2>
|
<div class="card mb-5 p-4 p-lg-5">
|
||||||
|
<div class="card-body">
|
||||||
|
|
||||||
<div class="row g-4 mb-3">
|
|
||||||
<div class="col-lg-8"><a class="btn btn-phoenix-primary me-1" href="{% url 'item_service_update' request.dealer.slug service.pk %}"> Edit</a></div>
|
|
||||||
<div class="col-lg-4"><a class="btn btn-phoenix-secondary mb-2" href="{% url 'item_service_list' request.dealer.slug %}">Back To List</a></div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row g-4 text-center text-md-start">
|
<h2 class="card-title fw-bold mb-4">{% trans "Service Details" %}</h2>
|
||||||
|
|
||||||
<div class="col-md-4">
|
|
||||||
<h6 class="text-uppercase text-muted small mb-1">{% trans 'Service Name' %}</h6>
|
<div class="row g-4 mb-3">
|
||||||
<p class="fw-bold fs-7 mb-0">{{ service.name|capfirst }}</p>
|
<div class="col-lg-8"><a class="btn btn-phoenix-primary me-1" href="{% url 'item_service_update' request.dealer.slug service.pk %}"> Edit</a></div>
|
||||||
|
<div class="col-lg-4"><a class="btn btn-phoenix-secondary mb-2" href="{% url 'item_service_list' request.dealer.slug %}">Back To List</a></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="col-md-4">
|
<div class="row g-4 text-center text-md-start">
|
||||||
<h6 class="text-uppercase text-muted small mb-1">{% trans 'Price' %}</h6>
|
|
||||||
<p class="fw-bold fs-7 mb-0">{{ service.price }}<span class="icon-saudi_riyal ms-1"></span></p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="col-md-2">
|
<div class="col-md-4">
|
||||||
<h6 class="text-uppercase text-muted small mb-1">{% trans 'Unit of Measure' %}</h6>
|
<h6 class="text-uppercase text-muted small mb-1">{% trans 'Service Name' %}</h6>
|
||||||
<p class="fw-bold fs-7 mb-0">{{ service.get_uom_display }}</p>
|
<p class="fw-bold fs-7 mb-0">{{ service.name|capfirst }}</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="col-md-4">
|
||||||
|
<h6 class="text-uppercase text-muted small mb-1">{% trans 'Price' %}</h6>
|
||||||
|
<p class="fw-bold fs-7 mb-0">{{ service.price }}<span class="icon-saudi_riyal ms-1"></span></p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-md-2">
|
||||||
|
<h6 class="text-uppercase text-muted small mb-1">{% trans 'Unit of Measure' %}</h6>
|
||||||
|
<p class="fw-bold fs-7 mb-0">{{ service.get_uom_display }}</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-md-2">
|
||||||
|
<h6 class="text-uppercase text-muted small mb-1">{% trans 'Tax Status' %}</h6>
|
||||||
|
<p class="fw-bold fs-7 mb-0">{% if service.taxable %}{% trans 'Taxable' %}{% else %}{% trans 'Non Taxable' %}{% endif %}</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="col-md-2">
|
|
||||||
<h6 class="text-uppercase text-muted small mb-1">{% trans 'Tax Status' %}</h6>
|
|
||||||
<p class="fw-bold fs-7 mb-0">{% if service.taxable %}{% trans 'Taxable' %}{% else %}{% trans 'Non Taxable' %}{% endif %}</p>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="text-center my-5 py-5 border rounded-3 p-4">
|
<div class="text-center my-5 py-5 border rounded-3 p-4">
|
||||||
<h2 class="fw-bold text-muted mb-4">{% trans "Total Revenue from this service" %}</h2>
|
<h2 class="fw-bold text-muted mb-4">{% trans "Total Revenue from this service" %}</h2>
|
||||||
<p class="display-5 fw-bold mb-0 text-primary">{{ total_services_price }}<span class="icon-saudi_riyal ms-4"></span></p>
|
<p class="display-5 fw-bold mb-0 text-primary">{{ total_services_price }}<span class="icon-saudi_riyal ms-4"></span></p>
|
||||||
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
</section>
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|||||||
@ -56,26 +56,26 @@
|
|||||||
<i class="fa fa-trash me-2"></i>{% trans "Delete" %}
|
<i class="fa fa-trash me-2"></i>{% trans "Delete" %}
|
||||||
</a> {% endcomment %}
|
</a> {% endcomment %}
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
{% empty %}
|
{% empty %}
|
||||||
<tr>
|
<tr>
|
||||||
<td colspan="6" class="text-center text-muted">{% trans "No Accounts Found" %}</td>
|
<td colspan="6" class="text-center text-muted">{% trans "No Accounts Found" %}</td>
|
||||||
</tr>
|
</tr>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
</div>
|
||||||
|
{% if page_obj.paginator.num_pages > 1 %}
|
||||||
|
<div class="d-flex justify-content-end mt-3">
|
||||||
|
<div class="d-flex">{% include 'partials/pagination.html' %}</div>
|
||||||
</div>
|
</div>
|
||||||
{% if page_obj.paginator.num_pages > 1 %}
|
|
||||||
<div class="d-flex justify-content-end mt-3">
|
|
||||||
<div class="d-flex">{% include 'partials/pagination.html' %}</div>
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
{% endif %}
|
||||||
{% else %}
|
</div>
|
||||||
{% url 'bank_account_create' request.dealer.slug as create_bank_account_url %}
|
{% else %}
|
||||||
{% include "empty-illustration-page.html" with value="bank account" url=create_bank_account_url %}
|
{% url 'bank_account_create' request.dealer.slug as create_bank_account_url %}
|
||||||
{% endif %}
|
{% include "empty-illustration-page.html" with value="bank account" url=create_bank_account_url %}
|
||||||
{% endblock %}
|
{% endif %}
|
||||||
|
{% endblock %}
|
||||||
|
|||||||
@ -41,55 +41,57 @@
|
|||||||
<td class="align-middle product white-space-nowrap">
|
<td class="align-middle product white-space-nowrap">
|
||||||
{% if bill.is_draft %}
|
{% if bill.is_draft %}
|
||||||
<span class="badge badge-phoenix badge-phoenix-warning">
|
<span class="badge badge-phoenix badge-phoenix-warning">
|
||||||
{% elif bill.is_review %}
|
{% elif bill.is_review %}
|
||||||
<span class="badge badge-phoenix badge-phoenix-info">
|
<span class="badge badge-phoenix badge-phoenix-info">
|
||||||
{% elif bill.is_approved %}
|
{% elif bill.is_approved %}
|
||||||
<span class="badge badge-phoenix badge-phoenix-success">
|
<span class="badge badge-phoenix badge-phoenix-success">
|
||||||
{% elif bill.is_paid %}
|
{% elif bill.is_paid %}
|
||||||
<span class="badge badge-phoenix badge-phoenix-success">
|
<span class="badge badge-phoenix badge-phoenix-success">
|
||||||
{% elif bill.is_canceled %}
|
{% elif bill.is_canceled %}
|
||||||
<span class="badge badge-phoenix badge-phoenix-danger">
|
<span class="badge badge-phoenix badge-phoenix-danger">
|
||||||
{% endif %}
|
{% elif bill.is_void %}
|
||||||
{{ bill.bill_status }}
|
<span class="badge badge-phoenix badge-phoenix-secondary">
|
||||||
</span>
|
{% endif %}
|
||||||
</td>
|
{{ bill.bill_status }}
|
||||||
<td class="align-middle product white-space-nowrap">{{ bill.vendor.vendor_name }}</td>
|
</span>
|
||||||
<td class="align-middle product white-space-nowrap">
|
</td>
|
||||||
{% if perms.django_ledger.view_billmodel %}
|
<td class="align-middle product white-space-nowrap">{{ bill.vendor.vendor_name }}</td>
|
||||||
<div class="btn-reveal-trigger position-static">
|
<td class="align-middle product white-space-nowrap">
|
||||||
<button class="btn btn-sm dropdown-toggle dropdown-caret-none transition-none btn-reveal fs-10"
|
{% if perms.django_ledger.view_billmodel %}
|
||||||
type="button"
|
<div class="btn-reveal-trigger position-static">
|
||||||
data-bs-toggle="dropdown"
|
<button class="btn btn-sm dropdown-toggle dropdown-caret-none transition-none btn-reveal fs-10"
|
||||||
data-boundary="window"
|
type="button"
|
||||||
aria-haspopup="true"
|
data-bs-toggle="dropdown"
|
||||||
aria-expanded="false"
|
data-boundary="window"
|
||||||
data-bs-reference="parent">
|
aria-haspopup="true"
|
||||||
<span class="fas fa-ellipsis-h fs-10"></span>
|
aria-expanded="false"
|
||||||
</button>
|
data-bs-reference="parent">
|
||||||
<div class="dropdown-menu dropdown-menu-end py-2">
|
<span class="fas fa-ellipsis-h fs-10"></span>
|
||||||
<a href="{% url 'bill-detail' dealer_slug=request.dealer.slug entity_slug=entity.slug bill_pk=bill.pk %}"
|
</button>
|
||||||
class="dropdown-item text-success-dark">{% trans 'View' %}</a>
|
<div class="dropdown-menu dropdown-menu-end py-2">
|
||||||
</div>
|
<a href="{% url 'bill-detail' dealer_slug=request.dealer.slug entity_slug=entity.slug bill_pk=bill.pk %}"
|
||||||
</div>
|
class="dropdown-item text-success-dark">{% trans 'View' %}</a>
|
||||||
{% endif %}
|
</div>
|
||||||
</td>
|
</div>
|
||||||
</tr>
|
{% endif %}
|
||||||
{% empty %}
|
</td>
|
||||||
<tr>
|
</tr>
|
||||||
<td colspan="5" class="text-center text-muted">{% trans 'No bill found.' %}</td>
|
{% empty %}
|
||||||
</tr>
|
<tr>
|
||||||
{% endfor %}
|
<td colspan="5" class="text-center text-muted">{% trans 'No bill found.' %}</td>
|
||||||
</tbody>
|
</tr>
|
||||||
</table>
|
{% endfor %}
|
||||||
</div>
|
</tbody>
|
||||||
{% if page_obj.paginator.num_pages > 1 %}
|
</table>
|
||||||
<div class="d-flex justify-content-end mt-3">
|
</div>
|
||||||
<div class="d-flex">{% include 'partials/pagination.html' %}</div>
|
{% if page_obj.paginator.num_pages > 1 %}
|
||||||
</div>
|
<div class="d-flex justify-content-end mt-3">
|
||||||
{% endif %}
|
<div class="d-flex">{% include 'partials/pagination.html' %}</div>
|
||||||
</div>
|
</div>
|
||||||
{% else %}
|
{% endif %}
|
||||||
{% url "bill-create" request.dealer.slug request.entity.slug as create_bill_url %}
|
</div>
|
||||||
{% include "empty-illustration-page.html" with value="bill" url=create_bill_url %}
|
{% else %}
|
||||||
{% endif %}
|
{% url "bill-create" request.dealer.slug request.entity.slug as create_bill_url %}
|
||||||
{% endblock %}
|
{% include "empty-illustration-page.html" with value="bill" url=create_bill_url %}
|
||||||
|
{% endif %}
|
||||||
|
{% endblock %}
|
||||||
|
|||||||
@ -136,24 +136,24 @@
|
|||||||
{% if perms.django_ledger.change_chartofaccountmodel %}
|
{% if perms.django_ledger.change_chartofaccountmodel %}
|
||||||
<a class="btn btn-sm btn-phoenix-primary me-1"
|
<a class="btn btn-sm btn-phoenix-primary me-1"
|
||||||
href="{% url 'account_update' request.dealer.slug url_kwargs.coa_pk account.pk %}">
|
href="{% url 'account_update' request.dealer.slug url_kwargs.coa_pk account.pk %}">
|
||||||
<i class="fa-solid fa-pen-to-square"></i> {{ _("Edit") }}
|
<i class="fa-solid fa-pen-to-square"></i> {{ _("Edit") }}
|
||||||
</a>
|
</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if perms.django_ledger.delete_chartofaccountmodel %}
|
{% if perms.django_ledger.delete_chartofaccountmodel %}
|
||||||
<a class="btn btn-sm btn-phoenix-danger me-1"
|
<a class="btn btn-sm btn-phoenix-danger me-1"
|
||||||
data-bs-toggle="modal"
|
data-bs-toggle="modal"
|
||||||
data-bs-target="#deleteModal">
|
data-bs-target="#deleteModal">
|
||||||
|
|
||||||
<i class="fa-solid fa-trash"></i> {{ _("Delete") }}
|
<i class="fa-solid fa-trash"></i> {{ _("Delete") }}
|
||||||
</a>
|
</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<a class="btn btn-sm btn-phoenix-secondary"
|
<a class="btn btn-sm btn-phoenix-secondary"
|
||||||
href="{% url 'account_list' request.dealer.slug url_kwargs.coa_pk %}">
|
href="{% url 'account_list' request.dealer.slug url_kwargs.coa_pk %}">
|
||||||
|
|
||||||
<i class="fa-regular fa-circle-left"></i> {% trans 'Back to COA List' %}
|
<i class="fa-regular fa-circle-left"></i> {% trans 'Back to COA List' %}
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!--test-->
|
<!--test-->
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|||||||
@ -20,7 +20,7 @@
|
|||||||
{% else %}
|
{% else %}
|
||||||
{% trans "Add New Account" %}
|
{% trans "Add New Account" %}
|
||||||
<i class="fa-solid fa-book ms-2"></i>
|
<i class="fa-solid fa-book ms-2"></i>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</h3>
|
</h3>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-body p-4 p-md-5">
|
<div class="card-body p-4 p-md-5">
|
||||||
|
|||||||
@ -10,194 +10,194 @@
|
|||||||
</a>
|
</a>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div class="row mt-4">
|
<div class="row mt-4">
|
||||||
<div class="d-flex justify-content-between mb-2">
|
<div class="d-flex justify-content-between mb-2">
|
||||||
<h3 class="">
|
<h3 class="">
|
||||||
{% trans "Accounts" %}<i class="fa-solid fa-book ms-2 text-primary"></i>
|
{% trans "Accounts" %}<i class="fa-solid fa-book ms-2 text-primary"></i>
|
||||||
</h3>
|
</h3>
|
||||||
{% if perms.django_ledger.add_chartofaccountmodel %}
|
{% if perms.django_ledger.add_chartofaccountmodel %}
|
||||||
<a href="{% url 'account_create' request.dealer.slug url_kwargs.coa_pk %}"
|
<a href="{% url 'account_create' request.dealer.slug url_kwargs.coa_pk %}"
|
||||||
class="btn btn-md btn-phoenix-primary"><i class="fa fa-plus me-2"></i>{% trans 'New Account' %}</a>
|
class="btn btn-md btn-phoenix-primary"><i class="fa fa-plus me-2"></i>{% trans 'New Account' %}</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
<!-- Account Type Tabs -->
|
<!-- Account Type Tabs -->
|
||||||
<div class="mb-4">
|
<div class="mb-4">
|
||||||
<ul class="nav nav-tabs" id="accountTypeTabs" role="tablist">
|
<ul class="nav nav-tabs" id="accountTypeTabs" role="tablist">
|
||||||
<li class="nav-item" role="presentation">
|
<li class="nav-item" role="presentation">
|
||||||
<button class="nav-link active"
|
<button class="nav-link active"
|
||||||
id="assets-tab"
|
id="assets-tab"
|
||||||
data-bs-toggle="tab"
|
data-bs-toggle="tab"
|
||||||
data-bs-target="#assets"
|
data-bs-target="#assets"
|
||||||
type="button"
|
type="button"
|
||||||
role="tab"
|
role="tab"
|
||||||
aria-controls="assets"
|
aria-controls="assets"
|
||||||
aria-selected="true">
|
aria-selected="true">
|
||||||
<i class="fas fa-wallet me-2"></i>{% trans "Assets" %}
|
<i class="fas fa-wallet me-2"></i>{% trans "Assets" %}
|
||||||
</button>
|
</button>
|
||||||
</li>
|
</li>
|
||||||
<li class="nav-item" role="presentation">
|
<li class="nav-item" role="presentation">
|
||||||
<button class="nav-link"
|
<button class="nav-link"
|
||||||
id="cogs-tab"
|
id="cogs-tab"
|
||||||
data-bs-toggle="tab"
|
data-bs-toggle="tab"
|
||||||
data-bs-target="#cogs"
|
data-bs-target="#cogs"
|
||||||
type="button"
|
type="button"
|
||||||
role="tab"
|
role="tab"
|
||||||
aria-controls="cogs"
|
aria-controls="cogs"
|
||||||
aria-selected="false">
|
aria-selected="false">
|
||||||
<i class="fas fa-boxes me-2"></i>{% trans "COGS" %}
|
<i class="fas fa-boxes me-2"></i>{% trans "COGS" %}
|
||||||
</button>
|
</button>
|
||||||
</li>
|
</li>
|
||||||
<li class="nav-item" role="presentation">
|
<li class="nav-item" role="presentation">
|
||||||
<button class="nav-link"
|
<button class="nav-link"
|
||||||
id="capital-tab"
|
id="capital-tab"
|
||||||
data-bs-toggle="tab"
|
data-bs-toggle="tab"
|
||||||
data-bs-target="#capital"
|
data-bs-target="#capital"
|
||||||
type="button"
|
type="button"
|
||||||
role="tab"
|
role="tab"
|
||||||
aria-controls="capital"
|
aria-controls="capital"
|
||||||
aria-selected="false">
|
aria-selected="false">
|
||||||
<i class="fas fa-landmark me-2"></i>{% trans "Capital" %}
|
<i class="fas fa-landmark me-2"></i>{% trans "Capital" %}
|
||||||
</button>
|
</button>
|
||||||
</li>
|
</li>
|
||||||
<li class="nav-item" role="presentation">
|
<li class="nav-item" role="presentation">
|
||||||
<button class="nav-link"
|
<button class="nav-link"
|
||||||
id="income-tab"
|
id="income-tab"
|
||||||
data-bs-toggle="tab"
|
data-bs-toggle="tab"
|
||||||
data-bs-target="#income"
|
data-bs-target="#income"
|
||||||
type="button"
|
type="button"
|
||||||
role="tab"
|
role="tab"
|
||||||
aria-controls="income"
|
aria-controls="income"
|
||||||
aria-selected="false">
|
aria-selected="false">
|
||||||
<i class="fas fa-money-bill-wave me-2"></i>{% trans "Income" %}
|
<i class="fas fa-money-bill-wave me-2"></i>{% trans "Income" %}
|
||||||
</button>
|
</button>
|
||||||
</li>
|
</li>
|
||||||
<li class="nav-item" role="presentation">
|
<li class="nav-item" role="presentation">
|
||||||
<button class="nav-link"
|
<button class="nav-link"
|
||||||
id="expenses-tab"
|
id="expenses-tab"
|
||||||
data-bs-toggle="tab"
|
data-bs-toggle="tab"
|
||||||
data-bs-target="#expenses"
|
data-bs-target="#expenses"
|
||||||
type="button"
|
type="button"
|
||||||
role="tab"
|
role="tab"
|
||||||
aria-controls="expenses"
|
aria-controls="expenses"
|
||||||
aria-selected="false">
|
aria-selected="false">
|
||||||
<i class="fas fa-receipt me-2"></i>{% trans "Expenses" %}
|
<i class="fas fa-receipt me-2"></i>{% trans "Expenses" %}
|
||||||
</button>
|
</button>
|
||||||
</li>
|
</li>
|
||||||
<li class="nav-item" role="presentation">
|
<li class="nav-item" role="presentation">
|
||||||
<button class="nav-link"
|
<button class="nav-link"
|
||||||
id="liabilities-tab"
|
id="liabilities-tab"
|
||||||
data-bs-toggle="tab"
|
data-bs-toggle="tab"
|
||||||
data-bs-target="#liabilities"
|
data-bs-target="#liabilities"
|
||||||
type="button"
|
type="button"
|
||||||
role="tab"
|
role="tab"
|
||||||
aria-controls="liabilities"
|
aria-controls="liabilities"
|
||||||
aria-selected="false">
|
aria-selected="false">
|
||||||
<i class="fas fa-receipt me-2"></i>{% trans "Liabilities" %}
|
<i class="fas fa-receipt me-2"></i>{% trans "Liabilities" %}
|
||||||
</button>
|
</button>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<div class="tab-content p-3 border border-top-0 rounded-bottom"
|
<div class="tab-content p-3 border border-top-0 rounded-bottom"
|
||||||
id="accountTypeTabsContent">
|
id="accountTypeTabsContent">
|
||||||
<!-- Assets Tab -->
|
<!-- Assets Tab -->
|
||||||
<div class="tab-pane fade show active"
|
<div class="tab-pane fade show active"
|
||||||
id="assets"
|
id="assets"
|
||||||
role="tabpanel"
|
role="tabpanel"
|
||||||
aria-labelledby="assets-tab">
|
aria-labelledby="assets-tab">
|
||||||
{% include "partials/search_box.html" %}
|
{% include "partials/search_box.html" %}
|
||||||
{% with accounts=accounts|filter_by_role:"asset_" %}
|
{% with accounts=accounts|filter_by_role:"asset_" %}
|
||||||
{% include "ledger/coa_accounts/partials/account_table.html" %}
|
{% include "ledger/coa_accounts/partials/account_table.html" %}
|
||||||
{% endwith %}
|
{% endwith %}
|
||||||
</div>
|
</div>
|
||||||
<!-- COGS Tab -->
|
<!-- COGS Tab -->
|
||||||
<div class="tab-pane fade"
|
<div class="tab-pane fade"
|
||||||
id="cogs"
|
id="cogs"
|
||||||
role="tabpanel"
|
role="tabpanel"
|
||||||
aria-labelledby="cogs-tab">
|
aria-labelledby="cogs-tab">
|
||||||
{% include "partials/search_box.html" %}
|
{% include "partials/search_box.html" %}
|
||||||
{% with accounts=accounts|filter_by_role:"cogs" %}
|
{% with accounts=accounts|filter_by_role:"cogs" %}
|
||||||
{% include "ledger/coa_accounts/partials/account_table.html" %}
|
{% include "ledger/coa_accounts/partials/account_table.html" %}
|
||||||
{% endwith %}
|
{% endwith %}
|
||||||
</div>
|
</div>
|
||||||
<!-- Capital Tab -->
|
<!-- Capital Tab -->
|
||||||
<div class="tab-pane fade"
|
<div class="tab-pane fade"
|
||||||
id="capital"
|
id="capital"
|
||||||
role="tabpanel"
|
role="tabpanel"
|
||||||
aria-labelledby="capital-tab">
|
aria-labelledby="capital-tab">
|
||||||
{% include "partials/search_box.html" %}
|
{% include "partials/search_box.html" %}
|
||||||
{% with accounts=accounts|filter_by_role:"eq_" %}
|
{% with accounts=accounts|filter_by_role:"eq_" %}
|
||||||
{% include "ledger/coa_accounts/partials/account_table.html" %}
|
{% include "ledger/coa_accounts/partials/account_table.html" %}
|
||||||
{% endwith %}
|
{% endwith %}
|
||||||
</div>
|
</div>
|
||||||
<!-- Income Tab -->
|
<!-- Income Tab -->
|
||||||
<div class="tab-pane fade"
|
<div class="tab-pane fade"
|
||||||
id="income"
|
id="income"
|
||||||
role="tabpanel"
|
role="tabpanel"
|
||||||
aria-labelledby="income-tab">
|
aria-labelledby="income-tab">
|
||||||
{% include "partials/search_box.html" %}
|
{% include "partials/search_box.html" %}
|
||||||
{% with accounts=accounts|filter_by_role:"in_" %}
|
{% with accounts=accounts|filter_by_role:"in_" %}
|
||||||
{% include "ledger/coa_accounts/partials/account_table.html" %}
|
{% include "ledger/coa_accounts/partials/account_table.html" %}
|
||||||
{% endwith %}
|
{% endwith %}
|
||||||
</div>
|
</div>
|
||||||
<!-- Expenses Tab -->
|
<!-- Expenses Tab -->
|
||||||
<div class="tab-pane fade"
|
<div class="tab-pane fade"
|
||||||
id="expenses"
|
id="expenses"
|
||||||
role="tabpanel"
|
role="tabpanel"
|
||||||
aria-labelledby="expenses-tab">
|
aria-labelledby="expenses-tab">
|
||||||
{% include "partials/search_box.html" %}
|
{% include "partials/search_box.html" %}
|
||||||
{% with accounts=accounts|filter_by_role:"ex_" %}
|
{% with accounts=accounts|filter_by_role:"ex_" %}
|
||||||
{% include "ledger/coa_accounts/partials/account_table.html" %}
|
{% include "ledger/coa_accounts/partials/account_table.html" %}
|
||||||
{% endwith %}
|
{% endwith %}
|
||||||
</div>
|
</div>
|
||||||
<!-- Liabilities Tab -->
|
<!-- Liabilities Tab -->
|
||||||
<div class="tab-pane fade"
|
<div class="tab-pane fade"
|
||||||
id="liabilities"
|
id="liabilities"
|
||||||
role="tabpanel"
|
role="tabpanel"
|
||||||
aria-labelledby="liabilities-tab">
|
aria-labelledby="liabilities-tab">
|
||||||
{% include "partials/search_box.html" %}
|
{% include "partials/search_box.html" %}
|
||||||
{% with accounts=accounts|filter_by_role:"lia_" %}
|
{% with accounts=accounts|filter_by_role:"lia_" %}
|
||||||
{% include "ledger/coa_accounts/partials/account_table.html" %}
|
{% include "ledger/coa_accounts/partials/account_table.html" %}
|
||||||
{% endwith %}
|
{% endwith %}
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
<!-- Delete Modal (moved outside tables) -->
|
<!-- Delete Modal (moved outside tables) -->
|
||||||
<div class="modal fade"
|
<div class="modal fade"
|
||||||
id="deleteModal"
|
id="deleteModal"
|
||||||
data-bs-backdrop="static"
|
data-bs-backdrop="static"
|
||||||
data-bs-keyboard="false"
|
data-bs-keyboard="false"
|
||||||
tabindex="-1"
|
tabindex="-1"
|
||||||
aria-labelledby="deleteModalLabel"
|
aria-labelledby="deleteModalLabel"
|
||||||
aria-hidden="true">
|
aria-hidden="true">
|
||||||
<div class="modal-dialog modal-sm">
|
<div class="modal-dialog modal-sm">
|
||||||
<div class="modal-content">
|
<div class="modal-content">
|
||||||
<div class="modal-header">
|
<div class="modal-header">
|
||||||
{% if perms.django_ledger.delete_chartofaccountmodel %}
|
{% if perms.django_ledger.delete_chartofaccountmodel %}
|
||||||
<h5 class="modal-title" id="deleteModalLabel">
|
<h5 class="modal-title" id="deleteModalLabel">
|
||||||
{% trans "Delete Account" %}
|
{% trans "Delete Account" %}
|
||||||
<span data-feather="alert-circle"></span>
|
<span data-feather="alert-circle"></span>
|
||||||
</h5>
|
</h5>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
<button type="button"
|
||||||
|
class="btn-close"
|
||||||
|
data-bs-dismiss="modal"
|
||||||
|
aria-label="Close"></button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body text-center">
|
||||||
|
<p class="mb-0 text-danger fw-bold">{% trans "Are you sure you want to delete this Account?" %}</p>
|
||||||
|
<div class="d-grid gap-2">
|
||||||
<button type="button"
|
<button type="button"
|
||||||
class="btn-close"
|
class="btn btn-phoenix-secondary btn-sm"
|
||||||
data-bs-dismiss="modal"
|
data-bs-dismiss="modal">{% trans "No" %}</button>
|
||||||
aria-label="Close"></button>
|
<a id="deleteAccountBtn"
|
||||||
</div>
|
type="button"
|
||||||
<div class="modal-body text-center">
|
class="btn btn-phoenix-danger btn-sm"
|
||||||
<p class="mb-0 text-danger fw-bold">{% trans "Are you sure you want to delete this Account?" %}</p>
|
href="#">{% trans "Yes" %}</a>
|
||||||
<div class="d-grid gap-2">
|
|
||||||
<button type="button"
|
|
||||||
class="btn btn-phoenix-secondary btn-sm"
|
|
||||||
data-bs-dismiss="modal">{% trans "No" %}</button>
|
|
||||||
<a id="deleteAccountBtn"
|
|
||||||
type="button"
|
|
||||||
class="btn btn-phoenix-danger btn-sm"
|
|
||||||
href="#">{% trans "Yes" %}</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
{% block customerJS %}
|
{% block customerJS %}
|
||||||
|
|||||||
@ -49,7 +49,7 @@
|
|||||||
<div class="dropdown-menu dropdown-menu-end py-2">
|
<div class="dropdown-menu dropdown-menu-end py-2">
|
||||||
<a href="{% url 'account_detail' request.dealer.slug url_kwargs.coa_pk account.uuid %}"
|
<a href="{% url 'account_detail' request.dealer.slug url_kwargs.coa_pk account.uuid %}"
|
||||||
class="dropdown-item text-success-dark">{% trans "View Journal Entries" %}</a>
|
class="dropdown-item text-success-dark">{% trans "View Journal Entries" %}</a>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
|
|||||||
@ -56,4 +56,4 @@
|
|||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|||||||
@ -3,7 +3,7 @@
|
|||||||
{% load static %}
|
{% load static %}
|
||||||
{% load crispy_forms_tags %}
|
{% load crispy_forms_tags %}
|
||||||
{% block title %}
|
{% block title %}
|
||||||
{% trans "Jorunal Entry Transactions" %}
|
{% trans "Jorunal Entry Transactions" %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div class="row justify-content-center">
|
<div class="row justify-content-center">
|
||||||
|
|||||||
@ -3,7 +3,7 @@
|
|||||||
{% load static %}
|
{% load static %}
|
||||||
{% load django_ledger %}
|
{% load django_ledger %}
|
||||||
{% block title %}
|
{% block title %}
|
||||||
{% trans 'ledger Detail' %}
|
{% trans 'ledger Detail' %}
|
||||||
{% endblock title %}
|
{% endblock title %}
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div class="row">
|
<div class="row">
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user