From 9f7cf0cf1c8aa80af9a884943157371e20f18166 Mon Sep 17 00:00:00 2001 From: Randy Schott <1815175+schottra@users.noreply.github.com> Date: Tue, 3 Oct 2023 17:48:40 -0400 Subject: [PATCH] [PAY-1861] Expose Pay Extra details in purchase/sales tables (#6209) --- packages/common/src/api/purchases.ts | 12 +++- .../common/src/models/USDCTransactions.ts | 1 + packages/common/src/utils/wallet.ts | 12 +++- .../components/PurchaseSummaryTable.tsx | 64 ++++++++++--------- .../SummaryTable.module.css} | 4 -- .../components/summary-table/SummaryTable.tsx | 45 +++++++++++++ .../web/src/components/summary-table/index.ts | 1 + .../components/PurchaseModalContent.tsx | 10 +-- .../components/SaleModalContent.tsx | 9 +-- .../components/TransactionSummary.tsx | 46 +++++++++++++ .../purchases-and-sales/PurchasesTable.tsx | 4 +- .../pages/purchases-and-sales/SalesTable.tsx | 4 +- 12 files changed, 156 insertions(+), 56 deletions(-) rename packages/web/src/components/{premium-content-purchase-modal/components/PurchaseSummaryTable.module.css => summary-table/SummaryTable.module.css} (93%) create mode 100644 packages/web/src/components/summary-table/SummaryTable.tsx create mode 100644 packages/web/src/components/summary-table/index.ts create mode 100644 packages/web/src/components/usdc-purchase-details-modal/components/TransactionSummary.tsx diff --git a/packages/common/src/api/purchases.ts b/packages/common/src/api/purchases.ts index 4ff8c91c421..3ed413bf760 100644 --- a/packages/common/src/api/purchases.ts +++ b/packages/common/src/api/purchases.ts @@ -21,13 +21,21 @@ type GetPurchaseListArgs = { } const parsePurchase = (purchase: full.Purchase): USDCPurchaseDetails => { - const { contentId, contentType, amount, buyerUserId, sellerUserId, ...rest } = - purchase + const { + contentId, + contentType, + extraAmount, + amount, + buyerUserId, + sellerUserId, + ...rest + } = purchase return { ...rest, contentType: contentType as USDCContentPurchaseType, contentId: HashId.parse(contentId), amount: amount as StringUSDC, + extraAmount: extraAmount as StringUSDC, buyerUserId: HashId.parse(buyerUserId), sellerUserId: HashId.parse(sellerUserId) } diff --git a/packages/common/src/models/USDCTransactions.ts b/packages/common/src/models/USDCTransactions.ts index 68b47490c59..60adf4d2709 100644 --- a/packages/common/src/models/USDCTransactions.ts +++ b/packages/common/src/models/USDCTransactions.ts @@ -22,6 +22,7 @@ export type USDCPurchaseDetails = { sellerUserId: number buyerUserId: number amount: StringUSDC + extraAmount: StringUSDC contentType: USDCContentPurchaseType contentId: number createdAt: string diff --git a/packages/common/src/utils/wallet.ts b/packages/common/src/utils/wallet.ts index 5ecc0a15e54..aff6c682650 100644 --- a/packages/common/src/utils/wallet.ts +++ b/packages/common/src/utils/wallet.ts @@ -162,10 +162,16 @@ export const floorBNUSDCToNearestCent = (value: BNUSDC): BNUSDC => { } /** Formats a USDC wei string (full precision) to a fixed string suitable for -display as a dollar amount. Note: will lose precision by rounding _up_ to nearest cent */ -export const formatUSDCWeiToUSDString = (amount: StringUSDC, precision = 2) => { +display as a dollar amount. Note: will lose precision by rounding _up_ to nearest +cent and will drop negative signs +*/ +export const formatUSDCWeiToUSDString = ( + amount: StringUSDC | BN, + precision = 2 +) => { + const amountBN = BN.isBN(amount) ? amount : new BN(amount) // remove negative sign if present. - const amountPos = amount.replace('-', '') + const amountPos = amountBN.abs() // Since we only need two digits of precision, we will multiply up by 1000 // with BN, divide by $1 Wei, ceiling up to the nearest cent, // and then convert to JS number and divide back down before formatting to diff --git a/packages/web/src/components/premium-content-purchase-modal/components/PurchaseSummaryTable.tsx b/packages/web/src/components/premium-content-purchase-modal/components/PurchaseSummaryTable.tsx index 78a9441c546..0a3a917f6ed 100644 --- a/packages/web/src/components/premium-content-purchase-modal/components/PurchaseSummaryTable.tsx +++ b/packages/web/src/components/premium-content-purchase-modal/components/PurchaseSummaryTable.tsx @@ -1,11 +1,9 @@ import { formatPrice } from '@audius/common' -import { Text } from 'components/typography' - -import styles from './PurchaseSummaryTable.module.css' +import { SummaryTable, SummaryTableItem } from 'components/summary-table' const messages = { - summary: 'Summary', + summary: 'Transaction Summary', premiumTrack: 'Premium Track', existingBalance: 'Existing USDC Balance', payExtra: 'Pay Extra', @@ -30,33 +28,37 @@ export const PurchaseSummaryTable = ({ existingBalance, isPurchased }: PurchaseSummaryTableProps) => { + const items: SummaryTableItem[] = [ + { + id: 'premiumTrack', + label: messages.premiumTrack, + value: messages.price(formatPrice(basePrice)) + } + ] + if (extraAmount != null) { + items.push({ + id: 'payExtra', + label: messages.payExtra, + value: messages.price(formatPrice(extraAmount)) + }) + } + if (existingBalance != null) { + items.push({ + id: 'existingBalance', + label: messages.existingBalance, + value: `-${messages.price(formatPrice(existingBalance))}` + }) + } + return ( - - - {messages.summary} - -
- {messages.premiumTrack} - {messages.price(formatPrice(basePrice))} -
- {extraAmount != null ? ( -
- {messages.payExtra} - {messages.price(formatPrice(extraAmount))} -
- ) : null} - {existingBalance != null ? ( -
- {messages.existingBalance} - {`-${messages.price(formatPrice(existingBalance))}`} -
- ) : null} - - {isPurchased ? messages.youPaid : messages.total} - - {messages.price(formatPrice(amountDue))} - - -
+ ) } diff --git a/packages/web/src/components/premium-content-purchase-modal/components/PurchaseSummaryTable.module.css b/packages/web/src/components/summary-table/SummaryTable.module.css similarity index 93% rename from packages/web/src/components/premium-content-purchase-modal/components/PurchaseSummaryTable.module.css rename to packages/web/src/components/summary-table/SummaryTable.module.css index 2a86dc01686..e659ed7bd99 100644 --- a/packages/web/src/components/premium-content-purchase-modal/components/PurchaseSummaryTable.module.css +++ b/packages/web/src/components/summary-table/SummaryTable.module.css @@ -26,7 +26,3 @@ .row:last-child { background: var(--background-surface-1); } - -.finalPrice { - color: var(--focus); -} diff --git a/packages/web/src/components/summary-table/SummaryTable.tsx b/packages/web/src/components/summary-table/SummaryTable.tsx new file mode 100644 index 00000000000..eca18d42a26 --- /dev/null +++ b/packages/web/src/components/summary-table/SummaryTable.tsx @@ -0,0 +1,45 @@ +import { ReactNode } from 'react' + +import { Text } from 'components/typography' + +import styles from './SummaryTable.module.css' + +export type SummaryTableItem = { + id: string + label: ReactNode + value: ReactNode +} + +export type SummaryTableProps = { + items: SummaryTableItem[] + summaryItem: SummaryTableItem + title: ReactNode +} + +export const SummaryTable = ({ + items, + summaryItem, + title +}: SummaryTableProps) => { + return ( +
+ + {title} + + {items.map(({ id, label, value }) => ( +
+ {label} + {value} +
+ ))} +
+ + {summaryItem.label} + + + {summaryItem.value} + +
+
+ ) +} diff --git a/packages/web/src/components/summary-table/index.ts b/packages/web/src/components/summary-table/index.ts new file mode 100644 index 00000000000..2feeb47e61c --- /dev/null +++ b/packages/web/src/components/summary-table/index.ts @@ -0,0 +1 @@ +export * from './SummaryTable' diff --git a/packages/web/src/components/usdc-purchase-details-modal/components/PurchaseModalContent.tsx b/packages/web/src/components/usdc-purchase-details-modal/components/PurchaseModalContent.tsx index 0070ef970e6..2df7d0cd014 100644 --- a/packages/web/src/components/usdc-purchase-details-modal/components/PurchaseModalContent.tsx +++ b/packages/web/src/components/usdc-purchase-details-modal/components/PurchaseModalContent.tsx @@ -1,6 +1,6 @@ import { useCallback } from 'react' -import { useGetTrackById, formatUSDCWeiToUSDString } from '@audius/common' +import { useGetTrackById } from '@audius/common' import { ModalHeader, ModalTitle, @@ -21,12 +21,12 @@ import { useGoToRoute } from 'hooks/useGoToRoute' import { DetailSection } from './DetailSection' import { TrackLink } from './TrackLink' +import { TransactionSummary } from './TransactionSummary' import styles from './styles.module.css' import { ContentProps } from './types' const messages = { by: 'By', - cost: 'Cost', date: 'Date', done: 'Done', purchaseDetails: 'Purchase Details', @@ -75,11 +75,7 @@ export const PurchaseModalContent = ({ {moment(purchaseDetails.createdAt).format('MMM DD, YYYY')} - - {`$${formatUSDCWeiToUSDString( - purchaseDetails.amount - )}`} - + - - {`$${formatUSDCWeiToUSDString( - purchaseDetails.amount - )}`} - + { + const amountBN = new BN(transaction.amount) + const items: SummaryTableItem[] = [ + { + id: 'cost', + label: messages.cost, + value: `$${formatUSDCWeiToUSDString(amountBN)}` + } + ] + const extraAmountBN = new BN(transaction.extraAmount) + if (!extraAmountBN.isZero()) { + items.push({ + id: 'payExtra', + label: messages.payExtra, + value: `$${formatUSDCWeiToUSDString(extraAmountBN)}` + }) + } + + return ( + + ) +} diff --git a/packages/web/src/pages/purchases-and-sales/PurchasesTable.tsx b/packages/web/src/pages/purchases-and-sales/PurchasesTable.tsx index 96f70d755bf..da8ddc14bac 100644 --- a/packages/web/src/pages/purchases-and-sales/PurchasesTable.tsx +++ b/packages/web/src/pages/purchases-and-sales/PurchasesTable.tsx @@ -5,6 +5,7 @@ import { USDCContentPurchaseType, USDCPurchaseDetails } from '@audius/common' +import BN from 'bn.js' import moment from 'moment' import { Table } from 'components/table' @@ -76,7 +77,8 @@ const renderDateCell = (cellInfo: PurchaseCell) => { const renderValueCell = (cellInfo: PurchaseCell) => { const transaction = cellInfo.row.original - return `$${formatUSDCWeiToUSDString(transaction.amount)}` + const total = new BN(transaction.amount).add(new BN(transaction.extraAmount)) + return `$${formatUSDCWeiToUSDString(total)}` } // Columns diff --git a/packages/web/src/pages/purchases-and-sales/SalesTable.tsx b/packages/web/src/pages/purchases-and-sales/SalesTable.tsx index f5b8cb7406d..cd96ddb1357 100644 --- a/packages/web/src/pages/purchases-and-sales/SalesTable.tsx +++ b/packages/web/src/pages/purchases-and-sales/SalesTable.tsx @@ -5,6 +5,7 @@ import { USDCContentPurchaseType, USDCPurchaseDetails } from '@audius/common' +import { BN } from 'bn.js' import moment from 'moment' import { Table } from 'components/table' @@ -73,7 +74,8 @@ const renderDateCell = (cellInfo: PurchaseCell) => { const renderValueCell = (cellInfo: PurchaseCell) => { const transaction = cellInfo.row.original - return `$${formatUSDCWeiToUSDString(transaction.amount)}` + const total = new BN(transaction.amount).add(new BN(transaction.extraAmount)) + return `$${formatUSDCWeiToUSDString(total)}` } // Columns