2019-02-22 09:30:00 +03:00
|
|
|
import { Elements, StripeProvider, injectStripe } from 'react-stripe-elements';
|
|
|
|
import { Component } from 'react';
|
|
|
|
import FormHeader from '../components/FormHeader';
|
|
|
|
import FormSubmit from '../components/FormSubmit';
|
|
|
|
import FormHeaderCTA from '../components/FormHeaderCTA';
|
|
|
|
import NameInput from '../components/NameInput';
|
|
|
|
import EmailInput from '../components/EmailInput';
|
2019-04-16 20:06:26 +03:00
|
|
|
import CouponInput from '../components/CouponInput';
|
2019-02-22 09:30:00 +03:00
|
|
|
import PasswordInput from '../components/PasswordInput';
|
|
|
|
import CheckoutForm from '../components/CheckoutForm';
|
|
|
|
import Form from '../components/Form';
|
|
|
|
|
2019-04-16 20:06:26 +03:00
|
|
|
const getCouponData = frameLocation => {
|
|
|
|
const params = new URLSearchParams(frameLocation.query);
|
|
|
|
const coupon = params.get('coupon') || '';
|
|
|
|
return { coupon };
|
|
|
|
};
|
2019-02-26 06:09:16 +03:00
|
|
|
|
2019-02-22 09:30:00 +03:00
|
|
|
class PaymentForm extends Component {
|
|
|
|
|
|
|
|
constructor(props) {
|
|
|
|
super(props);
|
|
|
|
}
|
|
|
|
|
2019-04-16 20:06:26 +03:00
|
|
|
handleSubmit = ({ name, email, password, plan, coupon }) => {
|
2019-02-22 09:30:00 +03:00
|
|
|
// Within the context of `Elements`, this call to createToken knows which Element to
|
|
|
|
// tokenize, since there's only one in this group.
|
|
|
|
plan = this.props.selectedPlan ? this.props.selectedPlan.name : "";
|
|
|
|
this.props.stripe.createToken({ name: name }).then(({ token }) => {
|
|
|
|
this.props.handleSubmit({
|
|
|
|
adapter: 'stripe',
|
|
|
|
plan: plan,
|
|
|
|
stripeToken: token.id,
|
2019-04-16 20:06:26 +03:00
|
|
|
name, email, password, coupon
|
2019-02-22 09:30:00 +03:00
|
|
|
});
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
2019-04-16 20:06:26 +03:00
|
|
|
render({frameLocation}) {
|
2019-04-17 17:16:03 +03:00
|
|
|
let label = this.props.showSpinner ? "Signing up..." : "Confirm payment";
|
2019-04-16 20:06:26 +03:00
|
|
|
const { coupon } = getCouponData(frameLocation);
|
2019-02-22 09:30:00 +03:00
|
|
|
return (
|
2019-04-16 20:06:26 +03:00
|
|
|
<Form includeData={getCouponData(frameLocation)} bindTo="request-password-reset" onSubmit={(data) => this.handleSubmit(data)}>
|
2019-02-26 06:09:16 +03:00
|
|
|
<NameInput bindTo="name" className="first" />
|
|
|
|
<EmailInput bindTo="email" />
|
|
|
|
<PasswordInput bindTo="password" />
|
2019-04-16 20:06:26 +03:00
|
|
|
{ coupon ? <CouponInput disabled={true} bindTo="coupon" /> : '' }
|
2019-02-22 09:30:00 +03:00
|
|
|
<CheckoutForm />
|
2019-04-17 17:16:03 +03:00
|
|
|
<FormSubmit label={label} showSpinner={this.props.showSpinner} />
|
2019-02-22 09:30:00 +03:00
|
|
|
</Form>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
const PaymentFormWrapped = injectStripe(PaymentForm);
|
|
|
|
|
2019-02-26 06:09:16 +03:00
|
|
|
export default class StripePaymentPage extends Component {
|
2019-02-22 09:30:00 +03:00
|
|
|
constructor(props) {
|
|
|
|
super(props);
|
|
|
|
this.plans = props.stripeConfig.config.plans || [];
|
|
|
|
this.state = {
|
|
|
|
selectedPlan: this.plans[0] ? this.plans[0] : ""
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
renderPlan({ currency, amount, id, interval, name }) {
|
|
|
|
const selectedPlanId = this.state.selectedPlan ? this.state.selectedPlan.id : "";
|
2019-02-26 06:09:16 +03:00
|
|
|
const dollarAmount = (amount / 100);
|
2019-02-22 09:30:00 +03:00
|
|
|
return (
|
2019-02-26 06:09:16 +03:00
|
|
|
<label for={ id }>
|
|
|
|
<div className={ (selectedPlanId === id ? "gm-plan selected" : "gm-plan") }>
|
|
|
|
<input type="radio" id={id} name="radio-group" value={id} defaultChecked={id === selectedPlanId} />
|
|
|
|
<span className="gm-amount">{`$${dollarAmount}`}</span>
|
|
|
|
<span className="gm-interval"><span className="gm-currency">{ `${currency}` }</span> {`${interval}`}</span>
|
|
|
|
</div>
|
|
|
|
</label>
|
2019-02-22 09:30:00 +03:00
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
changePlan(e) {
|
|
|
|
const plan = this.plans.find(plan => plan.id === e.target.value);
|
|
|
|
this.setState({
|
|
|
|
selectedPlan: plan
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2019-02-26 06:09:16 +03:00
|
|
|
renderPlans(plans, title, iconStyle) {
|
2019-02-22 09:30:00 +03:00
|
|
|
return (
|
2019-02-26 06:09:16 +03:00
|
|
|
<div className="gm-plans" onChange={(e) => this.changePlan(e)}>
|
|
|
|
<div className="gm-publication-info">
|
|
|
|
<div className="gm-logo" style={iconStyle}></div>
|
|
|
|
<div className="gm-publication-name">
|
|
|
|
<h2>{title}</h2>
|
|
|
|
<span>Subscription</span>
|
|
|
|
</div>
|
|
|
|
</div>
|
2019-02-22 09:30:00 +03:00
|
|
|
{
|
|
|
|
plans.map((plan) => this.renderPlan(plan))
|
|
|
|
}
|
|
|
|
</div>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2019-02-26 06:09:16 +03:00
|
|
|
renderPlansSection(title, iconStyle) {
|
2019-02-22 09:30:00 +03:00
|
|
|
return (
|
|
|
|
<div className="gm-plans-container">
|
2019-02-26 06:09:16 +03:00
|
|
|
{this.renderPlans(this.plans, title, iconStyle)}
|
2019-02-22 09:30:00 +03:00
|
|
|
</div>
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
2019-04-16 20:06:26 +03:00
|
|
|
render({ error, handleSubmit, stripeConfig, siteConfig, showSpinner, frameLocation }) {
|
2019-02-22 09:30:00 +03:00
|
|
|
const publicKey = stripeConfig.config.publicKey || '';
|
2019-02-26 06:09:16 +03:00
|
|
|
let iconUrl = siteConfig && siteConfig.icon;
|
|
|
|
let title = (siteConfig && siteConfig.title) || "Ghost Publication";
|
|
|
|
let iconStyle = iconUrl ? {
|
|
|
|
backgroundImage: `url(${iconUrl})`,
|
|
|
|
backgroundSize: `44px`
|
|
|
|
} : {};
|
2019-02-22 09:30:00 +03:00
|
|
|
return (
|
2019-02-26 06:09:16 +03:00
|
|
|
<div class="gm-subscribe-page">
|
2019-04-16 18:36:37 +03:00
|
|
|
<FormHeader title="Subscribe" error={ error } errorText={ error } />
|
2019-02-26 06:09:16 +03:00
|
|
|
<div className="gm-subscribe-form-wrapper">
|
|
|
|
<div className="gm-modal-form gm-subscribe-form">
|
|
|
|
<StripeProvider apiKey={publicKey}>
|
|
|
|
<Elements>
|
2019-04-16 20:06:26 +03:00
|
|
|
<PaymentFormWrapped handleSubmit={handleSubmit} frameLocation={frameLocation} publicKey={publicKey} selectedPlan={this.state.selectedPlan} showSpinner={showSpinner} />
|
2019-02-26 06:09:16 +03:00
|
|
|
</Elements>
|
|
|
|
</StripeProvider>
|
|
|
|
<div className="flex justify-center mt4">
|
|
|
|
<FormHeaderCTA title="Already a member?" label="Log in" hash="#signin" />
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div class="gm-plans-divider"></div>
|
|
|
|
{this.renderPlansSection(title, iconStyle)}
|
2019-02-22 09:30:00 +03:00
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
)
|
|
|
|
}
|
|
|
|
};
|