Skip to content

Instantly share code, notes, and snippets.

@matheuscouto
Created July 1, 2019 19:42
Show Gist options
  • Save matheuscouto/d392af1396774ef959edee08c0a87449 to your computer and use it in GitHub Desktop.
Save matheuscouto/d392af1396774ef959edee08c0a87449 to your computer and use it in GitHub Desktop.
templates/commpons/settings/index.js
import React, { Component } from 'react';
import Television from './../../../pages/Television';
import { getPlansPublisher } from '../../../utils/redux/actions/publisher/PlansActions';
import { updateUserCreditCard, refreshUserData} from '../../../utils/redux/actions/auth/actions';
import Slider from 'react-slick';
import validate from '../../utils/form/utilsForm/validForm' // validate({cpf: 'xxxx'}) => errors
import moment, { duration } from 'moment';
import MaskedInput from 'react-text-mask';
import { map } from 'lodash';
import {
EditionFieldWrapper,
RootWrapper,
MainWrapper,
UserDataWrapper,
SubscriptionDataWrapper,
SwitchPlanWrapper,
FullModal,
EditPaymentInfoWrapper,
SubmitButton,
ChangePasswordWrapper,
TransactionalDataWrapper,
PlanBox,
PlanWrapper,
SliderWrapper,
CollectionWrapper,
ClosePanel
} from './settingsStyle';
import { connect } from 'react-redux';
import { Router } from '../../../routes';
import { MediaService } from '../../../utils/api/mediaService';
// REDUX
import {
openDialog as updateDialogAction,
authConfirmUserSocialLogin,
authErrorUserSocialLogin,
authUpdateToken,
authConfirmUserAccount,
authUserLogout
} from '../../../utils/redux/actions/modalActions';
import {
getCollectionsOpen,
getCollections
} from '../../../utils/redux/actions/publisher/collectionActions';
import LinkSlug from '../../commons/linkSlug/LinkSlug';
import withAuthentication from '../../../utils/functions/withAuthentication';
import { UserService } from '../../../utils/api/userService';
moment.locale('pt-br')
class SettingsComponent extends Component {
state = {
didLoadUserData: false,
didLoadPlans: false,
didRefreshUserData: false, // because of the cache issue
profilePictureUrl: undefined,
previewProfilePictureUrl: 'https://proxy.duckduckgo.com/iu/?u=https%3A%2F%2Fi.dailymail.co.uk%2Fi%2Fpix%2F2017%2F04%2F20%2F13%2F3F6B966D00000578-4428630-image-m-80_1492690622006.jpg&f=1',
paymentMethod: 'credit-card',
paymentStatus: 'up-to-date',
switchingPlan: false,
subRouteTitle: '-',
subRouteSubtitle: '-',
fieldValues: {
personalData: {
name: '',
lastName: '',
cpf: '',
errors: ['cpf'],
id: ''
},
changePassword: {
currentPassword: '',
newPassword: '',
confirmNewPassword: '',
confirmPasswordWarning: 'none', // none | empty | different | weak | wrong-password
errors: ['currentPassword', 'newPassword', 'confirmNewPassword'],
},
deleteAccount: {
email: '',
errors: ['email'],
},
editCreditCard: {
number: '',
holderName: '',
expirationDate: '',
securityCode: '',
errors: ['number', 'holderName', 'expirationDate', 'securityCode'],
}
},
isMobile: false
}
componentDidMount() {
if(this.props.publisher.revenueModel === 'SUBSCRIPTION') {
this.switchRoute('subscription-data')();
} else {
this.switchRoute('transactional-data')();
}
this.updateResponsiveness();
window.addEventListener('resize', this.updateResponsiveness);
}
// Get current user favorite medias
getUserFavoriteMedias = async () => {
const { auth } = this.props;
MediaService.getAllFavMedias(auth.accessToken.accessToken).then(response => {
this.setState(state => ({
...state,
userFavorites: response,
}))
return response
})
}
// Get current user favorite collections
getUserFavoriteCollection = async () => {
const { auth } = this.props;
MediaService.getAllFavCollections(auth.accessToken.accessToken).then(response => {
this.setState(state => ({
...state,
userFavoritesCollection: response,
}))
return response
})
console.log(this.state.userFavoritesCollection)
}
updateResponsiveness = () => {
if(window.innerWidth > 1132 && this.state.isMobile) {
this.setState(state => ({
...state,
isMobile: false,
}))
if(this.props.publisher.revenueModel === 'SUBSCRIPTION') {
this.switchRoute('subscription-data')();
} else {
this.switchRoute('transactional-data')();
}
} else if(window.innerWidth <= 1132 && !this.state.isMobile) {
this.setState(state => ({
...state,
isMobile: true,
}))
this.switchRoute('mobile-navigator')();
}
}
componentDidUpdate(oldProps, oldState) {
const { didLoadUserData, didLoadPlans, didRefreshUserData, fieldValues: { changePassword }, userFavorites, userFavoritesCollection } = this.state;
// if(oldState) {
// const oldChangePasswordFields = oldState.fieldValues.changePassword
// const userTypedPasswordSession = oldChangePasswordFields.currentPassword !== changePassword.currentPassword || oldChangePasswordFields.newPassword !== changePassword.newPassword || oldChangePasswordFields.confirmNewPassword !== changePassword.confirmNewPassword;
// if(userTypedPasswordSession)
// {
// this.setState(state => ({
// ...state,
// fieldValues: {
// ...state.fieldValues,
// changePassword: {
// ...state.fieldValues.changePassword,
// confirmPasswordWarning: this.checkIfUserCanSubmitNewPassword(changePassword.currentPassword, changePassword.newPassword, changePassword.confirmNewPassword)
// }
// }
// }))
// }
// }
if (!userFavorites){
this.getUserFavoriteMedias();
}
if (!userFavoritesCollection) {
this.getUserFavoriteCollection();
}
if(!didRefreshUserData && this.props.auth && this.props.auth.accessToken) {
UserService.refreshUserData(this.props.auth.accessToken.user.id, this.props.auth.accessToken.accessToken, this.props.refreshUserData)
this.setState(state => ({
...state,
didRefreshUserData: true
}))
}
if(!didLoadPlans && this.props.auth && this.props.auth.accessToken && this.props.publisher.revenueModel === 'SUBSCRIPTION') {
this.props.getPlansPublisher(this.props.auth.accessToken.accessToken, this.props.publisher.id)
this.setState(state => ({
...state,
didLoadPlans: true
}))
}
if(!didLoadUserData && this.props.auth && this.props.auth.accessToken) {
const { subscription } = this.props.auth.accessToken.user
if(this.props.publisher.revenueModel === 'SUBSCRIPTION' && !(!subscription || subscription.status === 'UNPAID' || subscription.status === 'ENDED')) {
this.handleGetUserSubscriptionData();
}
if(this.props.publisher.revenueModel === 'TRANSACTIONAL') {
this.props.getCollections(this.props.publisher, this.props.auth.accessToken.accessToken)
}
const { name, lastName, cpf } = this.props.auth.accessToken.user;
this.setState(state => ({
...state,
didLoadUserData: true,
fieldValues: {
...state.fieldValues,
personalData: {
...state.fieldValues.personalData,
name,
lastName,
cpf
}
}
}))
}
}
handleConfirmDeleteAccount = () => {
if(this.state.fieldValues.deleteAccount.email === this.props.auth.accessToken.user.login) {
this.state.modalConfirmAction();
this.handleUserLogout();
}
}
render() {
if(!this.props.auth || !this.props.auth.accessToken || !this.props.auth.accessToken.user) {
return(<div/>)
}
// console.log('PROPS: ', this.props)
// if(this.props.collection) {
// console.log('COLLECTIONS: ', this.props.collection.data)
// }
const {name, subscription} = this.props.auth.accessToken.user;
const { showFullModal, profilePictureUrl, routeName, subRoute, subRouteSubtitle, subRouteTitle, routeTitle, routeSubtitle, isMobile, selectedPlan, userSubscriptionInfo} = this.state;
if(showFullModal) {
return (
<FullModal danger={showFullModal === 'cancel-subscription' || showFullModal === 'delete-account'}>
<div className="modal-window">
{
showFullModal === 'confirm-switch-plan'
&& <>
<h1>Confirmar alteração?</h1>
<p className="message">Após a alteração você continuará usando o plano “<b>{userSubscriptionInfo.name}</b> - {translatePlan[userSubscriptionInfo.period]}” até <b>{moment(this.props.auth.accessToken.user.subscription.currentPeriodEnd).format('DD/MMMM/YYYY').replace('/',' de ').replace('/',' de ')}</b>.<br/><br/>
Uma cobrança no valor de R$ {(selectedPlan.price/100).toFixed(2).replace('.',',')} (em {planModifier[selectedPlan.period]} parcela{planModifier[selectedPlan.period] > 1 && 's'}) será
realizada neste dia para ativar o plano “<b>{selectedPlan.title}</b> - {translatePlan[selectedPlan.period]}”
que será renovada automaticamente a cada {planModifier[selectedPlan.period] > 1 ? `${planModifier[selectedPlan.period]} meses` : 'mês'}.</p>
{
isMobile
? <div className="buttons-wrapper">
<div onClick={() => {this.state.modalConfirmAction(); this.handleCloseFullModal();}} className="button">Alterar Plano</div>
<div onClick={this.handleCloseFullModal} className="button cancel">Não Alterar Plano</div>
</div>
: <div className="buttons-wrapper">
<div onClick={this.handleCloseFullModal} className="button cancel">Não Alterar Plano</div>
<div onClick={() => {this.state.modalConfirmAction(); this.handleCloseFullModal();}} className="button">Alterar Plano</div>
</div>
}
</>
}
{
showFullModal === 'cancel-subscription'
&& <>
<h1>Cancelar assinatura?</h1>
<p className="message">Ao cancelar a assinatura você continua assistindo aos conteúdos até o dia {moment(this.props.auth.accessToken.user.subscription.currentPeriodEnd).format('DD/MMM').replace('/', ' de ')} e<br/>após esta data seu plano não será renovado.</p>
<div className="buttons-wrapper">
<div onClick={this.handleCloseFullModal} className="button cancel">Continuar Assistindo</div>
<div onClick={() => {this.state.modalConfirmAction(); this.handleCloseFullModal();}} className="button">Cancelar Assinatura</div>
</div>
</>
}
{
showFullModal === 'delete-account'
&& <>
<h1>Excluir conta?</h1>
<p className="message">Esta ação resultará na exclusão do seu acesso e informações. Digite abaixo o e-mail cadastrado para excluir a conta.</p>
<EditionField label="E-mail Cadastrado" fullWidth value={this.state.fieldValues.deleteAccount.email} onChange={this.handleInputChange('deleteAccount')('email')}/>
<div className="buttons-wrapper">
<div onClick={this.handleCloseFullModal} className="button cancel">Manter Minha Conta</div>
<div className={`button ${this.state.fieldValues.deleteAccount.email !== this.props.auth.accessToken.user.login ? 'disabled' : ''}`} onClick={this.handleConfirmDeleteAccount} >Excluir Minhas Informações</div>
</div>
</>
}
</div>
</FullModal>
)
}
if(routeName === 'mobile-navigator') {
return (
<RootWrapper>
<ClosePanel onClick={() => window.location.href='/'}>
<i className="material-icons">close</i>
</ClosePanel>
<LeftNavigator publisherRevenueType={this.props.publisher.revenueModel} handleUserLogout={this.handleUserLogout} routeName={routeName} username={name} profilePictureUrl={profilePictureUrl} switchRoute={this.switchRoute} />
</RootWrapper>
)
}
return (
<RootWrapper>
<ClosePanel onClick={() => window.location.href='/'}>
Ir para o site <i className="material-icons">close</i>
</ClosePanel>
{
!isMobile && <LeftNavigator publisherRevenueType={this.props.publisher.revenueModel} handleUserLogout={this.handleUserLogout} routeName={routeName} username={name} profilePictureUrl={profilePictureUrl} switchRoute={this.switchRoute} />
}
<MainWrapper subRoute={subRoute}>
{
isMobile && <i onClick={subRoute ? this.switchSubRouteTitleAndSubtitle('return') : this.switchRoute('mobile-navigator')} className="material-icons">arrow_back</i>
}
{
subRoute
? isMobile ? null : <div onClick={this.switchSubRouteTitleAndSubtitle('return')} className="go__back"><i className="material-icons">arrow_back</i><p>Voltar</p></div>
: isMobile ? null : <div style={{height: 60}} />
}
{
(!isMobile || (routeName !== 'user-data' && isMobile) || subRoute === 'change-password') && <h1 className="main__content__title">{subRoute ? subRouteTitle : routeTitle}</h1>
}
{
(!isMobile || (routeName !== 'user-data' && isMobile))
&& (subRoute
? subRoute === 'switch-plan'
? <h2 className="main__content__subtitle">{subRouteSubtitle.split('$')[0]}<b>{subRouteSubtitle.split('$')[1]}</b></h2>
: <h2 className="main__content__subtitle">{subRouteSubtitle.split('<br/>')[0]}<br/>{subRouteSubtitle.split('<br/>')[1]}</h2>
: <h2 className="main__content__subtitle">{routeSubtitle}</h2>)
}
{this.selectedRoute()}
</MainWrapper>
</RootWrapper>
);
}
handleError = (area) => (field) => (operation) => {
const errors = this.state.fieldValues[area].errors.slice(0);
if(operation === 'add') {
if(errors.indexOf(field) === -1) {
errors.push(field);
this.setState(state => ({
...state,
fieldValues: {
...state.fieldValues,
[area]: {
...state.fieldValues[area],
errors
}
}
}))
}
} else if(operation === 'remove') {
if(errors.indexOf(field) !== -1) {
const index = errors.indexOf(field);
errors.splice(index, 1);
this.setState(state => ({
...state,
fieldValues: {
...state.fieldValues,
[area]: {
...state.fieldValues[area],
errors
}
}
}))
}
}
}
handleChangeUserPassword = () => {
const { currentPassword, newPassword } = this.state.fieldValues.changePassword;
const { user: { id }, accessToken } = this.props.auth.accessToken;
this.setState(state => ({ ...state, loadingChangePassword: true }))
const removeLoadingStateChangePassword = (code, message) => {
if(code === 200) {
this.setState(state => ({
...state,
loadingChangePassword: false,
fieldValues: {
...state.fieldValues,
changePassword: {
currentPassword: '',
newPassword: '',
confirmNewPassword: '',
confirmPasswordWarning: 'none', // none | wrong-password
errors: ['currentPassword', 'newPassword', 'confirmNewPassword', 'wrongPassword'],
}
}
}))
this.switchRoute('user-data')();
} else {
if(message === 'USER_WRONG_CURRENT_PASSWORD') {
this.setState(state => ({
...state,
loadingChangePassword: false,
fieldValues: {
...state.fieldValues,
changePassword: {
...state.fieldValues.changePassword,
confirmPasswordWarning: 'wrong-password',
}
}
}))
} else {
this.setState(state => ({ ...state, loadingChangePassword: false, }))
}
}
}
UserService.updateUserPassword(id, accessToken, currentPassword, newPassword, removeLoadingStateChangePassword);
}
handleShowFullModal = (modalConfirmAction, type, payload) => {
if(payload) {
this.setState(state => ({
...state,
showFullModal: type,
modalConfirmAction,
...payload
}))
} else {
this.setState(state => ({
...state,
showFullModal: type,
modalConfirmAction,
}))
}
}
handleCloseFullModal = () => {
this.setState(state => ({
...state,
showFullModal: undefined,
}))
}
handleGetUserSubscriptionData = (userSubscriptionInfo) => {
if(userSubscriptionInfo) {
this.setState(state => ({
...state,
userSubscriptionInfo: {
...state.userSubscription,
nextPlan: userSubscriptionInfo
}
}))
} else {
const { accessToken, user: { id } } = this.props.auth.accessToken;
UserService.getUserPlan(accessToken).then(resp => {
this.setState(state => ({
...state,
userSubscriptionInfo: resp.data
}))
UserService.refreshUserData(id, accessToken, this.props.refreshUserData)
}).catch(err => console.error(err))
}
}
switchRoute = (routeName) => () => {
this.setState(state => ({
...state,
...this.switchRouteTitleAndSubtitle(routeName),
routeName,
}))
}
selectedRoute = () => {
const { routeName, subRoute, userSubscriptionInfo, fieldValues: { changePassword: { confirmPasswordWarning } }, loadingChangePassword, isMobile } = this.state;
const { user: { name, login, id, payerInfo }, accessToken, user } = this.props.auth.accessToken;
if(subRoute) {
switch(subRoute) {
case 'switch-plan':
return <SwitchPlan
plans={this.props.plans}
isMobile={isMobile}
userSubscription={user.subscription}
payerInfo={payerInfo}
userAccessToken={accessToken}
getPlansPublisher={() => this.props.getPlansPublisher(accessToken.accessToken, this.props.publisher.id)}
userSubscriptionInfo={userSubscriptionInfo}
handleGetUserSubscriptionData={this.handleGetUserSubscriptionData}
handleShowFullModal={this.handleShowFullModal}
uid={id}
refreshUserData={this.props.refreshUserData}
/>
case 'edit-payment-method':
return <EditPaymentInfo
uid={id}
isMobile={isMobile}
returnScreen={this.switchSubRouteTitleAndSubtitle('return')}
updateUserCreditCard={this.props.updateUserCreditCard}
userAccessToken={accessToken}
pagarMeEncryptKey={this.props.publisher.pagarMeEncryptKey}
errors={this.state.fieldValues.editCreditCard.errors}
handleError={this.handleError('editCreditCard')}
payerInfo={payerInfo}
handleInputChange={this.handleInputChange('editCreditCard')}
fieldValues={this.state.fieldValues.editCreditCard}
/>
case 'change-password':
return <ChangePassword
fieldValues={this.state.fieldValues}
handleChangeUserPassword={this.handleChangeUserPassword}
handleInputChange={this.handleInputChange('changePassword')}
confirmPasswordWarning={confirmPasswordWarning}
loadingChangePassword={loadingChangePassword}
errors={this.state.fieldValues.changePassword.errors}
handleError={this.handleError('changePassword')}
isPasswordStrong={this.isPasswordStrong}
isMobile={isMobile}
/>
}
} else {
switch(routeName) {
case 'user-data':
return <UserData
username={name}
email={login}
fieldValues={this.state.fieldValues}
handleInputChange={this.handleInputChange('personalData')}
uid={id}
accessToken={accessToken}
oldUserData={this.props.auth}
authUpdateToken={this.props.authUpdateToken}
switchSubRouteTitleAndSubtitle={this.switchSubRouteTitleAndSubtitle}
handleShowFullModal={() => this.handleShowFullModal(() => UserService.deleteUser(id, accessToken), 'delete-account')}
isMobile={isMobile}
handleError={this.handleError('personalData')}
/>
case 'user-favorites':
return <MyFavorites items={this.state.userFavorites} items_collection={this.state.userFavoritesCollection}/>
case 'subscription-data':
return <SubscriptionData
{...this.state}
openCheckOut={this.props.openDialog}
payerInfo={user.payerInfo}
switchSubRouteTitleAndSubtitle={this.switchSubRouteTitleAndSubtitle}
userSubscription={user.subscription}
userSubscriptionInfo={userSubscriptionInfo}
handleShowFullModal={this.handleShowFullModal}
revenueModel={this.props.publisher.revenueModel}
userAccessToken={accessToken}
plans={this.props.plans}
uid={id}
userStatus={user.status}
refreshUserData={this.props.refreshUserData}
voucherInfo={user.voucher}
/>
case 'transactional-data':
return <TransactionalData collections={this.props.collection} />
default:
return null
}
}
}
switchRouteTitleAndSubtitle = (routeName) => {
this.switchSubRouteTitleAndSubtitle()()
switch(routeName) {
case 'user-data':
return {
routeTitle: 'Meus Dados',
routeSubtitle: 'Configure seus dados pessoais aqui.'
}
case 'user-favorites':
return {
routeTitle: 'Meus Favoritos',
routeSubtitle: 'Confira os seus conteúdos favoritos.'
}
case 'subscription-data':
return {
routeTitle: 'Assinatura',
routeSubtitle: 'Gerencie aqui seu plano.'
}
case 'transactional-data':
return {
routeTitle: 'Meus Conteúdos',
routeSubtitle: 'Confira aqui seus conteúdos.'
}
default:
return {
routeTitle: '-',
routeSubtitle: '-'
}
}
}
switchSubRouteTitleAndSubtitle = (subRouteName) => () => {
// console.log('PROPS: ', )
switch(subRouteName) {
case 'switch-plan':
return this.setState(state => ({
...state,
subRoute: subRouteName,
subRouteTitle: 'Alterar Plano',
subRouteSubtitle: `Escolha um novo plano. Ele só será ativado e cobrado em $${moment(this.props.auth.accessToken.user.subscription.currentPeriodEnd).add(1, 'd').format('DD/MMMM/YYYY').replace('/',' de ').replace('/',' de ')}`
}))
case 'edit-payment-method':
let subRouteSubtitle = '';
if(this.props.auth.accessToken.user.payerInfo.method === 'CREDIT_CARD') {
subRouteSubtitle = 'cartão de final ' + this.props.auth.accessToken.user.payerInfo.cardLastDigits
} else if (this.props.auth.accessToken.user.payerInfo.method === 'BOLETO') {
subRouteSubtitle = 'boleto'
}
return this.setState(state => ({
...state,
subRoute: subRouteName,
subRouteTitle: 'Pagamento',
subRouteSubtitle: `Atualmente o seu plano é renovado no ${subRouteSubtitle}.<br/> `
}))
case 'change-password':
return this.setState(state => ({
...state,
subRoute: subRouteName,
subRouteTitle: 'Alterar Senha',
subRouteSubtitle: ''
}))
case 'return':
return this.setState(state => ({
...state,
subRoute: undefined,
subRouteTitle: '-',
subRouteSubtitle: '-',
}))
default:
return this.setState(state => ({
...state,
subRoute: undefined,
subRouteTitle: '-',
subRouteSubtitle: '-',
}))
}
}
handleInputChange = (area) => (name) => (e) => {
const value = e.target.value;
// if(name === 'cpf') {
// this.setState(state => ({
// ...state,
// fieldValues: {
// ...state.fieldValues,
// [area]: {
// ...state.fieldValues[area],
// cpf: value,
// errors: validate({cpf: value})
// }
// }
// }))
// } else {
this.setState(state => ({
...state,
fieldValues: {
...state.fieldValues,
[area]: {
...state.fieldValues[area],
[name]: value,
}
}
}))
// }
}
checkIfUserCanSubmitNewPassword = (currentPassword, newPassword, confirmNewPassword) => {
if(!this.isPasswordStrong(newPassword)) {
return 'weak';
}
if(newPassword !== confirmNewPassword) {
return 'different';
}
if(currentPassword === '' || newPassword === '' || confirmNewPassword === '') {
return 'empty';
}
return 'none';
}
handleUserLogout = () => {
const {publisher, auth: {accessToken}} = this.props;
if(accessToken.accessToken){
this.props.authUserLogout(accessToken.accessToken , publisher);
}
}
}
class TransactionalData extends React.Component {
render() {
if(!this.props.collections || !this.props.collections.data) {
return null
}
if(this.props.collections.data.length === 0) {
return (
<SubscriptionDataWrapper>
<div className="sign__now">
<Television className="television__icon" />
<div>
<h3>Compre coleções e tenha<br/>acesso a conteúdos exclusivos</h3>
<button onClick={() => window.location.href='/'} className="call__to__action small__label">Ver todos os conteúdos</button>
</div>
</div>
</SubscriptionDataWrapper>
)
}
return(
<TransactionalDataWrapper>
{/* <Collection /> */}
{
this.props.collections.data.map(collection => (
<Collection {...collection} key={collection.id} />
))
}
</TransactionalDataWrapper>
)
}
}
const Collection = ({title, totalMedias, totalDuration, accessInfo, bannerUrl, watchedDuration, collectionProgress, id}) => {
function truncate(title){
if (title.length > 22)
return title.substring(0,22)+'...';
else
return title;
};
return (
<CollectionWrapper bannerUrl={bannerUrl}>
<div className="hero__image">
{
(accessInfo && accessInfo.expireAt) && <p className="available__until">Disponível até <b>{moment(accessInfo.expireAt).format('DD MMM YYYY')}</b></p>
}
<LinkSlug
route='colecao'
collectionType
collectionSlug={title}
identifier={{ id }}
lowerCase
>
<div className="cta">
<i className="material-icons">play_arrow</i>
<span>{collectionProgress ? 'Continuar Assistindo' : 'Assistir'}</span>
</div>
</LinkSlug>
</div>
<div className="collection__info">
<p>{truncate(title)}</p>
<div className="collection_statistics">
<span>
<i className="material-icons">ondemand_video</i> {totalMedias} vídeos
</span>
<span>
<i className="material-icons">access_time</i> {Math.floor(totalDuration/60000)} min
</span>
</div>
{/* <span className="more"><i className="material-icons">expand_more</i> ver mais</span> */}
</div>
</CollectionWrapper>
)
}
const LeftNavigator = ({routeName, profilePictureUrl, username, switchRoute, handleUserLogout, publisherRevenueType, isMobile}) => (
<div className="left__navigator">
<div className="user__initial" style={{backgroundImage: `url(${profilePictureUrl ? profilePictureUrl : undefined})`}}>
{!profilePictureUrl && username[0]}
</div>
<p className="user__name">{username}</p>
{
publisherRevenueType === 'SUBSCRIPTION'
&& <ButtonNavigator idBtn="btnSignature" switchRoute={switchRoute} currentRoute={routeName} routeName="Assinatura" route="subscription-data" iconName="confirmation_number" />
}
{
publisherRevenueType === 'TRANSACTIONAL'
&& <ButtonNavigator idBtn="btnMyContents" switchRoute={switchRoute} currentRoute={routeName} routeName="Meus Conteúdos" route="transactional-data" iconName="ondemand_video" />
}
<ButtonNavigator switchRoute={switchRoute} currentRoute={routeName} routeName="Meus dados" route="user-data" iconName="person" />
<ButtonNavigator switchRoute={switchRoute} currentRoute={routeName} routeName="Meus favoritos" route="user-favorites" iconName="favorite" />
<span onClick={handleUserLogout} className="sign__out">
<i className="material-icons">power_settings_new</i>
Sair
</span>
</div>
)
const ButtonNavigator = ({idBtn, currentRoute, switchRoute, route, iconName, routeName}) => (
<button id={idBtn} onClick={switchRoute(route)} className={currentRoute === route ? 'selected' : undefined }>
<div>
<i className="material-icons">{iconName}</i>
<span>{routeName}</span>
</div>
<i className="material-icons">keyboard_arrow_right</i>
</button>
)
const SubscriptionData = ({voucherInfo, userStatus, paymentStatus, switchSubRouteTitleAndSubtitle, userSubscription, payerInfo, openCheckOut, userSubscriptionInfo, isMobile, handleShowFullModal, revenueModel, userAccessToken, plans, uid, refreshUserData}) => {
switchSubRouteTitleAndSubtitle('switch-plan')
const handleGoToCheckout = () => {
openCheckOut('PLANS', null);
window.location.href='/';
}
if(userStatus === 'VOUCHER' && voucherInfo && voucherInfo.periodEnd > Date.now() && voucherInfo.status === 'ACTIVE') {
return <SubscriptionDataWrapper>
<div className="sign__now">
<Television className="television__icon" />
<div style={{justifyContent: 'center'}}>
<h3 style={{margin: 0}}>Seu voucher está ativo!</h3>
</div>
</div>
</SubscriptionDataWrapper>
}
if((!userSubscription || !userSubscriptionInfo) || (userSubscription.status === 'UNPAID' || userSubscription.status === 'ENDED')) {
return (
<SubscriptionDataWrapper>
<div className="sign__now">
<Television className="television__icon" />
<div>
{
revenueModel === 'SUBSCRIPTION'
? <>
<h3>Assine agora e acesse<br/>conteúdos exclusivos</h3>
<button onClick={handleGoToCheckout} className="call__to__action small__label">Assinar agora</button>
</>
: <>
<h3>Compre coleções e tenha<br/>acesso a conteúdos exclusivos</h3>
<button onClick={() => window.location.href='/'} className="call__to__action small__label">Ver todos os conteúdos</button>
</>
}
</div>
</div>
</SubscriptionDataWrapper>
)
}
const { method } = payerInfo;
console.log('userSubscriptionInfo: ', userSubscriptionInfo)
console.log('userSubscription: ', userSubscription)
if(userSubscription.status === 'PENDING_PAYMENT') {
return(
<SubscriptionDataWrapper>
<p className="additional__info">O pagamento pode levar até 48h para ser <br/>reconhecido e o acesso liberado para consumo.</p>
{
method === 'CREDIT_CARD'
&& <>
{
!isMobile && <p id="change-credit-card" className="clear__button" onClick={switchSubRouteTitleAndSubtitle('edit-payment-method')}>Alterar Cartão de Crédito</p>
}
</>
}
</SubscriptionDataWrapper>
)
}
if(userSubscription.status === 'CANCELED') {
return (
<SubscriptionDataWrapper>
<div className="subscription__box canceled">
<h3>{userSubscriptionInfo.nextPlan ? userSubscriptionInfo.nextPlan.name : userSubscriptionInfo.name}</h3>
<p className="plan__period">{translatePlan[userSubscriptionInfo.nextPlan ? userSubscriptionInfo.nextPlan.period : userSubscriptionInfo.period]}</p>
<p className="next__billing">Assinatura cancelada.{isMobile && <br/>} Acesse ate <span>{moment(userSubscription.currentPeriodEnd).format('DD MMM YYYY')}</span></p>
{
userSubscriptionInfo.nextPlan
? <h3 className="plan__value">{planPeriodicity[userSubscriptionInfo.nextPlan.period]}x R$ {(userSubscriptionInfo.nextPlan.amount/(planPeriodicity[userSubscriptionInfo.nextPlan.period]*100)).toFixed(2).replace('.', ',')}</h3>
: <h3 className="plan__value">{userSubscription.installments}x R$ {(userSubscription.amount/(userSubscription.installments*100)).toFixed(2).replace('.', ',')}</h3>
}
</div>
{
moment(userSubscription.currentPeriodEnd).isBefore(moment()) && <SubmitButton id="btnSignAgain" isMobile={isMobile} marginTop="15px" onClick={handleGoToCheckout}>Assinar Novamente</SubmitButton>
}
</SubscriptionDataWrapper>
)
}
return (
<SubscriptionDataWrapper>
{
method !== 'no-plan' &&
<div className="subscription__box">
<div>
<h3>{userSubscriptionInfo.nextPlan ? userSubscriptionInfo.nextPlan.name : userSubscriptionInfo.name}</h3>
{
(!isMobile && plans && plans.resp && plans.resp.data && plans.resp.data.length > 1 && method !== 'BOLETO')
&& <p id="change-plan" className="clear__button change__plan" onClick={switchSubRouteTitleAndSubtitle('switch-plan')}>Alterar Plano</p>
}
</div>
<p className="plan__period">{translatePlan[userSubscriptionInfo.nextPlan ? userSubscriptionInfo.nextPlan.period : userSubscriptionInfo.period]}</p>
{/* Credit card payment method */}
{
method === 'CREDIT_CARD'
&& <>
<p className="next__billing">Próxima cobrança em {isMobile && <br/>}<span>{moment(userSubscription.currentPeriodEnd).format('DD MMM YYYY')}</span> no cartão {isMobile && <br/>}**** **** **** {payerInfo.cardLastDigits}</p>
{
!isMobile && <p id="change-credit-card" className="clear__button" onClick={switchSubRouteTitleAndSubtitle('edit-payment-method')}>Alterar Cartão de Crédito</p>
}
</>
}
{/* Boleto payment method, it has three states: 'up_to_date', 'awaiting_plan_renewal' and 'awaiting_first_payment' */}
{
method === 'BOLETO'
&& <>
{/* Each paymentStatus has it's own context */}
{
paymentStatus === 'up_to_date'
&& <p className="next__billing">Próxima cobrança em <span>23 mai 2018</span> no Boleto Bancário</p>
}
{
paymentStatus === 'awaiting_plan_renewal'
&& <>
<p className="next__billing">Boleto para renovação em <span>23 mai 2018</span></p>
<p className="clear__button">Baixar boleto</p>
</>
}
{
paymentStatus === 'awaiting_first_payment'
&& <>
<p className="next__billing">Aguardando pagamento...</p>
<button className="call__to__action">
Baixar Boleto
</button>
</>
}
</>
}
{
!(method === 'boleto' && paymentStatus === 'awaiting_first_payment')
&& userSubscriptionInfo.nextPlan
? <h3 className="plan__value">{planPeriodicity[userSubscriptionInfo.nextPlan.period]}x R$ {(userSubscriptionInfo.nextPlan.amount/(planPeriodicity[userSubscriptionInfo.nextPlan.period]*100)).toFixed(2).replace('.', ',')}</h3>
: <h3 className="plan__value">{userSubscription.installments}x R$ {(userSubscription.amount/(userSubscription.installments*100)).toFixed(2).replace('.', ',')}</h3>
}
</div>
}
{/* {
method === 'no-plan'
&& <div className="sign__now">
<Television className="television__icon" />
<div>
<h3>Assine agora e acesse<br/>conteúdos exclusivos</h3>
<button onClick={() => window.location.href='/'} className="call__to__action small__label">Assinar agora</button>
</div>
</div>
} */}
{
isMobile
? <div className="mobile__action__buttons">
{
(plans && plans.resp && plans.resp.data && plans.resp.data.length > 1 && method !== 'BOLETO')
&& <p id="change-plan" className="clear__button change__plan" onClick={switchSubRouteTitleAndSubtitle('switch-plan')}>Alterar Plano</p>
}
<p id="change-credit-card" className="clear__button" onClick={switchSubRouteTitleAndSubtitle('edit-payment-method')}>Alterar Cartão de Crédito</p>
<p id="cancel-subscription" className="clear__button cancel__subscription" onClick={() => handleShowFullModal(() => UserService.cancelSubscription(userAccessToken, uid, refreshUserData, () => window.location.href='/settings'), 'cancel-subscription')}>Cancelar Assinatura</p>
</div>
: <div className="action__buttons">
<p id="cancel-subscription" className="clear__button cancel__subscription" onClick={() => handleShowFullModal(() => UserService.cancelSubscription(userAccessToken, uid, refreshUserData, () => window.location.href='/settings'), 'cancel-subscription')}>Cancelar Assinatura</p>
</div>
}
</SubscriptionDataWrapper>
)
}
class MyFavorites extends React.PureComponent {
state = {
tab: 'media',
}
render() {
const {items, items_collection} = this.props;
console.log('items: ', items_collection)
return (
<div>
<div style={{ display: 'flex', alignItems: 'center', width: '100%', borderBottom: '1px solid #B3B8BF', height: 50, marginBottom: 30}}>
<div onClick={this.handleChangeTab('collection')} style={{ display: 'flex', height: '100%', justifyContent: 'center', alignItems: 'center', width: 100, color: this.state.tab === 'collection' ? 'black' : '#B3B8BF', fontWeight: this.state.tab === 'collection' ? 'bold' : 'normal', borderBottom: this.state.tab === 'collection' ? '1px solid black' : '0', cursor: 'pointer' }}>
<p>Coleções</p>
</div>
<div onClick={this.handleChangeTab('media')} style={{ display: 'flex', height: '100%', justifyContent: 'center', alignItems: 'center', width: 100, color: this.state.tab === 'media' ? 'black' : '#B3B8BF', fontWeight: this.state.tab === 'media' ? 'bold' : 'normal', borderBottom: this.state.tab === 'media' ? '1px solid black' : '0', cursor: 'pointer' }}>
<p>Vídeos</p>
</div>
</div>
{
this.state.tab === 'media'
? <div>
<div style={{ display: "flex", flexDirection: "row", flexWrap: "wrap" }}>
{
items &&
map(items, (item) => (
<SingleFavorite item={item} type="media" />
))
}
{ items.length > 0 ?
<div />
:
<div>Nenhum vídeo marcado como favorito no momento.</div>
}
</div>
</div>
: <div>
{
items_collection &&
map(items_collection, (item) => (
<SingleFavorite item={item} type="collection" />
))
}
{items_collection.length > 0 ?
<div />
:
<div>Nenhum vídeo marcado como favorito no momento.</div>
}
</div>
}
</div>
)
}
handleChangeTab = (tab) => () => {
this.setState({
tab
})
}
}
const SingleFavorite = (props) => {
const { item, type } = props;
const { mediaFiles, name, duration, id } = item;
function truncate(title){
if (title.length > 50)
return title.substring(0,50)+'...';
else
return title;
};
if(type === 'collection') {
return (
<div style={{display: 'flex', flexDirection: 'column', maxWidth: 280, height: 55, marginRight: 25}}>
<LinkSlug
route='colecao'
collectionType
collectionSlug={item.title}
identifier={{ id }}
lowerCase
>
<img style={{ width: 280, height: 130, minHeight: 130, borderRadius: 4 }} src={item.bannerUrl} />
<div style={{minHeight: 60}}>
<p style={{ fontSize: 16, fontWeight: '600', marginTop: 10 }}>{truncate(item.title)}</p>
</div>
</LinkSlug>
<div style={{display: 'flex', width: '100%', marginTop: 5, justifyContent: 'space-between'}}>
<span style={{display: 'flex', alignItems: 'center', fontSize: 12}}><i style={{marginRight: 5, fontSize: 12}} className="material-icons">access_time</i> {Math.floor(duration/60000)} min</span>
<i style={{marginRight: 5, fontSize: 12, color: 'red'}} className="material-icons">favorite</i>
</div>
</div>
)
}
return (
<div style={{display: 'flex', flexDirection: 'column', maxWidth: 280, height: 55, marginRight: 25}}>
<LinkSlug
route={type === 'media' ? 'midia' : 'colecao'}
collectionType={type === 'collection'}
collectionSlug={type === 'collection' ? name : 'a' }
mediaSlug={type === 'media' ? name : undefined}
identifier={{ idCollection: type === 'media' ? 'aa' : undefined, idMedia: id }}
lowerCase
>
<img style={{ width: 280, height: 130, minHeight: 130, borderRadius: 4 }} src={mediaFiles[0].progressiveUrl} />
<div style={{minHeight: 60}}>
<p style={{ fontSize: 16, fontWeight: '600', marginTop: 10 }}>{truncate(name)}</p>
</div>
</LinkSlug>
<div style={{display: 'flex', width: '100%', marginTop: 5, justifyContent: 'space-between'}}>
{
duration
? <span style={{display: 'flex', alignItems: 'center', fontSize: 12}}><i style={{marginRight: 5, fontSize: 12}} className="material-icons">access_time</i> {Math.floor(duration/60000)} min</span>
: <span/>
}
<i style={{marginRight: 5, fontSize: 12, color: 'red'}} className="material-icons">favorite</i>
</div>
</div>
)
}
const UserData = ({id, previewProfilePictureUrl, username, email, handleInputChange, fieldValues, uid, accessToken, oldUserData, authUpdateToken, switchSubRouteTitleAndSubtitle, handleShowFullModal, isMobile, handleError}) => {
return (
<UserDataWrapper>
<div className="profile__picture__edition">
<div className="profile__picture__preview" style={{backgroundImage: `url(${previewProfilePictureUrl ? previewProfilePictureUrl : undefined})`}}>
{!previewProfilePictureUrl && username[0]}
</div>
{
!isMobile &&
<span>
<i className="material-icons">photo_camera</i>
Alterar Foto
</span>
}
</div>
{
isMobile
? <div className="personal__data__edition">
<div className="field__row">
<EditionField idInput="idName" label="Nome" onChange={handleInputChange('name')} value={fieldValues.personalData.name} fullWidth handleError={handleError('name')} validations={{required: true, maxSize: 45}} maxLength={45}/>
</div>
<div className="field__row">
<EditionField idInput="idLastName" label="Sobrenome" optional onChange={handleInputChange('lastName')} value={fieldValues.personalData.lastName} fullWidth handleError={handleError('lastName')} maxLength={45}/>
</div>
<div className="field__row">
<EditionField idInput="idCPF" label="CPF" optional onChange={handleInputChange('cpf')} value={fieldValues.personalData.cpf} fullWidth mask={[/\d/, /\d/, /\d/, '.', /\d/, /\d/, /\d/, '.', /\d/, /\d/, /\d/, '-', /\d/, /\d/]} handleError={handleError('cpf')} validations={{cpf: true, required: true}}/>
</div>
<div className="field__row">
<EditionField idInput="idEmail" label="E-mail" email={email} disabled fullWidth/>
</div>
</div>
: <div className="personal__data__edition">
<div className="field__row">
<EditionField idInput="idName" label="Nome" onChange={handleInputChange('name')} value={fieldValues.personalData.name} handleError={handleError('cpf')} validations={{required: true, maxSize: 45}} maxLength={45}/>
<span />
<EditionField idInput="idLastName" label="Sobrenome" optional onChange={handleInputChange('lastName')} value={fieldValues.personalData.lastName} maxLength={45}/>
</div>
<div className="field__row">
<EditionField idInput="idCPF" label="CPF" optional onChange={handleInputChange('cpf')} value={fieldValues.personalData.cpf} mask={[/\d/, /\d/, /\d/, '.', /\d/, /\d/, /\d/, '.', /\d/, /\d/, /\d/, '-', /\d/, /\d/]} handleError={handleError('cpf')} validations={{cpf: true, required: true}}/>
<span />
<EditionField idInput="idEmail" label="E-mail" email={email} disabled />
</div>
</div>
}
<SubmitButton id="btnSave" isMobile={isMobile} disabled={fieldValues.personalData.errors.length > 0} className="submit__edition" onClick={UpdateUserData({fieldValues, uid, email, accessToken, oldUserData, authUpdateToken})}>Salvar</SubmitButton>
<div className="secondary__options">
<span id="idChangePassword" onClick={switchSubRouteTitleAndSubtitle('change-password')}>Alterar Senha</span>
<span id="idDeleteAccount" onClick={handleShowFullModal} className="danger__option">Excluir Conta</span>
</div>
</UserDataWrapper>
)
}
class ChangePassword extends React.PureComponent {
state = {
visibility: {
currentPassword: true,
newPassword: true,
confirmNewPassword: true
}
}
render() {
const { handleChangeUserPassword, handleInputChange, confirmPasswordWarning, loadingChangePassword, handleError, errors, fieldValues, isMobile } = this.props;
const { visibility } = this.state;
return (
<ChangePasswordWrapper>
<div className="password__wrapper" >
<i className="material-icons" onClick={this.switchVisibility('currentPassword')}>{visibility.currentPassword ? 'visibility' : 'visibility_off'}</i>
<EditionField idInput="idCurrentPassword" handleError={handleError('currentPassword')} onChange={handleInputChange('currentPassword')} label="Senha atual" fullWidth password={visibility.currentPassword} value={fieldValues.changePassword.currentPassword} validations={{required: true, wrongPassword: fieldValues.changePassword.confirmPasswordWarning === 'wrong-password'}} />
</div>
<div className="horizontal__line" />
<div className="password__wrapper" >
<i className="material-icons" onClick={this.switchVisibility('newPassword')}>{visibility.newPassword ? 'visibility' : 'visibility_off'}</i>
<EditionField idInput="idNewPassword" handleError={handleError('newPassword')} validations={{required: true, passwordStrength: true}} onChange={handleInputChange('newPassword')} label="Nova senha" fullWidth password={visibility.newPassword} value={fieldValues.changePassword.newPassword}/>
</div>
<div className="password__wrapper" >
<i className="material-icons" onClick={this.switchVisibility('confirmNewPassword')}>{visibility.confirmNewPassword ? 'visibility' : 'visibility_off'}</i>
<EditionField idInput="idConfirmNewPassword" handleError={handleError('confirmNewPassword')} validations={{required: true, confirmNewPassword: fieldValues.changePassword.newPassword}} onChange={handleInputChange('confirmNewPassword')} label="Confirmar nova senha" fullWidth password={visibility.confirmNewPassword} value={fieldValues.changePassword.confirmNewPassword}/>
</div>
<SubmitButton isMobile={isMobile} disabled={loadingChangePassword || errors.length > 0} onClick={handleChangeUserPassword}>
{
loadingChangePassword
? 'Carregando...'
: 'Salvar'
}
</SubmitButton>
</ChangePasswordWrapper>
)
}
switchVisibility = (fieldName) => () => {
this.setState(state => ({
...state,
visibility: {
...state.visibility,
[fieldName]: !state.visibility[fieldName]
}
}))
}
}
const UpdateUserData = ({fieldValues, uid, email, accessToken, oldUserData, authUpdateToken}) => () => {
const newUserData = {
id: uid,
name: fieldValues.personalData.name,
lastName: fieldValues.personalData.lastName,
cpf: fieldValues.personalData.cpf,
email,
address: null
}
UserService.updateUser(uid, accessToken, newUserData, oldUserData, authUpdateToken)
}
const UpdateUserCache = (uid) => {
UserService.refreshUserData(uid);
}
class EditionField extends React.PureComponent {
state = {}
componentDidUpdate() {
if(this.props.validations && this.props.validations.wrongPassword && !this.state.alreadyShowedWarning) {
this.setState({
warningMessage: this.warningMessages['wrong-password'],
alreadyShowedWarning: true,
})
}
}
render() {
const { idInput, label, disabled, optional, email, value, onChange, fullWidth, password, mask, upperCase, margin, maxlength} = this.props
const { warningMessage } = this.state;
return (
<EditionFieldWrapper fullWidth={fullWidth} warning={warningMessage} margin={margin}>
{
optional
? <div className="optional__wrapper">
<p className="label">{label}</p>
<span>opcional</span>
</div>
: <p className="label">{label}</p>
}
{
disabled
? <div id={idInput} className="disabled__field">{email}</div>
: mask
? <MaskedInput
id={idInput}
onChange={onChange} value={value}
mask={mask}
onBlur={this.validateField}
maxlength={maxlength}
/>
: <input id={idInput} maxlength={maxlength} type={password ? 'password' : 'text'} onChange={onChange} onBlur={this.validateField} value={value} style={{textTransform: upperCase ? 'uppercase' : undefined}} />
}
{ warningMessage && <p className="warning__message">{warningMessage}</p>}
</EditionFieldWrapper>
)
}
validateField = () => {
const { value, validations = {}, handleError } = this.props;
// console.log('Validation: ', validations)
// console.log('VALUE: ', value)
let msg;
if(validations.creditCard) {
try {
msg = validate({numCard: value}).numCard;
} catch(err) {
msg = 'Oops, número de cartão incorreto';
}
}
if(validations.required && (value === '' || !value)) {
this.setState({
warningMessage: this.warningMessages['empty']
})
handleError('add')
} else if(validations.date && (moment(value, 'MM/YY').isBefore(moment()) || !moment(value, 'MM/YY').isValid())) {
this.setState({
warningMessage: this.warningMessages['invalid-date']
})
handleError('add')
} else if(validations.cpf && !!validate({cpf: value}).cpf) {
this.setState({
warningMessage: validate({cpf: value}).cpf
})
handleError('add')
} else if(validations.securityCode && !!validate({securityCodCard: value}).securityCodCard) {
this.setState({
warningMessage: validate({securityCodCard: value}).securityCodCard
})
handleError('add')
} else if(validations.creditCard && !!msg) {
this.setState({
warningMessage: msg,
})
handleError('add')
} else if(validations.passwordStrength && !this.isPasswordStrong(value)) {
this.setState({
warningMessage: this.warningMessages['weak-password'],
})
handleError('add')
} else if(validations.confirmNewPassword && validations.confirmNewPassword !== value) {
this.setState({
warningMessage: this.warningMessages['different-passwords'],
})
handleError('add')
} else if(validations.wrongPassword) {
this.setState({
warningMessage: undefined,
})
} else if(validations.maxSize && Number(value) > validations.maxSize) {
this.setState({
warningMessage: this.warningMEssages['too-large']
})
handleError('add')
} else {
this.setState({
warningMessage: undefined
})
handleError('remove')
}
}
isPasswordStrong(strPassword) {
function countContain(strPassword, strCheck)
{
// Declare variables
var nCount = 0;
var i;
for (i = 0; i < strPassword.length; i++)
{
if (strCheck.indexOf(strPassword.charAt(i)) > -1)
{
nCount++;
}
}
return nCount;
}
var m_strNumber = "0123456789";
var nNumberCount = countContain(strPassword, m_strNumber);
// -- 7 or less characters
if (strPassword.length < 8)
{
return false
}
// -- 0 numbers
if (nNumberCount < 1)
{
return false
}
return true;
}
warningMessages = {
'wrong-card-number': 'Oops, número do cartão incorreto',
'empty': 'Campo obrigatório',
'invalid-date': 'Data inválida',
'invalid-security-code': 'Código de segurança inválido',
'weak-password': 'Insira uma senha com pelo menos 8 caracteres e pelo menos 1 número.',
'different-passwords': 'Esta senha está diferente.',
'wrong-password': 'Senha incorreta.',
'too-large': 'Nome muito grande.'
}
}
class SwitchPlan extends React.PureComponent {
componentDidMount() {
this.props.getPlansPublisher()
}
sliderSettings = {
dots: true,
infinite: false,
centerMode: true,
speed: 500,
slidesToShow: 1,
slidesToScroll: 1,
variableWidth: true
};
render() {
const { plans, userSubscription, payerInfo, userAccessToken, userSubscriptionInfo, handleGetUserSubscriptionData, handleShowFullModal, isMobile, uid, refreshUserData } = this.props
if(!plans || !plans.resp || !plans.resp.data || !userSubscriptionInfo) {
return <div/>
}
// const plansList = plans.resp.data.map(plan => (
// <Plan
// handleShowFullModal={handleShowFullModal}
// handleGetUserSubscriptionData={handleGetUserSubscriptionData}
// userAccessToken={userAccessToken}
// planId={plan.id}
// title={plan.name}
// rawPeriod={plan.period}
// period={plan.period}
// recommended={plan.defaultPlan}
// selected={plan.id === userSubscriptionInfo.id}
// payerInfo={payerInfo}
// price={plan.amount}
// />
// ))
// if(isMobile) {
// return (
// // <div style={{width: 200}}>
// // // <SwitchPlanWrapper>
// // <SliderWrapper style={{width:'100%'}}>
// // <Slider {...this.sliderSettings}>
// // <div>
// // <Plan title="Istambul" period="semestral" />
// // </div>
// // {/* <div style={{width: 20}}> */}
// // <div>
// // <Plan title="Praga" period="anual" recommended />
// // </div>
// // </Slider>
// // </SliderWrapper>
// )
// }
const currentSubscriptionInfo = userSubscriptionInfo.nextPlan ? userSubscriptionInfo.nextPlan : userSubscriptionInfo
const isNextPlan = userSubscriptionInfo.nextPlan ? true : false
return (
<SwitchPlanWrapper isMobile={isMobile}>
{
plans.resp.data.map(plan => (
<Plan
handleShowFullModal={handleShowFullModal}
handleGetUserSubscriptionData={handleGetUserSubscriptionData}
userAccessToken={userAccessToken}
planId={plan.id}
title={plan.name}
rawPeriod={plan.period}
period={plan.period}
recommended={plan.defaultPlan}
selected={plan.id === currentSubscriptionInfo.id}
userSubscriptionInfo={currentSubscriptionInfo}
payerInfo={payerInfo}
price={plan.amount}
isMobile={isMobile}
userSubscription={userSubscription}
uid={uid}
refreshUserData={refreshUserData}
isNextPlan={isNextPlan}
/>
))
}
{/* <Plan title="San Francisco" period="trimestral" />
<Plan title="Istambul" period="semestral" />
<Plan title="Praga" period="anual" recommended /> */}
</SwitchPlanWrapper>
)
}
}
const translatePlan = {
MONTH: 'Mensal',
QUARTER: 'Trimestral',
HALF: 'Semestral',
YEAR: 'Anual'
}
const planPeriodicity = {
MONTH: 1,
QUARTER: 3,
HALF: 6,
YEAR: 12
}
const Plan = ({selected, recommended, title, price, period, userAccessToken, planId, handleGetUserSubscriptionData, handleShowFullModal, isMobile, rawPeriod, userSubscriptionInfo, userSubscription, uid, refreshUserData, isNextPlan}) => {
let realPrice;
if(selected && !isNextPlan) {
realPrice = (userSubscriptionInfo.amount/(userSubscription.installments*100)).toFixed(2).split('.')
} else {
realPrice = (price/100/planModifier[rawPeriod]).toFixed(2).split('.')
}
const handlePlanClick = () => handleShowFullModal(() => UserService.changePlan(planId, userAccessToken, handleGetUserSubscriptionData, uid, refreshUserData), 'confirm-switch-plan', {selectedPlan: {title, price, period}})
return (
<PlanWrapper onClick={selected ? () => null : handlePlanClick}>
<PlanBox isMobile={isMobile} className={selected ? 'selected' : ''} selected={selected}>
<h4>{title}</h4>
<label>{translatePlan[period]}</label>
{ // {userSubscription.installments}x R$ {(userSubscriptionInfo.amount/(userSubscription.installments*100)).toFixed(2).replace('.', ',')}
(selected && !isNextPlan)
? <p><b>{userSubscription.installments}x</b> R$ <span className="bigger">{realPrice[0]},</span><span className="cents">{realPrice[1]}</span></p>
: <p>R$ <span className="bigger">{realPrice[0]},</span><span className="cents">{realPrice[1]}</span></p>
}
<label>{(!selected && !isNextPlan) && 'por mês'}</label>
{/* <label>Ou R$ 158,47 à vista no boleto</label> */}
{
selected
? <label className="last">Este é o seu <b>plano atual</b><br/><br/>Ele é automaticamente renovado<br/>a cada {transplatePlanToPhrase[rawPeriod]}</label>
: <label className="last">Este plano é automaticamente<br/>renovado a cada {transplatePlanToPhrase[rawPeriod]}</label>
}
</PlanBox>
</PlanWrapper>
)
}
const transplatePlanToPhrase = {
MONTH: 'mês',
QUARTER: '3 meses',
HALF: '6 meses',
YEAR: '12 meses'
}
const planModifier = {
MONTH: 1,
QUARTER: 3,
HALF: 6,
YEAR: 12
}
class EditPaymentInfo extends React.PureComponent {
state = {}
componentDidMount() {
this.setState(state => ({
...state,
currentEditingMethod: this.props.payerInfo.method
}))
}
render() {
const { currentEditingMethod } = this.state;
const { handleInputChange, fieldValues, handleError, errors, isMobile } = this.props;
switch(currentEditingMethod) {
case 'CREDIT_CARD':
return (
<EditPaymentInfoWrapper>
<EditionField label="Número do Cartão" fullWidth mask={this.masks.creditCard} onChange={handleInputChange('number')} value={fieldValues.number} warning={true} validations={{required: true, creditCard: true}} handleError={handleError('number')} />
<EditionField label="Nome igual ao cartão" upperCase fullWidth onChange={handleInputChange('holderName')} value={fieldValues.holderName} warning={true} validations={{required: true}} handleError={handleError('holderName')}/>
<div className="double__fields">
<EditionField label="Validade" mask={this.masks.date} fullWidth onChange={handleInputChange('expirationDate')} value={fieldValues.expirationDate} warning={true} validations={{required: true, date: true}} handleError={handleError('expirationDate')}/>
<div style={{width:60}}/>
<EditionField label={isMobile ? "Código" : "Cod. Segurança"} mask={this.masks.security} fullWidth onChange={handleInputChange('securityCode')} value={fieldValues.securityCode} warning={true} validations={{required: true, securityCode: true}} handleError={handleError('securityCode')} />
</div>
<SubmitButton isMobile={isMobile} disabled={errors.length > 0} onClick={this.handleUpdateCard}>Definir Cartão</SubmitButton>
{/* <div onClick={this.changeCurrentMethod('BOLETO')} className="secondary__options">
<span>Trocar para boleto</span>
</div> */}
</EditPaymentInfoWrapper>
)
case 'BOLETO':
return (
<EditPaymentInfoWrapper>
<EditionField label="CPF" fullWidth /*value={fieldValues.personalData.name}*/ />
<SubmitButton isMobile={isMobile}>Definir Boleto</SubmitButton>
<div onClick={this.changeCurrentMethod('CREDIT_CARD')} className="secondary__options">
<span>Trocar para cartão de crédito</span>
</div>
</EditPaymentInfoWrapper>
)
default:
return null
}
}
handleUpdateCard = async () => {
try {
const cardHash = await this.handleCreateCardHash()
UserService.updateCreditCardNumber(
cardHash,
this.props.userAccessToken,
this.props.updateUserCreditCard,
this.props.returnScreen,
this.props.uid,
this.props.refreshUserData
)
} catch(err) {
console.error(err)
}
}
handleCreateCardHash = () =>
pagarme.client.connect({ encryption_key: this.props.pagarMeEncryptKey })
.then(client => {
return client.security.encrypt({
card_number: this.props.fieldValues.number,
card_holder_name: this.props.fieldValues.holderName,
card_expiration_date: this.props.fieldValues.expirationDate,
card_cvv: this.props.fieldValues.securityCode,
})
})
.then(card_hash => card_hash)
changeCurrentMethod = (nextMethod) => () => {
this.setState(state => ({
...state,
currentEditingMethod: nextMethod,
}))
}
masks = {
creditCard: [/\d/, /\d/, /\d/, /\d/, ' ', /\d/, /\d/, /\d/, /\d/, ' ', /\d/, /\d/, /\d/, /\d/, ' ', /\d/, /\d/, /\d/, /\d/],
date: [/\d/, /\d/, '/', /\d/, /\d/],
security: [/\d/, /\d/, /\d/]
}
}
// const EditPaymentInfo = ({payerInfo, switchPaymentMethodEdition}) => {
// const { method } = payerInfo;
// console.log('PAYMENT METHOD: ', method)
// if(method === 'CREDIT_CARD')
// {
// return (
// <EditPaymentInfoWrapper>
// <EditionField label="Número do Cartão" fullWidth /*value={fieldValues.personalData.name}*/ />
// <EditionField label="Nome igual ao cartão" fullWidth /*value={fieldValues.personalData.name}*/ />
// <div className="double__fields">
// <EditionField label="Validade" fullWidth /*value={fieldValues.personalData.name}*/ />
// <div style={{width:60}}/>
// <EditionField label="Cod. Segurança" fullWidth /*value={fieldValues.personalData.name}*/ />
// </div>
// <SubmitButton>Definir Cartão</SubmitButton>
// <div className="secondary__options">
// <span>Trocar para boleto</span>
// </div>
// </EditPaymentInfoWrapper>
// )
// }
// return null
// }
const mapDispatchToProps = dispatch => {
return {
openDialog: (type, data) => {
dispatch(updateDialogAction(type, data));
},
authConfirmUserSocialLogin: (publisher, fbCode, url) => {
dispatch(authConfirmUserSocialLogin(publisher, fbCode, url));
},
authConfirmUserAccount: (code, url) => {
dispatch(authConfirmUserAccount(code, url));
},
authErrorUserSocialLogin: (error, url) => {
dispatch(authErrorUserSocialLogin(error, url));
},
authUpdateToken : (token) => {
dispatch(authUpdateToken(token));
},
authUserLogout: (token , publisher) => {
dispatch(authUserLogout(token , publisher));
},
getPlansPublisher: (token, publisher) => {
dispatch(getPlansPublisher(token, publisher));
},
getCollections: (publisher, accessToken) => {
dispatch(getCollections(publisher, accessToken, 1, 9999, true));
},
updateUserCreditCard: (payerInfo) => {
dispatch(updateUserCreditCard(payerInfo))
},
refreshUserData: (payload) => {
dispatch(refreshUserData(payload))
}
};
}
const mapStateToProps = state => {
///console.log('[BASE - COMPONENT]', state);
const {modalReducer, paymentReducers, publisherReducers, collectionReducers, i18n, plansReducers} = state;
return {
getStatusModal: modalReducer.dialog,
publisher: publisherReducers.publisher,
collection: collectionReducers.collections,
bannerCollection: collectionReducers.collections && collectionReducers.collections.data && collectionReducers.collections.data[0],
theme: publisherReducers.publisher && publisherReducers.publisher.theme,
auth: modalReducer.auth && modalReducer.auth.token,
dialog: modalReducer.dialog,
payment: paymentReducers.payment,
plans: plansReducers,
i18n: i18n.ptBR
};
};
export default withAuthentication(connect(mapStateToProps, mapDispatchToProps)(SettingsComponent));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment