2026-06-25 18:24:59 +02:00
< div >
< x - slot name = "header" >
{{ -- ── Cabecera ─────────────────────────────────────────────────────────── -- }}
2026-05-07 23:31:33 +02:00
< div class = "flex justify-between items-center mb-4" >
2026-06-25 17:26:12 +02:00
< div >
< h1 class = "text-xl font-bold" > 📋 {{ __ ( 'Inspection templates' ) }} </ h1 >
< p class = "text-sm text-base-content/60" > {{ __ ( 'Global catalogue, reusable across all projects.' ) }} </ p >
</ div >
2026-06-25 18:24:59 +02:00
< div class = "flex items-center gap-4" >
2026-06-25 14:18:21 +02:00
< button wire : click = "openImportFileModal" class = "btn btn-outline btn-sm gap-1" title = "{{ __('Import from CSV/Excel') }}" >
< x - heroicon - o - document - arrow - up class = "w-4 h-4" />
{{ __ ( 'Import CSV/Excel' ) }}
</ button >
2026-05-11 15:32:00 +02:00
< button wire : click = "newTemplate" class = "btn btn-primary btn-sm" >
2026-06-17 10:56:25 +02:00
{{ __ ( 'New template' ) }}
2026-05-11 15:32:00 +02:00
</ button >
</ div >
2026-05-07 23:31:33 +02:00
</ div >
2026-06-25 18:24:59 +02:00
</ x - slot >
2026-05-07 23:31:33 +02:00
2026-06-25 18:24:59 +02:00
< div class = "py-12" >
< div class = "max-w-7xl mx-auto sm:px-6 lg:px-8" >
< div class = "bg-white rounded-lg shadow p-6" >
@ if ( $showForm )
< form wire : submit . prevent = "saveTemplate" class = "border p-4 rounded mb-6 bg-base-200" >
< table class = "w-full mb-8" >
< tbody >
< tr >
< td class = "w-1/4 py-3 pr-4 align-top" > {{ __ ( 'Template name' ) }} </ td >
< td class = "py-3" >< input type = "text" wire : model = "form.name" class = "input w-full" required ></ td >
</ tr >
< tr >
< td class = "w-1/4 py-3 pr-4 align-top" > {{ __ ( 'Description' ) }} </ td >
< td class = "py-3" >< textarea wire : model = "form.description" class = "textarea textarea-bordered w-full" rows = "2" ></ textarea ></ td >
</ tr >
</ tbody >
</ table >
2026-05-07 23:31:33 +02:00
2026-06-25 18:24:59 +02:00
< div class = "border-t pt-4 mt-2" >
< h3 class = "font-bold mb-3" > {{ __ ( 'Form fields' ) }} </ h3 >
@ foreach ( $form [ 'fields' ] as $index => $field )
< div class = "border p-3 rounded mb-3 bg-base-100" >
< div class = "grid grid-cols-1 md:grid-cols-2 gap-4 mb-2" >
< div class = "font-medium" > {{ __ ( 'Group / section' ) }} </ div >
< div >< input type = "text" wire : model = "form.fields.{{ $index }}.group" placeholder = "ej: Geometría" class = "input input-sm w-full" ></ div >
</ div >
< div class = "grid grid-cols-1 md:grid-cols-2 gap-4 mb-2" >
< div class = "font-medium" > {{ __ ( 'Internal name' ) }} </ div >
< div >< input type = "text" wire : model = "form.fields.{{ $index }}.name" placeholder = "ej: altura_medida" class = "input input-sm w-full" ></ div >
</ div >
< div class = "grid grid-cols-1 md:grid-cols-2 gap-4 mb-2" >
< div class = "font-medium" > {{ __ ( 'Visible label' ) }} </ div >
< div >< input type = "text" wire : model = "form.fields.{{ $index }}.label" placeholder = "ej: Altura medida (m)" class = "input input-sm w-full" ></ div >
</ div >
< div class = "grid grid-cols-1 md:grid-cols-2 gap-4 mb-2" >
< div class = "font-medium" > {{ __ ( 'Question / check' ) }} </ div >
< div >< input type = "text" wire : model = "form.fields.{{ $index }}.question" placeholder = "ej: ¿Cumple la cota?" class = "input input-sm w-full" ></ div >
</ div >
< div class = "grid grid-cols-1 md:grid-cols-2 gap-4 mb-2" >
< div class = "font-medium" > {{ __ ( 'Field type' ) }} </ div >
< div >
< select wire : model = "form.fields.{{ $index }}.type" class = "select select-sm w-full" >
@ foreach ( $fieldTypes as $typeValue => $typeLabel )
< option value = "{{ $typeValue }}" > {{ $typeLabel }} </ option >
@ endforeach
</ select >
</ div >
</ div >
< div class = "grid grid-cols-1 md:grid-cols-2 gap-4 mb-2" >
< div class = "font-medium" > {{ __ ( 'Required' ) }} </ div >
< div class = "flex justify-between items-center" >
< input type = "checkbox" wire : model = "form.fields.{{ $index }}.required" class = "checkbox checkbox-sm" >
< button type = "button" wire : click = "removeField({{ $index }})" class = "btn btn-xs btn-error" > {{ __ ( 'Remove field' ) }} </ button >
</ div >
</ div >
@ if ( in_array ( $field [ 'type' ], [ 'integer' , 'decimal' , 'percentage' ]))
< div class = "grid grid-cols-1 md:grid-cols-2 gap-4 mb-2" >
< div class = "font-medium" > {{ __ ( 'Min' ) }} / {{ __ ( 'Max' ) }} / {{ __ ( 'Step' ) }} </ div >
< div class = "flex gap-2" >
< input type = "number" wire : model = "form.fields.{{ $index }}.min" placeholder = "{{ __('Min') }}" class = "input input-xs w-20" >
< input type = "number" wire : model = "form.fields.{{ $index }}.max" placeholder = "{{ __('Max') }}" class = "input input-xs w-20" >
< input type = "number" step = "any" wire : model = "form.fields.{{ $index }}.step" placeholder = "{{ __('Step') }}" class = "input input-xs w-20" >
</ div >
</ div >
@ elseif ( $field [ 'type' ] === 'select' )
< div class = "grid grid-cols-1 md:grid-cols-2 gap-4 mb-2" >
< div class = "font-medium" > {{ __ ( 'Options (comma separated)' ) }} </ div >
< div >< input type = "text" wire : model = "form.fields.{{ $index }}.options" placeholder = "ej: Bueno,Regular,Malo" class = "input input-sm w-full" ></ div >
</ div >
@ endif
< div class = "grid grid-cols-1 md:grid-cols-2 gap-4 mb-2" >
< div class = "font-medium" > {{ __ ( 'Comments / help' ) }} </ div >
< div >< textarea wire : model = "form.fields.{{ $index }}.help" rows = "2" placeholder = "{{ __('Notes or instructions for this field') }}" class = "textarea textarea-bordered textarea-sm w-full" ></ textarea ></ div >
2026-05-07 23:31:33 +02:00
</ div >
</ div >
2026-06-25 18:24:59 +02:00
@ endforeach
< button type = "button" wire : click = "addField" class = "btn btn-sm btn-secondary mt-2" >+ {{ __ ( 'Add field' ) }} </ button >
</ div >
< div class = "flex gap-2 mt-4" >
< button type = "submit" class = "btn btn-primary" > {{ $editingTemplate ? __ ( 'Update' ) : __ ( 'Save template' ) }} </ button >
< button type = "button" wire : click = "cancelForm" class = "btn" > {{ __ ( 'Cancel' ) }} </ button >
</ div >
</ form >
@ endif
{{ -- Tabla Rappasoft ( filtros en cabecera : nombre , descripción , uso ) -- }}
< livewire : inspections . inspection - templates - table : key = "'tpl-table'" />
</ div >
{{ -- MODAL : Importar desde CSV / Excel -- }}
@ if ( $showImportFileModal )
< div class = "fixed inset-0 z-40 bg-black/50" wire : click = " $set ('showImportFileModal', false)" ></ div >
< div class = "fixed inset-0 z-50 flex items-center justify-center p-4" >
< div class = "bg-base-100 rounded-box shadow-2xl w-full max-w-2xl max-h-[90vh] overflow-y-auto" >
< div class = "flex items-center justify-between p-4 border-b border-base-300" >
< h3 class = "font-bold" > {{ __ ( 'Import from CSV/Excel' ) }} </ h3 >
< button wire : click = " $set ('showImportFileModal', false)" class = "btn btn-sm btn-ghost btn-circle" >< x - heroicon - o - x - mark class = "w-4 h-4" /></ button >
</ div >
< div class = "p-4 space-y-3" >
< p class = "text-xs text-base-content/60" >
{{ __ ( 'Columns: name, label, type, required, options, min, max, step' ) }} .
< button type = "button" wire : click = "downloadExampleCsv" class = "link link-primary" > {{ __ ( 'Download example CSV' ) }} </ button >
</ p >
< div class = "form-control" >
< label class = "label" >< span class = "label-text font-medium" > {{ __ ( 'Template name' ) }} < span class = "text-error" >*</ span ></ span ></ label >
< input type = "text" wire : model = "importTemplateName" class = "input input-bordered w-full" />
@ error ( 'importTemplateName' ) < span class = "text-xs text-error" > {{ $message }} </ span >@ enderror
</ div >
< div class = "form-control" >
< label class = "label" >< span class = "label-text font-medium" > {{ __ ( 'File (CSV / Excel)' ) }} < span class = "text-error" >*</ span ></ span ></ label >
< input type = "file" wire : model = "importFile" accept = ".csv,.txt,.xlsx,.xls" class = "file-input file-input-bordered w-full" />
@ error ( 'importFile' ) < span class = "text-xs text-error" > {{ $message }} </ span >@ enderror
</ div >
@ if ( $importError ) < div class = "alert alert-error text-sm py-2" > {{ $importError }} </ div >@ endif
< div class = "flex justify-end" >
< button wire : click = "parseImportFile" class = "btn btn-sm btn-secondary gap-1" >< x - heroicon - o - eye class = "w-4 h-4" /> {{ __ ( 'Preview' ) }} </ button >
</ div >
@ if ( ! empty ( $importPreviewFields ))
< div class = "border border-base-300 rounded-box p-2" >
< p class = "text-sm font-medium mb-2" > {{ count ( $importPreviewFields ) }} {{ __ ( 'fields detected' ) }} :</ p >
< div class = "overflow-x-auto" >
< table class = "table table-xs" >
< thead >< tr >< th > {{ __ ( 'Label' ) }} </ th >< th > {{ __ ( 'Name' ) }} </ th >< th > {{ __ ( 'Type' ) }} </ th >< th > {{ __ ( 'Required' ) }} </ th ></ tr ></ thead >
< tbody >
@ foreach ( $importPreviewFields as $f )
< tr >< td > {{ $f [ 'label' ] }} </ td >< td class = "font-mono text-xs" > {{ $f [ 'name' ] }} </ td >< td >< span class = "badge badge-ghost badge-sm" > {{ $f [ 'type' ] }} </ span ></ td >< td > {{ ! empty ( $f [ 'required' ]) ? '✓' : '' }} </ td ></ tr >
@ endforeach
</ tbody >
</ table >
</ div >
2026-05-07 23:31:33 +02:00
</ div >
@ endif
</ div >
2026-06-25 18:24:59 +02:00
< div class = "flex justify-end gap-2 p-4 border-t border-base-300" >
< button wire : click = " $set ('showImportFileModal', false)" class = "btn btn-ghost btn-sm" > {{ __ ( 'Cancel' ) }} </ button >
< button wire : click = "confirmImportFile" class = "btn btn-primary btn-sm" @ disabled ( empty ( $importPreviewFields )) > {{ __ ( 'Create template' ) }} </ button >
</ div >
</ div >
2026-05-07 23:31:33 +02:00
</ div >
2026-06-25 18:24:59 +02:00
@ endif
2026-05-07 23:31:33 +02:00
</ div >
</ div >
2026-06-25 18:24:59 +02:00
</ div >