Ticket visibility and dashboard cleanup
This commit is contained in:
parent
dba907a85f
commit
c079737b5b
|
|
@ -5,6 +5,9 @@ # Changelog
|
|||
## [Unreleased]
|
||||
|
||||
- Initial open-source release prep.
|
||||
- Removed active-stabile filtering from topbar avvisi/urgenze counters and from the Google ticket-operativi box so cross-stabile operational tickets stay visible.
|
||||
- Removed the Google Workspace widget from the main/support dashboard, leaving the full panel only under Impostazioni > Google.
|
||||
- Tightened Filament sidebar navigation spacing between main menu groups for denser top-level navigation.
|
||||
- Added immediate local preview for Ticket Mobile photos and attachments before final send on phone.
|
||||
- Split insurance handling out of Ticket Gestione into dedicated Tab 4 and added centralized Supporto claims list.
|
||||
- Fixed supplier ticket-detail access by resolving both intervention-id and ticket-id safely in supplier context.
|
||||
|
|
|
|||
|
|
@ -114,6 +114,9 @@ class TicketGestione extends Page
|
|||
/** @var array<string,mixed>|null */
|
||||
public ?array $attachmentPreview = null;
|
||||
|
||||
/** @var array<string,mixed>|null */
|
||||
public ?array $attachmentMapPreview = null;
|
||||
|
||||
/** @var \Illuminate\Support\Collection<int, Ticket> */
|
||||
public $tickets;
|
||||
|
||||
|
|
@ -320,6 +323,7 @@ public function openAttachmentPreview(int $attachmentId): void
|
|||
|
||||
$isImage = $attachment->isImage();
|
||||
$isPdf = $attachment->isPdf();
|
||||
$details = $this->getAttachmentDetails($attachment);
|
||||
|
||||
$this->attachmentPreview = [
|
||||
'id' => (int) $attachment->id,
|
||||
|
|
@ -329,12 +333,58 @@ public function openAttachmentPreview(int $attachmentId): void
|
|||
'is_image' => $isImage,
|
||||
'is_pdf' => $isPdf,
|
||||
'mime' => $mime,
|
||||
'details' => $details,
|
||||
];
|
||||
}
|
||||
|
||||
public function openAttachmentMapPreview(int $attachmentId): void
|
||||
{
|
||||
$ticket = $this->selectedTicket;
|
||||
if (! $ticket) {
|
||||
return;
|
||||
}
|
||||
|
||||
$attachment = $ticket->attachments->firstWhere('id', $attachmentId);
|
||||
if (! $attachment instanceof TicketAttachment) {
|
||||
return;
|
||||
}
|
||||
|
||||
$details = $this->getAttachmentDetails($attachment);
|
||||
$gps = $details['gps'] ?? [];
|
||||
$lat = $gps['lat'] ?? null;
|
||||
$lng = $gps['lng'] ?? null;
|
||||
|
||||
if (! is_numeric($lat) || ! is_numeric($lng)) {
|
||||
Notification::make()->title('Coordinate GPS non disponibili per questo allegato')->warning()->send();
|
||||
return;
|
||||
}
|
||||
|
||||
$this->attachmentMapPreview = [
|
||||
'attachment_id' => (int) $attachment->id,
|
||||
'name' => (string) ($attachment->original_file_name ?? 'Allegato'),
|
||||
'label' => (string) ($gps['label'] ?? (number_format((float) $lat, 5, '.', '') . ', ' . number_format((float) $lng, 5, '.', ''))),
|
||||
'maps_url' => (string) ($details['maps_url'] ?? ('https://maps.google.com/?q=' . $lat . ',' . $lng)),
|
||||
'embed_url' => (string) ($details['maps_embed_url'] ?? ('https://maps.google.com/maps?q=' . $lat . ',' . $lng . '&z=17&output=embed')),
|
||||
];
|
||||
}
|
||||
|
||||
public function closeAttachmentPreview(): void
|
||||
{
|
||||
$this->attachmentPreview = null;
|
||||
$this->attachmentMapPreview = null;
|
||||
}
|
||||
|
||||
public function closeAttachmentMapPreview(): void
|
||||
{
|
||||
$this->attachmentMapPreview = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string,mixed>
|
||||
*/
|
||||
public function getAttachmentDetails(TicketAttachment $attachment): array
|
||||
{
|
||||
return $this->parseAttachmentDescription((string) ($attachment->description ?? ''));
|
||||
}
|
||||
|
||||
public function getSelectedTicketProperty(): ?Ticket
|
||||
|
|
@ -1276,6 +1326,95 @@ private function syncTicketAttachmentsArchive(Ticket $ticket): void
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string,mixed>
|
||||
*/
|
||||
private function parseAttachmentDescription(string $description): array
|
||||
{
|
||||
$parts = preg_split('/\s*\|\s*/', trim($description)) ?: [];
|
||||
|
||||
$details = [
|
||||
'primary_description' => '',
|
||||
'gps' => null,
|
||||
'maps_url' => null,
|
||||
'maps_embed_url' => null,
|
||||
'exif_datetime' => null,
|
||||
'device' => null,
|
||||
'file_label' => null,
|
||||
'original_label' => null,
|
||||
'other' => [],
|
||||
'full_description' => trim($description),
|
||||
];
|
||||
|
||||
foreach ($parts as $part) {
|
||||
$part = trim((string) $part);
|
||||
if ($part === '') {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (str_starts_with($part, 'GPS:')) {
|
||||
$gpsValue = trim((string) Str::after($part, 'GPS:'));
|
||||
if (preg_match('/^\s*(-?\d+(?:\.\d+)?)\s*,\s*(-?\d+(?:\.\d+)?)\s*$/', $gpsValue, $matches) === 1) {
|
||||
$lat = (float) $matches[1];
|
||||
$lng = (float) $matches[2];
|
||||
|
||||
$details['gps'] = [
|
||||
'lat' => $lat,
|
||||
'lng' => $lng,
|
||||
'label' => number_format($lat, 5, '.', '') . ', ' . number_format($lng, 5, '.', ''),
|
||||
];
|
||||
$details['maps_embed_url'] = 'https://maps.google.com/maps?q=' . $lat . ',' . $lng . '&z=17&output=embed';
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (str_starts_with($part, 'Maps:')) {
|
||||
$details['maps_url'] = trim((string) Str::after($part, 'Maps:'));
|
||||
continue;
|
||||
}
|
||||
|
||||
if (str_starts_with($part, 'EXIF:')) {
|
||||
$details['exif_datetime'] = trim((string) Str::after($part, 'EXIF:'));
|
||||
continue;
|
||||
}
|
||||
|
||||
if (str_starts_with($part, 'Device:')) {
|
||||
$details['device'] = trim((string) Str::after($part, 'Device:'));
|
||||
continue;
|
||||
}
|
||||
|
||||
if (str_starts_with($part, 'File:')) {
|
||||
$details['file_label'] = trim((string) Str::after($part, 'File:'));
|
||||
continue;
|
||||
}
|
||||
|
||||
if (str_starts_with($part, 'Orig:')) {
|
||||
$details['original_label'] = trim((string) Str::after($part, 'Orig:'));
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($details['primary_description'] === '') {
|
||||
$details['primary_description'] = $part;
|
||||
continue;
|
||||
}
|
||||
|
||||
$details['other'][] = $part;
|
||||
}
|
||||
|
||||
if ($details['maps_url'] === null && is_array($details['gps'])) {
|
||||
$details['maps_url'] = 'https://maps.google.com/?q=' . $details['gps']['lat'] . ',' . $details['gps']['lng'];
|
||||
}
|
||||
|
||||
if ($details['primary_description'] === '') {
|
||||
$details['primary_description'] = $details['full_description'] !== ''
|
||||
? $details['full_description']
|
||||
: 'Allegato ticket';
|
||||
}
|
||||
|
||||
return $details;
|
||||
}
|
||||
|
||||
private function archiveTicketAttachmentDocument(Ticket $ticket, TicketAttachment $attachment): void
|
||||
{
|
||||
if (! Schema::hasTable('documenti')) {
|
||||
|
|
|
|||
|
|
@ -673,15 +673,21 @@ private function loadOpenTickets(): void
|
|||
return;
|
||||
}
|
||||
|
||||
$stabileId = StabileContext::resolveActiveStabileId($user);
|
||||
if (! $stabileId) {
|
||||
$stabileIds = StabileContext::accessibleStabili($user)
|
||||
->pluck('id')
|
||||
->map(fn($value) => (int) $value)
|
||||
->filter(fn(int $value) => $value > 0)
|
||||
->values()
|
||||
->all();
|
||||
|
||||
if ($stabileIds === []) {
|
||||
$this->openTickets = [];
|
||||
return;
|
||||
}
|
||||
|
||||
$items = Ticket::query()
|
||||
->with('stabile:id,denominazione')
|
||||
->where('stabile_id', $stabileId)
|
||||
->whereIn('stabile_id', $stabileIds)
|
||||
->aperti()
|
||||
->orderByDesc('created_at')
|
||||
->limit(8)
|
||||
|
|
|
|||
|
|
@ -10,7 +10,6 @@
|
|||
use App\Filament\Pages\Gescon\RubricaUniversaleArchivio;
|
||||
use App\Filament\Pages\Supporto\SupportoDashboard;
|
||||
use App\Filament\Pages\Supporto\TicketMobile;
|
||||
use App\Filament\Widgets\GoogleScadenziarioOverview;
|
||||
use App\Filament\Widgets\TicketMobileOverview;
|
||||
use App\Models\Fornitore;
|
||||
use App\Models\FornitoreDipendente;
|
||||
|
|
@ -116,7 +115,6 @@ public function panel(Panel $panel): Panel
|
|||
->discoverWidgets(in: app_path('Filament/Widgets'), for : 'App\\Filament\\Widgets')
|
||||
->widgets([
|
||||
AccountWidget::class,
|
||||
GoogleScadenziarioOverview::class,
|
||||
TicketMobileOverview::class,
|
||||
])
|
||||
->middleware([
|
||||
|
|
|
|||
|
|
@ -35,4 +35,18 @@ .netgescon-footer {
|
|||
width: 100% !important;
|
||||
flex: 0 0 auto;
|
||||
margin-top: auto;
|
||||
}
|
||||
|
||||
.fi-sidebar-nav,
|
||||
.fi-sidebar-nav-groups {
|
||||
row-gap: calc(var(--spacing) * 4);
|
||||
}
|
||||
|
||||
.fi-sidebar-group-btn,
|
||||
.fi-sidebar-group-dropdown-trigger-btn {
|
||||
padding-block: calc(var(--spacing) * 1.25);
|
||||
}
|
||||
|
||||
.fi-sidebar-group-label {
|
||||
line-height: calc(var(--spacing) * 5);
|
||||
}
|
||||
|
|
@ -1,17 +1,22 @@
|
|||
@php
|
||||
$user = \Illuminate\Support\Facades\Auth::user();
|
||||
$stabileId = null;
|
||||
$stabileIds = [];
|
||||
|
||||
if ($user instanceof \App\Models\User) {
|
||||
$stabileId = \App\Support\StabileContext::resolveActiveStabileId($user);
|
||||
$stabileIds = \App\Support\StabileContext::accessibleStabili($user)
|
||||
->pluck('id')
|
||||
->map(fn($value) => (int) $value)
|
||||
->filter(fn(int $value) => $value > 0)
|
||||
->values()
|
||||
->all();
|
||||
}
|
||||
|
||||
$avvisiCount = 0;
|
||||
$urgenzeCount = 0;
|
||||
|
||||
if ($stabileId) {
|
||||
if ($stabileIds !== []) {
|
||||
$baseQuery = \App\Models\Ticket::query()
|
||||
->where('stabile_id', $stabileId)
|
||||
->whereIn('stabile_id', $stabileIds)
|
||||
->whereIn('stato', ['Aperto', 'Preso in Carico', 'In Lavorazione']);
|
||||
|
||||
$urgenzeCount = (clone $baseQuery)->where('priorita', 'Urgente')->count();
|
||||
|
|
|
|||
|
|
@ -5,11 +5,17 @@
|
|||
$avvisi = 0;
|
||||
|
||||
if ($user instanceof \App\Models\User) {
|
||||
$stabileId = \App\Support\StabileContext::resolveActiveStabileId($user);
|
||||
if ($stabileId) {
|
||||
$stabileIds = \App\Support\StabileContext::accessibleStabili($user)
|
||||
->pluck('id')
|
||||
->map(fn($value) => (int) $value)
|
||||
->filter(fn(int $value) => $value > 0)
|
||||
->values()
|
||||
->all();
|
||||
|
||||
if ($stabileIds !== []) {
|
||||
$base = \App\Models\Ticket::query()
|
||||
->where('stabile_id', $stabileId)
|
||||
->where('stato', 'Aperto');
|
||||
->whereIn('stabile_id', $stabileIds)
|
||||
->whereIn('stato', ['Aperto', 'Preso in Carico', 'In Lavorazione']);
|
||||
|
||||
$urgenti = (clone $base)->where('priorita', 'Urgente')->count();
|
||||
$avvisi = (clone $base)->where('priorita', '!=', 'Urgente')->count();
|
||||
|
|
|
|||
|
|
@ -16,7 +16,5 @@
|
|||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@livewire(\App\Filament\Widgets\GoogleScadenziarioOverview::class)
|
||||
</div>
|
||||
</x-filament-panels::page>
|
||||
|
|
|
|||
|
|
@ -332,6 +332,7 @@
|
|||
|
||||
<div class="mt-4 grid gap-3 sm:grid-cols-2">
|
||||
@forelse($ticket->attachments as $a)
|
||||
@php($details = $this->getAttachmentDetails($a))
|
||||
<div class="rounded-xl border bg-white p-3 text-xs shadow-sm">
|
||||
<div class="aspect-[4/3] rounded-lg border bg-gray-50 p-2">
|
||||
@if($a->isImage())
|
||||
|
|
@ -347,10 +348,48 @@
|
|||
</div>
|
||||
|
||||
<div class="mt-2 font-medium">{{ $a->original_file_name }}</div>
|
||||
<div class="mt-1 text-gray-600">{{ $a->description ?: 'Nessuna descrizione' }}</div>
|
||||
<div class="mt-1 text-gray-700">{{ $details['primary_description'] ?: 'Nessuna descrizione' }}</div>
|
||||
<div class="mt-2 flex flex-wrap gap-1">
|
||||
@if(!empty($details['gps']))
|
||||
<span class="inline-flex items-center rounded-full bg-emerald-100 px-2 py-0.5 text-[10px] font-semibold text-emerald-800">GPS</span>
|
||||
@endif
|
||||
@if(!empty($details['exif_datetime']))
|
||||
<span class="inline-flex items-center rounded-full bg-sky-100 px-2 py-0.5 text-[10px] font-semibold text-sky-800">EXIF</span>
|
||||
@endif
|
||||
@if(!empty($details['device']))
|
||||
<span class="inline-flex items-center rounded-full bg-slate-100 px-2 py-0.5 text-[10px] font-semibold text-slate-700">{{ $details['device'] }}</span>
|
||||
@endif
|
||||
</div>
|
||||
@if(!empty($details['gps']) || !empty($details['exif_datetime']) || !empty($details['file_label']) || !empty($details['original_label']) || !empty($details['other']))
|
||||
<div class="mt-2 rounded-lg border border-slate-200 bg-slate-50 p-2 text-[11px] text-slate-700">
|
||||
@if(!empty($details['gps']))
|
||||
<div><span class="font-medium">Coordinate:</span> {{ $details['gps']['label'] }}</div>
|
||||
@endif
|
||||
@if(!empty($details['exif_datetime']))
|
||||
<div><span class="font-medium">Data EXIF:</span> {{ $details['exif_datetime'] }}</div>
|
||||
@endif
|
||||
@if(!empty($details['device']))
|
||||
<div><span class="font-medium">Dispositivo:</span> {{ $details['device'] }}</div>
|
||||
@endif
|
||||
@if(!empty($details['file_label']))
|
||||
<div><span class="font-medium">Nome file:</span> {{ $details['file_label'] }}</div>
|
||||
@endif
|
||||
@if(!empty($details['original_label']))
|
||||
<div><span class="font-medium">Origine:</span> {{ $details['original_label'] }}</div>
|
||||
@endif
|
||||
@foreach($details['other'] as $otherPart)
|
||||
<div>{{ $otherPart }}</div>
|
||||
@endforeach
|
||||
</div>
|
||||
@endif
|
||||
<div class="mt-2 text-[11px] text-gray-500">{{ optional($a->created_at)->format('d/m/Y H:i') }}</div>
|
||||
|
||||
<button type="button" wire:click="openAttachmentPreview({{ (int) $a->id }})" class="mt-2 inline-flex items-center rounded-md bg-indigo-600 px-2 py-1 text-[11px] font-medium text-white hover:bg-indigo-500">Visualizza in modal</button>
|
||||
<div class="mt-2 flex flex-wrap gap-2">
|
||||
<button type="button" wire:click="openAttachmentPreview({{ (int) $a->id }})" class="inline-flex items-center rounded-md bg-indigo-600 px-2 py-1 text-[11px] font-medium text-white hover:bg-indigo-500">Visualizza allegato</button>
|
||||
@if(!empty($details['gps']))
|
||||
<button type="button" wire:click="openAttachmentMapPreview({{ (int) $a->id }})" class="inline-flex items-center rounded-md bg-emerald-600 px-2 py-1 text-[11px] font-medium text-white hover:bg-emerald-500">Apri mappa</button>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
@empty
|
||||
<div class="text-xs text-gray-500">Nessun allegato.</div>
|
||||
|
|
@ -545,8 +584,21 @@
|
|||
<div class="flex items-center justify-between border-b px-4 py-3">
|
||||
<div>
|
||||
<div class="text-sm font-semibold">{{ $attachmentPreview['name'] ?? 'Allegato' }}</div>
|
||||
@if(!empty($attachmentPreview['description']))
|
||||
<div class="text-xs text-gray-500">{{ $attachmentPreview['description'] }}</div>
|
||||
@if(!empty($attachmentPreview['details']['primary_description']))
|
||||
<div class="text-xs text-gray-500">{{ $attachmentPreview['details']['primary_description'] }}</div>
|
||||
@endif
|
||||
@if(!empty($attachmentPreview['details']['gps']) || !empty($attachmentPreview['details']['exif_datetime']) || !empty($attachmentPreview['details']['device']))
|
||||
<div class="mt-1 flex flex-wrap gap-2 text-[11px] text-slate-600">
|
||||
@if(!empty($attachmentPreview['details']['gps']))
|
||||
<span>GPS {{ $attachmentPreview['details']['gps']['label'] }}</span>
|
||||
@endif
|
||||
@if(!empty($attachmentPreview['details']['exif_datetime']))
|
||||
<span>EXIF {{ $attachmentPreview['details']['exif_datetime'] }}</span>
|
||||
@endif
|
||||
@if(!empty($attachmentPreview['details']['device']))
|
||||
<span>{{ $attachmentPreview['details']['device'] }}</span>
|
||||
@endif
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
<div class="flex items-center gap-2">
|
||||
|
|
@ -560,12 +612,21 @@
|
|||
<button type="button" x-on:click="nextPage()" class="rounded-md bg-slate-100 px-2 py-1 text-xs hover:bg-slate-200">Pagina successiva</button>
|
||||
<button type="button" x-on:click="printPdf()" class="rounded-md bg-slate-100 px-2 py-1 text-xs hover:bg-slate-200">Stampa PDF</button>
|
||||
@endif
|
||||
@if(!empty($attachmentPreview['details']['gps']))
|
||||
<button type="button" wire:click="openAttachmentMapPreview({{ (int) ($attachmentPreview['id'] ?? 0) }})" class="rounded-md bg-emerald-100 px-2 py-1 text-xs text-emerald-800 hover:bg-emerald-200">Google Maps</button>
|
||||
@endif
|
||||
<a href="{{ $attachmentPreview['url'] }}" target="_blank" class="rounded-md bg-slate-100 px-2 py-1 text-xs hover:bg-slate-200">Apri in nuova scheda</a>
|
||||
<button type="button" wire:click="closeAttachmentPreview" class="rounded-md bg-gray-100 px-2 py-1 text-xs hover:bg-gray-200">Chiudi</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="h-[calc(92vh-64px)] overflow-auto p-4">
|
||||
@if(!empty($attachmentPreview['details']['full_description']))
|
||||
<div class="mb-3 rounded-lg border border-slate-200 bg-slate-50 p-3 text-xs text-slate-700">
|
||||
<div class="font-medium text-slate-900">Dettagli allegato</div>
|
||||
<div class="mt-1 whitespace-pre-wrap">{{ $attachmentPreview['details']['full_description'] }}</div>
|
||||
</div>
|
||||
@endif
|
||||
@if($attachmentPreview['is_image'] ?? false)
|
||||
<div class="h-full overflow-auto rounded-lg bg-slate-50 p-4">
|
||||
<div class="flex min-h-full min-w-full items-start justify-center">
|
||||
|
|
@ -584,4 +645,24 @@
|
|||
</div>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
@if($attachmentMapPreview)
|
||||
<div class="fixed inset-0 z-[60] flex items-center justify-center bg-black/70 p-4">
|
||||
<div class="h-[88vh] w-full max-w-5xl rounded-xl bg-white shadow-2xl">
|
||||
<div class="flex items-center justify-between border-b px-4 py-3">
|
||||
<div>
|
||||
<div class="text-sm font-semibold">Mappa allegato</div>
|
||||
<div class="text-xs text-slate-500">{{ $attachmentMapPreview['name'] ?? 'Allegato' }} · {{ $attachmentMapPreview['label'] ?? '' }}</div>
|
||||
</div>
|
||||
<div class="flex items-center gap-2">
|
||||
<a href="{{ $attachmentMapPreview['maps_url'] }}" target="_blank" rel="noopener noreferrer" class="rounded-md bg-emerald-100 px-2 py-1 text-xs text-emerald-800 hover:bg-emerald-200">Apri Google Maps</a>
|
||||
<button type="button" wire:click="closeAttachmentMapPreview" class="rounded-md bg-gray-100 px-2 py-1 text-xs hover:bg-gray-200">Chiudi</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="h-[calc(88vh-64px)] p-4">
|
||||
<iframe src="{{ $attachmentMapPreview['embed_url'] }}" class="h-full w-full rounded-lg border" loading="lazy" referrerpolicy="no-referrer-when-downgrade"></iframe>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
</x-filament-panels::page>
|
||||
|
|
|
|||
|
|
@ -364,7 +364,7 @@
|
|||
|
||||
<div x-show="localCameraPreviews.length || localAttachmentPreviews.length" x-cloak class="mt-3 rounded-xl border border-sky-200 bg-sky-50 p-3">
|
||||
<div class="text-xs font-semibold text-sky-900">Anteprima immediata sul telefono</div>
|
||||
<div class="mt-1 text-[11px] text-sky-800">Le foto e gli allegati selezionati si vedono subito qui, prima dell'accodamento definitivo nella bozza ticket.</div>
|
||||
<div class="mt-1 text-[11px] text-sky-800">Le foto e gli allegati selezionati si vedono subito qui mentre entrano in coda. Nella griglia sotto ogni miniatura resta nello stesso box della sua descrizione.</div>
|
||||
|
||||
<template x-if="localCameraPreviews.length">
|
||||
<div class="mt-3">
|
||||
|
|
@ -419,13 +419,13 @@
|
|||
@if(count($this->selectedUploads) > 0)
|
||||
<div class="md:col-span-2">
|
||||
<div class="mb-2 text-xs font-semibold text-gray-700">Coda allegati pronta per il ticket</div>
|
||||
<div class="mb-2 text-[11px] text-gray-500">Qui sotto restano solo i dati operativi del file. L'anteprima immagine resta nel riquadro sopra fino all'invio del ticket.</div>
|
||||
<div class="mb-2 text-[11px] text-gray-500">Ogni allegato mantiene qui miniatura, protocollo e descrizione nello stesso riquadro, cosi puoi descrivere correttamente piu foto consecutive.</div>
|
||||
<div class="grid gap-3 sm:grid-cols-2">
|
||||
@foreach($this->selectedUploads as $upload)
|
||||
<div class="rounded-xl border bg-white p-3 text-xs shadow-sm">
|
||||
@if($upload['is_image'] && $upload['preview_url'])
|
||||
<div class="mb-2 aspect-[4/3] overflow-hidden rounded-lg border bg-slate-50">
|
||||
<img src="{{ $upload['preview_url'] }}" alt="{{ $upload['name'] }}" class="h-full w-full object-cover" />
|
||||
@if($upload['is_image'])
|
||||
<div class="mb-2 aspect-[4/3] overflow-hidden rounded-lg border bg-slate-50" x-show="Boolean(@js($upload['preview_url']) || previewFor(@js($upload['name']), @js($upload['original_name'])))">
|
||||
<img x-bind:src="@js($upload['preview_url']) || previewFor(@js($upload['name']), @js($upload['original_name']))" alt="{{ $upload['name'] }}" class="h-full w-full object-cover" />
|
||||
</div>
|
||||
@endif
|
||||
<div class="flex flex-wrap items-center gap-2 rounded-lg border bg-gray-50 px-3 py-2">
|
||||
|
|
@ -433,7 +433,7 @@
|
|||
{{ $upload['is_image'] ? 'Immagine' : (strtoupper(pathinfo($upload['name'], PATHINFO_EXTENSION) ?: 'FILE')) }}
|
||||
</span>
|
||||
<div class="text-[11px] text-gray-600">
|
||||
{{ $upload['is_image'] ? 'Anteprima visibile sopra' : 'Allegato pronto per l\'invio' }}
|
||||
{{ $upload['is_image'] ? 'Miniatura agganciata a questa descrizione' : 'Allegato pronto per l\'invio' }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user