CI (.github/workflows/tests.yml) reuses docker-compose.test.yml verbatim for the Postgres job rather than re-describing that environment in YAML, so the Docker image stays the single source of truth for it. Fixes a real mismatch found while wiring PHP versions into the workflow: composer.json declared "php": "^8.3", but the locked Symfony packages require >=8.4.1 — installing on 8.3 would fail at `composer install`, exactly what the Dockerfile's own comment already warned about. Bumped the constraint and resynced composer.lock's content-hash (no package versions changed). The pre-commit hook (.githooks/pre-commit, activated via `git config core.hooksPath` in post-autoload-dump) runs `pint --dirty --test` and refuses to commit unformatted files rather than silently rewriting them. The accessibility pass only touches this app's own hand-written Blade views, not Filament's components: aria-hidden on icons that repeat adjacent text, an aria-label on the one icon that is the only signal of a health check's severity, rel="noopener" and a labelled announcement on preview links that open in a new tab. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
150 lines
6.6 KiB
PHP
150 lines
6.6 KiB
PHP
<x-filament-panels::page>
|
|
{{-- The headline. Whether anything is actually wrong is the one thing
|
|
somebody opening this page came to find out.
|
|
|
|
Most of the icons below are `aria-hidden`: colour and shape repeating
|
|
what the text beside them already says. The one on each check's own
|
|
heading is the exception — severity there is never written out in
|
|
words, only implied by an icon and a badge colour — so that one gets
|
|
a spoken name instead of being hidden. --}}
|
|
@if ($this->problems()->isEmpty())
|
|
<div class="rounded-xl border border-success-300 bg-success-50 p-4 dark:border-success-700/50 dark:bg-success-500/10">
|
|
<div class="flex items-center gap-3">
|
|
<x-filament::icon
|
|
icon="heroicon-o-check-circle"
|
|
aria-hidden="true"
|
|
class="h-5 w-5 shrink-0 text-success-600 dark:text-success-400"
|
|
/>
|
|
|
|
<p class="font-semibold text-success-800 dark:text-success-300">
|
|
{{ __('health.all_clear') }}
|
|
</p>
|
|
</div>
|
|
</div>
|
|
@else
|
|
@php($tone = $this->hasErrors() ? 'danger' : 'warning')
|
|
|
|
<div @class([
|
|
'rounded-xl border p-4',
|
|
'border-danger-300 bg-danger-50 dark:border-danger-700/50 dark:bg-danger-500/10' => $tone === 'danger',
|
|
'border-warning-300 bg-warning-50 dark:border-warning-700/50 dark:bg-warning-500/10' => $tone === 'warning',
|
|
])>
|
|
<div class="flex items-start gap-3">
|
|
<x-filament::icon
|
|
icon="heroicon-o-exclamation-triangle"
|
|
aria-hidden="true"
|
|
@class([
|
|
'mt-0.5 h-5 w-5 shrink-0',
|
|
'text-danger-600 dark:text-danger-400' => $tone === 'danger',
|
|
'text-warning-600 dark:text-warning-400' => $tone === 'warning',
|
|
])
|
|
/>
|
|
|
|
<div class="space-y-1">
|
|
<p @class([
|
|
'font-semibold',
|
|
'text-danger-800 dark:text-danger-300' => $tone === 'danger',
|
|
'text-warning-800 dark:text-warning-300' => $tone === 'warning',
|
|
])>
|
|
{{ trans_choice('health.problem_summary', $this->problems()->count(), ['count' => $this->problems()->count()]) }}
|
|
</p>
|
|
|
|
<p @class([
|
|
'text-sm',
|
|
'text-danger-700 dark:text-danger-400' => $tone === 'danger',
|
|
'text-warning-700 dark:text-warning-400' => $tone === 'warning',
|
|
])>
|
|
{{ __('health.problem_hint') }}
|
|
</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
@endif
|
|
|
|
{{-- Failing checks, worst first. --}}
|
|
@foreach ($this->problems() as $finding)
|
|
<x-filament::section>
|
|
<x-slot name="heading">
|
|
<span class="flex items-center gap-2">
|
|
<x-filament::icon
|
|
:icon="$finding->severity->getIcon()"
|
|
:aria-label="$finding->severity->getLabel()"
|
|
role="img"
|
|
@class([
|
|
'h-5 w-5 shrink-0',
|
|
'text-danger-500' => $finding->severity->getColor() === 'danger',
|
|
'text-warning-500' => $finding->severity->getColor() === 'warning',
|
|
])
|
|
/>
|
|
|
|
{{ $finding->title() }}
|
|
|
|
<x-filament::badge :color="$finding->severity->getColor()" size="sm">
|
|
{{ $finding->count }}
|
|
</x-filament::badge>
|
|
</span>
|
|
</x-slot>
|
|
|
|
<div class="space-y-3">
|
|
<p class="text-sm text-gray-600 dark:text-gray-300">
|
|
{{ $finding->description() }}
|
|
</p>
|
|
|
|
{{-- Examples rather than only a number: "12 pages" is a
|
|
statistic, "12, starting with these" is something
|
|
somebody can act on. --}}
|
|
@if (filled($finding->samples))
|
|
<ul class="space-y-1 text-sm text-gray-500 dark:text-gray-400">
|
|
@foreach ($finding->samples as $sample)
|
|
<li class="flex items-start gap-2">
|
|
<span class="mt-1.5 h-1 w-1 shrink-0 rounded-full bg-gray-400"></span>
|
|
<span>{{ $sample }}</span>
|
|
</li>
|
|
@endforeach
|
|
|
|
@if ($finding->count > count($finding->samples))
|
|
<li class="text-xs italic">
|
|
{{ __('health.and_more', ['count' => $finding->count - count($finding->samples)]) }}
|
|
</li>
|
|
@endif
|
|
</ul>
|
|
@endif
|
|
|
|
@if ($finding->url)
|
|
<x-filament::link :href="$finding->url" size="sm">
|
|
{{ __('health.actions.go_fix') }}
|
|
</x-filament::link>
|
|
@endif
|
|
</div>
|
|
</x-filament::section>
|
|
@endforeach
|
|
|
|
{{-- What passed, collapsed. Worth showing at all: it says what was
|
|
actually looked at, so a clean page is not mistaken for a page that
|
|
never ran. --}}
|
|
@if ($this->passing()->isNotEmpty())
|
|
<x-filament::section collapsible collapsed>
|
|
<x-slot name="heading">
|
|
{{ trans_choice('health.passing', $this->passing()->count(), ['count' => $this->passing()->count()]) }}
|
|
</x-slot>
|
|
|
|
<ul class="space-y-2">
|
|
@foreach ($this->passing() as $finding)
|
|
<li class="flex items-start gap-2 text-sm">
|
|
<x-filament::icon
|
|
icon="heroicon-o-check-circle"
|
|
aria-hidden="true"
|
|
class="mt-0.5 h-4 w-4 shrink-0 text-success-500"
|
|
/>
|
|
|
|
<span>
|
|
<span class="font-medium text-gray-700 dark:text-gray-200">{{ $finding->title() }}</span>
|
|
<span class="text-gray-500 dark:text-gray-400"> — {{ $finding->description() }}</span>
|
|
</span>
|
|
</li>
|
|
@endforeach
|
|
</ul>
|
|
</x-filament::section>
|
|
@endif
|
|
</x-filament-panels::page>
|