feat: add assignment status indication and improve submission logic for assigned students
This commit is contained in:
parent
7c5b279689
commit
eb39408dae
@ -186,16 +186,25 @@ public function assignments(): Collection
|
||||
|
||||
$pinnedIds = $this->pinnedIds;
|
||||
|
||||
$assignments = Assignment::with(['course', 'assignmentSubmissions' => function ($q) use ($studentProfile) {
|
||||
$isStaff = auth()->user()->hasAnyRole(['Developer', 'Kosma']);
|
||||
|
||||
$assignments = Assignment::with([
|
||||
'course',
|
||||
'assignmentSubmissions' => function ($q) use ($studentProfile) {
|
||||
$q->where('student_id', $studentProfile->id)
|
||||
->orWhereHas('studyGroup', fn ($sq) => $sq->where('leader_id', $studentProfile->id)->orWhereHas('students', fn ($ssq) => $ssq->whereKey($studentProfile->id)));
|
||||
}, 'studyGroups.students'])
|
||||
},
|
||||
'studyGroups.students',
|
||||
'students',
|
||||
])
|
||||
->whereHas('course', function ($q) {
|
||||
$q->where('semester', app(GeneralSettings::class)->current_semester);
|
||||
})
|
||||
->where(function ($query) use ($studentProfile) {
|
||||
$query->whereHas('students', fn ($q) => $q->whereKey($studentProfile->id))
|
||||
->orWhereHas('studyGroups', fn ($q) => $q->where('leader_id', $studentProfile->id)->orWhereHas('students', fn ($sq) => $sq->whereKey($studentProfile->id)));
|
||||
->when(! $isStaff, function ($query) use ($studentProfile) {
|
||||
$query->where(function ($q) use ($studentProfile) {
|
||||
$q->whereHas('students', fn ($sq) => $sq->whereKey($studentProfile->id))
|
||||
->orWhereHas('studyGroups', fn ($sq) => $sq->where('leader_id', $studentProfile->id)->orWhereHas('students', fn ($ssq) => $ssq->whereKey($studentProfile->id)));
|
||||
});
|
||||
})
|
||||
->when($this->search, function ($query) {
|
||||
$query->where(function ($q) {
|
||||
@ -273,11 +282,15 @@ public function assignmentCards()
|
||||
$isGroup = $assignment->type === AssignmentType::Group;
|
||||
|
||||
$isLeader = false;
|
||||
$isAssigned = false;
|
||||
if ($isGroup) {
|
||||
$userGroup = $assignment->studyGroups?->first(function ($g) use ($studentProfile) {
|
||||
return $g->leader_id === $studentProfile->id || $g->students?->contains($studentProfile->id);
|
||||
});
|
||||
$isLeader = $userGroup && $userGroup->leader_id === $studentProfile->id;
|
||||
$isAssigned = $userGroup !== null;
|
||||
} else {
|
||||
$isAssigned = $assignment->students?->contains($studentProfile->id) ?? false;
|
||||
}
|
||||
|
||||
$isSentToLecturer = $assignment->is_sent_to_lecturer;
|
||||
@ -286,13 +299,17 @@ public function assignmentCards()
|
||||
$canSubmit = ! $isSentToLecturer;
|
||||
|
||||
$canSubmitByRole = ! $isGroup || $isLeader;
|
||||
$canSubmitActual = $canSubmit && $canSubmitByRole;
|
||||
$canSubmitActual = $canSubmit && $canSubmitByRole && $isAssigned;
|
||||
|
||||
$isUrgent = ! $isSubmitted && $canSubmitActual && now()->diffInHours($assignment->due_date) <= 48;
|
||||
$isUrgent = $isAssigned && ! $isSubmitted && $canSubmitActual && now()->diffInHours($assignment->due_date) <= 48;
|
||||
$isNew = $assignment->created_at?->diffInDays(now()) <= 3;
|
||||
$isPinned = in_array($assignment->id, $pinnedIds);
|
||||
|
||||
if ($isSubmitted) {
|
||||
if (! $isAssigned) {
|
||||
$submissionLabel = 'Tidak Ditugaskan';
|
||||
$submissionColor = 'gray';
|
||||
$submissionIcon = 'heroicon-o-minus-circle';
|
||||
} elseif ($isSubmitted) {
|
||||
$submissionLabel = SystemNotification::getByKey('labels.assignment_status.submitted');
|
||||
$submissionColor = 'success';
|
||||
$submissionIcon = 'heroicon-o-check-circle';
|
||||
@ -329,12 +346,13 @@ public function assignmentCards()
|
||||
'is_urgent' => $isUrgent,
|
||||
'is_new' => $isNew,
|
||||
'is_pinned' => $isPinned,
|
||||
'is_assigned' => $isAssigned,
|
||||
'submission_status' => (object) [
|
||||
'label' => $submissionLabel,
|
||||
'color' => $submissionColor,
|
||||
'icon' => $submissionIcon,
|
||||
'classes' => Arr::toCssClasses([
|
||||
'inline-flex items-center gap-1 rounded-full px-2.5 py-0.5 text-xs font-semibold', // font-semibold for clarity
|
||||
'inline-flex items-center gap-1 rounded-full px-2.5 py-0.5 text-xs font-semibold',
|
||||
'bg-success-100 text-success-700 dark:bg-success-900/30 dark:text-success-400' => $submissionColor === 'success',
|
||||
'bg-danger-100 text-danger-700 dark:bg-danger-900/30 dark:text-danger-400' => $submissionColor === 'danger',
|
||||
'bg-warning-100 text-warning-700 dark:bg-warning-900/30 dark:text-warning-400' => $submissionColor === 'warning',
|
||||
@ -346,7 +364,7 @@ public function assignmentCards()
|
||||
'color' => $deliveryColor,
|
||||
'icon' => $deliveryIcon,
|
||||
'classes' => Arr::toCssClasses([
|
||||
'inline-flex items-center gap-1 rounded-full px-2.5 py-0.5 text-xs font-bold ring-1 ring-inset', // font-bold and ring for "delivery" status to make it pop
|
||||
'inline-flex items-center gap-1 rounded-full px-2.5 py-0.5 text-xs font-bold ring-1 ring-inset',
|
||||
'bg-success-50 text-success-700 ring-success-600/20 dark:bg-success-900/10 dark:text-success-400 dark:ring-success-500/20' => $deliveryColor === 'success',
|
||||
'bg-amber-50 text-amber-700 ring-amber-600/20 dark:bg-amber-900/10 dark:text-amber-400 dark:ring-amber-500/20' => $deliveryColor === 'amber',
|
||||
]),
|
||||
@ -355,15 +373,17 @@ public function assignmentCards()
|
||||
// Pre-calculated classes
|
||||
'card_classes' => Arr::toCssClasses([
|
||||
'group flex w-full rounded-xl border transition-all overflow-hidden relative',
|
||||
'border-primary-300 dark:border-primary-700 bg-primary-50/30 dark:bg-primary-900/10 shadow-sm' => $isPinned,
|
||||
'border-gray-200 dark:border-gray-700 bg-white dark:bg-gray-800' => ! $isPinned && $canSubmitActual,
|
||||
'border-gray-100 dark:border-gray-800 bg-gray-50 dark:bg-gray-800/40 opacity-80' => ! $canSubmitActual,
|
||||
'border-dashed border-gray-300 dark:border-gray-700 bg-gray-50/50 dark:bg-gray-800/10 opacity-75' => ! $isAssigned,
|
||||
'border-primary-300 dark:border-primary-700 bg-primary-50/30 dark:bg-primary-900/10 shadow-sm' => $isAssigned && $isPinned,
|
||||
'border-gray-200 dark:border-gray-700 bg-white dark:bg-gray-800' => $isAssigned && ! $isPinned && $canSubmitActual,
|
||||
'border-gray-100 dark:border-gray-800 bg-gray-50 dark:bg-gray-800/40 opacity-80' => $isAssigned && ! $isPinned && ! $canSubmitActual,
|
||||
]),
|
||||
'icon_wrapper_classes' => Arr::toCssClasses([
|
||||
'flex h-11 w-11 shrink-0 items-center justify-center rounded-lg',
|
||||
'bg-success-50 dark:bg-success-900/20 text-success-600 dark:text-success-400' => $isSubmitted,
|
||||
'bg-danger-50 dark:bg-danger-900/20 text-danger-600 dark:text-danger-400' => ! $isSubmitted && $isOverdue,
|
||||
'bg-warning-50 dark:bg-warning-900/20 text-warning-600 dark:text-warning-400' => ! $isSubmitted && ! $isOverdue,
|
||||
'bg-gray-100 dark:bg-gray-800 text-gray-400' => ! $isAssigned,
|
||||
'bg-success-50 dark:bg-success-900/20 text-success-600 dark:text-success-400' => $isAssigned && $isSubmitted,
|
||||
'bg-danger-50 dark:bg-danger-900/20 text-danger-600 dark:text-danger-400' => $isAssigned && ! $isSubmitted && $isOverdue,
|
||||
'bg-warning-50 dark:bg-warning-900/20 text-warning-600 dark:text-warning-400' => $isAssigned && ! $isSubmitted && ! $isOverdue,
|
||||
]),
|
||||
'indicator_icon_classes' => Arr::toCssClasses([
|
||||
'h-5 w-5 opacity-20',
|
||||
|
||||
@ -101,7 +101,7 @@ public function statusCards(): array
|
||||
}
|
||||
|
||||
#[Computed]
|
||||
public function student(): Student
|
||||
public function student(): ?Student
|
||||
{
|
||||
/** @var User|null $user */
|
||||
$user = Auth::user();
|
||||
@ -152,9 +152,28 @@ public function isOverdue(): bool
|
||||
return now()->isAfter($this->record?->due_date);
|
||||
}
|
||||
|
||||
#[Computed]
|
||||
public function isAssigned(): bool
|
||||
{
|
||||
$student = $this->student;
|
||||
if (! $student) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($this->record?->type === AssignmentType::Individual) {
|
||||
return $this->record?->students()->whereKey($student->id)->exists();
|
||||
}
|
||||
|
||||
return $this->currentGroup !== null;
|
||||
}
|
||||
|
||||
#[Computed]
|
||||
public function canSubmit(): bool
|
||||
{
|
||||
if (! $this->isAssigned) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($this->record?->type === AssignmentType::Individual) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -38,6 +38,12 @@ class="inline-flex items-center gap-1.5 rounded-full bg-primary-100 text-primary
|
||||
📌 Dipinned
|
||||
</span>
|
||||
@endif
|
||||
@if (isset($card->is_assigned) && ! $card->is_assigned)
|
||||
<span
|
||||
class="inline-flex items-center gap-1.5 rounded-full bg-gray-100 text-gray-700 dark:bg-gray-800 dark:text-gray-300 px-2.5 py-1 text-xs font-bold whitespace-nowrap border border-gray-200 dark:border-gray-700">
|
||||
🚫 Tidak Ditugaskan
|
||||
</span>
|
||||
@endif
|
||||
@if ($card->is_new)
|
||||
<span
|
||||
class="inline-flex items-center gap-1.5 rounded-full bg-violet-100 text-violet-700 dark:bg-violet-900/30 dark:text-violet-400 px-2.5 py-1 text-xs font-bold whitespace-nowrap border border-violet-200/50 dark:border-violet-500/20">
|
||||
|
||||
@ -105,6 +105,17 @@ class="block border-0"></iframe>
|
||||
</div>
|
||||
@endif
|
||||
</x-filament::section>
|
||||
@elseif (!$this->isAssigned)
|
||||
<x-filament::section>
|
||||
<div
|
||||
class="flex flex-col items-center justify-center py-8 text-center text-gray-500 dark:text-gray-400">
|
||||
<x-filament::icon icon="heroicon-o-x-circle" class="w-12 h-12 mb-3 text-gray-400" />
|
||||
<p class="font-semibold text-gray-700 dark:text-gray-300">Anda Tidak Ditugaskan</p>
|
||||
<p class="text-sm mt-1 max-w-sm">
|
||||
Anda dapat melihat detail tugas ini karena role Anda (Kosma/Developer), tetapi Anda tidak ditugaskan untuk mengumpulkannya.
|
||||
</p>
|
||||
</div>
|
||||
</x-filament::section>
|
||||
@elseif (!$this->canSubmit)
|
||||
<x-filament::section>
|
||||
<div
|
||||
|
||||
Loading…
Reference in New Issue
Block a user