diff --git a/network-api/networkapi/buyersguide/templates/product_page.html b/network-api/networkapi/buyersguide/templates/product_page.html index d18a0e3b1e3..b1d33283e0e 100644 --- a/network-api/networkapi/buyersguide/templates/product_page.html +++ b/network-api/networkapi/buyersguide/templates/product_page.html @@ -23,7 +23,11 @@

{{product.name}}

{{product.blurb}}
-
+
+ {% csrf_token %} + + +

Can it spy on me?

diff --git a/source/js/buyers-guide/bg-main.js b/source/js/buyers-guide/bg-main.js index b1781dd6692..7ba67f21a5a 100644 --- a/source/js/buyers-guide/bg-main.js +++ b/source/js/buyers-guide/bg-main.js @@ -75,7 +75,23 @@ let main = { injectReactComponents() { if (document.querySelectorAll(`.creep-vote-target`)) { Array.from(document.querySelectorAll(`.creep-vote-target`)).forEach(element => { - ReactDOM.render(, element); + let csrf = element.querySelector(`input[name=csrfmiddlewaretoken]`); + let productID = element.querySelector(`input[name=productID]`).value; + let votes = element.querySelector(`input[name=votes]`).value; + + try { + votes = JSON.parse(votes.replace(/'/g,`"`)); + } catch (e) { + votes = { + creepiness: { + average: 50, + 'vote_breakdown': {'0': 0, '1': 0, '2': 0, '3': 0, '4': 0} + }, + confidence: {'0': 0, '1': 0} + }; + } + + ReactDOM.render(, element); }); } diff --git a/source/js/buyers-guide/components/creep-vote/creep-vote.jsx b/source/js/buyers-guide/components/creep-vote/creep-vote.jsx index d70d50041c2..1edc6bfb8c9 100644 --- a/source/js/buyers-guide/components/creep-vote/creep-vote.jsx +++ b/source/js/buyers-guide/components/creep-vote/creep-vote.jsx @@ -6,34 +6,103 @@ import LikelyhoodChart from '../likelyhood-chart/likelyhood-chart.jsx'; export default class CreepVote extends React.Component { constructor(props) { super(props); - this.state = this.getInitialState(); - - this.submitVote = this.submitVote.bind(this); + console.log(this.props.votes); } getInitialState() { + let conf = this.props.votes.confidence; + let totalVotes = conf[0] + conf[1]; + return { + totalVotes, + creepiness: 50, + confidence: undefined, didVote: false }; } - submitVote(){ - this.setState({didVote:true}); + showVoteResult() { + if (this.state.creepinessSubmitted && this.state.confidenceSubmitted) { + this.setState({ didVote: true }); + } + } + + sendVoteFor(payload) { + let attribute = payload.attribute; + let url = "/privacynotincluded/vote"; + let method = "POST"; + let credentials = 'same-origin'; + let headers = { + "X-CSRFToken": this.props.csrf, + "Content-Type": "application/json" + }; + + fetch(url, { + method, + credentials, + headers, + body: JSON.stringify(payload) + }) + .then(response => { + let update = {}; + update[`${attribute}Submitted`] = true; + this.setState(update, () => { + this.showVoteResult() + }); + }) + .catch(e => { + console.warn(e); + this.setState({ disableVoteButton: false }); + }); + } + + submitVote(evt) { + evt.preventDefault(); + + let confidence = this.state.confidence; + + if (confidence === undefined) { + return; + } + + this.setState({ disableVoteButton: true }); + + let productID = this.props.productID; + + this.sendVoteFor({ + attribute: 'confidence', + productID, + value: confidence, + }); + + this.sendVoteFor({ + attribute: 'creepiness', + productID, + value: this.state.creepiness + }); + } + + setCreepiness(creepiness) { + this.setState({ creepiness }); + } + + setConfidence(confidence) { + this.setState({ confidence }); } /** * @returns {jsx} What users see when they haven't voted on this product yet. */ renderVoteAsk() { - return (
+ return ( this.submitVote(evt)}>

How creepy is this product?

Majority of voters think it is super creepy

- + this.setCreepiness(value)}>
@@ -43,10 +112,12 @@ export default class CreepVote extends React.Component {
@@ -54,8 +125,8 @@ export default class CreepVote extends React.Component {
- -

367 votes

+ +

{this.state.totalVotes} votes

); @@ -69,12 +140,16 @@ export default class CreepVote extends React.Component {
-

Thanks for voting! Here are the results

-
367 Votes
+

Thanks for voting! Here are the results so far:

+
{this.state.totalVotes} Votes
-
-
+
+ +
+
+ +
diff --git a/source/js/buyers-guide/components/creep-vote/creep-vote.scss b/source/js/buyers-guide/components/creep-vote/creep-vote.scss index 032e7258270..a9f3a1f4942 100644 --- a/source/js/buyers-guide/components/creep-vote/creep-vote.scss +++ b/source/js/buyers-guide/components/creep-vote/creep-vote.scss @@ -5,6 +5,16 @@ $btn-shadow-width: 3px; border-bottom: 1px solid #c8c8ca; border-top: 1px solid #c8c8ca; + button[disabled] { + color: #bbbbbb; + + &.btn-ghost:hover { + cursor: auto; + color: inherit; + background: inherit; + } + } + .btn-group { .btn { border: 1px solid $medium-gray; @@ -12,6 +22,7 @@ $btn-shadow-width: 3px; color: black; text-transform: initial; transition: all 0.1s linear; + } input { display: none; } diff --git a/source/js/buyers-guide/components/creepiness-chart/creepiness-chart.jsx b/source/js/buyers-guide/components/creepiness-chart/creepiness-chart.jsx index 84785f483d8..2ff9deaa5e8 100644 --- a/source/js/buyers-guide/components/creepiness-chart/creepiness-chart.jsx +++ b/source/js/buyers-guide/components/creepiness-chart/creepiness-chart.jsx @@ -3,64 +3,47 @@ import React from 'react'; export default class CreepChart extends React.Component { constructor(props) { super(props); - this.state = this.getInitialState(); - } getInitialState() { + let values = this.props.values; + let data = [ + {c: 'no-creep', label: 'Not creepy', value: values[0], offset: 0}, + {c: 'little-creep', label: 'A little creepy', value: values[1], offset: 225}, + {c: 'somewhat-creep', label: 'Somewhat creepy', value: values[2], offset: 475}, + {c: 'very-creep', label: 'Very creepy', value: values[3], offset: 725}, + {c: 'super-creep', label: 'Super creepy', value: values[4], offset: 975} + ]; + let sum = data.reduce((tally, v) => tally + v.value, 0); + return { + totalCreepiness: sum, + creepinessData: data }; } - render(){ + render() { return (
- {/* TODO: Pull in vote% and apply as pixel height, td value. - TODO: Apply "your-vote" class to the level of the user's vote - Height needs to be in px so that the value sits on top of the bar */} - - - - - - - - - - - - - - - - - - - - + { + this.state.creepinessData.map(data => { + let percent = Math.round(100 * data.value / this.state.totalCreepiness); + console.log(data.value, this.state.totalCreepiness, percent); + return ( + + + + + ); + }) + }
-
- Not creepy - -
1%
-
- A little creepy - -
2%
-
- Somewhat creepy - -
3%
-
- Very creepy - -
4%
-
- Super creepy - -
5%
+
+ {data.label} + +
{percent}%
diff --git a/source/js/buyers-guide/components/creepometer/creepometer.jsx b/source/js/buyers-guide/components/creepometer/creepometer.jsx index eb55c7004e5..7434d162b25 100644 --- a/source/js/buyers-guide/components/creepometer/creepometer.jsx +++ b/source/js/buyers-guide/components/creepometer/creepometer.jsx @@ -44,7 +44,7 @@ export default class Creepometer extends React.Component { slideMove(e) { if (this.state.isHandleGrabbed) { - let clientX, sliderLeftEdgeX, offset; + let clientX, sliderLeftEdgeX, offset, value=50; if (e.nativeEvent.type === `touchmove`){ clientX = e.nativeEvent.touches[0].pageX; @@ -53,11 +53,16 @@ export default class Creepometer extends React.Component { } sliderLeftEdgeX = this.sliderElement.getBoundingClientRect().left; offset = Math.floor(clientX - sliderLeftEdgeX); + value = Math.floor(offset / this.sliderElement.scrollWidth * this.encodedStepCount); this.setState({ handleOffset: offset, - encodedValue: Math.floor(offset / this.sliderElement.scrollWidth * this.encodedStepCount) + encodedValue: value }); + + if (this.props.onChange) { + this.props.onChange(value); + } } } diff --git a/source/js/buyers-guide/components/likelyhood-chart/likelyhood-chart.jsx b/source/js/buyers-guide/components/likelyhood-chart/likelyhood-chart.jsx index 00f75d60350..df614dcac24 100644 --- a/source/js/buyers-guide/components/likelyhood-chart/likelyhood-chart.jsx +++ b/source/js/buyers-guide/components/likelyhood-chart/likelyhood-chart.jsx @@ -5,17 +5,12 @@ import React from 'react'; export default class LikelyhoodChart extends React.Component { constructor(props) { super(props); - - this.state = this.getInitialState(); - - } - - getInitialState() { - return { - }; } render(){ + let values = this.props.values; + let total = values[0] + values[1]; + let perc = Math.round(100 * values[0]/total, 10); return (
@@ -25,8 +20,8 @@ export default class LikelyhoodChart extends React.Component { Likely @@ -34,8 +29,8 @@ export default class LikelyhoodChart extends React.Component { Not likely
- - 95% Likely to buy it + + {100 - perc}% Likely to buy it
- - 5% Not likely to buy it + + {perc}% Not likely to buy it