Skip to content

Instantly share code, notes, and snippets.

@Loupeznik
Last active September 17, 2022 12:21
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save Loupeznik/5fe0e3fff362bfd46dabda82c782ff00 to your computer and use it in GitHub Desktop.
Save Loupeznik/5fe0e3fff362bfd46dabda82c782ff00 to your computer and use it in GitHub Desktop.
Laravel Visitor Counter - data visualization
<x-app-layout>
<x-slot name="header">
<h2 class="font-semibold text-xl text-gray-800 leading-tight">
{{ __('Dashboard') }}
</h2>
</x-slot>
<div class="py-12">
<div class="max-w-7xl mx-auto sm:px-6 lg:px-8">
<div class="bg-white overflow-hidden shadow-sm sm:rounded-lg">
<div class="p-6 bg-white border-b border-gray-200">
<x-graph :data="$chart_data" />
<x-table :columns="['Date', 'Visitors']">
@forelse ($visitors as $day)
<x-table-row :row="[date('d.m.Y', strtotime($day->date)), $day->total]" />
@empty
<x-table-row :row="['-', 'No data available']" />
@endforelse
</x-table>
</div>
</div>
</div>
</div>
</x-app-layout>
// app/Http/Controllers/DashboardController.php
<?php
namespace App\Http\Controllers;
use App\Models\Visitor;
use Illuminate\Support\Facades\DB;
class DashboardController extends Controller
{
/**
* Display a listing of the resource.
*
* @return \Illuminate\Http\Response
*/
public function index()
{
$visitors = Visitor::select('date', DB::raw('count(*) as total'))->where('date', '>', today()->subMonth())->groupBy('date')->get();
$chart_data = array();
foreach ($visitors as $data)
{
array_push($chart_data, array($data->date->format('d.m.Y'), $data->total));
}
return view('dashboard', compact(['visitors', 'chart_data']));
}
}
@props(['data'])
<canvas id="chartContainer"></canvas>
<script>
var jsonData = <?php echo json_encode($data, JSON_NUMERIC_CHECK); ?>;
var dates = [];
var visitors = [];
for (var i = 0; i < jsonData.length; i++) {
dates.push(jsonData[i][0]);
visitors.push(jsonData[i][1]);
}
var ctx = document.getElementById('chartContainer').getContext('2d');
var myChart = new Chart(ctx, {
type: 'line',
data: {
labels: dates,
datasets: [{
label: 'Visits per day',
data: visitors,
backgroundColor: '#EAB543',
hoverBackgroundColor: '#F8EFBA',
borderColor: '#25CCF7',
borderWidth: 2,
}]
},
options: {
scales: {
yAxes: [{
ticks: {
beginAtZero: false,
fontFamily: 'Nunito',
fontStyle: 'bold',
},
gridLines: {
display: false,
},
}],
xAxes: [{
gridLines: {
display: false,
},
ticks: {
fontFamily: 'Nunito',
},
}],
},
}
});
</script>
@props(['row', 'actions'])
<tr class="border-b border-gray-200 hover:bg-gray-100">
@foreach ($row as $var)
<td class="py-3 px-6 whitespace-nowrap text-center">{!!$var!!}</td>
@endforeach
@if (!empty($actions))
<td class="py-3 px-6 whitespace-nowrap text-center">
@foreach($actions as $action)
@if ($action == 'delete')
<a href="{{'/' . request()->path() . '/' . $row[0]}}" onclick="event.preventDefault(); document.getElementById('form-{{$row[0]}}').submit();"><i class="ri-delete-bin-2-line text-red-500"></i></a>
<form method="POST" action="{{'/' . request()->path() . '/' . $row[0]}}" style="display: none" id="form-{{$row[0]}}">
@csrf
@method('delete')
</form>
@elseif ($action == 'edit')
<a href="{{'/' . request()->path() . '/' . $row[0] . '/edit'}}"><i class="ri-edit-2-line text-blue-500"></i></a>
@endif
@endforeach
</td>
@endif
{{$slot}}
</tr>
@props(['columns'])
<table class="min-w-max w-full table-auto">
<thead>
<tr class="bg-gray-200 text-gray-600 uppercase text-sm leading-normal">
@foreach ($columns as $name)
<th class="py-3 px-6 text-center">
{{$name}}
</th>
@endforeach
</tr>
</thead>
<tbody class="text-gray-600 text-sm font-light">
{{$slot}}
</tbody>
</table>
// app/Models/Visitor.php
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Visitor extends Model
{
use HasFactory;
public $timestamps = FALSE;
protected $fillable = [
'date',
'ip'
];
/**
* The attributes that should be cast.
*
* @var array
*/
protected $casts = [
'date' => 'datetime:Y-m-d',
];
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment