Skip to content

Commit

Permalink
Merge branch 'main' into bitcoin-native-experience
Browse files Browse the repository at this point in the history
  • Loading branch information
nkuba authored May 29, 2024
2 parents f0fecf0 + ae598d1 commit 60c1231
Show file tree
Hide file tree
Showing 27 changed files with 447 additions and 75 deletions.
13 changes: 5 additions & 8 deletions dapp/src/assets/icons/animated/ArrowUpRightAnimatedIcon.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from "react"
import { ArrowUpRight } from "#/assets/icons"
import { Box, Icon } from "@chakra-ui/react"
import { Box, BoxProps, Icon } from "@chakra-ui/react"
import { Variants, motion } from "framer-motion"
import { chakraUnitToPx } from "#/theme/utils"

Expand Down Expand Up @@ -34,18 +34,15 @@ const arrowBottomVariants: Variants = {
}),
}

type ArrowUpRightAnimatedIconProps = {
type ArrowUpRightAnimatedIconProps = BoxProps & {
boxSize?: number
color?: string
}

export function ArrowUpRightAnimatedIcon({
boxSize = 4,
color = "brand.400",
}: ArrowUpRightAnimatedIconProps) {
export function ArrowUpRightAnimatedIcon(props: ArrowUpRightAnimatedIconProps) {
const { boxSize = 4, color = "inherit", ...restProps } = props
const boxSizePx = chakraUnitToPx(boxSize)
return (
<Box pos="relative" boxSize={boxSize} overflow="hidden">
<Box pos="relative" boxSize={boxSize} overflow="hidden" {...restProps}>
{[
{ id: "arrow-up", variants: arrowUpVariants },
{ id: "arrow-bottom", variants: arrowBottomVariants },
Expand Down
Binary file added dapp/src/assets/images/empty-state.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ export const PAGINATION_BUTTONS = [
},
]

// TODO: move to top level `utils` directory
export const getPaginationState = (
pageIndex: number,
pageSize: number,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useCallback } from "react"
import React, { useCallback, useEffect } from "react"
import {
useActionFlowTokenAmount,
useAppDispatch,
Expand All @@ -18,7 +18,7 @@ import Spinner from "#/components/shared/Spinner"
import { TextMd } from "#/components/shared/Typography"
import { CardAlert } from "#/components/shared/alerts"
import { ONE_SEC_IN_MILLISECONDS } from "#/constants"
import { setStatus } from "#/store/action-flow"
import { setStatus, setTxHash } from "#/store/action-flow"

const DELAY = ONE_SEC_IN_MILLISECONDS
const TOAST_ID = TOAST_IDS.DEPOSIT_TRANSACTION_ERROR
Expand Down Expand Up @@ -64,11 +64,17 @@ export default function DepositBTCModal() {

const onDepositBTCError = useCallback(() => showError(), [showError])

const { sendBitcoinTransaction } = useDepositBTCTransaction(
const { sendBitcoinTransaction, transactionHash } = useDepositBTCTransaction(
onDepositBTCSuccess,
onDepositBTCError,
)

useEffect(() => {
if (transactionHash) {
dispatch(setTxHash(transactionHash))
}
}, [dispatch, transactionHash])

const handledDepositBTC = useCallback(async () => {
if (!tokenAmount?.amount || !btcAddress || !depositReceipt || !ethAccount)
return
Expand Down
8 changes: 6 additions & 2 deletions dapp/src/components/TransactionModal/ModalContentWrapper.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import React from "react"
import {
useActionFlowStatus,
useActionFlowTokenAmount,
useActionFlowTxHash,
useActionFlowType,
useRequestBitcoinAccount,
useWalletContext,
Expand All @@ -25,6 +26,7 @@ export default function ModalContentWrapper({
const status = useActionFlowStatus()
const type = useActionFlowType()
const tokenAmount = useActionFlowTokenAmount()
const txHash = useActionFlowTxHash()

if (!btcAccount || !isSupportedBTCAddressType(btcAccount.address))
return (
Expand All @@ -39,8 +41,10 @@ export default function ModalContentWrapper({

if (status === PROCESS_STATUSES.LOADING) return <LoadingModal />

if (status === PROCESS_STATUSES.SUCCEEDED)
return <SuccessModal type={type} tokenAmount={tokenAmount} />
if (status === PROCESS_STATUSES.SUCCEEDED && txHash)
return (
<SuccessModal type={type} tokenAmount={tokenAmount} txHash={txHash} />
)

if (status === PROCESS_STATUSES.FAILED) return <ErrorModal type={type} />

Expand Down
42 changes: 35 additions & 7 deletions dapp/src/components/TransactionModal/SuccessModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import React from "react"
import {
Button,
HStack,
Icon,
ModalBody,
ModalFooter,
ModalHeader,
Expand All @@ -11,6 +12,9 @@ import { LoadingSpinnerSuccessIcon } from "#/assets/icons"
import { useModal } from "#/hooks"
import { CurrencyBalanceWithConversion } from "#/components/shared/CurrencyBalanceWithConversion"
import { ACTION_FLOW_TYPES, ActionFlowType, TokenAmount } from "#/types"
import { useNavigate } from "react-router-dom"
import { routerPath } from "#/router/path"
import { IconArrowUpRight } from "@tabler/icons-react"
import { TextMd } from "../shared/Typography"
import Spinner from "../shared/Spinner"
import BlockExplorerLink from "../shared/BlockExplorerLink"
Expand All @@ -19,13 +23,13 @@ const CONTENT: Record<
ActionFlowType,
{
header: string
renderBody: (tokenAmount: TokenAmount) => React.ReactNode
renderBody: (tokenAmount: TokenAmount, txHash: string) => React.ReactNode
footer: string
}
> = {
[ACTION_FLOW_TYPES.STAKE]: {
header: "Deposit received",
renderBody: (tokenAmount) => (
renderBody: (tokenAmount, txHash) => (
<>
<VStack spacing={0}>
<CurrencyBalanceWithConversion
Expand All @@ -42,8 +46,18 @@ const CONTENT: Record<
}}
/>
</VStack>
{/* TODO: Use correct tx hash and update styles */}
<BlockExplorerLink id="" type="transaction" chain="bitcoin" mt={2} />
{/* TODO: Update styles */}
<BlockExplorerLink
id={txHash}
type="transaction"
chain="bitcoin"
mt={2}
>
<HStack gap={1}>
<TextMd fontWeight="semibold">View on Mempool</TextMd>
<Icon as={IconArrowUpRight} color="brand.400" boxSize={5} />
</HStack>
</BlockExplorerLink>
</>
),
footer: "The staking will continue in the background",
Expand All @@ -63,10 +77,16 @@ const CONTENT: Record<
type SuccessModalProps = {
type: ActionFlowType
tokenAmount: TokenAmount
txHash: string
}

export default function SuccessModal({ type, tokenAmount }: SuccessModalProps) {
export default function SuccessModal({
type,
tokenAmount,
txHash,
}: SuccessModalProps) {
const { closeModal } = useModal()
const navigate = useNavigate()

const { header, footer, renderBody } = CONTENT[type]

Expand All @@ -76,11 +96,19 @@ export default function SuccessModal({ type, tokenAmount }: SuccessModalProps) {
<ModalBody gap={10}>
<VStack gap={4}>
<LoadingSpinnerSuccessIcon boxSize={20} />
{renderBody(tokenAmount)}
{renderBody(tokenAmount, txHash)}
</VStack>
</ModalBody>
<ModalFooter pt={0}>
<Button size="lg" width="100%" variant="outline" onClick={closeModal}>
<Button
size="lg"
width="100%"
variant="outline"
onClick={() => {
closeModal()
navigate(routerPath.dashboard)
}}
>
Go to dashboard
</Button>
<HStack spacing={2}>
Expand Down
43 changes: 43 additions & 0 deletions dapp/src/components/shared/Pagination/Pagination.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import React from "react"
import { PaginationContext } from "#/contexts"
import { StackProps, VStack } from "@chakra-ui/react"

export type PaginationProps<T> = Omit<StackProps, "as"> & {
data: T[]
pageSize?: number
defaultPage?: number
}

function Pagination<T>(props: PaginationProps<T>) {
const { data, children, pageSize = 10, defaultPage = 0, ...restProps } = props

const [page, setPage] = React.useState(defaultPage)

const pageData = React.useMemo(() => {
const startIndex = page * pageSize
const endIndex = startIndex + pageSize

return data.slice(startIndex, endIndex)
}, [data, page, pageSize])

const contextValue = React.useMemo(
() => ({
pageSize,
page,
setPage,
totalSize: data.length,
pageData,
}),
[pageSize, page, data, pageData],
)

return (
<PaginationContext.Provider value={contextValue}>
<VStack spacing={6} align="stretch" w="full" {...restProps}>
{children}
</VStack>
</PaginationContext.Provider>
)
}

export default Pagination
43 changes: 43 additions & 0 deletions dapp/src/components/shared/Pagination/PaginationButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import React from "react"
import { Icon, IconButton, IconButtonProps } from "@chakra-ui/react"
import { IconArrowLeft, IconArrowRight } from "@tabler/icons-react"
import { usePagination } from "#/hooks"

type PaginationButtonProps = Omit<IconButtonProps, "aria-label" | "icon"> & {
mode: "previous" | "next"
}

function PaginationButton(props: PaginationButtonProps) {
const { mode, ...restProps } = props
const { page, setPage, totalSize, pageSize } = usePagination()

const handleClick = () => setPage(mode === "next" ? page + 1 : page - 1)
const isDisabled = React.useMemo(
() =>
mode === "next" ? page * pageSize + pageSize >= totalSize : page === 0,
[mode, page, pageSize, totalSize],
)

return (
<IconButton
variant="pagination"
rounded="full"
p={1.5}
boxSize={7}
minW="unset"
icon={
<Icon
as={mode === "next" ? IconArrowRight : IconArrowLeft}
strokeWidth={2}
boxSize={4}
/>
}
aria-label={mode === "next" ? "Next" : "Previous"}
onClick={handleClick}
isDisabled={isDisabled}
{...restProps}
/>
)
}

export default PaginationButton
75 changes: 75 additions & 0 deletions dapp/src/components/shared/Pagination/PaginationPage.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import React from "react"
import { Box, Stack, StackProps, useToken } from "@chakra-ui/react"
import { useSize } from "@chakra-ui/react-use-size"
import { AnimatePresence, Transition, Variants, motion } from "framer-motion"
import { usePagination } from "#/hooks"

const transition: Transition = {
type: "spring",
stiffness: 120,
damping: 16,
mass: 0.85,
}

const variants: Variants = {
enter: ({ direction, spacing }) => ({
x: `calc((100% + ${spacing}) * ${direction === "right" ? 1 : -1})`,
transition,
}),
center: {
x: 0,
transition,
},
exit: ({ direction, spacing }) => ({
x: `calc((100% + ${spacing}) * ${direction === "left" ? 1 : -1})`,
transition,
}),
}

type PaginationPageProps<T> = Omit<StackProps, "children"> & {
children: (pageData: T[]) => React.ReactNode
pageSpacing?: number | string
}

function PaginationPage<T>(props: PaginationPageProps<T>) {
const { children, pageSpacing = 0, ...restProps } = props
const { page, pageData } = usePagination()

const ref = React.useRef<HTMLDivElement>(null)
const { height } = useSize(ref) ?? { height: 0 }

const previousPage = React.useRef<number>(0)
React.useEffect(() => {
previousPage.current = page
}, [page])

const direction = page < previousPage.current ? "left" : "right"
const spacing = useToken("space", pageSpacing, "20%")

return (
<Box as={motion.div} layout animate={{ height, transition }}>
<Box ref={ref}>
<AnimatePresence
mode="popLayout"
custom={{ direction, spacing }}
initial={false}
>
<Stack
as={motion.div}
custom={{ direction, spacing }}
key={page}
variants={variants}
animate="center"
initial="enter"
exit="exit"
{...restProps}
>
{children(pageData as T[])}
</Stack>
</AnimatePresence>
</Box>
</Box>
)
}

export default PaginationPage
28 changes: 28 additions & 0 deletions dapp/src/components/shared/Pagination/PaginationStatus.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import React from "react"
import { TextProps } from "@chakra-ui/react"
import { getPaginationState } from "#/components/TransactionHistory/Table/utils"
import { usePagination } from "#/hooks"
import { TextSm } from "../Typography"

type PaginationStatusProps = TextProps & {
dataLabel?: string
}

function PaginationStatus(props: PaginationStatusProps) {
const { dataLabel = "items", ...restProps } = props
const { page, pageSize, totalSize } = usePagination()

const { rowMin: rangeStart, rowMax: rangeEnd } = getPaginationState(
page,
pageSize,
totalSize,
)

return (
<TextSm {...restProps}>
Showing {rangeStart}-{rangeEnd} out of {totalSize} {dataLabel}
</TextSm>
)
}

export default PaginationStatus
4 changes: 4 additions & 0 deletions dapp/src/components/shared/Pagination/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export { default as Pagination } from "./Pagination"
export { default as PaginationStatus } from "./PaginationStatus"
export { default as PaginationPage } from "./PaginationPage"
export { default as PaginationButton } from "./PaginationButton"
Loading

0 comments on commit 60c1231

Please sign in to comment.