feat: introduce detailed viewing actions for assignments and materials in class sessions, enhancing user interaction with modals for comprehensive content display
This commit is contained in:
parent
b7e8f64d8b
commit
63241349cd
@ -0,0 +1,53 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\Learning\ClassSessions\Actions;
|
||||
|
||||
use App\Models\Assignment;
|
||||
use Filament\Actions\Action;
|
||||
use Filament\Infolists\Components\TextEntry;
|
||||
use Filament\Support\Enums\Width;
|
||||
use Joaopaulolndev\FilamentPdfViewer\Infolists\Components\PdfViewerEntry;
|
||||
|
||||
class ViewAssignmentDetailAction extends Action
|
||||
{
|
||||
public static function getDefaultName(): ?string
|
||||
{
|
||||
return 'viewAssignmentDetail';
|
||||
}
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
$this->modalHeading(fn (array $arguments) => Assignment::find($arguments['record'], ['*'])?->title ?? 'Detail Tugas')
|
||||
->modalSubmitAction(false)
|
||||
->modalCancelActionLabel('Tutup')
|
||||
->modalWidth(Width::FourExtraLarge)
|
||||
->infolist(function (array $arguments) {
|
||||
$record = Assignment::find($arguments['record'], ['*']);
|
||||
if (! $record) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$entries = [
|
||||
TextEntry::make('description')
|
||||
->label('Deskripsi')
|
||||
->html()
|
||||
->columnSpanFull(),
|
||||
TextEntry::make('due_date')
|
||||
->label('Batas Waktu')
|
||||
->dateTime('l, d F Y, H:i')
|
||||
->columnSpanFull(),
|
||||
];
|
||||
|
||||
$mediaEntries = $record->getMedia('assignments')->map(function ($item, $index) {
|
||||
return PdfViewerEntry::make('pdf_'.$index)
|
||||
->label('Lampiran PDF')
|
||||
->fileUrl($item->getUrl())
|
||||
->columnSpanFull();
|
||||
})->toArray();
|
||||
|
||||
return array_merge($entries, $mediaEntries);
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -21,12 +21,20 @@ protected function setUp(): void
|
||||
->color('info')
|
||||
->icon('heroicon-o-clipboard-document-list')
|
||||
->link()
|
||||
->modalHeading(fn (array $arguments) => 'Tugas Kuliah - Sesi Ke-'.ClassSession::find($arguments['session'], ['*'])->session_number)
|
||||
->modalHeading(fn (array $arguments) => 'Tugas Kuliah - Sesi Ke-'.(ClassSession::find($arguments['session'] ?? null, ['*'])?->session_number ?? ''))
|
||||
->modalSubmitAction(false)
|
||||
->modalCancelActionLabel('Tutup')
|
||||
->modalWidth(Width::Large)
|
||||
->modalContent(fn (array $arguments) => view('filament.resources.learning.class-sessions.assignments-modal', [
|
||||
'assignments' => ClassSession::find($arguments['session'], ['*'])->assignments()->latest()->get(),
|
||||
'assignments' => ClassSession::find($arguments['session'] ?? null, ['*'])?->assignments()
|
||||
->latest()
|
||||
->get()
|
||||
->map(fn ($a) => (object) [
|
||||
'id' => $a->id,
|
||||
'title' => $a->title,
|
||||
'type_label' => $a->type?->getLabel() ?? 'Tugas',
|
||||
'due_date_formatted' => $a->due_date?->translatedFormat('d F Y, H:i') ?? '-',
|
||||
]) ?? collect(),
|
||||
]));
|
||||
}
|
||||
}
|
||||
|
||||
@ -21,12 +21,12 @@ protected function setUp(): void
|
||||
->color('success')
|
||||
->icon('heroicon-o-check-circle')
|
||||
->link()
|
||||
->modalHeading(fn (array $arguments) => 'Daftar Presensi - Sesi Ke-'.ClassSession::find($arguments['session'], ['*'])->session_number)
|
||||
->modalHeading(fn (array $arguments) => 'Daftar Presensi - Sesi Ke-'.ClassSession::find($arguments['session'] ?? null, ['*'])?->session_number)
|
||||
->modalSubmitAction(false)
|
||||
->modalCancelActionLabel('Tutup')
|
||||
->modalWidth(Width::ExtraLarge)
|
||||
->modalContent(fn (array $arguments) => view('filament.resources.learning.class-sessions.attendance-modal', [
|
||||
'attendances' => ClassSession::find($arguments['session'], ['*'])->attendances()->with('student')->latest('attended_at')->get(),
|
||||
'attendances' => ClassSession::find($arguments['session'] ?? null, ['*'])?->attendances()->with('student')->latest('attended_at')->get() ?? collect(),
|
||||
]));
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\Learning\ClassSessions\Actions;
|
||||
|
||||
use App\Models\Material;
|
||||
use Filament\Actions\Action;
|
||||
use Filament\Support\Enums\Width;
|
||||
|
||||
class ViewMaterialDetailAction extends Action
|
||||
{
|
||||
public static function getDefaultName(): ?string
|
||||
{
|
||||
return 'viewMaterialDetail';
|
||||
}
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
$this->record(fn (array $arguments) => Material::find($arguments['record'] ?? null, ['*']))
|
||||
->modalHeading(fn (?Material $record) => $record?->title ?? 'Detail Materi')
|
||||
->modalSubmitAction(false)
|
||||
->modalCancelActionLabel('Tutup')
|
||||
->modalWidth(Width::FourExtraLarge)
|
||||
->modalContent(fn (?Material $record) => $record ? view('filament.resources.learning.class-sessions.material-detail-modal', [
|
||||
'record' => $record,
|
||||
]) : null);
|
||||
}
|
||||
}
|
||||
@ -21,12 +21,19 @@ protected function setUp(): void
|
||||
->color('warning')
|
||||
->icon('heroicon-o-book-open')
|
||||
->link()
|
||||
->modalHeading(fn (array $arguments) => 'Materi Kuliah - Sesi Ke-'.ClassSession::find($arguments['session'], ['*'])->session_number)
|
||||
->modalHeading(fn (array $arguments) => 'Materi Kuliah - Sesi Ke-'.(ClassSession::find($arguments['session'] ?? null, ['*'])?->session_number ?? ''))
|
||||
->modalSubmitAction(false)
|
||||
->modalCancelActionLabel('Tutup')
|
||||
->modalWidth(Width::Large)
|
||||
->modalContent(fn (array $arguments) => view('filament.resources.learning.class-sessions.materials-modal', [
|
||||
'materials' => ClassSession::find($arguments['session'], ['*'])->materials()->latest()->get(),
|
||||
'materials' => ClassSession::find($arguments['session'] ?? null, ['*'])?->materials()
|
||||
->latest()
|
||||
->get()
|
||||
->map(fn ($m) => (object) [
|
||||
'id' => $m->id,
|
||||
'title' => $m->title,
|
||||
'created_at_formatted' => $m->created_at?->translatedFormat('d F Y') ?? '-',
|
||||
]) ?? collect(),
|
||||
]));
|
||||
}
|
||||
}
|
||||
|
||||
@ -7,8 +7,10 @@
|
||||
use App\Filament\Resources\Learning\ClassSessions\Actions\DeleteSessionAction;
|
||||
use App\Filament\Resources\Learning\ClassSessions\Actions\EditSessionAction;
|
||||
use App\Filament\Resources\Learning\ClassSessions\Actions\GenerateSessionsAction;
|
||||
use App\Filament\Resources\Learning\ClassSessions\Actions\ViewAssignmentDetailAction;
|
||||
use App\Filament\Resources\Learning\ClassSessions\Actions\ViewAssignmentsAction;
|
||||
use App\Filament\Resources\Learning\ClassSessions\Actions\ViewAttendanceAction;
|
||||
use App\Filament\Resources\Learning\ClassSessions\Actions\ViewMaterialDetailAction;
|
||||
use App\Filament\Resources\Learning\ClassSessions\Actions\ViewMaterialsAction;
|
||||
use App\Filament\Resources\Learning\ClassSessions\ClassSessionResource;
|
||||
use App\Models\Course;
|
||||
@ -151,6 +153,19 @@ protected function getHeaderActions(): array
|
||||
];
|
||||
}
|
||||
|
||||
protected function getActions(): array
|
||||
{
|
||||
return [
|
||||
$this->viewAttendanceAction(),
|
||||
$this->viewMaterialsAction(),
|
||||
$this->viewAssignmentsAction(),
|
||||
$this->editSessionAction(),
|
||||
$this->deleteSessionAction(),
|
||||
$this->viewMaterialDetailAction(),
|
||||
$this->viewAssignmentDetailAction(),
|
||||
];
|
||||
}
|
||||
|
||||
public function viewAttendanceAction(): Action
|
||||
{
|
||||
return ViewAttendanceAction::make();
|
||||
@ -175,4 +190,14 @@ public function deleteSessionAction(): Action
|
||||
{
|
||||
return DeleteSessionAction::make();
|
||||
}
|
||||
|
||||
public function viewMaterialDetailAction(): Action
|
||||
{
|
||||
return ViewMaterialDetailAction::make();
|
||||
}
|
||||
|
||||
public function viewAssignmentDetailAction(): Action
|
||||
{
|
||||
return ViewAssignmentDetailAction::make();
|
||||
}
|
||||
}
|
||||
|
||||
@ -2,8 +2,10 @@
|
||||
|
||||
namespace App\Filament\Resources\Learning\ClassSessions\Pages;
|
||||
|
||||
use App\Filament\Resources\Learning\ClassSessions\Actions\ViewAssignmentDetailAction;
|
||||
use App\Filament\Resources\Learning\ClassSessions\Actions\ViewAssignmentsAction;
|
||||
use App\Filament\Resources\Learning\ClassSessions\Actions\ViewAttendanceAction;
|
||||
use App\Filament\Resources\Learning\ClassSessions\Actions\ViewMaterialDetailAction;
|
||||
use App\Filament\Resources\Learning\ClassSessions\Actions\ViewMaterialsAction;
|
||||
use App\Filament\Resources\Learning\ClassSessions\ClassSessionResource;
|
||||
use App\Models\ClassSession;
|
||||
@ -134,6 +136,17 @@ public function courses(): Collection
|
||||
});
|
||||
}
|
||||
|
||||
protected function getActions(): array
|
||||
{
|
||||
return [
|
||||
$this->viewAttendanceAction(),
|
||||
$this->viewMaterialsAction(),
|
||||
$this->viewAssignmentsAction(),
|
||||
$this->viewMaterialDetailAction(),
|
||||
$this->viewAssignmentDetailAction(),
|
||||
];
|
||||
}
|
||||
|
||||
public function viewAttendanceAction(): Action
|
||||
{
|
||||
return ViewAttendanceAction::make();
|
||||
@ -148,4 +161,14 @@ public function viewAssignmentsAction(): Action
|
||||
{
|
||||
return ViewAssignmentsAction::make();
|
||||
}
|
||||
|
||||
public function viewMaterialDetailAction(): Action
|
||||
{
|
||||
return ViewMaterialDetailAction::make();
|
||||
}
|
||||
|
||||
public function viewAssignmentDetailAction(): Action
|
||||
{
|
||||
return ViewAssignmentDetailAction::make();
|
||||
}
|
||||
}
|
||||
|
||||
@ -133,7 +133,8 @@ public static function table(Table $table): Table
|
||||
TextColumn::make('course.name')
|
||||
->label('Mata Kuliah')
|
||||
->searchable()
|
||||
->sortable(),
|
||||
->sortable()
|
||||
->description(fn (Material $record) => $record->classSession?->session_number ? "Sesi Ke-{$record->classSession->session_number}" : ''),
|
||||
|
||||
TextColumn::make('title')
|
||||
->label('Judul')
|
||||
@ -145,13 +146,6 @@ public static function table(Table $table): Table
|
||||
->date('l, d F Y')
|
||||
->sortable(),
|
||||
|
||||
TextColumn::make('classSession.session_number')
|
||||
->label('Pertemuan')
|
||||
->formatStateUsing(fn ($state) => $state ? "Sesi Ke-$state" : '-')
|
||||
->sortable()
|
||||
->badge()
|
||||
->color('gray'),
|
||||
|
||||
...TimestampColumns::make(),
|
||||
])
|
||||
->filters([
|
||||
|
||||
@ -7,19 +7,20 @@
|
||||
</div>
|
||||
<div class="flex flex-col">
|
||||
<span class="font-bold text-gray-900 dark:text-white leading-tight uppercase font-mono text-[11px] mb-0.5 tracking-tight text-primary-600/60 dark:text-primary-400/50 block">
|
||||
{{ $assignment->type->label() ?? 'TUGAS' }}
|
||||
{{ $assignment->type_label }}
|
||||
</span>
|
||||
<span class="font-bold text-gray-900 dark:text-white leading-tight">{{ $assignment->title }}</span>
|
||||
<div class="flex items-center gap-1.5 mt-0.5">
|
||||
<x-heroicon-o-clock class="w-3.5 h-3.5 text-gray-400 dark:text-gray-500" />
|
||||
<span class="text-[10px] text-gray-500 dark:text-gray-400 font-medium uppercase tracking-tight">
|
||||
Deadline: {{ $assignment->due_date?->translatedFormat('d F Y, H:i') ?? '-' }}
|
||||
Deadline: {{ $assignment->due_date_formatted }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-center gap-2">
|
||||
<a href="{{ \App\Filament\Resources\Learning\Assignments\AssignmentResource::getUrl('index') . '?tableFilters[course_id][value]=' . $assignment->course_id . '&tableSearch=' . urlencode($assignment->title) }}"
|
||||
<a href="{{ \App\Filament\Resources\Learning\Assignments\AssignmentResource::getUrl('submit', ['record' => $assignment->id]) }}"
|
||||
wire:navigate
|
||||
class="p-1.5 rounded-full hover:bg-gray-200 dark:hover:bg-white/10 text-gray-500 transition-colors"
|
||||
title="Lihat Detail">
|
||||
<x-heroicon-o-chevron-right class="w-5 h-5" />
|
||||
|
||||
@ -0,0 +1,12 @@
|
||||
<div class="space-y-4 py-2">
|
||||
@foreach($record->getMedia('materials') as $item)
|
||||
<div class="rounded-xl border border-gray-100 dark:border-white/5 overflow-hidden shadow-sm">
|
||||
<div class="p-3 bg-gray-50/50 dark:bg-white/5 border-b border-gray-100 dark:border-white/5">
|
||||
<span class="text-xs font-bold text-gray-500 dark:text-gray-400 uppercase tracking-tight">Lampiran PDF</span>
|
||||
</div>
|
||||
<div class="h-[600px] w-full bg-white dark:bg-gray-900 overflow-hidden">
|
||||
<iframe src="{{ $item->getUrl() }}" class="w-full h-full border-0" frameborder="0"></iframe>
|
||||
</div>
|
||||
</div>
|
||||
@endforeach
|
||||
</div>
|
||||
@ -8,16 +8,17 @@
|
||||
<div class="flex flex-col">
|
||||
<span class="font-bold text-gray-900 dark:text-white leading-tight">{{ $material->title }}</span>
|
||||
<span class="text-[10px] text-gray-500 dark:text-gray-400 font-medium uppercase mt-0.5">
|
||||
Dibuat: {{ $material->created_at?->translatedFormat('d F Y') ?? '-' }}
|
||||
Dibuat: {{ $material->created_at_formatted }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-center gap-2">
|
||||
<a href="{{ \App\Filament\Resources\Learning\Materials\MaterialResource::getUrl('index') . '?tableFilters[course_id][value]=' . $material->course_id . '&tableSearch=' . urlencode($material->title) }}"
|
||||
<button type="button"
|
||||
wire:click="mountAction('viewMaterialDetail', { record: {{ $material->id }} })"
|
||||
class="p-1.5 rounded-full hover:bg-gray-200 dark:hover:bg-white/10 text-gray-500 transition-colors"
|
||||
title="Lihat Detail">
|
||||
<x-heroicon-o-chevron-right class="w-5 h-5" />
|
||||
</a>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
@empty
|
||||
|
||||
@ -50,7 +50,7 @@ class="flex items-center gap-1.5 font-bold text-success-600 dark:text-success-40
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex items-center gap-1">
|
||||
<div class="flex items-center gap-3">
|
||||
{{ ($this->viewAttendanceAction)(['session' => $session->id]) }}
|
||||
{{ ($this->viewMaterialsAction)(['session' => $session->id]) }}
|
||||
{{ ($this->viewAssignmentsAction)(['session' => $session->id]) }}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user