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, }; } }