292 lines
9.0 KiB
PHP
292 lines
9.0 KiB
PHP
@extends('admin.layouts.app')
|
||
|
||
@section('page-title', 'Container Details')
|
||
|
||
@section('content')
|
||
<style>
|
||
.cm-detail-wrapper {
|
||
padding: 10px 0 20px 0;
|
||
}
|
||
.cm-detail-header-card {
|
||
border-radius: 14px;
|
||
border: none;
|
||
margin-bottom: 18px;
|
||
background: linear-gradient(90deg,#4c6fff,#8e54e9);
|
||
box-shadow: 0 6px 18px rgba(15,35,52,0.18);
|
||
color:#ffffff;
|
||
}
|
||
.cm-detail-header-card .card-body {
|
||
padding: 14px 18px;
|
||
display:flex;
|
||
justify-content:space-between;
|
||
align-items:center;
|
||
gap:10px;
|
||
}
|
||
.cm-detail-title {
|
||
margin:0;
|
||
font-size:20px;
|
||
font-weight:600;
|
||
}
|
||
.cm-detail-sub {
|
||
font-size:12px;
|
||
opacity:0.9;
|
||
}
|
||
.cm-detail-main-card {
|
||
border-radius:14px;
|
||
border:none;
|
||
box-shadow:0 6px 18px rgba(15,35,52,0.12);
|
||
overflow:hidden;
|
||
}
|
||
.cm-detail-main-card .card-header {
|
||
background:#ffffff;
|
||
border-bottom:1px solid #edf0f5;
|
||
padding:10px 18px;
|
||
display:flex;
|
||
justify-content:space-between;
|
||
align-items:center;
|
||
gap:10px;
|
||
}
|
||
.cm-detail-main-card .card-header h5 {
|
||
margin:0;
|
||
font-size:16px;
|
||
font-weight:600;
|
||
}
|
||
.cm-info-label {
|
||
font-size:12px;
|
||
color:#6c757d;
|
||
font-weight:500;
|
||
}
|
||
.cm-info-value {
|
||
font-size:13px;
|
||
font-weight:500;
|
||
color:#343a40;
|
||
}
|
||
.cm-table-wrapper {
|
||
position:relative;
|
||
max-height: 520px;
|
||
overflow:auto;
|
||
border-top:1px solid #edf0f5;
|
||
}
|
||
.cm-table {
|
||
font-size:11.5px;
|
||
min-width: 1100px;
|
||
}
|
||
.cm-table thead th {
|
||
position: sticky;
|
||
top: 0;
|
||
z-index: 2;
|
||
background: #fff7e0;
|
||
color:#495057;
|
||
font-weight:600;
|
||
border-bottom:1px solid #e0d2a4;
|
||
white-space:nowrap;
|
||
}
|
||
.cm-table tbody tr:nth-child(even) {
|
||
background:#fafbff;
|
||
}
|
||
.cm-table tbody tr:hover {
|
||
background:#e9f3ff;
|
||
}
|
||
.cm-table td,
|
||
.cm-table th {
|
||
padding:4px 6px;
|
||
vertical-align:middle;
|
||
}
|
||
.cm-table td {
|
||
white-space:nowrap;
|
||
}
|
||
.cm-table-caption {
|
||
font-size:11px;
|
||
color:#868e96;
|
||
padding:6px 18px 0 18px;
|
||
}
|
||
.cm-filter-bar {
|
||
padding:8px 18px 0 18px;
|
||
display:flex;
|
||
justify-content:space-between;
|
||
align-items:center;
|
||
gap:10px;
|
||
flex-wrap:wrap;
|
||
}
|
||
.cm-filter-input {
|
||
max-width:240px;
|
||
font-size:12px;
|
||
border-radius:20px;
|
||
padding:6px 10px;
|
||
}
|
||
.cm-edit-save-btn {
|
||
font-size:12px;
|
||
border-radius:20px;
|
||
padding:6px 14px;
|
||
}
|
||
.cm-cell-input {
|
||
width: 140px;
|
||
min-width: 120px;
|
||
max-width: 220px;
|
||
font-size:11px;
|
||
padding:3px 4px;
|
||
height: 26px;
|
||
}
|
||
@media (max-width: 767px) {
|
||
.cm-detail-header-card .card-body {
|
||
flex-direction:column;
|
||
align-items:flex-start;
|
||
}
|
||
.cm-table-wrapper {
|
||
max-height:400px;
|
||
}
|
||
}
|
||
</style>
|
||
|
||
<div class="container-fluid cm-detail-wrapper">
|
||
|
||
{{-- TOP GRADIENT HEADER --}}
|
||
<div class="card cm-detail-header-card">
|
||
<div class="card-body">
|
||
<div>
|
||
<h4 class="cm-detail-title">
|
||
Container: {{ $container->container_number }}
|
||
</h4>
|
||
<div class="cm-detail-sub">
|
||
Edit loading list directly – scroll horizontally and vertically like Excel.
|
||
</div>
|
||
</div>
|
||
<a href="{{ route('containers.index') }}" class="btn btn-light btn-sm">
|
||
← Back to list
|
||
</a>
|
||
</div>
|
||
</div>
|
||
|
||
{{-- MAIN CARD --}}
|
||
<div class="card cm-detail-main-card">
|
||
<div class="card-header">
|
||
<h5>Container Information</h5>
|
||
|
||
@if(!$container->rows->isEmpty())
|
||
{{-- Save button (submits form below) --}}
|
||
<button type="submit"
|
||
form="cm-edit-rows-form"
|
||
class="btn btn-primary cm-edit-save-btn">
|
||
💾 Save Changes
|
||
</button>
|
||
@endif
|
||
</div>
|
||
|
||
<div class="card-body pb-0">
|
||
{{-- BASIC INFO --}}
|
||
<div class="row g-3 mb-2">
|
||
<div class="col-md-4">
|
||
<div class="cm-info-label">Container</div>
|
||
<div class="cm-info-value">{{ $container->container_name }}</div>
|
||
</div>
|
||
<div class="col-md-4">
|
||
<div class="cm-info-label">Date</div>
|
||
<div class="cm-info-value">
|
||
{{ $container->container_date?->format('d-m-Y') }}
|
||
</div>
|
||
</div>
|
||
<div class="col-md-4">
|
||
<div class="cm-info-label">Excel File</div>
|
||
@if($container->excel_file)
|
||
<div class="cm-info-value">
|
||
<a href="{{ \Illuminate\Support\Facades\Storage::url($container->excel_file) }}"
|
||
target="_blank">
|
||
Download / View Excel
|
||
</a>
|
||
</div>
|
||
@else
|
||
<div class="cm-info-value text-muted">Not uploaded</div>
|
||
@endif
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
@if($container->rows->isEmpty())
|
||
<div class="p-3">
|
||
<p class="mb-0">No entries found for this container.</p>
|
||
</div>
|
||
@else
|
||
@php
|
||
// सर्व headings collect
|
||
$allHeadings = [];
|
||
foreach ($container->rows as $row) {
|
||
if (is_array($row->data)) {
|
||
$allHeadings = array_unique(array_merge($allHeadings, array_keys($row->data)));
|
||
}
|
||
}
|
||
@endphp
|
||
|
||
{{-- FILTER BAR --}}
|
||
<div class="cm-filter-bar">
|
||
<div class="cm-table-caption">
|
||
Total rows: {{ $container->rows->count() }} • Type to filter rows, edit cells then click "Save Changes".
|
||
</div>
|
||
<input type="text" id="cmRowSearch" class="form-control cm-filter-input"
|
||
placeholder="Quick search in table..." onkeyup="cmFilterRows()">
|
||
</div>
|
||
|
||
{{-- EDITABLE TABLE FORM --}}
|
||
<form id="cm-edit-rows-form"
|
||
action="{{ route('containers.rows.update', $container->id) }}"
|
||
method="POST">
|
||
@csrf
|
||
|
||
<div class="cm-table-wrapper mt-1">
|
||
<table class="table table-bordered table-hover cm-table" id="cmExcelTable">
|
||
<thead>
|
||
<tr>
|
||
@foreach($allHeadings as $heading)
|
||
<th>{{ $heading }}</th>
|
||
@endforeach
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
@foreach($container->rows as $row)
|
||
<tr>
|
||
@foreach($allHeadings as $heading)
|
||
@php
|
||
$value = $row->data[$heading] ?? '';
|
||
@endphp
|
||
<td>
|
||
<input type="text"
|
||
class="form-control form-control-sm cm-cell-input"
|
||
name="rows[{{ $row->id }}][{{ $heading }}]"
|
||
value="{{ $value }}">
|
||
</td>
|
||
@endforeach
|
||
</tr>
|
||
@endforeach
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
</form>
|
||
@endif
|
||
</div>
|
||
</div>
|
||
|
||
{{-- SIMPLE FRONT‑END SEARCH --}}
|
||
<script>
|
||
function cmFilterRows() {
|
||
const input = document.getElementById('cmRowSearch');
|
||
if (!input) return;
|
||
const filter = input.value.toLowerCase();
|
||
const table = document.getElementById('cmExcelTable');
|
||
if (!table) return;
|
||
|
||
const rows = table.getElementsByTagName('tr');
|
||
for (let i = 1; i < rows.length; i++) { // skip header
|
||
const cells = rows[i].getElementsByTagName('td');
|
||
let match = false;
|
||
for (let j = 0; j < cells.length; j++) {
|
||
const txt = cells[j].textContent || cells[j].innerText;
|
||
if (txt.toLowerCase().indexOf(filter) > -1) {
|
||
match = true;
|
||
break;
|
||
}
|
||
}
|
||
rows[i].style.display = match ? '' : 'none';
|
||
}
|
||
}
|
||
</script>
|
||
@endsection
|