Fakultas Ilmu Komputer UI

Commit 49bb331f authored by MUHAMMAD EZRA RIZKIATAMA PUTRA's avatar MUHAMMAD EZRA RIZKIATAMA PUTRA
Browse files

[#74] Profile: Contributor's Upload History

parent 9edc8814
.img-profile {
width: 10vw;
height: 10vw;
}
.profile-data {
color: #615CFD;
padding-right: 75px;
}
\ No newline at end of file
This diff is collapsed.
{% extends "base.html" %}
{% load static %}
{% block title %}Digipus - {% endblock %}
{% block header %}
<!DOCTYPE html>
<html lang="en">
<head>
<title>Digipus Home</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="../../static/app/vendor/bootstrap/css/bootstrap.min.css" rel="stylesheet">
<link href="../../static/app/css/heroic-features.css" rel="stylesheet">
<link rel="stylesheet" type="text/css" href="{% static 'app/css/katalog_materi.css' %}">
<link rel="stylesheet" type="text/css" href="{% static 'app/css/katalog_kontri.css' %}">
<link rel="stylesheet" type="text/css" href="{% static 'css/main.css' %}">
<link rel="stylesheet" type="text/css" href="{% static 'css/util.css' %}">
<link rel="stylesheet" type="text/css" href="{% static 'css/styles.css' %}">
<link rel="stylesheet" type="text/css" href="{% static 'fonts/font-awesome-4.7.0/css/font-awesome.min.css' %}">
<link rel="stylesheet" type="text/css" href="{% static 'vendor/animsition/css/animsition.min.css' %}">
<link rel="stylesheet" type="text/css" href="{% static 'vendor/daterangepicker/daterangepicker.css' %}">
<link rel="stylesheet" type="text/css" href="{% static 'vendor/css-hamburgers/hamburgers.min.css' %}">
<link rel="stylesheet" type="text/css" href="{% static 'vendor/select2/select2.min.css' %}">
<link rel="stylesheet" type="text/css" href="{% static 'vendor/animate/animate.css' %}">
<link rel="icon" type="image/png" href="{% static 'images/icons/logo.ico' %}" />
{% endblock header %}
{% block content %}
</head>
<body style="background-color: #f8f8f8;">
<div class="container main">
<header class="jumbotron my-4" id="profile">
<div class="container sub">
<div class="row">
<div class="col-lg-3">
<div class="img-squared">
{% if not contributor.default_profile_picture %}
<img class="img-profile rounded-circle" src="https://i.ibb.co/9wgPzyZ/default-image.png"
alt="Contributor profile picture">
{% else %}
<img class="img-profile rounded-circle" src="{{ contributor.profile_picture.url }}"
alt="Contributor profile picture">
{% endif %}
</div>
</div>
<div class="col-lg-9">
<table aria-describedby="profile">
<th colspan="2" id="contributor-data">
<h3 class="profile-data">{{ contributor.name }}</h3>
<br>
</th>
<tr>
<td class="profile-data">Instansi</td>
<td>{{ contributor.instansi }}</td>
</tr>
<tr>
<td class="profile-data">LinkedIn</td>
<td><a href="https://linkedin.com">{{ contributor.linkedin }}</a></td>
</tr>
<tr>
<td class="profile-data">Facebook</td>
<td><a href="https://facebook.com">{{ contributor.facebook }}</a></td>
</tr>
<tr>
<td class="profile-data">Twitter</td>
<td><a href="https://twitter.com">{{ contributor.twitter }}</a></td>
</tr>
<tr>
<td class="profile-data">Instagram</td>
<td><a href="https://instagram.com">{{ contributor.instagram }}</a></td>
</tr>
</table>
</div>
</div>
</div>
</header>
<div class="container">
<div class="row content">
<div class="col books">
{% for materi in materi_list %}
<div class="card book">
<img src={{materi.cover.url}} class="card-img-top" alt="cover"
style="height:200px; widows: 200px; overflow: hidden;"></img>
<div class="card-body">
<h5 class="card-title">{{materi.title}}</h5>
<p class="card-text">{{materi.author}}</p>
<a href="{% url 'view-materi' materi.id %}" class="btn btn-book">Baca</a>
<a href="{% url 'detail-materi' materi.id %}" class="btn btn-book">Detail</a>
</div>
</div>
{% endfor %}
</div>
<div class="center">
<div class="pagination">
<span class="step-links">
<span class="current">
Page {{ materi_list.number }} of {{ materi_list.paginator.num_pages }}
</span>
<br>
{% if materi_list.has_previous %}
<a href="?page=1{{url}}">&laquo; first</a>
<a href="?page={{ materi_list.previous_page_number }}{{url}}">previous</a>
{% endif %}
{% if materi_list.has_next %}
<a href="?page={{ materi_list.next_page_number }}{{url}}">next</a>
<a href="?page={{ materi_list.paginator.num_pages }}{{url}}">last &raquo;</a>
{% endif %}
</span>
</div>
</div>
</div>
</div>
</div>
</body>
</html>
{% endblock %}
\ No newline at end of file
......@@ -41,13 +41,13 @@
<link rel="stylesheet" type="text/css" href="{% static 'css/main.css' %}">
<!--===============================================================================================-->
{% endblock header %}
{% block content %}
{% endblock header %}
{% block content %}
</head>
<body style="background-color: #f8f8f8;">
<!-- Page Content -->
<!-- Page Content -->
<div class="container">
<header class="jumbotron my-4">
......@@ -56,18 +56,20 @@
<div class="col">
<h2 class="pageTitle">Temukan Materi Yang Kamu Mau!</h2>
<p class="description">Cari dengan judul buku, penerbit, atau penulis</p>
<form class="searchBar" action=''>
<form class="searchBar" action=''>
<div class="col-6 form-group">
<input type="text" name='search' class="form-control" placeholder="Tulis di sini" value='{{request.GET.search}}'>
<input type="text" name='search' class="form-control" placeholder="Tulis di sini"
value='{{request.GET.search}}'>
</div>
<button type="submit" class="btn btn-cari">Cari</button>
</form>
<p class="pageTitle">Tidak menemukan materi yang kamu cari ? ajukan permintaan materi kami <a href="/req-materi">disini</a></p>
<p class="pageTitle">Tidak menemukan materi yang kamu cari ? ajukan permintaan materi kami <a
href="/req-materi">disini</a></p>
</div>
</div>
</div>
</div>
</header>
<div class="container">
<div class="row content">
<div class="col-3 sidebar">
......@@ -75,26 +77,20 @@
<div class="card">
<div class="card-header" id="headingOne">
<h2 class="mb-0">
<button class="btn collapsed"
type="button"
data-toggle="collapse"
data-target="#collapseOne"
aria-expanded="true"
aria-controls="collapseOne">
Filter
<button class="btn collapsed" type="button" data-toggle="collapse"
data-target="#collapseOne" aria-expanded="true" aria-controls="collapseOne">
Filter
</button>
</h2>
</div>
<div id="collapseOne"
class="collapse"
aria-labelledby="headingOne"
data-parent="#accordionExample">
<div id="collapseOne" class="collapse" aria-labelledby="headingOne"
data-parent="#accordionExample">
<div class="card-body">
{% for itemKategori in kategori_list %}
<li>
<a href="?kategori={{itemKategori.pk}}">{{itemKategori.name}}</a>
</li>
<li>
<a href="?kategori={{itemKategori.pk}}">{{itemKategori.name}}</a>
</li>
{% endfor %}
</div>
</div>
......@@ -102,33 +98,35 @@
<div class="card">
<div class="card-header" id="headingTwo">
<h2 class="mb-0">
<button class="btn collapsed" type="button" data-toggle="collapse" data-target="#collapseTwo" aria-expanded="false" aria-controls="collapseTwo">
Sort
</button>
</h2>
</div>
<div id="collapseTwo" class="collapse" aria-labelledby="headingTwo" data-parent="#accordionExample">
<div class="card-body">
<li>
<a href="?sort=terbaru">terbaru</a>
</li>
<li>
<a href="?sort=terlama">terlama</a>
</li>
<li>
<a href="?sort=terpopuler">terpopuler</a>
</li>
<li>
<a href="?sort=judul">judul</a>
</li>
<li>
<a href="?sort=penulis">penulis</a>
</li>
<li>
<a href="?sort=pengunggah">pengunggah</a>
</li>
<h2 class="mb-0">
<button class="btn collapsed" type="button" data-toggle="collapse"
data-target="#collapseTwo" aria-expanded="false" aria-controls="collapseTwo">
Sort
</button>
</h2>
</div>
<div id="collapseTwo" class="collapse" aria-labelledby="headingTwo"
data-parent="#accordionExample">
<div class="card-body">
<li>
<a href="?sort=terbaru">terbaru</a>
</li>
<li>
<a href="?sort=terlama">terlama</a>
</li>
<li>
<a href="?sort=terpopuler">terpopuler</a>
</li>
<li>
<a href="?sort=judul">judul</a>
</li>
<li>
<a href="?sort=penulis">penulis</a>
</li>
<li>
<a href="?sort=pengunggah">pengunggah</a>
</li>
</div>
</div>
</div>
</div>
......@@ -137,11 +135,16 @@
<div class="col-9 books">
{% for item in materi_list %}
<div class="card book">
<img src={{item.cover.url}} class="card-img-top" alt="cover"
<img src={{item.cover.url}} class="card-img-top" alt="cover"
style="height:200px; widows: 200px;; overflow: hidden;"></img>
<div class="card-body">
<h5 class="card-title">{{item.title}}</h5>
<p class="card-text">{{item.author}}</p>
<p class="card-text">Diunggah oleh
<a class="card-link" href="{% url 'katalog-per-kontributor' item.uploader.email %}">
{{item.uploader.name}}
</a>
</p>
<a href="{% url 'view-materi' item.id %}" class="btn btn-book">Baca</a>
<a href="{% url 'detail-materi' item.id %}" class="btn btn-book">Detail</a>
</div>
......@@ -158,14 +161,14 @@
<br>
</br>
{% if materi_list.has_previous %}
<a href="?page=1{{url}}" >&laquo; first</a>
<a href="?page=1{{url}}">&laquo; first</a>
<a href="?page={{ materi_list.previous_page_number }}{{url}}">previous</a>
{% endif %}
{% if materi_list.has_next %}
<a href="?page={{ materi_list.next_page_number }}{{url}}">next</a>
<a href="?page={{ materi_list.paginator.num_pages }}{{url}}">last &raquo;</a>
......@@ -173,16 +176,14 @@
</span>
</div>
</div>
</div>
</div>
</div>
<!-- /.container -->
<!-- /.container -->
</body>
</html>
{% endblock %}
\ No newline at end of file
{% endblock %}
\ No newline at end of file
......@@ -19,7 +19,8 @@ from .models import Category, Comment, Materi, Like, Rating
from .views import (DaftarKatalog, DashboardKontributorView, DetailMateri,
ProfilKontributorView, SuksesLoginAdminView,
SuksesLoginKontributorView, SuntingProfilView,
ProfilAdminView, PostsView, SuntingProfilAdminView, RevisiMateriView)
ProfilAdminView, PostsView, SuntingProfilAdminView,
RevisiMateriView, KatalogPerKontributorView)
from app.forms import SuntingProfilForm
from app.utils.fileManagementUtil import get_random_filename, remove_image_exifdata
......@@ -48,6 +49,60 @@ class DaftarKatalogTest(TestCase):
resp = Materi.objects.get(id=materi.id)
self.assertEqual(resp, materi)
class DaftarKatalogPerKontributorTest(TestCase):
def setUp(self):
self.client = Client()
self.contributor_credential = {
"email": "kontributor@gov.id",
"password": "passwordtest"
}
self.contributor_credential_2 = {
"email": "kontributor2@gov.id",
"password": "passwordtest"
}
self.contributor = get_user_model().objects.create_user(
**self.contributor_credential, name="Kontributor 1", is_contributor=True)
self.contributor2 = get_user_model().objects.create_user(
**self.contributor_credential_2, name="Kontributor 2", is_contributor=True)
self.cover = SimpleUploadedFile(
"Cherprang_Areekul40_nJM9dGt.jpg", b"Test file")
self.content = SimpleUploadedFile("Bahan_PA_RKK.pdf", b"Test file")
Materi(title="Materi 1", author="Agas", uploader=self.contributor,
publisher="Kelas SC", descriptions="Deskripsi Materi 1",
status="APPROVE", cover=self.cover, content=self.content).save()
Materi(title="Materi 2", author="Agas", uploader=self.contributor,
publisher="Kelas SC", descriptions="Deskripsi Materi 2",
status="APPROVE", cover=self.cover, content=self.content).save()
Materi(title="Materi 3", author="Agas", uploader=self.contributor2,
publisher="Kelas SC", descriptions="Deskripsi Materi 3",
status="APPROVE", cover=self.cover, content=self.content).save()
self.url = f"/profil/{self.contributor.email}/"
def test_katalog_per_kontributor_url_exist(self):
response = self.client.get(self.url)
self.assertEqual(response.status_code, 200)
def test_katalog_per_kontributor_using_katalog_kontri_template(self):
response = self.client.get(self.url)
self.assertTemplateUsed(response, "app/katalog_kontri.html")
def test_katalog_per_kontributor_using_katalog_per_kontributor_func(self):
found = resolve(self.url)
self.assertEqual(found.func.__name__, KatalogPerKontributorView.as_view().__name__)
def test_katalog_per_kontributor_show_daftar_materi_kontributor(self):
response = self.client.get(self.url)
list_materi = Materi.objects.filter(uploader=self.contributor)
data = response.context_data['materi_list']
self.assertEqual(len(list_materi), len(data))
class DetailMateriTest(TestCase):
def setUp(self):
......
......@@ -4,7 +4,8 @@ from app import views
from app.views import (DashboardKontributorView, ProfilKontributorView,
SuksesLoginAdminView, SuksesLoginKontributorView,
SuntingProfilView, UploadMateriHTML, UploadMateriView,
ProfilAdminView, PostsView, SuntingProfilAdminView, ReqMateriView)
ProfilAdminView, PostsView, SuntingProfilAdminView,
ReqMateriView, KatalogPerKontributorView)
urlpatterns = [
path("", views.DaftarKatalog.as_view(), name="daftar_katalog"),
......@@ -28,5 +29,7 @@ urlpatterns = [
path("sunting-admin/", SuntingProfilAdminView.as_view(), name="sunting-admin"),
path("req-materi/", ReqMateriView.as_view(), name="req-materi"),
path("post-req-materi/", views.post_req_materi, name="post-req-materi"),
path("profil/<str:email>/", KatalogPerKontributorView.as_view(),
name="katalog-per-kontributor"),
path("materi/rate/", views.add_rating_materi, name="rate-materi"),
]
......@@ -77,6 +77,26 @@ class DaftarKatalog(TemplateView):
context["url"] = url
return self.render_to_response(context=context)
class KatalogPerKontributorView(TemplateView):
template_name = "app/katalog_kontri.html"
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
contributor = get_object_or_404(User, email=kwargs["email"])
context["contributor"] = contributor
return context
def get(self, request, *args, **kwargs):
context = self.get_context_data(**kwargs)
materi_list = Materi.objects.filter(status="APPROVE", uploader=context["contributor"]).order_by("date_modified")
paginator = Paginator(materi_list, 15)
page_number = request.GET.get('page')
materi_list_by_page = paginator.get_page(page_number)
context["materi_list"] = materi_list_by_page
return self.render_to_response(context=context)
class DetailMateri(TemplateView):
template_name = "app/detail_materi.html"
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment