{{-- Customer Documents listing — docs/wireframes-v12/upload-document.html, content region for content region (CR-15 §3.1). Two regions, top to bottom: the page action bar (the Upload New Document button on the right, on its own row above the card), then ONE card carrying the `.filter-bar` and the `.data-table` — the filters are the card's own header strip, not a card of their own. That is the shape every v12 management page uses and the shape projects/index and brokers/index use. DataTables drives the table. Its own search box stays out of the dom string because the wireframe's `.search-input` in the filter bar is the one the user sees; the script below feeds the plugin from it. The column list exists only in CustomerDocumentsDataTable::getColumns(). ## Deliberate differences from the wireframe * **A row is a BOOKING, not a document** (decision D4, client instruction §1) — "Show booking wise customer … and make sure atleast one document uploaded for that booking". Everything below follows from that. * **Five columns are gone** (decision D6, the client's own list): ID, Co-Applicant, File Name, Size and Status. The Co-Applicant is inside the Customer dropdown now; the other four describe one file where a row describes a booking, and there is no status column on `customer_docs` at all. * **Two filters are gone** (decision D7, the client's list): All Co-Applicants and All Status. What is left is the search box, All Customers and All Document Types. * **The Customers and Document Types filters are dynamic** where v12 hardcodes three or four mock names: a filter offering somebody with no documents returns an empty table and looks broken. CR-12 §D7 records the same reasoning for the Brokers listing's City filter. * **Two of the four row actions are gone** and two are added — see partials/actions.blade.php, which carries the reasoning per icon. * **The two in-row selects are the client's**, and the wireframe has no such thing. They are plain `.form-control` selects sized to the cell by `.cd-cell-select` (the CR-15 block in nrems-wireframe.css). ## No lang file (CR-15 §0.3) Every string on this screen is written here, on the client's instruction — including the ones the client module puts on screen, which come in through one JSON `data-strings` attribute rather than living in Javascript. That is the rule nrems-unit-import.js established and nrems-booking-form.js repeats: the module holds no wording of its own. --}} @extends('layouts.app') @section('title', 'Upload Documents') @section('breadcrumbs') @endsection @section('content') @php /* * Defaulted here as well as skipped in the controller on an ajax draw. * Either alone would be enough today; together they mean the page cannot * break on the difference between two ways of asking for it — the 500 * CR-7 shipped and then closed twice over. */ $customers = $customers ?? []; $docTypes = $docTypes ?? []; /* * Everything the client module can put on screen, in one attribute. * * `no_document` and `blank` are decision D9's literal and this * application's em-dash — both also rendered server-side by the * partials, so the two sides say one thing. * * `delete_confirm` is GONE with CR-15.3 item H2: the confirmation is no * longer a sentence this module passes to `window.confirm`, it is the * shared dialog included at the foot of this file, and its wording lives * there. The `delete` / `delete_aria` pair stays — they are the button's * own title and label, which this module still renders. */ $strings = [ 'no_document' => 'No Document', 'blank' => '—', 'download' => 'Download', 'download_aria' => 'Download document', 'edit' => 'Edit', 'edit_aria' => 'Edit document', 'delete' => 'Delete', 'delete_aria' => 'Delete document', 'customer_aria' => 'Customer', 'type_aria' => 'Document type', ]; @endphp {{-- v12 puts the primary action on its own right-aligned row at the top of the content region, with an empty left-hand cell (upload-document.html:78-81). The button is gated; the row is not, because an empty row is the wireframe's own layout. --}}
@can('customer_documents.create') Upload New Document @endcan
{{-- The filter bar IS the card's header strip in v12. It is a
here only so Enter does not reload the page; `.filter-bar` is the flex row, so the form element carries it directly. v12 labels none of these controls — a placeholder and an option list are all it draws. The visually-hidden labels are ours and are not a visual change: a select whose only name is its first option is unusable with a screen reader. --}}
{{-- The wireframe's placeholder is "Search by customer, file name...". The file-name half went with its column (decision D6), so the wording says what the box actually does: the booking code, or any person on the booking. --}}
{{-- `table-wrapper` is v12's own scroll box. `table-responsive` rides along because it is Bootstrap's name for the same thing and the one the shared component and its test both use; this screen does not go through that component (v12's card has no card-body around the table) but the two names stay together so a later reader does not read the difference as meaningful. --}}
{!! $dataTable->table(['class' => 'data-table']) !!}
{{-- The row delete confirmation (CR-15.3 item H2). Outside the card above and at the END of the content section, for the clipping reason the partial's own header records — and it is what pushes the toaster and the delete client, so the buttons this page renders need nothing of their own. --}} @include('customer-documents.partials.delete-modal') @endsection @push('styles') @endpush @push('scripts') {{-- Order is load bearing: jQuery (plugins.bundle.js, already in the layout) → core library → the Bootstrap 5 integration that patches its renderers → yajra's init, which calls $(…).DataTable(…) and would throw without the two above. --}} {!! $dataTable->scripts() !!} {{-- The row dropdowns, and the three cells they re-render. Loaded after yajra's init so the module can hook the table's own `draw` event; it also listens on the document, so a row DataTables replaces on a sort or a page turn keeps working without re-binding. --}} @endpush