diff --git a/app/Http/Controllers/Admin/AdminCustomerController.php b/app/Http/Controllers/Admin/AdminCustomerController.php index 393db9a..aab2cd1 100644 --- a/app/Http/Controllers/Admin/AdminCustomerController.php +++ b/app/Http/Controllers/Admin/AdminCustomerController.php @@ -9,36 +9,42 @@ use Illuminate\Support\Facades\Hash; class AdminCustomerController extends Controller { + + // --------------------------------------------------------- // LIST CUSTOMERS (with search + status filter) // --------------------------------------------------------- public function index(Request $request) - { - $search = $request->search; - $status = $request->status; +{ + $search = $request->search; + $status = $request->status; - $query = User::with(['marks', 'orders'])->orderBy('id', 'desc'); + $query = User::with(['marks', 'orders'])->orderBy('id', 'desc'); - // SEARCH FILTER - if (!empty($search)) { - $query->where(function ($q) use ($search) { - $q->where('customer_name', 'like', "%$search%") - ->orWhere('email', 'like', "%$search%") - ->orWhere('mobile_no', 'like', "%$search%") - ->orWhere('customer_id', 'like', "%$search%"); - }); - } - - // STATUS FILTER - if (!empty($status) && in_array($status, ['active', 'inactive'])) { - $query->where('status', $status); - } - - $customers = $query->get(); - - return view('admin.customers', compact('customers', 'search', 'status')); + // SEARCH FILTER + if (!empty($search)) { + $query->where(function ($q) use ($search) { + $q->where('customer_name', 'like', "%$search%") + ->orWhere('email', 'like', "%$search%") + ->orWhere('mobile_no', 'like', "%$search%") + ->orWhere('customer_id', 'like', "%$search%"); + }); } + // STATUS FILTER + if (!empty($status) && in_array($status, ['active', 'inactive'])) { + $query->where('status', $status); + } + + // Get all customers for statistics (without pagination) + $allCustomers = $query->get(); + + // Get paginated customers for the table (10 per page) + $customers = $query->paginate(10); + + return view('admin.customers', compact('customers', 'allCustomers', 'search', 'status')); +} + // --------------------------------------------------------- // SHOW ADD CUSTOMER FORM // --------------------------------------------------------- @@ -130,5 +136,6 @@ class AdminCustomerController extends Controller return back()->with('success', 'Customer status updated.'); } + } diff --git a/app/Http/Controllers/RequestController.php b/app/Http/Controllers/RequestController.php index 685271c..e2078c1 100644 --- a/app/Http/Controllers/RequestController.php +++ b/app/Http/Controllers/RequestController.php @@ -44,6 +44,8 @@ class RequestController extends Controller 'pincode' => $request->pincode, 'date' => Carbon::now()->toDateString(), // Auto current date 'status' => 'pending', // Default status + + ]); // ✅ Response diff --git a/public/invoices/invoice-INV-2025-000026.pdf b/public/invoices/invoice-INV-2025-000026.pdf new file mode 100644 index 0000000..619708c Binary files /dev/null and b/public/invoices/invoice-INV-2025-000026.pdf differ diff --git a/resources/views/admin/account.blade.php b/resources/views/admin/account.blade.php index 454de4c..4bbc8f4 100644 --- a/resources/views/admin/account.blade.php +++ b/resources/views/admin/account.blade.php @@ -523,6 +523,20 @@ tr:hover td{ background:#fbfdff; } .entry-summary-cards { gap: 12px; } .entry-summary-card { min-width: 140px; } } + +/* Table pagination wrapper */ +.table-pagination-wrapper { + margin-top: 20px; + border-top: 1px solid #eef3fb; + padding-top: 15px; +} + +/* Modal pagination wrapper */ +.modal-pagination-wrapper { + margin-top: 15px; + border-top: 1px solid #eef3fb; + padding-top: 12px; +}
@@ -551,6 +565,7 @@ tr:hover td{ background:#fbfdff; }
+
Payment Sent to China @@ -564,11 +579,34 @@ tr:hover td{ background:#fbfdff; } - Loading entries... + + + +
+
+
Showing 0 entries
+
+ +
+ +
+ +
+
+
+
Order Dispatch Status @@ -583,9 +621,31 @@ tr:hover td{ background:#fbfdff; } - Loading entries... + + + +
+
+
Showing 0 entries
+
+ +
+ +
+ +
+
+
@@ -649,29 +709,29 @@ tr:hover td{ background:#fbfdff; } - Loading available orders... + - -
-
Showing 1 to 10 of 0 entries
-
- -
- + +
@@ -682,8 +742,6 @@ tr:hover td{ background:#fbfdff; }
- -
Tip: Select orders from the list to include them in this consolidated entry. You can also search orders above.
@@ -787,7 +845,6 @@ function jsonFetch(url, opts = {}) { opts.headers = Object.assign({'Content-Type':'application/json','X-CSRF-TOKEN': csrfToken}, opts.headers || {}); if(opts.body && typeof opts.body !== 'string') opts.body = JSON.stringify(opts.body); return fetch(url, opts).then(r => { - // attempt to parse json even on non-ok to get backend message return r.json().catch(() => { throw new Error('Invalid server response'); }); }); } @@ -796,9 +853,13 @@ let entries = []; let availableOrders = []; let currentEntry = null; -/* Pagination state */ +/* Single pagination state for both tables */ let currentPage = 1; -const ordersPerPage = 10; +const entriesPerPage = 10; + +/* Separate pagination state for modal */ +let modalCurrentPage = 1; +const modalOrdersPerPage = 10; /* small util */ function escapeHtml(s){ if(s === null || s === undefined) return ''; return String(s).replace(/[&<>"']/g, m => ({'&':'&','<':'<','>':'>','"':'"',"'":"'"}[m])); } @@ -828,9 +889,17 @@ function bindUI(){ document.getElementById('cancelCreateModal').addEventListener('click', closeCreateOrderModal); document.getElementById('createOrderInlineForm').addEventListener('submit', submitCreateOrderInline); - // Pagination buttons - document.getElementById('prevPageBtn').addEventListener('click', goToPreviousPage); - document.getElementById('nextPageBtn').addEventListener('click', goToNextPage); + // Payment Table Pagination + document.getElementById('paymentPrevBtn').addEventListener('click', () => goToPreviousPage()); + document.getElementById('paymentNextBtn').addEventListener('click', () => goToNextPage()); + + // Order Table Pagination + document.getElementById('orderPrevBtn').addEventListener('click', () => goToPreviousPage()); + document.getElementById('orderNextBtn').addEventListener('click', () => goToNextPage()); + + // Modal Pagination + document.getElementById('modalPrevBtn').addEventListener('click', () => goToModalPreviousPage()); + document.getElementById('modalNextBtn').addEventListener('click', () => goToModalNextPage()); document.getElementById('refreshBtn').addEventListener('click', () => { loadDashboard(); }); document.getElementById('searchBtn').addEventListener('click', handleSearch); @@ -848,34 +917,58 @@ function bindUI(){ function goToPreviousPage() { if (currentPage > 1) { currentPage--; - renderConsolidateOrders(availableOrders); - updatePaginationControls(); + renderBothTables(); + updateBothPaginationControls(); } } function goToNextPage() { - const totalPages = Math.ceil(availableOrders.length / ordersPerPage); + const totalPages = Math.ceil(entries.length / entriesPerPage); if (currentPage < totalPages) { currentPage++; - renderConsolidateOrders(availableOrders); - updatePaginationControls(); + renderBothTables(); + updateBothPaginationControls(); } } -function updatePaginationControls() { - const totalPages = Math.ceil(availableOrders.length / ordersPerPage); - const prevBtn = document.getElementById('prevPageBtn'); - const nextBtn = document.getElementById('nextPageBtn'); - const pageInfo = document.getElementById('pageInfo'); - const paginationPages = document.getElementById('paginationPages'); +function goToModalPreviousPage() { + if (modalCurrentPage > 1) { + modalCurrentPage--; + renderConsolidateOrders(availableOrders); + updateModalPaginationControls(); + } +} + +function goToModalNextPage() { + const totalPages = Math.ceil(availableOrders.length / modalOrdersPerPage); + if (modalCurrentPage < totalPages) { + modalCurrentPage++; + renderConsolidateOrders(availableOrders); + updateModalPaginationControls(); + } +} + +function updateBothPaginationControls() { + const totalPages = Math.ceil(entries.length / entriesPerPage); + + // Update both pagination controls + updatePaginationControls('payment', totalPages); + updatePaginationControls('order', totalPages); +} + +function updatePaginationControls(tableType, totalPages) { + const prevBtn = document.getElementById(tableType + 'PrevBtn'); + const nextBtn = document.getElementById(tableType + 'NextBtn'); + const pageInfo = document.getElementById(tableType + 'PageInfo'); + const paginationPages = document.getElementById(tableType + 'PaginationPages'); prevBtn.disabled = currentPage === 1; nextBtn.disabled = currentPage === totalPages || totalPages === 0; // Update page info text - const startIndex = (currentPage - 1) * ordersPerPage + 1; - const endIndex = Math.min(currentPage * ordersPerPage, availableOrders.length); - pageInfo.textContent = `Showing ${startIndex} to ${endIndex} of ${availableOrders.length} entries`; + const startIndex = (currentPage - 1) * entriesPerPage + 1; + const endIndex = Math.min(currentPage * entriesPerPage, entries.length); + pageInfo.textContent = `Showing ${startIndex} to ${endIndex} of ${entries.length} entries`; // Generate page numbers paginationPages.innerHTML = ''; @@ -908,49 +1001,113 @@ function updatePaginationControls() { } } +function updateModalPaginationControls() { + const totalPages = Math.ceil(availableOrders.length / modalOrdersPerPage); + const prevBtn = document.getElementById('modalPrevBtn'); + const nextBtn = document.getElementById('modalNextBtn'); + const pageInfo = document.getElementById('modalPageInfo'); + const paginationPages = document.getElementById('modalPaginationPages'); + + prevBtn.disabled = modalCurrentPage === 1; + nextBtn.disabled = modalCurrentPage === totalPages || totalPages === 0; + + // Update page info text + const startIndex = (modalCurrentPage - 1) * modalOrdersPerPage + 1; + const endIndex = Math.min(modalCurrentPage * modalOrdersPerPage, availableOrders.length); + pageInfo.textContent = `Showing ${startIndex} to ${endIndex} of ${availableOrders.length} orders`; + + // Generate page numbers + paginationPages.innerHTML = ''; + + if (totalPages <= 7) { + // Show all pages + for (let i = 1; i <= totalPages; i++) { + addModalPageButton(i, paginationPages); + } + } else { + // Show first page, current page range, and last page + addModalPageButton(1, paginationPages); + + if (modalCurrentPage > 3) { + paginationPages.innerHTML += '...'; + } + + const start = Math.max(2, modalCurrentPage - 1); + const end = Math.min(totalPages - 1, modalCurrentPage + 1); + + for (let i = start; i <= end; i++) { + addModalPageButton(i, paginationPages); + } + + if (modalCurrentPage < totalPages - 2) { + paginationPages.innerHTML += '...'; + } + + addModalPageButton(totalPages, paginationPages); + } +} + function addPageButton(pageNumber, container) { const button = document.createElement('button'); button.className = 'pagination-page-btn'; + if (pageNumber === currentPage) { button.classList.add('active'); } + button.textContent = pageNumber; button.addEventListener('click', () => { currentPage = pageNumber; - renderConsolidateOrders(availableOrders); - updatePaginationControls(); + renderBothTables(); + updateBothPaginationControls(); }); container.appendChild(button); } +function addModalPageButton(pageNumber, container) { + const button = document.createElement('button'); + button.className = 'pagination-page-btn'; + + if (pageNumber === modalCurrentPage) { + button.classList.add('active'); + } + + button.textContent = pageNumber; + button.addEventListener('click', () => { + modalCurrentPage = pageNumber; + renderConsolidateOrders(availableOrders); + updateModalPaginationControls(); + }); + container.appendChild(button); +} + +function renderBothTables() { + renderPaymentTable(entries); + renderOrderTable(entries); +} + /* ---------- Create Order Modal Functions ---------- */ function openCreateOrderModal(){ const modal = document.getElementById('createOrderModal'); modal.classList.add('modal-open'); loadAvailableOrders(); - // focus first input setTimeout(()=> document.getElementById('inline_description').focus(), 220); } function closeCreateOrderModal(){ const modal = document.getElementById('createOrderModal'); modal.classList.remove('modal-open'); - // reset form and pagination document.getElementById('createOrderInlineForm').reset(); - currentPage = 1; + modalCurrentPage = 1; // Reset modal pagination when closing } /* ---------- Loaders ---------- */ function loadDashboard(){ - // show loading placeholders - document.getElementById('paymentTableBody').innerHTML = 'Loading entries...'; - document.getElementById('orderTableBody').innerHTML = 'Loading entries...'; jsonFetch('/admin/account/dashboard') .then(res => { if(!res.success) throw new Error(res.message || 'Failed to load dashboard'); entries = res.entries || []; - renderPaymentTable(entries); - renderOrderTable(entries); + renderBothTables(); document.getElementById('entriesCount').textContent = entries.length; }) .catch(err => { @@ -967,14 +1124,14 @@ function loadAvailableOrders(){ .then(res => { if(!res.success) throw new Error(res.message || 'Failed to load orders'); availableOrders = res.orders || []; - currentPage = 1; // Reset to first page when loading new orders + modalCurrentPage = 1; // Reset to first page when loading new orders renderConsolidateOrders(availableOrders); - updatePaginationControls(); + updateModalPaginationControls(); }) .catch(err => { console.error(err); tbody.innerHTML = 'Unable to load orders'; - updatePaginationControls(); + updateModalPaginationControls(); }); } @@ -982,11 +1139,18 @@ function loadAvailableOrders(){ function renderPaymentTable(list){ const body = document.getElementById('paymentTableBody'); body.innerHTML = ''; + if(!list || list.length === 0){ body.innerHTML = 'No entries found'; return; } - list.forEach(entry => { + + // Calculate pagination + const startIndex = (currentPage - 1) * entriesPerPage; + const endIndex = startIndex + entriesPerPage; + const paginatedEntries = list.slice(startIndex, endIndex); + + paginatedEntries.forEach(entry => { const tr = document.createElement('tr'); tr.innerHTML = ` ${escapeHtml(entry.entry_no)} @@ -1011,11 +1175,18 @@ function renderPaymentTable(list){ function renderOrderTable(list){ const body = document.getElementById('orderTableBody'); body.innerHTML = ''; + if(!list || list.length === 0){ body.innerHTML = 'No entries found'; return; } - list.forEach(entry => { + + // Calculate pagination + const startIndex = (currentPage - 1) * entriesPerPage; + const endIndex = startIndex + entriesPerPage; + const paginatedEntries = list.slice(startIndex, endIndex); + + paginatedEntries.forEach(entry => { const tr = document.createElement('tr'); const pending = Number(entry.pending_amount || 0); const pendingHtml = pending <= 0 ? 'Completed' : `${formatCurrency(pending)}`; @@ -1047,12 +1218,13 @@ function renderConsolidateOrders(list){ if(!list || list.length === 0){ body.innerHTML = 'No available orders'; + updateModalPaginationControls(); return; } - // Calculate pagination - const startIndex = (currentPage - 1) * ordersPerPage; - const endIndex = startIndex + ordersPerPage; + // Calculate pagination for modal + const startIndex = (modalCurrentPage - 1) * modalOrdersPerPage; + const endIndex = startIndex + modalOrdersPerPage; const paginatedOrders = list.slice(startIndex, endIndex); paginatedOrders.forEach(order => { @@ -1156,14 +1328,19 @@ async function submitCreateOrderInline(e){ /* ---------- Search ---------- */ function handleSearch(){ const q = document.getElementById('main-search').value.trim().toLowerCase(); - if(!q){ renderPaymentTable(entries); renderOrderTable(entries); return; } + if(!q){ + renderBothTables(); + return; + } const filtered = entries.filter(e => { return String(e.entry_no || '').toLowerCase().includes(q) || String(e.description || '').toLowerCase().includes(q) || String(e.region || '').toLowerCase().includes(q); }); - renderPaymentTable(filtered); - renderOrderTable(filtered); + entries = filtered; + currentPage = 1; // Reset to first page when searching + renderBothTables(); + updateBothPaginationControls(); } /* ---------- Entry details & installments ---------- */ @@ -1289,10 +1466,6 @@ async function submitInstallment(e){ if(btn){ btn.disabled = false; btn.textContent = 'Create Installment'; } } } - -/* ---------- Utilities ---------- */ -// ensure consolidate area visible by default -document.addEventListener('DOMContentLoaded', () => { document.getElementById('consolidateArea').style.display = 'block'; }); @endsection \ No newline at end of file diff --git a/resources/views/admin/customers.blade.php b/resources/views/admin/customers.blade.php index dd20aef..17162ce 100644 --- a/resources/views/admin/customers.blade.php +++ b/resources/views/admin/customers.blade.php @@ -288,7 +288,140 @@ flex-wrap: nowrap; gap: 8px; } - + + /* ---------- Pagination Styles (Same as Account Dashboard) ---------- */ + .pagination-container { + display: flex; + justify-content: space-between; + align-items: center; + margin-top: 15px; + padding: 12px 0; + border-top: 1px solid #eef3fb; + } + + .pagination-info { + font-size: 13px; + color: #9ba5bb; + font-weight: 600; + } + + .pagination-controls { + display: flex; + align-items: center; + gap: 8px; + } + + .pagination-btn { + background: #fff; + border: 1px solid #e3eaf6; + color: #1a2951; + padding: 8px 12px; + border-radius: 6px; + font-size: 13px; + font-weight: 600; + cursor: pointer; + transition: all 0.3s ease; + display: flex; + align-items: center; + justify-content: center; + min-width: 40px; + height: 32px; + } + + .pagination-btn:hover:not(:disabled) { + background: #1a2951; + color: white; + border-color: #1a2951; + } + + .pagination-btn:disabled { + background: #f8fafc; + color: #cbd5e0; + border-color: #e2e8f0; + cursor: not-allowed; + opacity: 0.6; + } + + .pagination-page-btn { + background: #fff; + border: 1px solid #e3eaf6; + color: #1a2951; + padding: 6px 12px; + border-radius: 6px; + font-size: 13px; + font-weight: 600; + cursor: pointer; + transition: all 0.3s ease; + min-width: 36px; + text-align: center; + } + + .pagination-page-btn:hover { + background: #1a2951; + color: white; + border-color: #1a2951; + } + + .pagination-page-btn.active { + background: #1a2951; + color: white; + border-color: #1a2951; + } + + .pagination-pages { + display: flex; + gap: 4px; + align-items: center; + } + + .pagination-ellipsis { + color: #9ba5bb; + font-size: 13px; + padding: 0 4px; + } + + /* Image-based pagination buttons */ + .pagination-img-btn { + background: #fff; + border: 1px solid #e3eaf6; + border-radius: 6px; + cursor: pointer; + transition: all 0.3s ease; + display: flex; + align-items: center; + justify-content: center; + min-width: 40px; + height: 32px; + padding: 0; + } + + .pagination-img-btn:hover:not(:disabled) { + background: #1a2951; + border-color: #1a2951; + } + + .pagination-img-btn:disabled { + background: #f8fafc; + border-color: #e2e8f0; + cursor: not-allowed; + opacity: 0.5; + } + + .pagination-img-btn img { + width: 16px; + height: 16px; + filter: brightness(0) saturate(100%) invert(26%) sepia(89%) saturate(748%) hue-rotate(201deg) brightness(93%) contrast(89%); + transition: filter 0.3s ease; + } + + .pagination-img-btn:hover:not(:disabled) img { + filter: brightness(0) saturate(100%) invert(100%) sepia(100%) saturate(0%) hue-rotate(288deg) brightness(106%) contrast(101%); + } + + .pagination-img-btn:disabled img { + filter: brightness(0) saturate(100%) invert(84%) sepia(8%) saturate(165%) hue-rotate(179deg) brightness(89%) contrast(86%); + } + @media (max-width: 768px) { .search-filter-container { flex-direction: column; @@ -303,6 +436,16 @@ justify-content: center; flex-wrap: wrap; } + + .pagination-container { + flex-direction: column; + gap: 10px; + align-items: stretch; + } + + .pagination-controls { + justify-content: center; + } } @@ -315,7 +458,7 @@
-
{{ $customers->count() }}
+
{{ $allCustomers->count() }}
Total Customers
@@ -323,7 +466,7 @@
@php - $newThisMonth = $customers->filter(function($customer) { + $newThisMonth = $allCustomers->filter(function($customer) { return $customer->created_at->format('Y-m') === now()->format('Y-m'); })->count(); @endphp @@ -336,7 +479,7 @@
@php - $activeCustomers = $customers->where('status', 'active')->count(); + $activeCustomers = $allCustomers->where('status', 'active')->count(); @endphp {{ $activeCustomers }}
@@ -347,7 +490,7 @@
@php - $premiumCount = $customers->where('customer_type', 'premium')->count(); + $premiumCount = $allCustomers->where('customer_type', 'premium')->count(); @endphp {{ $premiumCount }}
@@ -413,7 +556,7 @@ Actions - + @forelse($customers as $c) @@ -489,6 +632,64 @@
+ + +
+
+ Showing {{ $customers->firstItem() ?? 0 }} to {{ $customers->lastItem() ?? 0 }} of {{ $customers->total() }} entries +
+
+ +
+ @for ($i = 1; $i <= $customers->lastPage(); $i++) + + {{ $i }} + + @endfor +
+ +
+
+ + @endsection \ No newline at end of file diff --git a/resources/views/admin/dashboard.blade.php b/resources/views/admin/dashboard.blade.php index 1dc430a..d209de2 100644 --- a/resources/views/admin/dashboard.blade.php +++ b/resources/views/admin/dashboard.blade.php @@ -556,6 +556,138 @@ body, .container-fluid { overflow-y: auto; } +/* ===== PAGINATION STYLES ===== */ +.pagination-container { + display: flex; + justify-content: space-between; + align-items: center; + margin-top: 15px; + padding: 12px 0; + border-top: 1px solid #eef3fb; +} + +.pagination-info { + font-size: 13px; + color: #9ba5bb; + font-weight: 600; +} + +.pagination-controls { + display: flex; + align-items: center; + gap: 8px; +} + +.pagination-btn { + background: #fff; + border: 1px solid #e3eaf6; + color: #1a2951; + padding: 8px 12px; + border-radius: 6px; + font-size: 13px; + font-weight: 600; + cursor: pointer; + transition: all 0.3s ease; + display: flex; + align-items: center; + justify-content: center; + min-width: 40px; + height: 32px; +} + +.pagination-btn:hover:not(:disabled) { + background: #1a2951; + color: white; + border-color: #1a2951; +} + +.pagination-btn:disabled { + background: #f8fafc; + color: #cbd5e0; + border-color: #e2e8f0; + cursor: not-allowed; + opacity: 0.6; +} + +.pagination-page-btn { + background: #fff; + border: 1px solid #e3eaf6; + color: #1a2951; + padding: 6px 12px; + border-radius: 6px; + font-size: 13px; + font-weight: 600; + cursor: pointer; + transition: all 0.3s ease; + min-width: 36px; + text-align: center; +} + +.pagination-page-btn:hover { + background: #1a2951; + color: white; + border-color: #1a2951; +} + +.pagination-page-btn.active { + background: #1a2951; + color: white; + border-color: #1a2951; +} + +.pagination-pages { + display: flex; + gap: 4px; + align-items: center; +} + +.pagination-ellipsis { + color: #9ba5bb; + font-size: 13px; + padding: 0 4px; +} + +.pagination-img-btn { + background: #fff; + border: 1px solid #e3eaf6; + border-radius: 6px; + cursor: pointer; + transition: all 0.3s ease; + display: flex; + align-items: center; + justify-content: center; + min-width: 40px; + height: 32px; + padding: 0; +} + +.pagination-img-btn:hover:not(:disabled) { + background: #1a2951; + border-color: #1a2951; +} + +.pagination-img-btn:disabled { + background: #f8fafc; + border-color: #e2e8f0; + cursor: not-allowed; + opacity: 0.5; +} + +.pagination-img-btn img { + width: 16px; + height: 16px; + filter: brightness(0) saturate(100%) invert(26%) sepia(89%) saturate(748%) hue-rotate(201deg) brightness(93%) contrast(89%); + transition: filter 0.3s ease; +} + +.pagination-img-btn:hover:not(:disabled) img { + filter: brightness(0) saturate(100%) invert(100%) sepia(100%) saturate(0%) hue-rotate(288deg) brightness(106%) contrast(101%); +} + +.pagination-img-btn:disabled img { + filter: brightness(0) saturate(100%) invert(84%) sepia(8%) saturate(165%) hue-rotate(179deg) brightness(89%) contrast(86%); +} + /* ===== RESPONSIVE BREAKPOINTS ===== */ /* Laptop (1200px and below) */ @@ -598,6 +730,16 @@ body, .container-fluid { .table td { padding: 10px 5px; } + + .pagination-container { + flex-direction: column; + gap: 10px; + align-items: stretch; + } + + .pagination-controls { + justify-content: center; + } } /* Mobile Landscape (768px and below) */ @@ -900,6 +1042,9 @@ body, .container-fluid {
Recent Orders + + Total orders: {{ $orders->count() }} +
@@ -923,7 +1068,7 @@ body, .container-fluid { - + @forelse($orders as $order) @@ -963,6 +1108,28 @@ body, .container-fluid { @endforelse
Actions
{{ $order->id }}
+ + +
+
Showing 1 to 10 of {{ $orders->count() }} entries
+
+ +
+ +
+ +
+
@@ -1167,6 +1334,14 @@ document.addEventListener('DOMContentLoaded', function() { const closeBtn = document.getElementById('closeCreateOrderModal'); const clearFormBtn = document.getElementById('clearForm'); + // Pagination state + let currentPage = 1; + const ordersPerPage = 10; + let allOrders = @json($orders->values()); + + // Initialize pagination + initializePagination(); + // Reset temp data function const resetTempData = () => { fetch('{{ route("admin.orders.temp.reset") }}', { @@ -1265,6 +1440,168 @@ document.addEventListener('DOMContentLoaded', function() { }); }); }); + + /* ---------- Pagination Functions ---------- */ + function initializePagination() { + renderOrdersTable(allOrders); + updatePaginationControls(); + + // Bind pagination buttons + document.getElementById('prevPageBtn').addEventListener('click', goToPreviousPage); + document.getElementById('nextPageBtn').addEventListener('click', goToNextPage); + } + + function goToPreviousPage() { + if (currentPage > 1) { + currentPage--; + renderOrdersTable(allOrders); + updatePaginationControls(); + } + } + + function goToNextPage() { + const totalPages = Math.ceil(allOrders.length / ordersPerPage); + if (currentPage < totalPages) { + currentPage++; + renderOrdersTable(allOrders); + updatePaginationControls(); + } + } + + function updatePaginationControls() { + const totalPages = Math.ceil(allOrders.length / ordersPerPage); + const prevBtn = document.getElementById('prevPageBtn'); + const nextBtn = document.getElementById('nextPageBtn'); + const pageInfo = document.getElementById('pageInfo'); + const paginationPages = document.getElementById('paginationPages'); + + prevBtn.disabled = currentPage === 1; + nextBtn.disabled = currentPage === totalPages || totalPages === 0; + + // Update page info text + const startIndex = (currentPage - 1) * ordersPerPage + 1; + const endIndex = Math.min(currentPage * ordersPerPage, allOrders.length); + pageInfo.textContent = `Showing ${startIndex} to ${endIndex} of ${allOrders.length} entries`; + + // Generate page numbers + paginationPages.innerHTML = ''; + + if (totalPages <= 7) { + // Show all pages + for (let i = 1; i <= totalPages; i++) { + addPageButton(i, paginationPages); + } + } else { + // Show first page, current page range, and last page + addPageButton(1, paginationPages); + + if (currentPage > 3) { + paginationPages.innerHTML += '...'; + } + + const start = Math.max(2, currentPage - 1); + const end = Math.min(totalPages - 1, currentPage + 1); + + for (let i = start; i <= end; i++) { + addPageButton(i, paginationPages); + } + + if (currentPage < totalPages - 2) { + paginationPages.innerHTML += '...'; + } + + addPageButton(totalPages, paginationPages); + } + } + + function addPageButton(pageNumber, container) { + const button = document.createElement('button'); + button.className = 'pagination-page-btn'; + if (pageNumber === currentPage) { + button.classList.add('active'); + } + button.textContent = pageNumber; + button.addEventListener('click', () => { + currentPage = pageNumber; + renderOrdersTable(allOrders); + updatePaginationControls(); + }); + container.appendChild(button); + } + + function renderOrdersTable(orders) { + const tbody = document.getElementById('ordersTableBody'); + tbody.innerHTML = ''; + + if (!orders || orders.length === 0) { + tbody.innerHTML = 'No orders found'; + return; + } + + // Calculate pagination + const startIndex = (currentPage - 1) * ordersPerPage; + const endIndex = startIndex + ordersPerPage; + const paginatedOrders = orders.slice(startIndex, endIndex); + + paginatedOrders.forEach(order => { + const tr = document.createElement('tr'); + tr.innerHTML = ` + ${order.id} + + + ${order.order_id} + + + ${order.mark_no || ''} + ${order.origin || ''} + ${order.destination || ''} + ${order.ctn || ''} + ${order.qty || ''} + ${order.ttl_qty || ''} + ₹${order.ttl_amount ? Number(order.ttl_amount).toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 }) : '0.00'} + ${order.cbm || ''} + ${order.ttl_cbm || ''} + ${order.kg || ''} + ${order.ttl_kg || ''} + + ${order.status ? order.status.charAt(0).toUpperCase() + order.status.slice(1) : ''} + + ${new Date(order.created_at).toLocaleDateString('en-GB')} + + + View + + + `; + tbody.appendChild(tr); + + // Re-bind order details modal for newly rendered rows + const orderLink = tr.querySelector('.open-order-modal'); + if (orderLink) { + orderLink.addEventListener('click', function() { + let id = this.dataset.id; + let modal = new bootstrap.Modal(document.getElementById('orderDetailsModal')); + + document.getElementById('orderDetailsBody').innerHTML = + "

Loading...

"; + + modal.show(); + + fetch(`/admin/orders/view/${id}`) + .then(response => response.text()) + .then(html => { + document.getElementById('orderDetailsBody').innerHTML = html; + }) + .catch(() => { + document.getElementById('orderDetailsBody').innerHTML = + "

Failed to load order details.

"; + }); + }); + } + }); + } }); diff --git a/resources/views/admin/invoice.blade.php b/resources/views/admin/invoice.blade.php index f76d1eb..8582bd9 100644 --- a/resources/views/admin/invoice.blade.php +++ b/resources/views/admin/invoice.blade.php @@ -737,6 +737,139 @@ border: none; } +/* ---------- Pagination Styles (Same as Account Dashboard) ---------- */ +.pagination-container { + display: flex; + justify-content: space-between; + align-items: center; + margin-top: 15px; + padding: 12px 25px; + border-top: 1px solid #eef3fb; +} + +.pagination-info { + font-size: 13px; + color: #9ba5bb; + font-weight: 600; +} + +.pagination-controls { + display: flex; + align-items: center; + gap: 8px; +} + +.pagination-btn { + background: #fff; + border: 1px solid #e3eaf6; + color: #1a2951; + padding: 8px 12px; + border-radius: 6px; + font-size: 13px; + font-weight: 600; + cursor: pointer; + transition: all 0.3s ease; + display: flex; + align-items: center; + justify-content: center; + min-width: 40px; + height: 32px; +} + +.pagination-btn:hover:not(:disabled) { + background: #1a2951; + color: white; + border-color: #1a2951; +} + +.pagination-btn:disabled { + background: #f8fafc; + color: #cbd5e0; + border-color: #e2e8f0; + cursor: not-allowed; + opacity: 0.6; +} + +.pagination-page-btn { + background: #fff; + border: 1px solid #e3eaf6; + color: #1a2951; + padding: 6px 12px; + border-radius: 6px; + font-size: 13px; + font-weight: 600; + cursor: pointer; + transition: all 0.3s ease; + min-width: 36px; + text-align: center; +} + +.pagination-page-btn:hover { + background: #1a2951; + color: white; + border-color: #1a2951; +} + +.pagination-page-btn.active { + background: #1a2951; + color: white; + border-color: #1a2951; +} + +.pagination-pages { + display: flex; + gap: 4px; + align-items: center; +} + +.pagination-ellipsis { + color: #9ba5bb; + font-size: 13px; + padding: 0 4px; +} + +/* Image-based pagination buttons */ +.pagination-img-btn { + background: #fff; + border: 1px solid #e3eaf6; + border-radius: 6px; + cursor: pointer; + transition: all 0.3s ease; + display: flex; + align-items: center; + justify-content: center; + min-width: 40px; + height: 32px; + padding: 0; +} + +.pagination-img-btn:hover:not(:disabled) { + background: #1a2951; + border-color: #1a2951; +} + +.pagination-img-btn:disabled { + background: #f8fafc; + border-color: #e2e8f0; + cursor: not-allowed; + opacity: 0.5; +} + +.pagination-img-btn img { + width: 16px; + height: 16px; + filter: brightness(0) saturate(100%) invert(26%) sepia(89%) saturate(748%) hue-rotate(201deg) brightness(93%) contrast(89%); + transition: filter 0.3s ease; +} + +.pagination-img-btn:hover:not(:disabled) img { + filter: brightness(0) saturate(100%) invert(100%) sepia(100%) saturate(0%) hue-rotate(288deg) brightness(106%) contrast(101%); +} + +.pagination-img-btn:disabled img { + filter: brightness(0) saturate(100%) invert(84%) sepia(8%) saturate(165%) hue-rotate(179deg) brightness(89%) contrast(86%); +} + /* Responsive Design */ @media (max-width: 1200px) { .invoice-tools-row { @@ -835,6 +968,16 @@ grid-template-columns: 1fr; margin: 15px; } + + .pagination-container { + flex-direction: column; + gap: 10px; + align-items: stretch; + } + + .pagination-controls { + justify-content: center; + } } @media (max-width: 576px) { @@ -944,7 +1087,7 @@ - + @php $totalInvoices = $invoices->count(); $sortedInvoices = $invoices->sortByDesc('created_at'); // Latest first @@ -1006,7 +1149,7 @@
-
+
@php $totalInvoices = $invoices->count(); $sortedInvoices = $invoices->sortByDesc('created_at'); // Latest first @@ -1073,6 +1216,28 @@
No invoices found
@endforelse
+ + +
+
Showing 1 to {{ $invoices->count() }} of {{ $invoices->count() }} entries
+
+ +
+ +
+ +
+
@@ -1095,6 +1260,20 @@ diff --git a/resources/views/admin/layouts/app.blade.php b/resources/views/admin/layouts/app.blade.php index 2984c72..e437cc3 100644 --- a/resources/views/admin/layouts/app.blade.php +++ b/resources/views/admin/layouts/app.blade.php @@ -218,7 +218,7 @@
@csrf - +
diff --git a/resources/views/admin/mark_list.blade.php b/resources/views/admin/mark_list.blade.php index 82249bb..7ff94f2 100644 --- a/resources/views/admin/mark_list.blade.php +++ b/resources/views/admin/mark_list.blade.php @@ -277,6 +277,139 @@ from { box-shadow: 0 0 0px #b4a02455 inset; } to { box-shadow: 0 0 10px #b4a024aa inset; } } + + /* ---------- Pagination Styles ---------- */ + .pagination-container { + display: flex; + justify-content: space-between; + align-items: center; + margin-top: 15px; + padding: 12px 0; + border-top: 1px solid #eef3fb; + } + + .pagination-info { + font-size: 13px; + color: #9ba5bb; + font-weight: 600; + } + + .pagination-controls { + display: flex; + align-items: center; + gap: 8px; + } + + .pagination-btn { + background: #fff; + border: 1px solid #e3eaf6; + color: #1a2951; + padding: 8px 12px; + border-radius: 6px; + font-size: 13px; + font-weight: 600; + cursor: pointer; + transition: all 0.3s ease; + display: flex; + align-items: center; + justify-content: center; + min-width: 40px; + height: 32px; + } + + .pagination-btn:hover:not(:disabled) { + background: #1a2951; + color: white; + border-color: #1a2951; + } + + .pagination-btn:disabled { + background: #f8fafc; + color: #cbd5e0; + border-color: #e2e8f0; + cursor: not-allowed; + opacity: 0.6; + } + + .pagination-page-btn { + background: #fff; + border: 1px solid #e3eaf6; + color: #1a2951; + padding: 6px 12px; + border-radius: 6px; + font-size: 13px; + font-weight: 600; + cursor: pointer; + transition: all 0.3s ease; + min-width: 36px; + text-align: center; + } + + .pagination-page-btn:hover { + background: #1a2951; + color: white; + border-color: #1a2951; + } + + .pagination-page-btn.active { + background: #1a2951; + color: white; + border-color: #1a2951; + } + + .pagination-pages { + display: flex; + gap: 4px; + align-items: center; + } + + .pagination-ellipsis { + color: #9ba5bb; + font-size: 13px; + padding: 0 4px; + } + + /* Image-based pagination buttons */ + .pagination-img-btn { + background: #fff; + border: 1px solid #e3eaf6; + border-radius: 6px; + cursor: pointer; + transition: all 0.3s ease; + display: flex; + align-items: center; + justify-content: center; + min-width: 40px; + height: 32px; + padding: 0; + } + + .pagination-img-btn:hover:not(:disabled) { + background: #1a2951; + border-color: #1a2951; + } + + .pagination-img-btn:disabled { + background: #f8fafc; + border-color: #e2e8f0; + cursor: not-allowed; + opacity: 0.5; + } + + .pagination-img-btn img { + width: 16px; + height: 16px; + filter: brightness(0) saturate(100%) invert(26%) sepia(89%) saturate(748%) hue-rotate(201deg) brightness(93%) contrast(89%); + transition: filter 0.3s ease; + } + + .pagination-img-btn:hover:not(:disabled) img { + filter: brightness(0) saturate(100%) invert(100%) sepia(100%) saturate(0%) hue-rotate(288deg) brightness(106%) contrast(101%); + } + + .pagination-img-btn:disabled img { + filter: brightness(0) saturate(100%) invert(84%) sepia(8%) saturate(165%) hue-rotate(179deg) brightness(89%) contrast(86%); + } @if(session('success')) @@ -304,63 +437,207 @@ Action - - @foreach($markList as $mark) - - {{ $mark->id }} - {{ $mark->mark_no }} - {{ $mark->origin }} - {{ $mark->destination }} - {{ $mark->customer_name }} - {{ $mark->customer_id }} - {{ $mark->mobile_no }} - {{ \Carbon\Carbon::parse($mark->date)->format('d-m-Y') }} - - @if($mark->status == 'active') - - - Active - - @else - - - In-Active - - @endif - - - @if($mark->status == 'active') - - - Deactivate - - @else - - - Activate - - @endif - - - @endforeach + + - @if($markList->isEmpty()) -
No mark numbers found.
- @endif + +
+
Showing 0 entries
+
+ +
+ +
+ +
+
+ + diff --git a/resources/views/admin/orders.blade.php b/resources/views/admin/orders.blade.php index 9d421ba..2e4d102 100644 --- a/resources/views/admin/orders.blade.php +++ b/resources/views/admin/orders.blade.php @@ -146,6 +146,139 @@ html, body { padding: 16px; } } + + /* ---------- Pagination Styles (Same as Account Dashboard) ---------- */ + .pagination-container { + display: flex; + justify-content: space-between; + align-items: center; + margin-top: 15px; + padding: 12px 0; + border-top: 1px solid #eef3fb; + } + + .pagination-info { + font-size: 13px; + color: #9ba5bb; + font-weight: 600; + } + + .pagination-controls { + display: flex; + align-items: center; + gap: 8px; + } + + .pagination-btn { + background: #fff; + border: 1px solid #e3eaf6; + color: #1a2951; + padding: 8px 12px; + border-radius: 6px; + font-size: 13px; + font-weight: 600; + cursor: pointer; + transition: all 0.3s ease; + display: flex; + align-items: center; + justify-content: center; + min-width: 40px; + height: 32px; + } + + .pagination-btn:hover:not(:disabled) { + background: #1a2951; + color: white; + border-color: #1a2951; + } + + .pagination-btn:disabled { + background: #f8fafc; + color: #cbd5e0; + border-color: #e2e8f0; + cursor: not-allowed; + opacity: 0.6; + } + + .pagination-page-btn { + background: #fff; + border: 1px solid #e3eaf6; + color: #1a2951; + padding: 6px 12px; + border-radius: 6px; + font-size: 13px; + font-weight: 600; + cursor: pointer; + transition: all 0.3s ease; + min-width: 36px; + text-align: center; + } + + .pagination-page-btn:hover { + background: #1a2951; + color: white; + border-color: #1a2951; + } + + .pagination-page-btn.active { + background: #1a2951; + color: white; + border-color: #1a2951; + } + + .pagination-pages { + display: flex; + gap: 4px; + align-items: center; + } + + .pagination-ellipsis { + color: #9ba5bb; + font-size: 13px; + padding: 0 4px; + } + + /* Image-based pagination buttons */ + .pagination-img-btn { + background: #fff; + border: 1px solid #e3eaf6; + border-radius: 6px; + cursor: pointer; + transition: all 0.3s ease; + display: flex; + align-items: center; + justify-content: center; + min-width: 40px; + height: 32px; + padding: 0; + } + + .pagination-img-btn:hover:not(:disabled) { + background: #1a2951; + border-color: #1a2951; + } + + .pagination-img-btn:disabled { + background: #f8fafc; + border-color: #e2e8f0; + cursor: not-allowed; + opacity: 0.5; + } + + .pagination-img-btn img { + width: 16px; + height: 16px; + filter: brightness(0) saturate(100%) invert(26%) sepia(89%) saturate(748%) hue-rotate(201deg) brightness(93%) contrast(89%); + transition: filter 0.3s ease; + } + + .pagination-img-btn:hover:not(:disabled) img { + filter: brightness(0) saturate(100%) invert(100%) sepia(100%) saturate(0%) hue-rotate(288deg) brightness(106%) contrast(101%); + } + + .pagination-img-btn:disabled img { + filter: brightness(0) saturate(100%) invert(84%) sepia(8%) saturate(165%) hue-rotate(179deg) brightness(89%) contrast(86%); + } {{-- Make sure you include Font Awesome CDN in your main layout file, e.g., in : @@ -179,9 +312,8 @@ html, body { - + @foreach($orders as $order) - @php $mark = $order->markList ?? null; $invoice = $order->invoice ?? null; @@ -239,11 +371,32 @@ html, body { - @endforeach {{-- End table-wrapper --}} + + +
+
Showing 1 to {{ min(10, count($orders)) }} of {{ count($orders) }} entries
+
+ +
+ +
+ +
+
@else

No orders found. @@ -251,4 +404,158 @@ html, body { @endif + + @endsection \ No newline at end of file diff --git a/resources/views/admin/reports.blade.php b/resources/views/admin/reports.blade.php index 8049351..b2f37a3 100644 --- a/resources/views/admin/reports.blade.php +++ b/resources/views/admin/reports.blade.php @@ -541,6 +541,139 @@ background: #a8a8a8; } + /* ---------- Pagination Styles (Same as Account Dashboard) ---------- */ + .pagination-container { + display: flex; + justify-content: space-between; + align-items: center; + margin-top: 15px; + padding: 12px 0; + border-top: 1px solid #eef3fb; + } + + .pagination-info { + font-size: 13px; + color: #9ba5bb; + font-weight: 600; + } + + .pagination-controls { + display: flex; + align-items: center; + gap: 8px; + } + + .pagination-btn { + background: #fff; + border: 1px solid #e3eaf6; + color: #1a2951; + padding: 8px 12px; + border-radius: 6px; + font-size: 13px; + font-weight: 600; + cursor: pointer; + transition: all 0.3s ease; + display: flex; + align-items: center; + justify-content: center; + min-width: 40px; + height: 32px; + } + + .pagination-btn:hover:not(:disabled) { + background: #1a2951; + color: white; + border-color: #1a2951; + } + + .pagination-btn:disabled { + background: #f8fafc; + color: #cbd5e0; + border-color: #e2e8f0; + cursor: not-allowed; + opacity: 0.6; + } + + .pagination-page-btn { + background: #fff; + border: 1px solid #e3eaf6; + color: #1a2951; + padding: 6px 12px; + border-radius: 6px; + font-size: 13px; + font-weight: 600; + cursor: pointer; + transition: all 0.3s ease; + min-width: 36px; + text-align: center; + } + + .pagination-page-btn:hover { + background: #1a2951; + color: white; + border-color: #1a2951; + } + + .pagination-page-btn.active { + background: #1a2951; + color: white; + border-color: #1a2951; + } + + .pagination-pages { + display: flex; + gap: 4px; + align-items: center; + } + + .pagination-ellipsis { + color: #9ba5bb; + font-size: 13px; + padding: 0 4px; + } + + /* Image-based pagination buttons */ + .pagination-img-btn { + background: #fff; + border: 1px solid #e3eaf6; + border-radius: 6px; + cursor: pointer; + transition: all 0.3s ease; + display: flex; + align-items: center; + justify-content: center; + min-width: 40px; + height: 32px; + padding: 0; + } + + .pagination-img-btn:hover:not(:disabled) { + background: #1a2951; + border-color: #1a2951; + } + + .pagination-img-btn:disabled { + background: #f8fafc; + border-color: #e2e8f0; + cursor: not-allowed; + opacity: 0.5; + } + + .pagination-img-btn img { + width: 16px; + height: 16px; + filter: brightness(0) saturate(100%) invert(26%) sepia(89%) saturate(748%) hue-rotate(201deg) brightness(93%) contrast(89%); + transition: filter 0.3s ease; + } + + .pagination-img-btn:hover:not(:disabled) img { + filter: brightness(0) saturate(100%) invert(100%) sepia(100%) saturate(0%) hue-rotate(288deg) brightness(106%) contrast(101%); + } + + .pagination-img-btn:disabled img { + filter: brightness(0) saturate(100%) invert(84%) sepia(8%) saturate(165%) hue-rotate(179deg) brightness(89%) contrast(86%); + } + @media (max-width: 1024px) { .stats-container { grid-template-columns: repeat(3, 1fr); @@ -604,6 +737,16 @@ min-width: 100px; padding: 10px 8px; } + + .pagination-container { + flex-direction: column; + gap: 10px; + align-items: stretch; + } + + .pagination-controls { + justify-content: center; + } } @media (max-width: 480px) { @@ -833,12 +976,42 @@ + + +

+
Showing 1 to {{ min(10, count($reports)) }} of {{ count($reports) }} entries
+
+ +
+ +
+ +
+