@extends('layouts.app') @php // HH:MM everywhere — see App\Support\Duration. The consolidated sheet // carried seconds, but the agent checkpoints every five minutes, so that // precision was never real. $hms = fn ($sec) => \App\Support\Duration::hhmmOrDash((int) $sec); // Tiles and the bar chart read on their own, so they take the compact // form; the table below stays HH:MM so its columns line up. $hm = fn ($sec) => \App\Support\Duration::compact((int) $sec); $pct = fn ($v) => $v === null ? '—' : rtrim(rtrim(number_format($v, 1), '0'), '.') . '%'; // The same figure without the sign, for CSV. A spreadsheet reads "62.5%" as // text and will not average a column of it; on screen the sign is a label, // in a file it is in the way. $pctRaw = fn ($v) => $v === null ? '—' : rtrim(rtrim(number_format($v, 1), '0'), '.'); @endphp @section('header')
Reports

People Summary

{{ $from->toDateString() === $to->toDateString() ? $from->format('D, d M Y') : $from->format('d M Y') . ' → ' . $to->format('d M Y') }} · {{ $totals['people'] }} {{ Str::plural('person', $totals['people']) }}
@endsection @section('content') {{-- Filters — same contract as the Timesheet (?from=&to=&q=&status=). --}}
{{-- Display only; the hidden inputs carry the real values so the page still submits its range without JS. --}}
@if ($q !== '' || $status !== \App\Support\EmployeeStatus::ACTIVE || request()->hasAny(['from', 'to'])) @endif
@if ($rows->isEmpty())

Nothing tracked in this range

No employee recorded time between those dates.

@else @php $timerTotal = max(1, $totals['timer_sec']); // guard the divisions $idleShare = $totals['idle_sec'] / $timerTotal * 100; $workShare = 100 - $idleShare; // Donut geometry: one circle, one dash offset. Cheaper and sharper than // a charting library, and it inherits the theme's colours for free. $r = 52; $circ = 2 * M_PI * $r; @endphp
{{-- Headline tiles --}}
{{ $hm($totals['timer_sec']) }}
Total Time
{{ $pct($totals['activity_pct']) }}
Average Activity
{{ $hm($totals['idle_sec']) }}
Idle
{{-- Time split: tracked vs the gaps inside it --}}

Tracked vs Idle

{{ round($workShare) }}% tracked
Time Ex. Idle {{ $hm($totals['ex_idle_sec']) }}
Idle {{ $hm($totals['idle_sec']) }}
{{-- Who tracked the most. Ten bars, because more is unreadable and the table below already carries everyone. --}}

Top tracked

by total time
@php $peak = max(1, (int) $chartRows->max('timer_sec')); @endphp @foreach ($chartRows as $c)
{{ $c['name'] }}
{{ $hm($c['timer_sec']) }}
@endforeach
@foreach ($rows as $r2) {{-- Activity and Idle(%) are complements of one another, so the pair always totals 100 — the same reading the hand-built sheet gives. A dash means the range predates measurement, which is not 0%. --}} @endforeach
User Activity Level Idle (%) Timer Idle Total Ex. Idle
{{ $r2['name'] }}
{{ $r2['employee_id'] ?: $r2['designation'] ?: '—' }} · {{ $r2['shifts'] }} {{ Str::plural('shift', $r2['shifts']) }}
@include('reports._ps-meter', ['value' => $r2['activity_pct'], 'colour' => 'green']) @include('reports._ps-meter', ['value' => $r2['idle_pct'], 'colour' => 'yellow']) {{ $hms($r2['timer_sec']) }} {{ $hms($r2['idle_sec']) }} {{ $hms($r2['ex_idle_sec']) }}
{{ $totals['people'] }} {{ Str::plural('person', $totals['people']) }} {{ $pct($totals['activity_pct']) }} {{ $totals['activity_pct'] === null ? '—' : $pct(round(100 - $totals['activity_pct'], 1)) }} {{ $hms($totals['timer_sec']) }} {{ $hms($totals['idle_sec']) }} {{ $hms($totals['ex_idle_sec']) }}
@endif @endsection @push('styles') @include('partials.litepicker-theme') @endpush @push('scripts') @endpush