diff --git a/app/Filament/Actions/Cheerful/EditAction.php b/app/Filament/Actions/Cheerful/EditAction.php index 9f622d5..9ebdb0b 100644 --- a/app/Filament/Actions/Cheerful/EditAction.php +++ b/app/Filament/Actions/Cheerful/EditAction.php @@ -13,6 +13,7 @@ protected function setUp(): void $this->successNotification( SystemNotification::update() - ); + ) + ->color('warning'); } } diff --git a/app/Filament/Actions/GoToDateAction.php b/app/Filament/Actions/GoToDateAction.php deleted file mode 100644 index bdd8eff..0000000 --- a/app/Filament/Actions/GoToDateAction.php +++ /dev/null @@ -1,35 +0,0 @@ -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); - } -} diff --git a/app/Filament/Pages/Auth/Login.php b/app/Filament/Pages/Auth/Login.php index 1033496..56334ca 100644 --- a/app/Filament/Pages/Auth/Login.php +++ b/app/Filament/Pages/Auth/Login.php @@ -29,7 +29,7 @@ public function getHeading(): string|Htmlable return ''; } - public function form(Schema $schema): Schema + public function schema(Schema $schema): Schema { return $schema ->components([ diff --git a/app/Filament/Pages/Information/CourseSchedule/Actions/DeleteScheduleAction.php b/app/Filament/Pages/Information/CourseSchedule/Actions/DeleteScheduleAction.php index ecf192e..986890b 100644 --- a/app/Filament/Pages/Information/CourseSchedule/Actions/DeleteScheduleAction.php +++ b/app/Filament/Pages/Information/CourseSchedule/Actions/DeleteScheduleAction.php @@ -4,7 +4,6 @@ use App\Filament\Actions\Cheerful\DeleteAction; use App\Models\CourseSchedule; -use Filament\Support\Icons\Heroicon; class DeleteScheduleAction extends DeleteAction { @@ -21,9 +20,9 @@ protected function setUp(): void return CourseSchedule::findOrFail($arguments['schedule']); }) ->label('Hapus') - ->icon(Heroicon::OutlinedTrash) + ->icon('heroicon-o-trash') ->color('danger') - ->iconButton() + ->link() ->tooltip('Hapus') ->modalHeading('Hapus Jadwal Kuliah') ->modalDescription('Apakah Anda yakin ingin menghapus jadwal ini? Tindakan ini tidak dapat dibatalkan.') diff --git a/app/Filament/Pages/Information/CourseSchedule/Actions/EditScheduleAction.php b/app/Filament/Pages/Information/CourseSchedule/Actions/EditScheduleAction.php index 26f3e9b..3cc54de 100644 --- a/app/Filament/Pages/Information/CourseSchedule/Actions/EditScheduleAction.php +++ b/app/Filament/Pages/Information/CourseSchedule/Actions/EditScheduleAction.php @@ -5,7 +5,6 @@ use App\Filament\Actions\Cheerful\EditAction; use App\Models\CourseSchedule; use Filament\Support\Enums\Width; -use Filament\Support\Icons\Heroicon; class EditScheduleAction extends EditAction { @@ -20,8 +19,9 @@ protected function setUp(): void $this ->label('Ubah') - ->icon(Heroicon::OutlinedPencilSquare) - ->iconButton() + ->color('warning') + ->icon('heroicon-o-pencil-square') + ->link() ->tooltip('Ubah') ->record(function (array $arguments): CourseSchedule { return CourseSchedule::findOrFail($arguments['schedule']); diff --git a/app/Filament/Pages/Information/CourseSchedule/Index.php b/app/Filament/Pages/Information/CourseSchedule/Index.php index d248c4f..0878924 100644 --- a/app/Filament/Pages/Information/CourseSchedule/Index.php +++ b/app/Filament/Pages/Information/CourseSchedule/Index.php @@ -58,7 +58,7 @@ public function mount(): void $this->form->fill(); } - public function form(Schema $schema): Schema + public function schema(Schema $schema): Schema { return $schema ->schema([ diff --git a/app/Filament/Pages/Learning/StudyGroup/Actions/DeleteStudyGroupAction.php b/app/Filament/Pages/Learning/StudyGroup/Actions/DeleteStudyGroupAction.php index d0efb57..e9d50d4 100644 --- a/app/Filament/Pages/Learning/StudyGroup/Actions/DeleteStudyGroupAction.php +++ b/app/Filament/Pages/Learning/StudyGroup/Actions/DeleteStudyGroupAction.php @@ -4,7 +4,6 @@ use App\Filament\Actions\Cheerful\DeleteAction; use App\Models\StudyGroup; -use Filament\Support\Icons\Heroicon; class DeleteStudyGroupAction extends DeleteAction { @@ -19,9 +18,9 @@ protected function setUp(): void $this->record(fn (array $arguments): StudyGroup => StudyGroup::findOrFail($arguments['studyGroup'])) ->label('Hapus') - ->icon(Heroicon::OutlinedTrash) + ->icon('heroicon-o-trash') ->color('danger') - ->iconButton() + ->link() ->tooltip('Hapus') ->modalHeading(fn (StudyGroup $record) => "Hapus {$record->name}") ->modalDescription('Apakah Anda yakin ingin menghapus kelompok ini? Tindakan ini tidak dapat dibatalkan.') diff --git a/app/Filament/Pages/Learning/StudyGroup/Actions/EditStudyGroupAction.php b/app/Filament/Pages/Learning/StudyGroup/Actions/EditStudyGroupAction.php index 3e8920e..819f82d 100644 --- a/app/Filament/Pages/Learning/StudyGroup/Actions/EditStudyGroupAction.php +++ b/app/Filament/Pages/Learning/StudyGroup/Actions/EditStudyGroupAction.php @@ -5,7 +5,6 @@ use App\Filament\Actions\Cheerful\EditAction; use App\Models\StudyGroup; use Filament\Support\Enums\Width; -use Filament\Support\Icons\Heroicon; class EditStudyGroupAction extends EditAction { @@ -20,8 +19,9 @@ protected function setUp(): void $this ->label('Ubah') - ->icon(Heroicon::OutlinedPencilSquare) - ->iconButton() + ->color('warning') + ->icon('heroicon-o-pencil-square') + ->link() ->tooltip('Ubah') ->record(fn (array $arguments): StudyGroup => StudyGroup::findOrFail($arguments['studyGroup'])) ->modalHeading(fn (StudyGroup $record) => "Ubah {$record->name}") diff --git a/app/Filament/Pages/Learning/StudyGroup/Index.php b/app/Filament/Pages/Learning/StudyGroup/Index.php index a53341d..97a7fd4 100644 --- a/app/Filament/Pages/Learning/StudyGroup/Index.php +++ b/app/Filament/Pages/Learning/StudyGroup/Index.php @@ -61,7 +61,7 @@ public function mount(): void ]); } - public function form(Schema $schema): Schema + public function schema(Schema $schema): Schema { return $schema ->schema([ diff --git a/app/Filament/Pages/Profile.php b/app/Filament/Pages/Profile.php index f85c82f..76b32f9 100644 --- a/app/Filament/Pages/Profile.php +++ b/app/Filament/Pages/Profile.php @@ -15,7 +15,7 @@ class Profile extends EditProfile { - public function form(Schema $schema): Schema + public function schema(Schema $schema): Schema { return $schema ->components([ diff --git a/app/Filament/Pages/System/ManageSettings.php b/app/Filament/Pages/System/ManageSettings.php index 160b014..48c9d5d 100644 --- a/app/Filament/Pages/System/ManageSettings.php +++ b/app/Filament/Pages/System/ManageSettings.php @@ -40,7 +40,7 @@ public static function getPagePermission(): string protected static string $settings = GeneralSettings::class; - public function form(Schema $schema): Schema + public function schema(Schema $schema): Schema { return $schema ->components([ diff --git a/app/Filament/Resources/Learning/Assignments/Actions/DeleteAssignmentAction.php b/app/Filament/Resources/Learning/Assignments/Actions/DeleteAssignmentAction.php index ecdb68b..da25bd5 100644 --- a/app/Filament/Resources/Learning/Assignments/Actions/DeleteAssignmentAction.php +++ b/app/Filament/Resources/Learning/Assignments/Actions/DeleteAssignmentAction.php @@ -18,15 +18,14 @@ protected function setUp(): void $this ->label('Hapus') + ->icon('heroicon-o-trash') + ->link() ->modalHeading(fn (Assignment $record) => "Hapus {$record->title}") ->record(fn (array $arguments) => Assignment::find($arguments['record'])) ->after(function ($livewire) { unset($livewire->assignments); }) - ->icon('heroicon-m-trash') ->color('danger') - ->tooltip('Hapus') - ->size('sm') - ->iconButton(); + ->tooltip('Hapus'); } } diff --git a/app/Filament/Resources/Learning/Assignments/Actions/EditAssignmentAction.php b/app/Filament/Resources/Learning/Assignments/Actions/EditAssignmentAction.php index 20c208f..9563adb 100644 --- a/app/Filament/Resources/Learning/Assignments/Actions/EditAssignmentAction.php +++ b/app/Filament/Resources/Learning/Assignments/Actions/EditAssignmentAction.php @@ -23,15 +23,15 @@ protected function setUp(): void { parent::setUp(); - $this->icon('heroicon-m-pencil-square') + $this->label('Ubah') ->color('warning') + ->icon('heroicon-o-pencil-square') + ->link() ->tooltip('Ubah') - ->size('sm') - ->iconButton() ->record(fn (array $arguments) => Assignment::find($arguments['record'])) ->modalHeading(fn (Assignment $record) => "Ubah {$record->title}") ->modalWidth(Width::FourExtraLarge) - ->schema(fn (Schema $schema) => AssignmentForm::configure($schema)->getComponents()) + ->form(AssignmentForm::configure(new Schema)->getComponents()) ->fillForm(function (Assignment $record): array { $data = $record->toArray(); diff --git a/app/Filament/Resources/Learning/Assignments/Actions/PinAction.php b/app/Filament/Resources/Learning/Assignments/Actions/PinAction.php index 4fab69d..3fea5c3 100644 --- a/app/Filament/Resources/Learning/Assignments/Actions/PinAction.php +++ b/app/Filament/Resources/Learning/Assignments/Actions/PinAction.php @@ -17,14 +17,18 @@ protected function setUp(): void { 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') + ->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') - ->size('sm') - ->iconButton() ->action(function (array $arguments, $livewire) { $assignmentId = $arguments['record']; - $studentProfile = auth()->user()->student; + $studentProfile = auth()->user()?->student; + + if (! $studentProfile) { + return; + } $existing = AssignmentPin::where('student_id', $studentProfile->id) ->where('assignment_id', $assignmentId) diff --git a/app/Filament/Resources/Learning/Assignments/Actions/SubmitAction.php b/app/Filament/Resources/Learning/Assignments/Actions/SubmitAction.php index 888db25..e28d05d 100644 --- a/app/Filament/Resources/Learning/Assignments/Actions/SubmitAction.php +++ b/app/Filament/Resources/Learning/Assignments/Actions/SubmitAction.php @@ -19,8 +19,9 @@ protected function setUp(): void parent::setUp(); $this->label('Kumpulkan') - ->icon('heroicon-o-arrow-up-tray') - ->color('primary') + ->color('success') + ->icon('heroicon-o-paper-airplane') + ->link() ->url(fn (Assignment $record) => AssignmentResource::getUrl('submit', ['record' => $record->id])) ->visible(function (Assignment $record) { if (now()->isAfter($record->due_date)) { diff --git a/app/Filament/Resources/Learning/Attendances/AttendanceResource.php b/app/Filament/Resources/Learning/Attendances/AttendanceResource.php index 45bf3f4..1a84023 100644 --- a/app/Filament/Resources/Learning/Attendances/AttendanceResource.php +++ b/app/Filament/Resources/Learning/Attendances/AttendanceResource.php @@ -19,11 +19,11 @@ class AttendanceResource extends Resource 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 { diff --git a/app/Filament/Resources/Learning/ClassSessions/Actions/DeleteSessionAction.php b/app/Filament/Resources/Learning/ClassSessions/Actions/DeleteSessionAction.php new file mode 100644 index 0000000..1a0b130 --- /dev/null +++ b/app/Filament/Resources/Learning/ClassSessions/Actions/DeleteSessionAction.php @@ -0,0 +1,25 @@ +label('Hapus') + ->icon('heroicon-o-trash') + ->link() + ->record(fn (array $arguments) => ClassSession::find($arguments['session'], ['*'])) + ->color('danger'); + } +} diff --git a/app/Filament/Resources/Learning/ClassSessions/Actions/EditSessionAction.php b/app/Filament/Resources/Learning/ClassSessions/Actions/EditSessionAction.php new file mode 100644 index 0000000..cd547a8 --- /dev/null +++ b/app/Filament/Resources/Learning/ClassSessions/Actions/EditSessionAction.php @@ -0,0 +1,28 @@ +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); + } +} diff --git a/app/Filament/Resources/Learning/ClassSessions/Actions/GenerateSessionsAction.php b/app/Filament/Resources/Learning/ClassSessions/Actions/GenerateSessionsAction.php new file mode 100644 index 0000000..893ab40 --- /dev/null +++ b/app/Filament/Resources/Learning/ClassSessions/Actions/GenerateSessionsAction.php @@ -0,0 +1,64 @@ +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(); + }); + } +} diff --git a/app/Filament/Resources/Learning/ClassSessions/Actions/ViewAssignmentsAction.php b/app/Filament/Resources/Learning/ClassSessions/Actions/ViewAssignmentsAction.php new file mode 100644 index 0000000..8ba252b --- /dev/null +++ b/app/Filament/Resources/Learning/ClassSessions/Actions/ViewAssignmentsAction.php @@ -0,0 +1,32 @@ +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(), + ])); + } +} diff --git a/app/Filament/Resources/Learning/ClassSessions/Actions/ViewAttendanceAction.php b/app/Filament/Resources/Learning/ClassSessions/Actions/ViewAttendanceAction.php new file mode 100644 index 0000000..b507a6b --- /dev/null +++ b/app/Filament/Resources/Learning/ClassSessions/Actions/ViewAttendanceAction.php @@ -0,0 +1,32 @@ +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(), + ])); + } +} diff --git a/app/Filament/Resources/Learning/ClassSessions/Actions/ViewMaterialsAction.php b/app/Filament/Resources/Learning/ClassSessions/Actions/ViewMaterialsAction.php new file mode 100644 index 0000000..7050b0f --- /dev/null +++ b/app/Filament/Resources/Learning/ClassSessions/Actions/ViewMaterialsAction.php @@ -0,0 +1,32 @@ +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(), + ])); + } +} diff --git a/app/Filament/Resources/Learning/ClassSessions/ClassSessionResource.php b/app/Filament/Resources/Learning/ClassSessions/ClassSessionResource.php index a6d902a..1cff88b 100644 --- a/app/Filament/Resources/Learning/ClassSessions/ClassSessionResource.php +++ b/app/Filament/Resources/Learning/ClassSessions/ClassSessionResource.php @@ -2,33 +2,14 @@ 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\ManageClassSessions; use App\Filament\Resources\Learning\ClassSessions\RelationManagers\AttendanceRelationManager; use App\Models\ClassSession; -use App\Models\Course; use App\Settings\GeneralSettings; 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\Schemas\Components\Grid; -use Filament\Schemas\Schema; -use Filament\Support\Enums\Width; 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\SoftDeletingScope; use UnitEnum; @@ -43,155 +24,11 @@ class ClassSessionResource extends Resource 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'; - - 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); - } + protected static ?string $slug = 'learning/class-sessions'; public static function getRelations(): array { diff --git a/app/Filament/Resources/Learning/ClassSessions/Pages/ListCourseSessions.php b/app/Filament/Resources/Learning/ClassSessions/Pages/ListCourseSessions.php index 5fd9a3e..2b69e8f 100644 --- a/app/Filament/Resources/Learning/ClassSessions/Pages/ListCourseSessions.php +++ b/app/Filament/Resources/Learning/ClassSessions/Pages/ListCourseSessions.php @@ -4,11 +4,13 @@ use App\Filament\Actions\BackAction; use App\Filament\Actions\Cheerful\CreateAction; -use App\Filament\Actions\Cheerful\DeleteAction; -use App\Filament\Actions\Cheerful\EditAction; +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\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\Support\SystemNotification; -use App\Models\ClassSession; use App\Models\Course; use App\Models\Student; use Filament\Actions\Action; @@ -70,34 +72,43 @@ public function sessions(): Collection ]); } - public function formSchema(): array + public function schema(): array { return [ - Grid::make(['default' => 3]) + Grid::make(['default' => 2]) ->schema([ TextInput::make('session_number') ->label('Pertemuan Ke-') + ->placeholder('1') ->numeric() - ->default(fn () => ($this->course->classSessions()->max('session_number') ?? 0) + 1) - ->required(), + ->required() + ->minValue(1) + ->maxValue(16) + ->autocomplete(false), + DatePicker::make('date') ->label('Tanggal') - ->default(now()) + ->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(), - 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() ->url(ManageClassSessions::getUrl()), - $this->generateSessionsAction(), + GenerateSessionsAction::make(), + CreateAction::make() - ->label('Tambah Sesi') + ->label('Tambah') ->modalHeading('Tambah Sesi') ->modalSubmitActionLabel('Simpan') ->modalCancelActionLabel('Batal') - ->form($this->formSchema()) - ->mutateFormDataUsing(function (array $data): array { + ->schema($this->schema()) + ->mutateDataUsing(function (array $data): array { $data['course_id'] = $this->courseId; return $data; @@ -139,102 +151,28 @@ protected function getHeaderActions(): array ]; } - public function generateSessionsAction(): Action + public function viewAttendanceAction(): Action { - return Action::make('generateSessions') - ->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(); - }); + return ViewAttendanceAction::make(); } - protected function viewAttendanceAction(): Action + public function viewMaterialsAction(): Action { - return Action::make('viewAttendance') - ->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(), - ])); + return ViewMaterialsAction::make(); } - protected function viewMaterialsAction(): Action + public function viewAssignmentsAction(): Action { - return Action::make('viewMaterials') - ->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(), - ])); + return ViewAssignmentsAction::make(); } public function editSessionAction(): Action { - return EditAction::make('editSession') - ->record(fn (array $arguments) => ClassSession::find($arguments['session'])) - ->form($this->formSchema()) - ->modalWidth(Width::TwoExtraLarge); + return EditSessionAction::make(); } public function deleteSessionAction(): Action { - return DeleteAction::make('deleteSession') - ->record(fn (array $arguments) => ClassSession::find($arguments['session'])); + return DeleteSessionAction::make(); } } diff --git a/app/Filament/Resources/Learning/ClassSessions/Pages/ManageClassSessions.php b/app/Filament/Resources/Learning/ClassSessions/Pages/ManageClassSessions.php index ad2cae5..6119ddb 100644 --- a/app/Filament/Resources/Learning/ClassSessions/Pages/ManageClassSessions.php +++ b/app/Filament/Resources/Learning/ClassSessions/Pages/ManageClassSessions.php @@ -2,6 +2,9 @@ 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\Models\ClassSession; use App\Models\Course; @@ -15,7 +18,6 @@ use Filament\Forms\Contracts\HasForms; use Filament\Resources\Pages\Page; use Filament\Schemas\Schema; -use Filament\Support\Enums\Width; use Illuminate\Support\Collection; use Livewire\Attributes\Computed; @@ -132,42 +134,18 @@ public function courses(): Collection }); } - protected function viewAttendanceAction(): Action + public function viewAttendanceAction(): Action { - return Action::make('viewAttendance') - ->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(), - ])); + return ViewAttendanceAction::make(); } - protected function viewMaterialsAction(): Action + public function viewMaterialsAction(): Action { - return Action::make('viewMaterials') - ->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(), - ])); + return ViewMaterialsAction::make(); } - protected function viewAssignmentsAction(): Action + public 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(), - ])); + return ViewAssignmentsAction::make(); } } diff --git a/app/Filament/Resources/Learning/ClassSessions/RelationManagers/AttendanceRelationManager.php b/app/Filament/Resources/Learning/ClassSessions/RelationManagers/AttendanceRelationManager.php index e5f432d..7450543 100644 --- a/app/Filament/Resources/Learning/ClassSessions/RelationManagers/AttendanceRelationManager.php +++ b/app/Filament/Resources/Learning/ClassSessions/RelationManagers/AttendanceRelationManager.php @@ -21,7 +21,7 @@ class AttendanceRelationManager extends RelationManager protected static ?string $title = 'Presensi Mahasiswa'; - public function form(Schema $schema): Schema + public function schema(Schema $schema): Schema { return $schema ->components([ diff --git a/app/Filament/Resources/Master/Courses/CourseResource.php b/app/Filament/Resources/Master/Courses/CourseResource.php index b6f2fde..f74154a 100644 --- a/app/Filament/Resources/Master/Courses/CourseResource.php +++ b/app/Filament/Resources/Master/Courses/CourseResource.php @@ -34,11 +34,9 @@ class CourseResource extends Resource protected static string|BackedEnum|null $navigationIcon = Heroicon::OutlinedRectangleStack; - protected static ?string $title = 'Mata Kuliah'; - protected static ?string $navigationLabel = 'Mata Kuliah'; - protected static ?int $navigationSort = 15; + protected static ?int $navigationSort = 10; protected static ?string $recordTitleAttribute = 'name'; diff --git a/app/Filament/Resources/Master/Students/Actions/ChangePasswordAction.php b/app/Filament/Resources/Master/Students/Actions/ChangePasswordAction.php index 52dc8f1..dcf982a 100644 --- a/app/Filament/Resources/Master/Students/Actions/ChangePasswordAction.php +++ b/app/Filament/Resources/Master/Students/Actions/ChangePasswordAction.php @@ -7,7 +7,6 @@ use Filament\Actions\Action; use Filament\Forms\Components\TextInput; use Filament\Support\Enums\Width; -use Filament\Support\Icons\Heroicon; use Illuminate\Support\Facades\Hash; class ChangePasswordAction extends Action @@ -17,7 +16,6 @@ protected function setUp(): void parent::setUp(); $this->label('Ganti Kata Sandi') - ->icon(Heroicon::OutlinedKey) ->color('warning') ->modalWidth(Width::Medium) ->schema([ diff --git a/database/migrations/2026_03_12_114022_add_sharing_token_to_courses_table.php b/database/migrations/2026_03_12_114022_add_sharing_token_to_courses_table.php index d7c4265..02b83cd 100644 --- a/database/migrations/2026_03_12_114022_add_sharing_token_to_courses_table.php +++ b/database/migrations/2026_03_12_114022_add_sharing_token_to_courses_table.php @@ -1,8 +1,10 @@ each(function ($course) { - $course->update(['sharing_token' => \Illuminate\Support\Str::random(32)]); + Course::all()->each(function ($course) { + $course->update(['sharing_token' => Str::random(32)]); }); } diff --git a/resources/views/filament/resources/learning/assignments/index.blade.php b/resources/views/filament/resources/learning/assignments/index.blade.php index d6d96d6..ebd775d 100644 --- a/resources/views/filament/resources/learning/assignments/index.blade.php +++ b/resources/views/filament/resources/learning/assignments/index.blade.php @@ -91,7 +91,7 @@ class="h-4 w-4 text-gray-400 group-hover:text-primary-500 mt-1 transition-colors