* reviews displaying

This commit is contained in:
Seth Call 2016-01-14 15:23:11 -06:00
parent 7fe1824085
commit 1869ee021d
9 changed files with 375 additions and 2 deletions

View File

@ -38,6 +38,7 @@
//= require jquery.exists
//= require jquery.payment
//= require jquery.visible
//= require jquery.jstarbox
//= require classnames
//= require reflux
//= require howler.core.js

View File

@ -58,6 +58,31 @@ proficiencyDescriptionMap = {
onLanguagesChanged: () ->
@setState({languages: true})
componentDidMount: () ->
@root = $(@getDOMNode())
@starbox()
componentDidUpdate:() ->
@starbox()
starbox:() ->
$ratings = @root.find('.ratings-box')
$ratings.each((i, value) =>
$element = $(value)
rating = $element.attr('data-ratings')
rating = parseFloat(rating)
#$element.starbox('destroy')
$element.starbox({
average: rating,
changeable: false,
autoUpdateAverage: false,
ghosting: false
}).show()
)
beforeShow: (e) ->
@setState({userId: e.id, user: null})
rest.getUserDetail({
@ -470,8 +495,37 @@ proficiencyDescriptionMap = {
user = @state.user
teacher = user.teacher
summary = teacher.review_summary || {avg_rating: 0, review_count: 0}
if summary.review_count == 1
reviewCount = '1 review'
else
reviewCount = sumarry.review_count + ' reviews'
reviews = []
for review in teacher.recent_reviews
photo_url = review.user.photo_url
if !photo_url?
photo_url = '/assets/shared/avatar_generic.png'
name = `<div className="reviewer-name">{review.user.name}</div>`
reviews.push(`<div className="review">
<div className="review-header">
<div className="avatar small">
<img src={photo_url} />
</div>
{name}
<div className="ratings-box hidden" data-ratings={review.rating / 5 }/>
<div className="review-time">{context.JK.formatDateShort(review.created_at)}</div>
</div>
<div className="review-content" dangerouslySetInnerHTML={{__html: review.description}}></div>
</div>`)
`<div className="ratings-block info-block">
Coming Soon!
<h3>Ratings & Reviews</h3>
<h4>{user.first_name} Summary Rating: <div data-ratings={summary.avg_rating / 5} className="ratings-box hidden"/> <div className="review-count">({reviewCount})</div></h4>
{reviews}
</div>`
prices: () ->

View File

@ -714,6 +714,11 @@
return context.JK.padString(date.getMonth() + 1, 2) + "/" + context.JK.padString(date.getDate(), 2) + "/" + date.getFullYear() + " - " + date.toLocaleTimeString();
}
context.JK.formatDateShort = function (dateString) {
var date = dateString instanceof Date ? dateString : new Date(dateString);
return months[date.getMonth()] + ' ' + date.getDate() + ', ' + date.getFullYear();
}
// returns Fri May 20, 2013
context.JK.formatDate = function (dateString, suppressDay) {
var date = new Date(dateString);

View File

@ -11,6 +11,7 @@
*= require_self
*= require web/Raleway
*= require jquery.ui.datepicker
*= require jquery.jstarbox
*= require ./ie
*= require jquery.bt
*= require easydropdown

View File

@ -162,4 +162,85 @@
}
.years {float:right}
}
.ratings-block {
h3 {
margin-bottom:30px;
}
h4 {
margin-top:20px;
font-weight:bold;
margin-bottom:20px;
color:white;
}
.ratings-box {
display:inline-block;
}
.stars {
position: relative;
top: 3px;
left: 20px;
}
.review-count {
font-weight:normal;
display: inline-block;
margin-left: 40px;
font-size:12px;
color:$ColorTextTypical;
}
.review {
border-width:1px 0 0 0;
border-color:$ColorTextTypical;
border-style:solid;
padding:20px 3px;
.review-header {
margin-bottom:20px;
}
.avatar {
display:inline-block;
padding:1px;
width:36px;
height:36px;
background-color:#ed3618;
margin:0 20px 0 0;
-webkit-border-radius:18px;
-moz-border-radius:18px;
border-radius:18px;
}
.avatar-small {
float:left;
}
.avatar img {
width: 36px;
height: 36px;
-webkit-border-radius:18px;
-moz-border-radius:18px;
border-radius:18px;
}
.stars {
top:4px;
}
.review-time {
float:right;
}
.reviewer-name {
height:40px;
display:inline-block;
line-height:40px;
vertical-align: middle;
}
.reviewer-content {
}
}
}
}

View File

@ -40,7 +40,7 @@ child :review_summary => :review_summary do
end
child :recent_reviews => :recent_reviews do
attributes :description, :rating
attributes :description, :rating, :created_at
child(:user => :user) {
attributes :id, :first_name, :last_name, :name, :photo_url

View File

@ -64,6 +64,18 @@ namespace :db do
make_recording
end
task populate_reviews: :environment do
Teacher.all.each do |teacher|
@review = Review.new
@review.target_id = teacher.id
@review.user = User.last
@review.rating = 5
@review.description = 'Omg This teacher was so good. It was like whoa. Crazy whoa.'
@review.target_type = 'JamRuby::Teacher'
@review.save
end
end
task populate_jam_track_genres: :environment do
genres = Genre.all
genres = genres.sample(genres.count * 0.75)

View File

@ -0,0 +1,171 @@
/*
* Copyright (c) 2011 Raphael Schweikert, http://sabberworm.com/
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
(function() {
var dataKey = 'jstarbox-data';
var eventNamespace = '.jstarbox';
var defaultOptions = {
average: 0.5,
stars: 5,
buttons: 5, //false will allow any value between 0 and 1 to be set
ghosting: false,
changeable: true, // true, false, or "once"
autoUpdateAverage: false
};
var methods = {
destroy: function() {
this.removeData(dataKey);
this.unbind(eventNamespace).find('*').unbind(eventNamespace);
this.removeClass('starbox');
this.empty();
},
getValue: function() {
var data = this.data(dataKey);
return data.opts.currentValue;
},
setValue: function(val) {
var data = this.data(dataKey);
var size = arguments[1] || data.positioner.width();
var include_ghost = arguments[2];
if(include_ghost) {
data.ghost.css({width: ""+(val*size)+"px"});
}
data.colorbar.css({width: ""+(val*size)+"px"});
data.opts.currentValue = val;
},
getOption: function(option) {
var data = this.data(dataKey);
return data.opts[option];
},
setOption: function(option, value) {
var data = this.data(dataKey);
if(option === 'changeable' && value === false) {
data.positioner.triggerHandler('mouseleave');
}
data.opts[option] = value;
if(option === 'stars') {
data.methods.update_stars();
} else if(option === 'average') {
this.starbox('setValue', value, null, true);
}
},
markAsRated: function() {
var data = this.data(dataKey);
data.positioner.addClass('rated');
}
};
jQuery.fn.extend({
starbox: function(options) {
if(options.constructor === String && methods[options]) {
return methods[options].apply(this, Array.prototype.slice.call(arguments, 1)) || this;
}
options = jQuery.extend({}, defaultOptions, options);
this.each(function(count) {
var element = jQuery(this);
var opts = jQuery.extend({}, options);
var data = {
opts: opts,
methods: {}
};
element.data(dataKey, data);
var positioner = data.positioner = jQuery('<div/>').addClass('positioner');
var stars = data.stars = jQuery('<div/>').addClass('stars').appendTo(positioner);
var ghost = data.ghost = jQuery('<div/>').addClass('ghost').hide().appendTo(stars);
var colorbar = data.colorbar = jQuery('<div/>').addClass('colorbar').appendTo(stars);
var star_holder = data.star_holder = jQuery('<div/>').addClass('star_holder').appendTo(stars);
element.empty().addClass('starbox').append(positioner);
data.methods.update_stars = function() {
star_holder.empty();
for(var i=0;i<opts.stars;i++) {
var star = jQuery('<div/>').addClass('star').addClass('star-'+i).appendTo(star_holder);
}
// (Re-)Set initial value
methods.setOption.call(element, 'average', opts.average);
};
data.methods.update_stars();
positioner.bind('mousemove'+eventNamespace, function(event) {
if(!opts.changeable) return;
if(opts.ghosting) {
ghost.show();
}
var size = positioner.width();
var x = event.layerX;
if(x === undefined) {
x = (event.pageX-positioner.offset().left);
}
var val = x/size;
if(opts.buttons) {
val *= opts.buttons;
val = Math.floor(val);
val += 1;
val /= opts.buttons;
}
positioner.addClass('hover');
methods.setValue.call(element, val, size);
element.starbox('setValue', val, size);
element.triggerHandler('starbox-value-moved', val);
});
positioner.bind('mouseleave'+eventNamespace, function(event) {
if(!opts.changeable) return;
ghost.hide();
positioner.removeClass('hover');
methods.setValue.call(element, opts.average);
});
positioner.bind('click'+eventNamespace, function(event) {
if(!opts.changeable) return;
if(opts.autoUpdateAverage) {
methods.markAsRated.call(element);
methods.setOption.call(element, 'average', opts.currentValue);
}
var new_average = element.triggerHandler('starbox-value-changed', opts.currentValue);
if(!isNaN(parseFloat(new_average)) && isFinite(new_average)) {
methods.setOption.call(element, 'average', new_average);
}
if(opts.changeable === 'once') {
methods.setOption.call(element, 'changeable', false);
}
});
});
return this;
}
});
})();

View File

@ -0,0 +1,48 @@
.positioner {
position: relative;
display: inline-block;
line-height: 0;
}
.starbox .colorbar,
.starbox .ghost {
z-index: 0;
position: absolute;
top: 0;
bottom: 0;
left: 0;
}
.starbox .stars {
display: inline-block;
}
.starbox .stars .star_holder {
position: relative;
z-index: 1;
}
.starbox .stars .star_holder .star {
display: inline-block;
vertical-align: baseline;
background-repeat: no-repeat;
}
/* Override with your own image and size… */
.starbox .stars .star_holder .star {
background-image: url('/assets/jstarbox-5-large.png');
background-size:cover;
width: 20px;
height: 20px;
}
/* Override with your own colours… */
.starbox .stars { background: #ccc; }
.starbox .rated .stars { background: #dcdcdc; }
.starbox .rated.hover .stars { background: transparent; }
.starbox .colorbar { background: #ed3618; }
.starbox .hover .colorbar { background: #ffcc1c; }
.starbox .rated .colorbar { background: #64b2ff; }
.starbox .rated.hover .colorbar { background: #1e90ff; }
.starbox .ghost { background: #a1a1a1; }