223 lines
20 KiB
PHP
223 lines
20 KiB
PHP
<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">Rubrica clienti fornitore</div>
|
|
<div class="text-sm text-gray-600">
|
|
@if($this->fornitoreLabel)
|
|
Elenco clienti del singolo fornitore, con sorgente TecnoRepair `TClienti` e collegamento sicuro alla stessa rubrica fornitore quando esiste una scheda condivisa già agganciata.
|
|
@else
|
|
Seleziona un fornitore per aprire la rubrica clienti.
|
|
@endif
|
|
</div>
|
|
</div>
|
|
<div class="flex flex-wrap gap-2">
|
|
<a href="{{ $this->getLavorazioniUrl() }}" 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">Lavorazioni</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">Prodotti</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="rounded-xl border border-slate-200 bg-slate-50 px-4 py-3 text-sm text-slate-700">
|
|
Questa vista resta confinata al perimetro del fornitore. Prima importa i clienti con <span class="font-mono text-xs">{{ $this->importCommandHint }}</span>, poi usa questa pagina per lavorare in modo compatto su elenco, recapiti e storico apparecchi senza uscire nel pannello anagrafico admin.
|
|
</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="rounded-xl border bg-white p-4">
|
|
<div class="grid gap-3 xl:grid-cols-[1.2fr,0.8fr]">
|
|
<div class="flex flex-wrap items-center gap-2">
|
|
<button type="button" wire:click="selectTab('elenco')" class="inline-flex items-center rounded-md px-3 py-1.5 text-xs font-medium {{ $activeTab === 'elenco' ? 'bg-slate-800 text-white' : 'bg-white text-slate-700 ring-1 ring-inset ring-slate-300 hover:bg-slate-50' }}">Elenco compatto</button>
|
|
<button type="button" wire:click="selectTab('scheda')" class="inline-flex items-center rounded-md px-3 py-1.5 text-xs font-medium {{ $activeTab === 'scheda' ? 'bg-slate-800 text-white' : 'bg-white text-slate-700 ring-1 ring-inset ring-slate-300 hover:bg-slate-50' }}">Scheda cliente</button>
|
|
</div>
|
|
|
|
<div class="grid grid-cols-2 gap-2 xl:grid-cols-4">
|
|
<div class="rounded-lg border bg-slate-50 px-3 py-2 text-xs">Totali <span class="font-semibold">{{ $counters['totali'] ?? 0 }}</span></div>
|
|
<div class="rounded-lg border bg-emerald-50 px-3 py-2 text-xs text-emerald-800">Collegati <span class="font-semibold">{{ $counters['collegati'] ?? 0 }}</span></div>
|
|
<div class="rounded-lg border bg-sky-50 px-3 py-2 text-xs text-sky-800">Con email <span class="font-semibold">{{ $counters['con_email'] ?? 0 }}</span></div>
|
|
<div class="rounded-lg border bg-amber-50 px-3 py-2 text-xs text-amber-800">Con cellulare <span class="font-semibold">{{ $counters['con_cellulare'] ?? 0 }}</span></div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="mt-4 grid gap-4 xl:grid-cols-[1.4fr,0.6fr]">
|
|
<div>
|
|
@if($activeTab === 'elenco')
|
|
<label class="block text-sm">
|
|
<span class="mb-1 block font-medium">Cerca cliente</span>
|
|
<input type="text" wire:model.live.debounce.300ms="search" class="w-full rounded-lg border-gray-300" placeholder="Nome, telefono, email, citta" />
|
|
</label>
|
|
|
|
<div class="mt-4 overflow-x-auto">
|
|
<table class="min-w-full border-collapse border text-xs">
|
|
<thead>
|
|
<tr class="bg-slate-100 text-slate-700">
|
|
<th class="border px-2 py-2 text-left">Cliente</th>
|
|
<th class="border px-2 py-2 text-left">Recapiti</th>
|
|
<th class="border px-2 py-2 text-left">Zona</th>
|
|
<th class="border px-2 py-2 text-left">Schede</th>
|
|
<th class="border px-2 py-2 text-left">Rubrica</th>
|
|
<th class="border px-2 py-2 text-left">Azioni</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
@forelse($rows as $row)
|
|
<tr class="{{ ($selectedClienteId ?? 0) === (int) ($row['id'] ?? 0) && (int) ($row['id'] ?? 0) > 0 ? 'bg-sky-50' : 'bg-white hover:bg-slate-50' }}">
|
|
<td class="border px-2 py-2 align-top">
|
|
<div class="font-medium text-slate-900">{{ $row['display_name'] }}</div>
|
|
<div class="text-[11px] text-slate-500">Fonte {{ $row['source'] === 'tecnorepair_tclienti' ? 'TClienti' : 'ticket' }}</div>
|
|
</td>
|
|
<td class="border px-2 py-2 align-top">
|
|
<div>{{ $row['phone'] !== '' ? $row['phone'] : '-' }}</div>
|
|
<div class="text-[11px] text-slate-500">{{ $row['phone_alt'] !== '' ? $row['phone_alt'] : ($row['email'] !== '' ? $row['email'] : 'nessun recapito') }}</div>
|
|
</td>
|
|
<td class="border px-2 py-2 align-top">
|
|
<div>{{ $row['citta'] !== '' ? $row['citta'] : '-' }}</div>
|
|
<div class="text-[11px] text-slate-500">{{ $row['indirizzo'] !== '' ? $row['indirizzo'] : '' }}</div>
|
|
</td>
|
|
<td class="border px-2 py-2 align-top">
|
|
<div class="font-medium">{{ $row['totale_schede'] ?? 0 }}</div>
|
|
<div class="text-[11px] text-slate-500">Ultima {{ $row['ultima_data'] ?? '-' }}</div>
|
|
</td>
|
|
<td class="border px-2 py-2 align-top">
|
|
@if($row['rubrica_url'])
|
|
<a href="{{ $row['rubrica_url'] }}" class="inline-flex items-center rounded-md bg-white px-2 py-1 text-[11px] font-medium text-indigo-700 ring-1 ring-inset ring-indigo-300 hover:bg-indigo-50">Vai al cliente</a>
|
|
@else
|
|
<span class="text-[11px] text-amber-700">Non collegato</span>
|
|
@endif
|
|
</td>
|
|
<td class="border px-2 py-2 align-top">
|
|
@if((int) ($row['id'] ?? 0) > 0)
|
|
<button type="button" wire:click="selectCliente({{ (int) $row['id'] }})" class="inline-flex items-center rounded-md bg-slate-800 px-2 py-1 text-[11px] font-medium text-white hover:bg-slate-700">Apri</button>
|
|
@endif
|
|
</td>
|
|
</tr>
|
|
@empty
|
|
<tr>
|
|
<td colspan="6" class="border px-2 py-6 text-center text-sm text-slate-500">Nessun cliente disponibile. Importa prima `TClienti` nell'archivio legacy e poi lancia il comando rubrica clienti.</td>
|
|
</tr>
|
|
@endforelse
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
@else
|
|
@php
|
|
$selected = $this->selectedCliente;
|
|
@endphp
|
|
@if(! $selected)
|
|
<div class="rounded-lg border border-amber-200 bg-amber-50 p-4 text-sm text-amber-800">
|
|
Seleziona un cliente dall'elenco compatto per aprire la scheda fornitore limitata.
|
|
</div>
|
|
@else
|
|
<div class="grid gap-4 xl:grid-cols-[1.1fr,0.9fr]">
|
|
<div class="space-y-4">
|
|
<div class="rounded-xl border bg-slate-50 p-4">
|
|
<div class="text-xs font-semibold uppercase tracking-wide text-slate-500">Scheda cliente</div>
|
|
<div class="mt-2 text-lg font-semibold text-slate-900">{{ $selected->display_name ?: 'Cliente TecnoRepair' }}</div>
|
|
<div class="mt-1 text-xs text-slate-500">Legacy cliente ID {{ $selected->legacy_cliente_id ?: '-' }} · aggiornato {{ optional($selected->updated_at)->format('d/m/Y H:i') ?: '-' }}</div>
|
|
<div class="mt-4 grid gap-3 sm:grid-cols-2">
|
|
<div class="rounded-lg border bg-white px-3 py-2 text-sm">
|
|
<div class="text-[11px] font-semibold uppercase tracking-wide text-slate-500">Cellulare</div>
|
|
<div class="mt-1">{{ $selected->phone ?: '-' }}</div>
|
|
</div>
|
|
<div class="rounded-lg border bg-white px-3 py-2 text-sm">
|
|
<div class="text-[11px] font-semibold uppercase tracking-wide text-slate-500">Fisso / email</div>
|
|
<div class="mt-1">{{ $selected->phone_alt ?: ($selected->email ?: '-') }}</div>
|
|
</div>
|
|
<div class="rounded-lg border bg-white px-3 py-2 text-sm sm:col-span-2">
|
|
<div class="text-[11px] font-semibold uppercase tracking-wide text-slate-500">Indirizzo</div>
|
|
<div class="mt-1">{{ trim(implode(', ', array_filter([$selected->indirizzo, $selected->cap, $selected->citta, $selected->provincia]))) !== '' ? trim(implode(', ', array_filter([$selected->indirizzo, $selected->cap, $selected->citta, $selected->provincia]))) : '-' }}</div>
|
|
</div>
|
|
<div class="rounded-lg border bg-white px-3 py-2 text-sm">
|
|
<div class="text-[11px] font-semibold uppercase tracking-wide text-slate-500">Codice fiscale</div>
|
|
<div class="mt-1">{{ $selected->codice_fiscale ?: '-' }}</div>
|
|
</div>
|
|
<div class="rounded-lg border bg-white px-3 py-2 text-sm">
|
|
<div class="text-[11px] font-semibold uppercase tracking-wide text-slate-500">P. IVA</div>
|
|
<div class="mt-1">{{ $selected->partita_iva ?: '-' }}</div>
|
|
</div>
|
|
</div>
|
|
@if($selected->rubrica_id && $selected->rubrica_url)
|
|
<div class="mt-4">
|
|
<a href="{{ $selected->rubrica_url }}" class="inline-flex items-center rounded-md bg-indigo-600 px-3 py-1.5 text-xs font-medium text-white hover:bg-indigo-500">Apri vista cliente collegata</a>
|
|
</div>
|
|
@endif
|
|
</div>
|
|
|
|
<div class="rounded-xl border bg-white p-4">
|
|
<div class="text-xs font-semibold uppercase tracking-wide text-slate-500">Storico apparecchi / seriali</div>
|
|
<div class="mt-3 overflow-x-auto">
|
|
<table class="min-w-full border-collapse border text-xs">
|
|
<thead>
|
|
<tr class="bg-slate-100 text-slate-700">
|
|
<th class="border px-2 py-2 text-left">Scheda</th>
|
|
<th class="border px-2 py-2 text-left">Prodotto</th>
|
|
<th class="border px-2 py-2 text-left">Seriali</th>
|
|
<th class="border px-2 py-2 text-left">Stato</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
@forelse($this->selectedClienteSchede as $scheda)
|
|
<tr class="bg-white hover:bg-slate-50">
|
|
<td class="border px-2 py-2 align-top">
|
|
<div class="font-medium">{{ $scheda['numero'] }}</div>
|
|
<div class="text-[11px] text-slate-500">{{ $scheda['ingresso'] }}</div>
|
|
</td>
|
|
<td class="border px-2 py-2 align-top">
|
|
<div>{{ $scheda['prodotto'] }}</div>
|
|
<div class="text-[11px] text-slate-500">{{ $scheda['codice'] !== '' ? $scheda['codice'] : 'senza codice' }}</div>
|
|
</td>
|
|
<td class="border px-2 py-2 align-top">{{ $scheda['seriali'] }}</td>
|
|
<td class="border px-2 py-2 align-top"><span class="inline-flex rounded-full border px-2 py-1 text-[11px] font-medium {{ $scheda['status_badge'] }}">{{ $scheda['stato'] }}</span></td>
|
|
</tr>
|
|
@empty
|
|
<tr>
|
|
<td colspan="4" class="border px-2 py-4 text-center text-slate-500">Nessuna scheda legacy collegata a questo cliente.</td>
|
|
</tr>
|
|
@endforelse
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="space-y-4">
|
|
<div class="rounded-xl border bg-white p-4">
|
|
<div class="text-sm font-semibold">Google workspace fornitore</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>
|
|
@else
|
|
<div class="mt-3 text-sm text-gray-500">Stato Google del fornitore non disponibile.</div>
|
|
@endif
|
|
</div>
|
|
|
|
<div class="rounded-xl border bg-slate-50 p-4 text-sm text-slate-700">
|
|
Il modello dati prodotti e seriali è già separato: un prodotto unico può avere più seriali collegati. Nella fase successiva si può rifinire la UI della scheda intervento in stile TecnoRepair e riusare la pipeline FE lato fornitore senza auto-import.
|
|
</div>
|
|
</div>
|
|
</div>
|
|
@endif
|
|
</div>
|
|
@endif
|
|
</div>
|
|
</div>
|
|
@endif
|
|
</div>
|
|
</x-filament-panels::page> |