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

FET-1623: Add expiry info to registration completion page #875

Merged
merged 10 commits into from
Oct 8, 2024
7 changes: 4 additions & 3 deletions e2e/specs/stateless/extendNames.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@ test('should be able to register multiple names on the address page', async ({

await addresPage.goto(address)
await login.connect()
await page.pause()

await addresPage.selectToggle.click()

Expand Down Expand Up @@ -72,7 +71,6 @@ test('should be able to register multiple names on the address page', async ({
await addresPage.extendNamesModalNextButton.click()

// check the invoice details
await page.pause()
await expect(page.getByText(`Extend ${extendableNameItems.length} Names`)).toBeVisible()
await expect(page.getByText('1 year extension', { exact: true })).toBeVisible()

Expand All @@ -83,11 +81,14 @@ test('should be able to register multiple names on the address page', async ({

await transactionModal.autoComplete()

await expect(page.getByText('Your "Extend names" transaction was successful')).toBeVisible({
timeout: 10000,
})
await subgraph.sync()
await page.waitForTimeout(3000)

// Should be able to remove this after useQuery is fixed. Using to force a refetch.
await time.increaseTime({ seconds: 15 })
await page.pause()
await page.reload()
for (const name of extendableNameItems) {
const label = name.replace('.eth', '')
Expand Down
12 changes: 12 additions & 0 deletions e2e/specs/stateless/registerName.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -157,8 +157,20 @@ test.describe.serial('normal registration', () => {
await expect(page.getByText('Open Wallet')).toBeVisible()
await transactionModal.confirm()

// calculate date one year from now
const date = new Date()
date.setFullYear(date.getFullYear() + 1)
const formattedDate = date.toLocaleDateString('en-US', {
year: 'numeric',
month: 'long',
day: 'numeric',
})

// should show the correct details on completion
await expect(page.getByTestId('invoice-item-0-amount')).toHaveText(/0.0032 ETH/)
await expect(page.getByTestId('invoice-item-0')).toHaveText(/1 year registration/)
await expect(page.getByTestId('invoice-item-expiry')).toHaveText(/Name expires/)
await expect(page.getByTestId('invoice-item-expiry-date')).toHaveText(`${formattedDate}`)

await page.getByTestId('view-name').click()
await expect(page.getByTestId('address-profile-button-eth')).toHaveText(
Expand Down
7 changes: 3 additions & 4 deletions public/locales/en/register.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@
"heading": "Register {{name}}",
"invoice": {
"timeRegistration": "{{time}} registration",
"registration": "Registration",
"estimatedNetworkFee": "Est. network fee",
"networkFee": "Network fee",
"transactionFees": "Transaction fees",
"temporaryPremium": "Temporary premium",
"total": "Estimated total",
"totalPaid": "Total paid"
"totalPaid": "Total paid",
"expiry": "Name expires"
},
"error": {
"nameTooLong": "The name you want to register is too long. Please choose a shorter name."
Expand Down Expand Up @@ -151,7 +151,6 @@
"complete": {
"heading": "Congratulations!",
"subheading": "You are now the owner of ",
"description": "Your name was successfully registered. You can now view and manage your name.",
"registerAnother": "Register another",
"viewName": "View name"
},
Expand Down
2 changes: 1 addition & 1 deletion public/locales/nl/register.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"yearRegistration": "{{years}} jaar registratie",
"registration": "Registratie",
"estimatedNetworkFee": "Geschatte netwerk kosten",
"networkFee": "Netwerk kosten",
"transactionFees": "Netwerk kosten",
"temporaryPremium": "Tijdelijke premium",
"total": "Geschat totaal",
"totalPaid": "Totaal te betalen"
Expand Down
2 changes: 1 addition & 1 deletion public/locales/ru/register.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"timeRegistration": "{{time}} регистрация",
"registration": "Регистрация",
"estimatedNetworkFee": "Оценочная комиссия сети",
"networkFee": "Комиссия сети",
"transactionFees": "Комиссия транзакции",
"temporaryPremium": "Временная премия",
"total": "Оценочная общая сумма",
"totalPaid": "Всего оплачено"
Expand Down
2 changes: 1 addition & 1 deletion public/locales/uk/register.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"timeRegistration": "{{time}} реєстрація",
"registration": "Реєстрація",
"estimatedNetworkFee": "Оцінка плати за мережу",
"networkFee": "Плата за мережу",
"transactionFees": "Плата за транзакцію",
"temporaryPremium": "Тимчасовий преміум",
"total": "Орієнтовна сума",
"totalPaid": "Всього сплачено"
Expand Down
7 changes: 2 additions & 5 deletions public/locales/zh/register.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"timeRegistration": "注册{{time}}",
"registration": "注册",
"estimatedNetworkFee": "预估网络费",
"networkFee": "网络费",
"transactionFees": "网络费",
"temporaryPremium": "临时溢价",
"total": "预估总额",
"totalPaid": "支付总额"
Expand Down Expand Up @@ -161,10 +161,7 @@
"等待计时器完成 60 秒计时",
"完成第二笔交易来获得该名称"
],
"moonpayItems": [
"创建或登录现有的 Moonpay 账户",
"使用信用卡或借记卡完成单笔交易"
],
"moonpayItems": ["创建或登录现有的 Moonpay 账户", "使用信用卡或借记卡完成单笔交易"],
"setupProfile": "我希望先创建我的个人资料",
"paymentMethod": "支付方式",
"notEnoughEth": "钱包中的 ETH 不足",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -319,6 +319,7 @@ const Registration = ({ nameDetails, isLoading }: Props) => {
name={normalisedName}
beautifiedName={beautifiedName}
callback={onComplete}
registrationData={item}
isMoonpayFlow={item.isMoonpayFlow}
/>
))
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import dynamic from 'next/dynamic'
import React, { Fragment, useEffect, useMemo, useState } from 'react'
import { Fragment, useEffect, useMemo, useState } from 'react'
import type ConfettiT from 'react-confetti'
import { useTranslation } from 'react-i18next'
import styled, { css } from 'styled-components'
Expand All @@ -9,12 +9,18 @@ import { useAccount } from 'wagmi'
import { tokenise } from '@ensdomains/ensjs/utils'
import { Button, mq, Typography } from '@ensdomains/thorin'

import { Invoice } from '@app/components/@atoms/Invoice/Invoice'
import MobileFullWidth from '@app/components/@atoms/MobileFullWidth'
import NFTTemplate from '@app/components/@molecules/NFTTemplate/NFTTemplate'
import { Card } from '@app/components/Card'
import useWindowSize from '@app/hooks/useWindowSize'
import { useTransactionFlow } from '@app/transaction-flow/TransactionFlowProvider'
import { dateFromDateDiff } from '@app/utils/date'
import { isMobileDevice } from '@app/utils/device'
import { secondsToDays } from '@app/utils/time'
import { formatDurationOfDates } from '@app/utils/utils'

import { RegistrationReducerDataItem } from '../types'
import { Invoice } from './Invoice'

const StyledCard = styled(Card)(
({ theme }) => css`
Expand All @@ -39,10 +45,14 @@ const ButtonContainer = styled.div(
({ theme }) => css`
width: ${theme.space.full};
display: flex;
flex-direction: row;
flex-direction: column;
align-items: center;
justify-content: center;
gap: ${theme.space['2']};

${mq.sm.min(css`
flex-direction: row;
`)}
`,
)

Expand All @@ -60,6 +70,20 @@ const NFTContainer = styled.div(
`,
)

const InvoiceContainer = styled.div(
({ theme }) => css`
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
gap: ${theme.space['4']};
${mq.sm.min(css`
gap: ${theme.space['6']};
flex-direction: row;
`)}
`,
)

const TitleContainer = styled.div(
({ theme }) => css`
display: flex;
Expand Down Expand Up @@ -148,6 +172,7 @@ const Confetti = dynamic(() =>

const useEthInvoice = (
name: string,
seconds: number,
isMoonpayFlow: boolean,
): { InvoiceFilled?: React.ReactNode; avatarSrc?: string } => {
const { t } = useTranslation('register')
Expand Down Expand Up @@ -208,16 +233,33 @@ const useEthInvoice = (
const registerNetFee = registerGasUsed * registerGasPrice
const totalNetFee = commitNetFee && registerNetFee ? commitNetFee + registerNetFee : 0n

const date = dateFromDateDiff({
startDate: new Date(),
additionalDays: Math.floor(secondsToDays(seconds)),
})

return (
<Invoice
name={name}
expiryDate={date}
expiryTitle={t('invoice.expiry')}
items={[
{ label: t('invoice.registration'), value },
{ label: t('invoice.networkFee'), value: totalNetFee },
{
label: t('invoice.timeRegistration', {
time: formatDurationOfDates({
startDate: new Date(),
endDate: date,
shortYears: isMobileDevice(),
t,
}),
}),
value,
},
{ label: t('invoice.transactionFees'), value: totalNetFee },
]}
totalLabel={t('invoice.totalPaid')}
/>
)
}, [isLoading, registrationValue, commitReceipt, registerReceipt, t])
}, [isLoading, registrationValue, commitReceipt, registerReceipt, t, name, seconds])

if (isMoonpayFlow) return { InvoiceFilled: null, avatarSrc }

Expand All @@ -228,13 +270,14 @@ type Props = {
name: string
beautifiedName: string
callback: (toProfile: boolean) => void
registrationData: RegistrationReducerDataItem
isMoonpayFlow: boolean
}

const Complete = ({ name, beautifiedName, callback, isMoonpayFlow }: Props) => {
const Complete = ({ name, beautifiedName, callback, isMoonpayFlow, registrationData }: Props) => {
const { t } = useTranslation('register')
const { width, height } = useWindowSize()
const { InvoiceFilled, avatarSrc } = useEthInvoice(name, isMoonpayFlow)
const { InvoiceFilled, avatarSrc } = useEthInvoice(name, registrationData.seconds, isMoonpayFlow)

const nameWithColourEmojis = useMemo(() => {
const data = tokenise(beautifiedName)
Expand Down Expand Up @@ -275,18 +318,19 @@ const Complete = ({ name, beautifiedName, callback, isMoonpayFlow }: Props) => {
gravity={0.25}
initialVelocityY={20}
/>
<NFTContainer>
<NFTTemplate backgroundImage={avatarSrc} isNormalised name={name} />
</NFTContainer>
<TitleContainer>
<Title>{t('steps.complete.heading')}</Title>
<Typography style={{ display: 'inline' }} fontVariant="headingThree" weight="bold">
{t('steps.complete.subheading')}
<SubtitleWithGradient>{nameWithColourEmojis}</SubtitleWithGradient>
</Typography>
</TitleContainer>
<Typography>{t('steps.complete.description')}</Typography>
{InvoiceFilled}
<InvoiceContainer>
<NFTContainer>
<NFTTemplate backgroundImage={avatarSrc} isNormalised name={name} />
</NFTContainer>
{InvoiceFilled}
</InvoiceContainer>
<ButtonContainer>
<MobileFullWidth>
<Button colorStyle="accentSecondary" onClick={() => callback(false)}>
Expand Down
Loading
Loading