@extends('layouts.master') @section('title') {{ __('Requester Dashboard') }} @endsection @section('css') @endsection @section('content') @component('components.breadcrumb') @slot('li_1') {{ __('Requester') }} @endslot @slot('title') {{ __('Dashboard') }} @endslot @endcomponent @php $viewerId = (int) (Auth::id() ?? 0); $viewerRole = (string) (Auth::user()->role ?? ''); $viewerOrganization = strtolower(trim((string) (Auth::user()->organization_name ?? ''))); $canReviewDocument = \App\Support\WorkflowPermission::canUseAdminPermission($viewerRole, \App\Support\WorkflowPermission::ADMIN_PERMISSION_REVIEW_DOCUMENT); $canRequestDocument = \App\Support\WorkflowPermission::canUseAdminPermission($viewerRole, \App\Support\WorkflowPermission::ADMIN_PERMISSION_REQUEST_DOCUMENT); $isSentBackByViewer = function ($request) use ($viewerId) { $latestHistory = $request->latestHistory; return (string) ($latestHistory?->action ?? '') === \App\Support\WorkflowPermission::ACTION_REQUEST_REVISION && $viewerId > 0 && (int) ($latestHistory?->actor_user_id ?? 0) === $viewerId; }; $isRequesterSideCorrection = function ($request) use ($viewerId) { $latestHistory = $request->latestHistory; $latestMeta = is_array($latestHistory?->meta) ? $latestHistory->meta : []; $targetType = strtolower(trim((string) data_get($latestMeta, 'sent_back_target_type', ''))); $targetStepOrder = (int) data_get($latestMeta, 'sent_back_selected_target_step_order', 0); $targetUserId = (int) data_get( $latestMeta, 'sent_back_to_user_id', data_get($latestMeta, 'sent_back_selected_target_user_id', 0) ); $isRequesterTarget = in_array($targetType, ['requester', 'user'], true) || ($targetType === '' && $targetStepOrder <= 0 && $targetUserId === $viewerId); return (string) ($latestHistory?->action ?? '') === \App\Support\WorkflowPermission::ACTION_REQUEST_REVISION && (int) ($request->user_id ?? 0) === $viewerId && $targetStepOrder <= 0 && $isRequesterTarget && ($targetUserId === 0 || $targetUserId === $viewerId); }; $workStatusFor = function ($request) use ($viewerRole, $viewerId, $isRequesterSideCorrection, $isSentBackByViewer) { if ($isSentBackByViewer($request)) { return [ 'label' => 'Sent Back by You', 'badge' => \App\Support\WorkflowPermission::dashboardStatusBadgeClass('Sent Back by You'), 'title' => '', ]; } if ($isRequesterSideCorrection($request)) { return [ 'label' => 'In Progress', 'badge' => \App\Support\WorkflowPermission::dashboardStatusBadgeClass('In Progress'), 'title' => '', ]; } return \App\Support\WorkflowPermission::dashboardStatus($request, $viewerRole, $viewerId); }; $requestStatusFor = function ($request) use ($viewerId) { $status = \App\Support\WorkflowPermission::dashboardStatus($request, \App\Support\WorkflowPermission::ROLE_REQUESTER, $viewerId); if (!in_array($status['label'], ['Sent Back to You', 'Completed', 'Rejected'], true)) { $status['label'] = 'In Progress'; $status['badge'] = \App\Support\WorkflowPermission::dashboardStatusBadgeClass('In Progress'); $status['title'] = ''; } return $status; }; $personalRequests = $requests->filter(fn ($request) => (int) ($request->user_id ?? 0) === $viewerId)->values(); $workflowStepsFor = function ($request): array { $steps = $request->workflow_steps_override; if (!is_array($steps) || count($steps) === 0) { $templateSteps = $request->workflowTemplate?->steps ?? []; if (is_string($templateSteps)) { $decoded = json_decode($templateSteps, true); $templateSteps = is_array($decoded) ? $decoded : []; } $steps = is_array($templateSteps) ? $templateSteps : []; } return collect($steps) ->filter(fn ($step) => is_array($step)) ->sortBy(fn ($step) => (int) ($step['order'] ?? 0)) ->values() ->all(); }; $workflowIncludesViewerReviewStage = function ($request) use ($viewerId, $viewerRole, $viewerOrganization, $workflowStepsFor): bool { $viewerRoleKey = \App\Support\WorkflowPermission::normalizeRole($viewerRole); return collect($workflowStepsFor($request))->contains(function ($step) use ($viewerId, $viewerRoleKey, $viewerOrganization) { $permissionType = strtolower(trim((string) ($step['permission_type'] ?? ''))); $stepType = strtolower(trim((string) ($step['step_type'] ?? ''))); $actorRole = \App\Support\WorkflowPermission::normalizeRole((string) ($step['actor_role'] ?? '')); $stepOrganization = strtolower(trim((string) ($step['organization_name'] ?? $step['office_name'] ?? ''))); $assignedUserId = (int) ($step['rector_user_id'] ?? $step['assigned_user_id'] ?? 0); $isReviewOrApprovalStage = in_array($permissionType, ['reviewer', 'approver'], true) || in_array($stepType, ['organization', 'office', 'vice_rector', 'approval'], true) || in_array($actorRole, [ \App\Support\WorkflowPermission::ROLE_RECTOR, \App\Support\WorkflowPermission::ROLE_VICE_RECTOR, ], true); if (!$isReviewOrApprovalStage) { return false; } if ($viewerOrganization !== '' && $stepOrganization !== '' && $stepOrganization === $viewerOrganization) { return true; } if ($viewerId > 0 && $assignedUserId === $viewerId) { return true; } return $assignedUserId <= 0 && $viewerRoleKey !== '' && $actorRole !== '' && $actorRole === $viewerRoleKey; }); }; $workRequests = $canReviewDocument ? $requests->filter(function ($request) use ($isRequesterSideCorrection, $isSentBackByViewer, $workflowIncludesViewerReviewStage) { if ($isRequesterSideCorrection($request) && !$isSentBackByViewer($request)) { return false; } return $workflowIncludesViewerReviewStage($request); })->values() : collect(); $hasDashboardTabs = $canReviewDocument && $canRequestDocument; $requestedDashboardTab = (string) request()->query('view', ''); $activeDashboardTab = $hasDashboardTabs ? (in_array($requestedDashboardTab, ['work', 'requests'], true) ? $requestedDashboardTab : 'work') : ($canReviewDocument ? 'work' : 'requests'); $tableRequests = $activeDashboardTab === 'work' ? $workRequests : $personalRequests; $dashboardStatusFor = $activeDashboardTab === 'work' ? $workStatusFor : $requestStatusFor; $tableStatusCounts = $tableRequests ->map(fn ($request) => $dashboardStatusFor($request)['label']) ->countBy(); $tableTitle = $activeDashboardTab === 'work' ? 'Documents for Review' : 'Submitted Documents'; $emptyTableMessage = $activeDashboardTab === 'work' ? 'No work queue documents found.' : 'No requests submitted yet.'; $rowNewUpdateLabels = [ 'Needs Your Review', 'Need Your Decision', 'Returned Back', 'Sent Back to You', 'Sent Back to My Organization', ]; $rowHighlightForView = function ($request, string $view) use ( $viewerRole, $viewerId, $workStatusFor, $requestStatusFor, $rowNewUpdateLabels ): array { $status = $view === 'work' ? $workStatusFor($request) : $requestStatusFor($request); $baseViewerStatus = \App\Support\WorkflowPermission::dashboardStatus($request, $viewerRole, $viewerId); $isOverdue = \App\Support\WorkflowPermission::isDashboardOverdue($request) && ( $view === 'requests' || in_array( (string) ($baseViewerStatus['label'] ?? ''), ['Needs Your Review', 'Need Your Decision'], true ) ); $isNew = (bool) ($request->dashboard_has_unread_update ?? false) && in_array((string) ($status['label'] ?? ''), $rowNewUpdateLabels, true); return [ 'overdue' => $isOverdue, 'unread' => $isNew, 'highlighted' => $isOverdue || $isNew, ]; }; $workTabCount = $workRequests ->filter(fn ($request) => $rowHighlightForView($request, 'work')['highlighted']) ->count(); $requestTabCount = $personalRequests ->filter(fn ($request) => $rowHighlightForView($request, 'requests')['highlighted']) ->count(); $activeRowHighlightResolver = fn ($request) => $rowHighlightForView($request, $activeDashboardTab); $workQueueCards = [ [ 'label' => 'Needs Your Review', 'count' => (int) ($tableStatusCounts['Needs Your Review'] ?? 0), 'description' => 'Documents you can act on now', 'icon' => 'ri-file-search-line', 'color' => 'primary', ], [ 'label' => 'Sent Back to My Organization', 'count' => (int) ($tableStatusCounts['Sent Back to My Organization'] ?? 0), 'description' => 'Sent back for revision', 'icon' => 'ri-arrow-go-back-line', 'color' => 'warning', ], [ 'label' => 'Sent Back by You', 'count' => (int) ($tableStatusCounts['Sent Back by You'] ?? 0), 'description' => 'Waiting for the target to return it', 'icon' => 'ri-time-line', 'color' => 'warning', ], [ 'label' => 'Forwarded', 'count' => (int) ($tableStatusCounts['Forwarded'] ?? 0), 'description' => 'Already forwarded to the next step', 'icon' => 'ri-share-forward-line', 'color' => 'success', ], [ 'label' => 'Approved', 'count' => (int) ($tableStatusCounts['Approved'] ?? 0), 'description' => 'Approved documents', 'icon' => 'ri-check-line', 'color' => 'primary', ], [ 'label' => 'Overdue SLA', 'count' => (int) ($tableStatusCounts['Overdue SLA'] ?? 0), 'description' => 'Past SLA time', 'icon' => 'ri-alarm-warning-line', 'color' => 'danger', ], [ 'label' => 'Completed', 'count' => (int) ($tableStatusCounts['Completed'] ?? 0), 'description' => 'Completed work queue documents', 'icon' => 'ri-check-double-line', 'color' => 'success', ], [ 'label' => 'Rejected', 'count' => (int) ($tableStatusCounts['Rejected'] ?? 0), 'description' => 'Rejected work queue documents', 'icon' => 'ri-close-line', 'color' => 'danger', ], ]; $myRequestCards = [ [ 'label' => 'Total Submitted', 'count' => $personalRequests->count(), 'description' => 'Documents you created', 'icon' => 'ri-file-add-line', 'color' => 'info', ], [ 'label' => 'In Progress', 'count' => (int) ($tableStatusCounts['In Progress'] ?? 0) + (int) ($tableStatusCounts['Forwarded'] ?? 0) + (int) ($tableStatusCounts['Approved'] ?? 0) + (int) ($tableStatusCounts['Needs Your Review'] ?? 0) + (int) ($tableStatusCounts['Overdue SLA'] ?? 0), 'description' => 'Still moving through workflow', 'icon' => 'ri-loader-4-line', 'color' => 'warning', ], [ 'label' => 'Sent Back to Me', 'count' => (int) ($tableStatusCounts['Sent Back to You'] ?? 0), 'description' => 'Needs your revision', 'icon' => 'ri-arrow-go-back-line', 'color' => 'warning', ], [ 'label' => 'Completed', 'count' => (int) ($tableStatusCounts['Completed'] ?? 0), 'description' => 'Finished successfully', 'icon' => 'ri-check-double-line', 'color' => 'success', ], [ 'label' => 'Rejected', 'count' => (int) ($tableStatusCounts['Rejected'] ?? 0), 'description' => 'Rejected documents', 'icon' => 'ri-close-line', 'color' => 'danger', ], ]; $workStatusFilterMap = collect($workQueueCards) ->mapWithKeys(fn ($card) => [$card['label'] => [$card['label']]]) ->all(); $requestStatusFilterMap = [ 'In Progress' => ['In Progress', 'Forwarded', 'Approved', 'Needs Your Review', 'Overdue SLA'], 'Sent Back to Me' => ['Sent Back to You'], 'Completed' => ['Completed'], 'Rejected' => ['Rejected'], ]; $activeStatusFilterMap = $activeDashboardTab === 'work' ? $workStatusFilterMap : $requestStatusFilterMap; $dashboardChartColors = ['primary', 'success', 'warning', 'info', 'danger', 'secondary']; $dashboardChartCards = $tableRequests ->groupBy(fn ($request) => trim((string) ($request->document_type_label ?: $request->document_type ?: __('N/A')))) ->map(fn ($items, $label) => [ 'label' => $label !== '' ? $label : __('N/A'), 'key' => md5(mb_strtolower((string) ($label !== '' ? $label : __('N/A')))), 'count' => $items->count(), ]) ->sortByDesc('count') ->values() ->map(function ($card, $index) use ($dashboardChartColors) { $card['color'] = $dashboardChartColors[$index % count($dashboardChartColors)]; return $card; }) ->all(); $dashboardChartMax = max(1, (int) collect($dashboardChartCards)->max('count')); @endphp @if($hasDashboardTabs) @endif
@if($canReviewDocument && $activeDashboardTab === 'work')
@foreach($workQueueCards as $card) @php $cardColor = \App\Support\BadgeStyle::statusColor((string) ($card['label'] ?? ''), (string) ($card['color'] ?? 'primary')); @endphp

{{ __($card['label']) }}

{{ (int) $card['count'] }}

{{ __($card['description']) }}

@endforeach
@endif @if($canRequestDocument && $activeDashboardTab === 'requests')
@foreach($myRequestCards as $card) @php $cardColor = \App\Support\BadgeStyle::statusColor((string) ($card['label'] ?? ''), (string) ($card['color'] ?? 'primary')); @endphp

{{ __($card['label']) }}

{{ (int) $card['count'] }}

{{ __($card['description']) }}

@endforeach
@endif
@endsection @section('script') @endsection