feat(tickets): desktop mobile-upload UX, max10 files, attachment cues

This commit is contained in:
michele 2026-03-12 15:05:02 +00:00
parent 2b7dcb6ab7
commit 62f8613f9e
4 changed files with 53 additions and 29 deletions

View File

@ -387,7 +387,8 @@ private function loadTickets(): void
} }
$query = Ticket::query() $query = Ticket::query()
->with(['categoriaTicket', 'assegnatoAFornitore:id,ragione_sociale,nome,cognome']) ->with(['categoriaTicket', 'assegnatoAFornitore:id,ragione_sociale,nome,cognome', 'assegnatoAUser:id,name'])
->withCount('attachments')
->where('stabile_id', $stabileId); ->where('stabile_id', $stabileId);
if ($this->status === 'open') { if ($this->status === 'open') {

View File

@ -297,14 +297,25 @@ public function creaTicketRapido(): void
'newTicketCategoriaId' => ['nullable', 'integer', 'exists:categorie_ticket,id'], 'newTicketCategoriaId' => ['nullable', 'integer', 'exists:categorie_ticket,id'],
'newTicketTipoIntervento' => ['nullable', 'string', 'max:80'], 'newTicketTipoIntervento' => ['nullable', 'string', 'max:80'],
'newTicketFotoNote' => ['nullable', 'string', 'max:2000'], 'newTicketFotoNote' => ['nullable', 'string', 'max:2000'],
'newTicketCameraShots' => ['nullable', 'array', 'max:8'], 'newTicketCameraShots' => ['nullable', 'array', 'max:10'],
'newTicketCameraShots.*' => ['file', 'max:10240', 'mimes:jpg,jpeg,png,webp'], 'newTicketCameraShots.*' => ['file', 'max:10240', 'mimes:jpg,jpeg,png,webp'],
'newTicketAttachments' => ['nullable', 'array', 'max:8'], 'newTicketAttachments' => ['nullable', 'array', 'max:10'],
'newTicketAttachments.*' => ['file', 'max:10240', 'mimes:jpg,jpeg,png,webp,pdf,doc,docx,xls,xlsx,txt'], 'newTicketAttachments.*' => ['file', 'max:10240', 'mimes:jpg,jpeg,png,webp,pdf,doc,docx,xls,xlsx,txt'],
'newTicketAttachmentDescriptions' => ['nullable', 'array'], 'newTicketAttachmentDescriptions' => ['nullable', 'array'],
'newTicketAttachmentDescriptions.*' => ['nullable', 'string', 'max:255'], 'newTicketAttachmentDescriptions.*' => ['nullable', 'string', 'max:255'],
]); ]);
$totalUploads = count($this->newTicketCameraShots) + count($this->newTicketAttachments);
if ($totalUploads > 10) {
Notification::make()
->title('Troppi allegati selezionati')
->body('Puoi caricare al massimo 10 file totali (foto + documenti) per ticket.')
->warning()
->send();
return;
}
$user = Auth::user(); $user = Auth::user();
if (! $user instanceof User) { if (! $user instanceof User) {
return; return;

View File

@ -40,6 +40,7 @@
<th class="border px-2 py-2 text-left">ID</th> <th class="border px-2 py-2 text-left">ID</th>
<th class="border px-2 py-2 text-left">Titolo</th> <th class="border px-2 py-2 text-left">Titolo</th>
<th class="border px-2 py-2 text-left">Categoria</th> <th class="border px-2 py-2 text-left">Categoria</th>
<th class="border px-2 py-2 text-left">Assegnato a</th>
<th class="border px-2 py-2 text-left">Priorita</th> <th class="border px-2 py-2 text-left">Priorita</th>
<th class="border px-2 py-2 text-left">Stato</th> <th class="border px-2 py-2 text-left">Stato</th>
<th class="border px-2 py-2 text-left">Apertura</th> <th class="border px-2 py-2 text-left">Apertura</th>
@ -50,8 +51,18 @@
@forelse($tickets as $ticket) @forelse($tickets as $ticket)
<tr id="ticket-{{ (int) $ticket->id }}" class="hover:bg-slate-50"> <tr id="ticket-{{ (int) $ticket->id }}" class="hover:bg-slate-50">
<td class="border px-2 py-2">#{{ (int) $ticket->id }}</td> <td class="border px-2 py-2">#{{ (int) $ticket->id }}</td>
<td class="border px-2 py-2">{{ $ticket->titolo }}</td> <td class="border px-2 py-2">
<div class="flex items-center gap-1">
<span>{{ $ticket->titolo }}</span>
@if(((int) ($ticket->attachments_count ?? 0)) > 0)
<span title="Presenza allegati" class="inline-flex items-center rounded bg-emerald-100 px-1.5 py-0.5 text-[10px] font-semibold text-emerald-800">
ATT {{ (int) $ticket->attachments_count }}
</span>
@endif
</div>
</td>
<td class="border px-2 py-2">{{ optional($ticket->categoriaTicket)->nome ?: '-' }}</td> <td class="border px-2 py-2">{{ optional($ticket->categoriaTicket)->nome ?: '-' }}</td>
<td class="border px-2 py-2">{{ optional($ticket->assegnatoAUser)->name ?: '-' }}</td>
<td class="border px-2 py-2">{{ $ticket->priorita }}</td> <td class="border px-2 py-2">{{ $ticket->priorita }}</td>
<td class="border px-2 py-2">{{ $ticket->stato }}</td> <td class="border px-2 py-2">{{ $ticket->stato }}</td>
<td class="border px-2 py-2">{{ optional($ticket->data_apertura)->format('d/m/Y H:i') }}</td> <td class="border px-2 py-2">{{ optional($ticket->data_apertura)->format('d/m/Y H:i') }}</td>
@ -80,7 +91,7 @@
</tr> </tr>
@empty @empty
<tr> <tr>
<td colspan="7" class="border px-2 py-4 text-center text-gray-500">Nessun ticket per il filtro selezionato.</td> <td colspan="8" class="border px-2 py-4 text-center text-gray-500">Nessun ticket per il filtro selezionato.</td>
</tr> </tr>
@endforelse @endforelse
</tbody> </tbody>

View File

@ -140,10 +140,11 @@
<label class="inline-flex cursor-pointer items-center rounded-md bg-indigo-600 px-3 py-2 text-xs font-medium text-white hover:bg-indigo-500"> <label class="inline-flex cursor-pointer items-center rounded-md bg-indigo-600 px-3 py-2 text-xs font-medium text-white hover:bg-indigo-500">
Aggiungi allegati Aggiungi allegati
<input type="file" wire:model="newTicketAttachments" multiple accept="image/*,.pdf,.doc,.docx,.xls,.xlsx,.txt" class="hidden" /> <input type="file" wire:model="newTicketAttachments" multiple accept=".pdf,.doc,.docx,.xls,.xlsx,.txt,image/*" class="hidden" />
</label> </label>
</div> </div>
<div class="mt-1 text-xs text-gray-500">Dopo ogni scatto puoi aggiungere subito la descrizione. Se servono altre foto usa di nuovo "Scatta foto".</div> <div class="mt-1 text-xs text-gray-500">Puoi caricare fino a 10 file totali (foto + documenti). Ogni file ha descrizione separata.</div>
<div class="mt-1 text-xs text-gray-500">iPhone: su "Aggiungi allegati" scegli "Sfoglia" per aprire l'app File (iCloud Drive/On My iPhone).</div>
</label> </label>
@if(count($this->selectedUploads) > 0) @if(count($this->selectedUploads) > 0)