Skip to content
This repository has been archived by the owner on Nov 7, 2022. It is now read-only.

Commit

Permalink
added dashboard app
Browse files Browse the repository at this point in the history
  • Loading branch information
agusmakmun committed Dec 2, 2020
1 parent 1c0727e commit b20319c
Show file tree
Hide file tree
Showing 13 changed files with 437 additions and 2 deletions.
4 changes: 4 additions & 0 deletions apps/dashboard/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals

default_app_config = 'apps.dashboard.apps.DashboardConfig'
10 changes: 10 additions & 0 deletions apps/dashboard/apps.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.apps import AppConfig
from django.utils.translation import ugettext_lazy as _


class DashboardConfig(AppConfig):
name = 'apps.dashboard'
verbose_name = _('App Dashboard')
12 changes: 12 additions & 0 deletions apps/dashboard/urls.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.urls import path

from apps.dashboard.views.index import DashboardIndexView

app_name = 'apps.dashboard'

urlpatterns = [
path('', DashboardIndexView.as_view(), name='dashboard_index'),
]
Empty file.
136 changes: 136 additions & 0 deletions apps/dashboard/views/index.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
"""
Dashboard Index Views
to show all statistics.
"""
# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.utils import timezone
from django.utils.translation import ugettext_lazy as _
from django.views.generic import TemplateView

from core.utils.mixins import SuperUserLoginRequiredMixin

from apps.accounts.models.user import User
from apps.product.models.product import Product
from apps.blog.models.addons import Visitor
from apps.blog.models.post import Post
from apps.blog.models.tag import Tag


class DashboardIndexView(SuperUserLoginRequiredMixin, TemplateView):
template_name = 'apps/dashboard/index.html'
now = timezone.now()

def get_total_tags(self, period: str, month: int = None) -> int:
"""
function to get the total tags per-month / year.
:param `period` is string period (choices: "year", "month")
:param `month` is optional integer month if it period as "month".
:return int total of tags.
"""
if period == 'year':
return Tag.objects.filter(
created_at__year=self.now.year
).count()
elif period == 'month':
return Tag.objects.filter(
created_at__year=self.now.year,
created_at__month=month
).count()
return 0

def get_total_users(self, period: str, month: int = None) -> int:
"""
function to get the total users per-month / year.
:param `period` is string period (choices: "year", "month")
:param `month` is optional integer month if it period as "month".
:return int total of users
"""
if period == 'year':
return User.objects.filter(
date_joined__year=self.now.year
).count()
elif period == 'month':
return User.objects.filter(
date_joined__year=self.now.year,
date_joined__month=month
).count()
return 0

def get_total_posts(self, period: str, month: int = None) -> int:
"""
function to get the total posts per-month / year.
:param `period` is string period (choices: "year", "month")
:param `month` is optional integer month if it period as "month".
:return int total of posts.
"""
if period == 'year':
return Post.objects.filter(
created_at__year=self.now.year
).count()
elif period == 'month':
return Post.objects.filter(
created_at__year=self.now.year,
created_at__month=month
).count()
return 0

def get_total_visitors(self, period: str, month: int = None) -> int:
"""
function to get the total visitors per-month / year.
:param `period` is string period (choices: "year", "month")
:param `month` is optional integer month if it period as "month".
:return int total of visitors.
"""
if period == 'year':
return Visitor.objects.filter(
created_at__year=self.now.year
).count()
elif period == 'month':
return Visitor.objects.filter(
created_at__year=self.now.year,
created_at__month=month
).count()
return 0

def get_data_visitors_per_months(self) -> list:
"""
function to get the calculate the total data
of visitors for each month.
:return list dict of data per month.
"""
data_per_months = []
for month in range(1, 12):
total = self.get_total_visitors(period='month', month=month)
data_per_months.append(total)
return data_per_months

def get_data_per_months(self) -> list:
"""
function to get the calculate the total data
includes (user, product) for each month.
:return list dict of data per month.
"""
data_per_months = []
for month in range(1, 12):
data_per_months.append({
'tag': self.get_total_tags(period='month', month=month),
'post': self.get_total_posts(period='month', month=month),
'user': self.get_total_users(period='month', month=month)
})
return data_per_months

def get_context_data(self, **kwargs):
context_data = super().get_context_data(**kwargs)
context_data['total_tags'] = Tag.objects.all().count()
context_data['total_tags_this_year'] = self.get_total_tags(period='year')
context_data['total_users'] = User.objects.all().count()
context_data['total_users_this_year'] = self.get_total_users(period='year')
context_data['total_posts'] = Post.objects.all().count()
context_data['total_posts_this_year'] = self.get_total_posts(period='year')
context_data['total_visitors'] = Visitor.objects.all().count()
context_data['total_visitors_this_year'] = self.get_total_visitors(period='year')
context_data['data_visitors_per_months'] = self.get_data_visitors_per_months()
context_data['data_per_months'] = self.get_data_per_months()
return context_data
1 change: 1 addition & 0 deletions core/settings.py.example
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ INSTALLED_APPS = [
'apps.blog',
'apps.product',
'apps.api',
'apps.dashboard',
]


Expand Down
1 change: 1 addition & 0 deletions core/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
path('', include('apps.blog.urls')),
path('', include('apps.product.urls')),
path('api/', include('apps.api.urls')),
path('dash/', include('apps.dashboard.urls')),
]

if settings.DEBUG:
Expand Down
13 changes: 13 additions & 0 deletions core/utils/mixins.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.contrib.auth.mixins import LoginRequiredMixin


class SuperUserLoginRequiredMixin(LoginRequiredMixin):

def dispatch(self, request, *args, **kwargs):
if request.user.is_authenticated:
if request.user.is_superuser:
return super().dispatch(request, *args, **kwargs)
return self.handle_no_permission()
8 changes: 8 additions & 0 deletions templates/apps/accounts/user/profile.html
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,14 @@ <h5 class="text-bold">+ {{ user|get_total_posts|numberize }}</h5>
<span class="badge badge-light">{{ tag_data.total }}</span>
</div>
</div>
{% empty %}
<div class="col-md-12">
<ul class="list-group list-group-flush list-group-posts">
<li class="list-group-item">
<span>{% blocktrans with user=user %}{{ user }} dosen't have tags!{% endblocktrans %}</span>
</li>
</ul>
</div>
{% endfor %}
</div>
</div>
Expand Down
3 changes: 2 additions & 1 deletion templates/apps/blog/page/detail.html
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,15 @@
{% endblock %}

{% block css %}
<link href="{% static 'plugins/css/ace.min.css' %}" rel="stylesheet" media="all">
<link href="{% static 'martor/css/martor.bootstrap.min.css' %}" rel="stylesheet" media="all">
<style>div.martor-preview {border: 1px dashed #ddd}div.martor-preview hr{background-image: linear-gradient(to right,silver 50%,rgba(255,255,255,0) 40%); background-position: top; background-size: 3px 1px; background-repeat: repeat-x; height: 1px; border-top: 0; border-bottom: 0;}</style>
{% endblock %}


{% block content %}
<div class="container p-3">
<h5 class="mt-5 pt-4"><a class="no-underline" href="">{{ page_title }}</a></h5>
<h5><a class="no-underline" href="">{{ page_title }}</a></h5>
<div class="mt-4 row row-content">
<div class="col-md-8">
<div class="martor-preview">
Expand Down
1 change: 1 addition & 0 deletions templates/apps/blog/post/detail.html
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
{% endblock %}

{% block css %}
<link rel="stylesheet" href="{% static 'plugins/css/ace.min.css' %}" />
<link rel="stylesheet" href="{% static 'martor/css/martor.bootstrap.min.css' %}" />
<style>div.martor-preview {padding:0;background:transparent}</style>
{% endblock %}
Expand Down
Loading

0 comments on commit b20319c

Please sign in to comment.