Skip to content

Commit

Permalink
[PAY-2154] Implement add funds modal (#6714)
Browse files Browse the repository at this point in the history
  • Loading branch information
raymondjacobson authored Nov 16, 2023
1 parent 68aa7b5 commit 026aead
Show file tree
Hide file tree
Showing 25 changed files with 467 additions and 153 deletions.
16 changes: 16 additions & 0 deletions packages/common/src/store/ui/modals/add-funds-modal/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { createModal } from '../createModal'

export type AddFundsModalState = {
isOpen: boolean
}

const AddFundsModal = createModal<AddFundsModalState>({
reducerPath: 'AddFundsModal',
initialState: {
isOpen: false
},
sliceSelector: (state) => state.ui.modals
})

export const { hook: useAddFundsModal, reducer: addFundsModalReducer } =
AddFundsModal
1 change: 1 addition & 0 deletions packages/common/src/store/ui/modals/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,4 @@ export * from './edit-playlist-modal'
export * from './edit-track-modal'
export * from './premium-content-purchase-modal'
export * from './usdc-manual-transfer-modal'
export * from './add-funds-modal'
3 changes: 2 additions & 1 deletion packages/common/src/store/ui/modals/parentSlice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,8 @@ export const initialState: BasicModalsState = {
WithdrawUSDCModal: { isOpen: false },
USDCPurchaseDetailsModal: { isOpen: false },
USDCTransactionDetailsModal: { isOpen: false },
USDCManualTransferModal: { isOpen: false }
USDCManualTransferModal: { isOpen: false },
AddFundsModal: { isOpen: false }
}

const slice = createSlice({
Expand Down
2 changes: 2 additions & 0 deletions packages/common/src/store/ui/modals/reducers.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Action, combineReducers, Reducer } from '@reduxjs/toolkit'

import { addFundsModalReducer } from './add-funds-modal'
import { createChatModalReducer } from './create-chat-modal'
import { BaseModalState } from './createModal'
import { editPlaylistModalReducer } from './edit-playlist-modal'
Expand Down Expand Up @@ -37,6 +38,7 @@ const combinedReducers = combineReducers({
WithdrawUSDCModal: withdrawUSDCModalReducer,
USDCPurchaseDetailsModal: usdcPurchaseDetailsModalReducer,
USDCManualTransferModal: usdcManualTransferModalReducer,
AddFundsModal: addFundsModalReducer,
USDCTransactionDetailsModal: usdcTransactionDetailsModalReducer,
PremiumContentPurchaseModal: premiumContentPurchaseModalReducer
})
Expand Down
3 changes: 3 additions & 0 deletions packages/common/src/store/ui/modals/types.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { ModalSource } from 'models/Analytics'

import { AddFundsModalState } from './add-funds-modal'
import { CreateChatModalState } from './create-chat-modal'
import { BaseModalState } from './createModal'
import { EditPlaylistModalState } from './edit-playlist-modal'
Expand Down Expand Up @@ -60,6 +61,7 @@ export type Modals =
| 'USDCPurchaseDetailsModal'
| 'USDCTransactionDetailsModal'
| 'USDCManualTransferModal'
| 'AddFundsModal'

export type BasicModalsState = {
[modal in Modals]: BaseModalState
Expand All @@ -75,6 +77,7 @@ export type StatefulModalsState = {
USDCPurchaseDetailsModal: USDCPurchaseDetailsModalState
USDCTransactionDetailsModal: USDCTransactionDetailsModalState
USDCManualTransferModal: USDCManualTransferModalState
AddFundsModal: AddFundsModalState
PremiumContentPurchaseModal: PremiumContentPurchaseModalState
}

Expand Down
5 changes: 5 additions & 0 deletions packages/harmony/src/assets/icons/CreditCard.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,7 @@ export const BaseButton = forwardRef<HTMLButtonElement, BaseButtonProps>(
whiteSpace: 'nowrap',
transition: `
transform ${motion.hover},
border-color ${motion.hover},
background-color ${motion.hover}
border-color ${motion.hover}
`,

...(fullWidth && {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ export const FilterButton = forwardRef<HTMLButtonElement, FilterButtonProps>(
: color.text.default,
gap: spacing.xs,
fontSize: typography.size.s,
fontWeight: typography.weight.medium,
fontWeight: typography.weight.demiBold,
lineHeight: typography.lineHeight.s,

'&:hover': {
Expand Down
1 change: 1 addition & 0 deletions packages/harmony/src/icons/utilityIcons.ts
Original file line number Diff line number Diff line change
Expand Up @@ -131,3 +131,4 @@ export { default as IconHeadphones } from '../assets/icons/Headphones.svg'
export { default as IconValidationCheck } from '../assets/icons/ValidationCheck.svg'
export { default as IconValidationX } from '../assets/icons/ValidationX.svg'
export { default as IconSoundwave } from '../assets/icons/Soundwave.svg'
export { default as IconCreditCard } from '../assets/icons/CreditCard.svg'
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ const messages = {
addFunds: 'Add Funds'
}

const useStyles = makeStyles(({ spacing, palette, typography }) => ({
const useStyles = makeStyles(({ spacing, palette }) => ({
root: {
paddingVertical: spacing(8),
paddingHorizontal: spacing(3)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
.modal {
width: 720px;
}

.modalHeader {
text-align: center;
}

.modalHeader.mobile {
margin: 0;
padding: 0;
border: none;
}
80 changes: 80 additions & 0 deletions packages/web/src/components/add-funds-modal/AddFundsModal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import { useCallback, useState } from 'react'

import { useAddFundsModal } from '@audius/common'
import { ModalContent, ModalHeader } from '@audius/stems'
import cn from 'classnames'

import { AddFunds, Method } from 'components/add-funds/AddFunds'
import { Text } from 'components/typography'
import { USDCManualTransfer } from 'components/usdc-manual-transfer/USDCManualTransfer'
import ModalDrawer from 'pages/audio-rewards-page/components/modals/ModalDrawer'
import { isMobile } from 'utils/clientUtil'
import zIndex from 'utils/zIndex'

import styles from './AddFundsModal.module.css'

const messages = {
addFunds: 'Add Funds',
cryptoTransfer: 'Crypto Transfer'
}

type Page = 'add-funds' | 'crypto-transfer'

export const AddFundsModal = () => {
const { isOpen, onClose } = useAddFundsModal()
const mobile = isMobile()

const [page, setPage] = useState<Page>('add-funds')

const handleClose = useCallback(() => {
onClose()
}, [onClose])

const handleClosed = useCallback(() => {
setPage('add-funds')
}, [setPage])

const handleContinue = useCallback(
(method: Method) => {
setPage('crypto-transfer')
},
[setPage]
)

return (
<ModalDrawer
zIndex={zIndex.ADD_FUNDS_MODAL}
size={'small'}
onClose={handleClose}
isOpen={isOpen}
onClosed={handleClosed}
bodyClassName={styles.modal}
useGradientTitle={false}
dismissOnClickOutside
isFullscreen={false}
>
<ModalHeader
className={cn(styles.modalHeader, { [styles.mobile]: mobile })}
onClose={onClose}
showDismissButton={!mobile}
>
<Text
variant='label'
color='neutralLight2'
size='xLarge'
strength='strong'
className={styles.title}
>
{page === 'add-funds' ? messages.addFunds : messages.cryptoTransfer}
</Text>
</ModalHeader>
<ModalContent>
{page === 'add-funds' ? (
<AddFunds onContinue={handleContinue} />
) : (
<USDCManualTransfer onClose={handleClose} />
)}
</ModalContent>
</ModalDrawer>
)
}
15 changes: 15 additions & 0 deletions packages/web/src/components/add-funds/AddFunds.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
.root {
display: flex;
flex-direction: column;
gap: var(--unit-6);
}

.buttonContainer {
display: flex;
flex-direction: row;
gap: var(--unit-2);
}

.buttonContainer.mobile {
flex-direction: column;
}
128 changes: 128 additions & 0 deletions packages/web/src/components/add-funds/AddFunds.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
import { ChangeEvent, useCallback, useState } from 'react'

import {
BNUSDC,
decimalIntegerToHumanReadable,
formatUSDCWeiToFloorCentsNumber,
useCreateUserbankIfNeeded,
useUSDCBalance
} from '@audius/common'
import {
Box,
Button,
ButtonType,
Flex,
Text,
IconLogoCircleUSDC,
IconCreditCard,
IconTransaction,
FilterButton,
FilterButtonType
} from '@audius/harmony'
import { BN } from 'bn.js'
import cn from 'classnames'

import { SummaryTable, SummaryTableItem } from 'components/summary-table'
import { track } from 'services/analytics'
import { audiusBackendInstance } from 'services/audius-backend/audius-backend-instance'
import { isMobile } from 'utils/clientUtil'

import styles from './AddFunds.module.css'

const messages = {
usdcBalance: 'USDC Balance',
paymentMethod: 'Payment Method',
withCard: 'Add funds with Card',
withCrypto: 'Add funds with crypto transfer',
continue: 'Continue'
}

export type Method = 'card' | 'crypto'

export const AddFunds = ({
onContinue
}: {
onContinue: (method: Method) => void
}) => {
useCreateUserbankIfNeeded({
recordAnalytics: track,
audiusBackendInstance,
mint: 'usdc'
})
const [selectedMethod, setSelectedMethod] = useState<Method>('card')
const mobile = isMobile()
const { data: balance } = useUSDCBalance()
const balanceNumber = formatUSDCWeiToFloorCentsNumber(
(balance ?? new BN(0)) as BNUSDC
)
const balanceFormatted = decimalIntegerToHumanReadable(balanceNumber)

const items: SummaryTableItem[] = [
{
id: 'card',
label: messages.withCard,
icon: IconCreditCard,
value: (
<FilterButton
initialSelectionIndex={0}
variant={FilterButtonType.REPLACE_LABEL}
options={[{ label: 'Stripe' }]}
/>
)
},
{
id: 'crypto',
label: messages.withCrypto,
icon: IconTransaction
}
]

const handleChangeOption = useCallback(
(e: ChangeEvent<HTMLInputElement>) => {
setSelectedMethod(e.target.value as Method)
},
[setSelectedMethod]
)

return (
<div className={styles.root}>
<div
className={cn(styles.buttonContainer, {
[styles.mobile]: mobile
})}
>
<Flex direction='column' w='100%' gap='xl'>
<Box h='unit6' border='strong' p='m'>
<Flex alignItems='center' justifyContent='space-between'>
<Flex alignItems='center'>
<IconLogoCircleUSDC />
<Box pl='s'>
<Text variant='title' size='m'>
{messages.usdcBalance}
</Text>
</Box>
</Flex>
<Text variant='title' size='l' strength='strong'>
{`$${balanceFormatted}`}
</Text>
</Flex>
</Box>
<SummaryTable
title={messages.paymentMethod}
items={items}
withRadioOptions
onRadioChange={handleChangeOption}
selectedRadioOption={selectedMethod}
/>
<Button
variant={ButtonType.PRIMARY}
fullWidth
onClick={() => onContinue(selectedMethod)}
>
{messages.continue}
</Button>
</Flex>
</div>
</div>
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,7 @@
.rowGrayBackground {
background: var(--background-surface-1);
}

.radioGroup {
width: 100%;
}
Loading

0 comments on commit 026aead

Please sign in to comment.