Skip to content

Commit

Permalink
Merge pull request #634 from peanutprotocol/fix/wallet-ux
Browse files Browse the repository at this point in the history
[TASK-8198] fix: wallet ux
  • Loading branch information
jjramirezn authored Jan 20, 2025
2 parents 20685f7 + 1ae2b33 commit cfc3270
Show file tree
Hide file tree
Showing 55 changed files with 859 additions and 619 deletions.
2 changes: 1 addition & 1 deletion src/app/(mobile-ui)/history/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import TablePagination from '@/components/Global/TablePagination'
import { MobileTableComponent, TableComponent, Tabs } from '@/components/Profile/Components'
import { PEANUT_API_URL } from '@/constants'
import { useAuth } from '@/context/authContext'
import { useWallet } from '@/hooks/useWallet'
import { useWallet } from '@/hooks/wallet/useWallet'
import { IDashboardItem, IProfileTableData } from '@/interfaces'
import { formatAmountWithSignificantDigits, formatIban, printableAddress } from '@/utils'
import { identicon } from '@dicebear/collection'
Expand Down
128 changes: 85 additions & 43 deletions src/app/(mobile-ui)/home/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,12 @@ import WalletHeader from '@/components/Global/WalletHeader'
import { WalletCard } from '@/components/Home/WalletCard'
import ProfileSection from '@/components/Profile/Components/ProfileSection'
import { useAuth } from '@/context/authContext'
import { useWallet } from '@/hooks/useWallet'
import { useZeroDev } from '@/hooks/useZeroDev'
import { useWallet } from '@/hooks/wallet/useWallet'
import { useWalletConnection } from '@/hooks/wallet/useWalletConnection'
import { WalletProviderType } from '@/interfaces'
import { useAppDispatch } from '@/redux/hooks'
import { walletActions } from '@/redux/slices/wallet-slice'
import { getUserPreferences, updateUserPreferences } from '@/utils'
import classNames from 'classnames'
import { motion, useAnimation } from 'framer-motion'
Expand All @@ -19,28 +23,39 @@ const cardWidth = 300
const cardMargin = 16

export default function Home() {
const dispatch = useAppDispatch()
const controls = useAnimation()
const router = useRouter()
const carouselRef = useRef<HTMLDivElement>(null)
const { connectWallet } = useWalletConnection()

const [isBalanceHidden, setIsBalanceHidden] = useState(() => {
const prefs = getUserPreferences()
return prefs?.balanceHidden ?? false
})

const { addBYOW, username } = useAuth()
const { selectedWallet, wallets, isPeanutWallet, isConnected, setSelectedWallet } = useWallet()
const { username } = useAuth()

const hasWallets = wallets.length > 0
const { handleLogin, isLoggingIn } = useZeroDev()
const toast = useToast()
const { selectedWallet, wallets, isPeanutWallet, isConnected, setSelectedWallet, isWalletConnected } = useWallet()

// initialize focusedIndex to match selectedWalletIndex
const rawIndex = wallets.findIndex((wallet) => wallet.address === selectedWallet?.address)
const selectedWalletIndex = rawIndex === -1 ? 0 : rawIndex
const [focusedIndex, setFocusedIndex] = useState(selectedWalletIndex)

// update focusedIndex when selectedWallet changes
useEffect(() => {
const index = wallets.findIndex((wallet) => wallet.address === selectedWallet?.address)
if (index !== -1) {
setFocusedIndex(index)
}
}, [selectedWallet, wallets])

const hasWallets = wallets.length > 0
const { handleLogin, isLoggingIn } = useZeroDev()
const toast = useToast()
const totalCards = hasWallets ? wallets.length + 1 : 1

// hide balance
const handleToggleBalanceVisibility = (e: React.MouseEvent<HTMLButtonElement>) => {
e.stopPropagation()
setIsBalanceHidden((prev: boolean) => {
Expand All @@ -59,14 +74,55 @@ export default function Home() {

const handleCardClick = (index: number) => {
if (index < wallets.length) {
if (selectedWalletIndex === index) {
const wallet = wallets[index]

if (focusedIndex !== index) {
setFocusedIndex(index)
dispatch(walletActions.setFocusedWallet(wallet))
controls.start({
x: -(index * (cardWidth + cardMargin)),
transition: { type: 'spring', stiffness: 300, damping: 30 },
})

if (wallet.walletProviderType === WalletProviderType.PEANUT || isWalletConnected(wallet)) {
setSelectedWallet(wallet)
}
return
}

if (focusedIndex === index) {
router.push('/wallet')
} else {
setSelectedWallet(wallets[index])
}
}
}

const handleDragEnd = (_e: any, { offset, velocity }: any) => {
const swipe = Math.abs(offset.x) * velocity.x
let targetIndex = focusedIndex

if (swipe < -10000) {
targetIndex = Math.min(focusedIndex + 1, totalCards - 1)
} else if (swipe > 10000) {
targetIndex = Math.max(focusedIndex - 1, 0)
}

setFocusedIndex(targetIndex)

if (targetIndex < wallets.length) {
dispatch(walletActions.setFocusedWallet(wallets[targetIndex]))

const targetWallet = wallets[targetIndex]
if (targetWallet.walletProviderType === WalletProviderType.PEANUT || isWalletConnected(targetWallet)) {
setSelectedWallet(targetWallet)
}
}

controls.start({
x: -(targetIndex * (cardWidth + cardMargin)),
transition: { type: 'spring', stiffness: 300, damping: 30 },
})
}

return (
<div className="w-full">
<div className="flex w-full flex-row justify-center overflow-hidden p-6">
Expand Down Expand Up @@ -117,43 +173,29 @@ export default function Home() {
right: 0,
}}
dragElastic={0.2}
onDragEnd={(_e, { offset, velocity }) => {
const swipe = Math.abs(offset.x) * velocity.x
if (swipe < -10000) {
const nextIndex = Math.min(selectedWalletIndex + 1, totalCards - 1)
if (nextIndex < wallets.length) {
setSelectedWallet(wallets[nextIndex])
}
} else if (swipe > 10000) {
const prevIndex = Math.max(selectedWalletIndex - 1, 0)
setSelectedWallet(wallets[prevIndex])
} else {
controls.start({
x: -(selectedWalletIndex * (cardWidth + cardMargin)),
transition: { type: 'spring', stiffness: 300, damping: 30 },
})
}
}}
onDragEnd={handleDragEnd}
>
{wallets.map((wallet, index) => (
<WalletCard
key={wallet.address}
type="wallet"
wallet={wallet}
username={username ?? ''}
selected={selectedWalletIndex === index}
onClick={() => handleCardClick(index)}
index={index}
isBalanceHidden={isBalanceHidden}
onToggleBalanceVisibility={handleToggleBalanceVisibility}
/>
))}

<WalletCard type="add" onClick={addBYOW} />
{!!wallets.length &&
wallets.map((wallet, index) => (
<WalletCard
key={wallet.address}
type="wallet"
wallet={wallet}
username={username ?? ''}
selected={selectedWalletIndex === index}
onClick={() => handleCardClick(index)}
index={index}
isBalanceHidden={isBalanceHidden}
onToggleBalanceVisibility={handleToggleBalanceVisibility}
isFocused={focusedIndex === index}
/>
))}

<WalletCard type="add" onClick={connectWallet} />
</motion.div>
) : (
<div className="flex h-full w-full flex-grow flex-col justify-center">
<WalletCard type="add" onClick={addBYOW} />
<WalletCard type="add" onClick={connectWallet} />
</div>
)}
</div>
Expand Down
2 changes: 1 addition & 1 deletion src/app/(mobile-ui)/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ import WalletNavigation from '@/components/Global/WalletNavigation'
import HomeWaitlist from '@/components/Home/HomeWaitlist'
import { peanutWalletIsInPreview } from '@/constants'
import { useAuth } from '@/context/authContext'
import { useWallet } from '@/hooks/useWallet'
import { useZeroDev } from '@/hooks/useZeroDev'
import { useWallet } from '@/hooks/wallet/useWallet'
import { useAppKit } from '@reown/appkit/react'
import classNames from 'classnames'
import Link from 'next/link'
Expand Down
17 changes: 10 additions & 7 deletions src/app/(mobile-ui)/wallet/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,25 @@ import { ArrowIcon, Button, Card } from '@/components/0_Bruddle'
import Icon from '@/components/Global/Icon'
import { HomeLink } from '@/components/Home/HomeLink'
import { useAuth } from '@/context/authContext'
import { useWallet } from '@/hooks/useWallet'
import { WalletProviderType } from '@/interfaces'
import { useWalletStore } from '@/redux/hooks'
import { printableUsdc } from '@/utils'
import { motion } from 'framer-motion'
import Link from 'next/link'

const WalletDetailsPage = () => {
const { selectedWallet } = useWallet()
const { focusedWallet, wallets } = useWalletStore()
const { user } = useAuth()
const isActiveWalletPW = selectedWallet?.walletProviderType === WalletProviderType.PEANUT
const isActiveWalletBYOW = selectedWallet?.walletProviderType === WalletProviderType.BYOW

const walletDetails = wallets.find((wallet) => wallet.address === focusedWallet)

const isActiveWalletPW = walletDetails?.walletProviderType === WalletProviderType.PEANUT
const isActiveWalletBYOW = walletDetails?.walletProviderType === WalletProviderType.BYOW

return (
<div className="flex w-full flex-row justify-center gap-2">
<div className="flex w-[100%] flex-col gap-4 sm:w-[90%] sm:gap-2 md:w-[70%] lg:w-[35%]">
{selectedWallet && (
{focusedWallet && (
<Card shadowSize="4" className="w-full rounded-md py-5">
<Card.Content className="flex h-full flex-row items-center justify-evenly">
<img src={smallPeanut.src} className="h-15 w-15 object-contain" />
Expand All @@ -31,7 +34,7 @@ const WalletDetailsPage = () => {
)}
{isActiveWalletBYOW && (
<p className="text-xl sm:text-2xl">
<span className="font-bold">{selectedWallet.address}</span>.peanut.wallet
<span className="font-bold">{walletDetails.address}</span>.peanut.wallet
</p>
)}
</Card.Content>
Expand All @@ -40,7 +43,7 @@ const WalletDetailsPage = () => {

<Card shadowSize="4" className="w-full rounded-md py-10">
<Card.Content className="flex h-full flex-row items-center justify-center">
<div className="text-5xl">$ {printableUsdc(selectedWallet?.balance ?? 0n)}</div>
<div className="text-5xl">$ {printableUsdc(walletDetails?.balance ?? 0n)}</div>
</Card.Content>
</Card>
<div className="flex flex-row gap-2">
Expand Down
6 changes: 3 additions & 3 deletions src/components/Cashout/Components/Initial.view.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ import { MAX_CASHOUT_LIMIT, MIN_CASHOUT_LIMIT } from '@/components/Offramp/Offra
import { PEANUT_WALLET_CHAIN, PEANUT_WALLET_TOKEN } from '@/constants'
import * as context from '@/context'
import { useAuth } from '@/context/authContext'
import { useWallet } from '@/hooks/useWallet'
import { useZeroDev } from '@/hooks/useZeroDev'
import { useWallet } from '@/hooks/wallet/useWallet'
import { balanceByToken, floorFixed, formatIban, printableUsdc, validateBankAccount } from '@/utils'
import { formatBankAccountDisplay, sanitizeBankAccount } from '@/utils/format.utils'
import { useAppKit } from '@reown/appkit/react'
Expand Down Expand Up @@ -261,8 +261,8 @@ export const InitialCashoutView = ({
<FlowHeader />
<Card className="shadow-none sm:shadow-primary-4">
<Card.Header>
<Card.Title>Cash Out</Card.Title>
<Card.Description className="text-center">
<Card.Title className="mx-auto text-center">Cash Out</Card.Title>
<Card.Description className="mx-auto text-center">
Cash out your crypto to your bank account. Works best with popular stablecoins and other
commonly traded tokens.
</Card.Description>
Expand Down
2 changes: 1 addition & 1 deletion src/components/Claim/Claim.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import useClaimLink from './useClaimLink'
import * as assets from '@/assets'
import * as consts from '@/constants'
import * as context from '@/context'
import { useWallet } from '@/hooks/useWallet'
import { useWallet } from '@/hooks/wallet/useWallet'
import * as interfaces from '@/interfaces'
import * as utils from '@/utils'
import PageContainer from '../0_Bruddle/PageContainer'
Expand Down
2 changes: 1 addition & 1 deletion src/components/Claim/Generic/AlreadyClaimed.view.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export const AlreadyClaimedLinkView = ({ claimLinkData }: { claimLinkData: inter
return (
<Card className="shadow-none sm:shadow-primary-4">
<Card.Header>
<Card.Title>Payment Receipt</Card.Title>
<Card.Title className="mx-auto text-center">Payment Receipt</Card.Title>
<Card.Description></Card.Description>
</Card.Header>
<Card.Content className="flex flex-col gap-2">
Expand Down
35 changes: 16 additions & 19 deletions src/components/Claim/Generic/NotFound.view.tsx
Original file line number Diff line number Diff line change
@@ -1,31 +1,28 @@
'use client'

import * as _consts from '../Claim.consts'
import { useRouter } from 'next/navigation'
import { Button, Card } from '@/components/0_Bruddle'
import { Card } from '@/components/0_Bruddle'
import { PaymentsFooter } from '@/components/Global/PaymentsFooter'

export const NotFoundClaimLink = () => {
const router = useRouter()

return (
<Card className="shadow-none sm:shadow-primary-4">
<Card.Header>
<Card.Title>Sorryyy</Card.Title>
<Card.Description>Deposit not found. Are you sure your link is correct?</Card.Description>
<Card className="space-y-3 shadow-none sm:shadow-primary-4">
<Card.Header className="mx-auto space-y-2">
<Card.Title className="mx-auto text-center">Sorryyy</Card.Title>
<Card.Description className="mx-auto text-center">
This link is malformed. Are you sure you copied it correctly?
</Card.Description>
</Card.Header>
<Card.Content>
<label className="text-h9 font-normal">
We would like to hear from your experience. Hit us up on{' '}
<a
className="cursor-pointer text-black underline dark:text-white"
target="_blank"
href="https://discord.gg/BX9Ak7AW28"
>
<Card.Content className="mx-auto space-y-2 text-center">
<div className="block text-h8 font-normal">
Deposit not found. Are you sure your link is correct?
<a className="text-link-decoration" target="_blank" href="https://discord.gg/BX9Ak7AW28">
Discord!
</a>
</label>
<PaymentsFooter />
</div>

<div className="w-full">
<PaymentsFooter />
</div>
</Card.Content>
</Card>
)
Expand Down
8 changes: 4 additions & 4 deletions src/components/Claim/Generic/SenderClaim.view.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import { Button, Card } from '@/components/0_Bruddle'
import { PaymentsFooter } from '@/components/Global/PaymentsFooter'
import * as context from '@/context'
import { useWallet } from '@/hooks/useWallet'
import { useWallet } from '@/hooks/wallet/useWallet'
import * as interfaces from '@/interfaces'
import * as utils from '@/utils'
import { useContext, useState } from 'react'
Expand Down Expand Up @@ -68,9 +68,9 @@ export const SenderClaimLinkView = ({

return (
<Card className="shadow-none sm:shadow-primary-4">
<Card.Header>
<Card.Title>Hello, {utils.shortenAddress(address ?? '')}</Card.Title>
<Card.Description>
<Card.Header className="mx-auto text-center">
<Card.Title className="text-center">Hello, {utils.shortenAddress(address ?? '')}</Card.Title>
<Card.Description className="text-center">
This is a link that you have created. You can refund it or go to the recipient view.
</Card.Description>
</Card.Header>
Expand Down
Loading

0 comments on commit cfc3270

Please sign in to comment.