Files
analytics/app/Http/Controllers/CustomDashboardController.php
T
2026-03-24 21:12:21 +01:00

123 lines
4.0 KiB
PHP

<?php
namespace App\Http\Controllers;
use App\Http\Controllers\Concerns\ParsesDateRange;
use App\Models\DashboardWidget;
use App\Models\Website;
use App\Services\AnalyticsQueryService;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\View\View;
class CustomDashboardController extends Controller
{
use ParsesDateRange;
public function show(Request $request, Website $website): View
{
$this->authorize('view', $website);
[$from, $to] = $this->parseDateRange($request);
$service = AnalyticsQueryService::for($website, $from, $to);
$widgets = $website->dashboardWidgets()->orderBy('sort_order')->get();
$widgetData = [];
foreach ($widgets as $widget) {
$widgetData[$widget->id] = $this->resolveWidgetData($widget, $service);
}
return view('custom-dashboard.show', [
'website' => $website,
'widgets' => $widgets,
'widgetData' => $widgetData,
'from' => $from,
'to' => $to,
]);
}
public function manage(Website $website): View
{
$this->authorize('view', $website);
return view('custom-dashboard.manage', [
'website' => $website,
'widgets' => $website->dashboardWidgets()->orderBy('sort_order')->get(),
'types' => DashboardWidget::$types,
'metrics' => DashboardWidget::$metrics,
]);
}
public function store(Request $request, Website $website): RedirectResponse
{
$this->authorize('view', $website);
$validated = $request->validate([
'title' => 'required|string|max:255',
'widget_type' => 'required|string|in:' . implode(',', array_keys(DashboardWidget::$types)),
'size' => 'required|in:full,half,third',
'config' => 'nullable|array',
'config.metric' => 'nullable|string',
'config.limit' => 'nullable|integer|min:1|max:50',
]);
$maxSort = $website->dashboardWidgets()->max('sort_order') ?? 0;
$validated['sort_order'] = $maxSort + 1;
$website->dashboardWidgets()->create($validated);
return redirect()
->route('custom-dashboard.manage', $website)
->with('success', 'Widget added.');
}
public function reorder(Request $request, Website $website): RedirectResponse
{
$this->authorize('view', $website);
$request->validate([
'order' => 'required|array',
'order.*' => 'integer|exists:dashboard_widgets,id',
]);
foreach ($request->order as $position => $widgetId) {
$website->dashboardWidgets()->where('id', $widgetId)->update(['sort_order' => $position]);
}
return redirect()
->route('custom-dashboard.manage', $website)
->with('success', 'Widget order updated.');
}
public function destroy(Website $website, DashboardWidget $widget): RedirectResponse
{
$this->authorize('view', $website);
$widget->delete();
return redirect()
->route('custom-dashboard.manage', $website)
->with('success', 'Widget removed.');
}
private function resolveWidgetData(DashboardWidget $widget, AnalyticsQueryService $service): mixed
{
$config = $widget->config ?? [];
$limit = $config['limit'] ?? 5;
return match ($widget->widget_type) {
'metric' => $service->summary()[$config['metric'] ?? 'page_views'] ?? 0,
'chart' => $service->visitorsOverTime(),
'top_pages' => $service->topPages($limit),
'top_sources' => $service->trafficSources($limit),
'events' => $service->eventsOverview($limit),
'conversions' => $service->conversionsReport(),
'new_vs_returning' => $service->newVsReturning(),
'browsers' => $service->visitorsByBrowser($limit),
'countries' => $service->visitorsByCountry($limit),
default => null,
};
}
}