55 */
66import _ from 'lodash' ;
77import React from 'react' ;
8+ import { connect } from 'react-redux' ;
89import PT from 'prop-types' ;
910import { fixStyle } from 'utils/contentful' ;
1011import { getService } from 'services/contentful' ;
@@ -22,6 +23,8 @@ import {
2223 config , Link , isomorphy ,
2324} from 'topcoder-react-utils' ;
2425import qs from 'qs' ;
26+ import LoginModal from 'components/LoginModal' ;
27+ import modalStyle from 'components/LoginModal/modal.scss' ;
2528// SVGs and assets
2629import GestureIcon from 'assets/images/icon-gesture.svg' ;
2730import ReadMoreArrow from 'assets/images/read-more-arrow.svg' ;
@@ -41,21 +44,30 @@ const DEFAULT_BANNER_IMAGE = 'https://images.ctfassets.net/piwi0eufbb2g/7v2hlDsV
4144const RANDOM_BANNERS = [ '6G8mjiTC1mzeSQ2YoUG1gB' , '1DnDD02xX1liHfSTf5Vsn8' , 'HQZ3mN0rR92CbNTkKTHJ5' , '1OLoX8ZsvjAnn4TdGbZESD' , '77jn01UGoQe2gqA7x0coQD' ] ;
4245const RANDOM_BANNER = RANDOM_BANNERS [ _ . random ( 0 , 4 ) ] ;
4346
44- export default class Article extends React . Component {
47+ class Article extends React . Component {
4548 componentDidMount ( ) {
4649 const { fields } = this . props ;
4750 this . setState ( {
4851 upvotes : fields . upvotes || 0 ,
4952 downvotes : fields . downvotes || 0 ,
53+ showLogin : false ,
54+ voting : false ,
5055 } ) ;
5156 }
5257
58+ // eslint-disable-next-line consistent-return
5359 updateVote ( type ) {
54- let userVotes = localStorage . getItem ( LOCAL_STORAGE_KEY ) ;
55- userVotes = userVotes ? JSON . parse ( userVotes ) : { } ;
5660 const {
57- id, spaceName, environment, preview,
61+ id, spaceName, environment, preview, auth ,
5862 } = this . props ;
63+ // check for auth?
64+ if ( ! auth ) {
65+ return this . setState ( {
66+ showLogin : true ,
67+ } ) ;
68+ }
69+ let userVotes = localStorage . getItem ( LOCAL_STORAGE_KEY ) ;
70+ userVotes = userVotes ? JSON . parse ( userVotes ) : { } ;
5971 const articleVote = userVotes [ id ] ;
6072 let { upvotes, downvotes } = this . state ;
6173 // Check if user alredy voted on this article?
@@ -93,17 +105,21 @@ export default class Article extends React.Component {
93105 }
94106 }
95107 // Store user action
108+ this . setState ( {
109+ voting : true ,
110+ } ) ;
96111 getService ( { spaceName, environment, preview } ) . articleVote ( id , {
97112 upvotes,
98113 downvotes,
99- } )
114+ } , auth . tokenV3 )
100115 . then ( ( ) => {
101116 // Only when Contentful enntry was succesfully updated
102117 // then we update the local store and the state
103118 localStorage . setItem ( LOCAL_STORAGE_KEY , JSON . stringify ( userVotes ) ) ;
104119 this . setState ( {
105120 upvotes,
106121 downvotes,
122+ voting : false ,
107123 } ) ;
108124 } ) ;
109125 }
@@ -115,7 +131,9 @@ export default class Article extends React.Component {
115131 const contentfulConfig = {
116132 spaceName, environment, preview,
117133 } ;
118- const { upvotes, downvotes } = this . state || { } ;
134+ const {
135+ upvotes, downvotes, showLogin, voting,
136+ } = this . state || { } ;
119137 let shareUrl ;
120138 if ( isomorphy . isClientSide ( ) ) {
121139 shareUrl = encodeURIComponent ( window . location . href ) ;
@@ -283,7 +301,7 @@ export default class Article extends React.Component {
283301 { /* Voting */ }
284302 < div className = { theme . actionContainer } >
285303 < div className = { theme . action } >
286- < div tabIndex = { 0 } role = "button" className = { theme . circleGreenIcon } onClick = { ( ) => this . updateVote ( 'up' ) } onKeyPress = { ( ) => this . updateVote ( 'up' ) } >
304+ < div tabIndex = { 0 } role = "button" className = { voting ? theme . circleGreenIconDisabled : theme . circleGreenIcon } onClick = { ( ) => this . updateVote ( 'up' ) } onKeyPress = { ( ) => this . updateVote ( 'up' ) } >
287305 < GestureIcon />
288306 </ div >
289307 < span >
@@ -293,7 +311,7 @@ export default class Article extends React.Component {
293311 </ span >
294312 </ div >
295313 < div className = { theme . action } >
296- < div tabIndex = { 0 } role = "button" className = { theme . circleRedIcon } onClick = { ( ) => this . updateVote ( 'down' ) } onKeyPress = { ( ) => this . updateVote ( 'down' ) } >
314+ < div tabIndex = { 0 } role = "button" className = { voting ? theme . circleRedIconDisabled : theme . circleRedIcon } onClick = { ( ) => this . updateVote ( 'down' ) } onKeyPress = { ( ) => this . updateVote ( 'down' ) } >
297315 < GestureIcon />
298316 </ div >
299317 < span > { downvotes } </ span >
@@ -380,6 +398,19 @@ export default class Article extends React.Component {
380398 ) : null
381399 }
382400 </ div >
401+ {
402+ showLogin && (
403+ < LoginModal
404+ // eslint-disable-next-line no-restricted-globals
405+ retUrl = { isomorphy . isClientSide ( ) ? location . href : null }
406+ onCancel = { ( ) => this . setState ( { showLogin : false } ) }
407+ modalTitle = "Want to vote?"
408+ modalText = "You must be a Topcoder member to do that."
409+ utmSource = "thrive_article"
410+ infoNode = { < p className = { modalStyle . regTxt } > Discover < a href = "/community/learn" target = "_blank" rel = "noreferrer" > other features</ a > you can access by becoming a member.</ p > }
411+ />
412+ )
413+ }
383414 </ React . Fragment >
384415 ) ;
385416 }
@@ -388,6 +419,7 @@ export default class Article extends React.Component {
388419Article . defaultProps = {
389420 spaceName : null ,
390421 environment : null ,
422+ auth : null ,
391423} ;
392424
393425Article . propTypes = {
@@ -398,4 +430,16 @@ Article.propTypes = {
398430 preview : PT . bool . isRequired ,
399431 spaceName : PT . string ,
400432 environment : PT . string ,
433+ auth : PT . shape ( ) ,
401434} ;
435+
436+ function mapStateToProps ( state ) {
437+ const auth = state . auth && state . auth . profile ? { ...state . auth } : null ;
438+ return {
439+ auth,
440+ } ;
441+ }
442+
443+ export default connect (
444+ mapStateToProps ,
445+ ) ( Article ) ;
0 commit comments