Fakultas Ilmu Komputer UI

Commit 7adff2c8 authored by oki priyadi's avatar oki priyadi
Browse files

resolve merge conflict

parents f34e709d 50b1fb8c
Pipeline #60041 failed with stages
in 3 minutes and 25 seconds
......@@ -28,6 +28,8 @@ class UploadMateriForm(forms.ModelForm):
if (field_name == "categories"):
continue
field.widget.attrs["class"] = "form-control"
field.widget.attrs["placeholder"] = field.initial
field.initial = ""
self.fields['categories'].widget.attrs.update({'class' : "native"})
......@@ -57,7 +59,7 @@ class SuntingProfilForm(forms.ModelForm):
class RatingContributorForm(forms.ModelForm):
class Meta:
model = RatingContributor
fields = ['score', 'user']
fields = ['score', 'user', 'contributor']
SCORE_CHOICE = (
('', 'Select score'),
('1', '1'), # First one is the value of select option and second is the displayed value in option
......@@ -67,6 +69,7 @@ class RatingContributorForm(forms.ModelForm):
('5', '5'),
)
widgets = {
'score': forms.Select(choices=SCORE_CHOICE, attrs={'class': 'form-control'},),
'user': forms.HiddenInput()
'score': forms.Select(choices=SCORE_CHOICE, attrs={'class': 'form-control', 'id':'form-rating'},),
'user': forms.HiddenInput(),
'contributor': forms.HiddenInput()
}
# Generated by Django 3.1 on 2020-10-30 09:48
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('app', '0026_submitvisitor'),
]
operations = [
migrations.AddField(
model_name='ratingcontributor',
name='contributor',
field=models.ForeignKey(default='', on_delete=django.db.models.deletion.CASCADE, related_name='contributor', to='authentication.user'),
preserve_default=False,
),
migrations.AlterField(
model_name='ratingcontributor',
name='user',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='user', to=settings.AUTH_USER_MODEL),
),
migrations.AlterUniqueTogether(
name='ratingcontributor',
unique_together={('contributor', 'user')},
),
]
......@@ -253,13 +253,17 @@ class Rating(models.Model):
class RatingContributor(models.Model):
timestamp = models.DateTimeField(auto_now=True)
score = models.PositiveIntegerField(validators=[MinValueValidator(1), MaxValueValidator(5)])
user = models.ForeignKey(User, on_delete=models.CASCADE)
contributor = models.ForeignKey(User, on_delete=models.CASCADE, related_name='contributor')
user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='user')
def save(self, force_insert=False, force_update=False, using=None, update_fields=None):
if 1 <= self.score <= 5:
super().save(force_insert, force_update, using, update_fields)
else:
raise ValidationError("Rating score must be integer between 1-5")
class Meta:
unique_together = ["contributor", "user"]
class SubscribeModel(models.Model):
sys_id = models.AutoField(primary_key=True, null=False, blank=True)
......
......@@ -24,6 +24,7 @@
<!-- Custom styles for this page -->
<link href="{% static 'vendor/datatables/dataTables.bootstrap4.min.css' %}" rel="stylesheet">
{% block stylesheets %}{% endblock %}
{% block scripts %}{% endblock %}
</head>
<body id="page-top" style="font-family: 'Poppins', sans-serif;">
......
......@@ -24,6 +24,8 @@
<!-- Custom styles for this page -->
<link href="{% static 'vendor/datatables/dataTables.bootstrap4.min.css' %}" rel="stylesheet">
{% block stylesheets %}{% endblock %}
<script type="text/javascript" src="{% static 'vendor/jquery/jquery-3.2.1.min.js' %}"></script>
</head>
<body id="page-top" style="font-family: 'Poppins', sans-serif;">
......
......@@ -33,7 +33,6 @@ div.review {
<!-- Topbar Navbar -->
<ul class="navbar-nav ml-auto">
{% if request.user.is_contributor %}
{% if materi_data.status == "DISAPPROVE" %}
<li class="nav-item black-text">
......@@ -164,6 +163,14 @@ div.review {
<p class="info-content">{{materi_data.content.size|filesizeformat}}</p>
</dd>
</div>
<div class="info" id="1">
<dl class="col col-4">
<dt class="info-name">Jumlah Like</dt>
</dl>
<dd>
<p class="info-content">{{materi_data.like_count}}</p>
</dd>
</div>
<div class="info" id="1">
<dl class="col col-4">
<dt class="info-name">Jumlah Download</dt>
......@@ -225,11 +232,11 @@ div.review {
<input type="hidden" name="action" value="like">
</form>
{% if has_liked %}
<button id="thumb" class="btn btn-link btn-book shadow-sm p-2 mr-2 bg-white rounded"><i id="thumbIcon"
aria-hidden="true" class="fas fa-thumbs-up"></i> Disukai</button>
<button id="thumb" class="btn btn-link btn-book shadow-sm p-2 mr-2 bg-white rounded" onClick="postLike()"><i id="thumbIcon"
aria-hidden="true" class="fas fa-thumbs-up"></i><span> Disukai</span></button>
{% else %}
<button id="thumb" class="btn btn-link btn-book shadow-sm p-2 mr-2 bg-white rounded"><i id="thumbIcon"
aria-hidden="true" class="far fa-thumbs-up"></i> Sukai</button>
<button id="thumb" class="btn btn-link btn-book shadow-sm p-2 mr-2 bg-white rounded" onClick="postLike()"><i id="thumbIcon"
aria-hidden="true" class="far fa-thumbs-up"></i><span> Sukai</span></button>
{% endif %}
{% if user.is_authenticated %}
......@@ -331,7 +338,7 @@ div.review {
<div>
<button id="thumb-like-comment-{{ comment.id }}" class="btn btn-link btn-book shadow-sm p-2 mr-2 bg-white rounded" onClick="postLikeComment({{ comment.id }})">
<div class="d-flex flex-row">
{% if has_liked.comment.id %}
{% if has_liked_comment.comment.id %}
<i id="thumb-like-comment-icon-{{ comment.id }}" aria-hidden="true" class="fas fa-thumbs-up"></i>
{% else %}
<i id="thumb-like-comment-icon-{{ comment.id }}" aria-hidden="true" class="far fa-thumbs-up"></i>
......@@ -341,7 +348,7 @@ div.review {
</button>
<button id="thumb-dislike-comment-{{ comment.id }}" class="btn btn-link btn-book shadow-sm p-2 mr-2 bg-white rounded" onClick="postDislikeComment({{ comment.id }})">
<div class="d-flex flex-row">
{% if has_disliked.comment.id %}
{% if has_disliked_comment.comment.id %}
<i id="thumb-dislike-comment-icon-{{ comment.id }}" aria-hidden="true" class="fas fa-thumbs-down"></i>
{% else %}
<i id="thumb-dislike-comment-icon-{{ comment.id }}" aria-hidden="true" class="far fa-thumbs-down"></i>
......@@ -509,8 +516,7 @@ div.review {
}
</script>
<script>
$('#thumb').click(function () {
function postLike() {
$.ajaxSetup({
beforeSend: function (xhr, settings) {
if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
......@@ -528,7 +534,7 @@ div.review {
success: LikePost,
dataType: 'html'
});
});
}
function postLikeComment(comment_id) {
$.ajaxSetup({
......@@ -599,12 +605,15 @@ div.review {
function LikePost(data, jqXHR) {
var data = $.parseJSON(data)
var likeCount = parseInt($('.info-content')[6].textContent)
if (data['liked']) {
$('#thumbIcon').removeClass("fas fa-thumbs-up").addClass('far fa-thumbs-up')
document.getElementById("thumb").firstChild.data = " Sukai"
$('#thumb>span').text(" Sukai")
$('.info-content')[6].textContent = likeCount - 1
} else {
$('#thumbIcon').removeClass("far fa-thumbs-up").addClass('fas fa-thumbs-up')
document.getElementById("thumb").firstChild.data = " Disukai"
$('#thumb>span').text(" Disukai")
$('.info-content')[6].textContent = likeCount + 1
}
}
......
{% extends "base.html" %}
{% load static %}
{% load humanize %}
{% block title %}Digipus - {% endblock %}
{% block title %}Digipus - {{ contributor.name }}'s' Profile{% endblock %}
{% block header %}
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!DOCTYPE html>
<html lang="en">
<link href="../../static/app/vendor/bootstrap/css/bootstrap.min.css" rel="stylesheet">
<link href="../../static/app/css/heroic-features.css" rel="stylesheet">
<head>
<title>Digipus Home</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<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 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 '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 '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 '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="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="icon" type="image/png" href="{% static 'images/icons/logo.ico' %}" />
<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' %}">
{% endblock header %}
<link rel="icon" type="image/png" href="{% static 'images/icons/logo.ico' %}" />
{% endblock header %}
{% block content %}
</head>
{% block content %}
<body style="background-color: #f8f8f8;">
<div class="container main">
......@@ -87,10 +79,28 @@
</table>
</div>
</div>
<h4 id="rating">Rating: {% if avg_rating.avg_rating %}{{ avg_rating.avg_rating|floatformat:"2"|intcomma }}{% else %}0{% endif %}</h4>
<h6>oleh: {{ count_rating }} orang</h6>
<div class="row"><form method="post">{{ form_rating }} {% csrf_token %}
<button type="submit" class="form-control" style="margin-top: 1rem">Submit</button></form> </div>
<div class="row mx-5 mt-3">
<h4 id="rating">Rating: {% if avg_rating.avg_rating %}{{ avg_rating.avg_rating|floatformat:"2"|intcomma }}{% else %}0{% endif %}
</h4>
</div>
<div class="row mx-5 mt-2">
<h6>oleh: {{ count_rating }} orang</h6>
</div>
<div class="row mx-5 mt-3">
{% if not user.is_authenticated %}
<h4><a href="{% url 'login' %}">Kamu harus login untuk memberi rating</a></h4>
{% else %}
<form method="post" class="form-inline">{{ form_rating }} {% csrf_token %}
{% if has_rated %}
<button class="form-control mx-3" id="updateButton">Update</button>
<button class="btn btn-danger" id="deleteButton">Delete Rating</button>
{% else %}
<button type="submit" class="form-control mx-3">Submit</button>
{% endif %}
</form>
{% endif %}
</div>
</div>
</header>
......@@ -134,7 +144,73 @@
</div>
</div>
</body>
</html>
{% endblock %}
{% block extra_scripts %}
<script type="text/javascript">
// using jQuery
function getCookie(name) {
var cookieValue = null;
if (document.cookie && document.cookie != '') {
var cookies = document.cookie.split(';');
for (var i = 0; i < cookies.length; i++) {
var cookie = jQuery.trim(cookies[i]);
if (cookie.substring(0, name.length + 1) == (name + '=')) {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
}
var csrftoken = getCookie('csrftoken');
function csrfSafeMethod(method) {
// these HTTP methods do not require CSRF protection
return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
}
function reload () {
window.location = ''
};
$('#deleteButton').click(function () {
console.log("anjing")
$.ajaxSetup({
beforeSend: function (xhr, settings) {
if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
xhr.setRequestHeader("X-CSRFToken", csrftoken);
}
}
});
$.ajax({
type: 'POST',
url: "{% url 'katalog-per-kontributor' contributor.email%}",
data: {
'delete': true
},
success: reload,
dataType: 'html'
});
});
$('#updateButton').click(function () {
$.ajaxSetup({
beforeSend: function (xhr, settings) {
if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
xhr.setRequestHeader("X-CSRFToken", csrftoken);
}
}
});
$.ajax({
type: 'POST',
url: "{% url 'katalog-per-kontributor' contributor.email%}",
data: {
'update': true,
'score': $('#form-rating').val()
},
success: reload,
dataType: 'html'
});
});
</script>
{% endblock %}
\ No newline at end of file
......@@ -57,10 +57,9 @@
<div class="container">
<div class="row header">
<div class="col">
<a href= "/subscribeform"><img src="{% static 'images/sub-btn.png' %}" style="height:100px"></a>
<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 }}'>
......@@ -125,6 +124,32 @@
<div id="collapseTwo" class="collapse" aria-labelledby="headingTwo"
data-parent="#accordionExample">
<div class="card-body">
<ul>
<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>
<li>
<a href="?sort=jumlah_unduh">jumlah unduh</a>
</li>
<li>
<a href="?sort=jumlah_tampilan">jumlah tampilan</a>
</li>
</ul>
</div>
</div>
</div>
......
......@@ -72,8 +72,26 @@
</div>
</div>
</header>
{% if requested_material %}
<table class="table" aria-describedby="Requested Material">
<thead>
<tr>
<th scope="col">No</th>
<th scope="col">Title</th>
<th scope="col">Date</th>
</tr>
</thead>
<tbody>
{% for material in requested_material %}
<tr>
<td>{{ forloop.counter }}</td>
<td>{{ material.title }}</td>
<td>{{ material.timestamp }}</td>
</tr>
{% endfor %}
</tbody>
</table>
{% endif %}
</div>
<!-- /.container -->
......
......@@ -3,18 +3,18 @@
{% block title %}
<title>Sunting Profil | Digipus</title>
{% endblock %}
{% endblock %}
{% block content %}
<div class="container">
<div class="col-20">
<h1 class="mt-2">
{% if user.is_admin %}
Sunting Profil Admin
Sunting Profil Admin
{% elif user.is_contributor %}
Sunting Profil Kontributor
Sunting Profil Kontributor
{% else %}
Sunting Profil User
Sunting Profil User
{% endif %}
</h1>
<hr class="mt-0 mb-4">
......@@ -24,6 +24,26 @@
<div class="col-md-6">
<div class="fieldWrapper">
{{ field.label_tag }} {{ field }}
{% if field.name == 'email' %}
<div class="my-3">
{% if user.is_email_verified %}
<span class="text-success">
Email Status: Verified
</span>
{% else %}
<span class="text-danger">
Email Status: Unverified
<button class="btn btn-success" id='verify-button'
style="background-color: #615CFD; border-color: #615CFD;">
Verify
</button>
</span>
{% endif %}
</div>
{% endif %}
{% if field.errors %}
<span class="text-danger">
{{ field.errors }}
......@@ -33,15 +53,41 @@
<p class="help">{{ field.help_text|safe }}</p>
{% endif %}
</div>
</div>
{% endfor %}
<div class="form-margin"></div>
<div class="col-md-6">
<div class="fieldWrapper">
<button type="submit" class="btn btn-success btn-edit" style="background-color: #615CFD; border-color: #615CFD;">Simpan</button>
<button type="submit" class="btn btn-success btn-edit"
style="background-color: #615CFD; border-color: #615CFD;">Simpan</button>
</div>
</div>
</form>
</div>
</div>
<script type="text/javascript">
$(document).ready(function () {
const csrftoken = document.querySelector('[name=csrfmiddlewaretoken]').value;
$('#verify-button').click(function () {
$.ajax({
url: '/registrasi/send-verify-email',
headers: {
'X-CSRFToken': csrftoken
},
method: 'POST',
data: {
email: $('#id_email').val()
},
success: function (data, status) {
alert(data)
},
})
return false;
});
});
</script>
{% endblock %}
\ No newline at end of file
......@@ -5,6 +5,10 @@
<title>Unggah Materi | Digipus</title>
{% endblock %}
{% block scripts %}
<script src="{% static 'js/upload-preview.js' %}"></script>
{% endblock %}
{% block content %}
<div class="container">
<div class="col-20">
......@@ -36,6 +40,17 @@
{% if field.help_text %}
<p class="help">{{ field.help_text|safe }}</p>
{% endif %}
{% if field.name == 'cover' %}
<div hidden id="frame_cover_parent" class="my-3">
<div class="mb-2">Preview Cover:</div>
<img id="frame_cover" class="constraint-frame" alt="Cover Preview" />
</div>
{% elif field.name == 'content' %}
<div hidden id="frame_content_parent" class="my-3">
<div class="mb-2">Preview Content:</div>
<embed id="frame_content" width="550px" height="550px" />
</div>
{% endif %}
</div>
</div>
{% endfor %}
......
This diff is collapsed.
......@@ -97,19 +97,51 @@ class KatalogPerKontributorView(TemplateView):
page_number = request.GET.get("page")
materi_list_by_page = paginator.get_page(page_number)
context["materi_list"] = materi_list_by_page
contributor = get_object_or_404(User, email=kwargs["email"])
context["form_rating"] = RatingContributorForm(initial={"user": contributor})
contributor = context["contributor"]
context["form_rating"] = RatingContributorForm(initial={
"contributor": contributor,
"user":request.user
})
context["avg_rating"] = User.objects.filter(email=kwargs["email"]) \
.annotate(avg_rating=Avg("ratingcontributor__score"))[0]
context["count_rating"] = RatingContributor.objects.filter(user=contributor).count()
.annotate(avg_rating=Avg("contributor__score"))[0]
context["count_rating"] = RatingContributor.objects.filter(contributor=contributor).count()
if request.user.is_authenticated:
has_rated = RatingContributor.objects.filter(user=request.user, contributor=contributor).exists()
context["has_rated"] = has_rated
return self.render_to_response(context=context)
def post(self, request, *args, **kwargs):
data = RatingContributorForm(request.POST)
if data.is_valid():
data.save()
return redirect("katalog-per-kontributor", email=kwargs["email"])
context = self.get_context_data(**kwargs)
if not request.user.is_authenticated:
raise PermissionDenied(request)
is_delete = request.POST.get('delete', None)
is_update = request.POST.get('update', None)
if is_delete:
rating_contributor = get_object_or_404(
RatingContributor,
user=request.user,
contributor=context["contributor"]
)
rating_contributor.delete()
elif is_update:
score = request.POST.get('score', None)
rating = RatingContributor.objects.filter(