Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

😨 ChangeNOW modal adjustements v2 #6041

Merged
merged 3 commits into from
Apr 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ export const ChangeNowModal = ({ type, onClose }: ChangeNowModalProps) => {
if (primaryButtonProps) {
return {
text: 'Go to dashboard',
onClick: () => onClose(),
to: absoluteRoutes.viewer.portfolio(),
}
}
Expand Down
14 changes: 13 additions & 1 deletion packages/atlas/src/components/ChangeNowModal/steps/FormStep.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ import { FormField } from '@/components/_inputs/FormField'
import { Input } from '@/components/_inputs/Input'
import { TokenInput, TokenInputProps } from '@/components/_inputs/TokenInput'
import { Spinner } from '@/components/_loaders/Spinner'
import { hapiBnToTokenNumber } from '@/joystream-lib/utils'
import { useSubscribeAccountBalance } from '@/providers/joystream'
import { useSnackbar } from '@/providers/snackbars'
import { square } from '@/styles'
import {
Expand All @@ -23,6 +25,7 @@ import {
changeNowService,
} from '@/utils/ChangeNowService'
import { SentryLogger } from '@/utils/logs'
import { formatSmallDecimal } from '@/utils/number'

type CurrencyInputValues = {
amount: number
Expand All @@ -46,10 +49,13 @@ type FormStepProps = {

export const FormStep = ({ setPrimaryButtonProps, onSubmit, type, initialValues }: FormStepProps) => {
const { displaySnackbar } = useSnackbar()
const { accountBalance } = useSubscribeAccountBalance()
const [isLoadingRate, setIsLoadingRate] = useState<'to' | 'from' | null>(null)
const debouncedExchangeEstimation = useRef<DebouncedFunc<
(amount: number, type: 'from' | 'to') => Promise<void>
> | null>(null)
const isSellingJoy = type === 'sell'

const { data } = useQuery('changenow-currency', () => changeNowService.getAvailableCurrencies(), {
onSuccess: (data) => {
const currencyOptions = data.map((curr) => ({
Expand Down Expand Up @@ -179,6 +185,12 @@ export const FormStep = ({ setPrimaryButtonProps, onSubmit, type, initialValues
if (!value.currency) {
return 'Please choose currency'
}

if (isSellingJoy && accountBalance) {
if (value.amount > hapiBnToTokenNumber(accountBalance)) {
return 'Amount exceeds your balance'
}
}
},
}}
render={({ field: { value, onChange } }) => {
Expand Down Expand Up @@ -285,7 +297,7 @@ export const FormStep = ({ setPrimaryButtonProps, onSubmit, type, initialValues
/>
{from.currency && to.currency && (
<Text variant="t200" as="p" color={isLoadingRate ? 'colorTextMuted' : 'colorText'}>
Estimated rate: 1 {from.currency.toUpperCase()} ~ {to.amount / from.amount || 'N/A'}{' '}
Estimated rate: 1 {from.currency.toUpperCase()} ~ {formatSmallDecimal(to.amount / from.amount) || 'N/A'}{' '}
{to.currency.toUpperCase()}
</Text>
)}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,13 @@ type ProgressStepProps = {
transactionData: TransactionData
} & CommonProps

export const ProgressStep = ({ transactionData, type, setPrimaryButtonProps, goToStep }: ProgressStepProps) => {
export const ProgressStep = ({
transactionData,
type,
setPrimaryButtonProps,
goToStep,
onClose,
}: ProgressStepProps) => {
const [retry, setRetry] = useState(true)
const isSellingJoy = type === 'sell'
const steps = isSellingJoy ? sellSteps : buySteps
Expand Down Expand Up @@ -118,13 +124,13 @@ export const ProgressStep = ({ transactionData, type, setPrimaryButtonProps, goT
setRetry(false)
setPrimaryButtonProps({
text: 'Close',
onClick: () => undefined,
onClick: () => onClose(),
})
step = steps.length
extraContent = successText
}
return [step, steps[step]?.[1], extraContent]
}, [data, isSellingJoy, setPrimaryButtonProps, steps, transactionData.hasAutomaticTransactionSucceeded])
}, [data, isSellingJoy, onClose, setPrimaryButtonProps, steps, transactionData.hasAutomaticTransactionSucceeded])

return (
<FlexBox gap={6} flow="column">
Expand Down
33 changes: 22 additions & 11 deletions packages/atlas/src/components/ChangeNowModal/steps/SummaryStep.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import { cVar, sizes } from '@/styles'
import { changeNowService } from '@/utils/ChangeNowService'
import { formatJoystreamAddress } from '@/utils/address'
import { shortenString } from '@/utils/misc'
import { formatSmallDecimal } from '@/utils/number'
import { formatDurationShort, getTimeDiffInSeconds } from '@/utils/time'

import { FormData } from './FormStep'
Expand All @@ -43,6 +44,7 @@ export const SummaryStep = ({
}: SummaryStepProps) => {
const [termsAccepted, setTermsAccepted] = useState(false)
const [error, setError] = useState('')
const [loading, setLoading] = useState(false)
const [timeDiff, setTimeDiff] = useState<number | undefined>(undefined)
const { activeMembership } = useUser()
const { currentUser } = useAuth()
Expand All @@ -61,6 +63,7 @@ export const SummaryStep = ({
}
const isSellingJoy = type === 'sell'
const refundAddress = isSellingJoy ? activeMembership.controllerAccount : undefined
setLoading(true)
const txData = await changeNowService
.createExchangeTransaction({
refundAddress,
Expand All @@ -74,13 +77,15 @@ export const SummaryStep = ({
})
.then((res) => res.data)
.catch(() => {
setLoading(false)
displaySnackbar({
title: 'Transaction creation failed',
description: 'Please try again, if the problem persists contact support.',
})
})

if (!txData) {
setLoading(false)
return
}

Expand Down Expand Up @@ -110,6 +115,9 @@ export const SummaryStep = ({
})
goToStep(ChangeNowModalStep.PROGRESS)
},
onError: () => {
setLoading(false)
},
})
} else {
goToStep(ChangeNowModalStep.PROGRESS)
Expand All @@ -136,7 +144,8 @@ export const SummaryStep = ({

useEffect(() => {
setPrimaryButtonProps({
text: 'Next',
text: loading ? 'Next' : 'Waiting...',
disabled: loading,
onClick: async () => {
if (termsAccepted && validUntil) {
const timeDiff = getTimeDiffInSeconds(new Date(validUntil))
Expand All @@ -150,7 +159,7 @@ export const SummaryStep = ({
}
},
})
}, [goToStep, onTransactionSubmit, setPrimaryButtonProps, termsAccepted, validUntil])
}, [goToStep, loading, onTransactionSubmit, setPrimaryButtonProps, termsAccepted, validUntil])

useMountEffect(() => {
if (!validUntil) {
Expand Down Expand Up @@ -204,14 +213,16 @@ export const SummaryStep = ({
</Text>
</FlexBox>

<FlexBox width="100%" justifyContent="space-between">
<Text variant="t200" as="p" color="colorText">
Estimated Arrival
</Text>
<Text variant="t200" as="p">
{estimatedArrival ? new Date(estimatedArrival).toDateString() : 'N/A'}
</Text>
</FlexBox>
{estimatedArrival ? (
<FlexBox width="100%" justifyContent="space-between">
<Text variant="t200" as="p" color="colorText">
Estimated Arrival
</Text>
<Text variant="t200" as="p">
{new Date(estimatedArrival).toDateString()}
</Text>
</FlexBox>
) : null}

<FlexBox width="100%" justifyContent="space-between">
<Text variant="t200" as="p" color="colorText">
Expand All @@ -227,7 +238,7 @@ export const SummaryStep = ({
Estimated Rate
</Text>
<Text variant="t200" as="p">
1 {fromTicker} ~ {to.amount / from.amount} {toTicker}
1 {fromTicker} ~ {formatSmallDecimal(to.amount / from.amount)} {toTicker}
</Text>
</FlexBox>

Expand Down
2 changes: 1 addition & 1 deletion packages/atlas/src/utils/number.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ export const getRandomIntInclusive = (min: number, max: number) => {
}

const numberFormatter = new Intl.NumberFormat('en-US', { maximumFractionDigits: 2 })
const smallDecimalFormatter = new Intl.NumberFormat('en-US', { maximumFractionDigits: 6 })
const smallDecimalFormatter = new Intl.NumberFormat('en-US', { maximumFractionDigits: 10 })

export const formatNumber = (num: number): string => {
return numberFormatter.format(num).replaceAll(',', ' ')
Expand Down
Loading