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)
|
->modalWidth(Width::TwoExtraLarge)
|
||||||
->modalContent(fn (array $arguments) => view('filament.resources.learning.class-sessions.assignments-modal', [
|
->modalContent(fn (array $arguments) => view('filament.resources.learning.class-sessions.assignments-modal', [
|
||||||
'assignments' => ClassSession::find($arguments['session'] ?? null, ['*'])?->assignments()
|
'assignments' => ClassSession::find($arguments['session'] ?? null, ['*'])?->assignments()
|
||||||
|
->with(['assignmentSubmissions.student'])
|
||||||
->latest()
|
->latest()
|
||||||
->get()
|
->get()
|
||||||
->map(fn ($a) => (object) [
|
->map(fn ($a) => (object) [
|
||||||
'id' => $a->id,
|
'id' => $a->id,
|
||||||
'title' => $a->title,
|
'title' => $a->title,
|
||||||
'type_label' => $a->type?->getLabel() ?? 'Tugas',
|
'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(),
|
]) ?? 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)
|
@forelse($assignments as $assignment)
|
||||||
<div
|
<div class="space-y-3">
|
||||||
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
|
||||||
<div class="flex items-center gap-3">
|
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="p-2 rounded-lg bg-primary-100 dark:bg-primary-900/20 text-primary-600 dark:text-primary-400">
|
<div class="flex items-center gap-3">
|
||||||
<x-heroicon-o-pencil-square class="w-5 h-5" />
|
<div class="p-2 rounded-lg bg-primary-100 dark:bg-primary-900/20 text-primary-600 dark:text-primary-400">
|
||||||
</div>
|
<x-heroicon-o-pencil-square class="w-5 h-5" />
|
||||||
<div class="flex flex-col">
|
</div>
|
||||||
<span
|
<div class="flex flex-col">
|
||||||
class="font-bold text-gray-900 dark:text-white leading-tight uppercase font-mono text-[11px] mb-0.5 tracking-tight text-primary-600/60 dark:text-primary-400/50 block">
|
<span
|
||||||
{{ $assignment->type_label }}
|
class="font-bold text-gray-900 dark:text-white leading-tight uppercase font-mono text-[11px] mb-0.5 tracking-tight text-primary-600/60 dark:text-primary-400/50 block">
|
||||||
</span>
|
{{ $assignment->type_label }}
|
||||||
<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>
|
</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>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex items-center gap-2">
|
|
||||||
<a href="{{ \App\Filament\Resources\Learning\Assignments\AssignmentResource::getUrl('submit', ['record' => $assignment->id]) }}"
|
@if ($assignment->submissions->count() > 0)
|
||||||
class="p-1.5 rounded-full hover:bg-gray-200 dark:hover:bg-white/10 text-gray-500 transition-colors"
|
<div
|
||||||
title="Lihat Detail">
|
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">
|
||||||
<x-heroicon-o-chevron-right class="w-5 h-5" />
|
<table class="w-full text-sm text-left divide-y divide-gray-200 dark:divide-white/5">
|
||||||
</a>
|
<thead class="bg-gray-50 dark:bg-gray-800 sticky top-0 z-10">
|
||||||
</div>
|
<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>
|
</div>
|
||||||
@empty
|
@empty
|
||||||
<x-filament::empty-state icon="heroicon-o-clipboard-document" heading="Tidak ada data yang ditemukan"
|
<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>
|
</x-filament::empty-state>
|
||||||
@endforelse
|
@endforelse
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@ -3,9 +3,12 @@
|
|||||||
use App\Enums\RoleEnum;
|
use App\Enums\RoleEnum;
|
||||||
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\Models\Assignment;
|
||||||
|
use App\Models\AssignmentSubmission;
|
||||||
use App\Models\ClassSession;
|
use App\Models\ClassSession;
|
||||||
use App\Models\Course;
|
use App\Models\Course;
|
||||||
use App\Models\CourseSchedule;
|
use App\Models\CourseSchedule;
|
||||||
|
use App\Models\Student;
|
||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
use App\Settings\GeneralSettings;
|
use App\Settings\GeneralSettings;
|
||||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||||
@ -173,6 +176,28 @@
|
|||||||
->assertActionVisible('viewMaterials')
|
->assertActionVisible('viewMaterials')
|
||||||
->assertActionVisible('viewAssignments');
|
->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 () {
|
describe('Search and Dashboard Filter', function () {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user