@php $stageMeta = [ 'pre_production' => ['chip' => 'bg-brand-50 text-brand-700', 'icon' => 'flag', 'bar' => 'bg-brand-500', 'ring' => '#6366f1'], 'production' => ['chip' => 'bg-sky-50 text-sky-700', 'icon' => 'cog-6-tooth', 'bar' => 'bg-sky-500', 'ring' => '#0ea5e9'], 'pre_delivery' => ['chip' => 'bg-emerald-50 text-emerald-700','icon' => 'shield-check','bar' => 'bg-emerald-500', 'ring' => '#10b981'], ]; $filterMeta = [ 'all' => ['label' => __('All checks'), 'icon' => 'queue-list'], 'outstanding' => ['label' => __('Still to do'), 'icon' => 'clock'], 'required' => ['label' => __('Required'), 'icon' => 'shield-check'], 'mine' => ['label' => __('For me'), 'icon' => 'user'], ]; // Ring geometry for the completion donut. $ringRadius = 34; $ringCircumference = 2 * M_PI * $ringRadius; $ringDash = $ringCircumference * min(100, max(0, $summary['pct'])) / 100; $allClear = $summary['required'] > 0 && $summary['outstandingRequired'] === 0; // Slate while untouched, navy while in flight, emerald once the required set is clear. $ringColor = $summary['done'] === 0 ? '#cbd5e1' : ($allClear ? '#10b981' : '#2a5786'); @endphp
{{-- ============ QC SUMMARY ============ --}}

{{ __('Quality Control') }}

{{ __('Tick each check off as the job moves through production. The ones marked required need doing before the job can be completed or delivered.') }}

{{ __('Preview certificate') }} {{ __('Download') }} @if ($canManageChecks) {{ __('Add check') }} @endif
{{-- Completion donut --}}
{{ $summary['pct'] }}%
{{-- Verdict --}}
@if (! $hasChecks)

{{ __('There are no quality checks on this job yet') }}

{{ __('You can add a one-off check here, or set up a template under Jobs → Quality Checklists so every job of this kind starts with the same list.') }}

@elseif ($allClear)

{{ __('All done, everything required has been checked') }}

{{ trans_choice('{1}:done of :total check verified.|[2,*]:done of :total checks verified.', $summary['total'], ['done' => $summary['done'], 'total' => $summary['total']]) }} {{ __('This job is ready for its quality certificate.') }}

@elseif ($summary['required'] === 0)

{{ __('Nothing here is required') }}

{{ __('These checks are kept for the record, so none of them will hold the job up.') }}

@else

{{ trans_choice('{1}:count check still to do|[2,*]:count checks still to do', $summary['outstandingRequired'], ['count' => $summary['outstandingRequired']]) }}

{{ __('Once these are ticked off, the job is free to move on. An owner can also let it through early if something is urgent, and that decision is kept on record.') }}

@endif
{{-- Status gates --}} @if ($hasChecks)
@foreach ($gates as $gate)

{{ $gate['label'] }}

@unless ($gate['ready'])

{{ trans_choice('{1}:count check to go|[2,*]:count checks to go', $gate['outstanding'], ['count' => $gate['outstanding']]) }}

@endunless
@endforeach
@endif
{{-- Compact stat strip --}} @if ($hasChecks) @php $stats = [ ['label' => __('Checks done'), 'value' => $summary['done'].' of '.$summary['total'], 'icon' => 'check-circle', 'tone' => 'brand'], ['label' => __('Required done'), 'value' => $summary['requiredDone'].' of '.$summary['required'], 'icon' => 'shield-check', 'tone' => $allClear ? 'emerald' : 'amber'], ['label' => __('Photos & files'), 'value' => $summary['evidence'] > 0 ? $summary['evidence'].' '.trans_choice('{1}file|[2,*]files', $summary['evidence']) : __('None yet'), 'icon' => 'photo', 'tone' => 'cyan'], ['label' => __('Last update'), 'value' => $summary['lastCheckedAt'] ? \Illuminate\Support\Carbon::parse($summary['lastCheckedAt'])->diffForHumans(null, true).' '.__('ago') : __('Not started'), 'icon' => 'clock', 'tone' => 'slate'], ]; $toneChip = [ 'brand' => 'bg-brand-50 text-brand-700', 'emerald' => 'bg-emerald-50 text-emerald-600', 'amber' => 'bg-brand-yellow-50 text-brand-yellow-700', 'cyan' => 'bg-cyan-50 text-cyan-600', 'slate' => 'bg-slate-100 text-slate-500', ]; @endphp
@foreach ($stats as $stat)

{{ $stat['label'] }}

{{ $stat['value'] }}

@endforeach
@endif
{{-- ============ FILTERS ============ --}} @if ($hasChecks)
@foreach ($filterMeta as $key => $meta) @endforeach

{{ __('Every tick records who did it and when, so nobody has to remember later.') }}

@endif {{-- ============ CHECKS BY STAGE ============ --}} @foreach ($stageOrder as $stage) @php $items = $grouped[$stage] ?? collect(); $meta = $stageMeta[$stage] ?? $stageMeta['production']; $p = $progress[$stage] ?? ['total' => 0, 'done' => 0, 'required' => 0, 'requiredDone' => 0, 'pct' => 0]; @endphp @if ($items->isNotEmpty()) {{-- Stage header --}}

{{ $stageLabels[$stage] ?? $stage }}

@if ($p['required'] > 0) {{ $p['requiredDone'] }}/{{ $p['required'] }} {{ __('required') }} @endif
{{ $p['done'] }}/{{ $p['total'] }} {{ __('done') }} @if (($quickTickable[$stage] ?? 0) > 0) @endif
{{-- Checks --}}
@endif @endforeach {{-- Nothing to show --}} @if ($grouped->isEmpty()) @if ($hasChecks) {{ __('Show all checks') }} @else @if ($canManageChecks) {{ __('Add the first check') }} @endif @endif @endif {{-- Evidence that arrived through Drive rather than being captured here, so it belongs to the job but to no particular check. --}} @if ($unpinnedMedia->isNotEmpty())

{{ __('Evidence not linked to a check') }}

{{ __('Found in the job’s Quality Control folder in Drive. It counts as evidence on this job, but nobody said which check it proves.') }}

@foreach ($unpinnedMedia as $m) @endforeach
@endif {{-- ============ QUALITY NOTES ============ --}}

{{ __('Quality notes') }}

{{ __('Raise issues, observations or sign-off remarks about this job’s quality.') }}

@if ($comments->isNotEmpty()) {{ $comments->count() }} @endif
@if ($canManage)
@if ($commentItemId) @php $pinned = $commentItems->firstWhere('id', $commentItemId); @endphp @if ($pinned)
{{ \Illuminate\Support\Str::limit($pinned->label, 60) }}
@endif @endif
{{ __('Post note') }}
@endif
    @forelse ($comments as $c)
  • {{ \Illuminate\Support\Str::of($c->user?->name ?? '?')->trim()->substr(0, 1)->upper() }}

    {{ $c->user?->name ?? __('Unknown') }}

    {{ $c->created_at?->format('j M Y, H:i') }}

    @if ($canManage && ($c->user_id === auth()->id() || $canModerate)) @endif
    @if ($c->checklistItem)

    {{ \Illuminate\Support\Str::limit($c->checklistItem->label, 60) }}

    @endif

    {{ $c->body }}

  • @empty
  • {{ __('No quality notes yet.') }}

  • @endforelse
{{-- ============ SIGN-OFF MODAL ============ --}} {{ __('Verify check') }} @php $signItem = $signOffId ? $commentItems->firstWhere('id', $signOffId) : null; @endphp @if ($signItem)

{{ $signItem->label }}

{{ $stageLabels[$signItem->stage] ?? $signItem->stage }} · {{ $respMeta[$signItem->responsible]['label'] ?? ucfirst($signItem->responsible) }} @if ($signItem->requires_approval) · {{ __('needs an approver') }} @endif @if ($signItem->requires_evidence) · {{ __('needs evidence') }} @endif

@endif

{{ __('A photo of the approved sample, a clip of the machine running, a voice note on what you found — anything that stands as the record. Each one is saved as you capture it.') }}

@php $signMedia = ($signOffId ? ($mediaByItem[$signOffId] ?? collect()) : collect()) ->sortBy(fn ($m) => $m->is_audio ? 1 : 0) ->values(); @endphp @if ($signMedia->isNotEmpty())
@foreach ($signMedia as $m) @endforeach
@endif
{{ __('Cancel') }} {{ __('Verify & mark done') }} {{ __('Saving…') }}
{{-- ============ ADD CHECK MODAL ============ --}} {{ __('Add a check') }}

{{ __('A one-off check for this job only. To add it to every job of this type, edit the template under Jobs → Checklists.') }}

{{ __('Cancel') }} {{ __('Add check') }} {{ __('Adding…') }}