feat: add download support for non-PDF files in assignment submission views
This commit is contained in:
parent
9727e8d52f
commit
1f0db96179
@ -11,6 +11,7 @@
|
||||
use App\Models\Assignment;
|
||||
use App\Models\AssignmentSubmission;
|
||||
use Filament\Actions\Action;
|
||||
use Filament\Infolists\Components\TextEntry;
|
||||
use Filament\Resources\Pages\Page;
|
||||
use Filament\Support\Enums\Width;
|
||||
use Illuminate\Support\Arr;
|
||||
@ -100,6 +101,8 @@ public function submissionSummary(): Collection
|
||||
'submitted' => $isSubmitted,
|
||||
'submitted_at_formatted' => $isSubmitted ? $submission?->submitted_at?->translatedFormat('l, d F Y H:i') : '-',
|
||||
'has_file' => $isSubmitted && $submission->hasMedia('submission'),
|
||||
'is_pdf' => $isSubmitted && str_ends_with(strtolower($submission->getFirstMediaUrl('submission')), '.pdf'),
|
||||
'file_url' => $isSubmitted ? $submission->getFirstMediaUrl('submission') : null,
|
||||
'status_classes' => Arr::toCssClasses([
|
||||
'inline-flex items-center gap-1 rounded-full px-2.5 py-0.5 text-xs font-medium',
|
||||
'bg-success-100 text-success-700 dark:bg-success-900/30 dark:text-success-400' => $isSubmitted,
|
||||
@ -129,6 +132,8 @@ public function submissionSummary(): Collection
|
||||
'submitted' => $isSubmitted,
|
||||
'submitted_at_formatted' => $isSubmitted ? $submission->submitted_at?->translatedFormat('l, d F Y H:i') : '-',
|
||||
'has_file' => $isSubmitted && $submission->hasMedia('submission'),
|
||||
'is_pdf' => $isSubmitted && str_ends_with(strtolower($submission->getFirstMediaUrl('submission')), '.pdf'),
|
||||
'file_url' => $isSubmitted ? $submission->getFirstMediaUrl('submission') : null,
|
||||
'status_classes' => Arr::toCssClasses([
|
||||
'inline-flex items-center gap-1 rounded-full px-2.5 py-0.5 text-xs font-medium',
|
||||
'bg-success-100 text-success-700 dark:bg-success-900/30 dark:text-success-400' => $isSubmitted,
|
||||
@ -195,14 +200,39 @@ public function previewSubmissionAction(): Action
|
||||
->modalWidth(Width::SixExtraLarge)
|
||||
->infolist([
|
||||
PdfViewerEntry::make('submission')
|
||||
->visible(fn (AssignmentSubmission $record) => str_ends_with(strtolower($record->getFirstMediaUrl('submission')), '.pdf'))
|
||||
->hiddenLabel()
|
||||
->fileUrl(fn (AssignmentSubmission $record) => $record->getFirstMediaUrl('submission'))
|
||||
->columnSpanFull(),
|
||||
|
||||
TextEntry::make('download_file')
|
||||
->label('Berkas non-PDF')
|
||||
->visible(fn (AssignmentSubmission $record) => ! str_ends_with(strtolower($record->getFirstMediaUrl('submission')), '.pdf'))
|
||||
->hint('Klik ikon unduh untuk melihat isi berkas.')
|
||||
->default(fn (AssignmentSubmission $record) => $record->getFirstMedia('submission')?->file_name ?? 'Unduh Berkas')
|
||||
->suffixAction(
|
||||
Action::make('download')
|
||||
->label('Unduh')
|
||||
->icon('heroicon-o-arrow-down-tray')
|
||||
->url(fn (AssignmentSubmission $record) => $record->getFirstMediaUrl('submission'), true)
|
||||
),
|
||||
])
|
||||
->modalSubmitAction(false)
|
||||
->modalCancelActionLabel('Tutup');
|
||||
}
|
||||
|
||||
public function downloadMedia(int $submissionId)
|
||||
{
|
||||
$submission = AssignmentSubmission::findOrFail($submissionId);
|
||||
$media = $submission->getFirstMedia('submission');
|
||||
|
||||
if (! $media) {
|
||||
return;
|
||||
}
|
||||
|
||||
return response()->download($media->getPath(), $media->file_name);
|
||||
}
|
||||
|
||||
protected function getHeaderActions(): array
|
||||
{
|
||||
return [
|
||||
|
||||
@ -248,6 +248,26 @@ public function getSubmissionFileUrl(): ?string
|
||||
return $this->existingSubmission?->getFirstMediaUrl('submission');
|
||||
}
|
||||
|
||||
public function downloadAttachment()
|
||||
{
|
||||
$media = $this->record->getFirstMedia('assignments');
|
||||
if (! $media) {
|
||||
return;
|
||||
}
|
||||
|
||||
return response()->download($media->getPath(), $media->file_name);
|
||||
}
|
||||
|
||||
public function downloadSubmission()
|
||||
{
|
||||
$media = $this->existingSubmission?->getFirstMedia('submission');
|
||||
if (! $media) {
|
||||
return;
|
||||
}
|
||||
|
||||
return response()->download($media->getPath(), $media->file_name);
|
||||
}
|
||||
|
||||
public function submit(): void
|
||||
{
|
||||
$student = $this->student;
|
||||
|
||||
@ -111,7 +111,7 @@ public static function configure(Schema $schema): Schema
|
||||
->columnSpanFull(),
|
||||
|
||||
AdvancedFileUpload::make('pdf')
|
||||
->label('Lampiran PDF')
|
||||
->label('Lampiran Berkas')
|
||||
->pdfPreviewHeight(400)
|
||||
->pdfDisplayPage(1)
|
||||
->pdfToolbar(true)
|
||||
@ -119,7 +119,7 @@ public static function configure(Schema $schema): Schema
|
||||
->pdfFitType(PdfViewFit::FIT)
|
||||
->pdfNavPanes(true)
|
||||
->disk(config('filesystems.default'))
|
||||
->acceptedFileTypes(['application/pdf'])
|
||||
->acceptedFileTypes(['application/pdf', 'application/zip', 'application/x-zip-compressed', 'application/x-zip', 'application/octet-stream', 'multipart/x-zip', '.zip', '.7z'])
|
||||
->maxSize(1024 * 5)
|
||||
->directory('assignments-tmp/'.now()->toDateString())
|
||||
->nullable()
|
||||
|
||||
@ -13,7 +13,7 @@ public static function configure(Schema $schema): Schema
|
||||
return $schema
|
||||
->components([
|
||||
AdvancedFileUpload::make('file')
|
||||
->label(fn ($get) => $get('is_resubmit') ? 'Ganti Berkas PDF (Opsional)' : 'Lampiran Berkas Tugas')
|
||||
->label(fn ($get) => $get('is_resubmit') ? 'Ganti Berkas Tugas (Opsional)' : 'Lampiran Berkas Tugas')
|
||||
->pdfPreviewHeight(400)
|
||||
->pdfDisplayPage(1)
|
||||
->pdfToolbar(true)
|
||||
@ -21,12 +21,12 @@ public static function configure(Schema $schema): Schema
|
||||
->pdfFitType(PdfViewFit::FIT)
|
||||
->pdfNavPanes(true)
|
||||
->disk(config('filesystems.default'))
|
||||
->acceptedFileTypes(['application/pdf'])
|
||||
->acceptedFileTypes(['application/pdf', 'application/zip', 'application/x-zip-compressed', 'application/x-zip', 'application/octet-stream', 'multipart/x-zip', '.zip', '.7z'])
|
||||
->maxSize(1024 * 5)
|
||||
->directory('submissions/'.now()->toDateString())
|
||||
->required(fn ($get) => ! $get('is_resubmit'))
|
||||
->hiddenLabel()
|
||||
->helperText('Hanya file PDF dengan ukuran maksimal 5MB.')
|
||||
->helperText('File PDF atau ZIP dengan ukuran maksimal 5MB.')
|
||||
->columnSpanFull(),
|
||||
]);
|
||||
}
|
||||
|
||||
@ -101,12 +101,21 @@
|
||||
|
||||
<td class="px-4 py-3">
|
||||
@if ($item->has_file)
|
||||
<button type="button"
|
||||
wire:click="mountAction('previewSubmission', { submissionId: {{ $item->submission_id }} })"
|
||||
class="inline-flex items-center gap-1 text-xs text-primary-600 dark:text-primary-400 hover:underline">
|
||||
<x-filament::icon icon="heroicon-o-eye" class="h-3.5 w-3.5" />
|
||||
Lihat Tugas
|
||||
</button>
|
||||
@if ($item->is_pdf)
|
||||
<button type="button"
|
||||
wire:click="mountAction('previewSubmission', { submissionId: {{ $item->submission_id }} })"
|
||||
class="inline-flex items-center gap-1 text-xs text-primary-600 dark:text-primary-400 hover:underline">
|
||||
<x-filament::icon icon="heroicon-o-eye" class="h-3.5 w-3.5" />
|
||||
Lihat Tugas
|
||||
</button>
|
||||
@else
|
||||
<button type="button"
|
||||
wire:click="downloadMedia({{ $item->submission_id }})"
|
||||
class="inline-flex items-center gap-1 text-xs text-success-600 dark:text-success-400 hover:underline">
|
||||
<x-filament::icon icon="heroicon-o-arrow-down-tray" class="h-3.5 w-3.5" />
|
||||
Unduh ZIP
|
||||
</button>
|
||||
@endif
|
||||
@else
|
||||
<span class="text-xs text-gray-400">-</span>
|
||||
@endif
|
||||
|
||||
@ -35,11 +35,28 @@ class="prose prose-sm dark:prose-invert max-w-none text-gray-600 dark:text-gray-
|
||||
@if ($attachmentUrl = $this->record->getFirstMediaUrl('assignments'))
|
||||
<div class="mt-4 pt-4 border-t border-gray-100 dark:border-gray-700">
|
||||
<p class="text-xs font-medium text-gray-500 dark:text-gray-400 mb-2">Lampiran Tugas</p>
|
||||
<div
|
||||
class="rounded-lg overflow-hidden border border-gray-200 dark:border-gray-700 bg-gray-50 dark:bg-gray-900">
|
||||
<iframe src="{{ $attachmentUrl }}" width="100%" height="500"
|
||||
class="block border-0"></iframe>
|
||||
</div>
|
||||
@if (str_ends_with(strtolower($attachmentUrl), '.pdf'))
|
||||
<div
|
||||
class="rounded-lg overflow-hidden border border-gray-200 dark:border-gray-700 bg-gray-50 dark:bg-gray-900">
|
||||
<iframe src="{{ $attachmentUrl }}" width="100%" height="500"
|
||||
class="block border-0"></iframe>
|
||||
</div>
|
||||
@else
|
||||
<div class="flex items-center justify-between p-4 bg-gray-50 dark:bg-gray-900 rounded-xl border border-gray-200 dark:border-gray-700 group hover:border-primary-500 transition-colors">
|
||||
<div class="flex items-center gap-4">
|
||||
<div class="p-2.5 bg-primary-100 dark:bg-primary-900/30 rounded-lg text-primary-600">
|
||||
<x-filament::icon icon="heroicon-o-document-arrow-down" class="w-6 h-6" />
|
||||
</div>
|
||||
<div>
|
||||
<p class="text-sm font-semibold text-gray-900 dark:text-white">{{ $this->record->getFirstMedia('assignments')?->file_name ?? 'Berkas Lampiran' }}</p>
|
||||
<p class="text-xs text-gray-500 dark:text-gray-400">Klik tombol di samping untuk mengunduh berkas.</p>
|
||||
</div>
|
||||
</div>
|
||||
<x-filament::button type="button" wire:click="downloadAttachment" color="gray" size="sm" icon="heroicon-o-arrow-down-tray">
|
||||
Unduh
|
||||
</x-filament::button>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
@endif
|
||||
</x-filament::section>
|
||||
@ -63,11 +80,28 @@ class="flex h-10 w-10 shrink-0 items-center justify-center rounded-full bg-dange
|
||||
@if ($url = $this->getSubmissionFileUrl())
|
||||
<div>
|
||||
<p class="text-xs font-medium text-gray-500 dark:text-gray-400 mb-2">File yang Terakhir Dikumpulkan</p>
|
||||
<div
|
||||
class="rounded-lg overflow-hidden border border-gray-200 dark:border-gray-700 bg-gray-50 dark:bg-gray-900">
|
||||
<iframe src="{{ $url }}" width="100%" height="400"
|
||||
class="block border-0"></iframe>
|
||||
</div>
|
||||
@if (str_ends_with(strtolower($url), '.pdf'))
|
||||
<div
|
||||
class="rounded-lg overflow-hidden border border-gray-200 dark:border-gray-700 bg-gray-50 dark:bg-gray-900">
|
||||
<iframe src="{{ $url }}" width="100%" height="400"
|
||||
class="block border-0"></iframe>
|
||||
</div>
|
||||
@else
|
||||
<div class="flex items-center justify-between p-4 bg-gray-50 dark:bg-gray-900 rounded-xl border border-gray-200 dark:border-gray-700 group hover:border-primary-500 transition-colors">
|
||||
<div class="flex items-center gap-4">
|
||||
<div class="p-2.5 bg-primary-100 dark:bg-primary-900/30 rounded-lg text-primary-600">
|
||||
<x-filament::icon icon="heroicon-o-document-arrow-down" class="w-6 h-6" />
|
||||
</div>
|
||||
<div>
|
||||
<p class="text-sm font-semibold text-gray-900 dark:text-white">{{ $this->existingSubmission?->getFirstMedia('submission')?->file_name ?? 'Berkas Tugas' }}</p>
|
||||
<p class="text-xs text-gray-500 dark:text-gray-400">Berkas non-PDF (ZIP)</p>
|
||||
</div>
|
||||
</div>
|
||||
<x-filament::button type="button" wire:click="downloadSubmission" color="gray" size="sm" icon="heroicon-o-arrow-down-tray">
|
||||
Unduh
|
||||
</x-filament::button>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
@endif
|
||||
</x-filament::section>
|
||||
@ -86,11 +120,27 @@ class="flex flex-col items-center justify-center py-8 text-center text-gray-500
|
||||
<div class="mt-6">
|
||||
<p class="text-xs font-medium text-gray-500 dark:text-gray-400 mb-2 italic">File yang telah
|
||||
dikumpulkan oleh kelompok Anda:</p>
|
||||
<div
|
||||
class="rounded-lg overflow-hidden border border-gray-200 dark:border-gray-700 bg-gray-50 dark:bg-gray-900">
|
||||
<iframe src="{{ $url }}" width="100%" height="400"
|
||||
class="block border-0"></iframe>
|
||||
</div>
|
||||
@if (str_ends_with(strtolower($url), '.pdf'))
|
||||
<div
|
||||
class="rounded-lg overflow-hidden border border-gray-200 dark:border-gray-700 bg-gray-50 dark:bg-gray-900">
|
||||
<iframe src="{{ $url }}" width="100%" height="400"
|
||||
class="block border-0"></iframe>
|
||||
</div>
|
||||
@else
|
||||
<div class="flex items-center justify-between p-4 bg-gray-50 dark:bg-gray-900 rounded-xl border border-gray-200 dark:border-gray-700">
|
||||
<div class="flex items-center gap-4">
|
||||
<div class="p-2.5 bg-primary-100 dark:bg-primary-900/30 rounded-lg text-primary-600">
|
||||
<x-filament::icon icon="heroicon-o-document-arrow-down" class="w-6 h-6" />
|
||||
</div>
|
||||
<div>
|
||||
<p class="text-sm font-semibold text-gray-900 dark:text-white">{{ $this->existingSubmission?->getFirstMedia('submission')?->file_name ?? 'Berkas Tugas' }}</p>
|
||||
</div>
|
||||
</div>
|
||||
<x-filament::button type="button" wire:click="downloadSubmission" color="gray" size="sm" icon="heroicon-o-arrow-down-tray">
|
||||
Unduh
|
||||
</x-filament::button>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
@endif
|
||||
</x-filament::section>
|
||||
@ -112,11 +162,28 @@ class="block border-0"></iframe>
|
||||
@if ($this->isResubmit && ($url = $this->getSubmissionFileUrl()))
|
||||
<div class="mb-4">
|
||||
<p class="text-xs font-medium text-gray-500 dark:text-gray-400 mb-2">File Terkumpul Saat Ini</p>
|
||||
<div
|
||||
class="rounded-lg overflow-hidden border border-success-200 dark:border-success-800 bg-gray-50 dark:bg-gray-900">
|
||||
<iframe src="{{ $url }}" width="100%" height="400"
|
||||
class="block border-0"></iframe>
|
||||
</div>
|
||||
@if (str_ends_with(strtolower($url), '.pdf'))
|
||||
<div
|
||||
class="rounded-lg overflow-hidden border border-success-200 dark:border-success-800 bg-gray-50 dark:bg-gray-900">
|
||||
<iframe src="{{ $url }}" width="100%" height="400"
|
||||
class="block border-0"></iframe>
|
||||
</div>
|
||||
@else
|
||||
<div class="flex items-center justify-between p-4 bg-success-50/50 dark:bg-success-900/10 rounded-xl border border-success-200 dark:border-success-800">
|
||||
<div class="flex items-center gap-4">
|
||||
<div class="p-2.5 bg-success-100 dark:bg-success-900/30 rounded-lg text-success-600">
|
||||
<x-filament::icon icon="heroicon-o-check-badge" class="w-6 h-6" />
|
||||
</div>
|
||||
<div>
|
||||
<p class="text-sm font-semibold text-gray-900 dark:text-white">{{ $this->existingSubmission?->getFirstMedia('submission')?->file_name ?? 'Berkas Tugas' }}</p>
|
||||
<p class="text-xs text-gray-500 dark:text-gray-400">Berkas Terkumpul (ZIP)</p>
|
||||
</div>
|
||||
</div>
|
||||
<x-filament::button type="button" wire:click="downloadSubmission" color="success" size="sm" icon="heroicon-o-arrow-down-tray" variant="outline">
|
||||
Unduh
|
||||
</x-filament::button>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
@endif
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user