Created
July 10, 2019 12:35
-
-
Save flavienbonvin/5eefa0b970a417337f06edbdcbc11182 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React, { Component } from 'react' | |
import { Card, Col } from 'antd' | |
import { $, key } from '../../localization/localization' | |
import { Pricing } from '../../models/Pricing' | |
class PricingCol extends Component { | |
render () { | |
const {title, onClick, className, iconType, numberOfPlans, status, hoverable} = this.props | |
return <Col span={8} type={'flex'} align={'middle'}> | |
<Card title={title} hoverable={hoverable} onClick={onClick} className={className}> | |
<img src={process.env.PUBLIC_URL + iconType} style={{height: '80px', width: '80px', marginBottom: '17px'}} alt='icon_basic'/> | |
<p style={{marginBottom: '37px'}}>{numberOfPlans}</p> | |
<p style={{marginBottom: '0px'}}>{Pricing.priceWithCurrentCurrency(status)}</p> | |
<p style={{padding: '20px'}}>{$(key.pricingModalChargedHow, Pricing.annualPriceWithCurrentCurrency(status))}</p> | |
</Card> | |
</Col> | |
} | |
} | |
export default PricingCol |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React, { Component } from 'react' | |
import { USER_STATUS_BASIC, USER_STATUS_PREMIUM, USER_STATUS_STARTER } from '../../models/User' | |
import withCurrentUser from '../currentUser/withCurrentUser' | |
import { compose } from 'recompose' | |
import { Button, Col, Modal, Row, Spin } from 'antd' | |
import { track } from '../../helpers/trackerHelper' | |
import axios from 'axios' | |
import firebase from 'firebase/app' | |
import { $, key } from '../../localization/localization' | |
import { getCustomerCardInformation } from '../../helpers/customerCardInformation' | |
import { Pricing } from '../../models/Pricing' | |
import { StripeForm } from './StripeForm' | |
import PricingCol from './PricingCol' | |
const displayLoading = () => { | |
return <div className="loader-modal"> | |
<Spin size='large'/> | |
</div> | |
} | |
const displayPricingInformation = (onCardClick, classPremium, classStarter, classBasic, hoverablePremium, hoverableStarter, hoverableBasic) => { | |
return <div> | |
<Row gutter={16}> | |
<Col span={24} type={'flex'} align={'middle'} style={{paddingBottom: 40}}>{$(key.pricingModalDescription)}</Col> | |
<PricingCol title={$(key.pricingModalBasicTitle)} | |
onClick={() => onCardClick(USER_STATUS_BASIC)} | |
hoverable={hoverableBasic} | |
className={classBasic} | |
iconType={'/images/icon_basic.png'} | |
numberOfPlans={$(key.pricingModalBasicNumberPlans)} | |
status={USER_STATUS_BASIC}/> | |
<PricingCol title={$(key.pricingModalPremiumTitle)} | |
onClick={() => onCardClick(USER_STATUS_PREMIUM)} | |
hoverable={hoverablePremium} | |
className={classPremium} | |
iconType={'/images/icon_premium.png'} | |
numberOfPlans={$(key.pricingModalPremiumNumberPlans)} | |
status={USER_STATUS_PREMIUM}/> | |
<PricingCol title={$(key.pricingModalStarterTitle)} | |
onClick={() => onCardClick(USER_STATUS_STARTER)} | |
hoverable={hoverableStarter} | |
className={classStarter} | |
iconType={'/images/icon_starter.png'} | |
numberOfPlans={$(key.pricingModalStarterNumberPlans)} | |
status={USER_STATUS_STARTER}/> | |
</Row> | |
</div> | |
} | |
class PricingModal extends Component { | |
constructor (props) { | |
super(props) | |
this.initialState = { | |
pricingModalVisible: false, | |
loading: false, | |
selectedStatus: USER_STATUS_PREMIUM, | |
cardInformation: {}, | |
classBasic: '', | |
classStarter: '', | |
classPremium: 'pricing-selected', | |
hoverableBasic: true, | |
hoverableStarter: true, | |
hoverablePremium: true, | |
} | |
this.state = this.initialState | |
} | |
onCardClick = (e) => { | |
const {currentUser} = this.props | |
if (e === currentUser.status) return | |
else if (currentUser.status === USER_STATUS_STARTER && (e === USER_STATUS_BASIC || e === USER_STATUS_PREMIUM)) return | |
switch (e) { | |
case USER_STATUS_PREMIUM: | |
this.setState({ | |
classBasic: this.state.classBasic === 'pricing-disabled' ? 'pricing-disabled' : '', | |
classPremium: 'pricing-selected', | |
classStarter: '' | |
}) | |
break | |
case USER_STATUS_STARTER: | |
this.setState({ | |
classBasic: this.state.classBasic === 'pricing-disabled' ? 'pricing-disabled' : '', | |
classPremium: '', | |
classStarter: 'pricing-selected' | |
}) | |
break | |
case USER_STATUS_BASIC: | |
this.setState({ | |
classBasic: 'pricing-selected', | |
classPremium: '', | |
classStarter: '' | |
}) | |
break | |
default: | |
break | |
} | |
this.setState({selectedStatus: e}) | |
} | |
pricingModalDisplay = () => { | |
this.setState({pricingModalVisible: true}) | |
this.setInitialStatus() | |
track('pricing_modal', {from: this.props.from}) | |
axios.post(`${process.env.REACT_APP_FUNCTION_URL}/updateStripeName`, { | |
userId: this.props.currentUser.id, | |
name: firebase.auth().currentUser.displayName | |
}) | |
} | |
pricingModalCancel = () => this.setState(this.initialState) | |
componentWillMount () { | |
getCustomerCardInformation(this.props.currentUser.id).then(cardInformation => { | |
this.setState({cardInformation: cardInformation}) | |
}) | |
} | |
onToken = (token, planId) => { | |
this.setState({loading: true}) | |
axios.post(`${process.env.REACT_APP_FUNCTION_URL}/createStripeSubscription`, { | |
userId: this.props.currentUser.id, | |
stripeCustomerId: this.props.currentUser.stripeCustomerId, | |
stripePlanId: planId, | |
token: token.id | |
}) | |
.then(() => { | |
track('user_subscribed', {plan: Pricing.planTypeFor(planId)}) | |
this.setState(this.initialState) | |
}) | |
.catch(() => { | |
this.setState(this.initialState) | |
}) | |
} | |
upgradeTo = (status) => { | |
this.setState({loading: true}) | |
const planId = Pricing.planIdForCurrentCurrency(status) | |
axios.post(`${process.env.REACT_APP_FUNCTION_URL}/updateStripeSubscription`, { | |
userId: this.props.currentUser.id, | |
stripeCustomerId: this.props.currentUser.stripeCustomerId, | |
stripeSubscriptionId: this.props.currentUser.stripeSubscriptionId, | |
stripePlanId: planId, | |
}) | |
.then(() => { | |
track('user_upgraded', {plan: Pricing.planTypeFor(planId)}) | |
this.setState(this.initialState) | |
}) | |
.catch(() => { | |
this.setState(this.initialState) | |
}) | |
} | |
setInitialStatus = () => { | |
const {currentUser} = this.props | |
switch (currentUser.status) { | |
case USER_STATUS_PREMIUM: | |
this.setState({ | |
classPremium: 'pricing-disabled', | |
classStarter: 'pricing-disabled', | |
classBasic: 'pricing-disabled', | |
hoverablePremium: false, | |
hoverableStarter: false, | |
hoverableBasic: false, | |
}) | |
break | |
case USER_STATUS_STARTER: | |
this.setState({ | |
classPremium: 'pricing-selected', | |
classStarter: 'pricing-disabled', | |
classBasic: 'pricing-disabled', | |
hoverablePremium: true, | |
hoverableStarter: false, | |
hoverableBasic: false, | |
}) | |
break | |
case USER_STATUS_BASIC: | |
this.setState({ | |
classPremium: 'pricing-selected', | |
classStarter: '', | |
classBasic: 'pricing-disabled', | |
hoverablePremium: true, | |
hoverableStarter: true, | |
hoverableBasic: false, | |
}) | |
break | |
default: | |
break | |
} | |
} | |
render () { | |
const {buttonRendering, currentUser} = this.props | |
const {cardRegistered} = this.state.cardInformation | |
const {pricingModalVisible, loading, selectedStatus, classPremium, classStarter, classBasic, hoverablePremium, hoverableStarter, hoverableBasic} = this.state | |
const upgradeButton = | |
cardRegistered ? <Button key='buy' type='primary' onClick={() => this.upgradeTo(selectedStatus)}>{$(key.pricingModalUpgradePlanCTA)}</Button> | |
: currentUser.stripeSubscriptionId | |
? <StripeForm key='buy' status={selectedStatus} onToken={() => this.upgradeTo(selectedStatus)}/> | |
: <StripeForm key='buy' status={selectedStatus} onToken={this.onToken}/> | |
if (currentUser.status === USER_STATUS_PREMIUM && !currentUser.hasOutdatedSubscription()) { | |
return null | |
} else { | |
return ( | |
<div> | |
<Modal | |
visible={pricingModalVisible} | |
onCancel={this.pricingModalCancel} | |
title={$(key.pricingModalTitle)} | |
width={893} | |
footer={loading | |
? null | |
: [ | |
<Button key='cancel' className="cancel-button" onClick={this.pricingModalCancel}>{$(key.cancel)}</Button>, | |
upgradeButton | |
]}> | |
{loading | |
? displayLoading() | |
: displayPricingInformation(this.onCardClick, classPremium, classStarter, classBasic, hoverablePremium, hoverableStarter, hoverableBasic) | |
} | |
</Modal> | |
<div onClick={this.pricingModalDisplay}> | |
{buttonRendering} | |
</div> | |
</div> | |
) | |
} | |
} | |
} | |
export default compose( | |
withCurrentUser | |
)(PricingModal) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment