414 lines
13 KiB
PHP
414 lines
13 KiB
PHP
@extends('admin.layouts.app')
|
||
|
||
@section('page-title', 'Container Details')
|
||
|
||
@section('content')
|
||
<style>
|
||
@import url('https://fonts.googleapis.com/css2?family=DM+Sans:wght@400;500;600;700&display=swap');
|
||
|
||
/* ── TOP HEADER CARD ── */
|
||
.cm-header-card {
|
||
background: linear-gradient(100deg, #4c6fff 0%, #8e54e9 100%);
|
||
border-radius: 14px;
|
||
border: none;
|
||
box-shadow: 0 6px 24px rgba(76,111,255,0.22);
|
||
margin-bottom: 18px;
|
||
color: #fff;
|
||
}
|
||
.cm-header-card .card-body {
|
||
padding: 14px 20px;
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
gap: 10px;
|
||
}
|
||
.cm-header-title {
|
||
margin: 0;
|
||
font-size: 19px;
|
||
font-weight: 700;
|
||
letter-spacing: -0.3px;
|
||
}
|
||
.cm-header-sub {
|
||
font-size: 12px;
|
||
opacity: 0.88;
|
||
margin-top: 2px;
|
||
}
|
||
|
||
/* ── MAIN CARD ── */
|
||
.cm-main-card {
|
||
border-radius: 14px;
|
||
border: none;
|
||
box-shadow: 0 4px 20px rgba(15,35,52,0.10);
|
||
overflow: hidden;
|
||
background: #fff;
|
||
}
|
||
.cm-main-card .card-header {
|
||
background: #fff;
|
||
border-bottom: 1px solid #edf0f5;
|
||
padding: 12px 20px;
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
}
|
||
.cm-main-card .card-header h5 {
|
||
margin: 0;
|
||
font-size: 15px;
|
||
font-weight: 700;
|
||
color: #1a2340;
|
||
}
|
||
|
||
/* ── INFO STRIP ── */
|
||
.cm-info-strip {
|
||
display: flex;
|
||
gap: 28px;
|
||
padding: 12px 20px 0 20px;
|
||
flex-wrap: wrap;
|
||
}
|
||
.cm-info-label {
|
||
font-size: 11px;
|
||
color: #8a93a6;
|
||
font-weight: 600;
|
||
text-transform: uppercase;
|
||
letter-spacing: 0.5px;
|
||
margin-bottom: 2px;
|
||
}
|
||
.cm-info-value {
|
||
font-size: 13px;
|
||
font-weight: 600;
|
||
color: #1a2340;
|
||
}
|
||
|
||
/* ── FILTER BAR ── */
|
||
.cm-filter-bar {
|
||
padding: 12px 20px 0 20px;
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
gap: 10px;
|
||
flex-wrap: wrap;
|
||
}
|
||
.cm-row-count {
|
||
font-size: 12px;
|
||
color: #8a93a6;
|
||
font-weight: 500;
|
||
}
|
||
.cm-filter-input {
|
||
max-width: 240px;
|
||
font-size: 12px;
|
||
border-radius: 20px;
|
||
border: 1px solid #dde2ee;
|
||
padding: 6px 14px;
|
||
outline: none;
|
||
transition: border 0.2s;
|
||
}
|
||
.cm-filter-input:focus {
|
||
border-color: #4c6fff;
|
||
box-shadow: 0 0 0 3px rgba(76,111,255,0.1);
|
||
}
|
||
|
||
/* ── TABLE SCROLL OUTER ── */
|
||
.cm-table-scroll-outer {
|
||
margin: 10px 14px 0 14px;
|
||
border-radius: 14px 14px 0 0;
|
||
/* इथे overflow: hidden होते, ते visible केले */
|
||
overflow-x: auto; /* फक्त horizontal scroll हवा असेल तर */
|
||
overflow-y: visible;
|
||
border: 1.5px solid #b8920e;
|
||
border-bottom: none;
|
||
box-shadow: 0 -2px 10px rgba(184,146,14,0.10);
|
||
}
|
||
|
||
/* ── TABLE WRAPPER ── */
|
||
.cm-table-wrapper {
|
||
position: relative;
|
||
/* इथे max-height, overflow auto काढले, जे inner scroll देत होते */
|
||
max-height: none;
|
||
overflow: visible;
|
||
border-top: none;
|
||
}
|
||
|
||
/* ── TABLE STYLES ── */
|
||
.cm-table {
|
||
font-size: 12px;
|
||
min-width: 1100px;
|
||
width: 100%;
|
||
border-collapse: separate;
|
||
border-spacing: 0;
|
||
font-family: 'DM Sans', sans-serif;
|
||
}
|
||
|
||
/* Sticky header – light header color */
|
||
.cm-table thead tr th {
|
||
position: sticky;
|
||
top: 0;
|
||
z-index: 3;
|
||
background: #fde4b3;
|
||
color: #0a0a09;
|
||
font-weight: 700;
|
||
font-size: 12px;
|
||
padding: 11px 14px;
|
||
border-bottom: 2px solid #fde4b3;
|
||
border-right: 1px solid #fde4b3;
|
||
white-space: nowrap;
|
||
text-align: center;
|
||
letter-spacing: 0.2px;
|
||
text-shadow: 0 1px 2px rgba(0,0,0,0.18);
|
||
}
|
||
.cm-table thead tr th:last-child {
|
||
border-right: none;
|
||
}
|
||
|
||
/* # column – narrower */
|
||
.cm-table thead tr th:first-child,
|
||
.cm-table tbody tr td:first-child {
|
||
width: 46px;
|
||
min-width: 46px;
|
||
max-width: 46px;
|
||
text-align: center;
|
||
}
|
||
|
||
/* Body rows */
|
||
.cm-table tbody tr td {
|
||
padding: 8px 14px;
|
||
border-bottom: 1px solid #f0f3fb;
|
||
border-right: 1px solid #f0f3fb;
|
||
color: #2d3a55;
|
||
font-size: 12.5px;
|
||
text-align: center;
|
||
vertical-align: middle;
|
||
background: #fff;
|
||
transition: background 0.15s;
|
||
}
|
||
.cm-table tbody tr td:last-child {
|
||
border-right: none;
|
||
}
|
||
|
||
/* Zebra */
|
||
.cm-table tbody tr:nth-child(even) td {
|
||
background: #f8f9ff;
|
||
}
|
||
/* Hover */
|
||
.cm-table tbody tr:hover td {
|
||
background: #edf3ff !important;
|
||
}
|
||
|
||
/* Row number td */
|
||
.cm-row-num {
|
||
color: #8a93a6;
|
||
font-size: 11px;
|
||
font-weight: 600;
|
||
}
|
||
|
||
/* Editable cell input */
|
||
.cm-cell-input {
|
||
width: 100%;
|
||
min-width: 90px;
|
||
background: transparent;
|
||
border: 1.5px solid transparent;
|
||
border-radius: 5px;
|
||
font-size: 12.5px;
|
||
font-family: 'DM Sans', sans-serif;
|
||
color: #2d3a55;
|
||
padding: 3px 6px;
|
||
text-align: center;
|
||
transition: border 0.15s, background 0.15s, box-shadow 0.15s;
|
||
outline: none;
|
||
}
|
||
.cm-cell-input:hover {
|
||
border-color: #c9d4f5;
|
||
background: #f5f8ff;
|
||
}
|
||
.cm-cell-input:focus {
|
||
border-color: #4c6fff;
|
||
background: #fff;
|
||
box-shadow: 0 0 0 3px rgba(76,111,255,0.12);
|
||
}
|
||
|
||
/* Save button */
|
||
.cm-save-btn {
|
||
font-size: 12.5px;
|
||
font-weight: 600;
|
||
border-radius: 20px;
|
||
padding: 7px 18px;
|
||
background: linear-gradient(90deg, #4c6fff, #8e54e9);
|
||
border: none;
|
||
color: #fff;
|
||
box-shadow: 0 3px 10px rgba(76,111,255,0.22);
|
||
transition: opacity 0.2s, transform 0.15s;
|
||
cursor: pointer;
|
||
}
|
||
.cm-save-btn:hover {
|
||
opacity: 0.92;
|
||
transform: translateY(-1px);
|
||
}
|
||
|
||
/* Empty state */
|
||
.cm-empty {
|
||
padding: 30px 20px;
|
||
color: #8a93a6;
|
||
font-size: 13px;
|
||
}
|
||
|
||
/* Scrollbar styling – आता फक्त horizontal ला लागू होईल */
|
||
.cm-table-scroll-outer::-webkit-scrollbar { height: 6px; }
|
||
.cm-table-scroll-outer::-webkit-scrollbar-track { background: #f0f3fb; border-radius: 4px; }
|
||
.cm-table-scroll-outer::-webkit-scrollbar-thumb { background: #c5cce8; border-radius: 4px; }
|
||
.cm-table-scroll-outer::-webkit-scrollbar-thumb:hover { background: #8a99d0; }
|
||
|
||
@media (max-width: 767px) {
|
||
.cm-header-card .card-body { flex-direction: column; align-items: flex-start; }
|
||
.cm-info-strip { gap: 16px; }
|
||
.cm-table-scroll-outer { overflow-x: auto; }
|
||
.cm-table { min-width: 900px; }
|
||
}
|
||
</style>
|
||
|
||
<div class="container-fluid cm-wrapper">
|
||
|
||
{{-- TOP GRADIENT HEADER --}}
|
||
<div class="card cm-header-card">
|
||
<div class="card-body">
|
||
<div>
|
||
<h4 class="cm-header-title">
|
||
Container: {{ $container->container_number }}
|
||
</h4>
|
||
<div class="cm-header-sub">
|
||
Edit loading list directly — scroll horizontally & 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-main-card">
|
||
|
||
<div class="card-header">
|
||
<h5>Container Information</h5>
|
||
@if(!$container->rows->isEmpty())
|
||
<button type="submit"
|
||
form="cm-edit-rows-form"
|
||
class="cm-save-btn">
|
||
💾 Save Changes
|
||
</button>
|
||
@endif
|
||
</div>
|
||
|
||
{{-- INFO STRIP --}}
|
||
<div class="cm-info-strip">
|
||
<div class="cm-info-item">
|
||
<div class="cm-info-label">Container</div>
|
||
<div class="cm-info-value">{{ $container->container_name }}</div>
|
||
</div>
|
||
<div class="cm-info-item">
|
||
<div class="cm-info-label">Date</div>
|
||
<div class="cm-info-value">{{ $container->container_date?->format('d-m-Y') }}</div>
|
||
</div>
|
||
<div class="cm-info-item">
|
||
<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" style="color:#4c6fff;text-decoration:none;font-weight:600;">
|
||
📄 Download / View
|
||
</a>
|
||
</div>
|
||
@else
|
||
<div class="cm-info-value" style="color:#b0b8cc;">Not uploaded</div>
|
||
@endif
|
||
</div>
|
||
</div>
|
||
|
||
@if($container->rows->isEmpty())
|
||
<div class="cm-empty">No entries found for this container.</div>
|
||
@else
|
||
@php
|
||
$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">
|
||
<span class="cm-row-count">
|
||
Total rows: {{ $container->rows->count() }} • Edit cells then click "Save Changes"
|
||
</span>
|
||
<input type="text"
|
||
id="cmRowSearch"
|
||
class="cm-filter-input"
|
||
placeholder="🔍 Quick search..."
|
||
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-scroll-outer">
|
||
<div class="cm-table-wrapper">
|
||
<table class="cm-table" id="cmExcelTable">
|
||
<thead>
|
||
<tr>
|
||
<th>#</th>
|
||
@foreach($allHeadings as $heading)
|
||
<th>{{ $heading }}</th>
|
||
@endforeach
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
@foreach($container->rows as $index => $row)
|
||
<tr>
|
||
<td class="cm-row-num">{{ $index + 1 }}</td>
|
||
@foreach($allHeadings as $heading)
|
||
@php $value = $row->data[$heading] ?? ''; @endphp
|
||
<td>
|
||
<input type="text"
|
||
class="cm-cell-input"
|
||
name="rows[{{ $row->id }}][{{ $heading }}]"
|
||
value="{{ $value }}">
|
||
</td>
|
||
@endforeach
|
||
</tr>
|
||
@endforeach
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
</div>
|
||
</form>
|
||
@endif
|
||
</div>
|
||
|
||
</div>
|
||
|
||
<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++) {
|
||
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
|