refactor: update class session management by introducing dedicated actions for viewing assignments, attendance, and materials, enhancing modularity and user interaction
This commit is contained in:
parent
66c07556b7
commit
b7e8f64d8b
@ -13,6 +13,7 @@ protected function setUp(): void
|
|||||||
|
|
||||||
$this->successNotification(
|
$this->successNotification(
|
||||||
SystemNotification::update()
|
SystemNotification::update()
|
||||||
);
|
)
|
||||||
|
->color('warning');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,35 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Filament\Actions;
|
|
||||||
|
|
||||||
use Filament\Actions\Action;
|
|
||||||
use Filament\Forms\Components\DatePicker;
|
|
||||||
use Filament\Support\Enums\Width;
|
|
||||||
|
|
||||||
class GoToDateAction extends Action
|
|
||||||
{
|
|
||||||
public static function getDefaultName(): ?string
|
|
||||||
{
|
|
||||||
return 'goToDate';
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function setUp(): void
|
|
||||||
{
|
|
||||||
parent::setUp();
|
|
||||||
|
|
||||||
$this->label('Lompat ke Tanggal')
|
|
||||||
->icon('heroicon-o-calendar-days')
|
|
||||||
->schema([
|
|
||||||
DatePicker::make('date')
|
|
||||||
->label('Pilih Tanggal')
|
|
||||||
->placeholder(fn () => now()->addMonth(10)->format('l, d F Y'))
|
|
||||||
->required()
|
|
||||||
->native(false)
|
|
||||||
->displayFormat('l, d F Y'),
|
|
||||||
])
|
|
||||||
->action(function (array $data, $livewire) {
|
|
||||||
$livewire->setOption('date', $data['date']);
|
|
||||||
})
|
|
||||||
->modalWidth(Width::Large);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -29,7 +29,7 @@ public function getHeading(): string|Htmlable
|
|||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
public function form(Schema $schema): Schema
|
public function schema(Schema $schema): Schema
|
||||||
{
|
{
|
||||||
return $schema
|
return $schema
|
||||||
->components([
|
->components([
|
||||||
|
|||||||
@ -4,7 +4,6 @@
|
|||||||
|
|
||||||
use App\Filament\Actions\Cheerful\DeleteAction;
|
use App\Filament\Actions\Cheerful\DeleteAction;
|
||||||
use App\Models\CourseSchedule;
|
use App\Models\CourseSchedule;
|
||||||
use Filament\Support\Icons\Heroicon;
|
|
||||||
|
|
||||||
class DeleteScheduleAction extends DeleteAction
|
class DeleteScheduleAction extends DeleteAction
|
||||||
{
|
{
|
||||||
@ -21,9 +20,9 @@ protected function setUp(): void
|
|||||||
return CourseSchedule::findOrFail($arguments['schedule']);
|
return CourseSchedule::findOrFail($arguments['schedule']);
|
||||||
})
|
})
|
||||||
->label('Hapus')
|
->label('Hapus')
|
||||||
->icon(Heroicon::OutlinedTrash)
|
->icon('heroicon-o-trash')
|
||||||
->color('danger')
|
->color('danger')
|
||||||
->iconButton()
|
->link()
|
||||||
->tooltip('Hapus')
|
->tooltip('Hapus')
|
||||||
->modalHeading('Hapus Jadwal Kuliah')
|
->modalHeading('Hapus Jadwal Kuliah')
|
||||||
->modalDescription('Apakah Anda yakin ingin menghapus jadwal ini? Tindakan ini tidak dapat dibatalkan.')
|
->modalDescription('Apakah Anda yakin ingin menghapus jadwal ini? Tindakan ini tidak dapat dibatalkan.')
|
||||||
|
|||||||
@ -5,7 +5,6 @@
|
|||||||
use App\Filament\Actions\Cheerful\EditAction;
|
use App\Filament\Actions\Cheerful\EditAction;
|
||||||
use App\Models\CourseSchedule;
|
use App\Models\CourseSchedule;
|
||||||
use Filament\Support\Enums\Width;
|
use Filament\Support\Enums\Width;
|
||||||
use Filament\Support\Icons\Heroicon;
|
|
||||||
|
|
||||||
class EditScheduleAction extends EditAction
|
class EditScheduleAction extends EditAction
|
||||||
{
|
{
|
||||||
@ -20,8 +19,9 @@ protected function setUp(): void
|
|||||||
|
|
||||||
$this
|
$this
|
||||||
->label('Ubah')
|
->label('Ubah')
|
||||||
->icon(Heroicon::OutlinedPencilSquare)
|
->color('warning')
|
||||||
->iconButton()
|
->icon('heroicon-o-pencil-square')
|
||||||
|
->link()
|
||||||
->tooltip('Ubah')
|
->tooltip('Ubah')
|
||||||
->record(function (array $arguments): CourseSchedule {
|
->record(function (array $arguments): CourseSchedule {
|
||||||
return CourseSchedule::findOrFail($arguments['schedule']);
|
return CourseSchedule::findOrFail($arguments['schedule']);
|
||||||
|
|||||||
@ -58,7 +58,7 @@ public function mount(): void
|
|||||||
$this->form->fill();
|
$this->form->fill();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function form(Schema $schema): Schema
|
public function schema(Schema $schema): Schema
|
||||||
{
|
{
|
||||||
return $schema
|
return $schema
|
||||||
->schema([
|
->schema([
|
||||||
|
|||||||
@ -4,7 +4,6 @@
|
|||||||
|
|
||||||
use App\Filament\Actions\Cheerful\DeleteAction;
|
use App\Filament\Actions\Cheerful\DeleteAction;
|
||||||
use App\Models\StudyGroup;
|
use App\Models\StudyGroup;
|
||||||
use Filament\Support\Icons\Heroicon;
|
|
||||||
|
|
||||||
class DeleteStudyGroupAction extends DeleteAction
|
class DeleteStudyGroupAction extends DeleteAction
|
||||||
{
|
{
|
||||||
@ -19,9 +18,9 @@ protected function setUp(): void
|
|||||||
|
|
||||||
$this->record(fn (array $arguments): StudyGroup => StudyGroup::findOrFail($arguments['studyGroup']))
|
$this->record(fn (array $arguments): StudyGroup => StudyGroup::findOrFail($arguments['studyGroup']))
|
||||||
->label('Hapus')
|
->label('Hapus')
|
||||||
->icon(Heroicon::OutlinedTrash)
|
->icon('heroicon-o-trash')
|
||||||
->color('danger')
|
->color('danger')
|
||||||
->iconButton()
|
->link()
|
||||||
->tooltip('Hapus')
|
->tooltip('Hapus')
|
||||||
->modalHeading(fn (StudyGroup $record) => "Hapus {$record->name}")
|
->modalHeading(fn (StudyGroup $record) => "Hapus {$record->name}")
|
||||||
->modalDescription('Apakah Anda yakin ingin menghapus kelompok ini? Tindakan ini tidak dapat dibatalkan.')
|
->modalDescription('Apakah Anda yakin ingin menghapus kelompok ini? Tindakan ini tidak dapat dibatalkan.')
|
||||||
|
|||||||
@ -5,7 +5,6 @@
|
|||||||
use App\Filament\Actions\Cheerful\EditAction;
|
use App\Filament\Actions\Cheerful\EditAction;
|
||||||
use App\Models\StudyGroup;
|
use App\Models\StudyGroup;
|
||||||
use Filament\Support\Enums\Width;
|
use Filament\Support\Enums\Width;
|
||||||
use Filament\Support\Icons\Heroicon;
|
|
||||||
|
|
||||||
class EditStudyGroupAction extends EditAction
|
class EditStudyGroupAction extends EditAction
|
||||||
{
|
{
|
||||||
@ -20,8 +19,9 @@ protected function setUp(): void
|
|||||||
|
|
||||||
$this
|
$this
|
||||||
->label('Ubah')
|
->label('Ubah')
|
||||||
->icon(Heroicon::OutlinedPencilSquare)
|
->color('warning')
|
||||||
->iconButton()
|
->icon('heroicon-o-pencil-square')
|
||||||
|
->link()
|
||||||
->tooltip('Ubah')
|
->tooltip('Ubah')
|
||||||
->record(fn (array $arguments): StudyGroup => StudyGroup::findOrFail($arguments['studyGroup']))
|
->record(fn (array $arguments): StudyGroup => StudyGroup::findOrFail($arguments['studyGroup']))
|
||||||
->modalHeading(fn (StudyGroup $record) => "Ubah {$record->name}")
|
->modalHeading(fn (StudyGroup $record) => "Ubah {$record->name}")
|
||||||
|
|||||||
@ -61,7 +61,7 @@ public function mount(): void
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function form(Schema $schema): Schema
|
public function schema(Schema $schema): Schema
|
||||||
{
|
{
|
||||||
return $schema
|
return $schema
|
||||||
->schema([
|
->schema([
|
||||||
|
|||||||
@ -15,7 +15,7 @@
|
|||||||
|
|
||||||
class Profile extends EditProfile
|
class Profile extends EditProfile
|
||||||
{
|
{
|
||||||
public function form(Schema $schema): Schema
|
public function schema(Schema $schema): Schema
|
||||||
{
|
{
|
||||||
return $schema
|
return $schema
|
||||||
->components([
|
->components([
|
||||||
|
|||||||
@ -40,7 +40,7 @@ public static function getPagePermission(): string
|
|||||||
|
|
||||||
protected static string $settings = GeneralSettings::class;
|
protected static string $settings = GeneralSettings::class;
|
||||||
|
|
||||||
public function form(Schema $schema): Schema
|
public function schema(Schema $schema): Schema
|
||||||
{
|
{
|
||||||
return $schema
|
return $schema
|
||||||
->components([
|
->components([
|
||||||
|
|||||||
@ -18,15 +18,14 @@ protected function setUp(): void
|
|||||||
|
|
||||||
$this
|
$this
|
||||||
->label('Hapus')
|
->label('Hapus')
|
||||||
|
->icon('heroicon-o-trash')
|
||||||
|
->link()
|
||||||
->modalHeading(fn (Assignment $record) => "Hapus {$record->title}")
|
->modalHeading(fn (Assignment $record) => "Hapus {$record->title}")
|
||||||
->record(fn (array $arguments) => Assignment::find($arguments['record']))
|
->record(fn (array $arguments) => Assignment::find($arguments['record']))
|
||||||
->after(function ($livewire) {
|
->after(function ($livewire) {
|
||||||
unset($livewire->assignments);
|
unset($livewire->assignments);
|
||||||
})
|
})
|
||||||
->icon('heroicon-m-trash')
|
|
||||||
->color('danger')
|
->color('danger')
|
||||||
->tooltip('Hapus')
|
->tooltip('Hapus');
|
||||||
->size('sm')
|
|
||||||
->iconButton();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -23,15 +23,15 @@ protected function setUp(): void
|
|||||||
{
|
{
|
||||||
parent::setUp();
|
parent::setUp();
|
||||||
|
|
||||||
$this->icon('heroicon-m-pencil-square')
|
$this->label('Ubah')
|
||||||
->color('warning')
|
->color('warning')
|
||||||
|
->icon('heroicon-o-pencil-square')
|
||||||
|
->link()
|
||||||
->tooltip('Ubah')
|
->tooltip('Ubah')
|
||||||
->size('sm')
|
|
||||||
->iconButton()
|
|
||||||
->record(fn (array $arguments) => Assignment::find($arguments['record']))
|
->record(fn (array $arguments) => Assignment::find($arguments['record']))
|
||||||
->modalHeading(fn (Assignment $record) => "Ubah {$record->title}")
|
->modalHeading(fn (Assignment $record) => "Ubah {$record->title}")
|
||||||
->modalWidth(Width::FourExtraLarge)
|
->modalWidth(Width::FourExtraLarge)
|
||||||
->schema(fn (Schema $schema) => AssignmentForm::configure($schema)->getComponents())
|
->form(AssignmentForm::configure(new Schema)->getComponents())
|
||||||
->fillForm(function (Assignment $record): array {
|
->fillForm(function (Assignment $record): array {
|
||||||
$data = $record->toArray();
|
$data = $record->toArray();
|
||||||
|
|
||||||
|
|||||||
@ -17,14 +17,18 @@ protected function setUp(): void
|
|||||||
{
|
{
|
||||||
parent::setUp();
|
parent::setUp();
|
||||||
|
|
||||||
$this->icon(fn (array $arguments, $livewire) => in_array($arguments['record'], $livewire->pinnedIds) ? 'heroicon-s-bookmark' : 'heroicon-o-bookmark')
|
$this->label(fn (array $arguments, $livewire) => in_array($arguments['record'], $livewire->pinnedIds) ? 'Lepas Pin' : 'Pin Tugas')
|
||||||
->color(fn (array $arguments, $livewire) => in_array($arguments['record'], $livewire->pinnedIds) ? 'primary' : 'gray')
|
->color(fn (array $arguments, $livewire) => in_array($arguments['record'], $livewire->pinnedIds) ? 'primary' : 'gray')
|
||||||
|
->icon(fn (array $arguments, $livewire) => in_array($arguments['record'], $livewire->pinnedIds) ? 'heroicon-s-bookmark' : 'heroicon-o-bookmark')
|
||||||
|
->link()
|
||||||
->tooltip(fn (array $arguments, $livewire) => in_array($arguments['record'], $livewire->pinnedIds) ? 'Lepas pin' : 'Pin tugas ini')
|
->tooltip(fn (array $arguments, $livewire) => in_array($arguments['record'], $livewire->pinnedIds) ? 'Lepas pin' : 'Pin tugas ini')
|
||||||
->size('sm')
|
|
||||||
->iconButton()
|
|
||||||
->action(function (array $arguments, $livewire) {
|
->action(function (array $arguments, $livewire) {
|
||||||
$assignmentId = $arguments['record'];
|
$assignmentId = $arguments['record'];
|
||||||
$studentProfile = auth()->user()->student;
|
$studentProfile = auth()->user()?->student;
|
||||||
|
|
||||||
|
if (! $studentProfile) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
$existing = AssignmentPin::where('student_id', $studentProfile->id)
|
$existing = AssignmentPin::where('student_id', $studentProfile->id)
|
||||||
->where('assignment_id', $assignmentId)
|
->where('assignment_id', $assignmentId)
|
||||||
|
|||||||
@ -19,8 +19,9 @@ protected function setUp(): void
|
|||||||
parent::setUp();
|
parent::setUp();
|
||||||
|
|
||||||
$this->label('Kumpulkan')
|
$this->label('Kumpulkan')
|
||||||
->icon('heroicon-o-arrow-up-tray')
|
->color('success')
|
||||||
->color('primary')
|
->icon('heroicon-o-paper-airplane')
|
||||||
|
->link()
|
||||||
->url(fn (Assignment $record) => AssignmentResource::getUrl('submit', ['record' => $record->id]))
|
->url(fn (Assignment $record) => AssignmentResource::getUrl('submit', ['record' => $record->id]))
|
||||||
->visible(function (Assignment $record) {
|
->visible(function (Assignment $record) {
|
||||||
if (now()->isAfter($record->due_date)) {
|
if (now()->isAfter($record->due_date)) {
|
||||||
|
|||||||
@ -19,11 +19,11 @@ class AttendanceResource extends Resource
|
|||||||
|
|
||||||
protected static ?string $navigationLabel = 'Presensi';
|
protected static ?string $navigationLabel = 'Presensi';
|
||||||
|
|
||||||
protected static ?int $navigationSort = 3;
|
protected static ?int $navigationSort = 20;
|
||||||
|
|
||||||
protected static ?string $modelLabel = 'Presensi';
|
protected static ?string $recordTitleAttribute = 'date';
|
||||||
|
|
||||||
protected static ?string $pluralModelLabel = 'Presensi';
|
protected static ?string $slug = 'learning/attendances';
|
||||||
|
|
||||||
public static function getPages(): array
|
public static function getPages(): array
|
||||||
{
|
{
|
||||||
|
|||||||
@ -0,0 +1,25 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Filament\Resources\Learning\ClassSessions\Actions;
|
||||||
|
|
||||||
|
use App\Filament\Actions\Cheerful\DeleteAction;
|
||||||
|
use App\Models\ClassSession;
|
||||||
|
|
||||||
|
class DeleteSessionAction extends DeleteAction
|
||||||
|
{
|
||||||
|
public static function getDefaultName(): ?string
|
||||||
|
{
|
||||||
|
return 'deleteSession';
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function setUp(): void
|
||||||
|
{
|
||||||
|
parent::setUp();
|
||||||
|
|
||||||
|
$this->label('Hapus')
|
||||||
|
->icon('heroicon-o-trash')
|
||||||
|
->link()
|
||||||
|
->record(fn (array $arguments) => ClassSession::find($arguments['session'], ['*']))
|
||||||
|
->color('danger');
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,28 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Filament\Resources\Learning\ClassSessions\Actions;
|
||||||
|
|
||||||
|
use App\Filament\Actions\Cheerful\EditAction;
|
||||||
|
use App\Models\ClassSession;
|
||||||
|
use Filament\Support\Enums\Width;
|
||||||
|
|
||||||
|
class EditSessionAction extends EditAction
|
||||||
|
{
|
||||||
|
public static function getDefaultName(): ?string
|
||||||
|
{
|
||||||
|
return 'editSession';
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function setUp(): void
|
||||||
|
{
|
||||||
|
parent::setUp();
|
||||||
|
|
||||||
|
$this->label('Ubah')
|
||||||
|
->color('warning')
|
||||||
|
->icon('heroicon-o-pencil')
|
||||||
|
->link()
|
||||||
|
->record(fn (array $arguments) => ClassSession::find($arguments['session'], ['*']))
|
||||||
|
->schema(fn ($livewire) => $livewire->schema())
|
||||||
|
->modalWidth(Width::TwoExtraLarge);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,64 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Filament\Resources\Learning\ClassSessions\Actions;
|
||||||
|
|
||||||
|
use App\Filament\Support\SystemNotification;
|
||||||
|
use App\Models\ClassSession;
|
||||||
|
use Carbon\Carbon;
|
||||||
|
use Filament\Actions\Action;
|
||||||
|
use Filament\Forms\Components\DatePicker;
|
||||||
|
|
||||||
|
class GenerateSessionsAction extends Action
|
||||||
|
{
|
||||||
|
public static function getDefaultName(): ?string
|
||||||
|
{
|
||||||
|
return 'generateSessions';
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function setUp(): void
|
||||||
|
{
|
||||||
|
parent::setUp();
|
||||||
|
|
||||||
|
$this->label('Generate Sesi')
|
||||||
|
->color('warning')
|
||||||
|
->requiresConfirmation()
|
||||||
|
->modalHeading('Generate Sesi Pembelajaran')
|
||||||
|
->modalDescription('Sistem akan men-generate atau memperbarui sesi 1 sampai 16 secara otomatis berdasarkan jadwal mata kuliah ini.')
|
||||||
|
->schema([
|
||||||
|
DatePicker::make('start_date')
|
||||||
|
->label('Tanggal Pertemuan Ke-1')
|
||||||
|
->default(now())
|
||||||
|
->required()
|
||||||
|
->native(false)
|
||||||
|
->displayFormat('l, d F Y'),
|
||||||
|
])
|
||||||
|
->action(function (array $data, $livewire) {
|
||||||
|
$course = $livewire->course;
|
||||||
|
$schedule = $course->courseSchedules()->first();
|
||||||
|
|
||||||
|
if (! $schedule) {
|
||||||
|
SystemNotification::danger('Batal!', 'Jadwal belum ditentukan untuk mata kuliah ini.')->send();
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$startDate = Carbon::parse($data['start_date']);
|
||||||
|
|
||||||
|
for ($i = 1; $i <= 16; $i++) {
|
||||||
|
ClassSession::updateOrCreate(
|
||||||
|
[
|
||||||
|
'course_id' => $course->id,
|
||||||
|
'session_number' => $i,
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'date' => $startDate->copy()->addWeeks($i - 1)->toDateString(),
|
||||||
|
'start_time' => $schedule->start_time,
|
||||||
|
'end_time' => $schedule->end_time,
|
||||||
|
]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
SystemNotification::success('Selesai!', '16 Sesi berhasil digenerate/diperbarui.')->send();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,32 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Filament\Resources\Learning\ClassSessions\Actions;
|
||||||
|
|
||||||
|
use App\Models\ClassSession;
|
||||||
|
use Filament\Actions\Action;
|
||||||
|
use Filament\Support\Enums\Width;
|
||||||
|
|
||||||
|
class ViewAssignmentsAction extends Action
|
||||||
|
{
|
||||||
|
public static function getDefaultName(): ?string
|
||||||
|
{
|
||||||
|
return 'viewAssignments';
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function setUp(): void
|
||||||
|
{
|
||||||
|
parent::setUp();
|
||||||
|
|
||||||
|
$this->label('Tugas')
|
||||||
|
->color('info')
|
||||||
|
->icon('heroicon-o-clipboard-document-list')
|
||||||
|
->link()
|
||||||
|
->modalHeading(fn (array $arguments) => 'Tugas Kuliah - Sesi Ke-'.ClassSession::find($arguments['session'], ['*'])->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(),
|
||||||
|
]));
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,32 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Filament\Resources\Learning\ClassSessions\Actions;
|
||||||
|
|
||||||
|
use App\Models\ClassSession;
|
||||||
|
use Filament\Actions\Action;
|
||||||
|
use Filament\Support\Enums\Width;
|
||||||
|
|
||||||
|
class ViewAttendanceAction extends Action
|
||||||
|
{
|
||||||
|
public static function getDefaultName(): ?string
|
||||||
|
{
|
||||||
|
return 'viewAttendance';
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function setUp(): void
|
||||||
|
{
|
||||||
|
parent::setUp();
|
||||||
|
|
||||||
|
$this->label('Presensi')
|
||||||
|
->color('success')
|
||||||
|
->icon('heroicon-o-check-circle')
|
||||||
|
->link()
|
||||||
|
->modalHeading(fn (array $arguments) => 'Daftar Presensi - Sesi Ke-'.ClassSession::find($arguments['session'], ['*'])->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(),
|
||||||
|
]));
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,32 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Filament\Resources\Learning\ClassSessions\Actions;
|
||||||
|
|
||||||
|
use App\Models\ClassSession;
|
||||||
|
use Filament\Actions\Action;
|
||||||
|
use Filament\Support\Enums\Width;
|
||||||
|
|
||||||
|
class ViewMaterialsAction extends Action
|
||||||
|
{
|
||||||
|
public static function getDefaultName(): ?string
|
||||||
|
{
|
||||||
|
return 'viewMaterials';
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function setUp(): void
|
||||||
|
{
|
||||||
|
parent::setUp();
|
||||||
|
|
||||||
|
$this->label('Materi')
|
||||||
|
->color('warning')
|
||||||
|
->icon('heroicon-o-book-open')
|
||||||
|
->link()
|
||||||
|
->modalHeading(fn (array $arguments) => 'Materi Kuliah - Sesi Ke-'.ClassSession::find($arguments['session'], ['*'])->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(),
|
||||||
|
]));
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -2,33 +2,14 @@
|
|||||||
|
|
||||||
namespace App\Filament\Resources\Learning\ClassSessions;
|
namespace App\Filament\Resources\Learning\ClassSessions;
|
||||||
|
|
||||||
use App\Enums\RoleEnum;
|
|
||||||
use App\Filament\Actions\Cheerful\DeleteAction;
|
|
||||||
use App\Filament\Actions\Cheerful\EditAction;
|
|
||||||
use App\Filament\Actions\Cheerful\ForceDeleteAction;
|
|
||||||
use App\Filament\Actions\Cheerful\RestoreAction;
|
|
||||||
use App\Filament\Actions\DefaultBulkActions;
|
|
||||||
use App\Filament\Columns\TimestampColumns;
|
|
||||||
use App\Filament\Resources\Learning\ClassSessions\Pages\ListCourseSessions;
|
use App\Filament\Resources\Learning\ClassSessions\Pages\ListCourseSessions;
|
||||||
use App\Filament\Resources\Learning\ClassSessions\Pages\ManageClassSessions;
|
use App\Filament\Resources\Learning\ClassSessions\Pages\ManageClassSessions;
|
||||||
use App\Filament\Resources\Learning\ClassSessions\RelationManagers\AttendanceRelationManager;
|
use App\Filament\Resources\Learning\ClassSessions\RelationManagers\AttendanceRelationManager;
|
||||||
use App\Models\ClassSession;
|
use App\Models\ClassSession;
|
||||||
use App\Models\Course;
|
|
||||||
use App\Settings\GeneralSettings;
|
use App\Settings\GeneralSettings;
|
||||||
use BackedEnum;
|
use BackedEnum;
|
||||||
use Filament\Actions\BulkActionGroup;
|
|
||||||
use Filament\Forms\Components\DatePicker;
|
|
||||||
use Filament\Forms\Components\Select;
|
|
||||||
use Filament\Forms\Components\TextInput;
|
|
||||||
use Filament\Forms\Components\TimePicker;
|
|
||||||
use Filament\Resources\Resource;
|
use Filament\Resources\Resource;
|
||||||
use Filament\Schemas\Components\Grid;
|
|
||||||
use Filament\Schemas\Schema;
|
|
||||||
use Filament\Support\Enums\Width;
|
|
||||||
use Filament\Support\Icons\Heroicon;
|
use Filament\Support\Icons\Heroicon;
|
||||||
use Filament\Tables\Columns\TextColumn;
|
|
||||||
use Filament\Tables\Filters\TrashedFilter;
|
|
||||||
use Filament\Tables\Table;
|
|
||||||
use Illuminate\Database\Eloquent\Builder;
|
use Illuminate\Database\Eloquent\Builder;
|
||||||
use Illuminate\Database\Eloquent\SoftDeletingScope;
|
use Illuminate\Database\Eloquent\SoftDeletingScope;
|
||||||
use UnitEnum;
|
use UnitEnum;
|
||||||
@ -43,155 +24,11 @@ class ClassSessionResource extends Resource
|
|||||||
|
|
||||||
protected static ?string $navigationLabel = 'Sesi Kelas';
|
protected static ?string $navigationLabel = 'Sesi Kelas';
|
||||||
|
|
||||||
protected static ?int $navigationSort = 1;
|
protected static ?int $navigationSort = 5;
|
||||||
|
|
||||||
protected static ?string $modelLabel = 'Sesi Kelas';
|
protected static ?string $recordTitleAttribute = 'session_number';
|
||||||
|
|
||||||
protected static ?string $pluralModelLabel = 'Sesi Kelas';
|
protected static ?string $slug = 'learning/class-sessions';
|
||||||
|
|
||||||
public static function form(Schema $schema): Schema
|
|
||||||
{
|
|
||||||
return $schema
|
|
||||||
->components([
|
|
||||||
Grid::make(2)
|
|
||||||
->schema([
|
|
||||||
Select::make('course_id')
|
|
||||||
->label('Mata Kuliah')
|
|
||||||
->placeholder('Pilih Mata Kuliah')
|
|
||||||
->options(function () {
|
|
||||||
return Course::query()
|
|
||||||
->where('semester', app(GeneralSettings::class)->current_semester)
|
|
||||||
->pluck('name', 'id')
|
|
||||||
->toArray();
|
|
||||||
})
|
|
||||||
->searchable()
|
|
||||||
->required()
|
|
||||||
->preload()
|
|
||||||
->live()
|
|
||||||
->afterStateUpdated(function ($state, $set) {
|
|
||||||
if (! $state) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$schedule = \App\Models\CourseSchedule::where('course_id', $state)->first();
|
|
||||||
|
|
||||||
if ($schedule) {
|
|
||||||
$set('start_time', $schedule->start_time?->format('H:i'));
|
|
||||||
$set('end_time', $schedule->end_time?->format('H:i'));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ambil pertemuan terakhir + 1
|
|
||||||
$lastSession = \App\Models\ClassSession::where('course_id', $state)->max('session_number');
|
|
||||||
$set('session_number', ($lastSession ?? 0) + 1);
|
|
||||||
})
|
|
||||||
->columnSpanFull(),
|
|
||||||
|
|
||||||
TextInput::make('session_number')
|
|
||||||
->label('Pertemuan Ke-')
|
|
||||||
->placeholder('1')
|
|
||||||
->numeric()
|
|
||||||
->required()
|
|
||||||
->minValue(1)
|
|
||||||
->maxValue(16)
|
|
||||||
->autocomplete(false),
|
|
||||||
|
|
||||||
DatePicker::make('date')
|
|
||||||
->label('Tanggal')
|
|
||||||
->placeholder('Pilih Tanggal')
|
|
||||||
->required()
|
|
||||||
->native(false)
|
|
||||||
->displayFormat('l, d F Y')
|
|
||||||
->default(now()->toDateString()),
|
|
||||||
|
|
||||||
TimePicker::make('start_time')
|
|
||||||
->label('Waktu Mulai')
|
|
||||||
->placeholder('08:00')
|
|
||||||
->native(false)
|
|
||||||
->displayFormat('H:i')
|
|
||||||
->seconds(false)
|
|
||||||
->required(),
|
|
||||||
|
|
||||||
TimePicker::make('end_time')
|
|
||||||
->label('Waktu Selesai')
|
|
||||||
->placeholder('10:00')
|
|
||||||
->native(false)
|
|
||||||
->displayFormat('H:i')
|
|
||||||
->seconds(false)
|
|
||||||
->required(),
|
|
||||||
])
|
|
||||||
->columnSpanFull(),
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function table(Table $table): Table
|
|
||||||
{
|
|
||||||
return $table
|
|
||||||
->columns([
|
|
||||||
TextColumn::make('session_number')
|
|
||||||
->label('Pertemuan Ke-')
|
|
||||||
->sortable()
|
|
||||||
->badge(),
|
|
||||||
|
|
||||||
TextColumn::make('course.name')
|
|
||||||
->label('Mata Kuliah')
|
|
||||||
->searchable()
|
|
||||||
->sortable()
|
|
||||||
->wrap()
|
|
||||||
->description(fn (ClassSession $record) => $record->course->code),
|
|
||||||
|
|
||||||
TextColumn::make('date')
|
|
||||||
->label('Tanggal')
|
|
||||||
->date('l, d F Y')
|
|
||||||
->sortable()
|
|
||||||
->description(fn (ClassSession $record) => $record->start_time->format('H:i').' - '.$record->end_time->format('H:i').' WIB'),
|
|
||||||
|
|
||||||
TextColumn::make('attendances_count')
|
|
||||||
->counts('attendances')
|
|
||||||
->label('Presensi')
|
|
||||||
->badge()
|
|
||||||
->color('success'),
|
|
||||||
|
|
||||||
TextColumn::make('materials_count')
|
|
||||||
->counts('materials')
|
|
||||||
->label('Materi')
|
|
||||||
->badge()
|
|
||||||
->color('warning'),
|
|
||||||
|
|
||||||
TextColumn::make('assignments_count')
|
|
||||||
->counts('assignments')
|
|
||||||
->label('Tugas')
|
|
||||||
->badge()
|
|
||||||
->color('info'),
|
|
||||||
|
|
||||||
...TimestampColumns::make(),
|
|
||||||
])
|
|
||||||
->filters([
|
|
||||||
TrashedFilter::make()
|
|
||||||
->native(false)
|
|
||||||
->visible(fn () => auth()->user()->hasRole(RoleEnum::Developer)),
|
|
||||||
])
|
|
||||||
->recordActions([
|
|
||||||
EditAction::make()
|
|
||||||
->modalWidth(Width::TwoExtraLarge),
|
|
||||||
|
|
||||||
DeleteAction::make(),
|
|
||||||
|
|
||||||
ForceDeleteAction::make(),
|
|
||||||
|
|
||||||
RestoreAction::make(),
|
|
||||||
])
|
|
||||||
->toolbarActions([
|
|
||||||
BulkActionGroup::make([
|
|
||||||
...DefaultBulkActions::make('Sesi Kelas'),
|
|
||||||
]),
|
|
||||||
])
|
|
||||||
->emptyStateIcon(Heroicon::OutlinedPresentationChartBar)
|
|
||||||
->emptyStateDescription('Setelah Anda membuat data pertama, maka akan muncul disini.')
|
|
||||||
->defaultSort('created_at', 'desc')
|
|
||||||
->deferFilters(false)
|
|
||||||
->paginated([25, 50, 100, 'all'])
|
|
||||||
->defaultPaginationPageOption(25);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function getRelations(): array
|
public static function getRelations(): array
|
||||||
{
|
{
|
||||||
|
|||||||
@ -4,11 +4,13 @@
|
|||||||
|
|
||||||
use App\Filament\Actions\BackAction;
|
use App\Filament\Actions\BackAction;
|
||||||
use App\Filament\Actions\Cheerful\CreateAction;
|
use App\Filament\Actions\Cheerful\CreateAction;
|
||||||
use App\Filament\Actions\Cheerful\DeleteAction;
|
use App\Filament\Resources\Learning\ClassSessions\Actions\DeleteSessionAction;
|
||||||
use App\Filament\Actions\Cheerful\EditAction;
|
use App\Filament\Resources\Learning\ClassSessions\Actions\EditSessionAction;
|
||||||
|
use App\Filament\Resources\Learning\ClassSessions\Actions\GenerateSessionsAction;
|
||||||
|
use App\Filament\Resources\Learning\ClassSessions\Actions\ViewAssignmentsAction;
|
||||||
|
use App\Filament\Resources\Learning\ClassSessions\Actions\ViewAttendanceAction;
|
||||||
|
use App\Filament\Resources\Learning\ClassSessions\Actions\ViewMaterialsAction;
|
||||||
use App\Filament\Resources\Learning\ClassSessions\ClassSessionResource;
|
use App\Filament\Resources\Learning\ClassSessions\ClassSessionResource;
|
||||||
use App\Filament\Support\SystemNotification;
|
|
||||||
use App\Models\ClassSession;
|
|
||||||
use App\Models\Course;
|
use App\Models\Course;
|
||||||
use App\Models\Student;
|
use App\Models\Student;
|
||||||
use Filament\Actions\Action;
|
use Filament\Actions\Action;
|
||||||
@ -70,34 +72,43 @@ public function sessions(): Collection
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function formSchema(): array
|
public function schema(): array
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
Grid::make(['default' => 3])
|
Grid::make(['default' => 2])
|
||||||
->schema([
|
->schema([
|
||||||
TextInput::make('session_number')
|
TextInput::make('session_number')
|
||||||
->label('Pertemuan Ke-')
|
->label('Pertemuan Ke-')
|
||||||
|
->placeholder('1')
|
||||||
->numeric()
|
->numeric()
|
||||||
->default(fn () => ($this->course->classSessions()->max('session_number') ?? 0) + 1)
|
->required()
|
||||||
->required(),
|
->minValue(1)
|
||||||
|
->maxValue(16)
|
||||||
|
->autocomplete(false),
|
||||||
|
|
||||||
DatePicker::make('date')
|
DatePicker::make('date')
|
||||||
->label('Tanggal')
|
->label('Tanggal')
|
||||||
->default(now())
|
->placeholder('Pilih Tanggal')
|
||||||
|
->required()
|
||||||
->native(false)
|
->native(false)
|
||||||
|
->displayFormat('l, d F Y')
|
||||||
|
->default(now()->toDateString()),
|
||||||
|
|
||||||
|
TimePicker::make('start_time')
|
||||||
|
->label('Waktu Mulai')
|
||||||
|
->placeholder('08:00')
|
||||||
|
->native(false)
|
||||||
|
->displayFormat('H:i')
|
||||||
|
->seconds(false)
|
||||||
|
->required(),
|
||||||
|
|
||||||
|
TimePicker::make('end_time')
|
||||||
|
->label('Waktu Selesai')
|
||||||
|
->placeholder('10:00')
|
||||||
|
->native(false)
|
||||||
|
->displayFormat('H:i')
|
||||||
|
->seconds(false)
|
||||||
->required(),
|
->required(),
|
||||||
Grid::make(['default' => 2])
|
|
||||||
->schema([
|
|
||||||
TimePicker::make('start_time')
|
|
||||||
->label('Mulai')
|
|
||||||
->native(false)
|
|
||||||
->seconds(false)
|
|
||||||
->required(),
|
|
||||||
TimePicker::make('end_time')
|
|
||||||
->label('Selesai')
|
|
||||||
->native(false)
|
|
||||||
->seconds(false)
|
|
||||||
->required(),
|
|
||||||
])->columnSpan(1),
|
|
||||||
]),
|
]),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
@ -119,14 +130,15 @@ protected function getHeaderActions(): array
|
|||||||
BackAction::make()
|
BackAction::make()
|
||||||
->url(ManageClassSessions::getUrl()),
|
->url(ManageClassSessions::getUrl()),
|
||||||
|
|
||||||
$this->generateSessionsAction(),
|
GenerateSessionsAction::make(),
|
||||||
|
|
||||||
CreateAction::make()
|
CreateAction::make()
|
||||||
->label('Tambah Sesi')
|
->label('Tambah')
|
||||||
->modalHeading('Tambah Sesi')
|
->modalHeading('Tambah Sesi')
|
||||||
->modalSubmitActionLabel('Simpan')
|
->modalSubmitActionLabel('Simpan')
|
||||||
->modalCancelActionLabel('Batal')
|
->modalCancelActionLabel('Batal')
|
||||||
->form($this->formSchema())
|
->schema($this->schema())
|
||||||
->mutateFormDataUsing(function (array $data): array {
|
->mutateDataUsing(function (array $data): array {
|
||||||
$data['course_id'] = $this->courseId;
|
$data['course_id'] = $this->courseId;
|
||||||
|
|
||||||
return $data;
|
return $data;
|
||||||
@ -139,102 +151,28 @@ protected function getHeaderActions(): array
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function generateSessionsAction(): Action
|
public function viewAttendanceAction(): Action
|
||||||
{
|
{
|
||||||
return Action::make('generateSessions')
|
return ViewAttendanceAction::make();
|
||||||
->label('Generate Sesi')
|
|
||||||
->icon('heroicon-o-sparkles')
|
|
||||||
->color('warning')
|
|
||||||
->requiresConfirmation()
|
|
||||||
->modalHeading('Generate Sesi Pembelajaran')
|
|
||||||
->modalDescription('Sistem akan men-generate atau memperbarui sesi 1 sampai 16 secara otomatis berdasarkan jadwal mata kuliah ini.')
|
|
||||||
->form([
|
|
||||||
DatePicker::make('start_date')
|
|
||||||
->label('Tanggal Pertemuan Ke-1')
|
|
||||||
->default(now())
|
|
||||||
->required()
|
|
||||||
->native(false),
|
|
||||||
])
|
|
||||||
->action(function (array $data) {
|
|
||||||
$course = $this->course;
|
|
||||||
$schedule = $course->courseSchedules()->first();
|
|
||||||
|
|
||||||
if (! $schedule) {
|
|
||||||
SystemNotification::danger('Batal!', 'Jadwal belum ditentukan untuk mata kuliah ini.')->send();
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$startDate = \Carbon\Carbon::parse($data['start_date']);
|
|
||||||
|
|
||||||
for ($i = 1; $i <= 16; $i++) {
|
|
||||||
ClassSession::updateOrCreate(
|
|
||||||
[
|
|
||||||
'course_id' => $course->id,
|
|
||||||
'session_number' => $i,
|
|
||||||
],
|
|
||||||
[
|
|
||||||
'date' => $startDate->copy()->addWeeks($i - 1)->toDateString(),
|
|
||||||
'start_time' => $schedule->start_time,
|
|
||||||
'end_time' => $schedule->end_time,
|
|
||||||
]
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
SystemNotification::success('Selesai!', '16 Sesi berhasil digenerate/diperbarui.')->send();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function viewAttendanceAction(): Action
|
public function viewMaterialsAction(): Action
|
||||||
{
|
{
|
||||||
return Action::make('viewAttendance')
|
return ViewMaterialsAction::make();
|
||||||
->label('Lihat Presensi')
|
|
||||||
->modalHeading(fn (array $arguments) => 'Daftar Presensi - Sesi Ke-'.ClassSession::find($arguments['session'])->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(),
|
|
||||||
]));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function viewMaterialsAction(): Action
|
public function viewAssignmentsAction(): Action
|
||||||
{
|
{
|
||||||
return Action::make('viewMaterials')
|
return ViewAssignmentsAction::make();
|
||||||
->label('Daftar Materi')
|
|
||||||
->modalHeading(fn (array $arguments) => 'Materi Kuliah - Sesi Ke-'.ClassSession::find($arguments['session'])->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(),
|
|
||||||
]));
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function viewAssignmentsAction(): Action
|
|
||||||
{
|
|
||||||
return Action::make('viewAssignments')
|
|
||||||
->label('Daftar Tugas')
|
|
||||||
->modalHeading(fn (array $arguments) => 'Tugas Kuliah - Sesi Ke-'.ClassSession::find($arguments['session'])->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(),
|
|
||||||
]));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function editSessionAction(): Action
|
public function editSessionAction(): Action
|
||||||
{
|
{
|
||||||
return EditAction::make('editSession')
|
return EditSessionAction::make();
|
||||||
->record(fn (array $arguments) => ClassSession::find($arguments['session']))
|
|
||||||
->form($this->formSchema())
|
|
||||||
->modalWidth(Width::TwoExtraLarge);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function deleteSessionAction(): Action
|
public function deleteSessionAction(): Action
|
||||||
{
|
{
|
||||||
return DeleteAction::make('deleteSession')
|
return DeleteSessionAction::make();
|
||||||
->record(fn (array $arguments) => ClassSession::find($arguments['session']));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,6 +2,9 @@
|
|||||||
|
|
||||||
namespace App\Filament\Resources\Learning\ClassSessions\Pages;
|
namespace App\Filament\Resources\Learning\ClassSessions\Pages;
|
||||||
|
|
||||||
|
use App\Filament\Resources\Learning\ClassSessions\Actions\ViewAssignmentsAction;
|
||||||
|
use App\Filament\Resources\Learning\ClassSessions\Actions\ViewAttendanceAction;
|
||||||
|
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;
|
||||||
use App\Models\Course;
|
use App\Models\Course;
|
||||||
@ -15,7 +18,6 @@
|
|||||||
use Filament\Forms\Contracts\HasForms;
|
use Filament\Forms\Contracts\HasForms;
|
||||||
use Filament\Resources\Pages\Page;
|
use Filament\Resources\Pages\Page;
|
||||||
use Filament\Schemas\Schema;
|
use Filament\Schemas\Schema;
|
||||||
use Filament\Support\Enums\Width;
|
|
||||||
use Illuminate\Support\Collection;
|
use Illuminate\Support\Collection;
|
||||||
use Livewire\Attributes\Computed;
|
use Livewire\Attributes\Computed;
|
||||||
|
|
||||||
@ -132,42 +134,18 @@ public function courses(): Collection
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function viewAttendanceAction(): Action
|
public function viewAttendanceAction(): Action
|
||||||
{
|
{
|
||||||
return Action::make('viewAttendance')
|
return ViewAttendanceAction::make();
|
||||||
->label('Lihat Presensi')
|
|
||||||
->modalHeading(fn (array $arguments) => 'Daftar Presensi - Sesi Ke-'.ClassSession::find($arguments['session'])->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(),
|
|
||||||
]));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function viewMaterialsAction(): Action
|
public function viewMaterialsAction(): Action
|
||||||
{
|
{
|
||||||
return Action::make('viewMaterials')
|
return ViewMaterialsAction::make();
|
||||||
->label('Daftar Materi')
|
|
||||||
->modalHeading(fn (array $arguments) => 'Materi Kuliah - Sesi Ke-'.ClassSession::find($arguments['session'])->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(),
|
|
||||||
]));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function viewAssignmentsAction(): Action
|
public function viewAssignmentsAction(): Action
|
||||||
{
|
{
|
||||||
return Action::make('viewAssignments')
|
return ViewAssignmentsAction::make();
|
||||||
->label('Daftar Tugas')
|
|
||||||
->modalHeading(fn (array $arguments) => 'Tugas Kuliah - Sesi Ke-'.ClassSession::find($arguments['session'])->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(),
|
|
||||||
]));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -21,7 +21,7 @@ class AttendanceRelationManager extends RelationManager
|
|||||||
|
|
||||||
protected static ?string $title = 'Presensi Mahasiswa';
|
protected static ?string $title = 'Presensi Mahasiswa';
|
||||||
|
|
||||||
public function form(Schema $schema): Schema
|
public function schema(Schema $schema): Schema
|
||||||
{
|
{
|
||||||
return $schema
|
return $schema
|
||||||
->components([
|
->components([
|
||||||
|
|||||||
@ -34,11 +34,9 @@ class CourseResource extends Resource
|
|||||||
|
|
||||||
protected static string|BackedEnum|null $navigationIcon = Heroicon::OutlinedRectangleStack;
|
protected static string|BackedEnum|null $navigationIcon = Heroicon::OutlinedRectangleStack;
|
||||||
|
|
||||||
protected static ?string $title = 'Mata Kuliah';
|
|
||||||
|
|
||||||
protected static ?string $navigationLabel = 'Mata Kuliah';
|
protected static ?string $navigationLabel = 'Mata Kuliah';
|
||||||
|
|
||||||
protected static ?int $navigationSort = 15;
|
protected static ?int $navigationSort = 10;
|
||||||
|
|
||||||
protected static ?string $recordTitleAttribute = 'name';
|
protected static ?string $recordTitleAttribute = 'name';
|
||||||
|
|
||||||
|
|||||||
@ -7,7 +7,6 @@
|
|||||||
use Filament\Actions\Action;
|
use Filament\Actions\Action;
|
||||||
use Filament\Forms\Components\TextInput;
|
use Filament\Forms\Components\TextInput;
|
||||||
use Filament\Support\Enums\Width;
|
use Filament\Support\Enums\Width;
|
||||||
use Filament\Support\Icons\Heroicon;
|
|
||||||
use Illuminate\Support\Facades\Hash;
|
use Illuminate\Support\Facades\Hash;
|
||||||
|
|
||||||
class ChangePasswordAction extends Action
|
class ChangePasswordAction extends Action
|
||||||
@ -17,7 +16,6 @@ protected function setUp(): void
|
|||||||
parent::setUp();
|
parent::setUp();
|
||||||
|
|
||||||
$this->label('Ganti Kata Sandi')
|
$this->label('Ganti Kata Sandi')
|
||||||
->icon(Heroicon::OutlinedKey)
|
|
||||||
->color('warning')
|
->color('warning')
|
||||||
->modalWidth(Width::Medium)
|
->modalWidth(Width::Medium)
|
||||||
->schema([
|
->schema([
|
||||||
|
|||||||
@ -1,8 +1,10 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
use App\Models\Course;
|
||||||
use Illuminate\Database\Migrations\Migration;
|
use Illuminate\Database\Migrations\Migration;
|
||||||
use Illuminate\Database\Schema\Blueprint;
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
use Illuminate\Support\Facades\Schema;
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
use Illuminate\Support\Str;
|
||||||
|
|
||||||
return new class extends Migration
|
return new class extends Migration
|
||||||
{
|
{
|
||||||
@ -16,8 +18,8 @@ public function up(): void
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Populate existing courses with a random token
|
// Populate existing courses with a random token
|
||||||
\App\Models\Course::all()->each(function ($course) {
|
Course::all()->each(function ($course) {
|
||||||
$course->update(['sharing_token' => \Illuminate\Support\Str::random(32)]);
|
$course->update(['sharing_token' => Str::random(32)]);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -91,7 +91,7 @@ class="h-4 w-4 text-gray-400 group-hover:text-primary-500 mt-1 transition-colors
|
|||||||
</a>
|
</a>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
class="flex flex-col items-center justify-center border-l border-gray-100 dark:border-gray-700 p-1 gap-3 p-3">
|
class="flex flex-col items-start justify-center border-l border-gray-100 dark:border-gray-700 p-1 gap-3 p-3">
|
||||||
{{ ($this->pinAction)(['record' => $card->id]) }}
|
{{ ($this->pinAction)(['record' => $card->id]) }}
|
||||||
|
|
||||||
@canAny(['Update:Assignment', 'Delete:Assignment'])
|
@canAny(['Update:Assignment', 'Delete:Assignment'])
|
||||||
|
|||||||
@ -52,6 +52,8 @@ class="flex items-center gap-1.5 font-bold text-success-600 dark:text-success-40
|
|||||||
|
|
||||||
<div class="flex items-center gap-1">
|
<div class="flex items-center gap-1">
|
||||||
{{ ($this->viewAttendanceAction)(['session' => $session->id]) }}
|
{{ ($this->viewAttendanceAction)(['session' => $session->id]) }}
|
||||||
|
{{ ($this->viewMaterialsAction)(['session' => $session->id]) }}
|
||||||
|
{{ ($this->viewAssignmentsAction)(['session' => $session->id]) }}
|
||||||
{{ ($this->editSessionAction)(['session' => $session->id]) }}
|
{{ ($this->editSessionAction)(['session' => $session->id]) }}
|
||||||
{{ ($this->deleteSessionAction)(['session' => $session->id]) }}
|
{{ ($this->deleteSessionAction)(['session' => $session->id]) }}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -1,9 +1,10 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
use App\Http\Controllers\ShareAttendanceController;
|
||||||
use Illuminate\Support\Facades\Route;
|
use Illuminate\Support\Facades\Route;
|
||||||
|
|
||||||
Route::get('/', function () {
|
Route::get('/', function () {
|
||||||
return redirect()->route('filament.admin.auth.login');
|
return redirect()->route('filament.admin.auth.login');
|
||||||
});
|
});
|
||||||
|
|
||||||
Route::get('/share/presensi/{token}', [\App\Http\Controllers\ShareAttendanceController::class, 'show'])->name('share.attendance');
|
Route::get('/share/presensi/{token}', [ShareAttendanceController::class, 'show'])->name('share.attendance');
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user