UNPKG

react-saasify

Version:

React components for Saasify web clients.

145 lines (127 loc) 3.38 kB
import React, { Component } from 'react' import PropTypes from 'prop-types' import theme from 'lib/theme' import { StripeProvider, Elements, CardElement, injectStripe } from 'react-stripe-elements' import { observer, inject } from 'mobx-react' import { Button, Icon, Tooltip } from 'lib/antd' import env from 'lib/env' import styles from './styles.module.css' const createOptions = (fontSize = 16) => { return { style: { base: { fontSize, color: '#424770', letterSpacing: '0.025em', '::placeholder': { color: '#aab7c4' } }, invalid: { color: '#9e2146' } } } } @inject('config') @observer export class CheckoutForm extends Component { static propTypes = { onSubmit: PropTypes.func.isRequired, loading: PropTypes.bool, title: PropTypes.string, action: PropTypes.node, footer: PropTypes.node, className: PropTypes.string, config: PropTypes.object.isRequired } render() { return ( <StripeProvider apiKey={env.stripePublicKey}> <Elements> <CheckoutFormImpl {...this.props} /> </Elements> </StripeProvider> ) } } @injectStripe class CheckoutFormImpl extends Component { static propTypes = { config: PropTypes.object.isRequired, stripe: PropTypes.object.isRequired, onSubmit: PropTypes.func.isRequired, loading: PropTypes.bool, title: PropTypes.string, action: PropTypes.node, footer: PropTypes.node, className: PropTypes.string } static defaultProps = { loading: false } render() { const { config, loading, title, action, footer, className } = this.props return ( <form className={theme(styles, 'form', className, theme(styles, 'light'))} onSubmit={this._onSubmit} > {title && <h2 className={theme(styles, 'title')}>{title}</h2>} <label className={theme(styles, 'label')}> Name <input className={theme(styles, 'input')} name='name' type='text' placeholder='John Doe' required /> </label> <label className={theme(styles, 'label')}> Card Details <Tooltip placement='right' title='All payment info is securely handled by Stripe.' > <Icon className={theme(styles, 'detail')} type='question-circle' /> </Tooltip> <CardElement {...createOptions()} /> </label> {config.coupons && config.coupons.length > 0 && ( <label className={theme(styles, 'label')}> Promo Code <input className={theme(styles, 'input')} name='coupon' type='text' placeholder='' /> </label> )} {action && ( <Button type='primary' htmlType='submit' className={theme(styles, 'submit')} loading={loading} > {action} </Button> )} {footer} </form> ) } _onSubmit = async (e) => { e.preventDefault() const name = e.target.name.value const coupon = e.target.coupon && e.target.coupon.value this.props.onSubmit({ name, coupon, stripe: this.props.stripe }) } }