Skip to content
Snippets Groups Projects
Verified Commit 619b2cc3 authored by Sofiane Lasri's avatar Sofiane Lasri
Browse files

feat: enhance admin dashboard with visit statistics

- Added logging for the most visited pages functionality.
- Calculated total visits for different timeframes (24 hours, 7 days, 30 days, all time).
- Updated view to display total visits and statistics more clearly, including separate cards for each timeframe.
- Improved the structure of the visits per day and visits by country charts.
- Enhanced the display of the most visited pages in a responsive table format.
parent d5282382
Branches
No related tags found
1 merge request!57Resolve "Compléter home dashboard admin avec les stats journaliers du site"
Pipeline #1012 passed
......@@ -3,6 +3,9 @@
namespace App\Http\Controllers\Admin;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Route;
use Illuminate\Support\Str;
use Illuminate\View\View;
use SlProjects\LaravelRequestLogger\app\Models\LoggedRequest;
......@@ -10,26 +13,80 @@ class HomeController extends Controller
{
public function index(): View
{
$totalVisits = LoggedRequest::count();
$visitsPerDay = LoggedRequest::selectRaw('DATE(created_at) as date, COUNT(*) as count')
->groupBy('date')
->orderBy('date', 'desc')
->take(7)
->get();
$publicRoutes = collect(Route::getRoutes()->getRoutes());
$publicRoutes = $publicRoutes->filter(function ($route) {
$isNotAdmin = ! Str::startsWith($route->uri, 'admin');
$isNotEmpty = $route->uri !== '/' && ! empty($route->uri);
$isNotApi = ! Str::startsWith($route->uri, 'api');
$visitsByCountry = LoggedRequest::selectRaw('country_code, COUNT(*) as count')
->whereNotNull('country_code')
->groupBy('country_code')
->orderBy('count', 'desc')
->get();
return $isNotAdmin && $isNotEmpty && $isNotApi;
});
$mostVisitedPages = LoggedRequest::with('url')
->selectRaw('url_id, COUNT(*) as count')
->groupBy('url_id')
->orderBy('count', 'desc')
->take(5)
$visits = LoggedRequest::select('url_id', 'ip_address_id', 'created_at', 'country_code', 'urls.url')
->distinct('url_id', 'ip_address_id')
->join('urls', 'logged_requests.url_id', '=', 'urls.id')
->where(function ($query) use ($publicRoutes) {
foreach ($publicRoutes as $route) {
$query->orWhere('urls.url', 'like', '%'.$route->uri.'%');
}
})
->get();
return view('admin.home', compact('totalVisits', 'visitsPerDay', 'visitsByCountry', 'mostVisitedPages'));
$totalVisitsPastTwentyFourHours = $visits->where('created_at', '>=', now()->subDay());
$totalVisitsPastSevenDays = $visits->where('created_at', '>=', now()->subDays(7));
$totalVisitsPastThirtyDays = $visits->where('created_at', '>=', now()->subDays(30));
$totalVisitsAllTime = $visits;
$visitsPerDay = [];
foreach ($visits as $visit) {
$date = $visit->created_at->format('Y-m-d');
if (! isset($visitsPerDay[$date])) {
$visitsPerDay[$date] = 0;
}
$visitsPerDay[$date]++;
}
$visitsPerDay = collect($visitsPerDay)->map(function ($count, $date) {
return ['date' => $date, 'count' => $count];
})->values();
$visitsByCountry = [];
foreach ($visits as $visit) {
if (! isset($visitsByCountry[$visit->country_code])) {
$visitsByCountry[$visit->country_code] = 0;
}
$visitsByCountry[$visit->country_code]++;
}
$visitsByCountry = collect($visitsByCountry)->map(function ($count, $country) {
return ['country' => $country, 'count' => $count];
})->values();
$mostVisitedPages = [];
foreach ($visits as $visit) {
if (! isset($mostVisitedPages[$visit->url])) {
$mostVisitedPages[$visit->url] = 0;
}
$mostVisitedPages[$visit->url]++;
}
$mostVisitedPages = collect($mostVisitedPages)->map(function ($count, $url) {
return ['url' => $url, 'count' => $count];
})->values();
Log::info(json_encode($mostVisitedPages));
return view('admin.home', [
'totalVisitsPastTwentyFourHours' => $totalVisitsPastTwentyFourHours->count(),
'totalVisitsPastSevenDays' => $totalVisitsPastSevenDays->count(),
'totalVisitsPastThirtyDays' => $totalVisitsPastThirtyDays->count(),
'totalVisitsAllTime' => $totalVisitsAllTime->count(),
'visitsPerDay' => $visitsPerDay,
'visitsByCountry' => $visitsByCountry,
'mostVisitedPages' => $mostVisitedPages,
]);
}
}
......@@ -2,51 +2,92 @@
@section('content')
<div class="container" id="admin-home">
<h1 class="text-2xl font-bold mb-4">Statistiques des Visites</h1>
<h3 class="mb-4">Statistiques des Visites uniques</h3>
<div class="row mb-4">
<div class="col-md-3">
<div class="card">
<div class="card-body text-center">
<h5 class="card-title">Total des Visites</h5>
<p class="card-text text-2xl font-bold">{{ $totalVisits }}</p>
<div class="grid g-4 mb-4">
<!-- Total des visites -->
<div class="g-col-3">
<div class="card text-center">
<div class="card-body">
<h5 class="card-title">Total des visites</h5>
<p class="display-6 fw-bold">{{ $totalVisitsAllTime }}</p>
</div>
</div>
</div>
<div class="g-col-3">
<div class="card text-center">
<div class="card-body">
<h5 class="card-title">Visites depuis 30 jours</h5>
<p class="display-6 fw-bold">{{ $totalVisitsPastThirtyDays }}</p>
</div>
</div>
</div>
<div class="g-col-3">
<div class="card text-center">
<div class="card-body">
<h5 class="card-title">Visites depuis 7 jours</h5>
<p class="display-6 fw-bold">{{ $totalVisitsPastSevenDays }}</p>
</div>
</div>
</div>
<div class="g-col-3">
<div class="card text-center">
<div class="card-body">
<h5 class="card-title">Visites aujourd'hui</h5>
<p class="display-6 fw-bold">{{ $totalVisitsPastTwentyFourHours }}</p>
</div>
</div>
</div>
</div>
<div class="row mb-4">
<div class="col-md-6">
<h2 class="text-xl font-bold">Visites par jour</h2>
<div class="row g-4 mb-4">
<!-- Visites par jour -->
<div class="g-col-md-6 mb-4">
<div class="card">
<div class="card-body">
<h5 class="card-title">Visites par jour</h5>
<div id="visits-per-day-chart">
<visits-per-day-chart :data="{{ json_encode($visitsPerDay) }}"></visits-per-day-chart>
</div>
</div>
<div class="col-md-6">
<h2 class="text-xl font-bold">Visites par pays</h2>
</div>
</div>
<!-- Visites par pays -->
<div class="g-col-md-6">
<div class="card">
<div class="card-body">
<h5 class="card-title">Visites par pays</h5>
<div id="visits-by-country-chart">
<visits-by-country-chart :data="{{ json_encode($visitsByCountry) }}"></visits-by-country-chart>
<visits-by-country-chart
:data="{{ json_encode($visitsByCountry) }}"></visits-by-country-chart>
</div>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-md-12">
<h2 class="text-xl font-bold">Pages les plus visitées</h2>
<table class="table table-striped">
<div class="row g-4">
<!-- Pages les plus visitées -->
<div class="g-col-12">
<div class="card">
<div class="card-body">
<h5 class="card-title">Pages les plus visitées</h5>
<div class="table-responsive">
<table class="table table-striped align-middle">
<thead>
<tr>
<th>#</th>
<th>Page</th>
<th>Nombre de visites</th>
<th scope="col">#</th>
<th scope="col">Page</th>
<th scope="col">Nombre de visites</th>
</tr>
</thead>
<tbody>
@foreach ($mostVisitedPages as $index => $page)
<tr>
<td>{{ $index + 1 }}</td>
<td>{{ $page->url->url }}</td>
<td>{{ $page->count }}</td>
<th scope="row">{{ $index + 1 }}</th>
<td>{{ $page['url'] }}</td>
<td>{{ $page['count'] }}</td>
</tr>
@endforeach
</tbody>
......@@ -54,5 +95,8 @@
</div>
</div>
</div>
</div>
</div>
</div>
@vite('resources/js/pages/admin/home.js')
@endsection
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment