Files
Kent-logistics-Laravel/resources/views/admin/container_show.blade.php
2026-02-27 10:51:26 +05:30

414 lines
13 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

@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