From 0732a3b4029b25fadafb570d022fb6c6ccd5c10c Mon Sep 17 00:00:00 2001 From: Yoga Pangestu Date: Sun, 29 Mar 2026 23:26:05 +0700 Subject: [PATCH] feat: add attendance viewing functionality for class sessions, including a modal display of attendance records --- .../Attendances/Pages/ManageAttendances.php | 39 +++++++++--------- .../Pages/ListCourseSessions.php | 13 ++++++ .../Pages/ManageClassSessions.php | 21 ++++++++-- .../class-sessions/attendance-modal.blade.php | 41 +++++++++++++++++++ .../learning/class-sessions/index.blade.php | 18 ++++---- .../learning/class-sessions/show.blade.php | 1 + 6 files changed, 102 insertions(+), 31 deletions(-) create mode 100644 resources/views/filament/resources/learning/class-sessions/attendance-modal.blade.php diff --git a/app/Filament/Resources/Learning/Attendances/Pages/ManageAttendances.php b/app/Filament/Resources/Learning/Attendances/Pages/ManageAttendances.php index f8c4f91..8b4972c 100644 --- a/app/Filament/Resources/Learning/Attendances/Pages/ManageAttendances.php +++ b/app/Filament/Resources/Learning/Attendances/Pages/ManageAttendances.php @@ -6,6 +6,7 @@ use App\Filament\Resources\Learning\Attendances\AttendanceResource; use App\Filament\Support\SystemNotification; use App\Models\Attendance; +use App\Models\ClassSession; use App\Models\Course; use App\Models\CourseSchedule; use App\Models\User; @@ -45,17 +46,10 @@ public function getSchedules() return collect(); } - $today = now()->dayOfWeekIso; - $semester = app(GeneralSettings::class)->current_semester; - - return CourseSchedule::query() - ->where('day_of_week', $today) - ->whereHas('course', function ($q) use ($semester) { - $q->where('semester', $semester); - }) + return ClassSession::query() + ->whereDate('date', now()) ->with(['course', 'attendances' => function ($q) use ($student) { - $q->where('student_id', $student->id) - ->whereDate('date', now()->toDateString()); + $q->where('student_id', $student->id); }]) ->orderBy('start_time') ->get(); @@ -138,7 +132,7 @@ public function scheduleCards() }); } - public function attend(int $scheduleId): void + public function attend(int $sessionId): void { /** @var User $user */ $user = auth()->user(); @@ -147,41 +141,46 @@ public function attend(int $scheduleId): void return; } - $schedule = CourseSchedule::find($scheduleId); - if (! $schedule) { + $session = ClassSession::find($sessionId); + if (! $session) { return; } // Check if already attended $existing = Attendance::where('student_id', $student->id) - ->where('course_schedule_id', $scheduleId) - ->whereDate('date', now()->toDateString()) + ->where('class_session_id', $sessionId) ->first(); if ($existing) { SystemNotification::warning( 'Presensi Sudah Tercatat ⚠️', - 'Anda telah melakukan presensi untuk jadwal perkuliahan ini pada hari ini.' + 'Anda telah melakukan presensi untuk sesi perkuliahan ini.' )->send(); return; } // Check time - $startTime = now()->setTimeFrom($schedule->start_time); + $startTime = $session->start_time; if (now()->lessThan($startTime)) { SystemNotification::warning( 'Presensi Belum Dibuka ⏳', - 'Waktu presensi untuk jadwal perkuliahan ini belum dimulai. Silakan lakukan presensi setelah waktu dimulai.' + 'Waktu presensi untuk sesi perkuliahan ini belum dimulai.' )->send(); return; } + // Find schedule for compatibility + $schedule = CourseSchedule::where('course_id', $session->course_id) + ->where('day_of_week', $session->date->dayOfWeekIso) + ->first(); + Attendance::create([ 'student_id' => $student->id, - 'course_schedule_id' => $scheduleId, - 'date' => now()->toDateString(), + 'class_session_id' => $sessionId, + 'course_schedule_id' => $schedule?->id, + 'date' => $session->date->toDateString(), 'attended_at' => now(), ]); diff --git a/app/Filament/Resources/Learning/ClassSessions/Pages/ListCourseSessions.php b/app/Filament/Resources/Learning/ClassSessions/Pages/ListCourseSessions.php index 65caab7..4c9c633 100644 --- a/app/Filament/Resources/Learning/ClassSessions/Pages/ListCourseSessions.php +++ b/app/Filament/Resources/Learning/ClassSessions/Pages/ListCourseSessions.php @@ -178,6 +178,19 @@ public function generateSessionsAction(): 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(), + ])); + } + public function editSessionAction(): Action { return EditAction::make('editSession') diff --git a/app/Filament/Resources/Learning/ClassSessions/Pages/ManageClassSessions.php b/app/Filament/Resources/Learning/ClassSessions/Pages/ManageClassSessions.php index 4832236..976b032 100644 --- a/app/Filament/Resources/Learning/ClassSessions/Pages/ManageClassSessions.php +++ b/app/Filament/Resources/Learning/ClassSessions/Pages/ManageClassSessions.php @@ -6,6 +6,7 @@ use App\Models\ClassSession; use App\Models\Course; use App\Settings\GeneralSettings; +use Filament\Actions\Action; use Filament\Actions\Concerns\InteractsWithActions; use Filament\Actions\Contracts\HasActions; use Filament\Forms\Components\TextInput; @@ -13,6 +14,7 @@ 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; @@ -94,9 +96,9 @@ public function courses(): Collection if ($this->search) { $query->where(function ($q) { - $q->where('name', 'like', "%{$this->search}%") - ->orWhere('code', 'like', "%{$this->search}%") - ->orWhere('lecturer', 'like', "%{$this->search}%"); + $q->where('name', 'like', '%'.$this->search.'%') + ->orWhere('code', 'like', '%'.$this->search.'%') + ->orWhere('lecturer', 'like', '%'.$this->search.'%'); }); } @@ -111,4 +113,17 @@ public function courses(): Collection 'url' => ClassSessionResource::getUrl('course', ['courseId' => $course->id]), ]); } + + 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(), + ])); + } } diff --git a/resources/views/filament/resources/learning/class-sessions/attendance-modal.blade.php b/resources/views/filament/resources/learning/class-sessions/attendance-modal.blade.php new file mode 100644 index 0000000..dcfecef --- /dev/null +++ b/resources/views/filament/resources/learning/class-sessions/attendance-modal.blade.php @@ -0,0 +1,41 @@ +
+ @if ($attendances->isEmpty()) +
+ +

Belum ada mahasiswa yang melakukan presensi pada sesi ini.

+
+ @else +
+ + + + + + + + + @foreach ($attendances as $attendance) + + + + + @endforeach + +
MahasiswaWaktu Presensi
+
+ {{ $attendance->student->full_name }} + NIM: {{ $attendance->student->nim }} +
+
+ + {{ $attendance->attended_at->format('H:i') }} WIB + +
+
+
+

+ Total Kehadiran: {{ $attendances->count() }} Mahasiswa +

+
+ @endif +
diff --git a/resources/views/filament/resources/learning/class-sessions/index.blade.php b/resources/views/filament/resources/learning/class-sessions/index.blade.php index ab41dff..b804696 100644 --- a/resources/views/filament/resources/learning/class-sessions/index.blade.php +++ b/resources/views/filament/resources/learning/class-sessions/index.blade.php @@ -57,14 +57,16 @@ class="mt-2 flex items-center gap-1.5 text-[10px] text-gray-400 dark:text-gray-5 @else -
- - {{ $session->attendances_count }} - - - Hadir - -
+
+ + {{ $session->attendances_count }} + + + Hadir + +
@endif diff --git a/resources/views/filament/resources/learning/class-sessions/show.blade.php b/resources/views/filament/resources/learning/class-sessions/show.blade.php index 42084ef..265a86b 100644 --- a/resources/views/filament/resources/learning/class-sessions/show.blade.php +++ b/resources/views/filament/resources/learning/class-sessions/show.blade.php @@ -40,6 +40,7 @@ class="flex items-center gap-1.5 font-bold text-success-600 dark:text-success-40
+ {{ ($this->viewAttendanceAction)(['session' => $session->id]) }} {{ ($this->editSessionAction)(['session' => $session->id]) }} {{ ($this->deleteSessionAction)(['session' => $session->id]) }}