diff --git a/src/app/(mobile-ui)/history/page.tsx b/src/app/(mobile-ui)/history/page.tsx index a44d3bee..f0f6437a 100644 --- a/src/app/(mobile-ui)/history/page.tsx +++ b/src/app/(mobile-ui)/history/page.tsx @@ -1,16 +1,17 @@ 'use client' import { ARBITRUM_ICON } from '@/assets' +import { Button } from '@/components/0_Bruddle' import { useDashboard } from '@/components/Dashboard/useDashboard' +import NoDataEmptyState from '@/components/Global/EmptyStates/NoDataEmptyState' import { ListItemView, TransactionType } from '@/components/Global/ListItemView' -import * as utils from '@/utils' - import NavHeader from '@/components/Global/NavHeader' import { PEANUT_API_URL } from '@/constants' import { useWallet } from '@/hooks/wallet/useWallet' import { IDashboardItem } from '@/interfaces' -import { formatAmountWithSignificantDigits, printableAddress } from '@/utils' +import { formatAmountWithSignificantDigits, formatDate, printableAddress } from '@/utils' import { useInfiniteQuery } from '@tanstack/react-query' +import Link from 'next/link' import { useEffect, useRef, useState } from 'react' const ITEMS_PER_PAGE = 10 @@ -37,7 +38,7 @@ const HistoryPage = () => { const formattedData = pageData.map((data) => { const linkDetails = updatedData.find((item) => item.link === data.link) return { - id: (data.link ?? data.txHash ?? '') + Math.random(), + id: `${data.link ?? data.txHash ?? ''}-${Date.now()}`, transactionType: data.type, amount: `$ ${formatAmountWithSignificantDigits(Number(data.amount), 2)}`, recipientAddress: data.address ? `To ${printableAddress(data.address)}` : '', @@ -106,46 +107,58 @@ const HistoryPage = () => { return (
- -
- {data?.pages.map((page, pageIndex) => ( -
- {data?.pages.map((page, pageIndex) => ( -
- {page.items.map((item) => ( -
- -
- ))} -
- ))} + {!!data?.pages.length ? : null} +
+ {!!data?.pages.length ? ( + data?.pages.map((page, pageIndex) => ( +
+ {page.items.map((item) => ( +
+ +
+ ))} +
+ )) + ) : ( +
+ + + + } + />
- ))} + )}
{isFetchingNextPage &&
Loading more...
} diff --git a/src/app/(mobile-ui)/home/page.tsx b/src/app/(mobile-ui)/home/page.tsx index 757780e3..aa2a7ed7 100644 --- a/src/app/(mobile-ui)/home/page.tsx +++ b/src/app/(mobile-ui)/home/page.tsx @@ -1,7 +1,8 @@ 'use client' -import { ArrowIcon, Button } from '@/components/0_Bruddle' +import { Button } from '@/components/0_Bruddle' import { useToast } from '@/components/0_Bruddle/Toast' +import DirectionalActionButtons from '@/components/Global/DirectionalActionButtons' import WalletHeader from '@/components/Global/WalletHeader' import { WalletCard } from '@/components/Home/WalletCard' import ProfileSection from '@/components/Profile/Components/ProfileSection' @@ -15,7 +16,6 @@ import { walletActions } from '@/redux/slices/wallet-slice' import { getUserPreferences, updateUserPreferences } from '@/utils' import classNames from 'classnames' import { motion, useAnimation } from 'framer-motion' -import Link from 'next/link' import { useRouter } from 'next/navigation' import { useEffect, useRef, useState } from 'react' @@ -200,28 +200,16 @@ export default function Home() { )}
-
- - - - - - -
+
diff --git a/src/app/(mobile-ui)/layout.tsx b/src/app/(mobile-ui)/layout.tsx index d187952f..c3bfd327 100644 --- a/src/app/(mobile-ui)/layout.tsx +++ b/src/app/(mobile-ui)/layout.tsx @@ -40,7 +40,7 @@ const Layout = ({ children }: { children: React.ReactNode }) => { if (!isReady) return null return ( -
+
{ - const { focusedWallet, wallets } = useWalletStore() - const { user } = useAuth() + const { selectedWallet, isConnected } = useWallet() + const { open } = useAppKit() + const { disconnect } = useDisconnect() + const [isBalanceHidden, setIsBalanceHidden] = useState(() => { + const prefs = getUserPreferences() + return prefs?.balanceHidden ?? false + }) - const walletDetails = wallets.find((wallet) => wallet.address === focusedWallet) + const { username } = useAuth() + const isActiveWalletPW = selectedWallet?.walletProviderType === WalletProviderType.PEANUT + const isActiveWalletBYOW = selectedWallet?.walletProviderType === WalletProviderType.BYOW - const isActiveWalletPW = walletDetails?.walletProviderType === WalletProviderType.PEANUT - const isActiveWalletBYOW = walletDetails?.walletProviderType === WalletProviderType.BYOW + console.log('selectedWallet', selectedWallet) + + const handleToggleBalanceVisibility = (e: React.MouseEvent) => { + e.stopPropagation() + setIsBalanceHidden((prev: boolean) => { + const newValue = !prev + updateUserPreferences({ balanceHidden: newValue }) + return newValue + }) + } return ( -
-
- {focusedWallet && ( - - - - {isActiveWalletPW && ( -

- {user?.user.username}.peanut.wallet -

- )} - {isActiveWalletBYOW && ( -

- {walletDetails.address}.peanut.wallet -

- )} -
-
+
+
+ +
+ +
+ {selectedWallet && ( + {}} + index={0} + isBalanceHidden={isBalanceHidden} + onToggleBalanceVisibility={handleToggleBalanceVisibility} + /> )} +
- - -
$ {printableUsdc(walletDetails?.balance ?? 0n)}
-
-
-
- - -
-
- - - - -

Send

-
- - - - -

Recieve

-
-
+
+ ) : ( + + )} +
+
+
) diff --git a/src/components/0_Bruddle/Button.tsx b/src/components/0_Bruddle/Button.tsx index da3b39a1..2728e201 100644 --- a/src/components/0_Bruddle/Button.tsx +++ b/src/components/0_Bruddle/Button.tsx @@ -2,7 +2,7 @@ import React, { forwardRef } from 'react' import { twMerge } from 'tailwind-merge' import Loading from '../Global/Loading' -type ButtonVariant = 'purple' | 'dark' | 'stroke' | 'transparent-light' | 'transparent-dark' | 'green' | 'yellow' +export type ButtonVariant = 'purple' | 'dark' | 'stroke' | 'transparent-light' | 'transparent-dark' | 'green' | 'yellow' type ButtonSize = 'small' | 'medium' | 'large' | 'xl' | 'xl-fixed' type ButtonShape = 'default' | 'square' type ShadowSize = '4' | '6' | '8' diff --git a/src/components/Dashboard/components/MobileComponent.tsx b/src/components/Dashboard/components/MobileComponent.tsx index 39631a33..8f0206cd 100644 --- a/src/components/Dashboard/components/MobileComponent.tsx +++ b/src/components/Dashboard/components/MobileComponent.tsx @@ -17,7 +17,7 @@ export const MobileItemComponent = ({ return (
setModalVisible(true)} > @@ -54,7 +54,7 @@ export const MobileItemComponent = ({ {linkDetail.status === 'claimed' ? (
claimed
) : ( -
pending
+
pending
)}
diff --git a/src/components/Global/DirectionalActionButtons/index.tsx b/src/components/Global/DirectionalActionButtons/index.tsx new file mode 100644 index 00000000..3a330ec4 --- /dev/null +++ b/src/components/Global/DirectionalActionButtons/index.tsx @@ -0,0 +1,65 @@ +import { ArrowIcon, Button, ButtonVariant } from '@/components/0_Bruddle' +import Link from 'next/link' +import { twMerge } from 'tailwind-merge' + +interface DirectionalActionButton { + title: string + href: string + disabled?: boolean +} + +interface DirectionalActionButtonsProps { + leftButton?: DirectionalActionButton + rightButton?: DirectionalActionButton + variant?: ButtonVariant +} + +const DirectionalActionButtons = ({ + leftButton = { + title: 'Top up', + href: '/topup', + disabled: false, + }, + rightButton = { + title: 'Cash out', + href: '/cashout', + disabled: false, + }, + variant = 'purple', +}: DirectionalActionButtonsProps) => { + return ( +
+ + + + + + + +
+ ) +} + +export default DirectionalActionButtons diff --git a/src/components/Global/EmptyStates/NoDataEmptyState.tsx b/src/components/Global/EmptyStates/NoDataEmptyState.tsx new file mode 100644 index 00000000..0d6b71e2 --- /dev/null +++ b/src/components/Global/EmptyStates/NoDataEmptyState.tsx @@ -0,0 +1,42 @@ +import PEANUTMAN_CRY from '@/animations/GIF_ALPHA_BACKGORUND/512X512_ALPHA_GIF_konradurban_05.gif' +import Image from 'next/image' +import { useMemo } from 'react' + +interface NoDataEmptyStateProps { + message: string + cta?: React.ReactNode + animSize?: 'sm' | 'md' | 'lg' | 'xl' +} + +const NoDataEmptyState = ({ message, cta, animSize }: NoDataEmptyStateProps) => { + const getAnimSize = useMemo(() => { + switch (animSize) { + case 'sm': + return 96 + case 'md': + return 128 + case 'lg': + return 192 + case 'xl': + return 256 + default: + return 96 + } + }, [animSize]) + + return ( +
+ Peanutman crying 😭 +
{message}
+ {cta && cta} +
+ ) +} + +export default NoDataEmptyState diff --git a/src/components/Global/EmptyStates/index.ts b/src/components/Global/EmptyStates/index.ts new file mode 100644 index 00000000..bf8128d8 --- /dev/null +++ b/src/components/Global/EmptyStates/index.ts @@ -0,0 +1 @@ +export * from './NoDataEmptyState' diff --git a/src/components/Global/ListItemView/index.tsx b/src/components/Global/ListItemView/index.tsx index 104a1935..33ff9e91 100644 --- a/src/components/Global/ListItemView/index.tsx +++ b/src/components/Global/ListItemView/index.tsx @@ -7,6 +7,7 @@ import { copyTextToClipboardWithFallback, getExplorerUrl } from '@/utils' import Image from 'next/image' import { useState } from 'react' import { twMerge } from 'tailwind-merge' +import Icon from '../Icon' interface TokenBalance { chainId: string @@ -85,8 +86,10 @@ export const ListItemView = ({ id, variant, primaryInfo, secondaryInfo, metadata onClick={() => isHistory && setModalVisible(true)} >
- {metadata.tokenLogo && ( - token logo + {!!metadata.tokenLogo ? ( + token logo + ) : ( + )} {metadata.chainLogo && ( @@ -148,7 +151,8 @@ export const ListItemView = ({ id, variant, primaryInfo, secondaryInfo, metadata transactionDetails?.status === 'pending' && (
{ - transactionDetails.link && window.open(transactionDetails?.link ?? '', '_blank') + transactionDetails.link && + window.open(transactionDetails?.link ?? '', '_blank', 'noopener,noreferrer') }} className="flex h-12 w-full items-center gap-2 px-4 text-h8 text-sm font-bold transition-colors last:mb-0 hover:bg-n-3/10 disabled:cursor-not-allowed disabled:bg-n-4 disabled:hover:bg-n-4/90 dark:hover:bg-white/20" > @@ -175,7 +179,11 @@ export const ListItemView = ({ id, variant, primaryInfo, secondaryInfo, metadata ?.chainId ?? '' const explorerUrl = getExplorerUrl(chainId) - window.open(`${explorerUrl}/tx/${transactionDetails?.txHash ?? ''}`, '_blank') + window.open( + `${explorerUrl}/tx/${transactionDetails?.txHash ?? ''}`, + '_blank', + 'noopener,noreferrer' + ) }} className="flex h-12 w-full items-center gap-2 px-4 text-h8 text-sm font-bold transition-colors last:mb-0 hover:bg-n-3/10 disabled:cursor-not-allowed disabled:bg-n-4 disabled:hover:bg-n-4/90 dark:hover:bg-white/20" > @@ -187,6 +195,7 @@ export const ListItemView = ({ id, variant, primaryInfo, secondaryInfo, metadata href={transactionDetails.attachmentUrl} download target="_blank" + rel="noopener noreferrer" className="flex h-12 w-full items-center gap-2 px-4 text-h8 text-sm font-bold transition-colors last:mb-0 hover:bg-n-3/10 disabled:cursor-not-allowed disabled:bg-n-4 disabled:hover:bg-n-4/90 dark:hover:bg-white/20" > Download attachment diff --git a/src/utils/general.utils.ts b/src/utils/general.utils.ts index cf778eb5..2ae24f0c 100644 --- a/src/utils/general.utils.ts +++ b/src/utils/general.utils.ts @@ -3,6 +3,7 @@ import * as interfaces from '@/interfaces' import peanut from '@squirrel-labs/peanut-sdk' import chroma from 'chroma-js' import { ethers } from 'ethers' +import * as wagmiChains from 'wagmi/chains' export function urlBase64ToUint8Array(base64String: string) { const padding = '='.repeat((4 - (base64String.length % 4)) % 4) @@ -1064,3 +1065,8 @@ export async function fetchTokenSymbol(tokenAddress: string, chainId: string): P } return tokenSymbol } + +export function getChainName(chainId: string): string | undefined { + const chain = Object.entries(wagmiChains).find(([, chain]) => chain.id === Number(chainId))?.[1] + return chain?.name ?? undefined +}