487 lines
17 KiB
PHP
487 lines
17 KiB
PHP
|
|
|
|
@extends('admin.layouts.app')
|
|
|
|
@section('page-title', 'Shipment Management')
|
|
|
|
@section('content')
|
|
<style>
|
|
.search-shipment-bar {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 10px;
|
|
padding: 15px;
|
|
background-color: white;
|
|
border-radius: 8px;
|
|
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
|
|
flex-wrap: wrap;
|
|
}
|
|
.search-shipment-bar input,
|
|
.search-shipment-bar select {
|
|
padding: 8px 12px;
|
|
border: 1px solid #ddd;
|
|
border-radius: 4px;
|
|
flex: 1;
|
|
min-width: 150px;
|
|
}
|
|
.btn-add-shipment {
|
|
background-color: #0d6efd;
|
|
color: white;
|
|
border: none;
|
|
padding: 8px 16px;
|
|
border-radius: 4px;
|
|
cursor: pointer;
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 5px;
|
|
transition: background-color 0.3s;
|
|
white-space: nowrap;
|
|
}
|
|
.btn-add-shipment:hover {
|
|
background-color: #0b5ed7;
|
|
}
|
|
.search-icon {
|
|
font-size: 19px;
|
|
}
|
|
.truck-icon {
|
|
font-size: 17px;
|
|
}
|
|
|
|
@media (max-width: 768px) {
|
|
.search-shipment-bar {
|
|
flex-direction: column;
|
|
align-items: stretch;
|
|
}
|
|
.search-shipment-bar input,
|
|
.search-shipment-bar select {
|
|
width: 100%;
|
|
}
|
|
}
|
|
.modal-content {
|
|
border-radius: 16px;
|
|
border: 1px solid #ebe5c5;
|
|
background: #f9faff;
|
|
}
|
|
.modal-header {
|
|
border-radius: 16px 16px 0 0;
|
|
background: #f8f9fc;
|
|
border-bottom: 1px solid #e3e4ed;
|
|
padding: 20px 24px 10px 24px;
|
|
}
|
|
.form-label { font-weight:600; }
|
|
input[type="text"], input[type="date"] {
|
|
border-radius:8px !important;
|
|
font-size:15px !important;
|
|
box-shadow: none;
|
|
background: #fff !important;
|
|
border: 1px solid #ddd !important;
|
|
height: 41px;
|
|
}
|
|
/* Table styles */
|
|
.table-responsive {
|
|
border-radius: 14px;
|
|
overflow: hidden;
|
|
background: #fff;
|
|
border: 1.5px solid #efe5c5;
|
|
box-shadow: 0 2px 10px #ebe6cb;
|
|
padding-top:-10px;
|
|
padding-bottom:8px;
|
|
}
|
|
.custom-table {
|
|
width: 100%;
|
|
border-collapse: separate;
|
|
border-spacing: 0 14px;
|
|
margin:0;
|
|
background: transparent;
|
|
|
|
}
|
|
/* Header row: colored + rounded top */
|
|
.custom-table thead th {
|
|
background: #ffe9be;
|
|
font-weight:700;
|
|
font-size:16px;
|
|
padding: 10px 5px;
|
|
border:none;
|
|
text-align:center;
|
|
|
|
|
|
}
|
|
.custom-table thead tr:first-child th:first-child {
|
|
border-top-left-radius: 12px;
|
|
}
|
|
.custom-table thead tr:first-child th:last-child {
|
|
border-top-right-radius: 12px;
|
|
}
|
|
.custom-table thead tr {
|
|
box-shadow: 0 2px 9px #f4e1b1;
|
|
}
|
|
/* Content row: white + shadow + spacing */
|
|
.custom-table tbody tr {
|
|
background: #fff;
|
|
box-shadow: 0 2px 8px #ececec;
|
|
/* margin-bottom: 14px; this is handled by border-spacing */
|
|
}
|
|
.custom-table tbody td {
|
|
font-size:15px;
|
|
padding:12px 8px;
|
|
text-align:center;
|
|
vertical-align: middle;
|
|
border:none;
|
|
}
|
|
.custom-table tbody tr:first-child td:first-child {
|
|
border-top-left-radius:10px;
|
|
}
|
|
.custom-table tbody tr:first-child td:last-child {
|
|
border-top-right-radius:10px;
|
|
}
|
|
.custom-table tbody tr:last-child td:first-child {
|
|
border-bottom-left-radius:10px;
|
|
}
|
|
.custom-table tbody tr:last-child td:last-child {
|
|
border-bottom-right-radius:10px;
|
|
}
|
|
.btn-cancel {
|
|
background:#fff; color:#222; border:1px solid #bbb; border-radius:8px; font-weight:600; padding:7px 28px;
|
|
}
|
|
.btn-create {
|
|
background:#000; color:#fff; font-weight:600; font-size:17px; border-radius:8px; padding:7px 32px;
|
|
}
|
|
</style>
|
|
<div class="container-fluid py-4">
|
|
|
|
{{-- SUCCESS / ERROR MESSAGES --}}
|
|
@if(session('success'))
|
|
<div class="alert alert-success">{{ session('success') }}</div>
|
|
@endif
|
|
|
|
@if(session('error'))
|
|
<div class="alert alert-danger">{{ session('error') }}</div>
|
|
@endif
|
|
|
|
<!-- ============================= -->
|
|
<!-- SEARCH BAR AND ADD BUTTON -->
|
|
<!-- ============================= -->
|
|
<div class="search-shipment-bar mb-4">
|
|
<span class="search-icon">🔍</span>
|
|
<input type="text" placeholder="Search Shipments...">
|
|
<select>
|
|
<option>All Status</option>
|
|
<option>Pending</option>
|
|
<option>In Transit</option>
|
|
<option>Delivered</option>
|
|
</select>
|
|
<select>
|
|
<option>All Carriers</option>
|
|
<option>FedEx</option>
|
|
<option>UPS</option>
|
|
<option>DHL</option>
|
|
</select>
|
|
<button type="button" class="btn-add-shipment" data-bs-toggle="modal" data-bs-target="#createShipmentModal">
|
|
<span class="truck-icon">🚚</span>
|
|
Add Shipments
|
|
</button>
|
|
</div>
|
|
|
|
<!-- ============================= -->
|
|
<!-- CREATE SHIPMENT MODAL -->
|
|
<!-- ============================= -->
|
|
|
|
|
|
<div class="modal fade" id="createShipmentModal" tabindex="-1" aria-labelledby="createShipmentModalLabel" aria-hidden="true">
|
|
<div class="modal-dialog modal-xl">
|
|
<div class="modal-content">
|
|
<div class="modal-header">
|
|
<h5 class="modal-title" id="createShipmentModalLabel" style="font-weight: bold;">
|
|
Create New Shipment
|
|
</h5>
|
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
|
</div>
|
|
<div class="modal-body">
|
|
<form action="{{ route('admin.shipments.store') }}" method="POST">
|
|
@csrf
|
|
|
|
<div class="row g-3 pb-2">
|
|
<div class="col-md-4">
|
|
<label class="form-label">Origin *</label>
|
|
<input type="text" class="form-control" name="origin" required>
|
|
</div>
|
|
<div class="col-md-4">
|
|
<label class="form-label">Destination *</label>
|
|
<input type="text" class="form-control" name="destination" required>
|
|
</div>
|
|
<div class="col-md-4">
|
|
<label class="form-label">Status</label>
|
|
<input type="text" class="form-control" name="status">
|
|
</div>
|
|
<div class="col-md-4">
|
|
<label class="form-label">Shipment Date</label>
|
|
<input type="date"
|
|
name="shipment_date"
|
|
class="form-control"
|
|
value="{{ date('Y-m-d') }}"
|
|
min="{{ date('Y-m-d') }}"
|
|
required>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="table-responsive" style="max-height:340px;">
|
|
<table class="custom-table">
|
|
<thead>
|
|
<tr>
|
|
<th></th>
|
|
<th>Order ID</th>
|
|
<th>CTN</th>
|
|
<th>QTY</th>
|
|
<th>TTL/QTY</th>
|
|
<th>Price (₹)</th>
|
|
<th>Amount (₹)</th>
|
|
<th>CBM</th>
|
|
<th>TTL CBM</th>
|
|
<th>KG</th>
|
|
<th>TTL KG</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
@forelse($availableOrders as $order)
|
|
<tr>
|
|
<td>
|
|
<input type="checkbox" name="order_ids[]" value="{{ $order->id }}">
|
|
</td>
|
|
<td>
|
|
<a href="#" class="text-primary fw-bold" style="text-decoration:underline;">{{ $order->order_id }}</a>
|
|
</td>
|
|
<td>{{ $order->ctn }}</td>
|
|
<td>{{ $order->qty }}</td>
|
|
<td>{{ $order->ttl_qty }}</td>
|
|
<td>₹{{ number_format($order->unit_price, 2) }}</td>
|
|
<td>₹{{ number_format($order->ttl_amount, 2) }}</td>
|
|
<td>{{ $order->cbm }}</td>
|
|
<td>{{ $order->ttl_cbm }}</td>
|
|
<td>{{ $order->kg }}</td>
|
|
<td>{{ $order->ttl_kg }}</td>
|
|
</tr>
|
|
@empty
|
|
<tr>
|
|
<td colspan="11" class="text-muted">No available orders</td>
|
|
</tr>
|
|
@endforelse
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
<div class="d-flex justify-content-end mt-4 mb-2">
|
|
<button type="button" class="btn-cancel me-2" data-bs-dismiss="modal">Cancel</button>
|
|
<button type="submit" class="btn-create">
|
|
Create Shipment
|
|
</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- ============================= -->
|
|
<!-- SHIPMENT LIST TABLE -->
|
|
<!-- ============================= -->
|
|
<div class="card shadow-sm">
|
|
<div class="card-header bg-light">
|
|
<h5 class="mb-0"><i class="bi bi-table"></i> Shipments List</h5>
|
|
</div>
|
|
|
|
<div class="card-body table-responsive">
|
|
<table class="table table-striped table-bordered text-center align-middle">
|
|
<thead class="table-light">
|
|
<tr>
|
|
<th>#</th>
|
|
<th>Shipment ID</th>
|
|
<th>Origin</th>
|
|
<th>Destination</th>
|
|
|
|
<th>Total QTY</th>
|
|
<th>Total KG</th>
|
|
<th>Total Amount</th>
|
|
|
|
<th>Status</th>
|
|
<th>Date</th>
|
|
<th>Action</th>
|
|
</tr>
|
|
</thead>
|
|
|
|
<tbody>
|
|
@forelse($shipments as $ship)
|
|
<tr>
|
|
<td>{{ $ship->id }}</td>
|
|
|
|
<td>
|
|
<a href="#" class="text-primary fw-bold"
|
|
onclick="openShipmentDetails({{ $ship->id }})">
|
|
{{ $ship->shipment_id }}
|
|
</a>
|
|
</td>
|
|
|
|
<td>{{ $ship->origin }}</td>
|
|
<td>{{ $ship->destination }}</td>
|
|
|
|
<td>{{ $ship->total_qty }}</td>
|
|
<td>{{ $ship->total_kg }}</td>
|
|
<td>₹{{ number_format($ship->total_amount, 2) }}</td>
|
|
|
|
<td>
|
|
<span class="badge bg-info text-dark">{{ ucfirst($ship->status) }}</span>
|
|
</td>
|
|
|
|
<td>{{ $ship->shipment_date }}</td>
|
|
|
|
<td>
|
|
<form action="{{ route('admin.shipments.updateStatus') }}" method="POST" class="d-inline">
|
|
@csrf
|
|
<input type="hidden" name="shipment_id" value="{{ $ship->id }}">
|
|
|
|
<select name="status" class="form-select form-select-sm"
|
|
onchange="this.form.submit()">
|
|
<option value="pending" @selected($ship->status=='pending')>Pending</option>
|
|
<option value="in_transit" @selected($ship->status=='in_transit')>In Transit</option>
|
|
<option value="dispatched" @selected($ship->status=='dispatched')>Dispatched</option>
|
|
<option value="delivered" @selected($ship->status=='delivered')>Delivered</option>
|
|
</select>
|
|
</form>
|
|
</td>
|
|
|
|
</tr>
|
|
@empty
|
|
<tr>
|
|
<td colspan="10" class="text-muted">No shipments found</td>
|
|
</tr>
|
|
@endforelse
|
|
</tbody>
|
|
|
|
</table>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- ============================= -->
|
|
<!-- SHIPMENT DETAILS MODAL -->
|
|
<!-- ============================= -->
|
|
<div class="modal fade" id="shipmentDetailsModal" tabindex="-1">
|
|
<div class="modal-dialog modal-xl modal-dialog-scrollable">
|
|
<div class="modal-content">
|
|
|
|
<div class="modal-header bg-light">
|
|
<h5 class="modal-title fw-bold">Shipment Details</h5>
|
|
<button class="btn-close" data-bs-dismiss="modal"></button>
|
|
</div>
|
|
|
|
<div class="modal-body" id="shipmentDetailsContent">
|
|
<p class="text-center text-muted">Loading...</p>
|
|
</div>
|
|
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<!-- ========================= -->
|
|
<!-- MODAL LOAD SCRIPT (AJAX) -->
|
|
<!-- ========================= -->
|
|
<script>
|
|
function openShipmentDetails(id) {
|
|
let modal = new bootstrap.Modal(document.getElementById('shipmentDetailsModal'));
|
|
document.getElementById('shipmentDetailsContent').innerHTML =
|
|
"<p class='text-center text-muted'>Loading...</p>";
|
|
|
|
fetch(`/admin/shipments/${id}`)
|
|
.then(res => res.json())
|
|
.then(data => {
|
|
|
|
let html = `
|
|
<h5 class="text-primary mb-3">Shipment: ${data.shipment.shipment_id}</h5>
|
|
|
|
<div class="mb-3">
|
|
<strong>Origin:</strong> ${data.shipment.origin}
|
|
<strong>Destination:</strong> ${data.shipment.destination}
|
|
<strong>Status:</strong> ${data.shipment.status}
|
|
</div>
|
|
|
|
<h6 class="fw-bold mt-4">Orders Inside Shipment</h6>
|
|
|
|
<table class="table table-bordered text-center">
|
|
<thead class="table-light">
|
|
<tr>
|
|
<th>Order ID</th>
|
|
<th>Mark No</th>
|
|
<th>Origin</th>
|
|
<th>Destination</th>
|
|
|
|
<th>CTN</th>
|
|
<th>QTY</th>
|
|
<th>TTL QTY</th>
|
|
|
|
<th>TTL Amount</th>
|
|
|
|
<th>CBM</th>
|
|
<th>TTL CBM</th>
|
|
|
|
<th>KG</th>
|
|
<th>TTL KG</th>
|
|
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
`;
|
|
|
|
data.orders.forEach(order => {
|
|
html += `
|
|
<tr>
|
|
<td class="fw-bold text-primary">${order.order_id}</td>
|
|
<td>${order.mark_no}</td>
|
|
<td>${order.origin}</td>
|
|
<td>${order.destination}</td>
|
|
|
|
<td>${order.ctn}</td>
|
|
<td>${order.qty}</td>
|
|
<td>${order.ttl_qty}</td>
|
|
|
|
<td>₹${order.ttl_amount}</td>
|
|
|
|
<td>${order.cbm ?? '-'}</td>
|
|
<td>${order.ttl_cbm ?? '-'}</td>
|
|
|
|
<td>${order.kg}</td>
|
|
<td>${order.ttl_kg}</td>
|
|
|
|
</tr>
|
|
`;
|
|
});
|
|
|
|
html += `
|
|
</tbody>
|
|
</table>
|
|
|
|
<div class="mt-3">
|
|
<strong>Total CTN:</strong> ${data.shipment.total_ctn} <br>
|
|
<strong>Total QTY:</strong> ${data.shipment.total_qty} <br>
|
|
<strong>Total TTL QTY:</strong> ${data.shipment.total_ttl_qty} <br>
|
|
|
|
<strong>Total CBM:</strong> ${data.shipment.total_cbm} <br>
|
|
<strong>Total TTL CBM:</strong> ${data.shipment.total_ttl_cbm} <br>
|
|
|
|
<strong>Total KG:</strong> ${data.shipment.total_kg} <br>
|
|
<strong>Total TTL KG:</strong> ${data.shipment.total_ttl_kg} <br>
|
|
|
|
<strong>Total Amount:</strong> ₹${data.shipment.total_amount}
|
|
</div>
|
|
`;
|
|
|
|
document.getElementById('shipmentDetailsContent').innerHTML = html;
|
|
});
|
|
|
|
modal.show();
|
|
}
|
|
</script>
|
|
|
|
|
|
@endsection |