diff --git a/backend/db.sqlite3 b/backend/db.sqlite3 index c569ecb..4f609b8 100644 Binary files a/backend/db.sqlite3 and b/backend/db.sqlite3 differ diff --git a/backend/postings/forms.py b/backend/postings/forms.py index 99d8065..ccd5446 100644 --- a/backend/postings/forms.py +++ b/backend/postings/forms.py @@ -9,4 +9,6 @@ class EntityReviewForm(forms.Form): # The textual content of the review. content = forms.CharField(widget=forms.Textarea) # The id of the entity for which the review is created. - entity_id = forms.IntegerField() \ No newline at end of file + entity_id = forms.IntegerField() + # TEMPORARY name for author name. + name = forms.CharField(max_length=64, required=False) \ No newline at end of file diff --git a/backend/postings/migrations/0005_review_author_name.py b/backend/postings/migrations/0005_review_author_name.py new file mode 100644 index 0000000..dae5770 --- /dev/null +++ b/backend/postings/migrations/0005_review_author_name.py @@ -0,0 +1,18 @@ +# Generated by Django 2.1.1 on 2018-10-18 08:30 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('postings', '0004_remove_reviewhelpfulvote_user'), + ] + + operations = [ + migrations.AddField( + model_name='review', + name='author_name', + field=models.CharField(default='Anonymous', max_length=64), + ), + ] diff --git a/backend/postings/models.py b/backend/postings/models.py index 0054bed..cc3ffdc 100644 --- a/backend/postings/models.py +++ b/backend/postings/models.py @@ -40,6 +40,27 @@ class RateableEntity(models.Model): return None return rating_sum / reviews.count() + # Gets a 5-item list of the count of each rating, and the percentage of total votes. + def getRatingDistribution(self): + reviews = self.review_set.select_related() + distribution = [[0, 0], [0, 0], [0, 0], [0, 0], [0, 0]] + review_count = reviews.count() + + for review in reviews: + distribution[review.rating-1][0] += 1 + + if (review_count > 0): + max_val = 0 + for rating_dist in distribution: + rating_dist[1] = (rating_dist[0] / review_count) * 100 + if (rating_dist[1] > max_val): + max_val = rating_dist[1] + + for rating_dist in distribution: + rating_dist[1] = (rating_dist[1] / max_val) * 100 + + return distribution + # Simply returns the name as the string representation. def __str__(self): return self.name @@ -66,6 +87,8 @@ class Review(models.Model): last_updated_date = models.DateTimeField(auto_now=True) # A reference to the person who created this review. author = models.ForeignKey('postings.User', on_delete=models.PROTECT, null=True, blank=True) + # TEMPORARY: Name of person who gave review. + author_name = models.CharField(max_length=64, default='Anonymous') # Gets the total number of votes which marked this review as 'helpful'. @property diff --git a/backend/postings/static/postings/css/style.css b/backend/postings/static/postings/css/style.css index 867e3fd..ebb9f75 100644 --- a/backend/postings/static/postings/css/style.css +++ b/backend/postings/static/postings/css/style.css @@ -7,19 +7,32 @@ margin-bottom: 0; overflow-y: hidden; } -.fullcontainer { +.box .fullcontainer { display: flex; align-items: center; height: -webkit-calc(100vh - 50px); height: -moz-calc(100vh - 50px); height: calc(100vh - 50px); } +.box3 .fullcontainer { + display: flex; + height: -webkit-calc(100vh - 50px); + height: -moz-calc(100vh - 50px); + height: calc(100vh - 50px); } + .fullcontainer h1 { - font-size: 60px; } + font-size: 50px; } .fullcontainer h3 { margin-bottom: 30px; } +.whitebox { + background: white; + border-radius: 15px; + padding: 30px; + margin-top: 25px; + margin-bottom: 25px; } + .navbar-brand { cursor: pointer; } @@ -39,8 +52,7 @@ body { color: #FFF; } .rating-block { - background-color: #FAFAFA; - border: 1px solid #EFEFEF; + float: right; padding: 15px 15px 20px 15px; border-radius: 3px; } @@ -55,7 +67,9 @@ body { border: 1px solid #EFEFEF; padding: 15px; border-radius: 3px; - margin-bottom: 15px; } + margin-bottom: 15px; + float: right; + width: 100%; } .review-block-name { font-size: 12px; @@ -86,6 +100,10 @@ body { font-size: 24px; color: #d17581; } +.selfcenter { + margin: 0 auto; + float: inherit; } + .hr-line-dashed { border-top: 1px dashed #E7EAEC; color: #ffffff; @@ -106,4 +124,10 @@ h2 { .big-font { font-size: 25px; } +.box3 { + background: #5850c7 url(https://d20ohkaloyme4g.cloudfront.net/img/hero-illustration-module.png) repeat; } + +.box2 { + background: #5850c7 url(https://d20ohkaloyme4g.cloudfront.net/img/hero-illustration-module.png) repeat; } + /*# sourceMappingURL=style.css.map */ diff --git a/backend/postings/static/postings/css/style.css.map b/backend/postings/static/postings/css/style.css.map index 9fd736d..f25b872 100644 --- a/backend/postings/static/postings/css/style.css.map +++ b/backend/postings/static/postings/css/style.css.map @@ -1,6 +1,6 @@ { "version": 3, -"mappings": "AACA,IAAI;EACF,QAAQ,EAAE,QAAQ;EAClB,KAAK,EAAE,IAAI;EACX,UAAU,EAAE,0FAA0F;EACtG,KAAK,EAAE,IAAI;EACX,UAAU,EAAE,MAAM;EAClB,aAAa,EAAE,CAAC;EAChB,UAAU,EAAC,MAAM;;AAEnB,cAAe;EACb,OAAO,EAAE,IAAI;EACb,WAAW,EAAE,MAAM;EACnB,MAAM,EAAE,0BAA0B;EAClC,MAAM,EAAE,uBAAuB;EAC/B,MAAM,EAAE,kBAAkB;;AAE5B,iBAAiB;EACf,SAAS,EAAE,IAAI;;AAEjB,iBAAiB;EACf,aAAa,EAAE,IAAI;;AAIrB,aAAa;EACX,MAAM,EAAC,OAAO;;AAIhB,KAAM;EACJ,UAAU,EAAE,OAAO;EACnB,QAAQ,EAAE,QAAQ;EAClB,KAAK,EAAE,IAAI;;AAGb,MAAM;EACJ,UAAU,EAAE,KAAK;;AAGnB,IAAK;EACH,WAAW,EAAE,IAAI;;AAEnB,SAAS;EACP,gBAAgB,EAAC,OAAO;EACxB,KAAK,EAAC,IAAI;;AAEZ,aAAa;EACX,gBAAgB,EAAC,OAAO;EACxB,MAAM,EAAC,iBAAiB;EACxB,OAAO,EAAC,mBAAmB;EAC3B,aAAa,EAAC,GAAG;;AAEnB,KAAK;EACH,WAAW,EAAC,GAAG;;AAEjB,iBAAiB;EACf,cAAc,EAAC,GAAG;;AAGpB,aAAa;EACX,gBAAgB,EAAC,OAAO;EACxB,MAAM,EAAC,iBAAiB;EACxB,OAAO,EAAC,IAAI;EACZ,aAAa,EAAC,GAAG;EACjB,aAAa,EAAC,IAAI;;AAEpB,kBAAkB;EAChB,SAAS,EAAC,IAAI;EACd,MAAM,EAAC,MAAM;;AAEf,kBAAkB;EAChB,SAAS,EAAC,IAAI;;AAEhB,kBAAkB;EAChB,SAAS,EAAC,IAAI;EACd,aAAa,EAAC,IAAI;;AAEpB,mBAAmB;EACjB,SAAS,EAAC,IAAI;EACd,WAAW,EAAC,GAAG;EACf,aAAa,EAAC,IAAI;;AAEpB,yBAAyB;EACvB,SAAS,EAAC,IAAI;;AAGhB,SAAU;EACR,kBAAkB,EAAE,WAAW;EAC/B,eAAe,EAAE,WAAW;EAC5B,UAAU,EAAE,WAAW;;AAGzB,MACA;EACE,MAAM,EAAE,MAAM;EACd,SAAS,EAAE,IAAI;EACf,KAAK,EAAE,OAAO;;AAOhB,eAAgB;EACd,UAAU,EAAE,kBAAkB;EAC9B,KAAK,EAAE,OAAO;EACd,gBAAgB,EAAE,OAAO;EACzB,MAAM,EAAE,GAAG;EACX,MAAM,EAAE,MAAM;;AAGhB,EAAG;EACD,SAAS,EAAE,IAAI;EACf,WAAW,EAAE,GAAG;;AAElB,OAAQ;EACN,UAAU,EAAE,KAAK;;AAGnB,YAAY;EACV,SAAS,EAAC,IAAI;;AAGhB,SAAS;EACP,SAAS,EAAC,IAAI", +"mappings": "AACA,IAAI;EACF,QAAQ,EAAE,QAAQ;EAClB,KAAK,EAAE,IAAI;EACX,UAAU,EAAE,0FAA0F;EACtG,KAAK,EAAE,IAAI;EACX,UAAU,EAAE,MAAM;EAClB,aAAa,EAAE,CAAC;EAChB,UAAU,EAAC,MAAM;;AAEnB,mBAAoB;EAClB,OAAO,EAAE,IAAI;EACb,WAAW,EAAE,MAAM;EACnB,MAAM,EAAE,0BAA0B;EAClC,MAAM,EAAE,uBAAuB;EAC/B,MAAM,EAAE,kBAAkB;;AAG5B,oBAAqB;EACnB,OAAO,EAAE,IAAI;EACb,MAAM,EAAE,0BAA0B;EAClC,MAAM,EAAE,uBAAuB;EAC/B,MAAM,EAAE,kBAAkB;;AAE5B,iBAAiB;EACf,SAAS,EAAE,IAAI;;AAEjB,iBAAiB;EACf,aAAa,EAAE,IAAI;;AAGrB,SAAS;EACP,UAAU,EAAE,KAAK;EACjB,aAAa,EAAE,IAAI;EACnB,OAAO,EAAE,IAAI;EACb,UAAU,EAAC,IAAI;EACf,aAAa,EAAC,IAAI;;AAIpB,aAAa;EACX,MAAM,EAAC,OAAO;;AAIhB,KAAM;EACJ,UAAU,EAAE,OAAO;EACnB,QAAQ,EAAE,QAAQ;EAClB,KAAK,EAAE,IAAI;;AAGb,MAAM;EACJ,UAAU,EAAE,KAAK;;AAGnB,IAAK;EACH,WAAW,EAAE,IAAI;;AAEnB,SAAS;EACP,gBAAgB,EAAC,OAAO;EACxB,KAAK,EAAC,IAAI;;AAEZ,aAAa;EACX,KAAK,EAAC,KAAK;EACX,OAAO,EAAC,mBAAmB;EAC3B,aAAa,EAAC,GAAG;;AAEnB,KAAK;EACH,WAAW,EAAC,GAAG;;AAEjB,iBAAiB;EACf,cAAc,EAAC,GAAG;;AAGpB,aAAa;EACX,gBAAgB,EAAC,OAAO;EACxB,MAAM,EAAC,iBAAiB;EACxB,OAAO,EAAC,IAAI;EACZ,aAAa,EAAC,GAAG;EACjB,aAAa,EAAC,IAAI;EAClB,KAAK,EAAE,KAAK;EACZ,KAAK,EAAC,IAAI;;AAEZ,kBAAkB;EAChB,SAAS,EAAC,IAAI;EACd,MAAM,EAAC,MAAM;;AAEf,kBAAkB;EAChB,SAAS,EAAC,IAAI;;AAEhB,kBAAkB;EAChB,SAAS,EAAC,IAAI;EACd,aAAa,EAAC,IAAI;;AAEpB,mBAAmB;EACjB,SAAS,EAAC,IAAI;EACd,WAAW,EAAC,GAAG;EACf,aAAa,EAAC,IAAI;;AAEpB,yBAAyB;EACvB,SAAS,EAAC,IAAI;;AAGhB,SAAU;EACR,kBAAkB,EAAE,WAAW;EAC/B,eAAe,EAAE,WAAW;EAC5B,UAAU,EAAE,WAAW;;AAGzB,MACA;EACE,MAAM,EAAE,MAAM;EACd,SAAS,EAAE,IAAI;EACf,KAAK,EAAE,OAAO;;AAOhB,WAAW;EACT,MAAM,EAAE,MAAM;EACd,KAAK,EAAE,OAAO;;AAGhB,eAAgB;EACd,UAAU,EAAE,kBAAkB;EAC9B,KAAK,EAAE,OAAO;EACd,gBAAgB,EAAE,OAAO;EACzB,MAAM,EAAE,GAAG;EACX,MAAM,EAAE,MAAM;;AAGhB,EAAG;EACD,SAAS,EAAE,IAAI;EACf,WAAW,EAAE,GAAG;;AAElB,OAAQ;EACN,UAAU,EAAE,KAAK;;AAGnB,YAAY;EACV,SAAS,EAAC,IAAI;;AAGhB,SAAS;EACP,SAAS,EAAC,IAAI;;AAGhB,KAAK;EACH,UAAU,EAAE,0FAA0F;;AAExG,KAAK;EACH,UAAU,EAAE,0FAA0F", "sources": ["style.scss"], "names": [], "file": "style.css" diff --git a/backend/postings/static/postings/css/style.scss b/backend/postings/static/postings/css/style.scss index d964ee3..bb6eb86 100644 --- a/backend/postings/static/postings/css/style.scss +++ b/backend/postings/static/postings/css/style.scss @@ -8,20 +8,35 @@ margin-bottom: 0; overflow-y:hidden; } -.fullcontainer { +.box .fullcontainer { display: flex; align-items: center; height: -webkit-calc(100vh - 50px); height: -moz-calc(100vh - 50px); height: calc(100vh - 50px); } + +.box3 .fullcontainer { + display: flex; + height: -webkit-calc(100vh - 50px); + height: -moz-calc(100vh - 50px); + height: calc(100vh - 50px); +} .fullcontainer h1{ - font-size: 60px; + font-size: 50px; } .fullcontainer h3{ margin-bottom: 30px; } +.whitebox{ + background: white; + border-radius: 15px; + padding: 30px; + margin-top:25px; + margin-bottom:25px; +} + .navbar-brand{ cursor:pointer @@ -46,8 +61,7 @@ body { color:#FFF; } .rating-block{ - background-color:#FAFAFA; - border:1px solid #EFEFEF; + float:right; padding:15px 15px 20px 15px; border-radius:3px; } @@ -64,6 +78,8 @@ body { padding:15px; border-radius:3px; margin-bottom:15px; + float: right; + width:100%; } .review-block-name{ font-size:12px; @@ -102,6 +118,11 @@ body { } +.selfcenter{ + margin: 0 auto; + float: inherit; +} + .hr-line-dashed { border-top: 1px dashed #E7EAEC; color: #ffffff; @@ -124,4 +145,11 @@ h2 { .big-font{ font-size:25px; +} + +.box3{ + background: #5850c7 url(https://d20ohkaloyme4g.cloudfront.net/img/hero-illustration-module.png) repeat; +} +.box2{ + background: #5850c7 url(https://d20ohkaloyme4g.cloudfront.net/img/hero-illustration-module.png) repeat; } \ No newline at end of file diff --git a/backend/postings/static/postings/js/main.js b/backend/postings/static/postings/js/main.js index 64bda14..1ff3fa2 100644 --- a/backend/postings/static/postings/js/main.js +++ b/backend/postings/static/postings/js/main.js @@ -65,7 +65,7 @@ $(function(){ }); ///Set the stars for the average - if(i>avg){ + if((isNaN(parseFloat(avg)))||i>avg){ $(".rating-block").append(""); diff --git a/backend/postings/templates/postings/frontend/entity.html b/backend/postings/templates/postings/frontend/entity.html index 000ecdf..167e42f 100644 --- a/backend/postings/templates/postings/frontend/entity.html +++ b/backend/postings/templates/postings/frontend/entity.html @@ -8,27 +8,103 @@ {% endblock %} {% block content %} -
-
-
-

{{ entity.name }} {{ entity.average }}

+ +
+
+ {% block entity_info %} +
+
+

{{ entity.name }}

+
-
+ {% endblock %}
-
+
-

Average user rating

+

Average user rating

{{ entity.average_rating|floatformat:"-2" }} / 5

+ {# Rating Distribution Display #} +
+

Rating breakdown

+
+
+
5
+
+
+
+
+ 80% Complete (danger) +
+
+
+ +
+
+
+
4
+
+
+
+
+ 80% Complete (danger) +
+
+
+ +
+
+
+
3
+
+
+
+
+ 80% Complete (danger) +
+
+
+ +
+
+
+
2
+
+
+
+
+ 80% Complete (danger) +
+
+
+ +
+
+
+
1
+
+
+
+
+ 80% Complete (danger) +
+
+
+
+
+ + + +
-
+

-
+
@@ -39,12 +115,13 @@
+ {% endblock %} \ No newline at end of file diff --git a/backend/postings/templates/postings/frontend/review.html b/backend/postings/templates/postings/frontend/review.html index ab4f843..39d12ba 100644 --- a/backend/postings/templates/postings/frontend/review.html +++ b/backend/postings/templates/postings/frontend/review.html @@ -7,17 +7,17 @@ {# Username #} - + {# Date at which review was posted. #} -
{{ review.created_date|date:"j M, Y" }}
+

{{ review.created_date|date:"j M, Y" }}


-
{{ review.title }}
-
{{ review.content }}
+

{{ review.title }}

+

{{ review.content }}

diff --git a/backend/postings/views.py b/backend/postings/views.py index 7ffeeaf..c98473d 100644 --- a/backend/postings/views.py +++ b/backend/postings/views.py @@ -49,6 +49,7 @@ def rateable_entity(request, entity_id): # Set any auxiliary variables needed, like average rating. # This MUST be done after categorizing the object above. entity.average_rating = entity.getAverageRating() + entity.rating_distribution = entity.getRatingDistribution() except RateableEntity.DoesNotExist: raise Http404("RateableEntity with id " + str(entity_id) + " does not exist.") @@ -72,6 +73,12 @@ def post_review(request): title = form.cleaned_data['title'] content = form.cleaned_data['content'] entity_id = form.cleaned_data['entity_id'] + + if 'name' in request.POST: + author_name = form.cleaned_data['name'] + else: + author_name = None + try: entity = RateableEntity.objects.get(pk=entity_id) except RateableEntity.DoesNotExist: @@ -80,6 +87,7 @@ def post_review(request): # Creates the new Review object from the posted data. review = Review.objects.create( rating=rating, + author_name=author_name, title=title, content=content, rateable_entity=entity