lbry-desktop/ui/component/txoList/view.jsx

495 lines
18 KiB
React
Raw Normal View History

// @flow
2020-06-02 18:32:58 +02:00
import * as ICONS from 'constants/icons';
import React, { useEffect } from 'react';
import { withRouter } from 'react-router';
import { TXO_LIST as TXO } from 'lbry-redux';
import TransactionListTable from 'component/transactionListTable';
import Paginate from 'component/common/paginate';
import { FormField } from 'component/common/form-components/form-field';
import Button from 'component/button';
import Card from 'component/common/card';
import { toCapitalCase } from 'util/string';
import classnames from 'classnames';
2020-04-21 16:18:54 +02:00
import HelpLink from 'component/common/help-link';
import FileExporter from 'component/common/file-exporter';
2021-08-19 15:34:13 +02:00
import WalletFiatPaymentHistory from 'component/walletFiatPaymentHistory';
import WalletFiatAccountHistory from 'component/walletFiatAccountHistory';
2021-08-19 17:26:37 +02:00
import { STRIPE_PUBLIC_KEY } from '../../../config';
import { Lbryio } from 'lbryinc';
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';
}
type Props = {
search: string,
history: { action: string, push: (string) => void, replace: (string) => void },
txoPage: Array<Transaction>,
txoPageNumber: string,
txoItemCount: number,
fetchTxoPage: () => void,
fetchTransactions: () => void,
isFetchingTransactions: boolean,
transactionsFile: string,
updateTxoPageParams: (any) => void,
toast: (string, boolean) => void,
};
type Delta = {
dkey: string,
value: string,
2021-08-18 21:06:04 +02:00
tab: string
};
function TxoList(props: Props) {
const {
search,
txoPage,
txoItemCount,
fetchTxoPage,
fetchTransactions,
updateTxoPageParams,
history,
isFetchingTransactions,
transactionsFile,
} = props;
2021-08-19 17:26:37 +02:00
const [accountTransactionResponse, setAccountTransactionResponse] = React.useState([]);
const [customerTransactions, setCustomerTransactions] = React.useState([]);
function getPaymentHistory() {
return Lbryio.call(
'customer',
'list',
{
environment: stripeEnvironment,
},
'post'
);
}
function getAccountTransactionsa() {
return Lbryio.call(
'account',
'list',
{
environment: stripeEnvironment,
},
'post'
);
}
// calculate account transactions section
React.useEffect(() => {
(async function() {
try {
const getAccountTransactions = await getAccountTransactionsa();
setAccountTransactionResponse(getAccountTransactions);
} catch (err) {
console.log(err);
}
})();
}, []);
// populate customer payment data
React.useEffect(() => {
(async function() {
try {
// get card payments customer has made
let customerTransactionResponse = await getPaymentHistory();
// console.log('amount of transactions');
// console.log(customerTransactionResponse.length);
2021-08-19 19:41:58 +02:00
if(customerTransactionResponse && customerTransactionResponse.length){
customerTransactionResponse.reverse();
}
2021-08-19 17:26:37 +02:00
setCustomerTransactions(customerTransactionResponse);
} catch (err) {
console.log(err);
}
})();
}, []);
const urlParams = new URLSearchParams(search);
const page = urlParams.get(TXO.PAGE) || String(1);
const pageSize = urlParams.get(TXO.PAGE_SIZE) || String(TXO.PAGE_SIZE_DEFAULT);
const type = urlParams.get(TXO.TYPE) || TXO.ALL;
const subtype = urlParams.get(TXO.SUB_TYPE);
const active = urlParams.get(TXO.ACTIVE) || TXO.ALL;
2021-08-18 21:06:04 +02:00
const currency = urlParams.get('currency') || 'credits';
const fiatType = urlParams.get('fiatType') || 'incoming';
const currentUrlParams = {
page,
pageSize,
active,
type,
subtype,
2021-08-19 13:29:10 +02:00
currency,
fiatType,
};
2020-04-16 22:25:15 +02:00
const hideStatus =
2020-04-17 18:06:49 +02:00
type === TXO.SENT || (currentUrlParams.type === TXO.RECEIVED && currentUrlParams.subtype !== TXO.TIP);
2020-04-16 22:25:15 +02:00
const params = {};
if (currentUrlParams.type) {
if (currentUrlParams.type === TXO.ALL) {
params[TXO.EXCLUDE_INTERNAL_TRANSFERS] = true;
params[TXO.IS_MY_INPUT_OR_OUTPUT] = true;
} else if (currentUrlParams.type === TXO.SENT) {
params[TXO.IS_MY_INPUT] = true;
params[TXO.IS_NOT_MY_OUTPUT] = true;
if (currentUrlParams.subtype === TXO.TIP) {
params[TXO.TX_TYPE] = TXO.SUPPORT;
} else if (currentUrlParams.subtype === TXO.PURCHASE) {
params[TXO.TX_TYPE] = TXO.PURCHASE;
2020-04-16 22:25:15 +02:00
} else if (currentUrlParams.subtype === TXO.PAYMENT) {
params[TXO.TX_TYPE] = TXO.OTHER;
} else {
params[TXO.TX_TYPE] = [TXO.OTHER, TXO.PURCHASE, TXO.SUPPORT];
}
} else if (currentUrlParams.type === TXO.RECEIVED) {
params[TXO.IS_MY_OUTPUT] = true;
params[TXO.IS_NOT_MY_INPUT] = true;
if (currentUrlParams.subtype === TXO.TIP) {
params[TXO.TX_TYPE] = TXO.SUPPORT;
} else if (currentUrlParams.subtype === TXO.PURCHASE) {
params[TXO.TX_TYPE] = TXO.PURCHASE;
} else if (currentUrlParams.subtype === TXO.PAYMENT) {
params[TXO.TX_TYPE] = TXO.OTHER;
params[TXO.EXCLUDE_INTERNAL_TRANSFERS] = true;
} else {
params[TXO.TX_TYPE] = [TXO.OTHER, TXO.PURCHASE, TXO.SUPPORT];
}
} else if (currentUrlParams.type === TXO.SUPPORT) {
params[TXO.TX_TYPE] = TXO.SUPPORT;
params[TXO.IS_MY_INPUT] = true;
params[TXO.IS_MY_OUTPUT] = true;
} else if (currentUrlParams.type === TXO.CHANNEL || currentUrlParams.type === TXO.REPOST) {
params[TXO.TX_TYPE] = currentUrlParams.type;
} else if (currentUrlParams.type === TXO.PUBLISH) {
params[TXO.TX_TYPE] = TXO.STREAM;
}
}
if (currentUrlParams.active) {
if (currentUrlParams.active === 'spent') {
params[TXO.IS_SPENT] = true;
} else if (currentUrlParams.active === 'active') {
params[TXO.IS_NOT_SPENT] = true;
}
}
2020-04-16 22:25:15 +02:00
if (currentUrlParams.page) params[TXO.PAGE] = Number(page);
if (currentUrlParams.pageSize) params[TXO.PAGE_SIZE] = Number(pageSize);
function handleChange(delta: Delta) {
const url = updateUrl(delta);
history.push(url);
}
2021-08-18 21:06:04 +02:00
// let currency = 'credits';
function updateUrl(delta: Delta) {
const newUrlParams = new URLSearchParams();
2021-08-18 21:06:04 +02:00
2021-08-19 15:34:13 +02:00
const existingCurrency = newUrlParams.get('currency') || 'credits';
const existingFiatType = newUrlParams.get('fiatType') || 'incoming';
console.log(existingFiatType);
2021-08-19 15:34:13 +02:00
console.log(newUrlParams);
2021-08-18 21:06:04 +02:00
// set tab name to account for wallet page tab
newUrlParams.set('tab', delta.tab);
2021-08-19 13:29:10 +02:00
// only update currency if it's being changed
if (delta.currency) {
newUrlParams.set('currency', delta.currency);
}
2021-08-18 21:06:04 +02:00
if (delta.fiatType) {
newUrlParams.set('fiatType', delta.fiatType);
} else {
newUrlParams.set('fiatType', existingFiatType);
}
switch (delta.dkey) {
case TXO.PAGE:
if (currentUrlParams.type) {
newUrlParams.set(TXO.TYPE, currentUrlParams.type);
}
if (currentUrlParams.subtype) {
newUrlParams.set(TXO.SUB_TYPE, currentUrlParams.subtype);
}
if (currentUrlParams.active) {
newUrlParams.set(TXO.ACTIVE, currentUrlParams.active);
}
newUrlParams.set(TXO.PAGE, delta.value);
break;
case TXO.TYPE:
newUrlParams.set(TXO.TYPE, delta.value);
if (delta.value === TXO.SENT || delta.value === TXO.RECEIVED) {
2020-04-16 22:25:15 +02:00
newUrlParams.set(TXO.ACTIVE, 'all');
if (currentUrlParams.subtype) {
newUrlParams.set(TXO.SUB_TYPE, currentUrlParams.subtype);
} else {
newUrlParams.set(TXO.SUB_TYPE, 'all');
}
}
2020-04-17 17:20:48 +02:00
if (currentUrlParams.active && !hideStatus) {
newUrlParams.set(TXO.ACTIVE, currentUrlParams.active);
} else {
newUrlParams.set(TXO.ACTIVE, 'all');
}
newUrlParams.set(TXO.PAGE, String(1));
newUrlParams.set(TXO.PAGE_SIZE, currentUrlParams.pageSize);
break;
case TXO.SUB_TYPE:
if (currentUrlParams.type) {
newUrlParams.set(TXO.TYPE, currentUrlParams.type);
}
newUrlParams.set(TXO.ACTIVE, 'all');
newUrlParams.set(TXO.SUB_TYPE, delta.value);
newUrlParams.set(TXO.PAGE, String(1));
newUrlParams.set(TXO.PAGE_SIZE, currentUrlParams.pageSize);
break;
case TXO.ACTIVE:
if (currentUrlParams.type) {
newUrlParams.set(TXO.TYPE, currentUrlParams.type);
}
if (currentUrlParams.subtype) {
newUrlParams.set(TXO.SUB_TYPE, currentUrlParams.subtype);
}
newUrlParams.set(TXO.ACTIVE, delta.value);
newUrlParams.set(TXO.PAGE, String(1));
newUrlParams.set(TXO.PAGE_SIZE, currentUrlParams.pageSize);
break;
}
2020-04-17 17:20:48 +02:00
return `?${newUrlParams.toString()}`;
}
const paramsString = JSON.stringify(params);
2021-08-18 21:06:04 +02:00
// tab used in the wallet section
// TODO: change the name of this eventually
const tab = 'fiat-payment-history';
useEffect(() => {
if (paramsString && updateTxoPageParams) {
const params = JSON.parse(paramsString);
updateTxoPageParams(params);
}
}, [paramsString, updateTxoPageParams]);
return (
<Card
2021-08-18 20:06:12 +02:00
title={
<><div className="table__header-text" style={{width: '124px', display: 'inline-block'}}>{__(`Transactions`)}</div>
<div style={{display: 'inline-block'}}>
<fieldset-section>
<div className={'txo__radios'}>
<Button
button="alt"
2021-08-18 21:06:04 +02:00
onClick={(e) => handleChange({ currency: 'credits', tab })}
2021-08-18 20:06:12 +02:00
className={classnames(`button-toggle`, {
2021-08-18 21:06:04 +02:00
'button-toggle--active': currency === 'credits',
2021-08-18 20:06:12 +02:00
})}
2021-08-18 21:06:04 +02:00
label={__('Credits')}
2021-08-18 20:06:12 +02:00
/>
<Button
button="alt"
2021-08-18 21:06:04 +02:00
onClick={(e) => handleChange({ currency: 'fiat', tab })}
2021-08-18 20:06:12 +02:00
className={classnames(`button-toggle`, {
2021-08-18 21:06:04 +02:00
'button-toggle--active': currency === 'fiat',
2021-08-18 20:06:12 +02:00
})}
label={__('USD')}
/>
</div>
</fieldset-section>
</div>
2021-08-18 20:06:12 +02:00
</>
}
titleActions={ <></>
// <div className="card__actions--inline">
// {!isFetchingTransactions && transactionsFile === null && (
// <label>{<span className="error__text">{__('Failed to process fetched data.')}</span>}</label>
// )}
// <div className="txo__export">
// <FileExporter
// data={transactionsFile}
// label={__('Export')}
// tooltip={__('Fetch transaction data for export')}
// defaultFileName={'transactions-history.csv'}
// onFetch={() => fetchTransactions()}
// progressMsg={isFetchingTransactions ? __('Fetching data') : ''}
// />
// </div>
// <Button button="alt" icon={ICONS.REFRESH} label={__('Refresh')} onClick={() => fetchTxoPage()} />
// </div>
}
2020-04-29 21:31:11 +02:00
isBodyList
body={ currency === 'credits' ?
<div>
<div className="card__body-actions">
<div className="card__actions">
<div>
<FormField
type="select"
name="type"
2020-04-21 16:18:54 +02:00
label={
<>
{__('Type')}
<HelpLink href="https://lbry.com/faq/transaction-types" />
</>
}
value={type || 'all'}
2021-08-18 21:06:04 +02:00
onChange={(e) => handleChange({ dkey: TXO.TYPE, value: e.target.value, tab })}
>
{Object.values(TXO.DROPDOWN_TYPES).map((v) => {
const stringV = String(v);
return (
<option key={stringV} value={stringV}>
{stringV && __(toCapitalCase(stringV))}
</option>
);
})}
</FormField>
</div>
{(type === TXO.SENT || type === TXO.RECEIVED) && (
<div>
<FormField
type="select"
name="subtype"
label={__('Payment Type')}
value={subtype || 'all'}
2021-08-18 21:06:04 +02:00
onChange={(e) => handleChange({ dkey: TXO.SUB_TYPE, value: e.target.value, tab })}
>
{Object.values(TXO.DROPDOWN_SUBTYPES).map((v) => {
const stringV = String(v);
return (
<option key={stringV} value={stringV}>
{stringV && __(toCapitalCase(stringV))}
</option>
);
})}
</FormField>
</div>
)}
2020-04-16 22:25:15 +02:00
{!hideStatus && (
<div>
<fieldset-section>
2020-07-02 17:39:12 +02:00
<label>{__('Status')}</label>
2020-04-16 22:25:15 +02:00
<div className={'txo__radios'}>
<Button
button="alt"
2021-08-18 21:06:04 +02:00
onClick={(e) => handleChange({ dkey: TXO.ACTIVE, value: 'active', tab })}
2020-04-16 22:25:15 +02:00
className={classnames(`button-toggle`, {
'button-toggle--active': active === TXO.ACTIVE,
})}
label={__('Active')}
/>
<Button
button="alt"
2021-08-18 21:06:04 +02:00
onClick={(e) => handleChange({ dkey: TXO.ACTIVE, value: 'spent', tab })}
2020-04-16 22:25:15 +02:00
className={classnames(`button-toggle`, {
'button-toggle--active': active === 'spent',
})}
label={__('Historical')}
/>
<Button
button="alt"
2021-08-18 21:06:04 +02:00
onClick={(e) => handleChange({ dkey: TXO.ACTIVE, value: 'all', tab })}
2020-04-16 22:25:15 +02:00
className={classnames(`button-toggle`, {
'button-toggle--active': active === 'all',
})}
label={__('All')}
/>
</div>
</fieldset-section>
</div>
)}
2021-08-19 15:34:13 +02:00
<div className="card__actions--inline" style={{marginLeft: '181px'}}>
2021-08-18 20:06:12 +02:00
{!isFetchingTransactions && transactionsFile === null && (
<label>{<span className="error__text">{__('Failed to process fetched data.')}</span>}</label>
)}
<div className="txo__export">
<FileExporter
data={transactionsFile}
label={__('Export')}
tooltip={__('Fetch transaction data for export')}
defaultFileName={'transactions-history.csv'}
onFetch={() => fetchTransactions()}
progressMsg={isFetchingTransactions ? __('Fetching data') : ''}
/>
</div>
<Button button="alt" icon={ICONS.REFRESH} label={__('Refresh')} onClick={() => fetchTxoPage()} />
</div>
</div>
</div>
2021-08-18 20:06:12 +02:00
{/* listing of the transactions */}
<TransactionListTable txos={txoPage} />
<Paginate totalPages={Math.ceil(txoItemCount / Number(pageSize))} />
2021-08-19 15:34:13 +02:00
</div>
// fiat section
: <div>
2021-08-19 17:11:51 +02:00
<div className="section card-stack">
<div className="card__body-actions">
<div className="card__actions">
{!hideStatus && (
<div>
<fieldset-section>
<label>{__('Type')}</label>
<div className={'txo__radios'}>
<Button
button="alt"
onClick={(e) => handleChange({ tab, fiatType: 'incoming', currency: 'fiat' })}
className={classnames(`button-toggle`, {
'button-toggle--active': fiatType === 'incoming',
})}
label={__('Incoming')}
/>
<Button
button="alt"
onClick={(e) => handleChange({ tab, fiatType: 'outgoing', currency: 'fiat' })}
className={classnames(`button-toggle`, {
'button-toggle--active': fiatType === 'outgoing',
})}
label={__('Outgoing')}
/>
{/*<Button*/}
{/* button="alt"*/}
{/* onClick={(e) => handleChange({ dkey: TXO.ACTIVE, value: 'all', tab, currency: 'fiat' })}*/}
{/* className={classnames(`button-toggle`, {*/}
{/* 'button-toggle--active': active === 'all',*/}
{/* })}*/}
{/* label={__('Payouts')}*/}
{/*/>*/}
</div>
</fieldset-section>
</div>
)}
</div>
</div>
2021-08-19 17:11:51 +02:00
{/* listing of the transactions */}
2021-08-19 19:41:58 +02:00
{ fiatType === 'incoming' && <WalletFiatAccountHistory transactions={accountTransactionResponse} /> }
{ fiatType === 'outgoing' && <WalletFiatPaymentHistory transactions={customerTransactions} /> }
{/* TODO: have to finish pagination */}
2021-08-19 17:11:51 +02:00
<Paginate totalPages={Math.ceil(txoItemCount / Number(pageSize))} />
</div>
</div>
}
/>
);
}
export default withRouter(TxoList);