Files
Kent-logistics-Laravel/resources/views/admin/container_show.blade.php

414 lines
13 KiB
PHP
Raw Normal View History

2026-02-27 10:51:26 +05:30
@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 &amp; 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() }} &nbsp;&nbsp; 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