@extends('layouts.master')
@section('title')
{{ __('Rector Dashboard') }}
@endsection
@section('css')
@endsection
@section('content')
@component('components.breadcrumb')
@slot('li_1') {{ __('Rector') }} @endslot
@slot('title') {{ __('Dashboard') }} @endslot
@endcomponent
@php
$viewerId = (int) (Auth::id() ?? 0);
$viewerRole = (string) (Auth::user()->role ?? 'rector');
$decisionStatusLabel = 'Need Your Decision';
$sentBackStatusLabel = 'Sent Back by You';
$canRequestDocument = \App\Support\WorkflowPermission::canUseAdminPermission($viewerRole, \App\Support\WorkflowPermission::ADMIN_PERMISSION_REQUEST_DOCUMENT);
$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);
};
$syncRectorKpiStatus = function (array $status) use ($decisionStatusLabel, $sentBackStatusLabel) {
if (in_array($status['label'], ['Needs Your Review', 'Overdue SLA', 'Returned Back'], true)) {
$status['label'] = $decisionStatusLabel;
$status['badge'] = \App\Support\WorkflowPermission::dashboardStatusBadgeClass('Needs Your Review');
}
if ($status['label'] === 'Approved') {
$status['badge'] = 'bg-primary-subtle text-primary';
}
if (in_array($status['label'], ['Sent Back by You', 'Sent Back to You', 'Sent Back to My Organization'], true)) {
$status['label'] = $sentBackStatusLabel;
$status['badge'] = \App\Support\WorkflowPermission::dashboardStatusBadgeClass('Sent Back by You');
}
return $status;
};
$workStatusFor = function ($request) use ($viewerRole, $viewerId, $syncRectorKpiStatus, $isRequesterSideCorrection) {
if ($isRequesterSideCorrection($request)) {
return [
'label' => 'In Progress',
'badge' => \App\Support\WorkflowPermission::dashboardStatusBadgeClass('In Progress'),
'title' => '',
];
}
$status = \App\Support\WorkflowPermission::dashboardStatus($request, $viewerRole, $viewerId);
return $syncRectorKpiStatus($status);
};
$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;
};
$allRequests = collect($requests ?? []);
$personalRequests = $allRequests->filter(fn ($request) => (int) ($request->user_id ?? 0) === $viewerId)->values();
$workRequests = $allRequests->filter(function ($request) use ($viewerId, $isRequesterSideCorrection) {
if ($isRequesterSideCorrection($request)) {
return false;
}
return (int) ($request->user_id ?? 0) !== $viewerId
|| (int) ($request->current_holder_user_id ?? 0) === $viewerId
|| (int) optional($request->latestHistory)->actor_user_id === $viewerId;
})->values();
$hasDashboardTabs = $canRequestDocument;
$requestedDashboardTab = (string) request()->query('view', '');
$activeDashboardTab = $hasDashboardTabs && $requestedDashboardTab === 'requests' ? 'requests' : 'work';
$tableRequests = $activeDashboardTab === 'work' ? $workRequests : $personalRequests;
$dashboardStatusFor = $activeDashboardTab === 'work' ? $workStatusFor : $requestStatusFor;
$statusCounts = $tableRequests->map(fn ($request) => $dashboardStatusFor($request)['label'])->countBy();
$isUnreadAttentionForViewer = function ($request) use ($viewerId): bool {
$latestHistory = $request->latestHistory;
return $latestHistory !== null
&& !(bool) ($latestHistory->is_read ?? false)
&& (int) ($latestHistory->actor_user_id ?? 0) !== $viewerId
&& $latestHistory->hasNotificationRecipient($viewerId, Auth::user());
};
$workTabAttentionCount = $workRequests
->filter(function ($request) use ($workStatusFor, $decisionStatusLabel, $isUnreadAttentionForViewer) {
return \App\Support\WorkflowPermission::isDashboardOverdue($request)
|| (in_array($workStatusFor($request)['label'], [
$decisionStatusLabel,
'Returned Back',
'Sent Back to You',
'Sent Back to My Organization',
], true) && $isUnreadAttentionForViewer($request));
})
->count();
$requestTabAttentionCount = $personalRequests
->filter(function ($request) use ($viewerId, $isUnreadAttentionForViewer) {
$status = \App\Support\WorkflowPermission::dashboardStatus(
$request,
\App\Support\WorkflowPermission::ROLE_REQUESTER,
$viewerId
);
return \App\Support\WorkflowPermission::isDashboardOverdue($request)
|| ($status['label'] === 'Sent Back to You' && $isUnreadAttentionForViewer($request));
})
->count();
$tableTitle = $activeDashboardTab === 'work' ? 'Documents for Review and Decision' : 'Submitted Documents';
$statusFilterMap = $activeDashboardTab === 'work'
? [
$decisionStatusLabel => [$decisionStatusLabel],
'Approved' => ['Approved'],
$sentBackStatusLabel => [$sentBackStatusLabel],
'Completed' => ['Completed'],
'Rejected' => ['Rejected'],
]
: [
'In Progress' => ['In Progress'],
'Sent Back to Me' => ['Sent Back to You'],
'Completed' => ['Completed'],
'Rejected' => ['Rejected'],
];
$workKpiCards = [
[
'label' => $decisionStatusLabel,
'count' => $activeDashboardTab === 'work' ? (int) ($statusCounts[$decisionStatusLabel] ?? 0) : $tableRequests->count(),
'description' => 'Waiting for your review',
'icon' => 'ri-archive-line',
'color' => 'info',
],
[
'label' => 'Approved',
'count' => (int) ($statusCounts['Approved'] ?? 0),
'description' => 'Approved documents',
'icon' => 'ri-check-line',
'color' => 'primary',
],
[
'label' => $sentBackStatusLabel,
'count' => (int) ($statusCounts[$sentBackStatusLabel] ?? 0),
'description' => 'Sent back for revision',
'icon' => 'ri-arrow-go-back-line',
'color' => 'warning',
],
[
'label' => 'Completed',
'count' => (int) ($statusCounts['Completed'] ?? 0),
'description' => 'Completed documents',
'icon' => 'ri-checkbox-circle-line',
'color' => 'success',
],
[
'label' => 'Rejected',
'count' => (int) ($statusCounts['Rejected'] ?? 0),
'description' => 'Rejected documents',
'icon' => 'ri-close-line',
'color' => 'danger',
],
];
$myRequestKpiCards = [
[
'label' => 'Total Submitted',
'count' => $personalRequests->count(),
'description' => 'Documents you created',
'icon' => 'ri-file-add-line',
'color' => 'info',
],
[
'label' => 'In Progress',
'count' => (int) ($statusCounts['In Progress'] ?? 0),
'description' => 'Still moving through workflow',
'icon' => 'ri-loader-4-line',
'color' => 'warning',
],
[
'label' => 'Sent Back to Me',
'count' => (int) ($statusCounts['Sent Back to You'] ?? 0),
'description' => 'Needs your revision',
'icon' => 'ri-arrow-go-back-line',
'color' => 'warning',
],
[
'label' => 'Completed',
'count' => (int) ($statusCounts['Completed'] ?? 0),
'description' => 'Finished successfully',
'icon' => 'ri-check-double-line',
'color' => 'success',
],
[
'label' => 'Rejected',
'count' => (int) ($statusCounts['Rejected'] ?? 0),
'description' => 'Rejected documents',
'icon' => 'ri-close-line',
'color' => 'danger',
],
];
$dashboardKpiCards = $activeDashboardTab === 'work' ? $workKpiCards : $myRequestKpiCards;
$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
@foreach($dashboardKpiCards as $card)
@php
$cardColor = \App\Support\BadgeStyle::statusColor((string) ($card['label'] ?? ''), (string) ($card['color'] ?? 'primary'));
@endphp
{{ __($card['label']) }}
{{ (int) $card['count'] }}
{{ __($card['description']) }}
@endforeach
@endsection
@section('script')
@endsection