ui change for plans list and admin management to only show the admin user
This commit is contained in:
parent
2a292e546a
commit
d8650f3b09
@ -5,119 +5,128 @@ from plans.models import Plan, Quota, PlanQuota, Pricing, PlanPricing
|
||||
|
||||
|
||||
class Command(BaseCommand):
|
||||
help = "Create basic subscription plans structure"
|
||||
help = "Create basic subscription plans structure."
|
||||
|
||||
def add_arguments(self, parser):
|
||||
parser.add_argument(
|
||||
"--reset",
|
||||
action="store_true",
|
||||
help="Delete existing plans and quotas before creating new ones",
|
||||
help="Delete existing plans and quotas before creating new ones.",
|
||||
)
|
||||
|
||||
def handle(self, *args, **options):
|
||||
# Plan.objects.all().delete()
|
||||
# Quota.objects.all().delete()
|
||||
# PlanQuota.objects.all().delete()
|
||||
# Pricing.objects.all().delete()
|
||||
# PlanPricing.objects.all().delete()
|
||||
# UserPlan.objects.all().delete()
|
||||
# Order.objects.all().delete()
|
||||
# BillingInfo.objects.all().delete()
|
||||
if options["reset"]:
|
||||
self.stdout.write(self.style.WARNING("Resetting all plan-related data..."))
|
||||
Plan.objects.all().delete()
|
||||
Quota.objects.all().delete()
|
||||
Pricing.objects.all().delete()
|
||||
# Note: Deleting plans and quotas should cascade to related objects like PlanQuota and PlanPricing.
|
||||
self.stdout.write(self.style.SUCCESS("Data reset complete."))
|
||||
else:
|
||||
self.stdout.write(self.style.NOTICE("Creating or updating default plans and quotas..."))
|
||||
|
||||
users_quota = Quota.objects.create(
|
||||
name="Users", codename="Users", unit="number"
|
||||
# Create or get quotas
|
||||
users_quota, created_u = Quota.objects.get_or_create(
|
||||
codename="Users",
|
||||
defaults={"name": "Users", "unit": "number"}
|
||||
)
|
||||
cars_quota = Quota.objects.create(name="Cars", codename="Cars", unit="number")
|
||||
# Create plans
|
||||
basic_plan = Plan.objects.create(
|
||||
name="Basic", description="basic plan", available=True, visible=True
|
||||
if created_u:
|
||||
self.stdout.write(self.style.SUCCESS('Created quota: "Users"'))
|
||||
|
||||
cars_quota, created_c = Quota.objects.get_or_create(
|
||||
codename="Cars",
|
||||
defaults={"name": "Cars", "unit": "number"}
|
||||
)
|
||||
pro_plan = Plan.objects.create(
|
||||
name="Pro", description="Pro plan", available=True, visible=True
|
||||
if created_c:
|
||||
self.stdout.write(self.style.SUCCESS('Created quota: "Cars"'))
|
||||
|
||||
# Create or get plans
|
||||
basic_plan, created_bp = Plan.objects.get_or_create(
|
||||
name="Basic",
|
||||
defaults={"description": "basic plan", "available": True, "visible": True}
|
||||
)
|
||||
enterprise_plan = Plan.objects.create(
|
||||
if created_bp:
|
||||
self.stdout.write(self.style.SUCCESS('Created plan: "Basic"'))
|
||||
|
||||
pro_plan, created_pp = Plan.objects.get_or_create(
|
||||
name="Pro",
|
||||
defaults={"description": "Pro plan", "available": True, "visible": True}
|
||||
)
|
||||
if created_pp:
|
||||
self.stdout.write(self.style.SUCCESS('Created plan: "Pro"'))
|
||||
|
||||
enterprise_plan, created_ep = Plan.objects.get_or_create(
|
||||
name="Enterprise",
|
||||
description="Enterprise plan",
|
||||
available=True,
|
||||
visible=True,
|
||||
defaults={"description": "Enterprise plan", "available": True, "visible": True}
|
||||
)
|
||||
if created_ep:
|
||||
self.stdout.write(self.style.SUCCESS('Created plan: "Enterprise"'))
|
||||
|
||||
# Assign quotas to plans using get_or_create to prevent duplicates
|
||||
PlanQuota.objects.get_or_create(
|
||||
plan=basic_plan,
|
||||
quota=users_quota,
|
||||
defaults={"value": 10000000}
|
||||
)
|
||||
PlanQuota.objects.get_or_create(
|
||||
plan=basic_plan,
|
||||
quota=cars_quota,
|
||||
defaults={"value": 10000000}
|
||||
)
|
||||
|
||||
# Assign quotas to plans
|
||||
PlanQuota.objects.create(plan=basic_plan, quota=users_quota, value=10000000)
|
||||
PlanQuota.objects.create(plan=basic_plan, quota=cars_quota, value=10000000)
|
||||
|
||||
PlanQuota.objects.create(plan=pro_plan, quota=users_quota, value=10000000)
|
||||
PlanQuota.objects.create(plan=pro_plan, quota=cars_quota, value=10000000)
|
||||
|
||||
PlanQuota.objects.create(plan=enterprise_plan, quota=users_quota, value=10000000)
|
||||
PlanQuota.objects.create(plan=enterprise_plan, quota=cars_quota, value=10000000)
|
||||
|
||||
# PlanQuota.objects.create(plan=pro_plan, quota=project_quota, value=50)
|
||||
# PlanQuota.objects.create(plan=pro_plan, quota=storage_quota, value=100)
|
||||
|
||||
# Define pricing
|
||||
basic_pricing = Pricing.objects.create(name="3 Months", period=90)
|
||||
pro_pricing = Pricing.objects.create(name="6 Months", period=180)
|
||||
enterprise_pricing = Pricing.objects.create(name="1 Year", period=365)
|
||||
|
||||
PlanPricing.objects.create(
|
||||
plan=basic_plan, pricing=basic_pricing, price=Decimal("2997.00")
|
||||
# Pro plan quotas
|
||||
PlanQuota.objects.get_or_create(
|
||||
plan=pro_plan,
|
||||
quota=users_quota,
|
||||
defaults={"value": 10000000}
|
||||
)
|
||||
PlanPricing.objects.create(
|
||||
plan=pro_plan, pricing=pro_pricing, price=Decimal("5395.00")
|
||||
)
|
||||
PlanPricing.objects.create(
|
||||
plan=enterprise_plan, pricing=enterprise_pricing, price=Decimal("9590.00")
|
||||
PlanQuota.objects.get_or_create(
|
||||
plan=pro_plan,
|
||||
quota=cars_quota,
|
||||
defaults={"value": 10000000}
|
||||
)
|
||||
|
||||
# # Create quotas
|
||||
# project_quota = Quota.objects.create(name='projects', codename='projects', unit='projects')
|
||||
# storage_quota = Quota.objects.create(name='storage', codename='storage', unit='GB')
|
||||
# Enterprise plan quotas
|
||||
PlanQuota.objects.get_or_create(
|
||||
plan=enterprise_plan,
|
||||
quota=users_quota,
|
||||
defaults={"value": 10000000}
|
||||
)
|
||||
PlanQuota.objects.get_or_create(
|
||||
plan=enterprise_plan,
|
||||
quota=cars_quota,
|
||||
defaults={"value": 10000000}
|
||||
)
|
||||
|
||||
# # Create plans
|
||||
# basic_plan = Plan.objects.create(name='Basic', description='Basic plan', available=True, visible=True)
|
||||
# pro_plan = Plan.objects.create(name='Pro', description='Pro plan', available=True, visible=True)
|
||||
# Create or get pricing
|
||||
basic_pricing, created_bp_p = Pricing.objects.get_or_create(
|
||||
name="3 Months",
|
||||
defaults={"period": 90}
|
||||
)
|
||||
pro_pricing, created_pp_p = Pricing.objects.get_or_create(
|
||||
name="6 Months",
|
||||
defaults={"period": 180}
|
||||
)
|
||||
enterprise_pricing, created_ep_p = Pricing.objects.get_or_create(
|
||||
name="1 Year",
|
||||
defaults={"period": 365}
|
||||
)
|
||||
|
||||
# # Assign quotas to plans
|
||||
# PlanQuota.objects.create(plan=basic_plan, quota=project_quota, value=5)
|
||||
# PlanQuota.objects.create(plan=basic_plan, quota=storage_quota, value=10)
|
||||
# Assign pricing to plans
|
||||
PlanPricing.objects.get_or_create(
|
||||
plan=basic_plan,
|
||||
pricing=basic_pricing,
|
||||
defaults={"price": Decimal("2997.00")}
|
||||
)
|
||||
PlanPricing.objects.get_or_create(
|
||||
plan=pro_plan,
|
||||
pricing=pro_pricing,
|
||||
defaults={"price": Decimal("5395.00")}
|
||||
)
|
||||
PlanPricing.objects.get_or_create(
|
||||
plan=enterprise_plan,
|
||||
pricing=enterprise_pricing,
|
||||
defaults={"price": Decimal("9590.00")}
|
||||
)
|
||||
|
||||
# PlanQuota.objects.create(plan=pro_plan, quota=project_quota, value=50)
|
||||
# PlanQuota.objects.create(plan=pro_plan, quota=storage_quota, value=100)
|
||||
|
||||
# # Define pricing
|
||||
|
||||
# basic = Pricing.objects.create(name='Monthly', period=30)
|
||||
# pro = Pricing.objects.create(name='Monthly', period=30)
|
||||
|
||||
# basic_pricing = PlanPricing.objects.create(plan=basic_plan, pricing=basic, price=Decimal('19.99'))
|
||||
# pro_pricing = PlanPricing.objects.create(plan=pro_plan, pricing=pro, price=Decimal('29.99'))
|
||||
# Create users
|
||||
|
||||
# user = User.objects.first()
|
||||
|
||||
# # Create user plans
|
||||
# billing_info = BillingInfo.objects.create(
|
||||
# user=user,
|
||||
# tax_number='123456789',
|
||||
# name='John Doe',
|
||||
# street='123 Main St',
|
||||
# zipcode='12345',
|
||||
# city='Anytown',
|
||||
# country='US',
|
||||
# )
|
||||
|
||||
# order = Order.objects.create(
|
||||
# user=user,
|
||||
# plan=pro_plan,
|
||||
# pricing=pro_pricing,
|
||||
# amount=pro_pricing.price,
|
||||
# currency="SAR",
|
||||
# )
|
||||
|
||||
# UserPlan.objects.create(
|
||||
# user=user,
|
||||
# plan=pro_plan,
|
||||
# expire=timezone.now() + timedelta(days=2),
|
||||
# active=True,
|
||||
# )
|
||||
self.stdout.write(self.style.SUCCESS("Subscription plans structure successfully created or updated."))
|
||||
@ -1585,7 +1585,7 @@ def inventory_stats_view(request, dealer_slug):
|
||||
for make_data in inventory.values()
|
||||
],
|
||||
}
|
||||
return render(request, "inventory/inventory_stats.html", {"inventory": result})
|
||||
return render(request, "inventory/inventory_stats.html", {"inventory": result,"empty_state_value":_("car")})
|
||||
|
||||
|
||||
# @login_required
|
||||
@ -2450,6 +2450,7 @@ class CustomerListView(LoginRequiredMixin, PermissionRequiredMixin, ListView):
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super().get_context_data(**kwargs)
|
||||
context["query"] = self.request.GET.get("q", "")
|
||||
context["empty_state_value"] = _("customers")
|
||||
return context
|
||||
|
||||
|
||||
@ -3553,7 +3554,10 @@ class UserListView(LoginRequiredMixin, PermissionRequiredMixin, ListView):
|
||||
dealer = get_object_or_404(models.Dealer, slug=self.kwargs["dealer_slug"])
|
||||
staff = models.Staff.objects.filter(dealer=dealer, active=True).all()
|
||||
return apply_search_filters(staff, query)
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context=super().get_context_data(**kwargs)
|
||||
context['no_staff_message']=_("staff")
|
||||
return context
|
||||
|
||||
class UserDetailView(LoginRequiredMixin, PermissionRequiredMixin, DetailView):
|
||||
"""
|
||||
@ -3800,7 +3804,10 @@ class OrganizationListView(LoginRequiredMixin, PermissionRequiredMixin, ListView
|
||||
organization = dealer.organizations.filter(active=True)
|
||||
|
||||
return apply_search_filters(organization, query)
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context=super().get_context_data(**kwargs)
|
||||
context["empty_state_value"]=_("organization")
|
||||
return context
|
||||
|
||||
class OrganizationDetailView(LoginRequiredMixin, PermissionRequiredMixin, DetailView):
|
||||
"""
|
||||
@ -5020,6 +5027,10 @@ def create_estimate(request, dealer_slug, slug=None):
|
||||
],
|
||||
"opportunity_id": slug if slug else None,
|
||||
"customer_count": entity.get_customers().count(),
|
||||
"no_items_message": _("Please add at least one car or complete the car info before creating a quotation."),
|
||||
"no_items_button": _("Add car"),
|
||||
"no_customers_message": _("Please add at least one customer before creating a quotation."),
|
||||
"no_customers_button": _("Add Customer"),
|
||||
}
|
||||
|
||||
return render(request, "sales/estimates/estimate_form.html", context)
|
||||
@ -6168,6 +6179,10 @@ class LeadListView(LoginRequiredMixin, PermissionRequiredMixin, ListView):
|
||||
if self.request.is_staff:
|
||||
return qs.filter(staff=self.request.staff)
|
||||
return models.Lead.objects.none()
|
||||
def get_context_data(self, **kwargs):
|
||||
context=super().get_context_data(**kwargs)
|
||||
context['empty_state_value']=_("lead")
|
||||
return context
|
||||
|
||||
|
||||
class LeadDetailView(LoginRequiredMixin, PermissionRequiredMixin, DetailView):
|
||||
@ -6418,7 +6433,8 @@ def lead_tracking(request, dealer_slug):
|
||||
"won": won,
|
||||
"lose": lose,
|
||||
"negotiation": negotiation,
|
||||
"leads":leads
|
||||
"leads":leads,
|
||||
"empty_state_value": _("lead"),
|
||||
}
|
||||
return render(request, "crm/leads/lead_tracking.html", context)
|
||||
|
||||
@ -7471,6 +7487,7 @@ class OpportunityListView(LoginRequiredMixin, PermissionRequiredMixin, ListView)
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super().get_context_data(**kwargs)
|
||||
context["stage_choices"] = models.Stage.choices
|
||||
context["empty_state_value"] = _("opportunity")
|
||||
return context
|
||||
|
||||
def get_template_names(self):
|
||||
@ -10720,6 +10737,7 @@ class PurchaseOrderListView(LoginRequiredMixin, PermissionRequiredMixin, ListVie
|
||||
context = super().get_context_data(**kwargs)
|
||||
context["entity_slug"] = dealer.entity.slug
|
||||
context["vendors"] = vendors
|
||||
context["empty_state_value"] = _("purchase order")
|
||||
|
||||
return context
|
||||
|
||||
|
||||
@ -21,10 +21,11 @@
|
||||
</div>
|
||||
</a>
|
||||
<div class="text-center">
|
||||
<h3 class="text-body-highlight">{% trans 'Account Created Successfully' %}</h3>
|
||||
<h3 class="text-body-highlight">{% trans 'Registration Successful!' %}</h3>
|
||||
<p class="text-body-tertiary fs-9">
|
||||
{% blocktrans %}
|
||||
Thank you for registering at Haikal. We will contact you soon.
|
||||
|
||||
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 %}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@ -5,6 +5,7 @@
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
{% if request.user.is_superuser %}
|
||||
<div class="container py-5">
|
||||
<header class="mb-5">
|
||||
<h1 class="display-4 fw-bold">
|
||||
@ -12,7 +13,7 @@
|
||||
{% trans "Admin Dashboard" %}
|
||||
</h1>
|
||||
<p class="lead mt-3">
|
||||
{% trans "Manage user accounts, review system logs, and control access permissions." %}
|
||||
{% trans "Manage user accounts and review system logs." %}
|
||||
</p>
|
||||
</header>
|
||||
|
||||
@ -41,4 +42,5 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endblock content %}
|
||||
@ -258,6 +258,6 @@
|
||||
</div>
|
||||
{% else %}
|
||||
{% url 'lead_create' request.dealer.slug as create_lead_url %}
|
||||
{% include "empty-illustration-page.html" with value="lead" url=create_lead_url %}
|
||||
{% include "empty-illustration-page.html" with value=empty_state_value url=create_lead_url %}
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
@ -175,6 +175,6 @@
|
||||
</div>
|
||||
{% else %}
|
||||
{% url 'lead_create' request.dealer.slug as create_lead_url %}
|
||||
{% include "empty-illustration-page.html" with value="lead" url=create_lead_url %}
|
||||
{% include "empty-illustration-page.html" with value=empty_state_value url=create_lead_url %}
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
@ -118,7 +118,7 @@
|
||||
{% endif %}
|
||||
{% else %}
|
||||
{% url 'opportunity_create' request.dealer.slug as create_opportunity_url %}
|
||||
{% include "empty-illustration-page.html" with value="opportunity" url=create_opportunity_url %}
|
||||
{% include "empty-illustration-page.html" with value=empty_state_value url=create_opportunity_url %}
|
||||
{% endif %}
|
||||
{% block customJS %}
|
||||
<script>
|
||||
|
||||
@ -175,6 +175,6 @@
|
||||
{% include 'modal/delete_modal.html' %}
|
||||
{% else %}
|
||||
{% url "customer_create" request.dealer.slug as create_customer_url %}
|
||||
{% include "empty-illustration-page.html" with value="customer" url=create_customer_url %}
|
||||
{% include "empty-illustration-page.html" with value=empty_state_value url=create_customer_url %}
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
@ -81,7 +81,7 @@
|
||||
<div class="card-header "></div>
|
||||
<h4 class="my-4">{% trans "Permissions" %}</h4>
|
||||
<a class="btn btn-sm btn-phoenix-primary mt-2 mb-4"
|
||||
href="{% url 'group_permission' request.dealer.slug group.id %}"><i class="fa-solid fa-unlock"></i>{% trans "Manage Permissions" %}</a>
|
||||
href="{% url 'group_permission' request.dealer.slug group.id %}"><i class="fa-solid fa-unlock me-2"></i>{% trans "Manage Permissions" %}</a>
|
||||
<table class="table table-hover table-responsive-sm fs-9 mb-0">
|
||||
<thead>
|
||||
<tr>
|
||||
|
||||
@ -630,7 +630,7 @@
|
||||
{% endif %}
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
{% if request.is_dealer %}
|
||||
{% if request.user.is_superuser %}
|
||||
<a class="nav-link px-3 d-block"
|
||||
href="{% url 'management' request.dealer.slug %}"> <span class="me-2 text-body align-bottom" data-feather="shield"></span>{{ _("Admin Managemnet") }}</a>
|
||||
{% endif %}
|
||||
|
||||
@ -130,7 +130,7 @@
|
||||
{% else %}
|
||||
{% url "car_add" request.dealer.slug as create_car_url %}
|
||||
|
||||
{% include "empty-illustration-page.html" with value="car" url=create_car_url %}
|
||||
{% include "empty-illustration-page.html" with value=empty_state_value url=create_car_url %}
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
{% block customJS %}
|
||||
|
||||
@ -191,6 +191,6 @@
|
||||
</section>
|
||||
{% else %}
|
||||
{% url 'organization_create' request.dealer.slug as create_organization_url %}
|
||||
{% include "empty-illustration-page.html" with value="organization" url=create_organization_url %}
|
||||
{% include "empty-illustration-page.html" with value=empty_state_value url=create_organization_url %}
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
@ -2,38 +2,49 @@
|
||||
{% load i18n static %}
|
||||
{% block content %}
|
||||
<main class="main">
|
||||
<!-- Page Title -->
|
||||
<div class="page-title light-background">
|
||||
<div class="container d-lg-flex justify-content-between align-items-center">
|
||||
<h1 class="mb-2 mb-lg-0">{% trans "Payment Failed" %}</h1>
|
||||
<nav class="breadcrumbs">
|
||||
<ol>
|
||||
<li>
|
||||
<section class="py-4">
|
||||
<div class="container d-flex justify-content-between align-items-center">
|
||||
<h1 class="h3 mb-0 text-body-emphasis">{% trans "Payment Failed" %}</h1>
|
||||
<nav aria-label="breadcrumb">
|
||||
<ol class="breadcrumb mb-0">
|
||||
<li class="breadcrumb-item">
|
||||
<a href="{% url 'home' %}">{% trans "Home" %}</a>
|
||||
</li>
|
||||
<li class="current">{% trans "Failed" %}</li>
|
||||
<li class="breadcrumb-item active" aria-current="page">{% trans "Payment Failed" %}</li>
|
||||
</ol>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
<!-- End Page Title -->
|
||||
<!-- Failed Section -->
|
||||
<section class="section">
|
||||
<div class="container text-center" data-aos="fade-up">
|
||||
<div class="py-5">
|
||||
</section>
|
||||
|
||||
<section class="d-flex align-items-center justify-content-center py-5">
|
||||
<div class="container text-center" style="max-width: 32rem;">
|
||||
<div class="card p-5 shadow-sm border-0 rounded-4" data-aos="fade-up">
|
||||
<div class="card-body p-0">
|
||||
<div class="mb-4">
|
||||
<i class="bi bi-x-circle-fill text-danger" style="font-size: 5rem;"></i>
|
||||
<h2 class="mt-4">{% trans "Payment Failed" %}</h2>
|
||||
</div>
|
||||
|
||||
<h2 class="mt-4 mb-3 text-body-emphasis fw-bold">{% trans "Payment Failed" %}</h2>
|
||||
|
||||
{% if message %}
|
||||
<p class="lead">{{ message }}.</p>
|
||||
<p class="lead text-body-secondary">{{ message }}.</p>
|
||||
{% else %}
|
||||
<p class="lead">{% trans "We couldn't process your payment. Please try again" %}.</p>
|
||||
<p class="lead text-body-secondary">
|
||||
{% trans "We couldn't process your payment. Please review your information and try again." %}
|
||||
</p>
|
||||
{% endif %}
|
||||
<a href="{% url 'home' %}" class="btn btn-phoenix-primary mt-3">
|
||||
<i class="bi bi-house-door"></i> {% trans "Back to Home" %}
|
||||
|
||||
<div class="d-grid gap-3 col-md-8 mx-auto mt-4">
|
||||
<a href="{% url 'pricing_page' request.dealer.slug %}" class="btn btn-danger btn-lg rounded-pill">
|
||||
{% trans "Go Back and Try Again" %}
|
||||
</a>
|
||||
<a href="{% url 'home' %}" class="btn btn-link text-body-secondary text-decoration-none">
|
||||
{% trans "Back to Home" %}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<!-- /Failed Section -->
|
||||
</main>
|
||||
{% endblock content %}
|
||||
@ -1,40 +1,50 @@
|
||||
{% extends "base.html" %}
|
||||
{% load i18n static %}
|
||||
|
||||
{% block content %}
|
||||
<main class="main">
|
||||
<!-- Page Title -->
|
||||
<div class="page-title light-background">
|
||||
<div class="container d-lg-flex justify-content-between align-items-center">
|
||||
<h1 class="mb-2 mb-lg-0">{% trans "Payment Successful" %}</h1>
|
||||
<nav class="breadcrumbs">
|
||||
<ol>
|
||||
<li>
|
||||
<a href="{% url 'home' %}">{{ _("Home") }}</a>
|
||||
<section class="py-4">
|
||||
<div class="container d-flex justify-content-between align-items-center">
|
||||
<h1 class="h3 mb-0 text-body-emphasis">{% trans "Payment Successful" %}</h1>
|
||||
<nav aria-label="breadcrumb">
|
||||
<ol class="breadcrumb mb-0">
|
||||
<li class="breadcrumb-item">
|
||||
<a href="{% url 'home' %}">{% trans "Home" %}</a>
|
||||
</li>
|
||||
<li class="current">{{ _("Success") }}</li>
|
||||
<li class="breadcrumb-item active" aria-current="page">{% trans "Success" %}</li>
|
||||
</ol>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
<!-- End Page Title -->
|
||||
<!-- Success Section -->
|
||||
<section class="section">
|
||||
<div class="container text-center" data-aos="fade-up">
|
||||
<div class="py-5">
|
||||
</section>
|
||||
|
||||
<section class="d-flex align-items-center justify-content-center py-5">
|
||||
<div class="container text-center" style="max-width: 32rem;">
|
||||
<div class="card p-5 shadow-sm border-0 rounded-4" data-aos="fade-up">
|
||||
<div class="card-body p-0">
|
||||
<div class="mb-4">
|
||||
<i class="bi bi-check-circle-fill text-success" style="font-size: 5rem;"></i>
|
||||
<h2 class="mt-4">{{ _("Thank You") }}!</h2>
|
||||
<p class="lead">{{ _("Your payment was successful") }}. {{ _("Your order is being processed") }}.</p>
|
||||
</div>
|
||||
|
||||
<h2 class="mt-4 mb-3 text-body-emphasis fw-bold">{{ _("Thank You") }}!</h2>
|
||||
|
||||
<p class="lead text-body-secondary">
|
||||
{{ _("Your payment was successful") }}. {{ _("Your order is being processed") }}.
|
||||
</p>
|
||||
|
||||
<div class="d-grid gap-3 col-md-8 mx-auto mt-4">
|
||||
{% if invoice %}
|
||||
<a href="{% url 'invoice_preview_html' invoice.pk %}"
|
||||
class="btn btn-phoenix-primary mt-3"><i class="fas fa-eye"></i>
|
||||
{{ _("View Invoice") }}</a>
|
||||
class="btn btn-primary btn-lg rounded-pill">
|
||||
<i class="fas fa-eye me-2"></i> {{ _("View Invoice") }}
|
||||
</a>
|
||||
{% endif %}
|
||||
<a href="{% url 'home' %}" class="btn btn-phoenix-primary mt-3">
|
||||
<i class="fas fa-home"></i> {{ _("Back to Home") }}
|
||||
<a href="{% url 'home' %}" class="btn btn-link text-body-secondary text-decoration-none">
|
||||
<i class="fas fa-home me-2"></i> {{ _("Back to Home") }}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<!-- /Success Section -->
|
||||
</main>
|
||||
{% endblock content %}
|
||||
@ -52,6 +52,6 @@
|
||||
{% include "plans/pagination.html" %}
|
||||
{% endblock %}
|
||||
{% else %}
|
||||
{% blocktrans %}You do not have any orders so far.{% endblocktrans %}
|
||||
<p class="text-center">{% trans "You do not have any orders so far." %}<p>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
@ -4,96 +4,222 @@
|
||||
{% block title %}
|
||||
{% trans 'Upgrade Plan' %}
|
||||
{% endblock %}
|
||||
|
||||
{% block customCSS %}
|
||||
<link rel="stylesheet"
|
||||
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.0/css/all.min.css"
|
||||
integrity="sha512-X..."
|
||||
integrity="sha512-X... (Your actual integrity hash)"
|
||||
crossorigin="anonymous"
|
||||
referrerpolicy="no-referrer" />
|
||||
<style>
|
||||
.pricing-card .card {
|
||||
:root {
|
||||
--primary-color: #0d6efd;
|
||||
--primary-shadow: rgba(13, 110, 253, 0.25);
|
||||
--border-color: #e9ecef;
|
||||
--card-hover-shadow: rgba(0, 0, 0, 0.05);
|
||||
--card-selected-border: #0d6efd;
|
||||
--card-selected-shadow: rgba(13, 110, 253, 0.4);
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: #f8f9fa;
|
||||
}
|
||||
|
||||
.pricing-card-label {
|
||||
transition: all 0.2s ease-in-out;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.pricing-card-label .card {
|
||||
border: 2px solid var(--border-color);
|
||||
transition: all 0.3s ease-in-out;
|
||||
box-shadow: 0 4px 12px var(--card-hover-shadow);
|
||||
}
|
||||
|
||||
.pricing-card .card.selected {
|
||||
border-color:rgb(20, 108, 241);
|
||||
box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.4);
|
||||
.btn-check:checked + .pricing-card-label .card {
|
||||
border-color: var(--card-selected-border) !important;
|
||||
box-shadow: 0 0 0 0.25rem var(--card-selected-shadow) !important;
|
||||
}
|
||||
|
||||
.btn-check:checked + .btn .card {
|
||||
/* fallback if JS fails */
|
||||
border-color:rgb(13, 91, 207);
|
||||
box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.25);
|
||||
.btn-check:checked + .pricing-card-label .card:hover {
|
||||
transform: scale(1.02);
|
||||
}
|
||||
|
||||
.card.selected {
|
||||
border-color: #0d6efd;
|
||||
box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.4);
|
||||
.pricing-card-label .card:hover {
|
||||
box-shadow: 0 8px 20px var(--card-hover-shadow);
|
||||
transform: scale(1.01);
|
||||
}
|
||||
|
||||
.pricing-card-badge {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 1.5rem;
|
||||
transform: translateY(-50%);
|
||||
padding: 0.25rem 0.75rem;
|
||||
font-size: 0.8rem;
|
||||
font-weight: bold;
|
||||
color: white;
|
||||
background-color: var(--primary-color);
|
||||
border-radius: 1rem;
|
||||
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.progress-indicator {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
|
||||
.progress-indicator .step-item {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
position: relative;
|
||||
flex: 1;
|
||||
color: #6c757d;
|
||||
}
|
||||
|
||||
.progress-indicator .step-item .icon {
|
||||
width: 3rem;
|
||||
height: 3rem;
|
||||
border-radius: 50%;
|
||||
background-color: #e9ecef;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
font-size: 1.25rem;
|
||||
color: #6c757d;
|
||||
transition: all 0.3s;
|
||||
border: 2px solid #e9ecef;
|
||||
}
|
||||
|
||||
.progress-indicator .step-item.active .icon {
|
||||
background-color: var(--primary-color);
|
||||
color: white;
|
||||
border-color: var(--primary-color);
|
||||
}
|
||||
|
||||
.progress-indicator .step-item.completed .icon {
|
||||
background-color: #28a745;
|
||||
color: white;
|
||||
border-color: #28a745;
|
||||
}
|
||||
|
||||
.progress-indicator .step-item .step-text {
|
||||
margin-top: 0.5rem;
|
||||
font-size: 0.9rem;
|
||||
font-weight: 500;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.progress-indicator .line {
|
||||
height: 2px;
|
||||
width: 100%;
|
||||
background-color: #e9ecef;
|
||||
margin: 0 -1.5rem;
|
||||
position: relative;
|
||||
z-index: -1;
|
||||
}
|
||||
|
||||
.btn-phoenix-primary {
|
||||
background-color: var(--primary-color);
|
||||
color: white;
|
||||
border-color: var(--primary-color);
|
||||
transition: all 0.2s ease-in-out;
|
||||
}
|
||||
|
||||
.btn-phoenix-primary:hover {
|
||||
background-color: #0b5ed7;
|
||||
border-color: #0a58ca;
|
||||
}
|
||||
|
||||
.btn-phoenix-secondary {
|
||||
background-color: #6c757d;
|
||||
color: white;
|
||||
border-color: #6c757d;
|
||||
transition: all 0.2s ease-in-out;
|
||||
}
|
||||
|
||||
.btn-phoenix-secondary:hover {
|
||||
background-color: #5c636a;
|
||||
border-color: #565e64;
|
||||
}
|
||||
|
||||
.summary-box {
|
||||
border: 1px solid #8d8f94;
|
||||
border-radius: 0.5rem;
|
||||
padding: 1.5rem;
|
||||
background-color: #ffffff;
|
||||
border: 1px solid var(--border-color);
|
||||
border-radius: 0.75rem;
|
||||
padding: 2rem;
|
||||
box-shadow: 0 4px 15px rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
|
||||
.summary-box h5 {
|
||||
padding-bottom: 0.5rem;
|
||||
margin-bottom: 1rem;
|
||||
/* Validation styles for modern look */
|
||||
.form-control:focus {
|
||||
border-color: var(--primary-color);
|
||||
box-shadow: 0 0 0 0.25rem var(--primary-shadow);
|
||||
}
|
||||
|
||||
.summary-item {
|
||||
margin-bottom: 0.75rem;
|
||||
}
|
||||
|
||||
.form-label {
|
||||
font-weight: 500;
|
||||
}
|
||||
#pricing_container{
|
||||
max-width:60rem;
|
||||
|
||||
}
|
||||
|
||||
/* Validation styles */
|
||||
.is-invalid {
|
||||
.form-control.is-invalid {
|
||||
border-color: #dc3545 !important;
|
||||
padding-right: calc(1.5em + 0.75rem) !important;
|
||||
background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='%23dc3545'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3e%3c/svg%3e") !important;
|
||||
background-repeat: no-repeat !important;
|
||||
background-position: right calc(0.375em + 0.1875rem) center !important;
|
||||
background-size: calc(0.75em + 0.375rem) calc(0.75em + 0.375rem) !important;
|
||||
}
|
||||
|
||||
.invalid-feedback {
|
||||
display: none;
|
||||
width: 100%;
|
||||
margin-top: 0.25rem;
|
||||
font-size: 0.875em;
|
||||
color: #dc3545;
|
||||
font-size: 0.85em;
|
||||
display: none;
|
||||
margin-top: 0.25rem;
|
||||
}
|
||||
|
||||
.is-invalid + .invalid-feedback,
|
||||
.is-invalid ~ .invalid-feedback {
|
||||
display: block;
|
||||
}
|
||||
|
||||
/* Custom icons for lists */
|
||||
.fa-ul .fa-li {
|
||||
left: -1em;
|
||||
}
|
||||
|
||||
</style>
|
||||
{% endblock customCSS %}
|
||||
{% block content %}
|
||||
<div class="container py-5" id="pricing_container">
|
||||
<h1 class="text-center mb-5 text-primary">{{ _("Choose Your Plan") }}</h1>
|
||||
<h1 class="text-center mb-5 text-primary fw-bold">{{ _("Choose Your Plan") }}</h1>
|
||||
|
||||
<form method="POST"
|
||||
action="{% url 'submit_plan' request.dealer.slug %}"
|
||||
id="wizardForm">
|
||||
{% csrf_token %}
|
||||
<!--step1: Choose Plans-->
|
||||
<div class="step row justify-content-center mt-5 mb-3" id="step1">
|
||||
<div class="col-lg-8 col-md-10">
|
||||
<div class="card shadow-sm border-0 rounded-3">
|
||||
<div class="card-header bg-gray-200 py-3 border-0 rounded-top-3">
|
||||
<h4 class="mb-0 fs-4 text-center text-white">1. {{ _("Select a Plan") }}</h4>
|
||||
|
||||
<div class="progress-indicator mb-5">
|
||||
<div class="step-item active" id="progress-step-1">
|
||||
<div class="icon"><i class="fas fa-dollar-sign"></i></div>
|
||||
<span class="step-text">{{ _("Select Plan") }}</span>
|
||||
</div>
|
||||
<div class="card-body bg-light-subtle">
|
||||
<div class="line"></div>
|
||||
<div class="step-item" id="progress-step-2">
|
||||
<div class="icon"><i class="fas fa-user-check"></i></div>
|
||||
<span class="step-text">{{ _("Your Info") }}</span>
|
||||
</div>
|
||||
<div class="line"></div>
|
||||
<div class="step-item" id="progress-step-3">
|
||||
<div class="icon"><i class="fas fa-credit-card"></i></div>
|
||||
<span class="step-text">{{ _("Payment") }}</span>
|
||||
</div>
|
||||
<div class="line"></div>
|
||||
<div class="step-item" id="progress-step-4">
|
||||
<div class="icon"><i class="fas fa-receipt"></i></div>
|
||||
<span class="step-text">{{ _("Confirm") }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="step row justify-content-center" id="step1">
|
||||
<div class="col-lg-10 col-md-12">
|
||||
<h4 class="text-center mb-4 text-secondary">{{ _("1. Select a Plan") }}</h4>
|
||||
<div class="row g-4">
|
||||
{% for pp in plan_list %}
|
||||
<div class="col-md-12 mb-3">
|
||||
<div class="col-md-4 mb-3 d-flex">
|
||||
<input type="radio"
|
||||
class="btn-check"
|
||||
name="selected_plan"
|
||||
@ -103,19 +229,23 @@
|
||||
data-price="{{ pp.price_with_tax }}"
|
||||
autocomplete="off"
|
||||
{% if forloop.first %}checked{% endif %}>
|
||||
<label class="btn w-100 p-0 pricing-card" for="plan_{{ forloop.counter }}">
|
||||
<div class="card h-100 border border-2 rounded-4">
|
||||
<div class="card-body p-4">
|
||||
<h4 class="mb-3">{{ pp.plan.name|capfirst }}</h4>
|
||||
<h5 class="mb-4">
|
||||
{{pp.price_with_tax}} <span class="icon-saudi_riyal"></span><span class="fs-6 fw-normal">/ {{ pp.pricing.period }}</span> {% trans "days" %}
|
||||
</h5>
|
||||
<h5>{{ _("Include Haikal's") }}</h5>
|
||||
<label class="btn w-100 p-0 pricing-card-label"
|
||||
for="plan_{{ forloop.counter }}">
|
||||
<div class="card h-100 rounded-4">
|
||||
<div class="card-body p-4 position-relative">
|
||||
{% if forloop.first %}
|
||||
<div class="pricing-card-badge">{{ _("Most Popular") }}</div>
|
||||
{% endif %}
|
||||
<h4 class="mb-2 fw-bold text-primary">{{ pp.plan.name|capfirst }}</h4>
|
||||
<h2 class="mb-4">
|
||||
{{ pp.price_with_tax }}<span class="fs-5 fw-normal"> <span class="icon-saudi_riyal"></span> / {{ pp.pricing.period }} {{ _("days") }}</span>
|
||||
</h2>
|
||||
<h5>{{ _("Includes:") }}</h5>
|
||||
<ul class="fa-ul ps-3">
|
||||
{% if pp.plan.description %}
|
||||
{% for line in pp.plan.description|splitlines %}
|
||||
<li class="mb-2">
|
||||
<span class="fa-li"><i class="fas fa-check text-primary"></i></span>
|
||||
<span class="fa-li"><i class="fas fa-check-circle text-success"></i></span>
|
||||
{{ line|capfirst }}
|
||||
</li>
|
||||
{% endfor %}
|
||||
@ -129,105 +259,112 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!--step2: Information-->
|
||||
<div class="step d-none row justify-content-center mt-5 mb-3" id="step2">
|
||||
<div class="step d-none row justify-content-center" id="step2">
|
||||
<div class="col-lg-8 col-md-10">
|
||||
<div class="card shadow-sm border-0 rounded-3">
|
||||
<div class="card-header bg-gray-200 py-3 border-0 rounded-top-3">
|
||||
<h3 class="mb-0 fs-4 text-center text-white">2. {{ _("Enter Your Information") }}</h3>
|
||||
</div>
|
||||
<div class="card-body bg-light-subtle">
|
||||
<h4 class="text-center mb-4 text-secondary">{{ _("2. Enter Your Information") }}</h4>
|
||||
<div class="card shadow-sm border-0 rounded-3 p-4">
|
||||
<div class="mb-3">
|
||||
<label class="form-label" for="first_name">{{ _("First Name") }}</label>
|
||||
<div class="input-group">
|
||||
<span class="input-group-text"><i class="fas fa-user"></i></span>
|
||||
<input type="text"
|
||||
name="first_name"
|
||||
id="first_name"
|
||||
class="form-control form-control-sm"
|
||||
class="form-control"
|
||||
required
|
||||
placeholder='{{ _("First Name") }}'
|
||||
value="{{ request.dealer.first_name }}">
|
||||
<div class="invalid-feedback">{{ _("Please enter your first name.") }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label" for="last_name">{{ _("Last Name") }}</label>
|
||||
<div class="input-group">
|
||||
<span class="input-group-text"><i class="fas fa-user"></i></span>
|
||||
<input type="text"
|
||||
name="last_name"
|
||||
id="last_name"
|
||||
class="form-control form-control-sm"
|
||||
class="form-control"
|
||||
required
|
||||
placeholder='{{ _("Last Name") }}'
|
||||
value="{{ request.dealer.last_name }}">
|
||||
<div class="invalid-feedback">{{ _("Please enter your last name.") }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label" for="email">{{ _("Email Address") }}</label>
|
||||
<div class="input-group">
|
||||
<span class="input-group-text"><i class="fas fa-envelope"></i></span>
|
||||
<input type="email"
|
||||
name="email"
|
||||
id="email"
|
||||
class="form-control form-control-sm"
|
||||
class="form-control"
|
||||
required
|
||||
placeholder="email@example.com"
|
||||
value="{{ request.dealer.user.email }}">
|
||||
<div class="invalid-feedback">{{ _("Please enter a valid email address.") }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label" for="phone">{{ _("Phone Number") }}</label>
|
||||
<div class="input-group">
|
||||
<span class="input-group-text"><i class="fas fa-phone"></i></span>
|
||||
<input type="text"
|
||||
name="phone"
|
||||
id="phone"
|
||||
class="form-control form-control-sm"
|
||||
class="form-control"
|
||||
dir="ltr"
|
||||
maxlength="10"
|
||||
pattern="^05\d{8}$"
|
||||
inputmode="numeric"
|
||||
placeholder='{{ _("Phone Number") }}'
|
||||
placeholder='{{ _("05xxxxxxxx") }}'
|
||||
value="{{ request.dealer.phone_number }}"
|
||||
required>
|
||||
<div class="invalid-feedback">{{ _("Please enter a valid 10-digit phone number.") }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label" for="company">{{ _("Company") }}</label>
|
||||
<div class="input-group">
|
||||
<span class="input-group-text"><i class="fas fa-building"></i></span>
|
||||
<input type="text"
|
||||
name="company"
|
||||
id="company"
|
||||
class="form-control form-control-sm"
|
||||
placeholder='{{ _("Company") }}'
|
||||
class="form-control"
|
||||
placeholder='{{ _("Company Name") }}'
|
||||
value="{{ request.dealer.name }}">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!--step3: Payment-->
|
||||
<div class="step d-none row justify-content-center mt-5 mb-3" id="step3">
|
||||
<div class="step d-none row justify-content-center" id="step3">
|
||||
<div class="col-lg-8 col-md-10">
|
||||
<div class="card shadow-sm border-0 rounded-3">
|
||||
<div class="card-header bg-gray-200 py-3 border-0 rounded-top-3">
|
||||
<h3 class="mb-0 fs-4 text-center text-white">3. {{ _("Payment Information") }}</h3>
|
||||
</div>
|
||||
<div class="card-body bg-light-subtle">
|
||||
<h4 class="text-center mb-4 text-secondary">{{ _("3. Payment Information") }}</h4>
|
||||
<div class="card shadow-sm border-0 rounded-3 p-4">
|
||||
<div class="mb-3">
|
||||
<label class="form-label" for="card_name">{{ _("Cardholder Name") }}</label>
|
||||
<div class="input-group">
|
||||
<span class="input-group-text"><i class="fas fa-user"></i></span>
|
||||
<input type="text"
|
||||
name="card_name"
|
||||
id="card_name"
|
||||
class="form-control form-control-sm"
|
||||
class="form-control"
|
||||
placeholder='{{ _("Cardholder Name") }}'
|
||||
required>
|
||||
<div class="invalid-feedback" id="card_name_feedback">
|
||||
{{ _("Please enter the cardholder name") }}
|
||||
{{ _("Please enter the cardholder name.") }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label" for="card_number">{{ _("Card Number") }}</label>
|
||||
<div class="input-group">
|
||||
<span class="input-group-text"><i class="fas fa-credit-card"></i></span>
|
||||
<input type="text"
|
||||
name="card_number"
|
||||
id="card_number"
|
||||
class="form-control form-control-sm"
|
||||
class="form-control"
|
||||
placeholder='{{ _("Card Number") }}'
|
||||
maxlength="19"
|
||||
pattern="^\d{4}\s\d{4}\s\d{4}\s\d{4}$"
|
||||
@ -235,33 +372,37 @@
|
||||
required
|
||||
title="Enter a 16-digit card number">
|
||||
<div class="invalid-feedback" id="card_number_feedback">
|
||||
{{ _("Please enter a valid 16-digit card number") }}
|
||||
{{ _("Please enter a valid 16-digit card number.") }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label" for="card_expiry">{{ _("Expiry Date") }} (MM/YY)</label>
|
||||
<div class="input-group">
|
||||
<span class="input-group-text"><i class="far fa-calendar-alt"></i></span>
|
||||
<input type="text"
|
||||
name="card_expiry"
|
||||
id="card_expiry"
|
||||
class="form-control form-control-sm"
|
||||
placeholder='{{ _("Expiry Date") }}'
|
||||
class="form-control"
|
||||
placeholder='{{ _("MM/YY") }}'
|
||||
maxlength="5"
|
||||
pattern="^(0[1-9]|1[0-2])\/\d{2}$"
|
||||
inputmode="numeric"
|
||||
required
|
||||
title="Enter expiry in MM/YY format">
|
||||
<div class="invalid-feedback" id="card_expiry_feedback">
|
||||
{{ _("Please enter a valid expiry date (MM/YY)") }}
|
||||
{{ _("Please enter a valid expiry date (MM/YY).") }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label" for="card_cvv">{{ _("CVV") }}</label>
|
||||
<div class="input-group">
|
||||
<span class="input-group-text"><i class="fas fa-lock"></i></span>
|
||||
<input type="text"
|
||||
name="card_cvv"
|
||||
id="card_cvv"
|
||||
class="form-control form-control-sm"
|
||||
class="form-control"
|
||||
placeholder='{{ _("CVV") }}'
|
||||
maxlength="3"
|
||||
pattern="^\d{3}$"
|
||||
@ -269,83 +410,73 @@
|
||||
required
|
||||
title="Enter 3-digit CVV">
|
||||
<div class="invalid-feedback" id="card_cvv_feedback">
|
||||
{{ _("Please enter a valid 3-digit CVV") }}
|
||||
{{ _("Please enter a valid 3-digit CVV.") }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!--Step4 confirmation-->
|
||||
<div class="step d-none row justify-content-center mt-5 mb-3" id="step4">
|
||||
<div class="step d-none row justify-content-center" id="step4">
|
||||
<div class="col-lg-8 col-md-10">
|
||||
<div class="card shadow-sm border-0 rounded-3">
|
||||
<div class="card-header bg-gray-200 py-3 border-0 rounded-top-3">
|
||||
<h3 class="mb-0 fs-4 text-center text-white">4. {{ _("Confirm Your Information") }}</h3>
|
||||
</div>
|
||||
<div class="card-body bg-light-subtle">
|
||||
<h5 class="text-center">
|
||||
<i class="fas fa-file-invoice-dollar me-2"></i>{{ _("Order Summary") }}
|
||||
</h5>
|
||||
<h4 class="text-center mb-4 text-secondary">{{ _("4. Confirm Your Information") }}</h4>
|
||||
<div class="summary-box">
|
||||
<h5 class="text-center mb-4 fw-bold text-primary">{{ _("Order Summary") }}</h5>
|
||||
<div class="summary-item">
|
||||
<i class="fas fa-box me-2"></i><strong>{{ _("Plan") }}:</strong> <span id="summary_plan"></span>
|
||||
<p class="mb-1"><i class="fas fa-box me-2"></i><strong>{{ _("Plan") }}:</strong> <span id="summary_plan"></span></p>
|
||||
</div>
|
||||
<div class="summary-item">
|
||||
<i class="fas fa-tag me-2"></i><strong>{{ _("Price") }}:</strong> <span id="summary_price"></span>
|
||||
<p class="mb-1"><i class="fas fa-tag me-2"></i><strong>{{ _("Price") }}:</strong> <span id="summary_price"></span></p>
|
||||
</div>
|
||||
<div class="summary-item">
|
||||
<i class="fas fa-receipt me-2"></i><strong>{{ _("VAT") }} (15%):</strong> <span id="summary-tax">0.00</span> <span class="icon-saudi_riyal"></span>
|
||||
<p class="mb-1"><i class="fas fa-receipt me-2"></i><strong>{{ _("VAT") }} (15%):</strong> <span id="summary-tax">0.00</span> <span class="icon-saudi_riyal"></span></p>
|
||||
</div>
|
||||
<hr class="my-3">
|
||||
<div class="summary-item">
|
||||
<p class="mb-0 fs-5 fw-bold"><i class="fas fa-hand-holding-usd me-2"></i>{{ _("Total") }}: <span id="summary-total">0.00</span> <span class="icon-saudi_riyal"></span></p>
|
||||
</div>
|
||||
<h5 class="mt-4 text-center mb-4 fw-bold text-primary">{{ _("User Information") }}</h5>
|
||||
<div class="summary-item">
|
||||
<p class="mb-1"><i class="fas fa-signature me-2"></i><strong>{{ _("Name") }}:</strong> <span id="summary_name"></span></p>
|
||||
</div>
|
||||
<div class="summary-item">
|
||||
<i class="fas fa-hand-holding-usd me-2"></i><strong>{{ _("Total") }}:</strong> <span id="summary-total">0.00</span> <span class="icon-saudi_riyal"></span>
|
||||
</div>
|
||||
<hr>
|
||||
<h5 class="mt-4 text-center">
|
||||
<i class="fas fa-user me-2"></i>{{ _("User Information") }}
|
||||
</h5>
|
||||
<div class="summary-item">
|
||||
<i class="fas fa-signature me-2"></i><strong>{{ _("Name") }}:</strong> <span id="summary_name"></span>
|
||||
<p class="mb-1"><i class="fas fa-envelope me-2"></i><strong>{{ _("Email") }}:</strong> <span id="summary_email"></span></p>
|
||||
</div>
|
||||
<div class="summary-item">
|
||||
<i class="fas fa-envelope me-2"></i><strong>{{ _("Email") }}:</strong> <span id="summary_email"></span>
|
||||
<p class="mb-1"><i class="fas fa-building me-2"></i><strong>{{ _("Company") }}:</strong> <span id="summary_company"></span></p>
|
||||
</div>
|
||||
<div class="summary-item">
|
||||
<i class="fas fa-building me-2"></i><strong>{{ _("Company") }}:</strong> <span id="summary_company"></span>
|
||||
<p class="mb-1"><i class="fas fa-phone me-2"></i><strong>{{ _("Phone") }}:</strong> <span id="summary_phone"></span></p>
|
||||
</div>
|
||||
<h5 class="mt-4 text-center mb-4 fw-bold text-primary">{{ _("Payment") }}</h5>
|
||||
<div class="summary-item">
|
||||
<p class="mb-1"><i class="fas fa-user me-2"></i><strong>{{ _("Cardholder") }}:</strong> <span id="summary_card_name"></span></p>
|
||||
</div>
|
||||
<div class="summary-item">
|
||||
<i class="fas fa-phone me-2"></i><strong>{{ _("Phone") }}:</strong> <span id="summary_phone"></span>
|
||||
</div>
|
||||
<hr>
|
||||
<h5 class="mt-4 text-center">
|
||||
<i class="fas fa-credit-card me-2"></i>{{ _("Payment") }}
|
||||
</h5>
|
||||
<div class="summary-item">
|
||||
<i class="fas fa-user me-2"></i><strong>{{ _("Cardholder") }}:</strong> <span id="summary_card_name"></span>
|
||||
<p class="mb-1"><i class="fas fa-credit-card me-2"></i><strong>{{ _("Card Number") }}:</strong> <span id="summary_card_number"></span></p>
|
||||
</div>
|
||||
<div class="summary-item">
|
||||
<i class="fas fa-credit-card me-2"></i><strong>{{ _("Card Number") }}:</strong> <span id="summary_card_number"></span>
|
||||
</div>
|
||||
<div class="summary-item">
|
||||
<i class="far fa-calendar-alt me-2"></i><strong>{{ _("Expiry") }}:</strong> <span id="summary_card_expiry"></span>
|
||||
<p class="mb-1"><i class="far fa-calendar-alt me-2"></i><strong>{{ _("Expiry") }}:</strong> <span id="summary_card_expiry"></span></p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Navigation -->
|
||||
<div class="d-flex justify-content-between mt-4">
|
||||
<div class="d-flex justify-content-between mt-5">
|
||||
<button type="button"
|
||||
class="btn btn-lg btn-phoenix-secondary"
|
||||
class="btn btn-lg btn-phoenix-secondary px-5"
|
||||
id="prevBtn"
|
||||
disabled>{{ _("Previous") }}</button>
|
||||
<button type="button" class="btn btn-lg btn-phoenix-primary" id="nextBtn">{{ _("Next") }}</button>
|
||||
disabled><i class="fas fa-arrow-left me-2"></i>{{ _("Previous") }}</button>
|
||||
<button type="button"
|
||||
class="btn btn-lg btn-phoenix-primary px-5"
|
||||
id="nextBtn">{{ _("Next") }}<i class="fas fa-arrow-right ms-2"></i></button>
|
||||
<button type="submit"
|
||||
class="btn btn-lg btn-phoenix-primary d-none"
|
||||
class="btn btn-lg btn-phoenix-primary px-5 d-none"
|
||||
id="submitBtn">{{ _("Confirm") }}</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
{% endblock content %}
|
||||
|
||||
{% block customJS %}
|
||||
<script>
|
||||
// wizard-form.js
|
||||
|
||||
@ -118,7 +118,7 @@
|
||||
{% else %}
|
||||
{% if vendors %}
|
||||
{% url "purchase_order_create" request.dealer.slug request.dealer.entity.slug as create_purchase_url %}
|
||||
{% include "empty-illustration-page.html" with value="purchase order" url=create_purchase_url %}
|
||||
{% include "empty-illustration-page.html" with value=empty_state_value url=create_purchase_url %}
|
||||
{% else %}
|
||||
{% url "vendor_create" request.dealer.slug as vendor_create_url %}
|
||||
{% include "message-illustration.html" with value1=_("You don't have a Vendor, Please add a Vendor before creating a Purchase Order.") value2=_("Create New Vendor") url=vendor_create_url %}
|
||||
|
||||
@ -124,13 +124,13 @@
|
||||
<div class="col">
|
||||
{% if not items %}
|
||||
{% url "car_add" request.dealer.slug as create_car_url %}
|
||||
{% include "message-illustration.html" with value1="Please add at least one car or complete the car info before creating a quotation." value2="Add car" message_image="images/logos/no-content-new.jpg" url=create_car_url %}
|
||||
{% include "message-illustration.html" with value1=no_items_message value2=no_items_button message_image="images/logos/no-content-new.jpg" url=create_car_url %}
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="col">
|
||||
{% if not customer_count %}
|
||||
{% url "customer_create" request.dealer.slug as create_customer_url %}
|
||||
{% include "message-illustration.html" with value1="Please add at least one customer before creating a quotation." value2="Add Customer" message_image="images/logos/no-content-new.jpg" url=create_customer_url %}
|
||||
{% include "message-illustration.html" with value1=no_customers_message value2=no_customers_button message_image="images/logos/no-content-new.jpg" url=create_customer_url %}
|
||||
{% endif %}
|
||||
</div>
|
||||
<div>
|
||||
|
||||
@ -88,6 +88,6 @@
|
||||
</div>
|
||||
{% else %}
|
||||
{% url 'estimate_create' request.dealer.slug as url %}
|
||||
{% include "empty-illustration-page.html" with value="invoice" url=url %}
|
||||
{% include "empty-illustration-page.html" with value=_("invoice") url=url %}
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
@ -90,7 +90,7 @@
|
||||
{% else %}
|
||||
{% if request.user.userplan %}
|
||||
{% url "user_create" request.dealer.slug as create_staff_url %}
|
||||
{% include "empty-illustration-page.html" with value="staff" url=create_staff_url %}
|
||||
{% include "empty-illustration-page.html" with value=no_staff_message url=create_staff_url %}
|
||||
{% else %}
|
||||
{% url "pricing_page" request.dealer.slug as pricing_page_url %}
|
||||
{% include "message-illustration.html" with value1=_("No active plan, Please create a subscription plan.") value2=_("Buy Plan") url=pricing_page_url %}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user