Start on user dashboard
This commit is contained in:
parent
8c127ba5da
commit
a0db589dc5
@ -13,6 +13,11 @@ use App\Models\{Address,Domain,Echomail,Setup};
|
|||||||
|
|
||||||
class HomeController extends Controller
|
class HomeController extends Controller
|
||||||
{
|
{
|
||||||
|
public function home()
|
||||||
|
{
|
||||||
|
return redirect(Auth::check() ? 'dashboard' : 'about');
|
||||||
|
}
|
||||||
|
|
||||||
public function network(Domain $o)
|
public function network(Domain $o)
|
||||||
{
|
{
|
||||||
if (! $o->public && ! Gate::check('admin',$o))
|
if (! $o->public && ! Gate::check('admin',$o))
|
||||||
|
@ -9,11 +9,6 @@ use App\Models\User;
|
|||||||
|
|
||||||
class UserController extends Controller
|
class UserController extends Controller
|
||||||
{
|
{
|
||||||
public function __construct()
|
|
||||||
{
|
|
||||||
$this->middleware('can:admin');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add or edit a node
|
* Add or edit a node
|
||||||
*/
|
*/
|
||||||
@ -53,6 +48,11 @@ class UserController extends Controller
|
|||||||
->with('o',$o);
|
->with('o',$o);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function dashboard()
|
||||||
|
{
|
||||||
|
return view('dashboard');
|
||||||
|
}
|
||||||
|
|
||||||
public function home()
|
public function home()
|
||||||
{
|
{
|
||||||
return view('user.home');
|
return view('user.home');
|
||||||
|
@ -4,6 +4,7 @@ namespace App\Models;
|
|||||||
|
|
||||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
use Illuminate\Database\Eloquent\Model;
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
use Illuminate\Support\Collection;
|
||||||
|
|
||||||
use App\Traits\ScopeActive;
|
use App\Traits\ScopeActive;
|
||||||
|
|
||||||
@ -49,4 +50,32 @@ class Domain extends Model
|
|||||||
{
|
{
|
||||||
$this->attributes['homepage'] = base64_encode(gzcompress($value,9));
|
$this->attributes['homepage'] = base64_encode(gzcompress($value,9));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* METHODS */
|
||||||
|
|
||||||
|
public function stats(System $o=NULL): Collection
|
||||||
|
{
|
||||||
|
if (! $this->echoareas->count())
|
||||||
|
return collect();
|
||||||
|
|
||||||
|
$where = collect(['echoarea_id'=>$this->echoareas->pluck('id')->toArray()]);
|
||||||
|
|
||||||
|
if ($o)
|
||||||
|
$where->put('fftn_id',$o->addresses()->pluck('id'));
|
||||||
|
|
||||||
|
$echostats = Echomail::countGroupBy('echoarea_id',$where->toArray());
|
||||||
|
|
||||||
|
return $this->echoareas->map(function($item) use ($echostats) {
|
||||||
|
$stats = $echostats->filter(function($x) use ($item) {
|
||||||
|
return $x->id->echoarea_id == $item->id;
|
||||||
|
});
|
||||||
|
|
||||||
|
$item->count = 0;
|
||||||
|
|
||||||
|
foreach ($stats as $o)
|
||||||
|
$item->count += $o->count;
|
||||||
|
|
||||||
|
return $item;
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
@ -60,6 +60,13 @@ class User extends Authenticatable implements MustVerifyEmail
|
|||||||
|
|
||||||
protected $dates = ['last_on'];
|
protected $dates = ['last_on'];
|
||||||
|
|
||||||
|
/* RELATIONS */
|
||||||
|
|
||||||
|
public function systems()
|
||||||
|
{
|
||||||
|
return $this->belongsToMany(System::class);
|
||||||
|
}
|
||||||
|
|
||||||
/* GENERAL METHODS */
|
/* GENERAL METHODS */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -5,6 +5,8 @@
|
|||||||
*/
|
*/
|
||||||
namespace App\Traits;
|
namespace App\Traits;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Collection;
|
||||||
|
|
||||||
trait UseMongo
|
trait UseMongo
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
@ -40,4 +42,41 @@ trait UseMongo
|
|||||||
{
|
{
|
||||||
$this->attributes['subject'] = utf8_encode($value);
|
$this->attributes['subject'] = utf8_encode($value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* METHODS */
|
||||||
|
|
||||||
|
public static function countGroupBy(string $field,array $where=[]): Collection
|
||||||
|
{
|
||||||
|
$query = collect();
|
||||||
|
|
||||||
|
if (count($where)) {
|
||||||
|
$where_condition = [];
|
||||||
|
|
||||||
|
foreach ($where as $key => $values) {
|
||||||
|
if (! is_array($values))
|
||||||
|
throw new \Exception('Where values must be an array.');
|
||||||
|
|
||||||
|
$where_condition[$key] = ['$in' => $values];
|
||||||
|
}
|
||||||
|
|
||||||
|
$query->push([
|
||||||
|
'$match' => $where_condition
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
$query->push([
|
||||||
|
'$group' => [
|
||||||
|
'_id' => [$field=>'$'.$field],
|
||||||
|
'count' => ['$sum' => 1]
|
||||||
|
]
|
||||||
|
]);
|
||||||
|
|
||||||
|
return (new self)
|
||||||
|
->groupBy($field)
|
||||||
|
->raw(function($collection) use ($query) {
|
||||||
|
return $collection->aggregate(
|
||||||
|
$query->toArray()
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
220
resources/views/dashboard.blade.php
Normal file
220
resources/views/dashboard.blade.php
Normal file
@ -0,0 +1,220 @@
|
|||||||
|
@extends('layouts.app')
|
||||||
|
@section('htmlheader_title')
|
||||||
|
Dashboard
|
||||||
|
@endsection
|
||||||
|
|
||||||
|
@section('content')
|
||||||
|
<h1>{{ $user->name }}</h1>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
@if($user->systems->count())
|
||||||
|
<div class="col-8">
|
||||||
|
<div id="network_messages"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- System Addresses -->
|
||||||
|
<div class="col-4">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-12">
|
||||||
|
<table class="table monotable">
|
||||||
|
<thead>
|
||||||
|
<tr><th colspan="2">System Addresses</th></tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
@foreach ($user->systems as $o)
|
||||||
|
<tr>
|
||||||
|
<th>{{ $o->name }}</th>
|
||||||
|
<th class="text-end">{!! $o->addresses->pluck('ftn')->join('<br>') !!}</th>
|
||||||
|
</tr>
|
||||||
|
@endforeach
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-12">
|
||||||
|
<table class="table monotable">
|
||||||
|
<thead>
|
||||||
|
<tr><th colspan="2">Available Echos</th></tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
@foreach ($user->systems as $o)
|
||||||
|
<tr>
|
||||||
|
<th>{{ $o->name }}</th>
|
||||||
|
<th class="text-end">{!! $o->addresses->pluck('zone.domain.echoareas')->flatten()->pluck('name')->unique()->sort()->join(', ') !!}</th>
|
||||||
|
</tr>
|
||||||
|
@endforeach
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@else
|
||||||
|
<p>You are not linked to any BBS systems.</p>
|
||||||
|
@endif
|
||||||
|
</div>
|
||||||
|
@endsection
|
||||||
|
|
||||||
|
@section('page-scripts')
|
||||||
|
<script src="https://code.highcharts.com/highcharts.js"></script>
|
||||||
|
<script src="https://code.highcharts.com/modules/data.js"></script>
|
||||||
|
<script src="https://code.highcharts.com/modules/drilldown.js"></script>
|
||||||
|
<script src="https://code.highcharts.com/modules/exporting.js"></script>
|
||||||
|
<script src="https://code.highcharts.com/modules/export-data.js"></script>
|
||||||
|
<script src="https://code.highcharts.com/themes/dark-unica.js"></script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.highcharts-data-table table {
|
||||||
|
min-width: 310px;
|
||||||
|
max-width: 800px;
|
||||||
|
margin: 1em auto;
|
||||||
|
}
|
||||||
|
.highcharts-data-table table {
|
||||||
|
border-collapse: collapse;
|
||||||
|
border: 1px solid #EBEBEB;
|
||||||
|
margin: 10px auto;
|
||||||
|
text-align: center;
|
||||||
|
width: 100%;
|
||||||
|
max-width: 500px;
|
||||||
|
}
|
||||||
|
.highcharts-data-table caption {
|
||||||
|
padding: 1em 0;
|
||||||
|
font-size: 1.2em;
|
||||||
|
color: #555;
|
||||||
|
}
|
||||||
|
.highcharts-data-table th {
|
||||||
|
font-weight: 600;
|
||||||
|
padding: 0.5em;
|
||||||
|
}
|
||||||
|
.highcharts-data-table td, .highcharts-data-table th, .highcharts-data-table caption {
|
||||||
|
padding: 0.5em;
|
||||||
|
}
|
||||||
|
{{--
|
||||||
|
.highcharts-data-table thead tr, .highcharts-data-table tr:nth-child(even) {
|
||||||
|
background: #f8f8f8;
|
||||||
|
}
|
||||||
|
.highcharts-data-table tr:hover {
|
||||||
|
background: #f1f7ff;
|
||||||
|
}
|
||||||
|
--}}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
@if($user->systems->count())
|
||||||
|
// Create the chart
|
||||||
|
Highcharts.chart('network_messages',{
|
||||||
|
chart: {
|
||||||
|
type: 'column'
|
||||||
|
},
|
||||||
|
credits: {
|
||||||
|
enabled: false
|
||||||
|
},
|
||||||
|
title: {
|
||||||
|
text: 'Echomail Statistics'
|
||||||
|
},
|
||||||
|
subtitle: {
|
||||||
|
text: '{{ sprintf('%s - %s',\Carbon\Carbon::now()->subMonths(6)->format('Y-m-d'),\Carbon\Carbon::now()->format('Y-m-d')) }}'
|
||||||
|
},
|
||||||
|
xAxis: {
|
||||||
|
type: 'category'
|
||||||
|
},
|
||||||
|
yAxis: {
|
||||||
|
title: {
|
||||||
|
text: '# Msgs'
|
||||||
|
},
|
||||||
|
stackLabels: {
|
||||||
|
enabled: true,
|
||||||
|
style: {
|
||||||
|
fontWeight: 'bold',
|
||||||
|
color: (Highcharts.defaultOptions.title.style && Highcharts.defaultOptions.title.style.color) || 'gray'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
legend: {
|
||||||
|
align: 'right',
|
||||||
|
//x: -30,
|
||||||
|
verticalAlign: 'top',
|
||||||
|
y: 40,
|
||||||
|
floating: true,
|
||||||
|
backgroundColor: Highcharts.defaultOptions.legend.backgroundColor || 'white',
|
||||||
|
borderColor: '#e0e0e0',
|
||||||
|
borderWidth: 1,
|
||||||
|
shadow: false
|
||||||
|
},
|
||||||
|
plotOptions: {
|
||||||
|
column: {
|
||||||
|
dataLabels: {
|
||||||
|
enabled: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
series: {
|
||||||
|
borderWidth: 0,
|
||||||
|
grouping: false,
|
||||||
|
xdataLabels: {
|
||||||
|
enabled: false,
|
||||||
|
format: ''//'{point.y:.0f}'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
tooltip: {
|
||||||
|
headerFormat: '<span style="font-size:11px">{series.name}</span><br>',
|
||||||
|
pointFormat: '<span style="color:{point.color}">{point.name}</span>: <b>{point.y:.0f}</b>'
|
||||||
|
},
|
||||||
|
series: [
|
||||||
|
{
|
||||||
|
name: 'Networks',
|
||||||
|
colorByPoint: true,
|
||||||
|
data: [
|
||||||
|
@foreach($o->addresses->pluck('zone.domain')->sortBy('name') as $oo)
|
||||||
|
@php($x = $oo->stats())
|
||||||
|
{
|
||||||
|
name: '{{ $oo->name }}',
|
||||||
|
y: {{ $x->sum('count') }},
|
||||||
|
drilldown: 'n-{{ $oo->name }}',
|
||||||
|
},
|
||||||
|
@endforeach
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Yours',
|
||||||
|
colorByPoint: true,
|
||||||
|
pointPlacement: 0.1,
|
||||||
|
data: [
|
||||||
|
@foreach($o->addresses->pluck('zone.domain')->sortBy('name') as $oo)
|
||||||
|
@php($x = $oo->stats($o))
|
||||||
|
{
|
||||||
|
name: '{{ $oo->name }}',
|
||||||
|
y: {{ $x->sum('count') }},
|
||||||
|
drilldown: 'ny-{{ $oo->name }}',
|
||||||
|
color: Highcharts.color(Highcharts.getOptions().colors[{{$loop->index}}]).brighten(-0.2).get()
|
||||||
|
},
|
||||||
|
@endforeach
|
||||||
|
]
|
||||||
|
},
|
||||||
|
],
|
||||||
|
drilldown: {
|
||||||
|
series: [
|
||||||
|
@foreach($o->addresses->pluck('zone.domain')->sortBy('name') as $oo)
|
||||||
|
@php($x = $oo->stats())
|
||||||
|
{
|
||||||
|
name: '{{ $oo->name }}',
|
||||||
|
id: 'n-{{ $oo->name }}',
|
||||||
|
data: {!! $x->sortBy('name')->map(function($item) use ($oo) { return ['name'=>$item->name,'y'=>$item->count,'drilldown'=>'e-'.$item->name]; })->values() !!}
|
||||||
|
},
|
||||||
|
@endforeach
|
||||||
|
|
||||||
|
@foreach($o->addresses->pluck('zone.domain')->sortBy('name') as $oo)
|
||||||
|
@php($x = $oo->stats($o))
|
||||||
|
{
|
||||||
|
name: '{{ $oo->name }}',
|
||||||
|
id: 'ny-{{ $oo->name }}',
|
||||||
|
data: {!! $x->sortBy('name')->map(function($item) { return ['name'=>$item->name,'y'=>$item->count,'drilldown'=>'ey-'.$item->name]; })->values() !!}
|
||||||
|
},
|
||||||
|
@endforeach
|
||||||
|
]
|
||||||
|
},
|
||||||
|
});
|
||||||
|
@endif
|
||||||
|
</script>
|
||||||
|
@append
|
@ -2,7 +2,7 @@
|
|||||||
<h1>{{ $title ?? config('app.name') }}</h1>
|
<h1>{{ $title ?? config('app.name') }}</h1>
|
||||||
|
|
||||||
<ul id="navlist-desktop">
|
<ul id="navlist-desktop">
|
||||||
<li><a href="{{ url('/') }}" class="@if(preg_match('#^/#',request()->path()))thispage @endif"><span>Home</span></a></li>
|
<li><a href="{{ url($user ? 'dashboard' : '/') }}" class="@if(preg_match('#^/#',request()->path()))thispage @endif"><span>Home</span></a></li>
|
||||||
<li><a href="{{ url('about') }}" class="@if(preg_match('#^about#',request()->path()))thispage @endif"><span>About</span></a></li>
|
<li><a href="{{ url('about') }}" class="@if(preg_match('#^about#',request()->path()))thispage @endif"><span>About</span></a></li>
|
||||||
<li><a href="{{ url('help') }}" class="@if(preg_match('#^help#',request()->path()))thispage @endif disabled"><span>Help</span></a></li>
|
<li><a href="{{ url('help') }}" class="@if(preg_match('#^help#',request()->path()))thispage @endif disabled"><span>Help</span></a></li>
|
||||||
@can('admin')
|
@can('admin')
|
||||||
|
@ -37,10 +37,12 @@ Route::get('logout',[LoginController::class,'logout']);
|
|||||||
Route::get('admin/switch/start/{o}',[UserSwitchController::class,'user_switch_start']);
|
Route::get('admin/switch/start/{o}',[UserSwitchController::class,'user_switch_start']);
|
||||||
Route::get('admin/switch/stop',[UserSwitchController::class,'user_switch_stop']);
|
Route::get('admin/switch/stop',[UserSwitchController::class,'user_switch_stop']);
|
||||||
|
|
||||||
Route::redirect('/','about');
|
Route::get('/',[HomeController::class,'home']);
|
||||||
Route::view('about','about');
|
Route::view('about','about');
|
||||||
|
|
||||||
Route::middleware(['verified','activeuser'])->group(function () {
|
Route::middleware(['verified','activeuser'])->group(function () {
|
||||||
|
Route::get('dashboard',[UserController::class,'dashboard']);
|
||||||
|
|
||||||
Route::get('ftn/domain',[DomainController::class,'home']);
|
Route::get('ftn/domain',[DomainController::class,'home']);
|
||||||
Route::match(['get','post'],'ftn/domain/addedit/{o?}',[DomainController::class,'add_edit'])
|
Route::match(['get','post'],'ftn/domain/addedit/{o?}',[DomainController::class,'add_edit'])
|
||||||
->where('o','[0-9]+');
|
->where('o','[0-9]+');
|
||||||
|
Loading…
Reference in New Issue
Block a user