@extends('layouts.dashboard')
@section('title', 'Proj Mgr - ' . $sprint->name)
@section('content')
@php
$taskCount = $sprint->tasks->count();
$doneCount = $sprint->tasks->where('task_status', 'approved')->count();
$visibleTaskCount = $taskCount - $doneCount; // default: hide completed is checked
$progress = $taskCount > 0 ? round(($doneCount / $taskCount) * 100) : 0;
$statusColor = match($sprint->status) {
'active' => 'bg-green-100 text-green-800 border-green-200',
'completed' => 'bg-blue-100 text-blue-800 border-blue-200',
default => 'bg-yellow-100 text-yellow-800 border-yellow-200',
};
$userRoleNames = auth()->user()
? auth()->user()->roles->pluck('name')->map(fn($r) => strtolower($r))->all()
: [];
$isMasterAdmin = in_array('master admin', $userRoleNames) || in_array('master_admin', $userRoleNames);
$priorityOrder = ['urgent' => 0, 'high' => 1, 'medium' => 2, 'low' => 3];
$treeData = [];
foreach ($projects as $proj) {
$projNode = ['id' => $proj->id, 'name' => $proj->name, 'lists' => []];
// Sort task lists alphabetically
$sortedLists = $proj->taskLists->sortBy('name');
foreach ($sortedLists as $list) {
$listNode = ['id' => $list->id, 'name' => $list->name, 'tasks' => []];
// Sort tasks: priority first, then alphabetically by title
$sortedTasks = $list->tasks->sortBy([
fn($a, $b) => ($priorityOrder[$a->priority ?? 'medium'] ?? 2)
<=> ($priorityOrder[$b->priority ?? 'medium'] ?? 2),
fn($a, $b) => strcasecmp($a->title, $b->title),
]);
foreach ($sortedTasks as $task) {
$listNode['tasks'][] = [
'id' => $task->id,
'title' => $task->title,
'priority' => $task->priority ?? 'medium',
'status' => $task->task_status ?? 'pending',
'projectName' => $proj->name,
'listName' => $list->name,
];
}
if (!empty($listNode['tasks'])) {
$projNode['lists'][] = $listNode;
}
}
if (!empty($projNode['lists'])) {
$treeData[] = $projNode;
}
}
// Sort projects alphabetically
usort($treeData, fn($a, $b) => strcasecmp($a['name'], $b['name']));
// Group sprint tasks by project → task list (sorted alpha, tasks by priority then alpha)
$grouped = $sprint->tasks
->sortBy([
fn($a, $b) => ($priorityOrder[$a->priority ?? 'medium'] ?? 2)
<=> ($priorityOrder[$b->priority ?? 'medium'] ?? 2),
fn($a, $b) => strcasecmp($a->title, $b->title),
])
->groupBy([
fn($t) => $t->project?->name ?? 'No Project',
fn($t) => $t->taskList?->name ?? 'No Task List',
]);
$grouped = $grouped->sortKeys();
$grouped = $grouped->map(fn($lists) => $lists->sortKeys());
@endphp
Sprints
{{ $sprint->name }}
{{ ucfirst($sprint->status) }}
@if($isMasterAdmin)
@endif
@if($sprint->goal)
{{ $sprint->goal }}
@endif
{{ $sprint->start_date->format('M d, Y') }} – {{ $sprint->end_date->format('M d, Y') }}
{{ $visibleTaskCount }} {{ Str::plural('task', $visibleTaskCount) }}
{{ $doneCount }} completed
@if($taskCount > 0)
@endif
@if(session('success'))
{{ session('success') }}
@endif
Add Tasks to Sprint
( selected)
Selected
Click tasks on the right
to select them
No tasks available to add
task(s) selected
@if($sprint->tasks->isEmpty())
No tasks in this sprint yet.
Click Add Task above to assign tasks to this sprint.
@else
@php
$priBadge = fn($p) => match($p ?? 'medium') {
'urgent' => 'bg-red-100 text-red-800 border-red-200',
'high' => 'bg-orange-100 text-orange-800 border-orange-200',
'medium' => 'bg-yellow-100 text-yellow-800 border-yellow-200',
default => 'bg-green-100 text-green-800 border-green-200',
};
$statusBadge = fn($s) => match($s ?? 'pending') {
'pending' => 'bg-gray-500 text-white border-gray-600',
'in_progress' => 'bg-blue-100 text-blue-800 border-blue-200',
'completed_pending_review' => 'bg-yellow-100 text-yellow-800 border-yellow-200',
'approved' => 'bg-green-100 text-green-800 border-green-200',
'unapproved' => 'bg-red-100 text-red-800 border-red-200',
'deployed' => 'bg-purple-100 text-purple-800 border-purple-200',
default => 'bg-gray-100 text-gray-800 border-gray-200',
};
$taskTypeEmoji = fn($t) => match($t ?? 'general') {
'equipmentId' => '🔧',
'customerName' => '👤',
default => '📝',
};
@endphp
@foreach($grouped as $projectName => $lists)
@foreach($lists as $listName => $listTasks)
@php $listColor = $listTasks->first()?->taskList?->color ?? 'bg-gray-50'; @endphp
{{ $listName }}
{{ $listTasks->count() }} {{ Str::plural('task', $listTasks->count()) }}
@foreach($listTasks as $task)
@php
$isOverdue = $task->due_date && $task->due_date->isPast()
&& !in_array($task->task_status ?? 'pending', ['approved','deployed']);
$descText = $task->description ? Str::limit(strip_tags($task->description), 70) : null;
@endphp
{{ ucfirst($task->priority ?? 'medium') }}
@if($task->task_status === 'completed_pending_review') Review
@else {{ ucfirst(str_replace('_', ' ', $task->task_status ?? 'pending')) }}
@endif
@if($descText)
{{ $descText }}
@endif
@if($task->assignedUser)
{{ strtoupper(substr($task->assignedUser->first_name, 0, 1)) }}
{{ $task->assignedUser->first_name }}
@endif
@if($task->due_date)
{{ $task->due_date->format('M j') }}
@endif
@endforeach
@endforeach
@endforeach
@foreach($grouped as $projectName => $lists)
@foreach($lists as $listName => $listTasks)
@php $listColor = $listTasks->first()?->taskList?->color ?? 'bg-gray-50'; @endphp
{{ $listName }}
{{ $listTasks->count() }} {{ Str::plural('task', $listTasks->count()) }}
@foreach($listTasks as $task)
@php
$isOverdue = $task->due_date && $task->due_date->isPast()
&& !in_array($task->task_status ?? 'pending', ['approved','deployed']);
$descText = $task->description ? Str::limit(strip_tags($task->description), 100) : null;
@endphp
{{ $taskTypeEmoji($task->task_type) }}
{{ ucfirst($task->priority ?? 'medium') }}
@if($task->task_status === 'completed_pending_review') Review
@else {{ ucfirst(str_replace('_', ' ', $task->task_status ?? 'pending')) }}
@endif
@if($descText)
{{ $descText }}
@endif
@if($task->assignedUser)
{{ strtoupper(substr($task->assignedUser->first_name, 0, 2)) }}
{{ $task->assignedUser->first_name }} {{ $task->assignedUser->last_name }}
@else
Unassigned
@endif
@if($task->due_date)
Due: {{ $task->due_date->format('M j') }}
@endif
@endforeach
@endforeach
@endforeach
No tasks match the current filters.
@endif
@push('scripts')
@endpush
@endsection