fedi-feed-router/app/Livewire/Dashboard.php

134 lines
3.1 KiB
PHP

<?php
namespace App\Livewire;
use App\Services\DashboardStatsService;
use App\Support\DateRange;
use Illuminate\Contracts\View\View;
use Illuminate\Support\Carbon;
use InvalidArgumentException;
use Livewire\Attributes\Computed;
use Livewire\Component;
class Dashboard extends Component
{
public string $from = '';
public string $to = '';
public function mount(): void
{
$this->applyPreset('today');
}
public function applyPreset(string $preset): void
{
try {
$range = DateRange::preset($preset);
} catch (InvalidArgumentException) {
return;
}
$this->from = $range->from->toDateString();
$this->to = $range->to->toDateString();
}
/**
* @return array<string, string>
*/
public function presets(): array
{
return DateRange::presets();
}
public bool $rangeIsValid = true;
public function range(): ?DateRange
{
$from = $this->parseBoundary($this->from);
$to = $this->parseBoundary($this->to);
if (! $from instanceof Carbon || ! $to instanceof Carbon) {
return null;
}
try {
return new DateRange($from->startOfDay(), $to->endOfDay());
} catch (InvalidArgumentException) {
return null;
}
}
private function parseBoundary(string $value): ?Carbon
{
try {
return Carbon::parse($value);
} catch (\Exception) {
return null;
}
}
/**
* @return array<string, mixed>
*/
#[Computed]
public function articleStats(): array
{
$range = $this->range();
if (! $range instanceof DateRange) {
return [
'articles_fetched' => 0,
'articles_published' => 0,
'published_percentage' => 0.0,
];
}
return app(DashboardStatsService::class)->getStats($range);
}
/**
* @return array<string, int>
*/
#[Computed]
public function systemStats(): array
{
return app(DashboardStatsService::class)->getSystemStats();
}
public function updated(string $property): void
{
if (in_array($property, ['from', 'to'], true)) {
$this->validateRange();
}
}
private function validateRange(): void
{
$this->resetErrorBag(['from', 'to']);
$from = $this->parseBoundary($this->from);
$to = $this->parseBoundary($this->to);
if (! $from instanceof Carbon) {
$this->addError('from', 'The start date is not a valid date.');
}
if (! $to instanceof Carbon) {
$this->addError('to', 'The end date is not a valid date.');
}
if ($from instanceof Carbon && $to instanceof Carbon && $to->lessThan($from)) {
$this->addError('to', 'The end date must not be earlier than the start date.');
}
$this->rangeIsValid = $this->range() instanceof DateRange;
}
public function render(): View
{
return view('livewire.dashboard', [
'presets' => $this->presets(),
])->layout('layouts.app');
}
}