FabioFratini 10 месяцев назад
Родитель
Сommit
cb4a88a4dc

+ 222 - 40
app/Http/Livewire/Traits/HasAllegato.php

@@ -5,9 +5,12 @@ namespace App\Http\Livewire\Traits;
 use App\Models\AllegatiGalleryType;
 use App\Models\ReportAllegatiGallery;
 use Livewire\WithFileUploads;
+use Illuminate\Support\Facades\Log;
 
 trait HasAllegato
 {
+    use WithFileUploads;
+
     public $allegatoId = 0;
     public $allegatoType = 0;
     public $allegatoGallery = 0;
@@ -21,6 +24,80 @@ trait HasAllegato
 
     protected $imageExtensions = ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'svg', 'webp'];
 
+    protected function getAllegatiRules()
+    {
+        return [
+            'allegati.*' => 'file|max:2048',// 2MB max per file
+        ];
+    }
+
+    public function updatedAllegati()
+    {
+        $this->resetErrorBag('allegati');
+
+        Log::info('File upload started', [
+            'files_count' => is_array($this->allegati) ? count($this->allegati) : 'No files',
+        ]);
+
+        try {
+            $this->validate($this->getAllegatiRules(), [
+                'allegati.*.file' => 'Il file deve essere valido',
+                'allegati.*.max' => 'Il file non può superare 2MB',
+            ]);
+
+            if (!empty($this->allegati)) {
+                foreach ($this->allegati as $index => $allegato) {
+                    try {
+                        $size = $allegato->getSize();
+                        Log::info('Processing file', [
+                            'index' => $index,
+                            'original_name' => $allegato->getClientOriginalName(),
+                            'size' => $size,
+                            'size_mb' => round($size / 1024 / 1024, 2) . 'MB',
+                        ]);
+
+                        $name = $allegato->getClientOriginalName();
+                        $allegato->storeAs('', $name, 'public');
+                        $this->allegatiFiles[] = $name;
+
+                        Log::info('File stored successfully', [
+                            'name' => $name
+                        ]);
+                    } catch (\Exception $e) {
+                        Log::error('File upload error', [
+                            'index' => $index,
+                            'error' => $e->getMessage(),
+                            'trace' => $e->getTraceAsString()
+                        ]);
+                        session()->flash('error', 'Errore durante il caricamento del file: ' . $e->getMessage());
+                    }
+                }
+                $this->emit('attachments', implode("|", $this->allegatiFiles));
+                $this->allegati = [];
+
+                Log::info('All files processed', [
+                    'total_files' => count($this->allegatiFiles)
+                ]);
+            }
+        } catch (\Exception $e) {
+            Log::error('Validation error', [
+                'error' => $e->getMessage(),
+                'trace' => $e->getTraceAsString()
+            ]);
+            session()->flash('error', 'Errore di validazione: ' . $e->getMessage());
+        }
+    }
+
+    public function updatedAllegatoGallery()
+    {
+        $this->resetErrorBag('allegatoGallery');
+    }
+
+    public function updatedAllegatoName()
+    {
+        $this->resetErrorBag('allegatoName');
+    }
+
     public function getAllegatoType($type)
     {
         if ($type > 0) {
@@ -32,56 +109,97 @@ trait HasAllegato
 
     public function addAllegato($type)
     {
-        $this->allegatoId = 0;
+        $this->resetAllegatoFields();
         $this->allegatoType = $type;
-        $this->allegatoGallery = 0;
-        $this->allegatoName = '';
-        $this->allegatoVisible = false;
-        $this->allegatoFiles = '';
-        $this->allegatiFiles = [];
         $this->emit('attachments', "");
+        $this->emit('open-allegati-modal');
+
+        Log::info('Add allegato modal opened', [
+            'type' => $type
+        ]);
     }
 
     public function saveAllegato()
     {
-        if ($this->allegatoGallery == 1) {
+        Log::info('Save allegato started', [
+            'allegatoName' => $this->allegatoName,
+            'allegatoGallery' => $this->allegatoGallery,
+            'files_count' => count($this->allegatiFiles)
+        ]);
+
+        $this->validate([
+            'allegatoName' => 'required',
+            'allegatoGallery' => 'required',
+        ], [
+            'allegatoName.required' => 'Il nome è obbligatorio',
+            'allegatoGallery.required' => 'La tipologia è obbligatoria',
+        ]);
+
+        if ($this->allegatoGallery == 1 && !empty($this->allegatiFiles)) {
             foreach ($this->allegatiFiles as $file) {
                 $extension = pathinfo($file, PATHINFO_EXTENSION);
                 if (!in_array(strtolower($extension), $this->imageExtensions)) {
+                    Log::warning('Invalid file type', [
+                        'file' => $file,
+                        'extension' => $extension,
+                        'allowed_extensions' => $this->imageExtensions
+                    ]);
                     session()->flash('error', 'I File devono essere immagini per Tipologia: Foto sinistro');
                     return;
                 }
             }
         }
 
+        if (empty($this->allegatiFiles)) {
+            $this->addError('allegati', 'È necessario caricare almeno un file');
+            Log::warning('No files uploaded');
+            return;
+        }
+
         $files = implode("|", $this->allegatiFiles);
 
-        if ($this->allegatoId > 0) {
-            ReportAllegatiGallery::where('id', $this->allegatoId)->update([
-                'file_type' => $this->allegatoType,
-                'gallery_type' => $this->allegatoGallery,
-                'name' => $this->allegatoName,
-                'is_visible' => $this->allegatoVisible,
-                'files' => $files,
-                'state' => 0
-            ]);
-        } else {
-            ReportAllegatiGallery::create([
-                'report_id' => $this->dataId,
-                'file_type' => $this->allegatoType,
-                'gallery_type' => $this->allegatoGallery,
-                'name' => $this->allegatoName,
-                'is_visible' => $this->allegatoVisible,
-                'files' => $files,
-                'state' => 0,
-                'created' => date("Y-m-d H:i:s"),
-                'created_by' => 0
+        try {
+            if ($this->allegatoId > 0) {
+                Log::info('Updating existing allegato', [
+                    'id' => $this->allegatoId
+                ]);
+
+                ReportAllegatiGallery::where('id', $this->allegatoId)->update([
+                    'file_type' => $this->allegatoType,
+                    'gallery_type' => $this->allegatoGallery,
+                    'name' => $this->allegatoName,
+                    'is_visible' => $this->allegatoVisible,
+                    'files' => $files,
+                    'state' => 0
+                ]);
+            } else {
+                Log::info('Creating new allegato');
+
+                ReportAllegatiGallery::create([
+                    'report_id' => $this->dataId,
+                    'file_type' => $this->allegatoType,
+                    'gallery_type' => $this->allegatoGallery,
+                    'name' => $this->allegatoName,
+                    'is_visible' => $this->allegatoVisible,
+                    'files' => $files,
+                    'state' => 0,
+                    'created' => date("Y-m-d H:i:s"),
+                    'created_by' => 0
+                ]);
+            }
+
+            Log::info('Allegato saved successfully');
+            session()->flash('success', 'Allegato salvato con successo');
+            $this->resetAllegatoFields();
+            $this->refreshAllegatiCollections();
+            $this->emit('close-modal');
+        } catch (\Exception $e) {
+            Log::error('Save error', [
+                'error' => $e->getMessage(),
+                'trace' => $e->getTraceAsString()
             ]);
+            session()->flash('error', 'Errore durante il salvataggio: ' . $e->getMessage());
         }
-
-        $this->resetAllegatoFields();
-        $this->refreshAllegatiCollections();
-        $this->emit('close-modal');
     }
 
     private function resetAllegatoFields()
@@ -93,6 +211,10 @@ trait HasAllegato
         $this->allegatoFiles = '';
         $this->allegatiFiles = [];
         $this->allegatoType = 0;
+        $this->allegati = [];
+        $this->resetErrorBag();
+
+        Log::info('Allegato fields reset');
     }
 
     private function refreshAllegatiCollections()
@@ -106,11 +228,22 @@ trait HasAllegato
             ->where('file_type', 1)
             ->orderBy('name')
             ->get();
+
+        Log::info('Allegati collections refreshed', [
+            'immagini_count' => $this->allegatiImmagini->count(),
+            'documenti_count' => $this->allegatiDocumenti->count()
+        ]);
     }
 
     public function editAllegato($id)
     {
+        $this->resetErrorBag();
         $this->emit('attachments', "");
+
+        Log::info('Edit allegato started', [
+            'id' => $id
+        ]);
+
         $a = ReportAllegatiGallery::where('id', $id)->first();
 
         if ($a != null) {
@@ -118,26 +251,75 @@ trait HasAllegato
             $this->allegatoType = $a->file_type;
             $this->allegatoGallery = $a->gallery_type;
             $this->allegatoName = $a->name;
+            $this->allegatoVisible = $a->is_visible;
             $this->allegatoFiles = $a->files;
             $this->allegatiFiles = explode("|", $this->allegatoFiles);
+
+            Log::info('Allegato loaded for editing', [
+                'name' => $this->allegatoName,
+                'files_count' => count($this->allegatiFiles)
+            ]);
+
             $this->emit('attachments', $this->allegatoFiles);
+            $this->emit('open-allegati-modal');
+        } else {
+            Log::warning('Allegato not found', [
+                'id' => $id
+            ]);
         }
     }
 
     public function removeAllegato($id)
     {
-        ReportAllegatiGallery::findOrFail($id)->delete();
-        $this->refreshAllegatiCollections();
+        try {
+            Log::info('Remove allegato started', [
+                'id' => $id
+            ]);
+
+            ReportAllegatiGallery::findOrFail($id)->delete();
+
+            Log::info('Allegato removed successfully');
+            session()->flash('success', 'Allegato eliminato con successo');
+            $this->refreshAllegatiCollections();
+        } catch (\Exception $e) {
+            Log::error('Remove error', [
+                'error' => $e->getMessage(),
+                'trace' => $e->getTraceAsString()
+            ]);
+            session()->flash('error', 'Errore durante l\'eliminazione: ' . $e->getMessage());
+        }
     }
 
-    public function updatedAllegati()
+    public function removeFile($filename)
     {
-        foreach ($this->allegati as $allegato) {
-            $name = $allegato->getClientOriginalName();
-            $allegato->storeAs('', $name, 'public');
-            $this->allegatiFiles[] = $name;
+        Log::info('Remove file started', [
+            'filename' => $filename
+        ]);
+
+        $index = array_search($filename, $this->allegatiFiles);
+        if ($index !== false) {
+            unset($this->allegatiFiles[$index]);
+            $this->allegatiFiles = array_values($this->allegatiFiles);
+
+            $this->allegatoFiles = implode("|", $this->allegatiFiles);
+
+            Log::info('File removed from list', [
+                'remaining_files' => count($this->allegatiFiles)
+            ]);
+
+            $this->emit('attachments', $this->allegatoFiles);
+        } else {
+            Log::warning('File not found in list', [
+                'filename' => $filename,
+                'current_files' => $this->allegatiFiles
+            ]);
         }
-        $this->emit('attachments', implode("|", $this->allegatiFiles));
-        $this->allegati = [];
+    }
+
+    public function closeAllegatiModal()
+    {
+        Log::info('Closing allegati modal');
+        $this->resetAllegatoFields();
+        $this->emit('close-modal');
     }
 }

+ 134 - 57
resources/views/components/report/allegati/allegati-modal.blade.php

@@ -1,69 +1,146 @@
-<div wire:ignore class="modal fade " id="allegatiModal" tabindex="-1" aria-labelledby="allegatiModalLabel"
-            aria-hidden="true" data-keyboard="false">
-            <div class="modal-dialog modal-xl">
-                <div class="modal-content">
-                    <div class="modal-header">
-                        <h5 class="modal-title" id="allegatiModalLabel">Inserimento/modifica allegati</h5>
+<div wire:ignore.self class="modal fade" id="allegatiModal" tabindex="-1" aria-labelledby="allegatiModalLabel" aria-hidden="true" data-keyboard="false" data-backdrop="static">
+    <div class="modal-dialog modal-xl">
+        <div class="modal-content">
+            <div class="modal-header">
+                <h5 class="modal-title" id="allegatiModalLabel">
+                    @if($allegatoId > 0)
+                        Modifica allegato
+                    @else
+                        Nuovo allegato
+                    @endif
+                </h5>
+                <button type="button" class="close" data-dismiss="modal" aria-label="Close" wire:click="closeAllegatiModal">
+                    <span aria-hidden="true">&times;</span>
+                </button>
+            </div>
+            <div class="modal-body">
+                <div class="row mt-3">
+                    <div class="col-md-4">
+                        <label for="allegatoName" class="form-label">Nome</label>
                     </div>
-                    <div class="modal-body">
-                        <div class="row mt-3">
-                            <div class="col-md-4">
-                                <label for="allegatoName" class="form-label">Nome</label>
-                            </div>
-                            <div class="col-md-8">
-                                <input class="form-control" type="text" id="allegatoName" placeholder="Nome"
-                                    wire:model="allegatoName">
-                            </div>
-                        </div>
-                        <div class="row mt-3">
-                            <div class="col-md-4">
-                                <label for="allegatoGallery" class="form-label">Tipologia</label>
-                            </div>
-                            <div class="col-md-8">
-                                <select class="form-control" style="width:100%" wire:model="allegatoGallery">
-                                    <option value="">
-                                        @foreach ($allegatiType as $t)
-                                            <option value="{{ $t->id }}">{{ $t->name }}
-                                        @endforeach
-                                </select>
-                            </div>
-                        </div>
+                    <div class="col-md-8">
+                        <input class="form-control @error('allegatoName') is-invalid @enderror" type="text" id="allegatoName" placeholder="Nome" wire:model="allegatoName">
+                        @error('allegatoName')
+                            <div class="invalid-feedback">{{ $message }}</div>
+                        @enderror
+                    </div>
+                </div>
+                <div class="row mt-3">
+                    <div class="col-md-4">
+                        <label for="allegatoGallery" class="form-label">Tipologia</label>
+                    </div>
+                    <div class="col-md-8">
+                        <select class="form-control @error('allegatoGallery') is-invalid @enderror" style="width:100%" wire:model="allegatoGallery" id="allegatoGallery">
+                            <option value="">Seleziona...</option>
+                            @foreach ($allegatiType as $t)
+                                <option value="{{ $t->id }}">{{ $t->name }}</option>
+                            @endforeach
+                        </select>
+                        @error('allegatoGallery')
+                            <div class="invalid-feedback">{{ $message }}</div>
+                        @enderror
+                    </div>
+                </div>
 
-                        <div class="row mt-3">
-                            <div class="col-md-4">
-                                <label for="" class="form-label">Files</label>
-                            </div>
-                            <div class="col-md-8">
-                                <input type="file" wire:model="allegati" multiple>
-                                <div id="attachments">
-                                    @foreach ($allegatiFiles as $a)
-                                        {{ $a }}<br>
-                                    @endforeach
-                                </div>
-                            </div>
+                <div class="row mt-3">
+                    <div class="col-md-4">
+                        <label for="allegati" class="form-label">Files</label>
+                    </div>
+                    <div class="col-md-8">
+
+                        <div class="form-group">
+                            <input wire:model="allegati" type="file" class="form-control-file" id="allegati" multiple>
                         </div>
 
-                        <div class="row mt-3">
-                            <div class="col-md-4">
-                                <label for="" class="form-label">Visibile in stampa</label>
-                            </div>
-                            <div class="col-md-8">
-                                <div class="custom-control custom-switch custom-switch-md">
-                                    <input type="checkbox" class="custom-control-input" id="allegatoVisible"
-                                        wire:model="allegatoVisible">
-                                    <label class="custom-control-label" for="allegatoVisible">&nbsp;</label>
+                        <div id="files-container" class="mt-2">
+                            @if(!empty($allegatiFiles) && count($allegatiFiles) > 0)
+                                <div class="card">
+                                    <div class="card-header bg-light d-flex justify-content-between align-items-center">
+                                        <strong>File caricati ({{ count($allegatiFiles) }})</strong>
+                                    </div>
+                                    <div class="card-body p-2">
+                                        <ul class="list-group list-group-flush">
+                                            @foreach ($allegatiFiles as $a)
+                                                <li class="list-group-item d-flex justify-content-between align-items-center py-2">
+                                                    <span>{{ $a }}</span>
+                                                    <button class="btn btn-sm btn-outline-danger"
+                                                        wire:click.prevent="removeFile('{{ $a }}')">
+                                                        <i class="fa fa-times"></i>
+                                                    </button>
+                                                </li>
+                                            @endforeach
+                                        </ul>
+                                    </div>
                                 </div>
-                            </div>
+                            @endif
                         </div>
+                    </div>
+                </div>
 
+                <div class="row mt-3">
+                    <div class="col-md-4">
+                        <label for="allegatoVisible" class="form-label">Visibile in stampa</label>
                     </div>
-                    <div class="modal-footer">
-                        <button type="button" class="btn btn-secondary" data-dismiss="modal">Annulla</button>
-                        @if (!$this->validated)
-                            <button type="button" class="btn btn-primary" wire:click.prevent="saveAllegato()">Salva</button>
-                        @endif
+                    <div class="col-md-8">
+                        <div class="custom-control custom-switch custom-switch-md">
+                            <input type="checkbox" class="custom-control-input" id="allegatoVisible" wire:model="allegatoVisible">
+                            <label class="custom-control-label" for="allegatoVisible">&nbsp;</label>
+                        </div>
                     </div>
                 </div>
-
+            </div>
+            <div class="modal-footer">
+                <button type="button" class="btn btn-secondary" data-dismiss="modal" wire:click="closeAllegatiModal">Annulla</button>
+                @if (!$this->validated)
+                    <button type="button" class="btn btn-primary" wire:click.prevent="saveAllegato()">Salva</button>
+                @endif
             </div>
         </div>
+    </div>
+</div>
+
+@push('scripts')
+<script>
+    document.addEventListener('livewire:load', function () {
+        window.livewire.on('open-allegati-modal', function () {
+            $('#allegatiModal').modal('show');
+            console.log('Modal opened');
+        });
+
+        window.livewire.on('close-modal', function () {
+            $('#allegatiModal').modal('hide');
+        });
+
+        window.livewire.on('attachments', function (files) {
+            console.log('Attachments updated:', files);
+
+            setTimeout(function() {
+                window.livewire.emit('refresh');
+            }, 200);
+        });
+
+        document.getElementById('allegati').addEventListener('change', function(e) {
+            const maxFileSize = 2 * 1024 * 1024; // 2MB in bytes
+            const errorElement = document.getElementById('file-size-error');
+            errorElement.style.display = 'none';
+            errorElement.textContent = '';
+
+            if (this.files.length > 0) {
+                for (let i = 0; i < this.files.length; i++) {
+                    const file = this.files[i];
+                    console.log('File ' + (i+1) + ' size: ' + file.size + ' bytes');
+
+                    if (file.size > maxFileSize) {
+                        errorElement.style.display = 'block';
+                        errorElement.textContent = 'Errore: Il file "' + file.name + '" è troppo grande (' +
+                            Math.round(file.size / 1024 / 1024 * 10) / 10 + 'MB). La dimensione massima è 2MB.';
+                        // Clear the file input
+                        this.value = '';
+                        return;
+                    }
+                }
+            }
+        });
+    });
+</script>
+@endpush

+ 15 - 8
resources/views/components/report/allegati/allegato.blade.php

@@ -18,6 +18,7 @@
                                 </tr>
                             </thead>
                             <tbody>
+
                                 @foreach ($allegatiImmagini as $allegato)
                                     <tr>
                                         <td>{{ $allegato->name }}</td>
@@ -37,14 +38,20 @@
                                         @endif
                                     </tr>
                                     @if ($allegato->files != '')
-                                        <tr>
-                                            <td colspan="5" style="border-top:0px solid;">
-                                                @foreach (explode('|', $allegato->files) as $a)
-                                                    <a href="{{ url('/storage/' . $a) }}"
-                                                        target="_blank">{{ $a }}</a>&nbsp;&nbsp;&nbsp;
-                                                @endforeach
-                                            </td>
-                                        </tr>
+                                        @php
+                                            $files = explode('|', $allegato->files);
+                                            $chunks = array_chunk($files, 3);
+                                        @endphp
+
+                                        @foreach ($chunks as $fileChunk)
+                                            <tr>
+                                                <td colspan="5" style="border-top:0px solid;">
+                                                    @foreach ($fileChunk as $a)
+                                                        <a href="{{ url('/storage/' . $a) }}" target="_blank">{{ $a }}</a>&nbsp;&nbsp;&nbsp;
+                                                    @endforeach
+                                                </td>
+                                            </tr>
+                                        @endforeach
                                     @endif
                                 @endforeach
                             </tbody>