lbry-desktop/ui/component/preorderContent/view.jsx
mayeaux 4f47779303
Preorder content functionality (#1743)
* adding preorder button

* adding preorder modal

* frontend mostly done

* check if its already purchased

* refresh page after purchase

* smooth out purchase process

* check if user has card saved

* handle case where its the users own upload

* fix transaction listing order bug

* cleaning up code for merge

* fix lint errors

* fix flow errors

* allow eur purchases

* support eur on customer transaction page

* fix css
2022-06-23 20:58:32 -04:00

190 lines
5.1 KiB
JavaScript

// @flow
import { Form } from 'component/common/form';
import { Lbryio } from 'lbryinc';
import * as PAGES from 'constants/pages';
import Button from 'component/button';
import Card from 'component/common/card';
import React from 'react';
import { getStripeEnvironment } from 'util/stripe';
const stripeEnvironment = getStripeEnvironment();
type TipParams = { tipAmount: number, tipChannelName: string, channelClaimId: string };
type UserParams = { activeChannelName: ?string, activeChannelId: ?string };
type Props = {
activeChannelId?: string,
activeChannelName?: string,
claimId: string,
claimType?: string,
channelClaimId?: string,
tipChannelName?: string,
claimIsMine: boolean,
isSupport: boolean,
isTipOnly?: boolean,
customText?: string,
doHideModal: () => void,
setAmount?: (number) => void,
preferredCurrency: string,
preOrderPurchase: (
TipParams,
anonymous: boolean,
UserParams,
claimId: string,
stripe: ?string,
preferredCurrency: string,
?(any) => Promise<void>,
?(any) => void
) => void,
preorderTag: string,
checkIfAlreadyPurchased: () => void,
};
export default function PreorderContent(props: Props) {
const {
activeChannelId,
activeChannelName,
claimId,
channelClaimId,
tipChannelName,
doHideModal,
preOrderPurchase,
preferredCurrency,
preorderTag,
checkIfAlreadyPurchased,
} = props;
// set the purchase amount once the preorder tag is selected
React.useEffect(() => {
setTipAmount(Number(preorderTag));
}, [preorderTag]);
/** STATE **/
const [tipAmount, setTipAmount] = React.useState(0);
const [waitingForBackend, setWaitingForBackend] = React.useState(false);
const [hasCardSaved, setHasSavedCard] = React.useState(true);
// check if user has a payment method saved
React.useEffect(() => {
if (!stripeEnvironment) return;
Lbryio.call(
'customer',
'status',
{
environment: stripeEnvironment,
},
'post'
).then((customerStatusResponse) => {
const defaultPaymentMethodId =
customerStatusResponse.Customer &&
customerStatusResponse.Customer.invoice_settings &&
customerStatusResponse.Customer.invoice_settings.default_payment_method &&
customerStatusResponse.Customer.invoice_settings.default_payment_method.id;
setHasSavedCard(Boolean(defaultPaymentMethodId));
});
}, [setHasSavedCard]);
// text for modal header
const titleText = 'Preorder Your Content';
// icon to use or explainer text to show per tab
let explainerText =
'This content is not available yet but you' + ' can pre-order it now so you can access it as soon as it goes live';
// when the form button is clicked
function handleSubmit() {
const tipParams: TipParams = {
tipAmount,
tipChannelName: tipChannelName || '',
channelClaimId: channelClaimId || '',
};
const userParams: UserParams = { activeChannelName, activeChannelId };
async function checkIfFinished() {
await checkIfAlreadyPurchased();
doHideModal();
}
setWaitingForBackend(true);
// hit backend to send tip
preOrderPurchase(
tipParams,
!activeChannelId,
userParams,
claimId,
stripeEnvironment,
preferredCurrency,
checkIfFinished,
doHideModal
);
}
let fiatSymbolToUse = '$';
if (preferredCurrency === 'EUR') {
fiatSymbolToUse = '€';
}
function buildButtonText() {
return `Preorder your content for ${fiatSymbolToUse}${tipAmount.toString()}`;
}
return (
<Form onSubmit={handleSubmit}>
{!waitingForBackend && (
<Card
title={titleText}
className={'preorder-content-modal'}
subtitle={
<>
{/* short explainer under the button */}
<div className="section__subtitle">{explainerText}</div>
</>
}
actions={
// confirm purchase card
<>
{/* */}
<div className="handle-submit-area">
<Button
autoFocus
onClick={handleSubmit}
button="primary"
// label={__('Confirm')}
label={buildButtonText()}
disabled={!hasCardSaved}
/>
{!hasCardSaved && (
<>
<div className="add-card-prompt">
<Button navigate={`/$/${PAGES.SETTINGS_STRIPE_CARD}`} label={__('Add a Card')} button="link" />
{' ' + __('To Preorder Content')}
</div>
</>
)}
</div>
</>
}
/>
)}
{/* processing payment card */}
{waitingForBackend && (
<Card
title={titleText}
className={'preorder-content-modal-loading'}
subtitle={
<>
{/* short explainer under the button */}
<div className="section__subtitle">{'Processing your purchase...'}</div>
</>
}
/>
)}
</Form>
);
}