diff --git a/app/Filament/Resources/Feedback/Pages/EditFeedback.php b/app/Filament/Resources/Feedback/Pages/EditFeedback.php index 88152294..e60582f4 100644 --- a/app/Filament/Resources/Feedback/Pages/EditFeedback.php +++ b/app/Filament/Resources/Feedback/Pages/EditFeedback.php @@ -142,7 +142,7 @@ class EditFeedback extends EditRecord public function getFooter(): ?View { - return view('filament.resources.feedback.similar-cases'); + return view('filament.resources.feedback.edit-footer'); } protected function mutateFormDataBeforeSave(array $data): array diff --git a/app/Filament/Resources/Feedback/RelationManagers/InteractionsRelationManager.php b/app/Filament/Resources/Feedback/RelationManagers/InteractionsRelationManager.php index 56e4dcf2..da12d61e 100644 --- a/app/Filament/Resources/Feedback/RelationManagers/InteractionsRelationManager.php +++ b/app/Filament/Resources/Feedback/RelationManagers/InteractionsRelationManager.php @@ -143,6 +143,7 @@ class InteractionsRelationManager extends RelationManager 'url' => $fileService->getTemporaryUrl($a, 60), 'size' => $a->size ? round($a->size / 1024, 1) . ' KB' : 'N/A', 'collection' => $a->collection, + 'mime_type' => $a->mime_type, ]; }); diff --git a/app/Services/FileService.php b/app/Services/FileService.php index df39ac07..c5231287 100644 --- a/app/Services/FileService.php +++ b/app/Services/FileService.php @@ -74,13 +74,28 @@ class FileService return Storage::disk('public')->url($attachment->path); } - return URL::temporarySignedRoute( - 'storage.local', + return Storage::disk($attachment->disk)->temporaryUrl( + $attachment->path, now()->addMinutes($minutes), - ['path' => $attachment->path] ); } + /** + * Generate a preview (inline) URL vs download URL. + */ + public function getPreviewUrl(FeedbackAttachment $attachment, int $minutes = 60): string + { + return $this->getTemporaryUrl($attachment, $minutes); + } + + /** + * Check if attachment is an image (for inline preview). + */ + public function isImage(FeedbackAttachment $attachment): bool + { + return in_array($attachment->mime_type, ['image/jpeg', 'image/jpg', 'image/png']); + } + /** * Get all attachments of a specific collection for a model. */ diff --git a/database/seeders/AfterSalesSeeder.php b/database/seeders/AfterSalesSeeder.php index 32c8ea33..6fa7289c 100644 --- a/database/seeders/AfterSalesSeeder.php +++ b/database/seeders/AfterSalesSeeder.php @@ -222,6 +222,9 @@ class AfterSalesSeeder extends Seeder 'reason' => 'Vấn đề kỹ thuật về điều hòa, cần Phòng Kỹ thuật kiểm tra và xử lý.', ]); + $disk = \Illuminate\Support\Facades\Storage::disk('local'); + + $disk->put('feedback-attachments/ac_repair_report.pdf', '%PDF-1.4 Demo report content'); \App\Models\FeedbackAttachment::create([ 'uuid' => \Illuminate\Support\Str::uuid(), 'feedback_id' => $allFeedback[2]->id, @@ -231,9 +234,10 @@ class AfterSalesSeeder extends Seeder 'disk' => 'local', 'collection' => 'proof_of_resolution', 'mime_type' => 'application/pdf', - 'size' => 204800, + 'size' => $disk->size('feedback-attachments/ac_repair_report.pdf'), ]); + $disk->put('feedback-attachments/ceiling_photo.jpg', 'dummy-jpeg-content'); \App\Models\FeedbackAttachment::create([ 'uuid' => \Illuminate\Support\Str::uuid(), 'feedback_id' => $allFeedback[0]->id, @@ -243,9 +247,10 @@ class AfterSalesSeeder extends Seeder 'disk' => 'local', 'collection' => 'customer_evidence', 'mime_type' => 'image/jpeg', - 'size' => 512000, + 'size' => $disk->size('feedback-attachments/ceiling_photo.jpg'), ]); + $disk->put('feedback-attachments/replaced_hinge_photo.png', 'dummy-png-content'); \App\Models\FeedbackAttachment::create([ 'uuid' => \Illuminate\Support\Str::uuid(), 'feedback_id' => $allFeedback[4]->id, @@ -255,7 +260,7 @@ class AfterSalesSeeder extends Seeder 'disk' => 'local', 'collection' => 'proof_of_resolution', 'mime_type' => 'image/png', - 'size' => 307200, + 'size' => $disk->size('feedback-attachments/replaced_hinge_photo.png'), ]); } } diff --git a/resources/views/filament/resources/feedback/attachment-links.blade.php b/resources/views/filament/resources/feedback/attachment-links.blade.php index 5027b3d1..bc64d340 100644 --- a/resources/views/filament/resources/feedback/attachment-links.blade.php +++ b/resources/views/filament/resources/feedback/attachment-links.blade.php @@ -2,39 +2,60 @@ @if(empty($links) || count($links) === 0)

No attachments.

@else - - - - - - - - - - - @foreach($links as $link) - - - - - - - @endforeach - -
FileCollectionSizeAction
{{ $link['name'] }} - @if($link['collection'] === 'proof_of_resolution') - proof_of_resolution - @elseif($link['collection'] === 'customer_evidence') - customer_evidence +
+ @foreach($links as $link) + @php + $isImage = in_array($link['mime_type'] ?? '', ['image/jpeg', 'image/jpg', 'image/png']); + @endphp +
+ {{-- File icon or image preview --}} +
+ @if($isImage) + {{ $link['name'] }} + + @elseif(($link['mime_type'] ?? '') === 'application/pdf') +
+ +
@else - {{ $link['collection'] }} +
+ +
@endif -
{{ $link['size'] }} - - Download - -
-

Links expire after 60 minutes.

+ + + {{-- File info --}} +
+

+ {{ $link['name'] }} +

+
+ {{ $link['size'] }} + @if(($link['collection'] ?? '') === 'proof_of_resolution') + Proof of Resolution + @elseif(($link['collection'] ?? '') === 'customer_evidence') + Customer Evidence + @else + {{ $link['collection'] ?? 'General' }} + @endif +
+
+ + {{-- Download button --}} + + Open + + + @endforeach + +

Click to open. Links expire after 60 minutes.

@endif diff --git a/resources/views/filament/resources/feedback/edit-footer.blade.php b/resources/views/filament/resources/feedback/edit-footer.blade.php new file mode 100644 index 00000000..abf81935 --- /dev/null +++ b/resources/views/filament/resources/feedback/edit-footer.blade.php @@ -0,0 +1,4 @@ +
+ @include('filament.resources.feedback.feedback-attachments') + @include('filament.resources.feedback.similar-cases') +
diff --git a/resources/views/filament/resources/feedback/feedback-attachments.blade.php b/resources/views/filament/resources/feedback/feedback-attachments.blade.php new file mode 100644 index 00000000..e205c3cb --- /dev/null +++ b/resources/views/filament/resources/feedback/feedback-attachments.blade.php @@ -0,0 +1,61 @@ +@php + use App\Services\FileService; + $record = $this->getRecord(); + $fileService = app(FileService::class); + $attachments = $record->attachments()->orderBy('created_at', 'desc')->get(); +@endphp + +@if($attachments->isNotEmpty()) +
+
+

+ + Attachments +

+ {{ $attachments->count() }} file(s) +
+
+
+ @foreach($attachments as $attachment) + @php + $url = $fileService->getTemporaryUrl($attachment, 60); + $isImage = $fileService->isImage($attachment); + $sizeKb = $attachment->size ? round($attachment->size / 1024, 1) . ' KB' : 'N/A'; + @endphp +
+ @if($isImage) +
+ {{ $attachment->name }} +
+ @elseif($attachment->mime_type === 'application/pdf') +
+ +
+ @else +
+ +
+ @endif +
+

+ {{ $attachment->name }} +

+
+ {{ $sizeKb }} + @if($attachment->collection === 'proof_of_resolution') + Proof + @elseif($attachment->collection === 'customer_evidence') + Evidence + @else + General + @endif +
+
+
+ @endforeach +
+
+
+@endif