From b4541c5c6276c9f6c2d6eb18ef63b27a9fcfe348 Mon Sep 17 00:00:00 2001 From: Karolina Kosiorowska Date: Fri, 8 Mar 2024 11:25:17 +0100 Subject: [PATCH 01/40] Add a theme for `CloseButton` --- .../components/shared/ActivityBar/ActivityCard.tsx | 6 +----- dapp/src/theme/CloseButton.ts | 11 +++++++++++ dapp/src/theme/index.ts | 2 ++ 3 files changed, 14 insertions(+), 5 deletions(-) create mode 100644 dapp/src/theme/CloseButton.ts diff --git a/dapp/src/components/shared/ActivityBar/ActivityCard.tsx b/dapp/src/components/shared/ActivityBar/ActivityCard.tsx index 96e8cc8ba..8682c0964 100644 --- a/dapp/src/components/shared/ActivityBar/ActivityCard.tsx +++ b/dapp/src/components/shared/ActivityBar/ActivityCard.tsx @@ -51,11 +51,7 @@ function ActivityCard({ activity, onRemove }: ActivityCardType) { /> {isCompleted ? ( - + ) : ( Date: Tue, 12 Mar 2024 10:55:08 +0100 Subject: [PATCH 02/40] Restructure the styles for the Alert component According to styleguide, we need to update the styles for the Alert component. Additionally, the Toast component is based on the basic styles of Alert. Therefore, now the Alert component is based on the styleguide. However, a separate CardAlert component was created to contain the styles of the previous alert in one place. --- dapp/src/assets/icons/AlertError.tsx | 17 ++++++ dapp/src/assets/icons/AlertInfo.tsx | 25 ++++----- dapp/src/assets/icons/index.ts | 1 + .../ActiveStakingStep/DepositBTCModal.tsx | 6 +-- .../ActiveStakingStep/SignMessageModal.tsx | 4 +- .../ActiveUnstakingStep/SignMessageModal.tsx | 4 +- .../MissingAccountModal.tsx | 6 +-- .../ModalContentWrapper/SuccessModal.tsx | 4 +- dapp/src/components/shared/Alert.tsx | 52 +++++++++++++++++++ dapp/src/components/shared/Alert/index.tsx | 49 ----------------- dapp/src/components/shared/CardAlert.tsx | 51 ++++++++++++++++++ .../index.tsx => ReceiveSTBTCAlert.tsx} | 8 +-- dapp/src/components/shared/Toast.tsx | 26 ++++++++++ dapp/src/theme/Alert.ts | 44 +++++++--------- dapp/src/theme/utils/colors.ts | 3 ++ 15 files changed, 193 insertions(+), 107 deletions(-) create mode 100644 dapp/src/assets/icons/AlertError.tsx create mode 100644 dapp/src/components/shared/Alert.tsx delete mode 100644 dapp/src/components/shared/Alert/index.tsx create mode 100644 dapp/src/components/shared/CardAlert.tsx rename dapp/src/components/shared/{AlertReceiveSTBTC/index.tsx => ReceiveSTBTCAlert.tsx} (66%) create mode 100644 dapp/src/components/shared/Toast.tsx diff --git a/dapp/src/assets/icons/AlertError.tsx b/dapp/src/assets/icons/AlertError.tsx new file mode 100644 index 000000000..6fb513e5b --- /dev/null +++ b/dapp/src/assets/icons/AlertError.tsx @@ -0,0 +1,17 @@ +import React from "react" +import { createIcon } from "@chakra-ui/react" + +export const AlertError = createIcon({ + displayName: "AlertError", + viewBox: "0 0 24 25", + path: [ + , + ], +}) diff --git a/dapp/src/assets/icons/AlertInfo.tsx b/dapp/src/assets/icons/AlertInfo.tsx index a1c8cf1ad..2eda75539 100644 --- a/dapp/src/assets/icons/AlertInfo.tsx +++ b/dapp/src/assets/icons/AlertInfo.tsx @@ -3,22 +3,15 @@ import { createIcon } from "@chakra-ui/react" export const AlertInfo = createIcon({ displayName: "AlertInfo", - viewBox: "0 0 16 16", + viewBox: "0 0 24 24", path: [ - - - , - - - - - , + , ], }) diff --git a/dapp/src/assets/icons/index.ts b/dapp/src/assets/icons/index.ts index 347ef098c..5be87f41a 100644 --- a/dapp/src/assets/icons/index.ts +++ b/dapp/src/assets/icons/index.ts @@ -8,6 +8,7 @@ export * from "./AcreLogo" export * from "./ConnectBTCAccount" export * from "./ConnectETHAccount" export * from "./AlertInfo" +export * from "./AlertError" export * from "./stBTC" export * from "./BTC" export * from "./ShieldPlus" diff --git a/dapp/src/components/TransactionModal/ActiveStakingStep/DepositBTCModal.tsx b/dapp/src/components/TransactionModal/ActiveStakingStep/DepositBTCModal.tsx index 1701afbe5..0cf29d605 100644 --- a/dapp/src/components/TransactionModal/ActiveStakingStep/DepositBTCModal.tsx +++ b/dapp/src/components/TransactionModal/ActiveStakingStep/DepositBTCModal.tsx @@ -8,10 +8,10 @@ import { useTransactionContext, useWalletContext, } from "#/hooks" -import Alert from "#/components/shared/Alert" import { TextMd } from "#/components/shared/Typography" import { logPromiseFailure } from "#/utils" import { PROCESS_STATUSES } from "#/types" +import CardAlert from "#/components/shared/CardAlert" import StakingStepsModalContent from "./StakingStepsModalContent" export default function DepositBTCModal() { @@ -82,11 +82,11 @@ export default function DepositBTCModal() { activeStep={1} onClick={handledDepositBTCWrapper} > - + Make a Bitcoin transaction to deposit and stake your BTC. - + ) } diff --git a/dapp/src/components/TransactionModal/ActiveStakingStep/SignMessageModal.tsx b/dapp/src/components/TransactionModal/ActiveStakingStep/SignMessageModal.tsx index 84803da08..d8b059795 100644 --- a/dapp/src/components/TransactionModal/ActiveStakingStep/SignMessageModal.tsx +++ b/dapp/src/components/TransactionModal/ActiveStakingStep/SignMessageModal.tsx @@ -5,8 +5,8 @@ import { useStakeFlowContext, } from "#/hooks" import { logPromiseFailure } from "#/utils" -import AlertReceiveSTBTC from "#/components/shared/AlertReceiveSTBTC" import { PROCESS_STATUSES } from "#/types" +import ReceiveSTBTCAlert from "#/components/shared/ReceiveSTBTCAlert" import StakingStepsModalContent from "./StakingStepsModalContent" export default function SignMessageModal() { @@ -28,7 +28,7 @@ export default function SignMessageModal() { activeStep={0} onClick={handleSignMessageWrapper} > - + ) } diff --git a/dapp/src/components/TransactionModal/ActiveUnstakingStep/SignMessageModal.tsx b/dapp/src/components/TransactionModal/ActiveUnstakingStep/SignMessageModal.tsx index 0f9bd1003..0828456f9 100644 --- a/dapp/src/components/TransactionModal/ActiveUnstakingStep/SignMessageModal.tsx +++ b/dapp/src/components/TransactionModal/ActiveUnstakingStep/SignMessageModal.tsx @@ -3,8 +3,8 @@ import { useExecuteFunction, useModalFlowContext } from "#/hooks" import { PROCESS_STATUSES } from "#/types" import { Button, ModalBody, ModalFooter, ModalHeader } from "@chakra-ui/react" import { TextMd } from "#/components/shared/Typography" -import AlertReceiveSTBTC from "#/components/shared/AlertReceiveSTBTC" import { logPromiseFailure } from "#/utils" +import ReceiveSTBTCAlert from "#/components/shared/ReceiveSTBTCAlert" export default function SignMessageModal() { const { setStatus } = useModalFlowContext() @@ -46,7 +46,7 @@ export default function SignMessageModal() { You will sign a gas-free Ethereum message to indicate the address where you'd like to get your stBTC liquid staking token. - + + + + ), + }) + + const showToast = useCallback(() => { + if (!toast.isActive(type)) { + toast({ id: type }) + } + }, [toast, type]) + + useEffect(() => { + if (isToastClosed) return + + const timeout = setTimeout(showToast, delay) + + // eslint-disable-next-line consistent-return + return () => clearTimeout(timeout) + }, [delay, isToastClosed, showToast]) + + useEffect(() => { + if (!account || isToastClosed) return + + toast.close(type) + setIsToastClosed(true) + }, [account, isToastClosed, toast, type]) +} diff --git a/dapp/src/pages/OverviewPage/index.tsx b/dapp/src/pages/OverviewPage/index.tsx index 54bb52d8b..5ec9fb351 100644 --- a/dapp/src/pages/OverviewPage/index.tsx +++ b/dapp/src/pages/OverviewPage/index.tsx @@ -1,6 +1,6 @@ import React from "react" import { Flex, Grid, HStack, Switch } from "@chakra-ui/react" -import { useDocsDrawer } from "#/hooks" +import { useDocsDrawer, useWalletContext } from "#/hooks" import { TextSm } from "#/components/shared/Typography" import { USD } from "#/constants" import ButtonLink from "#/components/shared/ButtonLink" @@ -11,20 +11,37 @@ import ActivityBar from "../../components/shared/ActivityBar" export default function OverviewPage() { const { onOpen } = useDocsDrawer() + const { isConnected } = useWalletContext() return ( - - - {/* TODO: Handle click actions */} - - Show values in {USD.symbol} - - - - - Docs - - + + {!isConnected && ( + + + + Show values in {USD.symbol} + + + Docs + + + )} + {/* TODO: Add animation to show activity bar */} + {isConnected && ( + <> + + {/* TODO: Handle click actions */} + + Show values in {USD.symbol} + + + + + Docs + + + + )} ({ body: { "--toast-z-index": 1410, + "#chakra-toast-manager-top": { + marginTop: "toast_container_shift !important", + }, // TODO: Update when the dark theme is ready backgroundColor: mode("gold.300", "gold.300")(props), color: mode("grey.700", "grey.700")(props), diff --git a/dapp/src/theme/utils/colors.ts b/dapp/src/theme/utils/colors.ts index b3c103d2a..14a77fc45 100644 --- a/dapp/src/theme/utils/colors.ts +++ b/dapp/src/theme/utils/colors.ts @@ -64,7 +64,8 @@ export const colors = { }, }, black: { - "15": "rgba(0, 0, 0, 0.15)", + "05": "rgba(0, 0, 0, 0.05)", + 15: "rgba(0, 0, 0, 0.15)", }, }, } diff --git a/dapp/src/theme/utils/semanticTokens.ts b/dapp/src/theme/utils/semanticTokens.ts index 8db4851c1..41879fe4d 100644 --- a/dapp/src/theme/utils/semanticTokens.ts +++ b/dapp/src/theme/utils/semanticTokens.ts @@ -2,6 +2,7 @@ export const semanticTokens = { space: { header_height: 24, modal_shift: 48, + toast_container_shift: 16, }, sizes: { sidebar_width: 80, diff --git a/dapp/src/utils/errors.ts b/dapp/src/utils/errors.ts index f8675aa55..091178332 100644 --- a/dapp/src/utils/errors.ts +++ b/dapp/src/utils/errors.ts @@ -1,4 +1,5 @@ export const ERRORS = { SIGNING: "Message signing error.", DEPOSIT_TRANSACTION: "Deposit transaction execution error.", + WALLET_NOT_CONNECTED: (type: string) => `${type} wallet is not connected.`, } From a84b69cae835e1eb3e6ec28f86ddbd5654e0edb8 Mon Sep 17 00:00:00 2001 From: Karolina Kosiorowska Date: Wed, 13 Mar 2024 13:15:40 +0100 Subject: [PATCH 06/40] Create a separate directory for alerts --- .../ActiveStakingStep/DepositBTCModal.tsx | 3 +-- .../ActiveStakingStep/SignMessageModal.tsx | 3 +-- .../ActiveUnstakingStep/SignMessageModal.tsx | 2 +- .../ModalContentWrapper/MissingAccountModal.tsx | 2 +- .../ModalContentWrapper/SuccessModal.tsx | 2 +- dapp/src/components/shared/{ => alerts}/Alert.tsx | 2 +- dapp/src/components/shared/{ => alerts}/CardAlert.tsx | 4 ++-- .../shared/{ => alerts}/ReceiveSTBTCAlert.tsx | 6 +++--- dapp/src/components/shared/{ => alerts}/Toast.tsx | 11 +++-------- dapp/src/components/shared/alerts/index.tsx | 4 ++++ dapp/src/hooks/useWalletToast.tsx | 2 +- 11 files changed, 19 insertions(+), 22 deletions(-) rename dapp/src/components/shared/{ => alerts}/Alert.tsx (96%) rename dapp/src/components/shared/{ => alerts}/CardAlert.tsx (92%) rename dapp/src/components/shared/{ => alerts}/ReceiveSTBTCAlert.tsx (72%) rename dapp/src/components/shared/{ => alerts}/Toast.tsx (70%) create mode 100644 dapp/src/components/shared/alerts/index.tsx diff --git a/dapp/src/components/TransactionModal/ActiveStakingStep/DepositBTCModal.tsx b/dapp/src/components/TransactionModal/ActiveStakingStep/DepositBTCModal.tsx index 7c52ea051..c24c847b1 100644 --- a/dapp/src/components/TransactionModal/ActiveStakingStep/DepositBTCModal.tsx +++ b/dapp/src/components/TransactionModal/ActiveStakingStep/DepositBTCModal.tsx @@ -12,8 +12,7 @@ import { import { TextMd, TextSm } from "#/components/shared/Typography" import { ERRORS, logPromiseFailure } from "#/utils" import { PROCESS_STATUSES } from "#/types" -import CardAlert from "#/components/shared/CardAlert" -import Toast from "#/components/shared/Toast" +import { CardAlert, Toast } from "#/components/shared/alerts" import StakingStepsModalContent from "./StakingStepsModalContent" const ID_TOAST = "deposit-btc-error-toast" diff --git a/dapp/src/components/TransactionModal/ActiveStakingStep/SignMessageModal.tsx b/dapp/src/components/TransactionModal/ActiveStakingStep/SignMessageModal.tsx index 8e0bd1c36..c631b38c7 100644 --- a/dapp/src/components/TransactionModal/ActiveStakingStep/SignMessageModal.tsx +++ b/dapp/src/components/TransactionModal/ActiveStakingStep/SignMessageModal.tsx @@ -7,9 +7,8 @@ import { } from "#/hooks" import { ERRORS, logPromiseFailure } from "#/utils" import { PROCESS_STATUSES } from "#/types" -import ReceiveSTBTCAlert from "#/components/shared/ReceiveSTBTCAlert" -import Toast from "#/components/shared/Toast" import { TextSm } from "#/components/shared/Typography" +import { ReceiveSTBTCAlert, Toast } from "#/components/shared/alerts" import StakingStepsModalContent from "./StakingStepsModalContent" const ID_TOAST = "sign-message-error-toast" diff --git a/dapp/src/components/TransactionModal/ActiveUnstakingStep/SignMessageModal.tsx b/dapp/src/components/TransactionModal/ActiveUnstakingStep/SignMessageModal.tsx index 0828456f9..d462cab94 100644 --- a/dapp/src/components/TransactionModal/ActiveUnstakingStep/SignMessageModal.tsx +++ b/dapp/src/components/TransactionModal/ActiveUnstakingStep/SignMessageModal.tsx @@ -4,7 +4,7 @@ import { PROCESS_STATUSES } from "#/types" import { Button, ModalBody, ModalFooter, ModalHeader } from "@chakra-ui/react" import { TextMd } from "#/components/shared/Typography" import { logPromiseFailure } from "#/utils" -import ReceiveSTBTCAlert from "#/components/shared/ReceiveSTBTCAlert" +import { ReceiveSTBTCAlert } from "#/components/shared/alerts" export default function SignMessageModal() { const { setStatus } = useModalFlowContext() diff --git a/dapp/src/components/TransactionModal/ModalContentWrapper/MissingAccountModal.tsx b/dapp/src/components/TransactionModal/ModalContentWrapper/MissingAccountModal.tsx index 1be423c4b..e2c358152 100644 --- a/dapp/src/components/TransactionModal/ModalContentWrapper/MissingAccountModal.tsx +++ b/dapp/src/components/TransactionModal/ModalContentWrapper/MissingAccountModal.tsx @@ -11,7 +11,7 @@ import { import { TextMd } from "#/components/shared/Typography" import { logPromiseFailure, getCurrencyByType } from "#/utils" import { CurrencyType, RequestAccountParams } from "#/types" -import CardAlert from "#/components/shared/CardAlert" +import { CardAlert } from "#/components/shared/alerts" type MissingAccountModalProps = { currency: CurrencyType diff --git a/dapp/src/components/TransactionModal/ModalContentWrapper/SuccessModal.tsx b/dapp/src/components/TransactionModal/ModalContentWrapper/SuccessModal.tsx index 890e9cdff..e6dac590e 100644 --- a/dapp/src/components/TransactionModal/ModalContentWrapper/SuccessModal.tsx +++ b/dapp/src/components/TransactionModal/ModalContentWrapper/SuccessModal.tsx @@ -11,7 +11,7 @@ import { LoadingSpinnerSuccessIcon } from "#/assets/icons" import { useModalFlowContext } from "#/hooks" import { CurrencyBalanceWithConversion } from "#/components/shared/CurrencyBalanceWithConversion" import { ACTION_FLOW_TYPES, ActionFlowType, TokenAmount } from "#/types" -import ReceiveSTBTCAlert from "#/components/shared/ReceiveSTBTCAlert" +import { ReceiveSTBTCAlert } from "#/components/shared/alerts" const HEADER = { [ACTION_FLOW_TYPES.STAKE]: "Staking successful!", diff --git a/dapp/src/components/shared/Alert.tsx b/dapp/src/components/shared/alerts/Alert.tsx similarity index 96% rename from dapp/src/components/shared/Alert.tsx rename to dapp/src/components/shared/alerts/Alert.tsx index a18deb1c3..78ed33de3 100644 --- a/dapp/src/components/shared/Alert.tsx +++ b/dapp/src/components/shared/alerts/Alert.tsx @@ -25,7 +25,7 @@ export type AlertProps = ChakraAlertProps & { onClose?: () => void } -export default function Alert({ +export function Alert({ status = "info", alertIconColor, withAlertIcon, diff --git a/dapp/src/components/shared/CardAlert.tsx b/dapp/src/components/shared/alerts/CardAlert.tsx similarity index 92% rename from dapp/src/components/shared/CardAlert.tsx rename to dapp/src/components/shared/alerts/CardAlert.tsx index 56314fb60..2f5de52b1 100644 --- a/dapp/src/components/shared/CardAlert.tsx +++ b/dapp/src/components/shared/alerts/CardAlert.tsx @@ -1,14 +1,14 @@ import React from "react" import { HStack, Flex } from "@chakra-ui/react" import { ArrowUpRight } from "#/assets/icons" -import Alert, { AlertProps } from "./Alert" +import { Alert, AlertProps } from "./Alert" export type CardAlertProps = { withLink?: boolean onclick?: () => void } & Omit -export default function CardAlert({ +export function CardAlert({ withLink = false, children, onclick, diff --git a/dapp/src/components/shared/ReceiveSTBTCAlert.tsx b/dapp/src/components/shared/alerts/ReceiveSTBTCAlert.tsx similarity index 72% rename from dapp/src/components/shared/ReceiveSTBTCAlert.tsx rename to dapp/src/components/shared/alerts/ReceiveSTBTCAlert.tsx index 3897ff2ab..bf3fabbfb 100644 --- a/dapp/src/components/shared/ReceiveSTBTCAlert.tsx +++ b/dapp/src/components/shared/alerts/ReceiveSTBTCAlert.tsx @@ -1,9 +1,9 @@ import React from "react" import { Highlight } from "@chakra-ui/react" -import { TextMd } from "#/components/shared/Typography" -import CardAlert, { CardAlertProps } from "./CardAlert" +import { CardAlert, CardAlertProps } from "./CardAlert" +import { TextMd } from "../Typography" -export default function ReceiveSTBTCAlert({ ...restProps }: CardAlertProps) { +export function ReceiveSTBTCAlert({ ...restProps }: CardAlertProps) { return ( // TODO: Add the correct action after click {}} {...restProps}> diff --git a/dapp/src/components/shared/Toast.tsx b/dapp/src/components/shared/alerts/Toast.tsx similarity index 70% rename from dapp/src/components/shared/Toast.tsx rename to dapp/src/components/shared/alerts/Toast.tsx index 0f97a6ba6..89d07438c 100644 --- a/dapp/src/components/shared/Toast.tsx +++ b/dapp/src/components/shared/alerts/Toast.tsx @@ -1,7 +1,7 @@ import React from "react" import { HStack } from "@chakra-ui/react" -import { TextSm } from "./Typography" -import Alert, { AlertProps } from "./Alert" +import { Alert, AlertProps } from "./Alert" +import { TextSm } from "../Typography" type ToastProps = { title: string @@ -9,12 +9,7 @@ type ToastProps = { onClose: () => void } -export default function Toast({ - title, - children, - onClose, - ...props -}: ToastProps) { +export function Toast({ title, children, onClose, ...props }: ToastProps) { return ( diff --git a/dapp/src/components/shared/alerts/index.tsx b/dapp/src/components/shared/alerts/index.tsx new file mode 100644 index 000000000..ae4273f89 --- /dev/null +++ b/dapp/src/components/shared/alerts/index.tsx @@ -0,0 +1,4 @@ +export * from "./Alert" +export * from "./CardAlert" +export * from "./ReceiveSTBTCAlert" +export * from "./Toast" diff --git a/dapp/src/hooks/useWalletToast.tsx b/dapp/src/hooks/useWalletToast.tsx index 4507cb92c..98fa60837 100644 --- a/dapp/src/hooks/useWalletToast.tsx +++ b/dapp/src/hooks/useWalletToast.tsx @@ -1,8 +1,8 @@ import React, { useCallback, useEffect, useState } from "react" import { ONE_SEC_IN_MILLISECONDS } from "#/constants" -import Toast from "#/components/shared/Toast" import { ERRORS, capitalize, logPromiseFailure } from "#/utils" import { Button, Flex } from "@chakra-ui/react" +import { Toast } from "#/components/shared/alerts" import { useToast } from "./useToast" import { useWallet } from "./useWallet" From a16ae3c1a2fce767f7dec99cfc6c6d657c3f23f4 Mon Sep 17 00:00:00 2001 From: Karolina Kosiorowska Date: Thu, 14 Mar 2024 14:57:23 +0100 Subject: [PATCH 07/40] Export useful functions from useToast --- .../ActiveStakingStep/DepositBTCModal.tsx | 17 +++++------- .../ActiveStakingStep/SignMessageModal.tsx | 17 +++--------- dapp/src/hooks/useToast.ts | 26 ++++++++++++++++--- dapp/src/hooks/useWalletToast.tsx | 13 +++------- 4 files changed, 37 insertions(+), 36 deletions(-) diff --git a/dapp/src/components/TransactionModal/ActiveStakingStep/DepositBTCModal.tsx b/dapp/src/components/TransactionModal/ActiveStakingStep/DepositBTCModal.tsx index c24c847b1..7450638df 100644 --- a/dapp/src/components/TransactionModal/ActiveStakingStep/DepositBTCModal.tsx +++ b/dapp/src/components/TransactionModal/ActiveStakingStep/DepositBTCModal.tsx @@ -1,4 +1,4 @@ -import React, { useCallback } from "react" +import React, { useCallback, useEffect } from "react" import { useDepositBTCTransaction, useDepositTelemetry, @@ -15,8 +15,6 @@ import { PROCESS_STATUSES } from "#/types" import { CardAlert, Toast } from "#/components/shared/alerts" import StakingStepsModalContent from "./StakingStepsModalContent" -const ID_TOAST = "deposit-btc-error-toast" - export default function DepositBTCModal() { const { ethAccount } = useWalletContext() const { tokenAmount } = useTransactionContext() @@ -24,7 +22,8 @@ export default function DepositBTCModal() { const { btcAddress, depositReceipt, stake } = useStakeFlowContext() const depositTelemetry = useDepositTelemetry() - const toast = useToast({ + const { closeToast, showToast } = useToast({ + id: "deposit-btc-error-toast", render: ({ onClose }) => ( () => closeToast(), [closeToast]) + const onStakeBTCSuccess = useCallback(() => { setStatus(PROCESS_STATUSES.SUCCEEDED) }, [setStatus]) @@ -61,13 +62,7 @@ export default function DepositBTCModal() { }, 10000) }, [setStatus, handleStake]) - const onDepositBTCError = useCallback(() => { - if (!toast.isActive(ID_TOAST)) { - toast({ - id: ID_TOAST, - }) - } - }, [toast]) + const onDepositBTCError = useCallback(showToast, [showToast]) const { sendBitcoinTransaction } = useDepositBTCTransaction( onDepositBTCSuccess, diff --git a/dapp/src/components/TransactionModal/ActiveStakingStep/SignMessageModal.tsx b/dapp/src/components/TransactionModal/ActiveStakingStep/SignMessageModal.tsx index c631b38c7..054fef238 100644 --- a/dapp/src/components/TransactionModal/ActiveStakingStep/SignMessageModal.tsx +++ b/dapp/src/components/TransactionModal/ActiveStakingStep/SignMessageModal.tsx @@ -11,13 +11,12 @@ import { TextSm } from "#/components/shared/Typography" import { ReceiveSTBTCAlert, Toast } from "#/components/shared/alerts" import StakingStepsModalContent from "./StakingStepsModalContent" -const ID_TOAST = "sign-message-error-toast" - export default function SignMessageModal() { const { goNext, setStatus } = useModalFlowContext() const { signMessage } = useStakeFlowContext() - const toast = useToast({ + const { closeToast, showToast } = useToast({ + id: "sign-message-error-toast", render: ({ onClose }) => ( Please try again. @@ -25,15 +24,7 @@ export default function SignMessageModal() { ), }) - const onError = useCallback(() => { - if (!toast.isActive(ID_TOAST)) { - toast({ - id: ID_TOAST, - }) - } - }, [toast]) - - const handleSignMessage = useExecuteFunction(signMessage, goNext, onError) + const handleSignMessage = useExecuteFunction(signMessage, goNext, showToast) const handleSignMessageWrapper = useCallback(() => { logPromiseFailure(handleSignMessage()) @@ -43,7 +34,7 @@ export default function SignMessageModal() { setStatus(PROCESS_STATUSES.PENDING) }, [setStatus]) - useEffect(() => () => toast.close(ID_TOAST), [toast]) + useEffect(() => () => closeToast(), [closeToast]) return ( & { id: ToastId }) { + const toast = useChakraToast({ position: "top", duration: null, isClosable: true, containerStyle: { my: 1 }, ...props, }) + + const showToast = useCallback(() => { + if (!toast.isActive(id)) { + toast({ + id, + }) + } + }, [id, toast]) + + const closeToast = useCallback(() => toast.close(id), [id, toast]) + + return { toast, showToast, closeToast } } diff --git a/dapp/src/hooks/useWalletToast.tsx b/dapp/src/hooks/useWalletToast.tsx index 98fa60837..086196edd 100644 --- a/dapp/src/hooks/useWalletToast.tsx +++ b/dapp/src/hooks/useWalletToast.tsx @@ -21,7 +21,8 @@ export function useWalletToast( [requestAccount], ) - const toast = useToast({ + const { closeToast, showToast } = useToast({ + id: `${type}-account-toast`, render: ({ onClose }) => ( { - if (!toast.isActive(type)) { - toast({ id: type }) - } - }, [toast, type]) - useEffect(() => { if (isToastClosed) return @@ -64,7 +59,7 @@ export function useWalletToast( useEffect(() => { if (!account || isToastClosed) return - toast.close(type) + closeToast() setIsToastClosed(true) - }, [account, isToastClosed, toast, type]) + }, [account, closeToast, isToastClosed, type]) } From a4a22f2dec1ded427efe555c8f56479274c5a4ce Mon Sep 17 00:00:00 2001 From: Karolina Kosiorowska Date: Thu, 14 Mar 2024 15:20:24 +0100 Subject: [PATCH 08/40] Show button loading status when deposit address is verifying --- .../ActiveStakingStep/DepositBTCModal.tsx | 8 ++++++-- .../StakingStepsModalContent.tsx | 20 ++++++++++--------- .../shared/Form/FormSubmitButton.tsx | 15 ++++---------- dapp/src/components/shared/LoadingButton.tsx | 20 +++++++++++++++++++ 4 files changed, 41 insertions(+), 22 deletions(-) create mode 100644 dapp/src/components/shared/LoadingButton.tsx diff --git a/dapp/src/components/TransactionModal/ActiveStakingStep/DepositBTCModal.tsx b/dapp/src/components/TransactionModal/ActiveStakingStep/DepositBTCModal.tsx index 7450638df..7c7c9e892 100644 --- a/dapp/src/components/TransactionModal/ActiveStakingStep/DepositBTCModal.tsx +++ b/dapp/src/components/TransactionModal/ActiveStakingStep/DepositBTCModal.tsx @@ -1,4 +1,4 @@ -import React, { useCallback, useEffect } from "react" +import React, { useCallback, useEffect, useState } from "react" import { useDepositBTCTransaction, useDepositTelemetry, @@ -22,6 +22,8 @@ export default function DepositBTCModal() { const { btcAddress, depositReceipt, stake } = useStakeFlowContext() const depositTelemetry = useDepositTelemetry() + const [isLoading, setIsLoading] = useState(false) + const { closeToast, showToast } = useToast({ id: "deposit-btc-error-toast", render: ({ onClose }) => ( @@ -73,12 +75,13 @@ export default function DepositBTCModal() { if (!tokenAmount?.amount || !btcAddress || !depositReceipt || !ethAccount) return + setIsLoading(true) const response = await depositTelemetry( depositReceipt, btcAddress, ethAccount.address, ) - + setIsLoading(false) // TODO: Display the correct message for the user if (response.verificationStatus !== "valid") return @@ -100,6 +103,7 @@ export default function DepositBTCModal() { diff --git a/dapp/src/components/TransactionModal/ActiveStakingStep/StakingStepsModalContent.tsx b/dapp/src/components/TransactionModal/ActiveStakingStep/StakingStepsModalContent.tsx index bca9915d2..24f13b273 100644 --- a/dapp/src/components/TransactionModal/ActiveStakingStep/StakingStepsModalContent.tsx +++ b/dapp/src/components/TransactionModal/ActiveStakingStep/StakingStepsModalContent.tsx @@ -1,14 +1,9 @@ import React from "react" -import { - Button, - HStack, - ModalBody, - ModalFooter, - ModalHeader, -} from "@chakra-ui/react" +import { HStack, ModalBody, ModalFooter, ModalHeader } from "@chakra-ui/react" import { TextLg, TextMd } from "#/components/shared/Typography" import StepperBase, { StepBase } from "#/components/shared/StepperBase" import Spinner from "#/components/shared/Spinner" +import { LoadingButton } from "#/components/shared/LoadingButton" export function Title({ children }: { children: React.ReactNode }) { return {children} @@ -43,12 +38,14 @@ const STEPS: StepBase[] = [ export default function StakingStepsModalContent({ buttonText, + isLoading, activeStep, onClick, children, }: { buttonText: string activeStep: number + isLoading?: boolean onClick: () => void children: React.ReactNode }) { @@ -68,9 +65,14 @@ export default function StakingStepsModalContent({ {children} - + ) diff --git a/dapp/src/components/shared/Form/FormSubmitButton.tsx b/dapp/src/components/shared/Form/FormSubmitButton.tsx index 4991fddd6..d03fe4e25 100644 --- a/dapp/src/components/shared/Form/FormSubmitButton.tsx +++ b/dapp/src/components/shared/Form/FormSubmitButton.tsx @@ -1,27 +1,20 @@ import React from "react" import { useFormikContext } from "formik" -import { Button, ButtonProps } from "@chakra-ui/react" -import Spinner from "../Spinner" - -const LOADING_STYLE = { - _disabled: { background: "gold.300", opacity: 1 }, - _hover: { opacity: 1 }, -} +import { ButtonProps } from "@chakra-ui/react" +import { LoadingButton } from "../LoadingButton" export function FormSubmitButton({ children, ...props }: ButtonProps) { const { isSubmitting } = useFormikContext() return ( - + ) } diff --git a/dapp/src/components/shared/LoadingButton.tsx b/dapp/src/components/shared/LoadingButton.tsx new file mode 100644 index 000000000..2066c8b0d --- /dev/null +++ b/dapp/src/components/shared/LoadingButton.tsx @@ -0,0 +1,20 @@ +import React from "react" +import { Button, ButtonProps, Spinner } from "@chakra-ui/react" + +const LOADING_STYLE = { + _disabled: { background: "gold.300", opacity: 1 }, + _hover: { opacity: 1 }, +} + +export function LoadingButton({ isLoading, children, ...props }: ButtonProps) { + return ( + + ) +} From cb68d46e57a11bacfd5c0441fe8ab086c9a897fd Mon Sep 17 00:00:00 2001 From: Karolina Kosiorowska Date: Fri, 15 Mar 2024 09:11:20 +0100 Subject: [PATCH 09/40] Show error notification when the execution of a deposit transaction is interrupted --- .../ActiveStakingStep/DepositBTCModal.tsx | 21 ++++++++++++------- dapp/src/hooks/useDepositBTCTransaction.ts | 11 +++++++++- 2 files changed, 24 insertions(+), 8 deletions(-) diff --git a/dapp/src/components/TransactionModal/ActiveStakingStep/DepositBTCModal.tsx b/dapp/src/components/TransactionModal/ActiveStakingStep/DepositBTCModal.tsx index 55cf36a58..a5920f9ff 100644 --- a/dapp/src/components/TransactionModal/ActiveStakingStep/DepositBTCModal.tsx +++ b/dapp/src/components/TransactionModal/ActiveStakingStep/DepositBTCModal.tsx @@ -39,9 +39,10 @@ export default function DepositBTCModal() { useEffect(() => () => closeToast(), [closeToast]) - const onStakeBTCSuccess = useCallback(() => { - setStatus(PROCESS_STATUSES.SUCCEEDED) - }, [setStatus]) + const onStakeBTCSuccess = useCallback( + () => setStatus(PROCESS_STATUSES.SUCCEEDED), + [setStatus], + ) // TODO: After a failed attempt, we should display the message const onStakeBTCError = useCallback(() => { @@ -60,7 +61,10 @@ export default function DepositBTCModal() { logPromiseFailure(handleStake()) }, [setStatus, handleStake]) - const onDepositBTCError = useCallback(showToast, [showToast]) + const onDepositBTCError = useCallback( + () => setTimeout(showToast, 100), + [showToast], + ) const { sendBitcoinTransaction } = useDepositBTCTransaction( onDepositBTCSuccess, @@ -78,16 +82,19 @@ export default function DepositBTCModal() { ethAccount.address, ) setIsLoading(false) - // TODO: Display the correct message for the user - if (response.verificationStatus !== "valid") return - logPromiseFailure(sendBitcoinTransaction(tokenAmount?.amount, btcAddress)) + if (response.verificationStatus === "valid") { + logPromiseFailure(sendBitcoinTransaction(tokenAmount?.amount, btcAddress)) + } else { + setTimeout(showToast, 100) + } }, [ btcAddress, depositReceipt, depositTelemetry, ethAccount, sendBitcoinTransaction, + showToast, tokenAmount?.amount, ]) diff --git a/dapp/src/hooks/useDepositBTCTransaction.ts b/dapp/src/hooks/useDepositBTCTransaction.ts index d0296298a..f256255d2 100644 --- a/dapp/src/hooks/useDepositBTCTransaction.ts +++ b/dapp/src/hooks/useDepositBTCTransaction.ts @@ -63,10 +63,19 @@ export function useDepositBTCTransaction( await signAndBroadcastTransaction(btcAccount.id, bitcoinTransaction) walletApiReactTransport.disconnect() } catch (e) { + if (onError) { + onError(error) + } console.error(e) } }, - [btcAccount, signAndBroadcastTransaction, walletApiReactTransport], + [ + btcAccount, + error, + onError, + signAndBroadcastTransaction, + walletApiReactTransport, + ], ) return { ...rest, sendBitcoinTransaction, transactionHash, error } From aa8113ef3364034f95916d0b428915317f37c680 Mon Sep 17 00:00:00 2001 From: Karolina Kosiorowska Date: Fri, 15 Mar 2024 09:13:07 +0100 Subject: [PATCH 10/40] Update of error texts for dApp --- dapp/src/utils/errors.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dapp/src/utils/errors.ts b/dapp/src/utils/errors.ts index 091178332..26fa269fd 100644 --- a/dapp/src/utils/errors.ts +++ b/dapp/src/utils/errors.ts @@ -1,5 +1,5 @@ export const ERRORS = { - SIGNING: "Message signing error.", - DEPOSIT_TRANSACTION: "Deposit transaction execution error.", + SIGNING: "Message signing interrupted.", + DEPOSIT_TRANSACTION: "Deposit transaction execution interrupted.", WALLET_NOT_CONNECTED: (type: string) => `${type} wallet is not connected.`, } From 59e3432a03e8aedb314c839b751485ab4e58634e Mon Sep 17 00:00:00 2001 From: Karolina Kosiorowska Date: Fri, 15 Mar 2024 11:16:40 +0100 Subject: [PATCH 11/40] Simplify error handling logic for staking flow --- .../ActiveStakingStep/DepositBTCModal.tsx | 24 +++++++------- .../ActiveStakingStep/SignMessageModal.tsx | 32 +++++++++++++------ .../ModalContentWrapper/ResumeModal.tsx | 10 +++++- dapp/src/hooks/useToast.ts | 16 +++++++--- 4 files changed, 57 insertions(+), 25 deletions(-) diff --git a/dapp/src/components/TransactionModal/ActiveStakingStep/DepositBTCModal.tsx b/dapp/src/components/TransactionModal/ActiveStakingStep/DepositBTCModal.tsx index a5920f9ff..8db51881b 100644 --- a/dapp/src/components/TransactionModal/ActiveStakingStep/DepositBTCModal.tsx +++ b/dapp/src/components/TransactionModal/ActiveStakingStep/DepositBTCModal.tsx @@ -1,4 +1,4 @@ -import React, { useCallback, useEffect, useState } from "react" +import React, { useCallback, useState } from "react" import { useDepositBTCTransaction, useDepositTelemetry, @@ -23,6 +23,7 @@ export default function DepositBTCModal() { const depositTelemetry = useDepositTelemetry() const [isLoading, setIsLoading] = useState(false) + const [buttonText, setButtonText] = useState("Deposit BTC") const { closeToast, showToast } = useToast({ id: "deposit-btc-error-toast", @@ -37,8 +38,6 @@ export default function DepositBTCModal() { ), }) - useEffect(() => () => closeToast(), [closeToast]) - const onStakeBTCSuccess = useCallback( () => setStatus(PROCESS_STATUSES.SUCCEEDED), [setStatus], @@ -56,15 +55,18 @@ export default function DepositBTCModal() { ) const onDepositBTCSuccess = useCallback(() => { + closeToast() setStatus(PROCESS_STATUSES.LOADING) logPromiseFailure(handleStake()) - }, [setStatus, handleStake]) + }, [closeToast, setStatus, handleStake]) - const onDepositBTCError = useCallback( - () => setTimeout(showToast, 100), - [showToast], - ) + const showError = useCallback(() => { + showToast() + setButtonText("Try again") + }, [showToast]) + + const onDepositBTCError = useCallback(() => showError(), [showError]) const { sendBitcoinTransaction } = useDepositBTCTransaction( onDepositBTCSuccess, @@ -86,7 +88,7 @@ export default function DepositBTCModal() { if (response.verificationStatus === "valid") { logPromiseFailure(sendBitcoinTransaction(tokenAmount?.amount, btcAddress)) } else { - setTimeout(showToast, 100) + showError() } }, [ btcAddress, @@ -94,7 +96,7 @@ export default function DepositBTCModal() { depositTelemetry, ethAccount, sendBitcoinTransaction, - showToast, + showError, tokenAmount?.amount, ]) @@ -104,7 +106,7 @@ export default function DepositBTCModal() { return ( { + setStatus(PROCESS_STATUSES.PENDING) + }, [setStatus]) const { closeToast, showToast } = useToast({ id: "sign-message-error-toast", @@ -24,21 +30,29 @@ export default function SignMessageModal() { ), }) - const handleSignMessage = useExecuteFunction(signMessage, goNext, showToast) + const onSignMessageSuccess = useCallback(() => { + closeToast() + goNext() + }, [closeToast, goNext]) + + const onSignMessageError = useCallback(() => { + showToast() + setButtonText("Try again") + }, [showToast]) + + const handleSignMessage = useExecuteFunction( + signMessage, + onSignMessageSuccess, + onSignMessageError, + ) const handleSignMessageWrapper = useCallback(() => { logPromiseFailure(handleSignMessage()) }, [handleSignMessage]) - useEffect(() => { - setStatus(PROCESS_STATUSES.PENDING) - }, [setStatus]) - - useEffect(() => () => closeToast(), [closeToast]) - return ( diff --git a/dapp/src/components/TransactionModal/ModalContentWrapper/ResumeModal.tsx b/dapp/src/components/TransactionModal/ModalContentWrapper/ResumeModal.tsx index fb633e7eb..fcedd61a8 100644 --- a/dapp/src/components/TransactionModal/ModalContentWrapper/ResumeModal.tsx +++ b/dapp/src/components/TransactionModal/ModalContentWrapper/ResumeModal.tsx @@ -1,10 +1,11 @@ -import React from "react" +import React, { useEffect } from "react" import { ModalHeader, ModalBody, ModalFooter, Button, HStack, + useToast, } from "@chakra-ui/react" import Spinner from "#/components/shared/Spinner" @@ -18,6 +19,13 @@ export default function ResumeModal({ onResume: () => void onClose: () => void }) { + const toast = useToast() + + useEffect(() => { + // All notifications should be closed when the user is in the resume modal. + toast.closeAll() + }, [toast]) + return ( <> Paused diff --git a/dapp/src/hooks/useToast.ts b/dapp/src/hooks/useToast.ts index 263223c3b..e91567cbd 100644 --- a/dapp/src/hooks/useToast.ts +++ b/dapp/src/hooks/useToast.ts @@ -19,13 +19,21 @@ export function useToast({ const showToast = useCallback(() => { if (!toast.isActive(id)) { - toast({ - id, - }) + setTimeout( + () => + toast({ + id, + }), + 100, + ) } }, [id, toast]) - const closeToast = useCallback(() => toast.close(id), [id, toast]) + const closeToast = useCallback(() => { + if (toast.isActive(id)) { + toast.close(id) + } + }, [id, toast]) return { toast, showToast, closeToast } } From 3bf2a6828f7d1b1a03082854b77c5477ea542a56 Mon Sep 17 00:00:00 2001 From: Karolina Kosiorowska Date: Fri, 15 Mar 2024 11:42:33 +0100 Subject: [PATCH 12/40] Small improvements --- .../ActiveStakingStep/DepositBTCModal.tsx | 6 +--- .../ActiveStakingStep/SignMessageModal.tsx | 3 +- dapp/src/components/shared/alerts/Alert.tsx | 14 ++++---- .../components/shared/alerts/CardAlert.tsx | 4 +-- dapp/src/components/shared/alerts/Toast.tsx | 4 +-- dapp/src/hooks/useWalletToast.tsx | 1 - dapp/src/pages/OverviewPage/index.tsx | 36 ++++++++----------- 7 files changed, 28 insertions(+), 40 deletions(-) diff --git a/dapp/src/components/TransactionModal/ActiveStakingStep/DepositBTCModal.tsx b/dapp/src/components/TransactionModal/ActiveStakingStep/DepositBTCModal.tsx index 8db51881b..b67c9e43a 100644 --- a/dapp/src/components/TransactionModal/ActiveStakingStep/DepositBTCModal.tsx +++ b/dapp/src/components/TransactionModal/ActiveStakingStep/DepositBTCModal.tsx @@ -28,11 +28,7 @@ export default function DepositBTCModal() { const { closeToast, showToast } = useToast({ id: "deposit-btc-error-toast", render: ({ onClose }) => ( - + Please try again. ), diff --git a/dapp/src/components/TransactionModal/ActiveStakingStep/SignMessageModal.tsx b/dapp/src/components/TransactionModal/ActiveStakingStep/SignMessageModal.tsx index 8b7f316c1..d5066cbc1 100644 --- a/dapp/src/components/TransactionModal/ActiveStakingStep/SignMessageModal.tsx +++ b/dapp/src/components/TransactionModal/ActiveStakingStep/SignMessageModal.tsx @@ -1,4 +1,3 @@ -/* eslint-disable arrow-body-style */ import React, { useCallback, useEffect, useState } from "react" import { useExecuteFunction, @@ -24,7 +23,7 @@ export default function SignMessageModal() { const { closeToast, showToast } = useToast({ id: "sign-message-error-toast", render: ({ onClose }) => ( - + Please try again. ), diff --git a/dapp/src/components/shared/alerts/Alert.tsx b/dapp/src/components/shared/alerts/Alert.tsx index 78ed33de3..7f06f2201 100644 --- a/dapp/src/components/shared/alerts/Alert.tsx +++ b/dapp/src/components/shared/alerts/Alert.tsx @@ -14,12 +14,12 @@ const ICONS = { error: AlertError, } -export type AlertStatus = keyof typeof ICONS +type AlertStatus = keyof typeof ICONS export type AlertProps = ChakraAlertProps & { status?: AlertStatus - alertIconColor?: string - withAlertIcon?: boolean + colorIcon?: string + withIcon?: boolean withCloseButton?: boolean icon?: typeof Icon onClose?: () => void @@ -27,8 +27,8 @@ export type AlertProps = ChakraAlertProps & { export function Alert({ status = "info", - alertIconColor, - withAlertIcon, + colorIcon, + withIcon, children, withCloseButton, onClose, @@ -36,8 +36,8 @@ export function Alert({ }: AlertProps) { return ( - {withAlertIcon && status && ( - + {withIcon && status && ( + )} {children} diff --git a/dapp/src/components/shared/alerts/CardAlert.tsx b/dapp/src/components/shared/alerts/CardAlert.tsx index 2f5de52b1..6d242753d 100644 --- a/dapp/src/components/shared/alerts/CardAlert.tsx +++ b/dapp/src/components/shared/alerts/CardAlert.tsx @@ -22,8 +22,8 @@ export function CardAlert({ boxShadow="none" status="info" color="grey.700" - alertIconColor="grey.700" - withAlertIcon + colorIcon="grey.700" + withIcon {...props} > diff --git a/dapp/src/components/shared/alerts/Toast.tsx b/dapp/src/components/shared/alerts/Toast.tsx index 89d07438c..a43cc8519 100644 --- a/dapp/src/components/shared/alerts/Toast.tsx +++ b/dapp/src/components/shared/alerts/Toast.tsx @@ -5,13 +5,13 @@ import { TextSm } from "../Typography" type ToastProps = { title: string -} & Omit & { +} & Omit & { onClose: () => void } export function Toast({ title, children, onClose, ...props }: ToastProps) { return ( - + {title} {children} diff --git a/dapp/src/hooks/useWalletToast.tsx b/dapp/src/hooks/useWalletToast.tsx index 086196edd..bed9f7f24 100644 --- a/dapp/src/hooks/useWalletToast.tsx +++ b/dapp/src/hooks/useWalletToast.tsx @@ -25,7 +25,6 @@ export function useWalletToast( id: `${type}-account-toast`, render: ({ onClose }) => ( { diff --git a/dapp/src/pages/OverviewPage/index.tsx b/dapp/src/pages/OverviewPage/index.tsx index 5ec9fb351..444192776 100644 --- a/dapp/src/pages/OverviewPage/index.tsx +++ b/dapp/src/pages/OverviewPage/index.tsx @@ -15,32 +15,26 @@ export default function OverviewPage() { return ( - {!isConnected && ( - - - - Show values in {USD.symbol} - + + + {/* TODO: Handle click actions */} + + Show values in {USD.symbol} + + {!isConnected && ( Docs - - )} + )} + {/* TODO: Add animation to show activity bar */} {isConnected && ( - <> - - {/* TODO: Handle click actions */} - - Show values in {USD.symbol} - - - - - Docs - - - + + + + Docs + + )} Date: Fri, 15 Mar 2024 11:50:26 +0100 Subject: [PATCH 13/40] Rename from `isToastClosed` to `isToastAlreadyClosed` --- dapp/src/hooks/useWalletToast.tsx | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/dapp/src/hooks/useWalletToast.tsx b/dapp/src/hooks/useWalletToast.tsx index bed9f7f24..ccae7b21d 100644 --- a/dapp/src/hooks/useWalletToast.tsx +++ b/dapp/src/hooks/useWalletToast.tsx @@ -11,7 +11,7 @@ export function useWalletToast( delay = ONE_SEC_IN_MILLISECONDS, ) { // // The toast should be visible only once. - const [isToastClosed, setIsToastClosed] = useState(false) + const [isToastAlreadyClosed, setIsToastAlreadyClosed] = useState(false) const { [type]: { account, requestAccount }, } = useWallet() @@ -29,7 +29,7 @@ export function useWalletToast( title={ERRORS.WALLET_NOT_CONNECTED(capitalize(type))} onClose={() => { onClose() - setIsToastClosed(true) + setIsToastAlreadyClosed(true) }} > @@ -47,18 +47,18 @@ export function useWalletToast( }) useEffect(() => { - if (isToastClosed) return + if (isToastAlreadyClosed) return const timeout = setTimeout(showToast, delay) // eslint-disable-next-line consistent-return return () => clearTimeout(timeout) - }, [delay, isToastClosed, showToast]) + }, [delay, isToastAlreadyClosed, showToast]) useEffect(() => { - if (!account || isToastClosed) return + if (!account || isToastAlreadyClosed) return closeToast() - setIsToastClosed(true) - }, [account, closeToast, isToastClosed, type]) + setIsToastAlreadyClosed(true) + }, [account, closeToast, isToastAlreadyClosed, type]) } From 5c799df289902866fb4918429d2d95017bab060f Mon Sep 17 00:00:00 2001 From: Karolina Kosiorowska Date: Fri, 15 Mar 2024 16:19:00 +0100 Subject: [PATCH 14/40] Simplifying the logic of using toast component Created a custom useToast hook which wraps the useToast hook from Chakra UI and provides a render function to it to customize the toast components. In addition, a special ToastType was created to easily keep all kinds of notifications in the TOASTS object. This allows us to easily trigger a notification. Changing the approach of calling toast allowed to simplify the logic and get rid of unneeded parts of the code. --- .../ActiveStakingStep/DepositBTCModal.tsx | 26 +++---- .../ActiveStakingStep/SignMessageModal.tsx | 25 +++---- .../ModalContentWrapper/ResumeModal.tsx | 8 +-- dapp/src/components/shared/alerts/Toast.tsx | 70 ++++++++++++++++++- dapp/src/hooks/useToast.ts | 69 +++++++++--------- dapp/src/hooks/useWalletToast.ts | 50 +++++++++++++ dapp/src/hooks/useWalletToast.tsx | 64 ----------------- dapp/src/types/index.ts | 1 + dapp/src/types/toast.ts | 8 +++ dapp/src/utils/errors.ts | 5 -- dapp/src/utils/index.ts | 1 - 11 files changed, 186 insertions(+), 141 deletions(-) create mode 100644 dapp/src/hooks/useWalletToast.ts delete mode 100644 dapp/src/hooks/useWalletToast.tsx create mode 100644 dapp/src/types/toast.ts delete mode 100644 dapp/src/utils/errors.ts diff --git a/dapp/src/components/TransactionModal/ActiveStakingStep/DepositBTCModal.tsx b/dapp/src/components/TransactionModal/ActiveStakingStep/DepositBTCModal.tsx index b67c9e43a..61b1781b1 100644 --- a/dapp/src/components/TransactionModal/ActiveStakingStep/DepositBTCModal.tsx +++ b/dapp/src/components/TransactionModal/ActiveStakingStep/DepositBTCModal.tsx @@ -9,31 +9,25 @@ import { useTransactionContext, useWalletContext, } from "#/hooks" -import { TextMd, TextSm } from "#/components/shared/Typography" -import { ERRORS, logPromiseFailure } from "#/utils" -import { PROCESS_STATUSES } from "#/types" -import { CardAlert, Toast } from "#/components/shared/alerts" +import { TextMd } from "#/components/shared/Typography" +import { logPromiseFailure } from "#/utils" +import { PROCESS_STATUSES, TOAST_TYPES } from "#/types" +import { CardAlert, TOASTS } from "#/components/shared/alerts" import StakingStepsModalContent from "./StakingStepsModalContent" +const TOAST_ID = TOAST_TYPES.DEPOSIT_TRANSACTION_ERROR + export default function DepositBTCModal() { const { ethAccount } = useWalletContext() const { tokenAmount } = useTransactionContext() const { setStatus } = useModalFlowContext() const { btcAddress, depositReceipt, stake } = useStakeFlowContext() const depositTelemetry = useDepositTelemetry() + const { close: closeToast, open: openToast } = useToast() const [isLoading, setIsLoading] = useState(false) const [buttonText, setButtonText] = useState("Deposit BTC") - const { closeToast, showToast } = useToast({ - id: "deposit-btc-error-toast", - render: ({ onClose }) => ( - - Please try again. - - ), - }) - const onStakeBTCSuccess = useCallback( () => setStatus(PROCESS_STATUSES.SUCCEEDED), [setStatus], @@ -51,16 +45,16 @@ export default function DepositBTCModal() { ) const onDepositBTCSuccess = useCallback(() => { - closeToast() + closeToast(TOAST_ID) setStatus(PROCESS_STATUSES.LOADING) logPromiseFailure(handleStake()) }, [closeToast, setStatus, handleStake]) const showError = useCallback(() => { - showToast() + openToast(TOASTS[TOAST_ID]()) setButtonText("Try again") - }, [showToast]) + }, [openToast]) const onDepositBTCError = useCallback(() => showError(), [showError]) diff --git a/dapp/src/components/TransactionModal/ActiveStakingStep/SignMessageModal.tsx b/dapp/src/components/TransactionModal/ActiveStakingStep/SignMessageModal.tsx index d5066cbc1..345c4359e 100644 --- a/dapp/src/components/TransactionModal/ActiveStakingStep/SignMessageModal.tsx +++ b/dapp/src/components/TransactionModal/ActiveStakingStep/SignMessageModal.tsx @@ -5,39 +5,32 @@ import { useStakeFlowContext, useToast, } from "#/hooks" -import { ERRORS, logPromiseFailure } from "#/utils" -import { PROCESS_STATUSES } from "#/types" -import { TextSm } from "#/components/shared/Typography" -import { ReceiveSTBTCAlert, Toast } from "#/components/shared/alerts" +import { logPromiseFailure } from "#/utils" +import { PROCESS_STATUSES, TOAST_TYPES } from "#/types" +import { ReceiveSTBTCAlert, TOASTS } from "#/components/shared/alerts" import StakingStepsModalContent from "./StakingStepsModalContent" +const TOAST_ID = TOAST_TYPES.SIGNING_ERROR + export default function SignMessageModal() { const { goNext, setStatus } = useModalFlowContext() const { signMessage } = useStakeFlowContext() const [buttonText, setButtonText] = useState("Sign now") + const { close: closeToast, open: openToast } = useToast() useEffect(() => { setStatus(PROCESS_STATUSES.PENDING) }, [setStatus]) - const { closeToast, showToast } = useToast({ - id: "sign-message-error-toast", - render: ({ onClose }) => ( - - Please try again. - - ), - }) - const onSignMessageSuccess = useCallback(() => { - closeToast() + closeToast(TOAST_TYPES.SIGNING_ERROR) goNext() }, [closeToast, goNext]) const onSignMessageError = useCallback(() => { - showToast() + openToast(TOASTS[TOAST_ID]()) setButtonText("Try again") - }, [showToast]) + }, [openToast]) const handleSignMessage = useExecuteFunction( signMessage, diff --git a/dapp/src/components/TransactionModal/ModalContentWrapper/ResumeModal.tsx b/dapp/src/components/TransactionModal/ModalContentWrapper/ResumeModal.tsx index fcedd61a8..9e5bf6bd8 100644 --- a/dapp/src/components/TransactionModal/ModalContentWrapper/ResumeModal.tsx +++ b/dapp/src/components/TransactionModal/ModalContentWrapper/ResumeModal.tsx @@ -5,12 +5,12 @@ import { ModalFooter, Button, HStack, - useToast, } from "@chakra-ui/react" import Spinner from "#/components/shared/Spinner" import { PauseIcon } from "#/assets/icons" import { TextMd } from "#/components/shared/Typography" +import { useToast } from "#/hooks" export default function ResumeModal({ onResume, @@ -19,12 +19,12 @@ export default function ResumeModal({ onResume: () => void onClose: () => void }) { - const toast = useToast() + const { closeAll } = useToast() useEffect(() => { // All notifications should be closed when the user is in the resume modal. - toast.closeAll() - }, [toast]) + closeAll() + }, [closeAll]) return ( <> diff --git a/dapp/src/components/shared/alerts/Toast.tsx b/dapp/src/components/shared/alerts/Toast.tsx index a43cc8519..d97188ff3 100644 --- a/dapp/src/components/shared/alerts/Toast.tsx +++ b/dapp/src/components/shared/alerts/Toast.tsx @@ -1,5 +1,6 @@ import React from "react" -import { HStack } from "@chakra-ui/react" +import { Button, Flex, HStack, UseToastOptions } from "@chakra-ui/react" +import { TOAST_TYPES, ToastType } from "#/types" import { Alert, AlertProps } from "./Alert" import { TextSm } from "../Typography" @@ -19,3 +20,70 @@ export function Toast({ title, children, onClose, ...props }: ToastProps) { ) } + +export const TOASTS: Record< + ToastType, + (params?: { onClick: () => void }) => UseToastOptions +> = { + [TOAST_TYPES.BITCOIN_WALLET_NOT_CONNECTED_ERROR]: (params) => ({ + id: TOAST_TYPES.BITCOIN_WALLET_NOT_CONNECTED_ERROR, + render: ({ onClose }) => ( + onClose()} + > + + + + + ), + }), + [TOAST_TYPES.ETHEREUM_WALLET_NOT_CONNECTED_ERROR]: (params) => ({ + id: TOAST_TYPES.ETHEREUM_WALLET_NOT_CONNECTED_ERROR, + render: ({ onClose }) => ( + onClose()} + > + + + + + ), + }), + [TOAST_TYPES.SIGNING_ERROR]: () => ({ + id: TOAST_TYPES.SIGNING_ERROR, + render: ({ onClose }) => ( + + Please try again. + + ), + }), + [TOAST_TYPES.DEPOSIT_TRANSACTION_ERROR]: () => ({ + id: TOAST_TYPES.DEPOSIT_TRANSACTION_ERROR, + render: ({ onClose }) => ( + + Please try again. + + ), + }), +} diff --git a/dapp/src/hooks/useToast.ts b/dapp/src/hooks/useToast.ts index e91567cbd..97c469daf 100644 --- a/dapp/src/hooks/useToast.ts +++ b/dapp/src/hooks/useToast.ts @@ -1,39 +1,40 @@ -import { - ToastId, - UseToastOptions, - useToast as useChakraToast, -} from "@chakra-ui/react" -import { useCallback } from "react" +import { UseToastOptions, useToast as useChakraToast } from "@chakra-ui/react" +import { useCallback, useMemo } from "react" -export function useToast({ - id, - ...props -}: Omit & { id: ToastId }) { - const toast = useChakraToast({ - position: "top", - duration: null, - isClosable: true, - containerStyle: { my: 1 }, - ...props, - }) +export function useToast() { + const toast = useChakraToast() - const showToast = useCallback(() => { - if (!toast.isActive(id)) { - setTimeout( - () => - toast({ - id, - }), - 100, - ) - } - }, [id, toast]) + const returnFunction = useCallback( + (options: UseToastOptions) => + toast({ + position: "top", + duration: null, + isClosable: true, + containerStyle: { my: 1 }, + ...options, + }), + [toast], + ) - const closeToast = useCallback(() => { - if (toast.isActive(id)) { - toast.close(id) - } - }, [id, toast]) + const open = useCallback( + ({ id, ...options }: UseToastOptions) => { + if (!id) { + returnFunction(options) + } else if (!toast.isActive(id)) { + returnFunction({ + id, + ...options, + }) + } + }, + [returnFunction, toast], + ) - return { toast, showToast, closeToast } + return useMemo( + () => ({ + ...Object.assign(returnFunction, toast), + open, + }), + [returnFunction, toast, open], + ) } diff --git a/dapp/src/hooks/useWalletToast.ts b/dapp/src/hooks/useWalletToast.ts new file mode 100644 index 000000000..d8d024e20 --- /dev/null +++ b/dapp/src/hooks/useWalletToast.ts @@ -0,0 +1,50 @@ +import { useCallback, useEffect } from "react" +import { ONE_SEC_IN_MILLISECONDS } from "#/constants" +import { logPromiseFailure } from "#/utils" +import { TOASTS } from "#/components/shared/alerts" +import { TOAST_TYPES } from "#/types" +import { useToast } from "./useToast" +import { useWallet } from "./useWallet" + +const WALLET_TOAST = { + bitcoin: TOAST_TYPES.BITCOIN_WALLET_NOT_CONNECTED_ERROR, + ethereum: TOAST_TYPES.ETHEREUM_WALLET_NOT_CONNECTED_ERROR, +} + +export function useWalletToast( + type: "bitcoin" | "ethereum", + delay = ONE_SEC_IN_MILLISECONDS, +) { + const { + [type]: { account, requestAccount }, + } = useWallet() + const { close, open } = useToast() + + const toastId = WALLET_TOAST[type] + + const handleConnect = useCallback( + () => logPromiseFailure(requestAccount()), + [requestAccount], + ) + + useEffect(() => { + const timeout = setTimeout( + () => + open( + TOASTS[toastId]({ + onClick: handleConnect, + }), + ), + delay, + ) + + // eslint-disable-next-line consistent-return + return () => clearTimeout(timeout) + }, [delay, handleConnect, open, toastId, type]) + + useEffect(() => { + if (!account) return + + close(toastId) + }, [account, close, toastId]) +} diff --git a/dapp/src/hooks/useWalletToast.tsx b/dapp/src/hooks/useWalletToast.tsx deleted file mode 100644 index ccae7b21d..000000000 --- a/dapp/src/hooks/useWalletToast.tsx +++ /dev/null @@ -1,64 +0,0 @@ -import React, { useCallback, useEffect, useState } from "react" -import { ONE_SEC_IN_MILLISECONDS } from "#/constants" -import { ERRORS, capitalize, logPromiseFailure } from "#/utils" -import { Button, Flex } from "@chakra-ui/react" -import { Toast } from "#/components/shared/alerts" -import { useToast } from "./useToast" -import { useWallet } from "./useWallet" - -export function useWalletToast( - type: "bitcoin" | "ethereum", - delay = ONE_SEC_IN_MILLISECONDS, -) { - // // The toast should be visible only once. - const [isToastAlreadyClosed, setIsToastAlreadyClosed] = useState(false) - const { - [type]: { account, requestAccount }, - } = useWallet() - - const handleConnect = useCallback( - () => logPromiseFailure(requestAccount()), - [requestAccount], - ) - - const { closeToast, showToast } = useToast({ - id: `${type}-account-toast`, - render: ({ onClose }) => ( - { - onClose() - setIsToastAlreadyClosed(true) - }} - > - - - - - ), - }) - - useEffect(() => { - if (isToastAlreadyClosed) return - - const timeout = setTimeout(showToast, delay) - - // eslint-disable-next-line consistent-return - return () => clearTimeout(timeout) - }, [delay, isToastAlreadyClosed, showToast]) - - useEffect(() => { - if (!account || isToastAlreadyClosed) return - - closeToast() - setIsToastAlreadyClosed(true) - }, [account, closeToast, isToastAlreadyClosed, type]) -} diff --git a/dapp/src/types/index.ts b/dapp/src/types/index.ts index 12a5dc7b3..652e02c2a 100644 --- a/dapp/src/types/index.ts +++ b/dapp/src/types/index.ts @@ -10,3 +10,4 @@ export * from "./location" export * from "./charts" export * from "./activity" export * from "./coingecko" +export * from "./toast" diff --git a/dapp/src/types/toast.ts b/dapp/src/types/toast.ts new file mode 100644 index 000000000..1202dd1a8 --- /dev/null +++ b/dapp/src/types/toast.ts @@ -0,0 +1,8 @@ +export const TOAST_TYPES = { + BITCOIN_WALLET_NOT_CONNECTED_ERROR: "bitcoin-wallet-error", + ETHEREUM_WALLET_NOT_CONNECTED_ERROR: "ethereum-wallet-error", + SIGNING_ERROR: "signing-error", + DEPOSIT_TRANSACTION_ERROR: "deposit-transaction-error", +} as const + +export type ToastType = (typeof TOAST_TYPES)[keyof typeof TOAST_TYPES] diff --git a/dapp/src/utils/errors.ts b/dapp/src/utils/errors.ts deleted file mode 100644 index 26fa269fd..000000000 --- a/dapp/src/utils/errors.ts +++ /dev/null @@ -1,5 +0,0 @@ -export const ERRORS = { - SIGNING: "Message signing interrupted.", - DEPOSIT_TRANSACTION: "Deposit transaction execution interrupted.", - WALLET_NOT_CONNECTED: (type: string) => `${type} wallet is not connected.`, -} diff --git a/dapp/src/utils/index.ts b/dapp/src/utils/index.ts index fd22154ed..cb7034c47 100644 --- a/dapp/src/utils/index.ts +++ b/dapp/src/utils/index.ts @@ -8,4 +8,3 @@ export * from "./time" export * from "./promise" export * from "./exchangeApi" export * from "./verifyDepositAddress" -export * from "./errors" From 2e9fa482d2d8acdf80135fea24834063fa25c4a7 Mon Sep 17 00:00:00 2001 From: Karolina Kosiorowska Date: Mon, 18 Mar 2024 09:21:54 +0100 Subject: [PATCH 15/40] Use `TOAST_ID` everywhere to make the code transparent --- .../TransactionModal/ActiveStakingStep/SignMessageModal.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dapp/src/components/TransactionModal/ActiveStakingStep/SignMessageModal.tsx b/dapp/src/components/TransactionModal/ActiveStakingStep/SignMessageModal.tsx index 345c4359e..3b7d6bb6b 100644 --- a/dapp/src/components/TransactionModal/ActiveStakingStep/SignMessageModal.tsx +++ b/dapp/src/components/TransactionModal/ActiveStakingStep/SignMessageModal.tsx @@ -23,7 +23,7 @@ export default function SignMessageModal() { }, [setStatus]) const onSignMessageSuccess = useCallback(() => { - closeToast(TOAST_TYPES.SIGNING_ERROR) + closeToast(TOAST_ID) goNext() }, [closeToast, goNext]) From d402e84e766c0a6957bbf66d5425c112bbc7424c Mon Sep 17 00:00:00 2001 From: Karolina Kosiorowska Date: Mon, 18 Mar 2024 10:20:13 +0100 Subject: [PATCH 16/40] Reorganize global styles for Chakra UI For edge cases, you will have to override the global styles for chakra components. I moved these styles to a separate file to keep things in order. This will also make it easy to use the zIndices or semanticTokens file. --- dapp/src/theme/index.ts | 26 ++++++++++---------------- dapp/src/theme/utils/index.ts | 1 + dapp/src/theme/utils/styles.ts | 28 ++++++++++++++++++++++++++++ dapp/src/theme/utils/zIndices.ts | 1 + 4 files changed, 40 insertions(+), 16 deletions(-) create mode 100644 dapp/src/theme/utils/styles.ts diff --git a/dapp/src/theme/index.ts b/dapp/src/theme/index.ts index 09268aa63..dd32c1970 100644 --- a/dapp/src/theme/index.ts +++ b/dapp/src/theme/index.ts @@ -1,8 +1,14 @@ -import { StyleFunctionProps, extendTheme } from "@chakra-ui/react" -import { mode } from "@chakra-ui/theme-tools" +import { extendTheme } from "@chakra-ui/react" import { buttonTheme } from "./Button" import { switchTheme } from "./Switch" -import { colors, fonts, lineHeights, semanticTokens, zIndices } from "./utils" +import { + colors, + fonts, + lineHeights, + semanticTokens, + styles, + zIndices, +} from "./utils" import { drawerTheme } from "./Drawer" import { modalTheme } from "./Modal" import { cardTheme } from "./Card" @@ -37,19 +43,7 @@ const defaultTheme = { lineHeights, zIndices, semanticTokens, - styles: { - global: (props: StyleFunctionProps) => ({ - body: { - "--toast-z-index": 1410, - "#chakra-toast-manager-top": { - marginTop: "toast_container_shift !important", - }, - // TODO: Update when the dark theme is ready - backgroundColor: mode("gold.300", "gold.300")(props), - color: mode("grey.700", "grey.700")(props), - }, - }), - }, + styles, components: { Alert: alertTheme, Button: buttonTheme, diff --git a/dapp/src/theme/utils/index.ts b/dapp/src/theme/utils/index.ts index d2fad7e05..d100be7bb 100644 --- a/dapp/src/theme/utils/index.ts +++ b/dapp/src/theme/utils/index.ts @@ -2,3 +2,4 @@ export * from "./colors" export * from "./fonts" export * from "./zIndices" export * from "./semanticTokens" +export * from "./styles" diff --git a/dapp/src/theme/utils/styles.ts b/dapp/src/theme/utils/styles.ts new file mode 100644 index 000000000..71be2dc70 --- /dev/null +++ b/dapp/src/theme/utils/styles.ts @@ -0,0 +1,28 @@ +import { StyleFunctionProps, defineStyle } from "@chakra-ui/react" +import { mode } from "@chakra-ui/theme-tools" +import { semanticTokens } from "./semanticTokens" +import { zIndices } from "./zIndices" + +const bodyStyle = defineStyle((props: StyleFunctionProps) => ({ + // TODO: Update when the dark theme is ready + backgroundColor: mode("gold.300", "gold.300")(props), + color: mode("grey.700", "grey.700")(props), +})) + +const toastManagerStyle = defineStyle({ + marginTop: `${semanticTokens.space.toast_container_shift} !important`, + // To set the correct z-index value for the toast component, + // we need to override it in the global styles + // More info: + // https://github.com/chakra-ui/chakra-ui/issues/7505 + zIndex: `${zIndices.toast} !important`, +}) + +const globalStyle = (props: StyleFunctionProps) => ({ + "#chakra-toast-manager-top": toastManagerStyle, + body: bodyStyle(props), +}) + +export const styles = { + global: (props: StyleFunctionProps) => globalStyle(props), +} diff --git a/dapp/src/theme/utils/zIndices.ts b/dapp/src/theme/utils/zIndices.ts index a0834c287..4f196f66f 100644 --- a/dapp/src/theme/utils/zIndices.ts +++ b/dapp/src/theme/utils/zIndices.ts @@ -1,4 +1,5 @@ export const zIndices = { sidebar: 1450, drawer: 1470, + toast: 1410, } From 797603c3f22edd12d8a3292052c16685ce843d5d Mon Sep 17 00:00:00 2001 From: Karolina Kosiorowska Date: Wed, 20 Mar 2024 14:32:47 +0100 Subject: [PATCH 17/40] Fix typo for `onClick` --- dapp/src/components/shared/alerts/CardAlert.tsx | 6 +++--- dapp/src/components/shared/alerts/ReceiveSTBTCAlert.tsx | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/dapp/src/components/shared/alerts/CardAlert.tsx b/dapp/src/components/shared/alerts/CardAlert.tsx index 6d242753d..1c40f8a4e 100644 --- a/dapp/src/components/shared/alerts/CardAlert.tsx +++ b/dapp/src/components/shared/alerts/CardAlert.tsx @@ -5,13 +5,13 @@ import { Alert, AlertProps } from "./Alert" export type CardAlertProps = { withLink?: boolean - onclick?: () => void + onClick?: () => void } & Omit export function CardAlert({ withLink = false, children, - onclick, + onClick, ...props }: CardAlertProps) { return ( @@ -42,7 +42,7 @@ export function CardAlert({ boxSize={4} cursor="pointer" color="brand.400" - onClick={onclick} + onClick={onClick} /> )} diff --git a/dapp/src/components/shared/alerts/ReceiveSTBTCAlert.tsx b/dapp/src/components/shared/alerts/ReceiveSTBTCAlert.tsx index bf3fabbfb..a8003f524 100644 --- a/dapp/src/components/shared/alerts/ReceiveSTBTCAlert.tsx +++ b/dapp/src/components/shared/alerts/ReceiveSTBTCAlert.tsx @@ -6,7 +6,7 @@ import { TextMd } from "../Typography" export function ReceiveSTBTCAlert({ ...restProps }: CardAlertProps) { return ( // TODO: Add the correct action after click - {}} {...restProps}> + {}} {...restProps}> You will receive stBTC liquid staking token at this Ethereum address From 6585152a66b5d76609eeb46a450ee84224e664ca Mon Sep 17 00:00:00 2001 From: Karolina Kosiorowska Date: Wed, 20 Mar 2024 14:36:27 +0100 Subject: [PATCH 18/40] Change the default status value for the `Toast` component --- dapp/src/components/shared/alerts/Toast.tsx | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/dapp/src/components/shared/alerts/Toast.tsx b/dapp/src/components/shared/alerts/Toast.tsx index d97188ff3..60afe2a86 100644 --- a/dapp/src/components/shared/alerts/Toast.tsx +++ b/dapp/src/components/shared/alerts/Toast.tsx @@ -12,7 +12,7 @@ type ToastProps = { export function Toast({ title, children, onClose, ...props }: ToastProps) { return ( - + {title} {children} @@ -29,6 +29,7 @@ export const TOASTS: Record< id: TOAST_TYPES.BITCOIN_WALLET_NOT_CONNECTED_ERROR, render: ({ onClose }) => ( onClose()} @@ -50,6 +51,7 @@ export const TOASTS: Record< id: TOAST_TYPES.ETHEREUM_WALLET_NOT_CONNECTED_ERROR, render: ({ onClose }) => ( onClose()} @@ -70,7 +72,11 @@ export const TOASTS: Record< [TOAST_TYPES.SIGNING_ERROR]: () => ({ id: TOAST_TYPES.SIGNING_ERROR, render: ({ onClose }) => ( - + Please try again. ), @@ -79,6 +85,7 @@ export const TOASTS: Record< id: TOAST_TYPES.DEPOSIT_TRANSACTION_ERROR, render: ({ onClose }) => ( From ded8b11bc383f42b57418c1e77e998327b446596 Mon Sep 17 00:00:00 2001 From: Karolina Kosiorowska Date: Wed, 20 Mar 2024 14:53:57 +0100 Subject: [PATCH 19/40] Rename `WALLET_TOAST` to `WALLET_ERROR_TOAST_ID` --- dapp/src/hooks/useWalletToast.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dapp/src/hooks/useWalletToast.ts b/dapp/src/hooks/useWalletToast.ts index d8d024e20..6e3901bda 100644 --- a/dapp/src/hooks/useWalletToast.ts +++ b/dapp/src/hooks/useWalletToast.ts @@ -6,7 +6,7 @@ import { TOAST_TYPES } from "#/types" import { useToast } from "./useToast" import { useWallet } from "./useWallet" -const WALLET_TOAST = { +const WALLET_ERROR_TOAST_ID = { bitcoin: TOAST_TYPES.BITCOIN_WALLET_NOT_CONNECTED_ERROR, ethereum: TOAST_TYPES.ETHEREUM_WALLET_NOT_CONNECTED_ERROR, } @@ -20,7 +20,7 @@ export function useWalletToast( } = useWallet() const { close, open } = useToast() - const toastId = WALLET_TOAST[type] + const toastId = WALLET_ERROR_TOAST_ID[type] const handleConnect = useCallback( () => logPromiseFailure(requestAccount()), From 516d3157861d5cbbf82bf7122d313af3e823d5d4 Mon Sep 17 00:00:00 2001 From: Karolina Kosiorowska Date: Wed, 20 Mar 2024 15:53:39 +0100 Subject: [PATCH 20/40] Remove unnecessary disabling of the `eslint` rule --- dapp/src/hooks/useWalletToast.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/dapp/src/hooks/useWalletToast.ts b/dapp/src/hooks/useWalletToast.ts index 6e3901bda..fb088972b 100644 --- a/dapp/src/hooks/useWalletToast.ts +++ b/dapp/src/hooks/useWalletToast.ts @@ -38,7 +38,6 @@ export function useWalletToast( delay, ) - // eslint-disable-next-line consistent-return return () => clearTimeout(timeout) }, [delay, handleConnect, open, toastId, type]) From b208331c0749b7776b95ba18dd91fb903ada155b Mon Sep 17 00:00:00 2001 From: Karolina Kosiorowska Date: Wed, 20 Mar 2024 16:17:19 +0100 Subject: [PATCH 21/40] Move style for `LoadingButton` to theme --- dapp/src/components/shared/LoadingButton.tsx | 12 +----------- dapp/src/theme/Button.ts | 6 ++++++ 2 files changed, 7 insertions(+), 11 deletions(-) diff --git a/dapp/src/components/shared/LoadingButton.tsx b/dapp/src/components/shared/LoadingButton.tsx index 2066c8b0d..aa8c1715d 100644 --- a/dapp/src/components/shared/LoadingButton.tsx +++ b/dapp/src/components/shared/LoadingButton.tsx @@ -1,19 +1,9 @@ import React from "react" import { Button, ButtonProps, Spinner } from "@chakra-ui/react" -const LOADING_STYLE = { - _disabled: { background: "gold.300", opacity: 1 }, - _hover: { opacity: 1 }, -} - export function LoadingButton({ isLoading, children, ...props }: ButtonProps) { return ( - ) diff --git a/dapp/src/theme/Button.ts b/dapp/src/theme/Button.ts index f99609345..b424d1f53 100644 --- a/dapp/src/theme/Button.ts +++ b/dapp/src/theme/Button.ts @@ -27,6 +27,12 @@ export const buttonTheme: ComponentSingleStyleConfig = { _active: { bg: "brand.400", }, + _loading: { + _disabled: { + background: "gold.300", + opacity: 1, + }, + }, }, outline: ({ colorScheme }: StyleFunctionProps) => { const defaultStyles = { From 1bfe26c6043b5517790ddaa051911296c016ca5e Mon Sep 17 00:00:00 2001 From: Karolina Kosiorowska Date: Fri, 22 Mar 2024 08:02:53 +0100 Subject: [PATCH 22/40] Remove unnecessary `onClick` --- dapp/src/components/shared/alerts/ReceiveSTBTCAlert.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dapp/src/components/shared/alerts/ReceiveSTBTCAlert.tsx b/dapp/src/components/shared/alerts/ReceiveSTBTCAlert.tsx index a8003f524..d873f70b3 100644 --- a/dapp/src/components/shared/alerts/ReceiveSTBTCAlert.tsx +++ b/dapp/src/components/shared/alerts/ReceiveSTBTCAlert.tsx @@ -6,7 +6,7 @@ import { TextMd } from "../Typography" export function ReceiveSTBTCAlert({ ...restProps }: CardAlertProps) { return ( // TODO: Add the correct action after click - {}} {...restProps}> + You will receive stBTC liquid staking token at this Ethereum address From f0f846a916410b121d18e5a8e74b2ab6eeef276d Mon Sep 17 00:00:00 2001 From: Karolina Kosiorowska Date: Fri, 22 Mar 2024 08:05:47 +0100 Subject: [PATCH 23/40] Improve the `onClose` function pass --- dapp/src/components/shared/alerts/Toast.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dapp/src/components/shared/alerts/Toast.tsx b/dapp/src/components/shared/alerts/Toast.tsx index 60afe2a86..24a7adfaf 100644 --- a/dapp/src/components/shared/alerts/Toast.tsx +++ b/dapp/src/components/shared/alerts/Toast.tsx @@ -32,7 +32,7 @@ export const TOASTS: Record< status="error" width="xl" title="Bitcoin wallet is not connected." - onClose={() => onClose()} + onClose={onClose} > - - - ), - }), - [TOAST_TYPES.ETHEREUM_WALLET_NOT_CONNECTED_ERROR]: (params) => ({ - id: TOAST_TYPES.ETHEREUM_WALLET_NOT_CONNECTED_ERROR, - render: ({ onClose }) => ( - - - - - - ), - }), - [TOAST_TYPES.SIGNING_ERROR]: () => ({ - id: TOAST_TYPES.SIGNING_ERROR, - render: ({ onClose }) => ( - - Please try again. - - ), - }), - [TOAST_TYPES.DEPOSIT_TRANSACTION_ERROR]: () => ({ - id: TOAST_TYPES.DEPOSIT_TRANSACTION_ERROR, - render: ({ onClose }) => ( - - Please try again. - - ), - }), -} diff --git a/dapp/src/components/shared/alerts/ToastBase.tsx b/dapp/src/components/shared/alerts/ToastBase.tsx new file mode 100644 index 000000000..98cd45e6a --- /dev/null +++ b/dapp/src/components/shared/alerts/ToastBase.tsx @@ -0,0 +1,26 @@ +import React from "react" +import { HStack } from "@chakra-ui/react" +import { Alert, AlertProps } from "./Alert" +import { TextSm } from "../Typography" + +type ToastBaseProps = { + title: string +} & Omit & { + onClose: () => void + } + +export function ToastBase({ + title, + children, + onClose, + ...props +}: ToastBaseProps) { + return ( + + + {title} + {children} + + + ) +} diff --git a/dapp/src/components/shared/alerts/index.tsx b/dapp/src/components/shared/alerts/index.ts similarity index 75% rename from dapp/src/components/shared/alerts/index.tsx rename to dapp/src/components/shared/alerts/index.ts index ae4273f89..c9cbfceff 100644 --- a/dapp/src/components/shared/alerts/index.tsx +++ b/dapp/src/components/shared/alerts/index.ts @@ -1,4 +1,4 @@ export * from "./Alert" export * from "./CardAlert" export * from "./ReceiveSTBTCAlert" -export * from "./Toast" +export * from "./ToastBase" diff --git a/dapp/src/components/shared/toasts/DepositTransactionErrorToast.tsx b/dapp/src/components/shared/toasts/DepositTransactionErrorToast.tsx new file mode 100644 index 000000000..59c9f2332 --- /dev/null +++ b/dapp/src/components/shared/toasts/DepositTransactionErrorToast.tsx @@ -0,0 +1,19 @@ +import React from "react" +import { TextSm } from "../Typography" +import { ToastBase } from "../alerts" + +export function DepositTransactionErrorToast({ + onClose, +}: { + onClose: () => void +}) { + return ( + + Please try again. + + ) +} diff --git a/dapp/src/components/shared/toasts/MessageSigningErrorToast.tsx b/dapp/src/components/shared/toasts/MessageSigningErrorToast.tsx new file mode 100644 index 000000000..c9bebd0ef --- /dev/null +++ b/dapp/src/components/shared/toasts/MessageSigningErrorToast.tsx @@ -0,0 +1,15 @@ +import React from "react" +import { TextSm } from "../Typography" +import { ToastBase } from "../alerts" + +export function MessageSigningErrorToast({ onClose }: { onClose: () => void }) { + return ( + + Please try again. + + ) +} diff --git a/dapp/src/components/shared/toasts/WalletErrorToast.tsx b/dapp/src/components/shared/toasts/WalletErrorToast.tsx new file mode 100644 index 000000000..1d30869f8 --- /dev/null +++ b/dapp/src/components/shared/toasts/WalletErrorToast.tsx @@ -0,0 +1,23 @@ +import React from "react" +import { Flex, Button } from "@chakra-ui/react" +import { ToastBase } from "../alerts" + +export function WalletErrorToast({ + title, + onClick, + onClose, +}: { + title: string + onClick?: () => void + onClose: () => void +}) { + return ( + + + + + + ) +} diff --git a/dapp/src/components/shared/toasts/index.ts b/dapp/src/components/shared/toasts/index.ts new file mode 100644 index 000000000..9d37898ac --- /dev/null +++ b/dapp/src/components/shared/toasts/index.ts @@ -0,0 +1,4 @@ +export * from "./MessageSigningErrorToast" +export * from "./DepositTransactionErrorToast" +export * from "./WalletErrorToast" +export * from "./toasts" diff --git a/dapp/src/components/shared/toasts/toasts.tsx b/dapp/src/components/shared/toasts/toasts.tsx new file mode 100644 index 000000000..4c3a1160d --- /dev/null +++ b/dapp/src/components/shared/toasts/toasts.tsx @@ -0,0 +1,47 @@ +import React from "react" +import { TOAST_TYPES, ToastType } from "#/types" +import { UseToastOptions } from "@chakra-ui/react" +import { WalletErrorToast } from "./WalletErrorToast" +import { MessageSigningErrorToast } from "./MessageSigningErrorToast" +import { DepositTransactionErrorToast } from "./DepositTransactionErrorToast" + +const { + BITCOIN_WALLET_NOT_CONNECTED_ERROR, + ETHEREUM_WALLET_NOT_CONNECTED_ERROR, + SIGNING_ERROR, + DEPOSIT_TRANSACTION_ERROR, +} = TOAST_TYPES + +export const TOASTS: Record< + ToastType, + (params?: { onClick: () => void }) => UseToastOptions +> = { + [BITCOIN_WALLET_NOT_CONNECTED_ERROR]: (params) => ({ + id: BITCOIN_WALLET_NOT_CONNECTED_ERROR, + render: ({ onClose }) => ( + + ), + }), + [ETHEREUM_WALLET_NOT_CONNECTED_ERROR]: (params) => ({ + id: ETHEREUM_WALLET_NOT_CONNECTED_ERROR, + render: ({ onClose }) => ( + + ), + }), + [SIGNING_ERROR]: () => ({ + id: SIGNING_ERROR, + render: ({ onClose }) => , + }), + [DEPOSIT_TRANSACTION_ERROR]: () => ({ + id: DEPOSIT_TRANSACTION_ERROR, + render: ({ onClose }) => , + }), +} diff --git a/dapp/src/hooks/useWalletToast.ts b/dapp/src/hooks/useWalletToast.ts index fb088972b..cc146e4cd 100644 --- a/dapp/src/hooks/useWalletToast.ts +++ b/dapp/src/hooks/useWalletToast.ts @@ -1,8 +1,8 @@ import { useCallback, useEffect } from "react" import { ONE_SEC_IN_MILLISECONDS } from "#/constants" import { logPromiseFailure } from "#/utils" -import { TOASTS } from "#/components/shared/alerts" import { TOAST_TYPES } from "#/types" +import { TOASTS } from "#/components/shared/toasts" import { useToast } from "./useToast" import { useWallet } from "./useWallet" From 7853840033d483424de1f095addd40802ca5fae2 Mon Sep 17 00:00:00 2001 From: Karolina Kosiorowska Date: Tue, 2 Apr 2024 08:47:31 +0200 Subject: [PATCH 26/40] Rename from `overriddenToastFunction` to `overriddenToast` --- dapp/src/hooks/useToast.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/dapp/src/hooks/useToast.ts b/dapp/src/hooks/useToast.ts index 9b253dc29..60dbee49d 100644 --- a/dapp/src/hooks/useToast.ts +++ b/dapp/src/hooks/useToast.ts @@ -4,7 +4,7 @@ import { useCallback, useMemo } from "react" export function useToast() { const toast = useChakraToast() - const overriddenToastFunction = useCallback( + const overriddenToast = useCallback( (options: UseToastOptions) => toast({ position: "top", @@ -19,22 +19,22 @@ export function useToast() { const open = useCallback( ({ id, ...options }: UseToastOptions) => { if (!id) { - overriddenToastFunction(options) + overriddenToast(options) } else if (!toast.isActive(id)) { - overriddenToastFunction({ + overriddenToast({ id, ...options, }) } }, - [overriddenToastFunction, toast], + [overriddenToast, toast], ) return useMemo( () => ({ - ...Object.assign(overriddenToastFunction, toast), + ...Object.assign(overriddenToast, toast), open, }), - [overriddenToastFunction, toast, open], + [overriddenToast, toast, open], ) } From 7632242e02a45636a80d10d7f38cd31183634740 Mon Sep 17 00:00:00 2001 From: Karolina Kosiorowska Date: Tue, 2 Apr 2024 09:19:58 +0200 Subject: [PATCH 27/40] Create a `useTimeout` hook --- dapp/src/hooks/index.ts | 1 + dapp/src/hooks/useTimeout.ts | 25 +++++++++++++++++++++++++ dapp/src/hooks/useWalletToast.ts | 25 ++++++++++++------------- 3 files changed, 38 insertions(+), 13 deletions(-) create mode 100644 dapp/src/hooks/useTimeout.ts diff --git a/dapp/src/hooks/index.ts b/dapp/src/hooks/index.ts index dd0dba80c..2a1408832 100644 --- a/dapp/src/hooks/index.ts +++ b/dapp/src/hooks/index.ts @@ -20,3 +20,4 @@ export * from "./useFetchBTCPriceUSD" export * from "./useToast" export * from "./useWallet" export * from "./useWalletToast" +export * from "./useTimeout" diff --git a/dapp/src/hooks/useTimeout.ts b/dapp/src/hooks/useTimeout.ts new file mode 100644 index 000000000..ba037809e --- /dev/null +++ b/dapp/src/hooks/useTimeout.ts @@ -0,0 +1,25 @@ +import { useEffect, useLayoutEffect, useRef } from "react" + +// Source: https://usehooks-ts.com/react-hook/use-timeout +export function useTimeout(callback: () => void, delay: number | null) { + const savedCallback = useRef(callback) + + // Remember the latest callback if it changes. + useLayoutEffect(() => { + savedCallback.current = callback + }, [callback]) + + // Set up the timeout. + useEffect(() => { + // Don't schedule if no delay is specified. + // Note: 0 is a valid value for delay. + if (!delay && delay !== 0) { + return + } + + const id = setTimeout(() => savedCallback.current(), delay) + + // eslint-disable-next-line consistent-return + return () => clearTimeout(id) + }, [delay]) +} diff --git a/dapp/src/hooks/useWalletToast.ts b/dapp/src/hooks/useWalletToast.ts index cc146e4cd..32dfa00e2 100644 --- a/dapp/src/hooks/useWalletToast.ts +++ b/dapp/src/hooks/useWalletToast.ts @@ -5,6 +5,7 @@ import { TOAST_TYPES } from "#/types" import { TOASTS } from "#/components/shared/toasts" import { useToast } from "./useToast" import { useWallet } from "./useWallet" +import { useTimeout } from "./useTimeout" const WALLET_ERROR_TOAST_ID = { bitcoin: TOAST_TYPES.BITCOIN_WALLET_NOT_CONNECTED_ERROR, @@ -27,19 +28,17 @@ export function useWalletToast( [requestAccount], ) - useEffect(() => { - const timeout = setTimeout( - () => - open( - TOASTS[toastId]({ - onClick: handleConnect, - }), - ), - delay, - ) - - return () => clearTimeout(timeout) - }, [delay, handleConnect, open, toastId, type]) + const handleOpen = useCallback( + () => + open( + TOASTS[toastId]({ + onClick: handleConnect, + }), + ), + [handleConnect, open, toastId], + ) + + useTimeout(handleOpen, delay) useEffect(() => { if (!account) return From 45842488f0aba8ae312f9eea3591c36d33a69e4f Mon Sep 17 00:00:00 2001 From: Karolina Kosiorowska Date: Tue, 2 Apr 2024 09:21:43 +0200 Subject: [PATCH 28/40] Rename from `toastManagerStyle` to `toastManagerTopStyle` --- dapp/src/theme/utils/styles.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dapp/src/theme/utils/styles.ts b/dapp/src/theme/utils/styles.ts index 71be2dc70..a1a891663 100644 --- a/dapp/src/theme/utils/styles.ts +++ b/dapp/src/theme/utils/styles.ts @@ -9,7 +9,7 @@ const bodyStyle = defineStyle((props: StyleFunctionProps) => ({ color: mode("grey.700", "grey.700")(props), })) -const toastManagerStyle = defineStyle({ +const toastManagerTopStyle = defineStyle({ marginTop: `${semanticTokens.space.toast_container_shift} !important`, // To set the correct z-index value for the toast component, // we need to override it in the global styles @@ -19,7 +19,7 @@ const toastManagerStyle = defineStyle({ }) const globalStyle = (props: StyleFunctionProps) => ({ - "#chakra-toast-manager-top": toastManagerStyle, + "#chakra-toast-manager-top": toastManagerTopStyle, body: bodyStyle(props), }) From e99d2e579388b86302ac1766d2df16a751cd5dae Mon Sep 17 00:00:00 2001 From: Karolina Kosiorowska Date: Tue, 2 Apr 2024 09:24:01 +0200 Subject: [PATCH 29/40] Remove unnecessary padding for tooltip --- dapp/src/components/shared/ActivityBar/ActivityCard.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dapp/src/components/shared/ActivityBar/ActivityCard.tsx b/dapp/src/components/shared/ActivityBar/ActivityCard.tsx index 8682c0964..dcf0ca46e 100644 --- a/dapp/src/components/shared/ActivityBar/ActivityCard.tsx +++ b/dapp/src/components/shared/ActivityBar/ActivityCard.tsx @@ -50,7 +50,7 @@ function ActivityCard({ activity, onRemove }: ActivityCardType) { symbolFontWeight="medium" /> {isCompleted ? ( - + ) : ( From 33a042117c7f7ccd89e2f56bab3772da6fabf4d8 Mon Sep 17 00:00:00 2001 From: Karolina Kosiorowska Date: Tue, 2 Apr 2024 10:37:09 +0200 Subject: [PATCH 30/40] Removal of the global object `TOASTS` The previous approach created a bit of a mess. To call a specific toast we needed to provide an id. Currently, the solution allows a specific toast to be called directly in the area of use. --- .../Table/utils/columns.tsx | 10 ++-- .../ActiveStakingStep/DepositBTCModal.tsx | 8 ++-- .../ActiveStakingStep/SignMessageModal.tsx | 11 +++-- .../shared/ActivityBar/ActivityCard.tsx | 4 +- dapp/src/components/shared/toasts/index.ts | 1 - dapp/src/components/shared/toasts/toasts.tsx | 47 ------------------- dapp/src/hooks/useWalletToast.ts | 25 +++++----- .../pages/ActivityPage/ActivityDetails.tsx | 4 +- dapp/src/types/index.ts | 1 - dapp/src/types/toast.ts | 8 ---- dapp/src/utils/text.ts | 2 +- 11 files changed, 37 insertions(+), 84 deletions(-) delete mode 100644 dapp/src/components/shared/toasts/toasts.tsx delete mode 100644 dapp/src/types/toast.ts diff --git a/dapp/src/components/TransactionHistory/Table/utils/columns.tsx b/dapp/src/components/TransactionHistory/Table/utils/columns.tsx index 7523e56f8..d656a50ea 100644 --- a/dapp/src/components/TransactionHistory/Table/utils/columns.tsx +++ b/dapp/src/components/TransactionHistory/Table/utils/columns.tsx @@ -1,7 +1,7 @@ import React from "react" import { ColumnDef, createColumnHelper } from "@tanstack/react-table" import { StakeHistory } from "#/types" -import { capitalize, truncateAddress } from "#/utils" +import { capitalizeFirstLetter, truncateAddress } from "#/utils" import CustomCell from "../Cell/Custom" import Cell from "../Cell" import SimpleText from "../Cell/components/SimpleText" @@ -32,10 +32,14 @@ export const COLUMNS: ColumnDef[] = [ cell: ({ row: { original } }) => ( {capitalize(original.callTx.action)} + + {capitalizeFirstLetter(original.callTx.action)} + } secondField={ - {capitalize(original.receiptTx.action)} + + {capitalizeFirstLetter(original.receiptTx.action)} + } /> ), diff --git a/dapp/src/components/TransactionModal/ActiveStakingStep/DepositBTCModal.tsx b/dapp/src/components/TransactionModal/ActiveStakingStep/DepositBTCModal.tsx index 76f82cd2f..649da9e3a 100644 --- a/dapp/src/components/TransactionModal/ActiveStakingStep/DepositBTCModal.tsx +++ b/dapp/src/components/TransactionModal/ActiveStakingStep/DepositBTCModal.tsx @@ -11,12 +11,12 @@ import { } from "#/hooks" import { TextMd } from "#/components/shared/Typography" import { logPromiseFailure } from "#/utils" -import { PROCESS_STATUSES, TOAST_TYPES } from "#/types" +import { PROCESS_STATUSES } from "#/types" import { CardAlert } from "#/components/shared/alerts" -import { TOASTS } from "#/components/shared/toasts" +import { DepositTransactionErrorToast } from "#/components/shared/toasts" import StakingStepsModalContent from "./StakingStepsModalContent" -const TOAST_ID = TOAST_TYPES.DEPOSIT_TRANSACTION_ERROR +const TOAST_ID = "deposit-transaction-error" export default function DepositBTCModal() { const { ethAccount } = useWalletContext() @@ -53,7 +53,7 @@ export default function DepositBTCModal() { }, [closeToast, setStatus, handleStake]) const showError = useCallback(() => { - openToast(TOASTS[TOAST_ID]()) + openToast({ id: TOAST_ID, render: DepositTransactionErrorToast }) setButtonText("Try again") }, [openToast]) diff --git a/dapp/src/components/TransactionModal/ActiveStakingStep/SignMessageModal.tsx b/dapp/src/components/TransactionModal/ActiveStakingStep/SignMessageModal.tsx index ea2c09a58..7389990db 100644 --- a/dapp/src/components/TransactionModal/ActiveStakingStep/SignMessageModal.tsx +++ b/dapp/src/components/TransactionModal/ActiveStakingStep/SignMessageModal.tsx @@ -6,12 +6,12 @@ import { useToast, } from "#/hooks" import { logPromiseFailure } from "#/utils" -import { PROCESS_STATUSES, TOAST_TYPES } from "#/types" +import { PROCESS_STATUSES } from "#/types" import { ReceiveSTBTCAlert } from "#/components/shared/alerts" -import { TOASTS } from "#/components/shared/toasts" +import { MessageSigningErrorToast } from "#/components/shared/toasts" import StakingStepsModalContent from "./StakingStepsModalContent" -const TOAST_ID = TOAST_TYPES.SIGNING_ERROR +const TOAST_ID = "signing-error" export default function SignMessageModal() { const { goNext, setStatus } = useModalFlowContext() @@ -29,7 +29,10 @@ export default function SignMessageModal() { }, [closeToast, goNext]) const onSignMessageError = useCallback(() => { - openToast(TOASTS[TOAST_ID]()) + openToast({ + id: TOAST_ID, + render: MessageSigningErrorToast, + }) setButtonText("Try again") }, [openToast]) diff --git a/dapp/src/components/shared/ActivityBar/ActivityCard.tsx b/dapp/src/components/shared/ActivityBar/ActivityCard.tsx index dcf0ca46e..55ae9c4d2 100644 --- a/dapp/src/components/shared/ActivityBar/ActivityCard.tsx +++ b/dapp/src/components/shared/ActivityBar/ActivityCard.tsx @@ -11,7 +11,7 @@ import { } from "@chakra-ui/react" import { useLocation } from "react-router-dom" import { ActivityInfo, LocationState } from "#/types" -import { capitalize } from "#/utils" +import { capitalizeFirstLetter } from "#/utils" import { ChevronRightIcon } from "#/assets/icons" import { CurrencyBalance } from "#/components/shared/CurrencyBalance" import StatusInfo from "#/components/shared/StatusInfo" @@ -65,7 +65,7 @@ function ActivityCard({ activity, onRemove }: ActivityCardType) { - {capitalize(activity.action)} + {capitalizeFirstLetter(activity.action)} diff --git a/dapp/src/components/shared/toasts/index.ts b/dapp/src/components/shared/toasts/index.ts index 9d37898ac..9b997f38e 100644 --- a/dapp/src/components/shared/toasts/index.ts +++ b/dapp/src/components/shared/toasts/index.ts @@ -1,4 +1,3 @@ export * from "./MessageSigningErrorToast" export * from "./DepositTransactionErrorToast" export * from "./WalletErrorToast" -export * from "./toasts" diff --git a/dapp/src/components/shared/toasts/toasts.tsx b/dapp/src/components/shared/toasts/toasts.tsx deleted file mode 100644 index 4c3a1160d..000000000 --- a/dapp/src/components/shared/toasts/toasts.tsx +++ /dev/null @@ -1,47 +0,0 @@ -import React from "react" -import { TOAST_TYPES, ToastType } from "#/types" -import { UseToastOptions } from "@chakra-ui/react" -import { WalletErrorToast } from "./WalletErrorToast" -import { MessageSigningErrorToast } from "./MessageSigningErrorToast" -import { DepositTransactionErrorToast } from "./DepositTransactionErrorToast" - -const { - BITCOIN_WALLET_NOT_CONNECTED_ERROR, - ETHEREUM_WALLET_NOT_CONNECTED_ERROR, - SIGNING_ERROR, - DEPOSIT_TRANSACTION_ERROR, -} = TOAST_TYPES - -export const TOASTS: Record< - ToastType, - (params?: { onClick: () => void }) => UseToastOptions -> = { - [BITCOIN_WALLET_NOT_CONNECTED_ERROR]: (params) => ({ - id: BITCOIN_WALLET_NOT_CONNECTED_ERROR, - render: ({ onClose }) => ( - - ), - }), - [ETHEREUM_WALLET_NOT_CONNECTED_ERROR]: (params) => ({ - id: ETHEREUM_WALLET_NOT_CONNECTED_ERROR, - render: ({ onClose }) => ( - - ), - }), - [SIGNING_ERROR]: () => ({ - id: SIGNING_ERROR, - render: ({ onClose }) => , - }), - [DEPOSIT_TRANSACTION_ERROR]: () => ({ - id: DEPOSIT_TRANSACTION_ERROR, - render: ({ onClose }) => , - }), -} diff --git a/dapp/src/hooks/useWalletToast.ts b/dapp/src/hooks/useWalletToast.ts index 32dfa00e2..9e01c2b37 100644 --- a/dapp/src/hooks/useWalletToast.ts +++ b/dapp/src/hooks/useWalletToast.ts @@ -1,15 +1,14 @@ import { useCallback, useEffect } from "react" import { ONE_SEC_IN_MILLISECONDS } from "#/constants" -import { logPromiseFailure } from "#/utils" -import { TOAST_TYPES } from "#/types" -import { TOASTS } from "#/components/shared/toasts" +import { capitalizeFirstLetter, logPromiseFailure } from "#/utils" +import { WalletErrorToast } from "#/components/shared/toasts" import { useToast } from "./useToast" import { useWallet } from "./useWallet" import { useTimeout } from "./useTimeout" const WALLET_ERROR_TOAST_ID = { - bitcoin: TOAST_TYPES.BITCOIN_WALLET_NOT_CONNECTED_ERROR, - ethereum: TOAST_TYPES.ETHEREUM_WALLET_NOT_CONNECTED_ERROR, + bitcoin: "bitcoin-wallet-error", + ethereum: "ethereum-wallet-error", } export function useWalletToast( @@ -30,12 +29,16 @@ export function useWalletToast( const handleOpen = useCallback( () => - open( - TOASTS[toastId]({ - onClick: handleConnect, - }), - ), - [handleConnect, open, toastId], + open({ + id: toastId, + render: ({ onClose }) => + WalletErrorToast({ + title: capitalizeFirstLetter(`${type} wallet is not connected`), + onClose, + onClick: handleConnect, + }), + }), + [handleConnect, open, toastId, type], ) useTimeout(handleOpen, delay) diff --git a/dapp/src/pages/ActivityPage/ActivityDetails.tsx b/dapp/src/pages/ActivityPage/ActivityDetails.tsx index 05f82fd82..f6feb5f76 100644 --- a/dapp/src/pages/ActivityPage/ActivityDetails.tsx +++ b/dapp/src/pages/ActivityPage/ActivityDetails.tsx @@ -10,7 +10,7 @@ import { Flex, Text, } from "@chakra-ui/react" -import { capitalize } from "#/utils" +import { capitalizeFirstLetter } from "#/utils" import ActivityProgress from "#/assets/images/activity-progress.png" import { LocationState } from "#/types" import StatusInfo from "#/components/shared/StatusInfo" @@ -47,7 +47,7 @@ function ActivityDetails() { - {capitalize(activity.action)} + {capitalizeFirstLetter(activity.action)} +export const capitalizeFirstLetter = (text: string): string => text[0].toUpperCase() + text.slice(1) From e5f8eca33287c3c35a18dddbf5be3d8215a66dbf Mon Sep 17 00:00:00 2001 From: Karolina Kosiorowska Date: Tue, 2 Apr 2024 12:06:47 +0200 Subject: [PATCH 31/40] Show wallet error toast from the top level --- dapp/src/components/Header/ConnectWallet.tsx | 5 +---- dapp/src/hooks/index.ts | 2 +- dapp/src/hooks/useInitApp.ts | 3 +++ .../hooks/{useWalletToast.ts => useShowWalletErrorToast.ts} | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) rename dapp/src/hooks/{useWalletToast.ts => useShowWalletErrorToast.ts} (96%) diff --git a/dapp/src/components/Header/ConnectWallet.tsx b/dapp/src/components/Header/ConnectWallet.tsx index fc60ca3d4..1a76f97c3 100644 --- a/dapp/src/components/Header/ConnectWallet.tsx +++ b/dapp/src/components/Header/ConnectWallet.tsx @@ -1,7 +1,7 @@ import React from "react" import { Button, HStack, Icon, Tooltip } from "@chakra-ui/react" import { Account } from "@ledgerhq/wallet-api-client" -import { useWalletToast, useWallet } from "#/hooks" +import { useWallet } from "#/hooks" import { CurrencyBalance } from "#/components/shared/CurrencyBalance" import { TextMd } from "#/components/shared/Typography" import { Bitcoin, EthereumIcon } from "#/assets/icons" @@ -31,9 +31,6 @@ export default function ConnectWallet() { ethereum: { account: ethAccount, requestAccount: requestEthereumAccount }, } = useWallet() - useWalletToast("ethereum") - useWalletToast("bitcoin") - const customDataBtcAccount = getCustomDataByAccount(btcAccount) const customDataEthAccount = getCustomDataByAccount(ethAccount) diff --git a/dapp/src/hooks/index.ts b/dapp/src/hooks/index.ts index 2a1408832..2ce001d3d 100644 --- a/dapp/src/hooks/index.ts +++ b/dapp/src/hooks/index.ts @@ -19,5 +19,5 @@ export * from "./useDepositTelemetry" export * from "./useFetchBTCPriceUSD" export * from "./useToast" export * from "./useWallet" -export * from "./useWalletToast" +export * from "./useShowWalletErrorToast" export * from "./useTimeout" diff --git a/dapp/src/hooks/useInitApp.ts b/dapp/src/hooks/useInitApp.ts index bfa07283e..91a62066c 100644 --- a/dapp/src/hooks/useInitApp.ts +++ b/dapp/src/hooks/useInitApp.ts @@ -1,6 +1,7 @@ import { useSentry } from "./sentry" import { useInitializeAcreSdk } from "./useInitializeAcreSdk" import { useFetchBTCPriceUSD } from "./useFetchBTCPriceUSD" +import { useShowWalletErrorToast } from "./useShowWalletErrorToast" export function useInitApp() { // TODO: Let's uncomment when dark mode is ready @@ -8,4 +9,6 @@ export function useInitApp() { useSentry() useInitializeAcreSdk() useFetchBTCPriceUSD() + useShowWalletErrorToast("ethereum") + useShowWalletErrorToast("bitcoin") } diff --git a/dapp/src/hooks/useWalletToast.ts b/dapp/src/hooks/useShowWalletErrorToast.ts similarity index 96% rename from dapp/src/hooks/useWalletToast.ts rename to dapp/src/hooks/useShowWalletErrorToast.ts index 9e01c2b37..610f50731 100644 --- a/dapp/src/hooks/useWalletToast.ts +++ b/dapp/src/hooks/useShowWalletErrorToast.ts @@ -11,7 +11,7 @@ const WALLET_ERROR_TOAST_ID = { ethereum: "ethereum-wallet-error", } -export function useWalletToast( +export function useShowWalletErrorToast( type: "bitcoin" | "ethereum", delay = ONE_SEC_IN_MILLISECONDS, ) { From 4c340232a87375e46594ae57574de6627a61909e Mon Sep 17 00:00:00 2001 From: Karolina Kosiorowska Date: Tue, 2 Apr 2024 13:02:26 +0200 Subject: [PATCH 32/40] Reorganizing toasts components Actually, defined toast components are not part of the shared components. Only the base component should be there. Let's update the file locations of these to the correct levels. --- .../ActiveStakingStep/DepositBTCModal.tsx | 6 +++--- .../DepositTransactionErrorToast.tsx | 19 +++++++++++++++++++ .../ActiveStakingStep/SignMessageModal.tsx | 6 ++---- .../SigningMessageErrorToast.tsx | 19 +++++++++++++++++++ .../{shared/toasts => }/WalletErrorToast.tsx | 13 +++++++++---- .../{alerts/ToastBase.tsx => Toast.tsx} | 13 ++++++++----- dapp/src/components/shared/alerts/index.ts | 1 - .../toasts/DepositTransactionErrorToast.tsx | 19 ------------------- .../toasts/MessageSigningErrorToast.tsx | 15 --------------- dapp/src/components/shared/toasts/index.ts | 3 --- dapp/src/hooks/useShowWalletErrorToast.ts | 9 +++------ 11 files changed, 63 insertions(+), 60 deletions(-) create mode 100644 dapp/src/components/TransactionModal/ActiveStakingStep/DepositTransactionErrorToast.tsx create mode 100644 dapp/src/components/TransactionModal/ActiveStakingStep/SigningMessageErrorToast.tsx rename dapp/src/components/{shared/toasts => }/WalletErrorToast.tsx (57%) rename dapp/src/components/shared/{alerts/ToastBase.tsx => Toast.tsx} (64%) delete mode 100644 dapp/src/components/shared/toasts/DepositTransactionErrorToast.tsx delete mode 100644 dapp/src/components/shared/toasts/MessageSigningErrorToast.tsx delete mode 100644 dapp/src/components/shared/toasts/index.ts diff --git a/dapp/src/components/TransactionModal/ActiveStakingStep/DepositBTCModal.tsx b/dapp/src/components/TransactionModal/ActiveStakingStep/DepositBTCModal.tsx index 649da9e3a..4308a5097 100644 --- a/dapp/src/components/TransactionModal/ActiveStakingStep/DepositBTCModal.tsx +++ b/dapp/src/components/TransactionModal/ActiveStakingStep/DepositBTCModal.tsx @@ -13,10 +13,10 @@ import { TextMd } from "#/components/shared/Typography" import { logPromiseFailure } from "#/utils" import { PROCESS_STATUSES } from "#/types" import { CardAlert } from "#/components/shared/alerts" -import { DepositTransactionErrorToast } from "#/components/shared/toasts" import StakingStepsModalContent from "./StakingStepsModalContent" - -const TOAST_ID = "deposit-transaction-error" +import DepositTransactionErrorToast, { + TOAST_ID, +} from "./DepositTransactionErrorToast" export default function DepositBTCModal() { const { ethAccount } = useWalletContext() diff --git a/dapp/src/components/TransactionModal/ActiveStakingStep/DepositTransactionErrorToast.tsx b/dapp/src/components/TransactionModal/ActiveStakingStep/DepositTransactionErrorToast.tsx new file mode 100644 index 000000000..79d5dfe39 --- /dev/null +++ b/dapp/src/components/TransactionModal/ActiveStakingStep/DepositTransactionErrorToast.tsx @@ -0,0 +1,19 @@ +import React from "react" +import Toast from "#/components/shared/Toast" + +export const TOAST_ID = "deposit-transaction-error" + +export default function DepositTransactionErrorToast({ + onClose, +}: { + onClose: () => void +}) { + return ( + + ) +} diff --git a/dapp/src/components/TransactionModal/ActiveStakingStep/SignMessageModal.tsx b/dapp/src/components/TransactionModal/ActiveStakingStep/SignMessageModal.tsx index 7389990db..e3565a7a5 100644 --- a/dapp/src/components/TransactionModal/ActiveStakingStep/SignMessageModal.tsx +++ b/dapp/src/components/TransactionModal/ActiveStakingStep/SignMessageModal.tsx @@ -8,10 +8,8 @@ import { import { logPromiseFailure } from "#/utils" import { PROCESS_STATUSES } from "#/types" import { ReceiveSTBTCAlert } from "#/components/shared/alerts" -import { MessageSigningErrorToast } from "#/components/shared/toasts" import StakingStepsModalContent from "./StakingStepsModalContent" - -const TOAST_ID = "signing-error" +import SigningMessageErrorToast, { TOAST_ID } from "./SigningMessageErrorToast" export default function SignMessageModal() { const { goNext, setStatus } = useModalFlowContext() @@ -31,7 +29,7 @@ export default function SignMessageModal() { const onSignMessageError = useCallback(() => { openToast({ id: TOAST_ID, - render: MessageSigningErrorToast, + render: SigningMessageErrorToast, }) setButtonText("Try again") }, [openToast]) diff --git a/dapp/src/components/TransactionModal/ActiveStakingStep/SigningMessageErrorToast.tsx b/dapp/src/components/TransactionModal/ActiveStakingStep/SigningMessageErrorToast.tsx new file mode 100644 index 000000000..659a8d190 --- /dev/null +++ b/dapp/src/components/TransactionModal/ActiveStakingStep/SigningMessageErrorToast.tsx @@ -0,0 +1,19 @@ +import React from "react" +import Toast from "#/components/shared/Toast" + +export const TOAST_ID = "signing-error" + +export default function SigningMessageErrorToast({ + onClose, +}: { + onClose: () => void +}) { + return ( + + ) +} diff --git a/dapp/src/components/shared/toasts/WalletErrorToast.tsx b/dapp/src/components/WalletErrorToast.tsx similarity index 57% rename from dapp/src/components/shared/toasts/WalletErrorToast.tsx rename to dapp/src/components/WalletErrorToast.tsx index 1d30869f8..dbac73f28 100644 --- a/dapp/src/components/shared/toasts/WalletErrorToast.tsx +++ b/dapp/src/components/WalletErrorToast.tsx @@ -1,8 +1,13 @@ import React from "react" import { Flex, Button } from "@chakra-ui/react" -import { ToastBase } from "../alerts" +import Toast from "./shared/Toast" -export function WalletErrorToast({ +export const WALLET_ERROR_TOAST_ID = { + bitcoin: "bitcoin-wallet-error", + ethereum: "ethereum-wallet-error", +} + +export default function WalletErrorToast({ title, onClick, onClose, @@ -12,12 +17,12 @@ export function WalletErrorToast({ onClose: () => void }) { return ( - + - + ) } diff --git a/dapp/src/components/shared/alerts/ToastBase.tsx b/dapp/src/components/shared/Toast.tsx similarity index 64% rename from dapp/src/components/shared/alerts/ToastBase.tsx rename to dapp/src/components/shared/Toast.tsx index 98cd45e6a..092163fa7 100644 --- a/dapp/src/components/shared/alerts/ToastBase.tsx +++ b/dapp/src/components/shared/Toast.tsx @@ -1,24 +1,27 @@ import React from "react" import { HStack } from "@chakra-ui/react" -import { Alert, AlertProps } from "./Alert" -import { TextSm } from "../Typography" +import { Alert, AlertProps } from "./alerts" +import { TextSm } from "./Typography" -type ToastBaseProps = { +type ToastProps = { title: string + subtitle?: string } & Omit & { onClose: () => void } -export function ToastBase({ +export default function Toast({ title, + subtitle, children, onClose, ...props -}: ToastBaseProps) { +}: ToastProps) { return ( {title} + {subtitle && {subtitle}} {children} diff --git a/dapp/src/components/shared/alerts/index.ts b/dapp/src/components/shared/alerts/index.ts index c9cbfceff..79555f74d 100644 --- a/dapp/src/components/shared/alerts/index.ts +++ b/dapp/src/components/shared/alerts/index.ts @@ -1,4 +1,3 @@ export * from "./Alert" export * from "./CardAlert" export * from "./ReceiveSTBTCAlert" -export * from "./ToastBase" diff --git a/dapp/src/components/shared/toasts/DepositTransactionErrorToast.tsx b/dapp/src/components/shared/toasts/DepositTransactionErrorToast.tsx deleted file mode 100644 index 59c9f2332..000000000 --- a/dapp/src/components/shared/toasts/DepositTransactionErrorToast.tsx +++ /dev/null @@ -1,19 +0,0 @@ -import React from "react" -import { TextSm } from "../Typography" -import { ToastBase } from "../alerts" - -export function DepositTransactionErrorToast({ - onClose, -}: { - onClose: () => void -}) { - return ( - - Please try again. - - ) -} diff --git a/dapp/src/components/shared/toasts/MessageSigningErrorToast.tsx b/dapp/src/components/shared/toasts/MessageSigningErrorToast.tsx deleted file mode 100644 index c9bebd0ef..000000000 --- a/dapp/src/components/shared/toasts/MessageSigningErrorToast.tsx +++ /dev/null @@ -1,15 +0,0 @@ -import React from "react" -import { TextSm } from "../Typography" -import { ToastBase } from "../alerts" - -export function MessageSigningErrorToast({ onClose }: { onClose: () => void }) { - return ( - - Please try again. - - ) -} diff --git a/dapp/src/components/shared/toasts/index.ts b/dapp/src/components/shared/toasts/index.ts deleted file mode 100644 index 9b997f38e..000000000 --- a/dapp/src/components/shared/toasts/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -export * from "./MessageSigningErrorToast" -export * from "./DepositTransactionErrorToast" -export * from "./WalletErrorToast" diff --git a/dapp/src/hooks/useShowWalletErrorToast.ts b/dapp/src/hooks/useShowWalletErrorToast.ts index 610f50731..3bbbbbac7 100644 --- a/dapp/src/hooks/useShowWalletErrorToast.ts +++ b/dapp/src/hooks/useShowWalletErrorToast.ts @@ -1,16 +1,13 @@ import { useCallback, useEffect } from "react" import { ONE_SEC_IN_MILLISECONDS } from "#/constants" import { capitalizeFirstLetter, logPromiseFailure } from "#/utils" -import { WalletErrorToast } from "#/components/shared/toasts" +import WalletErrorToast, { + WALLET_ERROR_TOAST_ID, +} from "#/components/WalletErrorToast" import { useToast } from "./useToast" import { useWallet } from "./useWallet" import { useTimeout } from "./useTimeout" -const WALLET_ERROR_TOAST_ID = { - bitcoin: "bitcoin-wallet-error", - ethereum: "ethereum-wallet-error", -} - export function useShowWalletErrorToast( type: "bitcoin" | "ethereum", delay = ONE_SEC_IN_MILLISECONDS, From 976a466c49039be0e08c3dbd9bb73e3fdc7d01ea Mon Sep 17 00:00:00 2001 From: Karolina Kosiorowska Date: Tue, 2 Apr 2024 14:16:44 +0200 Subject: [PATCH 33/40] Add `@tabler/icons-react` package --- dapp/package.json | 1 + pnpm-lock.yaml | 16 ++++++++++++++++ 2 files changed, 17 insertions(+) diff --git a/dapp/package.json b/dapp/package.json index f93626084..0504d3ed5 100644 --- a/dapp/package.json +++ b/dapp/package.json @@ -24,6 +24,7 @@ "@reduxjs/toolkit": "^2.2.0", "@sentry/react": "^7.98.0", "@sentry/types": "^7.102.0", + "@tabler/icons-react": "^3.1.0", "@tanstack/react-table": "^8.11.3", "axios": "^1.6.7", "ethers": "^6.10.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 055e028ec..60946e42d 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -159,6 +159,9 @@ importers: '@sentry/types': specifier: ^7.102.0 version: 7.102.0 + '@tabler/icons-react': + specifier: ^3.1.0 + version: 3.1.0(react@18.2.0) '@tanstack/react-table': specifier: ^8.11.3 version: 8.11.7(react-dom@18.2.0)(react@18.2.0) @@ -6430,6 +6433,19 @@ packages: dependencies: defer-to-connect: 2.0.1 + /@tabler/icons-react@3.1.0(react@18.2.0): + resolution: {integrity: sha512-k/WTlax2vbj/LpxvaJ+BmaLAAhVUgyLj4Ftgaczz66tUSNzqrAZXCFdOU7cRMYPNVBqyqE2IdQd2rzzhDEJvkw==} + peerDependencies: + react: '>= 16' + dependencies: + '@tabler/icons': 3.1.0 + react: 18.2.0 + dev: false + + /@tabler/icons@3.1.0: + resolution: {integrity: sha512-CpZGyS1IVJKFcv88yZ2sYZIpWWhQ6oy76BQKQ5SF0fGgOqgyqKdBGG/YGyyMW632on37MX7VqQIMTzN/uQqmFg==} + dev: false + /@tanstack/react-table@8.11.7(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-ZbzfMkLjxUTzNPBXJYH38pv2VpC9WUA+Qe5USSHEBz0dysDTv4z/ARI3csOed/5gmlmrPzVUN3UXGuUMbod3Jg==} engines: {node: '>=12'} From 39850ceb5ea4557c0ff5f10641b73ce0ec4935a3 Mon Sep 17 00:00:00 2001 From: Karolina Kosiorowska Date: Tue, 2 Apr 2024 14:21:34 +0200 Subject: [PATCH 34/40] Use icons for alert from `@tabler/icons-react` --- dapp/src/assets/icons/AlertError.tsx | 17 ----------------- dapp/src/assets/icons/AlertInfo.tsx | 17 ----------------- dapp/src/assets/icons/index.ts | 2 -- .../shared/TokenBalanceInput/index.tsx | 4 ++-- dapp/src/components/shared/alerts/Alert.tsx | 9 ++++----- 5 files changed, 6 insertions(+), 43 deletions(-) delete mode 100644 dapp/src/assets/icons/AlertError.tsx delete mode 100644 dapp/src/assets/icons/AlertInfo.tsx diff --git a/dapp/src/assets/icons/AlertError.tsx b/dapp/src/assets/icons/AlertError.tsx deleted file mode 100644 index 6fb513e5b..000000000 --- a/dapp/src/assets/icons/AlertError.tsx +++ /dev/null @@ -1,17 +0,0 @@ -import React from "react" -import { createIcon } from "@chakra-ui/react" - -export const AlertError = createIcon({ - displayName: "AlertError", - viewBox: "0 0 24 25", - path: [ - , - ], -}) diff --git a/dapp/src/assets/icons/AlertInfo.tsx b/dapp/src/assets/icons/AlertInfo.tsx deleted file mode 100644 index 2eda75539..000000000 --- a/dapp/src/assets/icons/AlertInfo.tsx +++ /dev/null @@ -1,17 +0,0 @@ -import React from "react" -import { createIcon } from "@chakra-ui/react" - -export const AlertInfo = createIcon({ - displayName: "AlertInfo", - viewBox: "0 0 24 24", - path: [ - , - ], -}) diff --git a/dapp/src/assets/icons/index.ts b/dapp/src/assets/icons/index.ts index 5be87f41a..f6931b182 100644 --- a/dapp/src/assets/icons/index.ts +++ b/dapp/src/assets/icons/index.ts @@ -7,8 +7,6 @@ export * from "./ArrowRight" export * from "./AcreLogo" export * from "./ConnectBTCAccount" export * from "./ConnectETHAccount" -export * from "./AlertInfo" -export * from "./AlertError" export * from "./stBTC" export * from "./BTC" export * from "./ShieldPlus" diff --git a/dapp/src/components/shared/TokenBalanceInput/index.tsx b/dapp/src/components/shared/TokenBalanceInput/index.tsx index de55b64dd..f502bd3b1 100644 --- a/dapp/src/components/shared/TokenBalanceInput/index.tsx +++ b/dapp/src/components/shared/TokenBalanceInput/index.tsx @@ -17,8 +17,8 @@ import { getCurrencyByType, userAmountToBigInt, } from "#/utils" -import { AlertInfo } from "#/assets/icons" import { CurrencyType } from "#/types" +import { IconInfoCircle } from "@tabler/icons-react" import NumberFormatInput, { NumberFormatInputValues, } from "../NumberFormatInput" @@ -48,7 +48,7 @@ function HelperErrorText({ if (helperText) { return ( - + {helperText} ) diff --git a/dapp/src/components/shared/alerts/Alert.tsx b/dapp/src/components/shared/alerts/Alert.tsx index 7f06f2201..b22f08562 100644 --- a/dapp/src/components/shared/alerts/Alert.tsx +++ b/dapp/src/components/shared/alerts/Alert.tsx @@ -1,17 +1,16 @@ import React from "react" import { Alert as ChakraAlert, - AlertIcon, AlertProps as ChakraAlertProps, Icon, CloseButton, HStack, } from "@chakra-ui/react" -import { AlertError, AlertInfo } from "#/assets/icons" +import { IconInfoCircle, IconExclamationCircle } from "@tabler/icons-react" const ICONS = { - info: AlertInfo, - error: AlertError, + info: IconInfoCircle, + error: IconExclamationCircle, } type AlertStatus = keyof typeof ICONS @@ -37,7 +36,7 @@ export function Alert({ return ( {withIcon && status && ( - + )} {children} From 1107ecfa1d3a3720664ef2260c7c4d41eef1e35b Mon Sep 17 00:00:00 2001 From: Karolina Kosiorowska Date: Mon, 8 Apr 2024 13:50:31 +0200 Subject: [PATCH 35/40] Create a special hook for init global toasts --- dapp/src/hooks/index.ts | 3 +-- dapp/src/hooks/toasts/index.ts | 3 +++ dapp/src/hooks/toasts/useInitGlobalToasts.ts | 6 ++++++ dapp/src/hooks/{ => toasts}/useShowWalletErrorToast.ts | 4 ++-- dapp/src/hooks/{ => toasts}/useToast.ts | 0 dapp/src/hooks/useInitApp.ts | 5 ++--- 6 files changed, 14 insertions(+), 7 deletions(-) create mode 100644 dapp/src/hooks/toasts/index.ts create mode 100644 dapp/src/hooks/toasts/useInitGlobalToasts.ts rename dapp/src/hooks/{ => toasts}/useShowWalletErrorToast.ts (93%) rename dapp/src/hooks/{ => toasts}/useToast.ts (100%) diff --git a/dapp/src/hooks/index.ts b/dapp/src/hooks/index.ts index 7d3c2a063..08821f731 100644 --- a/dapp/src/hooks/index.ts +++ b/dapp/src/hooks/index.ts @@ -1,4 +1,5 @@ export * from "./store" +export * from "./toasts" export * from "./useDetectThemeMode" export * from "./useRequestBitcoinAccount" export * from "./useRequestEthereumAccount" @@ -17,8 +18,6 @@ export * from "./useInitApp" export * from "./useCurrencyConversion" export * from "./useDepositTelemetry" export * from "./useFetchBTCPriceUSD" -export * from "./useToast" export * from "./useWallet" -export * from "./useShowWalletErrorToast" export * from "./useTimeout" export * from "./useSize" diff --git a/dapp/src/hooks/toasts/index.ts b/dapp/src/hooks/toasts/index.ts new file mode 100644 index 000000000..c9a093219 --- /dev/null +++ b/dapp/src/hooks/toasts/index.ts @@ -0,0 +1,3 @@ +export * from "./useInitGlobalToasts" +export * from "./useShowWalletErrorToast" +export * from "./useToast" diff --git a/dapp/src/hooks/toasts/useInitGlobalToasts.ts b/dapp/src/hooks/toasts/useInitGlobalToasts.ts new file mode 100644 index 000000000..0fec6ef12 --- /dev/null +++ b/dapp/src/hooks/toasts/useInitGlobalToasts.ts @@ -0,0 +1,6 @@ +import { useShowWalletErrorToast } from "./useShowWalletErrorToast" + +export function useInitGlobalToasts() { + useShowWalletErrorToast("ethereum") + useShowWalletErrorToast("bitcoin") +} diff --git a/dapp/src/hooks/useShowWalletErrorToast.ts b/dapp/src/hooks/toasts/useShowWalletErrorToast.ts similarity index 93% rename from dapp/src/hooks/useShowWalletErrorToast.ts rename to dapp/src/hooks/toasts/useShowWalletErrorToast.ts index 3bbbbbac7..ae7f89922 100644 --- a/dapp/src/hooks/useShowWalletErrorToast.ts +++ b/dapp/src/hooks/toasts/useShowWalletErrorToast.ts @@ -5,8 +5,8 @@ import WalletErrorToast, { WALLET_ERROR_TOAST_ID, } from "#/components/WalletErrorToast" import { useToast } from "./useToast" -import { useWallet } from "./useWallet" -import { useTimeout } from "./useTimeout" +import { useWallet } from "../useWallet" +import { useTimeout } from "../useTimeout" export function useShowWalletErrorToast( type: "bitcoin" | "ethereum", diff --git a/dapp/src/hooks/useToast.ts b/dapp/src/hooks/toasts/useToast.ts similarity index 100% rename from dapp/src/hooks/useToast.ts rename to dapp/src/hooks/toasts/useToast.ts diff --git a/dapp/src/hooks/useInitApp.ts b/dapp/src/hooks/useInitApp.ts index 91a62066c..e559e6df4 100644 --- a/dapp/src/hooks/useInitApp.ts +++ b/dapp/src/hooks/useInitApp.ts @@ -1,7 +1,7 @@ import { useSentry } from "./sentry" import { useInitializeAcreSdk } from "./useInitializeAcreSdk" import { useFetchBTCPriceUSD } from "./useFetchBTCPriceUSD" -import { useShowWalletErrorToast } from "./useShowWalletErrorToast" +import { useInitGlobalToasts } from "./toasts/useInitGlobalToasts" export function useInitApp() { // TODO: Let's uncomment when dark mode is ready @@ -9,6 +9,5 @@ export function useInitApp() { useSentry() useInitializeAcreSdk() useFetchBTCPriceUSD() - useShowWalletErrorToast("ethereum") - useShowWalletErrorToast("bitcoin") + useInitGlobalToasts() } From 07b035f20dbd0fcb2f755be49e33654ab33e1dde Mon Sep 17 00:00:00 2001 From: Karolina Kosiorowska Date: Mon, 8 Apr 2024 14:15:01 +0200 Subject: [PATCH 36/40] Rename methods for `useToast` --- .../ActiveStakingStep/DepositBTCModal.tsx | 2 +- .../ActiveStakingStep/SignMessageModal.tsx | 2 +- .../src/hooks/toasts/useShowWalletErrorToast.ts | 10 +++++----- dapp/src/hooks/toasts/useToast.ts | 17 +++++++++-------- 4 files changed, 16 insertions(+), 15 deletions(-) diff --git a/dapp/src/components/TransactionModal/ActiveStakingStep/DepositBTCModal.tsx b/dapp/src/components/TransactionModal/ActiveStakingStep/DepositBTCModal.tsx index 4308a5097..dc8424ae0 100644 --- a/dapp/src/components/TransactionModal/ActiveStakingStep/DepositBTCModal.tsx +++ b/dapp/src/components/TransactionModal/ActiveStakingStep/DepositBTCModal.tsx @@ -24,7 +24,7 @@ export default function DepositBTCModal() { const { setStatus } = useModalFlowContext() const { btcAddress, depositReceipt, stake } = useStakeFlowContext() const depositTelemetry = useDepositTelemetry() - const { close: closeToast, open: openToast } = useToast() + const { closeToast, openToast } = useToast() const [isLoading, setIsLoading] = useState(false) const [buttonText, setButtonText] = useState("Deposit BTC") diff --git a/dapp/src/components/TransactionModal/ActiveStakingStep/SignMessageModal.tsx b/dapp/src/components/TransactionModal/ActiveStakingStep/SignMessageModal.tsx index e3565a7a5..6c8d5bba0 100644 --- a/dapp/src/components/TransactionModal/ActiveStakingStep/SignMessageModal.tsx +++ b/dapp/src/components/TransactionModal/ActiveStakingStep/SignMessageModal.tsx @@ -15,7 +15,7 @@ export default function SignMessageModal() { const { goNext, setStatus } = useModalFlowContext() const { signMessage } = useStakeFlowContext() const [buttonText, setButtonText] = useState("Sign now") - const { close: closeToast, open: openToast } = useToast() + const { closeToast, openToast } = useToast() useEffect(() => { setStatus(PROCESS_STATUSES.PENDING) diff --git a/dapp/src/hooks/toasts/useShowWalletErrorToast.ts b/dapp/src/hooks/toasts/useShowWalletErrorToast.ts index ae7f89922..33ed0e53f 100644 --- a/dapp/src/hooks/toasts/useShowWalletErrorToast.ts +++ b/dapp/src/hooks/toasts/useShowWalletErrorToast.ts @@ -15,7 +15,7 @@ export function useShowWalletErrorToast( const { [type]: { account, requestAccount }, } = useWallet() - const { close, open } = useToast() + const { closeToast, openToast } = useToast() const toastId = WALLET_ERROR_TOAST_ID[type] @@ -26,7 +26,7 @@ export function useShowWalletErrorToast( const handleOpen = useCallback( () => - open({ + openToast({ id: toastId, render: ({ onClose }) => WalletErrorToast({ @@ -35,7 +35,7 @@ export function useShowWalletErrorToast( onClick: handleConnect, }), }), - [handleConnect, open, toastId, type], + [handleConnect, openToast, toastId, type], ) useTimeout(handleOpen, delay) @@ -43,6 +43,6 @@ export function useShowWalletErrorToast( useEffect(() => { if (!account) return - close(toastId) - }, [account, close, toastId]) + closeToast(toastId) + }, [account, closeToast, toastId]) } diff --git a/dapp/src/hooks/toasts/useToast.ts b/dapp/src/hooks/toasts/useToast.ts index 60dbee49d..b38f1e098 100644 --- a/dapp/src/hooks/toasts/useToast.ts +++ b/dapp/src/hooks/toasts/useToast.ts @@ -16,7 +16,7 @@ export function useToast() { [toast], ) - const open = useCallback( + const openToast = useCallback( ({ id, ...options }: UseToastOptions) => { if (!id) { overriddenToast(options) @@ -30,11 +30,12 @@ export function useToast() { [overriddenToast, toast], ) - return useMemo( - () => ({ - ...Object.assign(overriddenToast, toast), - open, - }), - [overriddenToast, toast, open], - ) + return useMemo(() => { + const { close: closeToast, ...rest } = Object.assign(overriddenToast, toast) + return { + ...rest, + openToast, + closeToast, + } + }, [overriddenToast, toast, openToast]) } From 6fc58a31f00d598877f0afbe4a093343c14eb5c9 Mon Sep 17 00:00:00 2001 From: Karolina Kosiorowska Date: Mon, 8 Apr 2024 16:09:36 +0200 Subject: [PATCH 37/40] Save the toast id globally along with the correct component --- .../ActiveStakingStep/DepositBTCModal.tsx | 12 +++++--- .../ActiveStakingStep/SignMessageModal.tsx | 8 +++-- .../DepositTransactionErrorToast.tsx | 6 ++-- .../SigningMessageErrorToast.tsx | 10 ++----- .../{ => toasts}/WalletErrorToast.tsx | 9 ++---- dapp/src/components/toasts/index.ts | 3 ++ .../hooks/toasts/useShowWalletErrorToast.ts | 29 +++++++++++++------ dapp/src/types/index.ts | 1 + dapp/src/types/toast.ts | 23 +++++++++++++++ 9 files changed, 66 insertions(+), 35 deletions(-) rename dapp/src/components/{TransactionModal/ActiveStakingStep => toasts}/DepositTransactionErrorToast.tsx (61%) rename dapp/src/components/{TransactionModal/ActiveStakingStep => toasts}/SigningMessageErrorToast.tsx (50%) rename dapp/src/components/{ => toasts}/WalletErrorToast.tsx (70%) create mode 100644 dapp/src/components/toasts/index.ts create mode 100644 dapp/src/types/toast.ts diff --git a/dapp/src/components/TransactionModal/ActiveStakingStep/DepositBTCModal.tsx b/dapp/src/components/TransactionModal/ActiveStakingStep/DepositBTCModal.tsx index dc8424ae0..d2e7d87b5 100644 --- a/dapp/src/components/TransactionModal/ActiveStakingStep/DepositBTCModal.tsx +++ b/dapp/src/components/TransactionModal/ActiveStakingStep/DepositBTCModal.tsx @@ -13,10 +13,11 @@ import { TextMd } from "#/components/shared/Typography" import { logPromiseFailure } from "#/utils" import { PROCESS_STATUSES } from "#/types" import { CardAlert } from "#/components/shared/alerts" +import { TOASTS, TOAST_IDS } from "#/types/toast" import StakingStepsModalContent from "./StakingStepsModalContent" -import DepositTransactionErrorToast, { - TOAST_ID, -} from "./DepositTransactionErrorToast" + +const TOAST_ID = TOAST_IDS.DEPOSIT_TRANSACTION_ERROR +const TOAST = TOASTS[TOAST_ID] export default function DepositBTCModal() { const { ethAccount } = useWalletContext() @@ -53,7 +54,10 @@ export default function DepositBTCModal() { }, [closeToast, setStatus, handleStake]) const showError = useCallback(() => { - openToast({ id: TOAST_ID, render: DepositTransactionErrorToast }) + openToast({ + id: TOAST_ID, + render: TOAST, + }) setButtonText("Try again") }, [openToast]) diff --git a/dapp/src/components/TransactionModal/ActiveStakingStep/SignMessageModal.tsx b/dapp/src/components/TransactionModal/ActiveStakingStep/SignMessageModal.tsx index 6c8d5bba0..37bba6883 100644 --- a/dapp/src/components/TransactionModal/ActiveStakingStep/SignMessageModal.tsx +++ b/dapp/src/components/TransactionModal/ActiveStakingStep/SignMessageModal.tsx @@ -6,10 +6,12 @@ import { useToast, } from "#/hooks" import { logPromiseFailure } from "#/utils" -import { PROCESS_STATUSES } from "#/types" +import { PROCESS_STATUSES, TOASTS, TOAST_IDS } from "#/types" import { ReceiveSTBTCAlert } from "#/components/shared/alerts" import StakingStepsModalContent from "./StakingStepsModalContent" -import SigningMessageErrorToast, { TOAST_ID } from "./SigningMessageErrorToast" + +const TOAST_ID = TOAST_IDS.SIGNING_ERROR +const TOAST = TOASTS[TOAST_ID] export default function SignMessageModal() { const { goNext, setStatus } = useModalFlowContext() @@ -29,7 +31,7 @@ export default function SignMessageModal() { const onSignMessageError = useCallback(() => { openToast({ id: TOAST_ID, - render: SigningMessageErrorToast, + render: TOAST, }) setButtonText("Try again") }, [openToast]) diff --git a/dapp/src/components/TransactionModal/ActiveStakingStep/DepositTransactionErrorToast.tsx b/dapp/src/components/toasts/DepositTransactionErrorToast.tsx similarity index 61% rename from dapp/src/components/TransactionModal/ActiveStakingStep/DepositTransactionErrorToast.tsx rename to dapp/src/components/toasts/DepositTransactionErrorToast.tsx index 79d5dfe39..6a2dce775 100644 --- a/dapp/src/components/TransactionModal/ActiveStakingStep/DepositTransactionErrorToast.tsx +++ b/dapp/src/components/toasts/DepositTransactionErrorToast.tsx @@ -1,9 +1,7 @@ import React from "react" -import Toast from "#/components/shared/Toast" +import Toast from "../shared/Toast" -export const TOAST_ID = "deposit-transaction-error" - -export default function DepositTransactionErrorToast({ +export function DepositTransactionErrorToast({ onClose, }: { onClose: () => void diff --git a/dapp/src/components/TransactionModal/ActiveStakingStep/SigningMessageErrorToast.tsx b/dapp/src/components/toasts/SigningMessageErrorToast.tsx similarity index 50% rename from dapp/src/components/TransactionModal/ActiveStakingStep/SigningMessageErrorToast.tsx rename to dapp/src/components/toasts/SigningMessageErrorToast.tsx index 659a8d190..2b22cbb1a 100644 --- a/dapp/src/components/TransactionModal/ActiveStakingStep/SigningMessageErrorToast.tsx +++ b/dapp/src/components/toasts/SigningMessageErrorToast.tsx @@ -1,13 +1,7 @@ import React from "react" -import Toast from "#/components/shared/Toast" +import Toast from "../shared/Toast" -export const TOAST_ID = "signing-error" - -export default function SigningMessageErrorToast({ - onClose, -}: { - onClose: () => void -}) { +export function SigningMessageErrorToast({ onClose }: { onClose: () => void }) { return ( logPromiseFailure(requestAccount()), @@ -27,15 +38,15 @@ export function useShowWalletErrorToast( const handleOpen = useCallback( () => openToast({ - id: toastId, + id, render: ({ onClose }) => - WalletErrorToast({ + Component({ title: capitalizeFirstLetter(`${type} wallet is not connected`), onClose, onClick: handleConnect, }), }), - [handleConnect, openToast, toastId, type], + [Component, handleConnect, id, openToast, type], ) useTimeout(handleOpen, delay) @@ -43,6 +54,6 @@ export function useShowWalletErrorToast( useEffect(() => { if (!account) return - closeToast(toastId) - }, [account, closeToast, toastId]) + closeToast(id) + }, [account, closeToast, id]) } diff --git a/dapp/src/types/index.ts b/dapp/src/types/index.ts index 53aaf17ed..f36accc9c 100644 --- a/dapp/src/types/index.ts +++ b/dapp/src/types/index.ts @@ -11,3 +11,4 @@ export * from "./charts" export * from "./activity" export * from "./coingecko" export * from "./size" +export * from "./toast" diff --git a/dapp/src/types/toast.ts b/dapp/src/types/toast.ts new file mode 100644 index 000000000..c4a3fe962 --- /dev/null +++ b/dapp/src/types/toast.ts @@ -0,0 +1,23 @@ +import { ReactNode } from "react" +import { + DepositTransactionErrorToast, + SigningMessageErrorToast, + WalletErrorToast, +} from "#/components/toasts" + +export const TOAST_IDS = { + BITCOIN_WALLET_ERROR: "bitcoin-wallet-error", + ETHEREUM_WALLET_ERROR: "ethereum-wallet-error", + SIGNING_ERROR: "signing-error", + DEPOSIT_TRANSACTION_ERROR: "deposit-transaction-error", +} as const + +export type ToastID = (typeof TOAST_IDS)[keyof typeof TOAST_IDS] + +// eslint-disable-next-line @typescript-eslint/no-explicit-any +export const TOASTS: Record ReactNode> = { + [TOAST_IDS.BITCOIN_WALLET_ERROR]: WalletErrorToast, + [TOAST_IDS.ETHEREUM_WALLET_ERROR]: WalletErrorToast, + [TOAST_IDS.SIGNING_ERROR]: SigningMessageErrorToast, + [TOAST_IDS.DEPOSIT_TRANSACTION_ERROR]: DepositTransactionErrorToast, +} From dc90e68ff7a797649fc935ee5d786173695dcf16 Mon Sep 17 00:00:00 2001 From: Karolina Kosiorowska Date: Wed, 10 Apr 2024 09:33:14 +0200 Subject: [PATCH 38/40] Add description for `Toast` component --- dapp/src/components/shared/Toast.tsx | 3 +++ 1 file changed, 3 insertions(+) diff --git a/dapp/src/components/shared/Toast.tsx b/dapp/src/components/shared/Toast.tsx index 092163fa7..f341cbe8a 100644 --- a/dapp/src/components/shared/Toast.tsx +++ b/dapp/src/components/shared/Toast.tsx @@ -18,6 +18,9 @@ export default function Toast({ ...props }: ToastProps) { return ( + // Chakra UI uses an alert component for toast under the hood. + // Therefore, to define custom styles for the Toast component, + // need to base it on the Alert component. {title} From 56329fb4db0b9dbc373febcac1cc909b00bd3534 Mon Sep 17 00:00:00 2001 From: Karolina Kosiorowska Date: Thu, 11 Apr 2024 08:41:19 +0200 Subject: [PATCH 39/40] `OverviewPage` component update The previous changes have been restored. Updating the visual layer will be done in a separate task/PR. --- dapp/src/pages/OverviewPage/index.tsx | 42 +++++++++------------------ 1 file changed, 14 insertions(+), 28 deletions(-) diff --git a/dapp/src/pages/OverviewPage/index.tsx b/dapp/src/pages/OverviewPage/index.tsx index 08f283856..2a7433b92 100644 --- a/dapp/src/pages/OverviewPage/index.tsx +++ b/dapp/src/pages/OverviewPage/index.tsx @@ -1,10 +1,8 @@ import React from "react" import { Flex, Grid, HStack, Switch } from "@chakra-ui/react" -import { useDocsDrawer, useWalletContext } from "#/hooks" import { TextSm } from "#/components/shared/Typography" import { USD } from "#/constants" import { chakraUnitToPx } from "#/theme/utils" -import ButtonLink from "#/components/shared/ButtonLink" import PositionDetails from "./PositionDetails" import Statistics from "./Statistics" import TransactionHistory from "./TransactionHistory" @@ -12,33 +10,21 @@ import { DocsCard } from "./DocsCard" import { ActivityCarousel } from "./ActivityCarousel" export default function OverviewPage() { - const { onOpen } = useDocsDrawer() - const { isConnected } = useWalletContext() - return ( - - - - {/* TODO: Handle click actions */} - - Show values in {USD.symbol} - - {!isConnected && ( - - Docs - - )} - - {/* TODO: Add animation to show activity bar */} - {isConnected && ( - - - - - )} + + + {/* TODO: Handle click actions */} + + Show values in {USD.symbol} + + + + + + Date: Mon, 15 Apr 2024 17:09:13 +0200 Subject: [PATCH 40/40] Change `zIndex` for toast component Let's set the toast to be in front of the component drawer to avoid confusion. --- dapp/src/theme/utils/zIndices.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dapp/src/theme/utils/zIndices.ts b/dapp/src/theme/utils/zIndices.ts index 4f196f66f..4eda9c324 100644 --- a/dapp/src/theme/utils/zIndices.ts +++ b/dapp/src/theme/utils/zIndices.ts @@ -1,5 +1,5 @@ export const zIndices = { sidebar: 1450, drawer: 1470, - toast: 1410, + toast: 1480, }