@extends('layouts.portal') @section('title', 'Digital badges') @section('subtitle', 'The badge catalogue, who holds each badge, and manual awards. Every issued badge has a public verification page.') @section('actions') New badge @endsection @section('content') @php $levels = config('infotics.badges.levels'); $byLevel = $badges->groupBy('level'); $known = array_keys($levels); $others = $badges->reject(fn ($b) => in_array($b->level, $known, true)); $activeCount = $badges->where('status', 'active')->count(); $validCount = (int) ($stats['issued'] ?? 0); $revokedCount = (int) ($stats['revoked'] ?? 0); $top = $badges->sortByDesc('issuances_count')->first(); $criteriaLabel = ['manual' => 'Manual award', 'course' => 'Course completion', 'exam' => 'Exam pass']; $errorsOnIssue = $errors->any() && old('_form') === 'issue'; @endphp
Badges in catalogue{{ $badges->count() }}{{ $activeCount }} active{{ $badges->count() > $activeCount ? ' · '.($badges->count() - $activeCount).' draft or archived' : '' }}
Valid badges held{{ number_format($validCount) }}Publicly verifiable right now
Revoked{{ number_format($revokedCount) }}Shown as revoked on the verify page
Most awarded{{ $top && $top->issuances_count ? \Illuminate\Support\Str::limit($top->name, 26) : 'None yet' }}{{ $top && $top->issuances_count ? number_format($top->issuances_count).' issued' : 'Issue the first badge' }}

Catalogue

Grouped by level. Artwork is generated from the level colour unless you upload your own.
@if($badges->isEmpty())
Create the first badge
@endif @foreach(array_merge($known, $others->isNotEmpty() ? ['Other'] : []) as $level) @php $group = $level === 'Other' ? $others : ($byLevel[$level] ?? collect()); @endphp @continue($group->isEmpty()) @php $cfg = $levels[$level] ?? ['color' => '#0A66FF', 'stars' => 1]; @endphp

{{ $level }}

{{ $group->count() }}
@foreach($group as $b)
@if($b->status !== 'active')@endif

{{ $b->name }}

{{ $criteriaLabel[$b->criteria_type] ?? 'Manual award' }} · {{ number_format($b->issuances_count) }} issued

Edit
@endforeach
@endforeach

Issued badges

{{ number_format($issuances->total()) }} {{ \Illuminate\Support\Str::plural('record', $issuances->total()) }}{{ $filters ? ' match your search' : '' }}
@if($issuances->isEmpty())
@else
@foreach($issuances as $i) @php $st = $i->effectiveStatus(); @endphp @endforeach
HolderBadgeIssuedStatusVerifyActions
@if($i->user?->avatarUrl())@else{{ $i->user?->initials() ?? '?' }}@endif
{{ $i->user?->name ?? 'Deleted user' }}
{{ $i->user?->email }}
{{ $i->badge?->name ?? 'Deleted badge' }}{{ $i->badge_id_code }} {{ $i->issued_at?->format('d M Y') ?? '—' }}{{ $i->expires_at ? 'Expires '.$i->expires_at->format('d M Y') : 'No expiry' }} @if($st === 'revoked' && $i->revoke_reason){{ \Illuminate\Support\Str::limit($i->revoke_reason, 26) }}@endif @if($st !== 'revoked') @else {{ $i->revoked_at?->format('d M Y') }} @endif
{{ $issuances->links() }} @endif
{{-- Issue badge --}} {{-- Revoke badge --}} @push('scripts')@endpush @endsection