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')
|
->color('info')
|
||||||
->icon('heroicon-o-clipboard-document-list')
|
->icon('heroicon-o-clipboard-document-list')
|
||||||
->link()
|
->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)
|
->modalSubmitAction(false)
|
||||||
->modalCancelActionLabel('Tutup')
|
->modalCancelActionLabel('Tutup')
|
||||||
->modalWidth(Width::Large)
|
->modalWidth(Width::Large)
|
||||||
->modalContent(fn (array $arguments) => view('filament.resources.learning.class-sessions.assignments-modal', [
|
->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')
|
->color('success')
|
||||||
->icon('heroicon-o-check-circle')
|
->icon('heroicon-o-check-circle')
|
||||||
->link()
|
->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)
|
->modalSubmitAction(false)
|
||||||
->modalCancelActionLabel('Tutup')
|
->modalCancelActionLabel('Tutup')
|
||||||
->modalWidth(Width::ExtraLarge)
|
->modalWidth(Width::ExtraLarge)
|
||||||
->modalContent(fn (array $arguments) => view('filament.resources.learning.class-sessions.attendance-modal', [
|
->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')
|
->color('warning')
|
||||||
->icon('heroicon-o-book-open')
|
->icon('heroicon-o-book-open')
|
||||||
->link()
|
->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)
|
->modalSubmitAction(false)
|
||||||
->modalCancelActionLabel('Tutup')
|
->modalCancelActionLabel('Tutup')
|
||||||
->modalWidth(Width::Large)
|
->modalWidth(Width::Large)
|
||||||
->modalContent(fn (array $arguments) => view('filament.resources.learning.class-sessions.materials-modal', [
|
->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\DeleteSessionAction;
|
||||||
use App\Filament\Resources\Learning\ClassSessions\Actions\EditSessionAction;
|
use App\Filament\Resources\Learning\ClassSessions\Actions\EditSessionAction;
|
||||||
use App\Filament\Resources\Learning\ClassSessions\Actions\GenerateSessionsAction;
|
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\ViewAssignmentsAction;
|
||||||
use App\Filament\Resources\Learning\ClassSessions\Actions\ViewAttendanceAction;
|
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\Actions\ViewMaterialsAction;
|
||||||
use App\Filament\Resources\Learning\ClassSessions\ClassSessionResource;
|
use App\Filament\Resources\Learning\ClassSessions\ClassSessionResource;
|
||||||
use App\Models\Course;
|
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
|
public function viewAttendanceAction(): Action
|
||||||
{
|
{
|
||||||
return ViewAttendanceAction::make();
|
return ViewAttendanceAction::make();
|
||||||
@ -175,4 +190,14 @@ public function deleteSessionAction(): Action
|
|||||||
{
|
{
|
||||||
return DeleteSessionAction::make();
|
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;
|
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\ViewAssignmentsAction;
|
||||||
use App\Filament\Resources\Learning\ClassSessions\Actions\ViewAttendanceAction;
|
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\Actions\ViewMaterialsAction;
|
||||||
use App\Filament\Resources\Learning\ClassSessions\ClassSessionResource;
|
use App\Filament\Resources\Learning\ClassSessions\ClassSessionResource;
|
||||||
use App\Models\ClassSession;
|
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
|
public function viewAttendanceAction(): Action
|
||||||
{
|
{
|
||||||
return ViewAttendanceAction::make();
|
return ViewAttendanceAction::make();
|
||||||
@ -148,4 +161,14 @@ public function viewAssignmentsAction(): Action
|
|||||||
{
|
{
|
||||||
return ViewAssignmentsAction::make();
|
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')
|
TextColumn::make('course.name')
|
||||||
->label('Mata Kuliah')
|
->label('Mata Kuliah')
|
||||||
->searchable()
|
->searchable()
|
||||||
->sortable(),
|
->sortable()
|
||||||
|
->description(fn (Material $record) => $record->classSession?->session_number ? "Sesi Ke-{$record->classSession->session_number}" : ''),
|
||||||
|
|
||||||
TextColumn::make('title')
|
TextColumn::make('title')
|
||||||
->label('Judul')
|
->label('Judul')
|
||||||
@ -145,13 +146,6 @@ public static function table(Table $table): Table
|
|||||||
->date('l, d F Y')
|
->date('l, d F Y')
|
||||||
->sortable(),
|
->sortable(),
|
||||||
|
|
||||||
TextColumn::make('classSession.session_number')
|
|
||||||
->label('Pertemuan')
|
|
||||||
->formatStateUsing(fn ($state) => $state ? "Sesi Ke-$state" : '-')
|
|
||||||
->sortable()
|
|
||||||
->badge()
|
|
||||||
->color('gray'),
|
|
||||||
|
|
||||||
...TimestampColumns::make(),
|
...TimestampColumns::make(),
|
||||||
])
|
])
|
||||||
->filters([
|
->filters([
|
||||||
|
|||||||
@ -7,19 +7,20 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="flex flex-col">
|
<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">
|
<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>
|
||||||
<span class="font-bold text-gray-900 dark:text-white leading-tight">{{ $assignment->title }}</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">
|
<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" />
|
<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">
|
<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>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex items-center gap-2">
|
<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"
|
class="p-1.5 rounded-full hover:bg-gray-200 dark:hover:bg-white/10 text-gray-500 transition-colors"
|
||||||
title="Lihat Detail">
|
title="Lihat Detail">
|
||||||
<x-heroicon-o-chevron-right class="w-5 h-5" />
|
<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">
|
<div class="flex flex-col">
|
||||||
<span class="font-bold text-gray-900 dark:text-white leading-tight">{{ $material->title }}</span>
|
<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">
|
<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>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex items-center gap-2">
|
<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"
|
class="p-1.5 rounded-full hover:bg-gray-200 dark:hover:bg-white/10 text-gray-500 transition-colors"
|
||||||
title="Lihat Detail">
|
title="Lihat Detail">
|
||||||
<x-heroicon-o-chevron-right class="w-5 h-5" />
|
<x-heroicon-o-chevron-right class="w-5 h-5" />
|
||||||
</a>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@empty
|
@empty
|
||||||
|
|||||||
@ -50,7 +50,7 @@ class="flex items-center gap-1.5 font-bold text-success-600 dark:text-success-40
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex items-center gap-1">
|
<div class="flex items-center gap-3">
|
||||||
{{ ($this->viewAttendanceAction)(['session' => $session->id]) }}
|
{{ ($this->viewAttendanceAction)(['session' => $session->id]) }}
|
||||||
{{ ($this->viewMaterialsAction)(['session' => $session->id]) }}
|
{{ ($this->viewMaterialsAction)(['session' => $session->id]) }}
|
||||||
{{ ($this->viewAssignmentsAction)(['session' => $session->id]) }}
|
{{ ($this->viewAssignmentsAction)(['session' => $session->id]) }}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user