Skip to content

Commit 3f5c074

Browse files
renzonrenzon
authored andcommitted
Created Dashboard
close #1229
1 parent e1d1829 commit 3f5c074

File tree

10 files changed

+119
-2
lines changed

10 files changed

+119
-2
lines changed

pythonpro/core/templates/core/base.html

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@
9898
{{ user.first_name }}
9999
</a>
100100
<div class="dropdown-menu dropdown-menu-right" aria-labelledby="dropdownMenuButton">
101+
<a class="dropdown-item" href="{% url 'dashboard:home' %}">Dashboard</a>
101102
<a class="dropdown-item" href="{% url 'core:profile' %}">Perfil</a>
102103
<div class="dropdown-divider"></div>
103104
<div class="dropdown-item">
@@ -108,7 +109,7 @@
108109
</ul>
109110
{% else %}
110111
<a class="btn btn-light my-2 my-sm-0"
111-
href="{% url 'login' %}?next={{ request.get_full_path|urlencode }}">Entrar</a>
112+
href="{% url 'login' %}?next={% url 'dashboard:home' %}">Entrar</a>
112113
{% endif %}
113114
</div>
114115
</nav>

pythonpro/dashboard/models.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
from django.contrib.auth import get_user_model
22
from django.db import models
3+
from django.urls import reverse
34

45
from pythonpro.modules.facade import get_topic_model
56

@@ -17,3 +18,9 @@ class Meta:
1718
topic_duration = models.IntegerField('Duração do Tópico') # seconds
1819
total_watched_time = models.IntegerField('Tempo assistindo o Tópico') # seconds
1920
max_watched_time = models.IntegerField('Tempo até onde assistiu') # seconds
21+
22+
def get_topic_url(self):
23+
return reverse('topics:detail', kwargs={'slug': self.topic.slug})
24+
25+
def get_topic_title(self):
26+
return self.topic.title
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
{% extends 'core/base.html' %}
2+
{% load static %}
3+
{% load dashboard_tags %}
4+
{% block head %}
5+
<script type="application/javascript">
6+
$(function () {
7+
$('[data-toggle="tooltip"]').tooltip()
8+
})
9+
</script>
10+
{% endblock head %}
11+
{% block body %}
12+
<div class="container mt-5 mb-5">
13+
<div class="row">
14+
<div class="col">
15+
<h1 class="mb-4">Dashboard</h1>
16+
<p>Confira seus últimos acessos</p>
17+
<table class="table table-striped text-center">
18+
<thead>
19+
<tr>
20+
<th scope="col">Data</th>
21+
<th scope="col">Tópico</th>
22+
<th scope="col" data-toggle="tooltip" data-placement="top"
23+
title="Tempo onde parou de ver o vídeo">Parada <span
24+
class="badge badge-pill badge-dark">?</span></th>
25+
<th scope="col" data-toggle="tooltip" data-placement="top"
26+
title="Tempo total que passou vendo o vídeo">Tempo <span
27+
class="badge badge-pill badge-dark">?</span></th>
28+
</tr>
29+
</thead>
30+
<tbody>
31+
{% for interaction in interactions %}
32+
<tr>
33+
<td>{{ interaction.creation|date:"d/m/Y" }} {{ interaction.creation|time:"H:i:s" }}</td>
34+
<td><a href="{{ interaction.get_topic_url }}">{{ interaction.get_topic_title }}</a></td>
35+
<td>{{ interaction.max_watched_time|duration }}</td>
36+
<td>{{ interaction.total_watched_time|duration }}</td>
37+
</tr>
38+
{% empty %}
39+
<tr>
40+
<td colspan="4">Você ainda não assistiu nenhum tópico</td>
41+
</tr>
42+
{% endfor %}
43+
44+
</tbody>
45+
</table>
46+
</div>
47+
</div>
48+
</div>
49+
{% endblock body %}

pythonpro/dashboard/templatetags/__init__.py

Whitespace-only changes.
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
from django import template
2+
3+
4+
def duration(value):
5+
try:
6+
duration = int(value)
7+
except ValueError:
8+
return ''
9+
else:
10+
minutes, seconds = divmod(duration, 60)
11+
hours, minutes = divmod(minutes, 60)
12+
return f'{hours:02d}:{minutes:02d}:{seconds:02d}'
13+
14+
15+
register = template.Library()
16+
register.filter('duration', duration)

pythonpro/dashboard/tests/__init__.py

Whitespace-only changes.
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import pytest
2+
from django.urls import reverse
3+
from model_mommy import mommy
4+
5+
from pythonpro.dashboard.models import TopicInteraction
6+
from pythonpro.django_assertions import dj_assert_contains
7+
8+
9+
@pytest.fixture
10+
def interactions(logged_user, topic):
11+
return mommy.make(TopicInteraction, 100, user=logged_user, topic=topic)
12+
13+
14+
@pytest.fixture
15+
def resp(client_with_lead, interactions):
16+
return client_with_lead.get(
17+
reverse('dashboard:home'),
18+
secure=True
19+
)
20+
21+
22+
def test_topic_interaction_status_code(resp):
23+
return resp.status_code == 200
24+
25+
26+
def test_topic_url_is_present(resp, topic):
27+
dj_assert_contains(resp, reverse('topics:detail', kwargs={'slug': topic.slug}))
28+
29+
30+
def test_topic_title_is_present(resp, topic):
31+
dj_assert_contains(resp, topic.title)

pythonpro/dashboard/tests.py renamed to pythonpro/dashboard/tests/test_interaction_creation.py

File renamed without changes.

pythonpro/dashboard/urls.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,7 @@
33
from . import views
44

55
app_name = 'dashboard'
6-
urlpatterns = [path('topic_interaction', views.topic_interation, name='topic_interaction')]
6+
urlpatterns = [
7+
path('topic_interaction', views.topic_interation, name='topic_interaction'),
8+
path('', views.home, name='home'),
9+
]

pythonpro/dashboard/views.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,19 @@
1+
from django.contrib.auth.decorators import login_required
12
from django.http import JsonResponse
3+
from django.shortcuts import render
24
from django.views.decorators.csrf import csrf_exempt
35

46
from pythonpro.dashboard.forms import TopicInteractionForm
7+
from pythonpro.dashboard.models import TopicInteraction
58

69

10+
@login_required
11+
def home(request):
12+
interactions = TopicInteraction.objects.select_related('topic').filter(user=request.user).order_by('-creation')[:20]
13+
return render(request, 'dashboard/home.html', {'interactions': interactions})
14+
15+
16+
@login_required
717
@csrf_exempt
818
def topic_interation(request):
919
data = dict(request.POST.items())

0 commit comments

Comments
 (0)