lbry-desktop/ui/page/settingsStripeAccount/view.jsx
mayeaux 8ff3b753ad
Move transactions from Settings to Wallet (#6871)
* remove unused conditional

get stuff ready for merge

bugfix and cleanup

requested changes

fixing flow errors

fix last flow error and touchups

fiat and lbc tabs coming along

support setting currency as the default tab via query param

add wallet fiat balance

fixing naming

add fiat transactions

using es6 to populate data

should be fine but keeps crashing

transaction listing working

add no transactions thing

about to add a third tab

add third tab

add card last 4 to transaction history

some renaming

show payments successfully

show filler for subscriptions

display if no transactions or subs

working but in the wrong component

approaching something thats working

showing total tipped amount

about to add last couple features

cleanup

More touchups

adding last features

calculate the total amount of unique creators tipped

couple touchups

remove transaction listings from settings

add view transactions buttons

small optimization

add subscriptions section

fix lot of linting errors and make command more userful

* some copy changes

* about to add last couple changes

* update still require verification

* fix button spacing

* hide subscriptions sections and fix links

* cleanups before merging

* more cleanup

* cleanup with last four fix

* changing tab functionality

* bugfix and fix presentation of cards

* fix transactions bug

* change order and remove logs

* remove unused code in account

* more linter fixes

* update account balance presentation

* fix flow errors
2021-08-13 13:59:43 -04:00

295 lines
10 KiB
JavaScript

// @flow
import * as ICONS from 'constants/icons';
import * as PAGES from 'constants/pages';
import React from 'react';
import Button from 'component/button';
import Card from 'component/common/card';
import Page from 'component/page';
import { Lbryio } from 'lbryinc';
import { URL, WEBPACK_WEB_PORT, STRIPE_PUBLIC_KEY } from 'config';
const isDev = process.env.NODE_ENV !== 'production';
let stripeEnvironment = 'test';
// if the key contains pk_live it's a live key
// update the environment for the calls to the backend to indicate which environment to hit
if (STRIPE_PUBLIC_KEY.indexOf('pk_live') > -1) {
stripeEnvironment = 'live';
}
let successStripeRedirectUrl, failureStripeRedirectUrl;
let successEndpoint = '/$/settings/tip_account';
let failureEndpoint = '/$/settings/tip_account';
if (isDev) {
successStripeRedirectUrl = 'http://localhost:' + WEBPACK_WEB_PORT + successEndpoint;
failureStripeRedirectUrl = 'http://localhost:' + WEBPACK_WEB_PORT + failureEndpoint;
} else {
successStripeRedirectUrl = URL + successEndpoint;
failureStripeRedirectUrl = URL + failureEndpoint;
}
type Props = {
source: string,
doOpenModal: (string, {}) => void,
doToast: ({ message: string }) => void,
};
type State = {
error: boolean,
loading: boolean,
content: ?string,
stripeConnectionUrl: string,
accountConfirmed: boolean,
accountPendingConfirmation: boolean,
accountNotConfirmedButReceivedTips: boolean,
unpaidBalance: number,
pageTitle: string,
stillRequiringVerification: boolean,
accountTransactions: any
};
class StripeAccountConnection extends React.Component<Props, State> {
constructor(props: Props) {
super(props);
this.state = {
error: false,
content: null,
loading: true,
accountConfirmed: false,
accountPendingConfirmation: false,
accountNotConfirmedButReceivedTips: false,
unpaidBalance: 0,
stripeConnectionUrl: '',
pageTitle: 'Add Payout Method',
stillRequiringVerification: true,
accountTransactions: [],
};
}
componentDidMount() {
let doToast = this.props.doToast;
var that = this;
function getAndSetAccountLink(stillNeedToConfirmAccount) {
Lbryio.call(
'account',
'link',
{
return_url: successStripeRedirectUrl,
refresh_url: failureStripeRedirectUrl,
environment: stripeEnvironment,
},
'post'
).then((accountLinkResponse) => {
// stripe link for user to navigate to and confirm account
const stripeConnectionUrl = accountLinkResponse.url;
// set connection url on frontend
that.setState({
stripeConnectionUrl,
});
// show the account confirmation link if not created already
if (stillNeedToConfirmAccount) {
that.setState({
accountPendingConfirmation: true,
});
}
});
}
// call the account status endpoint
Lbryio.call(
'account',
'status',
{
environment: stripeEnvironment,
},
'post'
)
.then((accountStatusResponse) => {
const yetToBeCashedOutBalance = accountStatusResponse.total_received_unpaid;
if (yetToBeCashedOutBalance) {
that.setState({
unpaidBalance: yetToBeCashedOutBalance,
});
Lbryio.call(
'account',
'list',
{
environment: stripeEnvironment,
},
'post'
).then((accountListResponse: any) => {
// TODO type this
that.setState({
accountTransactions: accountListResponse.reverse(),
});
});
}
// if charges already enabled, no need to generate an account link
if (accountStatusResponse.charges_enabled) {
// account has already been confirmed
const eventuallyDueInformation = accountStatusResponse.account_info.requirements.eventually_due;
const currentlyDueInformation = accountStatusResponse.account_info.requirements.currently_due;
let objectToUpdateState = {
accountConfirmed: true,
stillRequiringVerification: false,
};
if ((eventuallyDueInformation && eventuallyDueInformation.length) || (currentlyDueInformation && currentlyDueInformation)) {
objectToUpdateState.stillRequiringVerification = true;
getAndSetAccountLink(false);
}
that.setState(objectToUpdateState);
// user has not confirmed an account but have received payments
} else if (accountStatusResponse.total_received_unpaid > 0) {
that.setState({
accountNotConfirmedButReceivedTips: true,
});
getAndSetAccountLink();
// user has not received any amount or confirmed an account
} else {
// get stripe link and set it on the frontend
// pass true so it updates the frontend
getAndSetAccountLink(true);
}
})
.catch(function (error) {
// errorString passed from the API (with a 403 error)
const errorString = 'account not linked to user, please link first';
// if it's beamer's error indicating the account is not linked yet
if (error.message.indexOf(errorString) > -1) {
// get stripe link and set it on the frontend
getAndSetAccountLink(true);
} else {
// probably an error from stripe
const displayString = __('There was an error getting your account setup, please try again later');
doToast({ message: displayString, isError: true });
// not an error from Beamer, throw it
throw new Error(error);
}
});
}
render() {
const {
stripeConnectionUrl,
accountConfirmed,
accountPendingConfirmation,
unpaidBalance,
accountNotConfirmedButReceivedTips,
pageTitle,
stillRequiringVerification,
} = this.state;
return (
<Page backout={{ title: pageTitle, backLabel: __('Done') }} noFooter noSideNavigation>
<Card
title={<div className="table__header-text">{__('Connect a bank account')}</div>}
isBodyList
body={
<div>
{/* show while waiting for account status */}
{!accountConfirmed && !accountPendingConfirmation && !accountNotConfirmedButReceivedTips && (
<div className="card__body-actions">
<div>
<div>
<h3>{__('Getting your bank account connection status...')}</h3>
</div>
</div>
</div>
)}
{/* user has yet to complete their integration */}
{!accountConfirmed && accountPendingConfirmation && (
<div className="card__body-actions">
<div>
<div>
<h3>{__('Connect your bank account to Odysee to receive donations directly from users')}</h3>
</div>
<div className="section__actions">
<a href={stripeConnectionUrl}>
<Button button="secondary" label={__('Connect your bank account')} icon={ICONS.FINANCE} />
</a>
</div>
</div>
</div>
)}
{/* user has completed their integration */}
{accountConfirmed && (
<div className="card__body-actions">
<div>
<div>
<h3>{__('Congratulations! Your account has been connected with Odysee.')}</h3>
{stillRequiringVerification && <><h3 style={{marginTop: '10px'}}>Although your account is connected it still requires verification to begin receiving tips.</h3>
<h3 style={{marginTop: '10px'}}>Please use the button below to complete your verification process and enable tipping for your account.</h3></> }
</div>
</div>
</div>
)}
{/* TODO: hopefully we won't be using this anymore and can remove it */}
{accountNotConfirmedButReceivedTips && (
<div className="card__body-actions">
<div>
<div>
<h3>{__('Congratulations, you have already begun receiving tips on Odysee!')}</h3>
<div>
<br />
<h3>
{__('Your pending account balance is $%balance% USD.', { balance: unpaidBalance / 100 })}
</h3>
</div>
<br />
<div>
<h3>
{__(
'Connect your bank account to be able to cash your pending balance out to your account.'
)}
</h3>
</div>
<div className="section__actions">
<a href={stripeConnectionUrl}>
<Button button="secondary" label={__('Connect your bank account')} icon={ICONS.FINANCE} />
</a>
</div>
</div>
</div>
</div>
)}
</div>
}
actions={
<>{ stillRequiringVerification && <Button
button="primary"
label={__('Complete Verification')}
icon={ICONS.SETTINGS}
navigate={stripeConnectionUrl}
className="stripe__complete-verification-button"
/> }
<Button
button="secondary"
label={__('View Transactions')}
icon={ICONS.SETTINGS}
navigate={`/$/${PAGES.WALLET}?tab=account-history`}
/></>
}
/>
<br />
</Page>
);
}
}
export default StripeAccountConnection;