2018-03-25 18:03:08 +00:00
// License: LGPL-3.0-or-later
2018-03-25 17:30:42 +00:00
const h = require ( 'snabbdom/h' )
const R = require ( 'ramda' )
const flyd = require ( 'flyd' )
const uuid = require ( 'uuid' )
const supporterFields = require ( '../../components/supporter-fields' )
const button = require ( 'ff-core/button' )
const dedicationForm = require ( './dedication-form' )
const serialize = require ( 'form-serialize' )
const request = require ( '../../common/request' )
const format = require ( '../../common/format' )
const sepaTab = 'sepa'
const cardTab = 'credit_card'
function init ( donation$ , parentState ) {
//console.log(donation$().val);
var state = {
donation$ : donation$
, submitSupporter$ : flyd . stream ( )
, submitDedication$ : flyd . stream ( )
, params$ : parentState . params$
, currentStep$ : flyd . stream ( )
, selectedPayment$ : parentState . selectedPayment$
}
// Save supporter for dedication logic
state . dedicationData$ = flyd . map ( form => serialize ( form , { hash : true } ) , state . submitDedication$ )
const dedicationSuppData$ = flyd . map (
data => R . merge (
R . pick ( [ 'phone' , 'email' , 'address' ] , data )
, { name : ` ${ data . first _name || '' } ${ data . last _name || '' } ` }
)
, state . dedicationData$
)
state . showDedicationForm$ = flyd . map ( ( ) => false , state . submitDedication$ )
// Save donor supporter record
state . supporterFields = supporterFields . init ( { required : { email : true } } , parentState . params$ )
state . savedSupp$ = flyd . flatMap ( postSupporter , flyd . map ( formatFormData , state . submitSupporter$ ) )
state . savedDedicatee$ = flyd . map (
supporter => ( { supporter , note : state . dedicationData$ ( ) . dedication _note , type : state . dedicationData$ ( ) . dedication _type } )
, flyd . flatMap ( postSupporter , dedicationSuppData$ )
)
const changedDedication$ = flyd . merge ( state . dedicationData$ , state . savedDedicatee$ )
state . supporter$ = flyd . merge ( flyd . stream ( { } ) , state . savedSupp$ )
return state
}
const formatFormData = form => {
const data = serialize ( form , { hash : true } )
return R . evolve ( { customFields : R . toPairs } , data )
}
const postSupporter = supporter =>
flyd . map (
resp => resp . body
, request ( {
method : 'post'
, path : ` /nonprofits/ ${ app . nonprofit _id } /supporters `
, send : R . merge ( supporter , { locale : I18n . locale } )
} ) . load
)
const customFields = fields => {
if ( ! fields ) return ''
const input = field => h ( 'input' , {
props : {
name : ` customFields[ ${ field . name } ] `
, placeholder : field . label
}
} )
return h ( 'div' , R . map ( input , fields ) )
}
function recurringMessage ( state ) {
//function recurringMessage(isRecurring, state) {
var isRecurring = state . donation$ ( ) . recurring ;
var amountLabel = isRecurring ? ` ${ I18n . t ( 'nonprofits.donate.payment.monthly_recurring' ) } ` : ` ${ I18n . t ( 'nonprofits.donate.payment.one_time' ) } `
var weekly = "" ;
if ( state . donation$ ( ) . weekly ) {
amountLabel = amountLabel . replace ( I18n . t ( 'nonprofits.donate.amount.monthly' ) , I18n . t ( 'nonprofits.donate.amount.weekly' ) ) + "*" ;
weekly = h ( 'div.u-centered.notice' , [ h ( "small" , I18n . t ( 'nonprofits.donate.amount.weekly_notice' , { amount : ( format . weeklyToMonthly ( state . donation$ ( ) . amount ) / 100.0 ) , currency : app . currency _symbol } ) ) ] ) ;
}
return h ( 'div' , [
h ( 'p.u-fontSize--18 u.marginBottom--0.u-centered.amount' , [
h ( 'span' , app . currency _symbol + format . centsToDollars ( state . donation$ ( ) . amount ) )
, h ( 'strong' , amountLabel )
] )
, weekly ]
)
}
function view ( state ) {
var form = h ( 'form' , {
on : {
submit : ev => { ev . preventDefault ( ) ; state . currentStep$ ( 2 ) ; state . submitSupporter$ ( ev . currentTarget ) }
}
} , [
recurringMessage ( state )
, supporterFields . view ( state . supporterFields )
, customFields ( state . params$ ( ) . custom _fields )
, dedicationLink ( state )
, app . nonprofit . no _anon ? '' : anonField ( state )
, h ( 'fieldset.u-inlineBlock.u-marginTop--10' , paymentMethodButtons ( [ "card" , "sepa" ] , state ) )
] )
return h ( 'div.wizard-step.info-step.u-padding--10' , [
form
, h ( 'div' , {
style : { background : '#f8f8f8' , position : 'absolute' , 'top' : '0' , left : '3px' , height : '100%' , width : '99%' }
, class : { 'u-hide' : ! state . showDedicationForm$ ( ) , opacity : 0 , transition : 'opacity 1s' , delay : { opacity : 1 } }
} , [ dedicationForm . view ( state ) ] )
] )
}
function paymentMethodButtons ( paymentMethods , state ) {
return h ( 'section.group' ) , [
paymentButton ( { error$ : state . errors$ , buttonText : I18n . t ( 'nonprofits.donate.payment.tabs.sepa' ) } , sepaTab , state )
, paymentButton ( { error$ : state . errors$ , buttonText : I18n . t ( 'nonprofits.donate.payment.tabs.card' ) } , cardTab , state )
]
}
function paymentButton ( options , label , state ) {
options . error$ = options . error$ || flyd . stream ( )
options . loading$ = options . loading$ || flyd . stream ( )
let btnclass = { 'ff-button--loading' : options . loading$ ( ) } ;
btnclass [ label ] = true ;
return h ( 'div.ff-buttonWrapper.u-floatL.u-marginBottom--10' , {
class : { 'ff-buttonWrapper--hasError' : options . error$ ( ) }
} , [
h ( 'p.ff-button-error' , { style : { display : options . error$ ( ) ? 'block' : 'none' } } , options . error$ ( ) )
, h ( 'button.ff-button' , {
props : { type : 'submit' , disabled : options . loading$ ( ) }
, on : { click : e => state . selectedPayment$ ( label ) }
, class : btnclass
} , [
options . loading$ ( ) ? ( options . loadingText || " Saving..." ) : ( options . buttonText || I18n . t ( 'nonprofits.donate.payment.card.submit' ) )
] )
] )
}
function anonField ( state ) {
state . anon _id = state . anon _id || uuid . v1 ( ) // we need a unique id in case there are multiple supporter forms on the page -- the label 'for' attribute needs to be unique
return h ( 'div.u-marginTop--10.u-centered' , [
h ( 'input' , {
props : {
type : 'checkbox'
, name : 'anonymous'
, checked : state . anonymous
, id : ` anon-checkbox- ${ state . anon _id } `
}
} )
, h ( 'label' , {
props : {
type : 'checkbox'
, htmlFor : ` anon-checkbox- ${ state . anon _id } `
, id : 'anonLabel'
}
} , [
h ( 'small' , I18n . t ( 'nonprofits.donate.info.anonymous_checkbox' ) )
] )
] )
}
const dedicationLink = state => {
if ( state . params$ ( ) . hide _dedication ) return ''
return h ( 'label.u-centered.u-marginTop--10' , [
h ( 'small' , [
h ( 'a' , {
on : { click : [ state . showDedicationForm$ , true ] }
} , state . dedicationData$ ( ) && state . dedicationData$ ( ) . first _name
? [ h ( 'i.fa.fa-check' ) , I18n . t ( 'nonprofits.donate.info.dedication_saved' ) + ` ${ state . dedicationData$ ( ) . first _name || '' } ${ state . dedicationData$ ( ) . last _name || '' } ` ]
: [ I18n . t ( 'nonprofits.donate.info.dedication_link' ) ]
)
] )
] )
}
module . exports = { view , init }