feat: display student assignment submissions in the session modal and add submission factory
This commit is contained in:
parent
86bc954edb
commit
e994adf5dc
@ -212,13 +212,20 @@ public function viewAssignmentsAction(): Action
|
||||
->modalWidth(Width::TwoExtraLarge)
|
||||
->modalContent(fn (array $arguments) => view('filament.resources.learning.class-sessions.assignments-modal', [
|
||||
'assignments' => ClassSession::find($arguments['session'] ?? null, ['*'])?->assignments()
|
||||
->with(['assignmentSubmissions.student'])
|
||||
->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') ?? '-',
|
||||
'due_date_formatted' => $a->due_date?->translatedFormat('d F Y H:i') ?? '-',
|
||||
'submissions' => $a->assignmentSubmissions->map(fn ($s) => (object) [
|
||||
'student_name' => $s->student->full_name,
|
||||
'student_number' => $s->student->student_number,
|
||||
'submitted_at_formatted' => $s->submitted_at?->translatedFormat('d F Y H:i') ?? '-',
|
||||
'id' => $s->id,
|
||||
]),
|
||||
]) ?? collect(),
|
||||
]));
|
||||
}
|
||||
|
||||
28
database/factories/AssignmentSubmissionFactory.php
Normal file
28
database/factories/AssignmentSubmissionFactory.php
Normal file
@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
namespace Database\Factories;
|
||||
|
||||
use App\Models\Assignment;
|
||||
use App\Models\AssignmentSubmission;
|
||||
use App\Models\Student;
|
||||
use Illuminate\Database\Eloquent\Factories\Factory;
|
||||
|
||||
/**
|
||||
* @extends Factory<AssignmentSubmission>
|
||||
*/
|
||||
class AssignmentSubmissionFactory extends Factory
|
||||
{
|
||||
/**
|
||||
* Define the model's default state.
|
||||
*
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public function definition(): array
|
||||
{
|
||||
return [
|
||||
'assignment_id' => Assignment::factory(),
|
||||
'student_id' => Student::factory(),
|
||||
'submitted_at' => now(),
|
||||
];
|
||||
}
|
||||
}
|
||||
@ -1,32 +1,72 @@
|
||||
<div class="space-y-4 py-2">
|
||||
<div class="space-y-6 py-2">
|
||||
@forelse($assignments as $assignment)
|
||||
<div
|
||||
class="flex items-center justify-between p-3 rounded-lg border border-gray-100 dark:border-white/5 bg-gray-50/50 dark:bg-white/5 hover:bg-white dark:hover:bg-white/10 transition-colors shadow-sm">
|
||||
<div class="flex items-center gap-3">
|
||||
<div class="p-2 rounded-lg bg-primary-100 dark:bg-primary-900/20 text-primary-600 dark:text-primary-400">
|
||||
<x-heroicon-o-pencil-square class="w-5 h-5" />
|
||||
</div>
|
||||
<div class="flex flex-col">
|
||||
<span
|
||||
class="font-bold text-gray-900 dark:text-white leading-tight uppercase font-mono text-[11px] mb-0.5 tracking-tight text-primary-600/60 dark:text-primary-400/50 block">
|
||||
{{ $assignment->type_label }}
|
||||
</span>
|
||||
<span class="font-bold text-gray-900 dark:text-white leading-tight">{{ $assignment->title }}</span>
|
||||
<div class="flex items-center gap-1.5 mt-0.5">
|
||||
<x-heroicon-o-clock class="w-3.5 h-3.5 text-gray-400 dark:text-gray-500" />
|
||||
<span class="text-[10px] text-gray-500 dark:text-gray-400 font-medium uppercase tracking-tight">
|
||||
Deadline: {{ $assignment->due_date_formatted }}
|
||||
<div class="space-y-3">
|
||||
<div
|
||||
class="flex items-center justify-between p-3 rounded-lg border border-gray-100 dark:border-white/5 bg-gray-50/50 dark:bg-white/5 shadow-sm">
|
||||
<div class="flex items-center gap-3">
|
||||
<div class="p-2 rounded-lg bg-primary-100 dark:bg-primary-900/20 text-primary-600 dark:text-primary-400">
|
||||
<x-heroicon-o-pencil-square class="w-5 h-5" />
|
||||
</div>
|
||||
<div class="flex flex-col">
|
||||
<span
|
||||
class="font-bold text-gray-900 dark:text-white leading-tight uppercase font-mono text-[11px] mb-0.5 tracking-tight text-primary-600/60 dark:text-primary-400/50 block">
|
||||
{{ $assignment->type_label }}
|
||||
</span>
|
||||
<span class="font-bold text-gray-900 dark:text-white leading-tight">{{ $assignment->title }}</span>
|
||||
<div class="flex items-center gap-1.5 mt-0.5">
|
||||
<x-heroicon-o-clock class="w-3.5 h-3.5 text-gray-400 dark:text-gray-500" />
|
||||
<span class="text-[10px] text-gray-500 dark:text-gray-400 font-medium uppercase tracking-tight">
|
||||
Deadline: {{ $assignment->due_date_formatted }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-center gap-2">
|
||||
<a href="{{ \App\Filament\Resources\Learning\Assignments\AssignmentResource::getUrl('submit', ['record' => $assignment->id]) }}"
|
||||
class="p-1.5 rounded-full hover:bg-gray-200 dark:hover:bg-white/10 text-gray-500 transition-colors"
|
||||
title="Lihat Detail">
|
||||
<x-heroicon-o-chevron-right class="w-5 h-5" />
|
||||
</a>
|
||||
</div>
|
||||
|
||||
@if ($assignment->submissions->count() > 0)
|
||||
<div
|
||||
class="fi-ta-content overflow-x-auto overflow-y-auto max-h-60 rounded-xl border border-gray-200 dark:border-gray-700 bg-white dark:bg-gray-900 ring-1 ring-gray-950/5 dark:ring-white/10">
|
||||
<table class="w-full text-sm text-left divide-y divide-gray-200 dark:divide-white/5">
|
||||
<thead class="bg-gray-50 dark:bg-gray-800 sticky top-0 z-10">
|
||||
<tr>
|
||||
<th class="px-4 py-2.5 font-bold text-gray-900 dark:text-white">Mahasiswa</th>
|
||||
<th class="px-4 py-2.5 font-bold text-gray-900 dark:text-white text-right">Waktu Unggah</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="divide-y divide-gray-200 dark:divide-white/5">
|
||||
@foreach ($assignment->submissions as $submission)
|
||||
<tr class="hover:bg-gray-50 dark:hover:bg-white/5 transition-colors">
|
||||
<td class="px-4 py-2.5 text-gray-950 dark:text-white font-medium">
|
||||
<div class="flex flex-col">
|
||||
<span class="text-sm">{{ $submission->student_name }}</span>
|
||||
<span class="text-[10px] text-gray-500 dark:text-gray-400 font-normal uppercase tabular-nums">
|
||||
NIM: {{ $submission->student_number }}
|
||||
</span>
|
||||
</div>
|
||||
</td>
|
||||
<td class="px-4 py-2.5 text-right">
|
||||
<span
|
||||
class="inline-flex items-center rounded-md bg-success-50 dark:bg-success-400/10 px-2 py-0.5 text-xs font-bold text-success-700 dark:text-success-400 ring-1 ring-inset ring-success-600/20 tabular-nums">
|
||||
{{ $submission->submitted_at_formatted }}
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="px-2">
|
||||
<p class="text-[10px] text-gray-500 font-medium uppercase tracking-wider">
|
||||
Total Pengumpulan: <span class="text-primary-600 dark:text-primary-400 font-bold font-mono">{{ $assignment->submissions->count() }}
|
||||
Mahasiswa</span>
|
||||
</p>
|
||||
</div>
|
||||
@else
|
||||
<div class="flex flex-col items-center justify-center p-6 border border-dashed rounded-xl border-gray-200 dark:border-white/10 bg-gray-50/50 dark:bg-white/5">
|
||||
<x-heroicon-o-document-minus class="w-8 h-8 text-gray-400 dark:text-gray-600 mb-2" />
|
||||
<p class="text-xs text-gray-500 dark:text-gray-400 font-medium">Belum ada pengumpulan untuk tugas ini.</p>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
@empty
|
||||
<x-filament::empty-state icon="heroicon-o-clipboard-document" heading="Tidak ada data yang ditemukan"
|
||||
@ -34,3 +74,4 @@ class="p-1.5 rounded-full hover:bg-gray-200 dark:hover:bg-white/10 text-gray-500
|
||||
</x-filament::empty-state>
|
||||
@endforelse
|
||||
</div>
|
||||
|
||||
|
||||
@ -3,9 +3,12 @@
|
||||
use App\Enums\RoleEnum;
|
||||
use App\Filament\Resources\Learning\ClassSessions\Pages\ListCourseSessions;
|
||||
use App\Filament\Resources\Learning\ClassSessions\Pages\ManageClassSessions;
|
||||
use App\Models\Assignment;
|
||||
use App\Models\AssignmentSubmission;
|
||||
use App\Models\ClassSession;
|
||||
use App\Models\Course;
|
||||
use App\Models\CourseSchedule;
|
||||
use App\Models\Student;
|
||||
use App\Models\User;
|
||||
use App\Settings\GeneralSettings;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
@ -173,6 +176,28 @@
|
||||
->assertActionVisible('viewMaterials')
|
||||
->assertActionVisible('viewAssignments');
|
||||
});
|
||||
|
||||
it('shows student submissions in the assignment modal', function () {
|
||||
$course = Course::factory()->create(['semester' => $this->currentSemester]);
|
||||
$session = ClassSession::factory()->create(['course_id' => $course->id]);
|
||||
$assignment = Assignment::factory()->create([
|
||||
'title' => 'Test Assignment Label',
|
||||
'class_session_id' => $session->id,
|
||||
'course_id' => $course->id,
|
||||
]);
|
||||
|
||||
$student = Student::factory()->create(['full_name' => 'John Doe', 'student_number' => '1234567890']);
|
||||
AssignmentSubmission::factory()->create([
|
||||
'assignment_id' => $assignment->id,
|
||||
'student_id' => $student->id,
|
||||
'submitted_at' => now(),
|
||||
]);
|
||||
|
||||
Livewire::test(ListCourseSessions::class, ['courseId' => $course->id])
|
||||
->mountAction('viewAssignments', ['session' => $session->id])
|
||||
->assertActionMounted('viewAssignments')
|
||||
->assertSuccessful();
|
||||
});
|
||||
});
|
||||
|
||||
describe('Search and Dashboard Filter', function () {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user