netgescon-day0/resources/views/filament/pages/fornitore/impostazioni-archivio.blade.php

261 lines
22 KiB
PHP
Executable File

<x-filament-panels::page>
<div class="space-y-4">
<div class="rounded-xl border bg-white p-4">
<div class="flex flex-wrap items-center justify-between gap-3">
<div>
<div class="text-lg font-semibold">Impostazioni fornitore e archivio operativo</div>
<div class="text-sm text-gray-600">
@if($this->fornitore)
Qui concentriamo archivio fornitore, moduli attivabili, import TecnoRepair e collegamento Google di {{ $this->fornitore->ragione_sociale ?? ('Fornitore #' . $this->fornitore->id) }}.
@else
Seleziona un fornitore per aprire questa vista.
@endif
</div>
</div>
<div class="flex flex-wrap gap-2">
<a href="{{ $this->getSchedaFornitoreUrl() }}" class="inline-flex items-center rounded-md bg-gray-800 px-3 py-1.5 text-xs font-medium text-white hover:bg-gray-700">Scheda fornitore</a>
<a href="{{ $this->getTicketsUrl() }}" class="inline-flex items-center rounded-md bg-white px-3 py-1.5 text-xs font-medium text-gray-700 ring-1 ring-inset ring-gray-300 hover:bg-gray-50">Ticket</a>
<a href="{{ $this->getProdottiUrl() }}" class="inline-flex items-center rounded-md bg-white px-3 py-1.5 text-xs font-medium text-gray-700 ring-1 ring-inset ring-gray-300 hover:bg-gray-50">Catalogo fornitore</a>
</div>
</div>
</div>
@if($this->missingAdminContext)
<div class="rounded-xl border border-amber-300 bg-amber-50 p-4 text-sm text-amber-800">
Questa vista richiede un fornitore selezionato.
</div>
@else
<div class="grid gap-4 xl:grid-cols-[1.4fr,1fr]">
<div class="space-y-4">
<div class="rounded-xl border bg-white p-4">
<div class="text-sm font-semibold">Archivio fornitore</div>
<div class="mt-1 text-xs text-gray-500">Il fornitore ora ha una struttura archivio dedicata, parallela a quella degli stabili, pronta per rubrica, FE, prodotti, comunicazioni e import tecnici.</div>
<div class="mt-4 space-y-2 text-sm">
@foreach($archiveFolders as $row)
<div class="rounded-lg border bg-slate-50 p-3">
<div class="font-medium text-slate-900">{{ $row['label'] }}</div>
<div class="mt-1 break-all font-mono text-[11px] text-slate-600">{{ $row['path'] }}</div>
</div>
@endforeach
</div>
</div>
<div class="rounded-xl border bg-white p-4">
<div class="text-sm font-semibold">TecnoRepair MDB</div>
<div class="mt-1 text-xs text-gray-500">Puoi caricare un archivio MDB dalla pagina web oppure indicare un percorso già disponibile sul server. Sono accettati sia path assoluti sia percorsi relativi dentro <span class="font-mono">storage/app</span>.</div>
<div class="mt-4 grid gap-3 md:grid-cols-2">
<label class="block text-sm md:col-span-2">
<span class="mb-1 block font-medium">Percorso MDB attivo</span>
<input type="text" wire:model.defer="tecnorepairMdbPath" class="w-full rounded-lg border-gray-300" placeholder="/percorso/TecnoRepairDB.mdb" />
</label>
<label class="block text-sm md:col-span-2">
<span class="mb-1 block font-medium">Carica archivio MDB</span>
<input type="file" wire:model="tecnorepairMdbUpload" accept=".mdb,application/octet-stream" class="w-full rounded-lg border-gray-300 text-sm" />
</label>
</div>
<div class="mt-4 flex flex-wrap gap-2">
<x-filament::button type="button" color="gray" wire:click="saveUploadedTecnoRepairMdb">Salva MDB in archivio fornitore</x-filament::button>
<x-filament::button type="button" color="primary" wire:click="importTecnoRepairFromArchive(false)">Importa TecnoRepair</x-filament::button>
<x-filament::button type="button" color="info" wire:click="importTecnoRepairFromArchive(true)">Simula import</x-filament::button>
</div>
@if(filled($lastImportOutput))
<div class="mt-4 whitespace-pre-wrap rounded-lg border border-emerald-200 bg-emerald-50 p-3 text-xs text-emerald-900">{{ $lastImportOutput }}</div>
@endif
</div>
<div class="rounded-xl border bg-white p-4">
<div class="flex flex-wrap items-center justify-between gap-2">
<div>
<div class="text-sm font-semibold">Chiavi, accesso e reperibilità</div>
<div class="mt-1 text-xs text-gray-500">Per ogni stabile del fornitore puoi memorizzare chi suonare, dove sono le chiavi e le istruzioni rapide da mostrare nella scheda intervento.</div>
</div>
<x-filament::button type="button" color="gray" wire:click="addStabileAccessRow">Aggiungi stabile</x-filament::button>
</div>
<label class="mt-4 block text-sm">
<span class="mb-1 block font-medium">Nota regia / dispatch board</span>
<textarea wire:model.defer="dispatchBoardNote" rows="3" class="w-full rounded-lg border-gray-300" placeholder="Esempio: chiamare sempre prima il portiere o l'inquilino prima di usare il pass."></textarea>
</label>
<div class="mt-4 space-y-3">
@forelse($stabileAccessRows as $index => $row)
<div class="rounded-xl border bg-slate-50 p-4">
<div class="grid gap-3 md:grid-cols-2">
<label class="block text-sm md:col-span-2">
<span class="mb-1 block font-medium">Stabile</span>
<select wire:model.defer="stabileAccessRows.{{ $index }}.stabile_id" class="w-full rounded-lg border-gray-300">
<option value="">Seleziona stabile</option>
@foreach($stabileOptions as $stabileId => $label)
<option value="{{ $stabileId }}">{{ $label }}</option>
@endforeach
</select>
</label>
<label class="block text-sm">
<span class="mb-1 block font-medium">Chi suonare / campanello</span>
<input type="text" wire:model.defer="stabileAccessRows.{{ $index }}.chi_suonare" class="w-full rounded-lg border-gray-300" placeholder="Es. interno 3, portiere, sig. Rossi" />
</label>
<label class="block text-sm">
<span class="mb-1 block font-medium">Referente sul posto</span>
<input type="text" wire:model.defer="stabileAccessRows.{{ $index }}.contatto_nome" class="w-full rounded-lg border-gray-300" placeholder="Nome e ruolo" />
</label>
<label class="block text-sm">
<span class="mb-1 block font-medium">Telefono referente</span>
<input type="text" wire:model.defer="stabileAccessRows.{{ $index }}.contatto_telefono" class="w-full rounded-lg border-gray-300" placeholder="Cellulare o numero richiamabile" />
</label>
<label class="block text-sm">
<span class="mb-1 block font-medium">Dove sono le chiavi</span>
<input type="text" wire:model.defer="stabileAccessRows.{{ $index }}.dove_sono_chiavi" class="w-full rounded-lg border-gray-300" placeholder="Es. cassetta GK-12, amministratore, portineria" />
</label>
<label class="block text-sm md:col-span-2">
<span class="mb-1 block font-medium">Istruzioni accesso</span>
<textarea wire:model.defer="stabileAccessRows.{{ $index }}.istruzioni_accesso" rows="3" class="w-full rounded-lg border-gray-300" placeholder="Passaggi pratici per entrare, zone comuni, allarmi, portoni, cancelli."></textarea>
</label>
<label class="block text-sm">
<span class="mb-1 block font-medium">Fascia reperibilità</span>
<input type="text" wire:model.defer="stabileAccessRows.{{ $index }}.fascia_reperibilita" class="w-full rounded-lg border-gray-300" placeholder="Es. 8:30-12:30 / 15:00-18:00" />
</label>
<label class="block text-sm">
<span class="mb-1 block font-medium">Note urgenza</span>
<input type="text" wire:model.defer="stabileAccessRows.{{ $index }}.note_urgenza" class="w-full rounded-lg border-gray-300" placeholder="Es. se non risponde nessuno chiamare subito il custode" />
</label>
</div>
<div class="mt-3 flex flex-wrap items-center justify-between gap-2">
<label class="inline-flex items-center gap-2 text-xs text-slate-600">
<input type="checkbox" wire:model.defer="stabileAccessRows.{{ $index }}.is_priority" class="rounded border-gray-300" />
<span>Mostra come accesso prioritario</span>
</label>
<button type="button" wire:click="removeStabileAccessRow({{ $index }})" class="inline-flex items-center rounded-md bg-rose-600 px-2 py-1 text-[11px] font-medium text-white hover:bg-rose-500">Rimuovi</button>
</div>
</div>
@empty
<div class="rounded-xl border border-dashed p-4 text-sm text-gray-500">Nessuna istruzione di accesso configurata. Aggiungi almeno lo stabile dove serve sapere chi suonare o dove recuperare le chiavi.</div>
@endforelse
</div>
</div>
<div class="rounded-xl border bg-white p-4">
<div class="flex flex-wrap items-center justify-between gap-2">
<div>
<div class="text-sm font-semibold">Memoria materiali ricorrenti</div>
<div class="mt-1 text-xs text-gray-500">Preferiti per lampade, ricambi e prodotti che il fornitore usa spesso. Verranno proposti nella scheda intervento.</div>
</div>
<x-filament::button type="button" color="gray" wire:click="addPreferredMaterialRow">Aggiungi materiale</x-filament::button>
</div>
@if(! $operationalConfigAvailable)
<div class="mt-4 rounded-lg border border-amber-300 bg-amber-50 p-3 text-xs text-amber-800">
La memoria materiali richiede la migrazione del database che aggiunge il campo <span class="font-mono">operational_config</span> ai fornitori.
</div>
@endif
<div class="mt-4 space-y-3">
@forelse($preferredMaterialRows as $index => $row)
<div class="rounded-xl border bg-slate-50 p-4">
<div class="grid gap-3 md:grid-cols-2">
<label class="block text-sm md:col-span-2">
<span class="mb-1 block font-medium">Etichetta materiale</span>
<input type="text" wire:model.defer="preferredMaterialRows.{{ $index }}.label" class="w-full rounded-lg border-gray-300" placeholder="Es. Lampadina E27 scala A" />
</label>
<label class="block text-sm">
<span class="mb-1 block font-medium">Marca / modello</span>
<input type="text" wire:model.defer="preferredMaterialRows.{{ $index }}.brand_model" class="w-full rounded-lg border-gray-300" placeholder="Es. Philips CorePro 10W" />
</label>
<label class="block text-sm">
<span class="mb-1 block font-medium">Barcode</span>
<input type="text" wire:model.defer="preferredMaterialRows.{{ $index }}.barcode" class="w-full rounded-lg border-gray-300" />
</label>
<label class="block text-sm">
<span class="mb-1 block font-medium">Codice interno</span>
<input type="text" wire:model.defer="preferredMaterialRows.{{ $index }}.internal_code" class="w-full rounded-lg border-gray-300" />
</label>
<label class="block text-sm">
<span class="mb-1 block font-medium">Fonte preferita</span>
<input type="text" wire:model.defer="preferredMaterialRows.{{ $index }}.preferred_source" class="w-full rounded-lg border-gray-300" placeholder="Catalogo interno, Amazon, grossista, TecnoRepair" />
</label>
<label class="block text-sm md:col-span-2">
<span class="mb-1 block font-medium">URL / riferimento acquisto</span>
<input type="text" wire:model.defer="preferredMaterialRows.{{ $index }}.preferred_url" class="w-full rounded-lg border-gray-300" placeholder="Link referral o pagina prodotto" />
</label>
<label class="block text-sm">
<span class="mb-1 block font-medium">Quantità tipica</span>
<input type="number" step="0.01" min="0.01" wire:model.defer="preferredMaterialRows.{{ $index }}.default_qty" class="w-full rounded-lg border-gray-300" />
</label>
<div class="grid gap-3 md:grid-cols-[1fr,120px] md:col-span-1">
<label class="block text-sm">
<span class="mb-1 block font-medium">Ultimo prezzo noto</span>
<input type="number" step="0.01" min="0" wire:model.defer="preferredMaterialRows.{{ $index }}.last_price" class="w-full rounded-lg border-gray-300" />
</label>
<label class="block text-sm">
<span class="mb-1 block font-medium">Valuta</span>
<input type="text" wire:model.defer="preferredMaterialRows.{{ $index }}.currency" class="w-full rounded-lg border-gray-300" />
</label>
</div>
<label class="block text-sm md:col-span-2">
<span class="mb-1 block font-medium">Nota memoria</span>
<textarea wire:model.defer="preferredMaterialRows.{{ $index }}.note" rows="2" class="w-full rounded-lg border-gray-300" placeholder="Es. usare sempre in vano scala, colore luce calda, alternativa accettata."></textarea>
</label>
</div>
<div class="mt-3 flex justify-end">
<button type="button" wire:click="removePreferredMaterialRow({{ $index }})" class="inline-flex items-center rounded-md bg-rose-600 px-2 py-1 text-[11px] font-medium text-white hover:bg-rose-500">Rimuovi</button>
</div>
</div>
@empty
<div class="rounded-xl border border-dashed p-4 text-sm text-gray-500">Nessun materiale preferito ancora salvato.</div>
@endforelse
</div>
<div class="mt-4">
<x-filament::button type="button" color="primary" wire:click="saveOperationalWorkflow">Salva workflow operativo</x-filament::button>
</div>
</div>
</div>
<div class="space-y-4">
<div class="rounded-xl border bg-white p-4">
<div class="text-sm font-semibold">Moduli fornitore</div>
<div class="mt-3 space-y-2">
@foreach($moduleRows as $row)
<div class="rounded-lg border p-3 text-sm">
<div class="flex items-start justify-between gap-3">
<div class="font-medium">{{ $row['module'] }}</div>
<span class="rounded-full bg-slate-100 px-2 py-1 text-[11px] font-semibold text-slate-700">{{ $row['status'] }}</span>
</div>
<div class="mt-1 text-xs text-slate-500">{{ $row['note'] }}</div>
</div>
@endforeach
</div>
</div>
<div class="rounded-xl border bg-white p-4">
<div class="text-sm font-semibold">Google Workspace</div>
@if($googleWorkspaceStatus)
<div class="mt-3 space-y-2 text-sm">
<div><span class="font-medium">Stato:</span> {{ $googleWorkspaceStatus['connected'] ? 'Collegato' : 'Non collegato' }}</div>
<div><span class="font-medium">Account:</span> {{ $googleWorkspaceStatus['email'] !== '' ? $googleWorkspaceStatus['email'] : '-' }}</div>
<div><span class="font-medium">Nome:</span> {{ $googleWorkspaceStatus['name'] !== '' ? $googleWorkspaceStatus['name'] : '-' }}</div>
<div><span class="font-medium">Ultimo collegamento:</span> {{ $googleWorkspaceStatus['connected_at'] !== '' ? $googleWorkspaceStatus['connected_at'] : '-' }}</div>
</div>
<div class="mt-3 flex flex-wrap gap-2">
<a href="{{ $this->getGoogleConnectUrl() }}" class="inline-flex items-center rounded-md bg-white px-3 py-1.5 text-xs font-medium text-gray-700 ring-1 ring-inset ring-gray-300 hover:bg-gray-50">Collega / aggiorna Google</a>
@if($googleWorkspaceStatus['connected'])
<form method="POST" action="{{ $this->getGoogleDisconnectUrl() }}">
@csrf
<button type="submit" class="inline-flex items-center rounded-md bg-rose-600 px-3 py-1.5 text-xs font-medium text-white hover:bg-rose-500">Scollega</button>
</form>
@endif
</div>
<div class="mt-2 text-xs text-gray-500">Questo collegamento usa una chiave account dedicata al fornitore, così rubrica e sincronizzazioni non si mischiano con il profilo amministratore anche se il backend resta sotto lo stesso tenant.</div>
@else
<div class="mt-3 text-sm text-gray-500">Contesto amministratore Google non disponibile per questo fornitore.</div>
@endif
</div>
</div>
</div>
@endif
</div>
</x-filament-panels::page>