Files
landing-api/resources/views/filament/pages/statistics.blade.php
Josep Piguillem 697d333ad4 Add a statistics page to the panel
The most read, reads per language with a daily chart, and published content
nobody opened, each compared with the period before.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 10:19:19 +02:00

103 lines
5.4 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<x-filament-panels::page>
<style>
.st-periods { display: flex; gap: .5rem; flex-wrap: wrap; }
.st-table { width: 100%; border-collapse: collapse; font-size: .875rem; }
.st-table th { text-align: left; font-weight: 600; font-size: .75rem; text-transform: uppercase; opacity: .7; padding: .5rem; }
.st-table td { padding: .5rem; border-top: 1px solid color-mix(in oklab, currentColor 10%, transparent); }
.st-table td.num, .st-table th.num { text-align: right; font-variant-numeric: tabular-nums; }
.st-up { color: #16a34a; } .st-down { color: #dc2626; }
.st-locales { display: grid; grid-template-columns: repeat(auto-fit, minmax(12rem, 1fr)); gap: 1rem; }
.st-locale strong { display: block; font-size: 1.5rem; font-variant-numeric: tabular-nums; }
.st-bar { height: .375rem; border-radius: 999px; background: color-mix(in oklab, currentColor 10%, transparent); overflow: hidden; margin-top: .5rem; }
.st-bar span { display: block; height: 100%; background: var(--primary-500, #f59e0b); }
.st-unread { columns: 2 18rem; column-gap: 2rem; font-size: .875rem; }
.st-unread li { break-inside: avoid; padding: .25rem 0; }
</style>
@php($stats = $this->stats())
<div class="st-periods" role="group" aria-label="{{ __('panel.statistics.period') }}">
@foreach (\App\Filament\Pages\Statistics::PERIODS as $period)
<x-filament::button
:color="$days === $period ? 'primary' : 'gray'"
wire:click="$set('days', {{ $period }})"
:aria-pressed="$days === $period ? 'true' : 'false'"
>
{{ __('panel.statistics.last_days', ['days' => $period]) }}
</x-filament::button>
@endforeach
</div>
<x-filament::section :heading="__('panel.statistics.languages')" :description="__('panel.statistics.compared')">
<div class="st-locales">
@foreach ($stats->byLocale() as $locale => $row)
@php($delta = $this->change($row['views'], $row['previous']))
<div class="st-locale">
<span>{{ config("locales.supported.{$locale}.native", $locale) }}</span>
<strong>{{ number_format($row['views'], 0, ',', '.') }}</strong>
<span @class(['st-up' => str_starts_with($delta, '+'), 'st-down' => str_starts_with($delta, '−')])>{{ $delta }}</span>
· {{ $row['share'] }} %
<div class="st-bar" aria-hidden="true"><span style="width: {{ $row['share'] }}%"></span></div>
</div>
@endforeach
</div>
</x-filament::section>
@livewire(\App\Filament\Charts\ViewsByLanguageChart::class, ['days' => $days], key('views-chart-'.$days))
<x-filament::section :heading="__('panel.statistics.top')">
@php($top = $stats->top())
@if ($top->isEmpty())
<p>{{ __('panel.statistics.no_views') }}</p>
@else
<table class="st-table">
<thead>
<tr>
<th scope="col">{{ __('panel.statistics.columns.title') }}</th>
<th scope="col">{{ __('panel.statistics.columns.type') }}</th>
<th scope="col" class="num">{{ __('panel.statistics.columns.views') }}</th>
<th scope="col" class="num">{{ __('panel.statistics.columns.change') }}</th>
</tr>
</thead>
<tbody>
@foreach ($top as $row)
@php($delta = $this->change($row['views'], $row['previous']))
<tr>
<td>
@if ($row['url'])
<x-filament::link :href="$row['url']">{{ $row['title'] }}</x-filament::link>
@else
{{ $row['title'] }}
@endif
</td>
<td>{{ __('panel.statistics.types.'.$row['type']) }}</td>
<td class="num">{{ number_format($row['views'], 0, ',', '.') }}</td>
<td @class(['num', 'st-up' => str_starts_with($delta, '+'), 'st-down' => str_starts_with($delta, '−')])>{{ $delta }}</td>
</tr>
@endforeach
</tbody>
</table>
@endif
</x-filament::section>
<x-filament::section :heading="__('panel.statistics.unread')" :description="__('panel.statistics.unread_hint')" collapsible>
@php($unread = $stats->unread())
@if ($unread->isEmpty())
<p>{{ __('panel.statistics.all_read') }}</p>
@else
<ul class="st-unread">
@foreach ($unread as $row)
<li>
<x-filament::badge color="gray" size="sm" style="display: inline-flex">{{ __('panel.statistics.types.'.$row['type']) }}</x-filament::badge>
@if ($row['url'])
<x-filament::link :href="$row['url']">{{ $row['title'] }}</x-filament::link>
@else
{{ $row['title'] }}
@endif
</li>
@endforeach
</ul>
@endif
</x-filament::section>
</x-filament-panels::page>