adding customers receive

This commit is contained in:
Flatlogic Bot 2026-02-02 18:48:59 +00:00
parent 34d6321e11
commit 82334fa523
9 changed files with 612 additions and 12 deletions

View File

@ -53,11 +53,11 @@
<!-- Sales Group --> <!-- Sales Group -->
<li class="sidebar-group-header mt-2"> <li class="sidebar-group-header mt-2">
<a href="#salesSubmenu" data-bs-toggle="collapse" aria-expanded="{% if url_name == 'pos' or url_name == 'invoice_create' or url_name == 'invoices' or url_name == 'invoice_detail' or url_name == 'quotations' or url_name == 'quotation_create' or url_name == 'quotation_detail' or 'sales/returns' in path %}true{% else %}false{% endif %}" class="dropdown-toggle-custom"> <a href="#salesSubmenu" data-bs-toggle="collapse" aria-expanded="{% if url_name == 'pos' or url_name == 'invoice_create' or url_name == 'invoices' or url_name == 'invoice_detail' or url_name == 'quotations' or url_name == 'quotation_create' or url_name == 'quotation_detail' or 'sales/returns' in path or url_name == 'customer_payments' %}true{% else %}false{% endif %}" class="dropdown-toggle-custom">
<span>{% trans "Sales" %}</span> <span>{% trans "Sales" %}</span>
<i class="bi bi-chevron-down chevron"></i> <i class="bi bi-chevron-down chevron"></i>
</a> </a>
<ul class="collapse list-unstyled sub-menu {% if url_name == 'pos' or url_name == 'invoice_create' or url_name == 'invoices' or url_name == 'invoice_detail' or url_name == 'quotations' or url_name == 'quotation_create' or url_name == 'quotation_detail' or 'sales/returns' in path %}show{% endif %}" id="salesSubmenu"> <ul class="collapse list-unstyled sub-menu {% if url_name == 'pos' or url_name == 'invoice_create' or url_name == 'invoices' or url_name == 'invoice_detail' or url_name == 'quotations' or url_name == 'quotation_create' or url_name == 'quotation_detail' or 'sales/returns' in path or url_name == 'customer_payments' %}show{% endif %}" id="salesSubmenu">
<li> <li>
<a href="{% url 'pos' %}" class="{% if url_name == 'pos' %}active{% endif %}"> <a href="{% url 'pos' %}" class="{% if url_name == 'pos' %}active{% endif %}">
<i class="bi bi-shop"></i> {% trans "POS System" %} <i class="bi bi-shop"></i> {% trans "POS System" %}
@ -83,24 +83,34 @@
<i class="bi bi-arrow-return-left"></i> {% trans "Sales Return" %} <i class="bi bi-arrow-return-left"></i> {% trans "Sales Return" %}
</a> </a>
</li> </li>
<li>
<a href="{% url 'customer_payments' %}" class="{% if url_name == 'customer_payments' %}active{% endif %}">
<i class="bi bi-receipt-cutoff"></i> {% trans 'Customer Receipts' %}
</a>
</li>
</ul> </ul>
</li> </li>
<!-- Inventory Group --> <!-- Purchases Group -->
<li class="sidebar-group-header mt-2"> <li class="sidebar-group-header mt-2">
<a href="#inventorySubmenu" data-bs-toggle="collapse" aria-expanded="{% if url_name == 'inventory' or url_name == 'purchases' or url_name == 'purchase_create' or url_name == 'purchase_detail' or 'purchases/returns' in path or url_name == 'barcode_labels' or url_name == 'reports' %}true{% else %}false{% endif %}" class="dropdown-toggle-custom"> <a href="#purchasesSubmenu" data-bs-toggle="collapse" aria-expanded="{% if url_name == 'purchases' or url_name == 'purchase_create' or url_name == 'purchase_detail' or url_name == 'supplier_payments' or 'purchases/returns' in path %}true{% else %}false{% endif %}" class="dropdown-toggle-custom">
<span>{% trans "Inventory" %}</span> <span>{% trans "Purchases" %}</span>
<i class="bi bi-chevron-down chevron"></i> <i class="bi bi-chevron-down chevron"></i>
</a> </a>
<ul class="collapse list-unstyled sub-menu {% if url_name == 'inventory' or url_name == 'purchases' or url_name == 'purchase_create' or url_name == 'purchase_detail' or 'purchases/returns' in path or url_name == 'barcode_labels' or url_name == 'reports' %}show{% endif %}" id="inventorySubmenu"> <ul class="collapse list-unstyled sub-menu {% if url_name == 'purchases' or url_name == 'purchase_create' or url_name == 'purchase_detail' or url_name == 'supplier_payments' or 'purchases/returns' in path %}show{% endif %}" id="purchasesSubmenu">
<li> <li>
<a href="{% url 'inventory' %}" class="{% if url_name == 'inventory' %}active{% endif %}"> <a href="{% url 'purchase_create' %}" class="{% if url_name == 'purchase_create' %}active{% endif %}">
<i class="bi bi-box-seam"></i> {% trans "Products" %} <i class="bi bi-plus-circle"></i> {% trans "New Purchase" %}
</a> </a>
</li> </li>
<li> <li>
<a href="{% url 'purchases' %}" class="{% if url_name == 'purchases' or url_name == 'purchase_create' or url_name == 'purchase_detail' %}active{% endif %}"> <a href="{% url 'purchases' %}" class="{% if url_name == 'purchases' or url_name == 'purchase_detail' %}active{% endif %}">
<i class="bi bi-cart-check"></i> {% trans "Purchases" %} <i class="bi bi-cart-check"></i> {% trans "Purchase List" %}
</a>
</li>
<li>
<a href="{% url 'supplier_payments' %}" class="{% if url_name == 'supplier_payments' %}active{% endif %}">
<i class="bi bi-cash-stack"></i> {% trans "Supplier Payments" %}
</a> </a>
</li> </li>
<li> <li>
@ -108,6 +118,21 @@
<i class="bi bi-arrow-return-right"></i> {% trans "Purchase Return" %} <i class="bi bi-arrow-return-right"></i> {% trans "Purchase Return" %}
</a> </a>
</li> </li>
</ul>
</li>
<!-- Inventory Group -->
<li class="sidebar-group-header mt-2">
<a href="#inventorySubmenu" data-bs-toggle="collapse" aria-expanded="{% if url_name == 'inventory' or url_name == 'barcode_labels' or url_name == 'reports' %}true{% else %}false{% endif %}" class="dropdown-toggle-custom">
<span>{% trans "Inventory" %}</span>
<i class="bi bi-chevron-down chevron"></i>
</a>
<ul class="collapse list-unstyled sub-menu {% if url_name == 'inventory' or url_name == 'barcode_labels' or url_name == 'reports' %}show{% endif %}" id="inventorySubmenu">
<li>
<a href="{% url 'inventory' %}" class="{% if url_name == 'inventory' %}active{% endif %}">
<i class="bi bi-box-seam"></i> {% trans "Products" %}
</a>
</li>
<li> <li>
<a href="{% url 'barcode_labels' %}" class="{% if url_name == 'barcode_labels' %}active{% endif %}"> <a href="{% url 'barcode_labels' %}" class="{% if url_name == 'barcode_labels' %}active{% endif %}">
<i class="bi bi-upc-scan"></i> {% trans "Barcode Printing" %} <i class="bi bi-upc-scan"></i> {% trans "Barcode Printing" %}
@ -296,4 +321,4 @@
</script> </script>
{% block scripts %}{% endblock %} {% block scripts %}{% endblock %}
</body> </body>
</html> </html>

View File

@ -0,0 +1,221 @@
{% load i18n static %}
<!DOCTYPE html>
<html lang="{{ LANGUAGE_CODE }}" dir="{% if LANGUAGE_CODE == 'ar' %}rtl{% else %}ltr{% endif %}">
<head>
<meta charset="UTF-8">
<title>{% trans "Payment Receipt" %} #{{ payment.id }}</title>
<style>
@media print {
.no-print { display: none; }
body { padding: 0; margin: 0; }
}
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
color: #333;
line-height: 1.6;
padding: 40px;
background-color: #f8f9fa;
}
.receipt-container {
max-width: 800px;
margin: 0 auto;
background: #fff;
padding: 40px;
border-radius: 12px;
box-shadow: 0 4px 20px rgba(0,0,0,0.05);
}
.header {
display: flex;
justify-content: space-between;
align-items: flex-start;
margin-bottom: 40px;
border-bottom: 2px solid #eee;
padding-bottom: 20px;
}
.business-info h1 {
margin: 0;
color: #0d6efd;
font-size: 28px;
}
.business-info p {
margin: 5px 0;
color: #666;
font-size: 14px;
}
.receipt-title {
text-align: right;
}
.receipt-title h2 {
margin: 0;
font-size: 24px;
color: #333;
text-transform: uppercase;
letter-spacing: 2px;
}
.receipt-meta {
margin-top: 10px;
font-size: 14px;
color: #666;
}
.info-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 40px;
margin-bottom: 40px;
}
.info-box h3 {
font-size: 14px;
text-transform: uppercase;
color: #999;
margin-bottom: 10px;
border-bottom: 1px solid #eee;
padding-bottom: 5px;
}
.info-box p {
margin: 0;
font-weight: 600;
}
.payment-details {
background-color: #fcfcfc;
border: 1px solid #eee;
border-radius: 8px;
padding: 20px;
margin-bottom: 40px;
}
.detail-row {
display: flex;
justify-content: space-between;
padding: 10px 0;
border-bottom: 1px dashed #eee;
}
.detail-row:last-child {
border-bottom: none;
}
.label {
color: #666;
}
.value {
font-weight: 600;
}
.amount-box {
background-color: #0d6efd;
color: #fff;
padding: 20px;
border-radius: 8px;
text-align: center;
margin-top: 20px;
}
.amount-box h4 {
margin: 0;
font-size: 14px;
text-transform: uppercase;
opacity: 0.8;
}
.amount-box .amount {
font-size: 32px;
font-weight: 700;
margin-top: 5px;
}
.footer {
text-align: center;
margin-top: 40px;
color: #999;
font-size: 12px;
border-top: 1px solid #eee;
padding-top: 20px;
}
.btn-print {
background: #333;
color: #fff;
border: none;
padding: 10px 20px;
border-radius: 6px;
cursor: pointer;
font-weight: 600;
margin-bottom: 20px;
}
.btn-print:hover { background: #000; }
[dir="rtl"] .header, [dir="rtl"] .detail-row {
flex-direction: row-reverse;
}
[dir="rtl"] .receipt-title {
text-align: left;
}
</style>
</head>
<body>
<div class="no-print" style="text-align: center;">
<button class="btn-print" onclick="window.print()">{% trans "Print Receipt" %}</button>
</div>
<div class="receipt-container">
<div class="header">
<div class="business-info">
{% if settings.logo %}
<img src="{{ settings.logo.url }}" alt="Logo" height="50" style="margin-bottom: 10px;">
{% endif %}
<h1>{{ settings.business_name }}</h1>
<p>{{ settings.address|linebreaksbr }}</p>
<p>{% trans "Phone" %}: {{ settings.phone }}</p>
{% if settings.vat_number %}
<p>{% trans "VAT No" %}: {{ settings.vat_number }}</p>
{% endif %}
</div>
<div class="receipt-title">
<h2>{% trans "Payment Receipt" %}</h2>
<div class="receipt-meta">
<p><strong>{% trans "Receipt #" %}:</strong> {{ payment.id }}</p>
<p><strong>{% trans "Date" %}:</strong> {{ payment.payment_date|date:"Y-m-d" }}</p>
</div>
</div>
</div>
<div class="info-grid">
<div class="info-box">
<h3>{% trans "Received From" %}</h3>
<p>{{ payment.sale.customer.name|default:"Guest" }}</p>
{% if payment.sale.customer.phone %}
<p class="text-muted" style="font-weight: normal; font-size: 14px;">{{ payment.sale.customer.phone }}</p>
{% endif %}
</div>
<div class="info-box">
<h3>{% trans "In Reference To" %}</h3>
<p>{% trans "Invoice" %} #{{ payment.sale.invoice_number|default:payment.sale.id }}</p>
<p class="text-muted" style="font-weight: normal; font-size: 14px;">{% trans "Total Amount" %}: {{ settings.currency_symbol }}{{ payment.sale.total_amount|floatformat:3 }}</p>
</div>
</div>
<div class="payment-details">
<div class="detail-row">
<span class="label">{% trans "Payment Method" %}</span>
<span class="value">{{ payment.payment_method_name }}</span>
</div>
<div class="detail-row">
<span class="label">{% trans "Transaction Status" %}</span>
<span class="value" style="color: green;">{% trans "Completed" %}</span>
</div>
<div class="detail-row">
<span class="label">{% trans "Recorded By" %}</span>
<span class="value">{{ payment.created_by.get_full_name|default:payment.created_by.username }}</span>
</div>
{% if payment.notes %}
<div class="detail-row">
<span class="label">{% trans "Notes" %}</span>
<span class="value">{{ payment.notes }}</span>
</div>
{% endif %}
</div>
<div class="amount-box">
<h4>{% trans "Amount Received" %}</h4>
<div class="amount">{{ settings.currency_symbol }}{{ payment.amount|floatformat:3 }}</div>
</div>
<div class="footer">
<p>{% trans "Thank you for your business!" %}</p>
<p>{{ settings.business_name }} &copy; {% now "Y" %}</p>
</div>
</div>
</body>
</html>

View File

@ -0,0 +1,113 @@
{% extends 'base.html' %}
{% load i18n %}
{% block title %}{% trans "Customer Receipts" %} | {{ site_settings.business_name }}{% endblock %}
{% block content %}
<div class="container-fluid px-4">
<div class="d-flex justify-content-between align-items-center mb-4">
<div>
<h2 class="fw-bold mb-0">{% trans "Customer Receipts" %}</h2>
<p class="text-muted small mb-0">{% trans "History of payments received from customers" %}</p>
</div>
<div class="d-flex gap-2">
<a href="{% url 'invoices' %}" class="btn btn-outline-primary rounded-3 px-4 shadow-sm">
<i class="bi bi-file-earmark-text me-2"></i>{% trans "Sales Invoices" %}
</a>
<a href="{% url 'pos' %}" class="btn btn-primary rounded-3 px-4 shadow-sm">
<i class="bi bi-shop me-2"></i>{% trans "POS System" %}
</a>
</div>
</div>
<!-- Filters -->
<div class="card border-0 shadow-sm rounded-4 mb-4">
<div class="card-body p-3">
<form method="get" class="row g-3">
<div class="col-md-3">
<label class="form-label small fw-bold text-muted">{% trans "Customer" %}</label>
<select name="customer" class="form-select border-0 bg-light">
<option value="">{% trans "All Customers" %}</option>
{% for c in customers %}
<option value="{{ c.id }}" {% if customer_id == c.id|stringformat:"s" %}selected{% endif %}>{{ c.name }}</option>
{% endfor %}
</select>
</div>
<div class="col-md-3">
<label class="form-label small fw-bold text-muted">{% trans "From" %}</label>
<input type="date" name="start_date" class="form-control border-0 bg-light" value="{{ start_date }}">
</div>
<div class="col-md-3">
<label class="form-label small fw-bold text-muted">{% trans "To" %}</label>
<input type="date" name="end_date" class="form-control border-0 bg-light" value="{{ end_date }}">
</div>
<div class="col-md-3 d-flex align-items-end gap-2">
<button type="submit" class="btn btn-dark w-100 rounded-3">{% trans "Filter" %}</button>
<a href="{% url 'customer_payments' %}" class="btn btn-light w-100 rounded-3 border">{% trans "Clear" %}</a>
</div>
</form>
</div>
</div>
<div class="card border-0 shadow-sm rounded-4">
<div class="card-body p-0">
<div class="table-responsive">
<table class="table table-hover align-middle mb-0">
<thead class="bg-light">
<tr>
<th class="ps-4">{% trans "Date" %}</th>
<th>{% trans "Invoice #" %}</th>
<th>{% trans "Customer" %}</th>
<th>{% trans "Amount" %}</th>
<th>{% trans "Method" %}</th>
<th>{% trans "User" %}</th>
<th>{% trans "Receipt" %}</th>
<th class="pe-4">{% trans "Notes" %}</th>
</tr>
</thead>
<tbody>
{% for payment in payments %}
<tr>
<td class="ps-4">{{ payment.payment_date|date:"Y-m-d" }}</td>
<td>
<a href="{% url 'invoice_detail' payment.sale.id %}" class="fw-bold text-decoration-none">
{{ payment.sale.invoice_number|default:payment.sale.id }}
</a>
</td>
<td>{{ payment.sale.customer.name|default:"Guest" }}</td>
<td class="fw-bold text-dark">{{ site_settings.currency_symbol }}{{ payment.amount|floatformat:3 }}</td>
<td>
<span class="badge bg-light text-dark border rounded-pill px-3">
{{ payment.payment_method_name }}
</span>
</td>
<td>
<span class="text-muted small">
<i class="bi bi-person me-1"></i>{{ payment.created_by.username|default:"System" }}
</span>
</td>
<td>
<a href="{% url 'customer_payment_receipt' payment.id %}" target="_blank" class="btn btn-sm btn-outline-info rounded-pill">
<i class="bi bi-printer me-1"></i>{% trans "Print" %}
</a>
</td>
<td class="pe-4">
<span class="small text-muted">{{ payment.notes|default:"-" }}</span>
</td>
</tr>
{% empty %}
<tr>
<td colspan="8" class="text-center py-5">
<img src="https://illustrations.popsy.co/gray/payments.svg" alt="Empty" style="width: 200px;" class="mb-3">
<p class="text-muted">{% trans "No customer receipts found." %}</p>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% include "core/pagination.html" with page_obj=payments %}
</div>
</div>
</div>
{% endblock %}

View File

@ -0,0 +1,73 @@
{% extends 'base.html' %}
{% load i18n %}
{% block title %}{% trans "Supplier Payments" %} | {{ site_settings.business_name }}{% endblock %}
{% block content %}
<div class="container-fluid px-4">
<div class="d-flex justify-content-between align-items-center mb-4">
<div>
<h2 class="fw-bold mb-0">{% trans "Supplier Payments" %}</h2>
<p class="text-muted small mb-0">{% trans "History of payments made to suppliers" %}</p>
</div>
<a href="{% url 'purchases' %}" class="btn btn-primary rounded-3 px-4 shadow-sm">
<i class="bi bi-list-ul me-2"></i>{% trans "Purchase Invoices" %}
</a>
</div>
<div class="card border-0 shadow-sm rounded-4">
<div class="card-body p-0">
<div class="table-responsive">
<table class="table table-hover align-middle mb-0">
<thead class="bg-light">
<tr>
<th class="ps-4">{% trans "Date" %}</th>
<th>{% trans "Purchase #" %}</th>
<th>{% trans "Supplier" %}</th>
<th>{% trans "Amount" %}</th>
<th>{% trans "Method" %}</th>
<th>{% trans "User" %}</th>
<th class="pe-4">{% trans "Notes" %}</th>
</tr>
</thead>
<tbody>
{% for payment in payments %}
<tr>
<td class="ps-4">{{ payment.payment_date|date:"Y-m-d" }}</td>
<td>
<a href="{% url 'purchase_detail' payment.purchase.id %}" class="fw-bold text-decoration-none">
{{ payment.purchase.invoice_number|default:payment.purchase.id }}
</a>
</td>
<td>{{ payment.purchase.supplier.name|default:"-" }}</td>
<td class="fw-bold text-dark">{{ site_settings.currency_symbol }}{{ payment.amount|floatformat:3 }}</td>
<td>
<span class="badge bg-light text-dark border rounded-pill px-3">
{{ payment.payment_method_name }}
</span>
</td>
<td>
<span class="text-muted small">
<i class="bi bi-person me-1"></i>{{ payment.created_by.username|default:"System" }}
</span>
</td>
<td class="pe-4">
<span class="small text-muted">{{ payment.notes|default:"-" }}</span>
</td>
</tr>
{% empty %}
<tr>
<td colspan="7" class="text-center py-5">
<img src="https://illustrations.popsy.co/gray/payments.svg" alt="Empty" style="width: 200px;" class="mb-3">
<p class="text-muted">{% trans "No purchase payments found." %}</p>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% include "core/pagination.html" with page_obj=payments %}
</div>
</div>
</div>
{% endblock %}

View File

@ -20,6 +20,8 @@ urlpatterns = [
path('invoices/<int:pk>/', views.invoice_detail, name='invoice_detail'), path('invoices/<int:pk>/', views.invoice_detail, name='invoice_detail'),
path('invoices/payment/<int:pk>/', views.add_sale_payment, name='add_sale_payment'), path('invoices/payment/<int:pk>/', views.add_sale_payment, name='add_sale_payment'),
path('invoices/delete/<int:pk>/', views.delete_sale, name='delete_sale'), path('invoices/delete/<int:pk>/', views.delete_sale, name='delete_sale'),
path('invoices/payments/', views.customer_payments, name='customer_payments'),
path('invoices/receipt/<int:pk>/', views.customer_payment_receipt, name='customer_payment_receipt'),
path("invoices/edit/<int:pk>/", views.edit_invoice, name="edit_invoice"), path("invoices/edit/<int:pk>/", views.edit_invoice, name="edit_invoice"),
# Quotations # Quotations
@ -42,6 +44,7 @@ urlpatterns = [
path('purchases/<int:pk>/', views.purchase_detail, name='purchase_detail'), path('purchases/<int:pk>/', views.purchase_detail, name='purchase_detail'),
path('purchases/payment/<int:pk>/', views.add_purchase_payment, name='add_purchase_payment'), path('purchases/payment/<int:pk>/', views.add_purchase_payment, name='add_purchase_payment'),
path('purchases/delete/<int:pk>/', views.delete_purchase, name='delete_purchase'), path('purchases/delete/<int:pk>/', views.delete_purchase, name='delete_purchase'),
path('purchases/payments/', views.supplier_payments, name='supplier_payments'),
# Purchase Returns # Purchase Returns
path('purchases/returns/', views.purchase_returns, name='purchase_returns'), path('purchases/returns/', views.purchase_returns, name='purchase_returns'),

View File

@ -132,6 +132,13 @@ def suppliers(request):
# --- Purchase Views --- # --- Purchase Views ---
@login_required @login_required
def supplier_payments(request):
payments_qs = PurchasePayment.objects.all().select_related("purchase", "purchase__supplier", "payment_method", "created_by").order_by("-payment_date", "-id")
paginator = Paginator(payments_qs, 25)
page_number = request.GET.get("page")
payments = paginator.get_page(page_number)
return render(request, "core/supplier_payments.html", {"payments": payments})
def purchases(request): def purchases(request):
purchases_qs = Purchase.objects.all().select_related('supplier', 'created_by').order_by('-created_at') purchases_qs = Purchase.objects.all().select_related('supplier', 'created_by').order_by('-created_at')
paginator = Paginator(purchases_qs, 25) paginator = Paginator(purchases_qs, 25)
@ -1859,3 +1866,48 @@ def update_sale_api(request, pk):
traceback.print_exc() traceback.print_exc()
return JsonResponse({'success': False, 'error': str(e)}, status=400) return JsonResponse({'success': False, 'error': str(e)}, status=400)
return JsonResponse({'success': False, 'error': 'Invalid request'}, status=405) return JsonResponse({'success': False, 'error': 'Invalid request'}, status=405)
@login_required
def customer_payments(request):
"""
List of payments received from customers
"""
payments_qs = SalePayment.objects.all().select_related("sale", "sale__customer", "payment_method", "created_by").order_by("-payment_date", "-id")
# Filtering
start_date = request.GET.get("start_date")
end_date = request.GET.get("end_date")
customer_id = request.GET.get("customer")
if start_date:
payments_qs = payments_qs.filter(payment_date__gte=start_date)
if end_date:
payments_qs = payments_qs.filter(payment_date__lte=end_date)
if customer_id:
payments_qs = payments_qs.filter(sale__customer_id=customer_id)
paginator = Paginator(payments_qs, 25)
page_number = request.GET.get("page")
payments = paginator.get_page(page_number)
customers = Customer.objects.all().order_by("name")
return render(request, "core/customer_payments.html", {
"payments": payments,
"customers": customers,
"start_date": start_date,
"end_date": end_date,
"customer_id": customer_id,
})
@login_required
def customer_payment_receipt(request, pk):
"""
Printable receipt for a customer payment
"""
payment = get_object_or_404(SalePayment, pk=pk)
settings = SystemSetting.objects.first()
return render(request, "core/customer_payment_receipt.html", {
"payment": payment,
"settings": settings
})

View File

@ -193,4 +193,117 @@ body {
#content { #content {
width: 100%; width: 100%;
} }
} }
/* Enhanced Responsiveness */
/* Container & Spacing Adjustments */
@media (max-width: 576px) {
main.p-4 {
padding: 1rem !important;
}
.hero-gradient {
padding: 1.5rem;
}
.top-navbar {
padding: 10px 15px;
}
h1, .h1 { font-size: 1.5rem; }
h2, .h2 { font-size: 1.25rem; }
h3, .h3 { font-size: 1.1rem; }
h4, .h4 { font-size: 1rem; }
}
/* Sidebar Overlay for Mobile */
@media (max-width: 992px) {
#sidebar {
box-shadow: 0 0 20px rgba(0,0,0,0.1);
}
#sidebar.active {
margin-inline-start: 0;
}
#sidebar:not(.active) {
margin-inline-start: calc(-1 * var(--sidebar-width));
}
/* Overlay effect when sidebar is active */
#sidebar.active::after {
content: '';
position: fixed;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
background: rgba(0,0,0,0.2);
z-index: -1;
display: block;
}
}
/* Table Card Styling for Mobile */
@media (max-width: 768px) {
.table-responsive {
border-radius: 12px;
overflow: hidden;
}
.btn-sm {
padding: 0.4rem 0.8rem;
}
}
/* POS Specific Responsive Utilities */
.mobile-cart-toggle {
display: none;
position: fixed;
bottom: 20px;
right: 20px;
z-index: 1030;
border-radius: 50px;
padding: 12px 24px;
box-shadow: 0 4px 15px rgba(46, 91, 255, 0.4);
}
[dir="rtl"] .mobile-cart-toggle {
right: auto;
left: 20px;
}
@media (max-width: 991px) {
.mobile-cart-toggle {
display: flex;
align-items: center;
}
.cart-container {
position: fixed !important;
top: 0 !important;
right: -100% !important;
width: 100% !important;
height: 100% !important;
z-index: 1040 !important;
transition: right 0.3s ease;
border-radius: 0 !important;
}
[dir="rtl"] .cart-container {
right: auto !important;
left: -100% !important;
transition: left 0.3s ease;
}
.cart-container.show {
right: 0 !important;
}
[dir="rtl"] .cart-container.show {
left: 0 !important;
}
/* Ensure body doesn't scroll when cart is open */
body.cart-open {
overflow: hidden;
}
}
/* Grid adjustments */
@media (max-width: 400px) {
#productGrid .col {
width: 100% !important;
}
}