added last month visits to home

pull/44/head
A1Gard 4 months ago
parent 264e5faed0
commit abb4330d62

@ -2,7 +2,11 @@
namespace App\Http\Controllers; namespace App\Http\Controllers;
use App\Helpers\TDate;
use App\Models\Visitor;
use Carbon\Carbon;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
class HomeController extends Controller class HomeController extends Controller
{ {
@ -23,6 +27,25 @@ class HomeController extends Controller
*/ */
public function index() public function index()
{ {
return view('home');
$visits = Visitor::where('created_at', '>=', Carbon::now()->subMonth())
->groupBy('date')
->orderBy('date', 'DESC')
->get(array(
DB::raw('Date(created_at) as date'),
DB::raw('COUNT(*) as "count"'),
DB::raw('SUM(visit) as "visits"'),
))->toArray();
$dates = range((count($visits) - 1) * -1, 0);
$dt = new TDate();
array_walk($dates, function (&$item, $key) use ($dt) {
$x = strtotime($item . ' days');
if (config('app.locale') == 'fa') {
$item = $dt->PDate('Y/m/d', $x);
} else {
$item = date('Y-m-d', $x);
}
});
return view('home',compact('dates','visits'));
} }
} }

@ -20,7 +20,7 @@ class VisitorFactory extends Factory
{ {
$displays = ['1920x1080', '1366x768', '1920x1080', '1366x768', '1280x1024', null, null]; $displays = ['1920x1080', '1366x768', '1920x1080', '1366x768', '1280x1024', null, null];
$displays_mobile = ['360x780', '430x932', '390x844', '375x667', '412x915', null, null]; $displays_mobile = ['360x780', '430x932', '390x844', '375x667', '412x915', '428x926', null];
if (rand(0, 2) == 1) { if (rand(0, 2) == 1) {
$date = $this->faker->dateTimeBetween('-30 days', 'now'); $date = $this->faker->dateTimeBetween('-30 days', 'now');
} else { } else {

@ -17,6 +17,7 @@
"vue": "^3.2.37" "vue": "^3.2.37"
}, },
"dependencies": { "dependencies": {
"chart.js": "^4.4.3",
"leaflet": "^1.9.4", "leaflet": "^1.9.4",
"remixicon": "^4.2.0", "remixicon": "^4.2.0",
"sortablejs": "^1.15.2", "sortablejs": "^1.15.2",

@ -18,6 +18,7 @@ import { createApp } from 'vue';
import ToastPlugin from 'vue-toast-notification'; import ToastPlugin from 'vue-toast-notification';
import {useToast} from 'vue-toast-notification'; import {useToast} from 'vue-toast-notification';
import store from "./components/libs/store.js"; import store from "./components/libs/store.js";
import chartjs from 'chart.js/auto';
import './panel/raw.js'; import './panel/raw.js';
import './panel/navbar.js'; import './panel/navbar.js';
import './panel/list-checkboxs.js'; import './panel/list-checkboxs.js';
@ -27,6 +28,10 @@ import './panel/step-controller.js';
import './panel/product-upload-controller.js'; import './panel/product-upload-controller.js';
import './panel/setting-section-controller.js'; import './panel/setting-section-controller.js';
import './panel/sotable-controller.js'; import './panel/sotable-controller.js';
import './panel/prototypes.js';
window.chartjs = chartjs;
window.isPaintedChart = false;
/** /**
* Next, we will create a fresh Vue application instance. You may then begin * Next, we will create a fresh Vue application instance. You may then begin

@ -7,6 +7,7 @@ import bootstrap from 'bootstrap/dist/js/bootstrap.bundle.min.js';
*/ */
import axios from 'axios'; import axios from 'axios';
window.axios = axios; window.axios = axios;
window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest'; window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
@ -34,7 +35,7 @@ window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
// }); // });
// fixed tooptips // fixed tooptips
document.addEventListener('readystatechange',function () { document.addEventListener('DOMContentLoaded',function () {
[...document.querySelectorAll('[data-bs-toggle="tooltip"]')] [...document.querySelectorAll('[data-bs-toggle="tooltip"]')]
.forEach(function (el) { .forEach(function (el) {
let e = new bootstrap.Tooltip(el); let e = new bootstrap.Tooltip(el);

@ -0,0 +1,17 @@
/**
*
* @param key
* @param makeNumber [0 = nothing ,1 = integer, 2 = float]
* @returns {any[]}
*/
Array.prototype.subItem = function (key, makeNumber = 0) {
return this.map(item => {
if (makeNumber == 2){
return parseFloat(item[key]);
}else if(makeNumber == 1){
return parseInt(item[key]);
}else{
return item[key];
}
});
};

@ -197,3 +197,12 @@ a.btn,a.action-btn,a.circle-btn{
[data-open-file]{ [data-open-file]{
cursor: pointer; cursor: pointer;
} }
.avatar-x64{
background: $body-bg;
width: 64px;
height: 64px;
border-radius: 50%;
object-fit: cover;
border: 3px rgba($primary-color-panel,127) solid ;
}

@ -1,9 +1,26 @@
@extends('layouts.app') @extends('layouts.app')
@section('content') @section('content')
<div class="container-fluid"> <div class="container-fluid">
<div class="row"> <div class="row">
<div class="col-md-6 mb-4"> <div class="col-md-6 p-0 pe-md-2 mb-3">
<div class="card">
<div class="card-body">
<div class="row">
<div class="col-3 text-center">
<img src="{{asset('panel/images/xshop-logo.svg')}}" class="avatar-x64" alt="">
</div>
<div class="col-9">
{{__("Welcome bak")}}
<h4>
{{auth()->user()->name}}
</h4>
</div>
</div>
</div>
</div>
</div>
<div class="col-md-6 p-0 ps-md-2 mb-3">
<div class="card"> <div class="card">
<div class="card-header"> <div class="card-header">
lorem lorem
@ -16,19 +33,17 @@
</div> </div>
</div> </div>
</div> </div>
<div class="col-md-6 mb-4"> <div class="col-md-12 mb-3 p-0" id="visitor-container">
<div class="card"> <div class="card">
<div class="card-header"> <div class="card-header">
lorem {{__("last month visits")}}
</div> </div>
<div class="card-body"> <div class="card-body">
Lorem ipsum dolor sit amet, consectetur adipisicing elit. <canvas id="visitor-chart" height="300"></canvas>
Aliquam aspernatur, commodi consequatur deleniti dolor,
dolore ducimus ipsa laudantium magni natus nemo neque odit
officia perferendis provident suscipit ullam voluptas voluptate?
</div> </div>
</div> </div>
</div> </div>
<div class="col-md-4 mb-4"> <div class="col-md-4 mb-4">
<div class="card"> <div class="card">
<div class="card-header"> <div class="card-header">
@ -121,5 +136,65 @@
</div> </div>
</div> </div>
</div> </div>
</div> </div>
@endsection
@section('js-content')
<script>
window.addEventListener('load', function () {
if (isPaintedChart) {
return;
}
isPaintedChart = true;
let ctx = document.getElementById('visitor-chart').getContext('2d');
let visits = @json($visits);
document.getElementById('visitor-chart').setAttribute('width', document.querySelector('#visitor-container').clientWidth - 45);
let chart = new window.chartjs(ctx, {
// The type of chart we want to create
type: 'line', // also try bar or other graph types
// The data for our dataset
data: {
labels: @json($dates),
// Information about the dataset
datasets: [
{
label: "{{__('Visitors')}}",
backgroundColor: 'rgba(128,0,255,0.1)',
borderColor: 'rgba(140,0,255,0.6)',
data: visits.subItem('count', 1),
fill: true,
},
{
label: "{{__('Visits')}}",
backgroundColor: 'rgba(255,0,0,0.1)',
borderColor: '#ff000099',
data: visits.subItem('visits', 1),
fill: true,
},
]
},
// Configuration options
options: {
layout: {
padding: 10,
},
legend: {
position: 'bottom',
},
title: {
display: true,
text: 'Precipitation in Toronto'
}
}
});
});
</script>
@endsection @endsection

@ -18,4 +18,5 @@
</div> </div>
</div> </div>
</div> </div>
@yield('js-content')
@include('components.panel-footer') @include('components.panel-footer')

@ -127,6 +127,11 @@
resolved "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz" resolved "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz"
integrity sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg== integrity sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==
"@kurkle/color@^0.3.0":
version "0.3.2"
resolved "https://registry.yarnpkg.com/@kurkle/color/-/color-0.3.2.tgz#5acd38242e8bde4f9986e7913c8fdf49d3aa199f"
integrity sha512-fuscdXJ9G1qb7W8VdHi+IwRqij3lBkosAm4ydQtEmbY58OzHXqQhvlxqEkoz0yssNVn38bcpRWgA9PP+OGoisw==
"@popperjs/core@^2.11.6": "@popperjs/core@^2.11.6":
version "2.11.8" version "2.11.8"
resolved "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz" resolved "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz"
@ -345,6 +350,13 @@ braces@~3.0.2:
dependencies: dependencies:
fill-range "^7.0.1" fill-range "^7.0.1"
chart.js@^4.4.3:
version "4.4.3"
resolved "https://registry.yarnpkg.com/chart.js/-/chart.js-4.4.3.tgz#3b2e11e7010fefa99b07d0349236f5098e5226ad"
integrity sha512-qK1gkGSRYcJzqrrzdR6a+I0vQ4/R+SoODXyAjscQ/4mzuNzySaMCd+hyVxitSY1+L2fjPD1Gbn+ibNqRmwQeLw==
dependencies:
"@kurkle/color" "^0.3.0"
"chokidar@>=3.0.0 <4.0.0": "chokidar@>=3.0.0 <4.0.0":
version "3.6.0" version "3.6.0"
resolved "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz" resolved "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz"

Loading…
Cancel
Save