This commit is contained in:
Stefanescu Mihai
2026-03-18 13:32:36 +02:00
parent 6ad100d331
commit 274f6a378e
22 changed files with 1217 additions and 42 deletions
@@ -0,0 +1,34 @@
<?php
namespace App\Http\Controllers\Concerns;
use Illuminate\Http\Request;
use Illuminate\Support\Carbon;
trait ParsesDateRange
{
private function parseDateRange(Request $request): array
{
$range = $request->get('range', '7d');
$to = Carbon::today();
$from = match ($range) {
'today' => Carbon::today(),
'7d' => Carbon::today()->subDays(6),
'30d' => Carbon::today()->subDays(29),
'90d' => Carbon::today()->subDays(89),
'custom' => Carbon::parse($request->get('from', Carbon::today()->subDays(6)->toDateString())),
default => Carbon::today()->subDays(6),
};
if ($range === 'custom' && $request->has('to')) {
$to = Carbon::parse($request->get('to'));
}
if ($from->gt($to)) {
[$from, $to] = [$to, $from];
}
return [$from, $to];
}
}
+3 -27
View File
@@ -2,15 +2,17 @@
namespace App\Http\Controllers;
use App\Http\Controllers\Concerns\ParsesDateRange;
use App\Models\Website;
use App\Services\AnalyticsQueryService;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Carbon;
use Illuminate\View\View;
class DashboardController extends Controller
{
use ParsesDateRange;
public function show(Request $request, Website $website): View
{
$this->authorize('view', $website);
@@ -35,30 +37,4 @@ class DashboardController extends Controller
'active' => AnalyticsQueryService::activeVisitors($website),
]);
}
private function parseDateRange(Request $request): array
{
$range = $request->get('range', '7d');
$to = Carbon::today();
$from = match ($range) {
'today' => Carbon::today(),
'7d' => Carbon::today()->subDays(6),
'30d' => Carbon::today()->subDays(29),
'90d' => Carbon::today()->subDays(89),
'custom' => Carbon::parse($request->get('from', Carbon::today()->subDays(6)->toDateString())),
default => Carbon::today()->subDays(6),
};
if ($range === 'custom' && $request->has('to')) {
$to = Carbon::parse($request->get('to'));
}
if ($from->gt($to)) {
[$from, $to] = [$to, $from];
}
return [$from, $to];
}
}
+196
View File
@@ -0,0 +1,196 @@
<?php
namespace App\Http\Controllers;
use App\Http\Controllers\Concerns\ParsesDateRange;
use App\Models\Website;
use App\Services\AnalyticsQueryService;
use Illuminate\Http\Request;
use Illuminate\View\View;
class ReportController extends Controller
{
use ParsesDateRange;
// ---- Audience ----
public function geographic(Request $request, Website $website): View
{
$this->authorize('view', $website);
[$from, $to] = $this->parseDateRange($request);
$service = AnalyticsQueryService::for($website, $from, $to);
return view('reports.audience.geographic', [
'website' => $website,
'from' => $from,
'to' => $to,
'countries' => $service->visitorsByCountry(),
'cities' => $service->visitorsByCity(),
]);
}
public function technology(Request $request, Website $website): View
{
$this->authorize('view', $website);
[$from, $to] = $this->parseDateRange($request);
$service = AnalyticsQueryService::for($website, $from, $to);
return view('reports.audience.technology', [
'website' => $website,
'from' => $from,
'to' => $to,
'browsers' => $service->visitorsByBrowser(),
'operatingSystems' => $service->visitorsByOS(),
'devices' => $service->visitorsByDeviceType(),
'resolutions' => $service->visitorsByScreenResolution(),
]);
}
public function language(Request $request, Website $website): View
{
$this->authorize('view', $website);
[$from, $to] = $this->parseDateRange($request);
$service = AnalyticsQueryService::for($website, $from, $to);
return view('reports.audience.language', [
'website' => $website,
'from' => $from,
'to' => $to,
'languages' => $service->visitorsByLanguage(),
]);
}
public function newVsReturning(Request $request, Website $website): View
{
$this->authorize('view', $website);
[$from, $to] = $this->parseDateRange($request);
$service = AnalyticsQueryService::for($website, $from, $to);
return view('reports.audience.new-vs-returning', [
'website' => $website,
'from' => $from,
'to' => $to,
'data' => $service->newVsReturning(),
]);
}
// ---- Acquisition ----
public function sources(Request $request, Website $website): View
{
$this->authorize('view', $website);
[$from, $to] = $this->parseDateRange($request);
$service = AnalyticsQueryService::for($website, $from, $to);
return view('reports.acquisition.sources', [
'website' => $website,
'from' => $from,
'to' => $to,
'sources' => $service->trafficSources(),
]);
}
public function campaigns(Request $request, Website $website): View
{
$this->authorize('view', $website);
[$from, $to] = $this->parseDateRange($request);
$service = AnalyticsQueryService::for($website, $from, $to);
return view('reports.acquisition.campaigns', [
'website' => $website,
'from' => $from,
'to' => $to,
'campaigns' => $service->campaigns(),
]);
}
public function referrers(Request $request, Website $website): View
{
$this->authorize('view', $website);
[$from, $to] = $this->parseDateRange($request);
$service = AnalyticsQueryService::for($website, $from, $to);
return view('reports.acquisition.referrers', [
'website' => $website,
'from' => $from,
'to' => $to,
'referrers' => $service->referrers(),
]);
}
// ---- Behavior ----
public function pages(Request $request, Website $website): View
{
$this->authorize('view', $website);
[$from, $to] = $this->parseDateRange($request);
$service = AnalyticsQueryService::for($website, $from, $to);
return view('reports.behavior.pages', [
'website' => $website,
'from' => $from,
'to' => $to,
'pages' => $service->topPages(),
]);
}
public function landingPages(Request $request, Website $website): View
{
$this->authorize('view', $website);
[$from, $to] = $this->parseDateRange($request);
$service = AnalyticsQueryService::for($website, $from, $to);
return view('reports.behavior.landing-pages', [
'website' => $website,
'from' => $from,
'to' => $to,
'pages' => $service->landingPages(),
]);
}
public function exitPages(Request $request, Website $website): View
{
$this->authorize('view', $website);
[$from, $to] = $this->parseDateRange($request);
$service = AnalyticsQueryService::for($website, $from, $to);
return view('reports.behavior.exit-pages', [
'website' => $website,
'from' => $from,
'to' => $to,
'pages' => $service->exitPages(),
]);
}
// ---- Events ----
public function events(Request $request, Website $website): View
{
$this->authorize('view', $website);
[$from, $to] = $this->parseDateRange($request);
$service = AnalyticsQueryService::for($website, $from, $to);
return view('reports.events.overview', [
'website' => $website,
'from' => $from,
'to' => $to,
'events' => $service->eventsOverview(),
]);
}
public function eventDetail(Request $request, Website $website, string $eventName): View
{
$this->authorize('view', $website);
[$from, $to] = $this->parseDateRange($request);
$service = AnalyticsQueryService::for($website, $from, $to);
return view('reports.events.detail', [
'website' => $website,
'from' => $from,
'to' => $to,
'eventName' => $eventName,
'details' => $service->eventDetail($eventName),
'trending' => $service->eventTrending($eventName),
]);
}
}