Fakultas Ilmu Komputer UI

Commit 59d87955 authored by Samuel Dimas Partogi's avatar Samuel Dimas Partogi
Browse files

Merge branch 'PBI-9-Statistik_Akses_Materi' into 'staging'

Pbi 9 statistik akses materi

See merge request ppl-fasilkom-ui/2020/ppl-c/diskominfo-depok-digipus/marjinal-digipus!69
parents 84bb7a6b 32ef74e1
Pipeline #49691 passed with stages
in 5 minutes and 39 seconds
......@@ -7,6 +7,7 @@ LONG_MONTH = ['', 'Januari', 'Februari', 'Maret', 'April', 'Mei', 'Juni',
BASE_PERIODE = [
("", "Pilih"),
('-----', (
("LAST_WEEK", "7 Hari Terakhir"),
("LAST_MONTH", "30 Hari Terakhir"),
......
from crispy_forms.helper import FormHelper
from crispy_forms.layout import Submit
from crispy_forms.layout import Layout, Submit, Row, Column, Reset, ButtonHolder, Button
from crispy_forms.bootstrap import InlineCheckboxes
from django import forms
from administration.choices import genereatePeriodeChoices
......@@ -9,6 +9,12 @@ from app.models import Category
from authentication.models import User
def generate_category_choices():
categories = Category.objects.all()
category_choices = [(i.id, i.name) for i in categories]
return category_choices
class DateInput(forms.DateInput):
input_type = 'date'
......@@ -87,6 +93,8 @@ class PeriodForm(forms.Form):
widget=DateInput, label="Waktu mulai", required=False)
end_date = forms.DateField(
widget=DateInput, label="Waktu selesai", required=False)
categories = forms.MultipleChoiceField(
label="Kategori", required=False, choices=generate_category_choices)
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
......@@ -95,7 +103,34 @@ class PeriodForm(forms.Form):
field.widget.attrs['class'] = 'form-control'
self.helper = FormHelper()
self.helper.attrs["name"] = "filter-form"
self.helper.form_method = 'get'
self.helper.add_input(Submit('submit', 'Filter'))
# def get_date(self):
self.helper.layout = Layout(
Row(
Column('period', css_class='form-group col-md-4 mb-0'),
Column('start_date', css_class='form-group col-md-4 mb-0'),
Column('end_date', css_class='form-group col-md-4 mb-0'),
css_class='form-row'
),
InlineCheckboxes('categories'),
Row(
ButtonHolder(Submit('submit', 'Filter')),
ButtonHolder(Button('reset_form', 'Hapus filter'), css_class ="btn-warning")
)
)
def clean(self):
cleaned_data = super().clean()
start_date = cleaned_data.get('start_date')
end_date = cleaned_data.get('end_date')
if start_date is not None and end_date is None:
self.add_error("end_date",
"masukan waktu selesai")
if start_date is None and end_date is not None:
self.add_error("start_date",
"masukan waktu mulai")
if start_date is not None and end_date is not None:
if start_date > end_date:
self.add_error("end_date",
"waktu selesai sebelum waktu mulai")
......@@ -3,47 +3,3 @@
// var heightRatio = 1.5;
// canvas.height = canvas.width * heightRatio;
// });
\ No newline at end of file
var ctx = document.getElementById("chart1").getContext("2d");
var myChart = new Chart(ctx, {
type: "bar",
responsive: true,
data: {
labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
datasets: [
{
label: "# of Votes",
data: [12, 19, 3, 5, 2, 3],
backgroundColor: [
"rgba(255, 99, 132, 0.2)",
"rgba(54, 162, 235, 0.2)",
"rgba(255, 206, 86, 0.2)",
"rgba(75, 192, 192, 0.2)",
"rgba(153, 102, 255, 0.2)",
"rgba(255, 159, 64, 0.2)",
],
borderColor: [
"rgba(255, 99, 132, 1)",
"rgba(54, 162, 235, 1)",
"rgba(255, 206, 86, 1)",
"rgba(75, 192, 192, 1)",
"rgba(153, 102, 255, 1)",
"rgba(255, 159, 64, 1)",
],
borderWidth: 1,
},
],
},
options: {
responsive: true,
maintainAspectRatio: false,
scales: {
yAxes: [
{
ticks: {
beginAtZero: true,
},
},
],
},
},
});
......@@ -16,6 +16,7 @@
</div>
</div>
<hr>
<h1>Statistik Materi</h1>
<div class="row">
<div class="col-xl-3 col-md-6 mb-4">
......@@ -23,27 +24,11 @@
<div class="card-body">
<div class="row no-gutters align-items-center">
<div class="col mr-2">
<div class="text-xs font-weight-bold text-primary text-uppercase mb-1">Jumlah Pengguna</div>
<div class="h5 mb-0 font-weight-bold text-gray-800">100</div>
<div class="text-xs font-weight-bold text-success text-uppercase mb-1">Dilihat</div>
<div class="h5 mb-0 font-weight-bold text-gray-800">{{chart_data.total.0}}</div>
</div>
<div class="col-auto">
<i class="fas fa-users fa-2x text-gray-300"></i>
</div>
</div>
</div>
</div>
</div>
<div class="col-xl-3 col-md-6 mb-4">
<div class="card border-left-success shadow h-100 py-2">
<div class="card-body">
<div class="row no-gutters align-items-center">
<div class="col mr-2">
<div class="text-xs font-weight-bold text-success text-uppercase mb-1">Jumlah Materi</div>
<div class="h5 mb-0 font-weight-bold text-gray-800">200</div>
</div>
<div class="col-auto">
<i class="fas fa-file fa-2x text-gray-300"></i>
<i class="fas fa-eye" aria-hidden="true"></i>
</div>
</div>
</div>
......@@ -52,15 +37,15 @@
<!-- Earnings (Monthly) Card Example -->
<div class="col-xl-3 col-md-6 mb-4">
<div class="card border-left-success shadow h-100 py-2">
<div class="card border-left-danger shadow h-100 py-2">
<div class="card-body">
<div class="row no-gutters align-items-center">
<div class="col mr-2">
<div class="text-xs font-weight-bold text-success text-uppercase mb-1">Jumlah Materi</div>
<div class="h5 mb-0 font-weight-bold text-gray-800">$215,000</div>
<div class="text-xs font-weight-bold text-success text-uppercase mb-1">Diunduh</div>
<div class="h5 mb-0 font-weight-bold text-gray-800">{{chart_data.total.1}}</div>
</div>
<div class="col-auto">
<i class="fas fa-dollar-sign fa-2x text-gray-300"></i>
<i class="fas fa-download" aria-hidden="true"></i>
</div>
</div>
</div>
......@@ -69,25 +54,15 @@
<!-- Earnings (Monthly) Card Example -->
<div class="col-xl-3 col-md-6 mb-4">
<div class="card border-left-info shadow h-100 py-2">
<div class="card border-left-success shadow h-100 py-2">
<div class="card-body">
<div class="row no-gutters align-items-center">
<div class="col mr-2">
<div class="text-xs font-weight-bold text-info text-uppercase mb-1">Tasks</div>
<div class="row no-gutters align-items-center">
<div class="col-auto">
<div class="h5 mb-0 mr-3 font-weight-bold text-gray-800">50%</div>
</div>
<div class="col">
<div class="progress progress-sm mr-2">
<div class="progress-bar bg-info" role="progressbar" style="width: 50%"
aria-valuenow="50" aria-valuemin="0" aria-valuemax="100"></div>
</div>
</div>
</div>
<div class="text-xs font-weight-bold text-success text-uppercase mb-1">Disukai</div>
<div class="h5 mb-0 font-weight-bold text-gray-800">{{chart_data.total.2}}</div>
</div>
<div class="col-auto">
<i class="fas fa-clipboard-list fa-2x text-gray-300"></i>
<i class="fas fa-thumbs-up" aria-hidden="true"></i>
</div>
</div>
</div>
......@@ -100,8 +75,8 @@
<div class="card-body">
<div class="row no-gutters align-items-center">
<div class="col mr-2">
<div class="text-xs font-weight-bold text-warning text-uppercase mb-1">Pending Requests</div>
<div class="h5 mb-0 font-weight-bold text-gray-800">18</div>
<div class="text-xs font-weight-bold text-warning text-uppercase mb-1">Komentar</div>
<div class="h5 mb-0 font-weight-bold text-gray-800">{{chart_data.total.3}}</div>
</div>
<div class="col-auto">
<i class="fas fa-comments fa-2x text-gray-300"></i>
......@@ -117,12 +92,12 @@
<div class="row">
<!-- Area Chart -->
<div class="col-xl-8 col-lg-7">
<div class="col-12">
<div class="card shadow mb-4">
<!-- Card Header - Dropdown -->
<div class="card-header py-3 d-flex flex-row align-items-center justify-content-between">
<h6 class="m-0 font-weight-bold text-primary">Earnings Overview</h6>
<div class="dropdown no-arrow">
<h6 class="m-0 font-weight-bold text-primary">Statistik</h6>
<!-- <div class="dropdown no-arrow">
<a class="dropdown-toggle" href="#" role="button" id="dropdownMenuLink" data-toggle="dropdown"
aria-haspopup="true" aria-expanded="false">
<i class="fas fa-ellipsis-v fa-sm fa-fw text-gray-400"></i>
......@@ -135,193 +110,21 @@
<div class="dropdown-divider"></div>
<a class="dropdown-item" href="#">Something else here</a>
</div>
</div>
</div> -->
</div>
<!-- Card Body -->
<div class="card-body">
<div class="card-body" style="overflow:auto!important; display:inline-block!important; height: 750px;">
<div class="chart-area">
<canvas id="chart1" class="canvas"></canvas>
</div>
</div>
</div>
</div>
<!-- Pie Chart -->
<div class="col-xl-4 col-lg-5">
<div class="card shadow mb-4">
<!-- Card Header - Dropdown -->
<div class="card-header py-3 d-flex flex-row align-items-center justify-content-between">
<h6 class="m-0 font-weight-bold text-primary">Revenue Sources</h6>
<div class="dropdown no-arrow">
<a class="dropdown-toggle" href="#" role="button" id="dropdownMenuLink" data-toggle="dropdown"
aria-haspopup="true" aria-expanded="false">
<i class="fas fa-ellipsis-v fa-sm fa-fw text-gray-400"></i>
</a>
<div class="dropdown-menu dropdown-menu-right shadow animated--fade-in"
aria-labelledby="dropdownMenuLink">
<div class="dropdown-header">Dropdown Header:</div>
<a class="dropdown-item" href="#">Action</a>
<a class="dropdown-item" href="#">Another action</a>
<div class="dropdown-divider"></div>
<a class="dropdown-item" href="#">Something else here</a>
</div>
</div>
</div>
<!-- Card Body -->
<div class="card-body">
<div class="chart-pie pt-4 pb-2">
<canvas id="myPieChart"></canvas>
</div>
<div class="mt-4 text-center small">
<span class="mr-2">
<i class="fas fa-circle text-primary"></i> Direct
</span>
<span class="mr-2">
<i class="fas fa-circle text-success"></i> Social
</span>
<span class="mr-2">
<i class="fas fa-circle text-info"></i> Referral
</span>
<canvas id="primaryChart" class="canvas"></canvas>
</div>
</div>
</div>
</div>
</div>
<!-- Content Row -->
<div class="row">
<!-- Content Column -->
<div class="col-lg-6 mb-4">
<!-- Project Card Example -->
<div class="row p-3">
<div class="card shadow mb-4">
<div class="card-header py-3">
<h6 class="m-0 font-weight-bold text-primary">Projects</h6>
</div>
<div class="card-body">
<h4 class="small font-weight-bold">Server Migration <span class="float-right">20%</span></h4>
<div class="progress mb-4">
<div class="progress-bar bg-danger" role="progressbar" style="width: 20%" aria-valuenow="20"
aria-valuemin="0" aria-valuemax="100"></div>
</div>
<h4 class="small font-weight-bold">Sales Tracking <span class="float-right">40%</span></h4>
<div class="progress mb-4">
<div class="progress-bar bg-warning" role="progressbar" style="width: 40%" aria-valuenow="40"
aria-valuemin="0" aria-valuemax="100"></div>
</div>
<h4 class="small font-weight-bold">Customer Database <span class="float-right">60%</span></h4>
<div class="progress mb-4">
<div class="progress-bar" role="progressbar" style="width: 60%" aria-valuenow="60" aria-valuemin="0"
aria-valuemax="100"></div>
</div>
<h4 class="small font-weight-bold">Payout Details <span class="float-right">80%</span></h4>
<div class="progress mb-4">
<div class="progress-bar bg-info" role="progressbar" style="width: 80%" aria-valuenow="80"
aria-valuemin="0" aria-valuemax="100"></div>
</div>
<h4 class="small font-weight-bold">Account Setup <span class="float-right">Complete!</span></h4>
<div class="progress">
<div class="progress-bar bg-success" role="progressbar" style="width: 100%" aria-valuenow="100"
aria-valuemin="0" aria-valuemax="100"></div>
</div>
</div>
</div>
<!-- Color System -->
<div class="row">
<div class="col-lg-6 mb-4">
<div class="card bg-primary text-white shadow">
<div class="card-body">
Primary
<div class="text-white-50 small">#4e73df</div>
</div>
</div>
</div>
<div class="col-lg-6 mb-4">
<div class="card bg-success text-white shadow">
<div class="card-body">
Success
<div class="text-white-50 small">#1cc88a</div>
</div>
</div>
</div>
<div class="col-lg-6 mb-4">
<div class="card bg-info text-white shadow">
<div class="card-body">
Info
<div class="text-white-50 small">#36b9cc</div>
</div>
</div>
</div>
<div class="col-lg-6 mb-4">
<div class="card bg-warning text-white shadow">
<div class="card-body">
Warning
<div class="text-white-50 small">#f6c23e</div>
</div>
</div>
</div>
<div class="col-lg-6 mb-4">
<div class="card bg-danger text-white shadow">
<div class="card-body">
Danger
<div class="text-white-50 small">#e74a3b</div>
</div>
</div>
</div>
<div class="col-lg-6 mb-4">
<div class="card bg-secondary text-white shadow">
<div class="card-body">
Secondary
<div class="text-white-50 small">#858796</div>
</div>
</div>
</div>
<div class="col-lg-6 mb-4">
<div class="card bg-light text-black shadow">
<div class="card-body">
Light
<div class="text-black-50 small">#f8f9fc</div>
</div>
</div>
</div>
<div class="col-lg-6 mb-4">
<div class="card bg-dark text-white shadow">
<div class="card-body">
Dark
<div class="text-white-50 small">#5a5c69</div>
</div>
</div>
</div>
</div>
</div>
<div class="row p-3">
<div class="col">
<div class="card shadow mb-4">
<div class="card-header py-3">
<h6 class="m-0 font-weight-bold text-primary" id="titleGrafik">Grafik</h6>
</div>
<div class="card-body">
<canvas id="chart1" height="200"></canvas>
</div>
</div>
</div>
<div class="col-md-8">
<div class="card shadow mb-4">
<div class="card-header py-3">
<h6 class="m-0 font-weight-bold text-primary" id="titleGrafik">Grafik</h6>
</div>
<div class="card-body">
</div>
</div>
</div>
</div>
<div class="row p-3">
<div class="card shadow mb-4">
<div class="card-header py-3">
<h6 class="m-0 font-weight-bold text-primary" id="titleTable">Tabel</h6>
<h6 class="m-0 font-weight-bold text-primary" id="titleTable">Tabel Materi</h6>
</div>
<div class="card-body">
<div class="table-responsive">
......@@ -360,13 +163,59 @@
</div>
</div>
</div>
</div>
{% endblock %}
</div>
{% endblock %}
{% block javascripts %}
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.min.js"
{% block javascripts %}
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.min.js"
integrity="sha256-VazP97ZCwtekAsvgPBSUwPFKdrwD3unUfSGVYrahUqU=" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/chart.js@2.9.3/dist/Chart.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
<script src="{% static 'administration/statistic-loader.js'%}"></script>
{% endblock %}
\ No newline at end of file
<script src="https://cdn.jsdelivr.net/npm/chart.js@2.9.3/dist/Chart.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
<script src="{% static 'administration/statistic-loader.js'%}"></script>
<script type="text/javascript">
$(function () {
$("#button-id-reset_form").bind("click", function () {
$('form[name="filter-form"]')
.find(':radio, :checkbox').removeAttr('checked').end()
.find('textarea, :text, select').val('')
$('form[name="filter-form"]').find('input[type="date"]').val('')
});
});
</script>
<script>
var datasets = {{ chart_data.charts | safe }};
var labels = {{ chart_data.label | safe }};
var barChartData = {
labels: labels,
datasets: datasets
};
var chartOptions = {
responsive: true,
legend: {
position: "top"
},
title: {
display: true,
text: "Statistik"
},
scales: {
yAxes: [{
ticks: {
beginAtZero: true
}
}]
}
}
window.onload = function () {
var ctx = document.getElementById("primaryChart").getContext("2d");
window.myBar = new Chart(ctx, {
type: "bar",
data: barChartData,
options: chartOptions
});
};
</script>
{% endblock %}
\ No newline at end of file
from django.urls import path
from administration.views import (VerificationView, DetailVerificationView,
VerificationSettingView, CategorySettingView, KelolaKontributorView,
ProfileContributorAdminView, ProfileAdminAdministrationView,
KelolaAdminView, RegistrasiAdminView, EditVerificationView, EditCategoryView, StatisticsView, StatisticApiView,
delete_admin, delete_contributor, delete_verification, delete_category)
from administration.views import VerificationView, DetailVerificationView, VerificationSettingView, CategorySettingView, KelolaKontributorView, ProfileContributorAdminView, ProfileAdminAdministrationView, KelolaAdminView, RegistrasiAdminView, EditVerificationView, delete_admin, delete_contributor, delete_verification, StatisticsView, StatisticApiView, EditCategoryView, delete_category
app_name = "administration"
......
import random
import string
from django.utils import timezone, lorem_ipsum
from dateutil.relativedelta import relativedelta
def generate_time_step(s, e, step="DAILY"):
result = []
time = s.replace(hour=0, minute=0, second=0, microsecond=0)
while time < e:
result.append(time)
if step == "DAILY":
time = time + relativedelta(days=1)
result.append(e)
return result
def id_generator(size=6, chars=string.ascii_uppercase + string.digits): # pragma: no cover
return ''.join(random.choice(chars) for _ in range(size))
import json
from datetime import datetime, date
from django.core.exceptions import PermissionDenied
from django.contrib.auth.hashers import make_password
......@@ -6,14 +7,64 @@ from django.http import HttpResponseRedirect, JsonResponse
from django.shortcuts import get_object_or_404, render
from django.views.generic import TemplateView, View
from django.contrib import messages
from django.utils import timezone, lorem_ipsum
from dateutil.relativedelta import relativedelta
from administration.models import VerificationReport, VerificationSetting, DeletionHistory
from administration.forms import CategoryForm, VerificationSettingForm, RegistrasiAdminForm, PeriodForm
from app.models import Category, Materi
from app.models import Category, Materi, ViewStatistics, DownloadStatistics, Comment, Like, getRandomColor
from authentication.models import User
from datetime import datetime
from administration.utils import generate_time_step
def get_start_end_date(period):
if period == 'ALL_TIME':
return (None, None)
elif period.split("_")[0] == "LAST":
end = timezone.now()
delta = 7
if period.split("_")[1] == "WEEK":
delta = 7
if period.split("_")[1] == "MONTH":
delta = 30
if period.split("_")[1] == "QUARTER":
delta = 90
if period.split("_")[1] == "YEAR":
delta = 365
start = end - relativedelta(days=delta)
return (start, end)
elif period.split("_")[0] == "CURRENT":
start = timezone.now()
if period.split("_")[1] == "MONTH":
start = start.replace(day=1, hour=0, minute=0,
second=0, microsecond=0)
end = start + relativedelta(months=1)
return (start, end)
elif period.split("_")[1] == "YEAR":