Add dashboard widgets

This commit is contained in:
Miguel Nogueira 2020-06-27 04:49:55 +01:00
parent 5a8c080a31
commit 71efdf93d8
4 changed files with 258 additions and 26 deletions

View File

@ -3,13 +3,29 @@
namespace App\Http\Controllers; namespace App\Http\Controllers;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use App\Vacancy;
use App\User;
use App\Ban;
use App\Application;
class DashboardController extends Controller class DashboardController extends Controller
{ {
public function index() public function index()
{ {
return view('dashboard.dashboard'); $totalPeerReview = Application::where('applicationStatus', 'STAGE_PEERAPPROVAL')->get()->count();
$totalNewApplications = Application::where('applicationStatus', 'STAGE_SUBMITTED')->get()->count();
$totalDenied = Application::where('applicationStatus', 'DENIED')->get()->count();
return view('dashboard.dashboard')
->with([
'vacancies' => Vacancy::all(),
'totalUserCount' => User::all()->count(),
'totalDenied' => $totalDenied,
'totalPeerReview' => $totalPeerReview,
'totalNewApplications' => $totalNewApplications
]);
} }
} }

View File

@ -208,6 +208,11 @@ return [
*/ */
'menu' => [ 'menu' => [
[
'text' => 'Home',
'icon' => 'fas fa-home',
'url' => 'dashboard'
],
[ [
'header' => 'Applications', 'header' => 'Applications',
'can' => 'applications.view.own' 'can' => 'applications.view.own'
@ -494,6 +499,22 @@ return [
'location' => '/js/datepick.js' 'location' => '/js/datepick.js'
] ]
] ]
],
[
'name' => 'Fullcalendar',
'active' => true,
'files' => [
[
'type' => 'js',
'asset' => false,
'location' => 'https://cdn.jsdelivr.net/npm/fullcalendar@5.0.1/main.min.js',
],
[
'type' => 'css',
'asset' => false,
'location' => 'https://cdn.jsdelivr.net/npm/fullcalendar@5.0.1/main.min.css'
]
]
] ]
], ],
]; ];

18
public/js/dashboard.js vendored Normal file
View File

@ -0,0 +1,18 @@
document.addEventListener('DOMContentLoaded', function() {
var calendarEl = document.getElementById('upcomingCalendar');
var calendar = new FullCalendar.Calendar(calendarEl, {
initialView: 'dayGridMonth',
themeSystem: 'bootstrap',
headerToolbar: {
left: 'dayGridMonth,timeGridWeek,timeGridDay',
center: 'title',
right: 'prevYear,prev,next,nextYear'
},
footerToolbar: {
center: '',
right: 'prev,next'
}
});
calendar.render();
});

View File

@ -3,44 +3,34 @@
@section('title', 'Raspberry Network Team Management') @section('title', 'Raspberry Network Team Management')
@section('content_header') @section('content_header')
<h1>Team Management Panel | Backoffice</h1> <h1>RaspberryNet Teams / Dashboard (<i>At a glance</i>)</h1>
@stop @stop
@section('js')
<script src="js/dashboard.js"></script>
@endsection
@section('content') @section('content')
<div class="row"> <div class="row mt-5">
<div class="col"> <div class="col">
@if (!is_null($mcstatus)) <div class="text-center">
@if($mcstatus[4]['sessionserver.mojang.com'] == 'red') <h4>Welcome back, {{ Auth::user()->name }}!</h4>
<div class="alert alert-danger">
<h4>Mojang's session servers are (apparently) down</h4>
<p>If you see missing profile pictures in our dashboard or in the staff list (homepage), or are unable to login to Raspberry Network or Minecraft itself, be advised that Mojang's session server is currently experiencing technical difficulties.</p>
<p>We hope this issue is resolved soon! For more information please visit the Mojang <a href="https://help.minecraft.net/hc/en-us">Support Center</a>.</p>
<p class="text-bold">Raspberry Network and Spacejewel Hosting are not affiliated with Mojang AB or Microsoft Corporation. Minecraft() is a trademark of Mojang AB.</p>
</div>
@else
<div class="alert alert-success">
<p>All OK! Feel free to explore the team management dashboard, manage your applications, or join our server.</p>
</div> </div>
@endif
@endif
</div>
</div> </div>
<div class="row">
</div>
<div class="row mb-3">
<div class="col"> <div class="col">
<div class="alert alert-info"> <div class="alert alert-info">
@ -52,4 +42,191 @@
</div> </div>
@if (!Auth::user()->isStaffMember())
<div class="row">
<div class="col-lg-3 col-3 offset-3">
<!-- small box -->
<div class="small-box bg-info">
<div class="inner">
<h3>{{ $openApplications ?? 0 }}</h3>
<p>Ongoing Apps</p>
</div>
<div class="icon">
<i class="fas fa-sync"></i>
</div>
<a href="{{ route('showUserApps') }}" class="small-box-footer">Open <i class="fas fa-arrow-circle-right"></i></a>
</div>
</div>
<!-- ./col -->
<div class="col-lg-3 col-6">
<!-- small box -->
<div class="small-box bg-danger">
<div class="inner">
<h3>{{ $deniedApplications ?? 0 }}</h3>
<p>Denied Apps</p>
</div>
<div class="icon">
<i class="fas fa-times"></i>
</div>
<a href="{{ route('showUserApps') }}" class="small-box-footer">Open <i class="fas fa-arrow-circle-right"></i></a>
</div>
</div>
</div>
@else
<div class="row">
<div class="col-lg-3 col-6">
<!-- small box -->
<div class="small-box bg-info">
<div class="inner">
<h3>{{ $totalUserCount }}</h3>
<p>Total Users + Staff</p>
</div>
<div class="icon">
<i class="fas fa-users"></i>
</div>
@if (Auth::user()->hasRole('admin'))
<a href="{{ route('registeredPlayerList') }}" class="small-box-footer">Open <i class="fas fa-arrow-circle-right"></i></a>
@endif
</div>
</div>
<!-- ./col -->
<div class="col-lg-3 col-6">
<!-- small box -->
<div class="small-box bg-danger">
<div class="inner">
<h3>{{ $totalDenied }}</h3>
<p>Denied applications</p>
</div>
<div class="icon">
<i class="fas fa-user-slash"></i>
</div>
</div>
</div>
<!-- ./col -->
<div class="col-lg-3 col-6">
<!-- small box -->
<div class="small-box bg-success">
<div class="inner">
<h3>{{ $totalNewApplications }}</h3>
<p>New applications</p>
</div>
<div class="icon">
<i class="fas fa-plus"></i>
</div>
<a href="{{ route('staffPendingApps') }}" class="small-box-footer">Open <i class="fas fa-arrow-circle-right"></i></a>
</div>
</div>
<!-- ./col -->
<div class="col-lg-3 col-6">
<!-- small box -->
<div class="small-box bg-warning">
<div class="inner">
<h3>{{ $totalPeerReview }}</h3>
<p>Vote backlog</p>
</div>
<div class="icon">
<i class="fas fa-vote-yea"></i>
</div>
<a href="{{ route('peerReview') }}" class="small-box-footer">Open <i class="fas fa-arrow-circle-right"></i></a>
</div>
</div>
<!-- ./col -->
</div>
@endif
@if ($isEligibleForApplication && !Auth::user()->isStaffMember())
<div class="row mt-5 mb-5">
<div class="col text-center">
<h4>Available ranks</h3>
<hr />
</div>
</div>
@endif
<div class="row">
@if (!$vacancies->isEmpty() && $isEligibleForApplication && !Auth::user()->isStaffMember())
@foreach($vacancies as $vacancy)
<div class="col{{ ($vacancy->count() == 1) ? '-3 offset-3' : '' }}">
<div class="card card-outline card-primary">
<div class="card-header">
<h3 class="card-title">{{ $vacancy->vacancyName }}</h3>
<div class="card-tools">
<button type="button" class="btn btn-tool" data-card-widget="collapse"><i class="fas fa-minus"></i>
</button>
</div>
<!-- /.card-tools -->
</div>
<!-- /.card-header -->
<div class="card-body" style="display: block;">
{{$vacancy->vacancyDescription}}
</div>
<!-- /.card-body -->
<div class="card-footer text-center">
<button type="button" class="btn btn-primary btn-sm" onclick="window.location.href='{{ route('renderApplicationForm', ['vacancySlug' => $vacancy->vacancySlug]) }}'">Apply</button>
<button type="button" class="btn btn-warning btn-sm">Learn More</button>
</div>
</div>
</div>
@endforeach
@endif
</div>
<div class="row mt-4">
<div class="col">
<div class="card">
<div class="card-header">
<h4>
<i class="fa fa-calendar"></i>&nbsp;&nbsp;Your upcoming interviews (<i>coming soon</i>)
</h4>
</div>
<div class="card-body">
<div id="upcomingCalendar"></div>
</div>
</div>
</div>
</div>
@stop @stop