Skip to content

Commit

Permalink
wip: continue
Browse files Browse the repository at this point in the history
  • Loading branch information
danielsimao committed Dec 4, 2024
1 parent 25e7e00 commit 1314b2a
Show file tree
Hide file tree
Showing 25 changed files with 858 additions and 55 deletions.
2 changes: 2 additions & 0 deletions apps/evm/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
"@dynamic-labs/iconic": "^3.6.2",
"@dynamic-labs/sdk-react-core": "^3.6.2",
"@dynamic-labs/wagmi-connector": "^3.6.2",
"@dynamic-labs/wallet-book": "^3.8.5",
"@gobob/bob-sdk": "^3.1.0",
"@gobob/chains": "workspace:^",
"@gobob/currency": "workspace:^",
Expand All @@ -46,6 +47,7 @@
"@wagmi/core": "catalog:",
"big.js": "catalog:",
"bitcoin-address-validation": "catalog:",
"boring-avatars": "^1.11.2",
"date-fns": "catalog:",
"graphql-request": "catalog:",
"lottie-react": "^2.4.0",
Expand Down
46 changes: 35 additions & 11 deletions apps/evm/src/components/Layout/ConnectButton.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,43 @@
'use client';

import { Button, Drawer } from '@gobob/ui';
import { useDynamicContext, UserProfile } from '@dynamic-labs/sdk-react-core';
import { Button, Flex, Span } from '@gobob/ui';
import { truncateBtcAddress, truncateEthAddress } from '@gobob/utils';
import { Trans } from '@lingui/macro';
import { useAccount } from 'wagmi';
import { useDynamicContext } from '@dynamic-labs/sdk-react-core';
import ProfileAvatar from 'boring-avatars';
import { useState } from 'react';
import { Address } from 'viem';
import { useAccount } from 'wagmi';

import { ProfileDrawer } from '../ProfileDrawer';

import { useBtcAccount } from '@/hooks';

const ConnectButton = (): JSX.Element => {
const { setShowAuthFlow } = useDynamicContext();
const Profile = ({
evmAddress,
btcAddress,
user
}: {
btcAddress?: string;
evmAddress?: Address;
user?: UserProfile;
}) => {
const displayedAddress = evmAddress
? truncateEthAddress(evmAddress)
: btcAddress
? truncateBtcAddress(btcAddress)
: undefined;

return (
<Flex alignItems='center' elementType='span' gap='s'>
{user?.userId ? <ProfileAvatar name={user.userId} size='1.5rem' /> : undefined}
<Span size='s'>{displayedAddress}</Span>
</Flex>
);
};

const ConnectButton = (): JSX.Element => {
const { setShowAuthFlow, user } = useDynamicContext();
const { address: evmAddress } = useAccount();
const { address: btcAddress } = useBtcAccount();

Expand All @@ -25,7 +51,7 @@ const ConnectButton = (): JSX.Element => {
};

return (
<Button onPress={handleConnect}>
<Button variant='ghost' onPress={handleConnect}>
<Trans>Connect Wallet</Trans>
</Button>
);
Expand All @@ -37,12 +63,10 @@ const ConnectButton = (): JSX.Element => {

return (
<>
<Button onPress={handleOpen}>
{evmAddress ? truncateEthAddress(evmAddress) : btcAddress ? truncateBtcAddress(btcAddress) : undefined}
<Button variant='ghost' onPress={handleOpen}>
<Profile btcAddress={btcAddress} evmAddress={evmAddress} user={user} />
</Button>
<Drawer isOpen={isOpen} onClose={handleClose}>
Here
</Drawer>
<ProfileDrawer isOpen={isOpen} onClose={handleClose} />
</>
);
};
Expand Down
31 changes: 31 additions & 0 deletions apps/evm/src/components/ProfileDrawer/AddornedAsset.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
'use client';

import { Flex } from '@gobob/ui';
import { ReactNode } from 'react';

const AddornedAsset = ({ addornment, asset }: { asset: ReactNode; addornment: ReactNode }) => {
return (
<Flex
elementType='span'
style={{ position: 'relative', display: 'inline-flex', width: 'max-content', height: 'fit-content' }}
>
{asset}
<span
style={{
display: 'inline-flex',
position: 'absolute',
bottom: 0,
right: 0,
border: '1px solid #000000',
borderRadius: 99999,
overflow: 'hidden',
transform: 'translate(15%,15%)'
}}
>
{addornment}
</span>
</Flex>
);
};

export { AddornedAsset };
157 changes: 157 additions & 0 deletions apps/evm/src/components/ProfileDrawer/ProfileDrawer.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
'use client';

import {
Button,
Card,
ChevronRight,
Cog,
Drawer,
Flex,
P,
Power,
QrCode,
SolidCreditCard,
Span,
Tabs,
TabsItem
} from '@gobob/ui';
import { Trans } from '@lingui/macro';
import { useAccount } from 'wagmi';
import { useDynamicContext } from '@dynamic-labs/sdk-react-core';
import { ETH } from '@gobob/icons';
import { WalletIcon } from '@dynamic-labs/wallet-book';
import { truncateEthAddress } from '@gobob/utils';

import { ChainLogo } from '../ChainLogo';

import { ProfileTag } from './ProfileTag';
import { TransactionList } from './TransactionList';
import { ProfileTokenList } from './ProfileTokenList';
import { AddornedAsset } from './AddornedAsset';

import { useBalances, useBtcAccount, useTotalBalance } from '@/hooks';
import { chainL1, L1_CHAIN } from '@/constants';
import { useGetTransactions } from '@/hooks/useGetTransactions';

enum ProfileDrawerTabs {
Tokens = 'tokens',
Activity = 'activity'
}

type ProfileDrawerProps = {
isOpen: boolean;
onClose: () => void;
};

const ProfileDrawer = ({ isOpen, onClose }: ProfileDrawerProps): JSX.Element => {
const { setShowAuthFlow, user, handleLogOut } = useDynamicContext();
const { address: evmAddress, chain } = useAccount();
const { address: btcAddress } = useBtcAccount();

const chainId = chain?.id || L1_CHAIN;
const chainName = chain?.name || chainL1.name;

Check warning on line 52 in apps/evm/src/components/ProfileDrawer/ProfileDrawer.tsx

View workflow job for this annotation

GitHub Actions / ESLint

'chainName' is assigned a value but never used

const { formatted } = useTotalBalance(chainId);

const { getBalance } = useBalances(chainId);
const { primaryWallet } = useDynamicContext();

const {
data: transactions,
isInitialLoading: isTransactionsInitialLoading,
refetch: refetchTransaction
} = useGetTransactions();

const isAuthenticated = evmAddress || btcAddress;

if (!isAuthenticated) {
const handleConnect = () => {
setShowAuthFlow(true);
};

return (
<Button variant='ghost' onPress={handleConnect}>
<Trans>Connect Wallet</Trans>
</Button>
);
}

const handleLogout = () => {
handleLogOut();
onClose();
};

return (
<Drawer isOpen={isOpen} onClose={onClose}>
<Flex direction='column' gap='xl' paddingX='s'>
<Flex alignItems='center' justifyContent='space-between' padding='s'>
<ProfileTag btcAddress={btcAddress} evmAddress={evmAddress} size='md' user={user} />
<Flex>
<Button isIconOnly aria-label='disconnect wallet(s)' size='s' variant='ghost' onPress={handleLogout}>
<Cog size='s' />
</Button>
<Button isIconOnly aria-label='disconnect wallet(s)' size='s' variant='ghost' onPress={handleLogout}>
<Power size='s' />
</Button>
</Flex>
</Flex>
{primaryWallet && (
<Card
alignItems='center'
background='grey-600'
direction='row'
gap='md'
justifyContent='space-between'
padding='md'
>
<Flex alignItems='center'>
<AddornedAsset addornment={<ChainLogo chainId={chainId} size='xs' />} asset={<ETH size='xl' />} />
<Flex direction='column'>
<Span size='s'>{getBalance('ETH')?.toSignificant()} ETH</Span>
<Flex gap='s'>
<Span color='grey-50' size='xs'>
{truncateEthAddress(primaryWallet.address)}{' '}
</Span>
<WalletIcon style={{ height: '1rem', width: '1rem' }} walletKey={primaryWallet?.connector?.key} />
</Flex>
</Flex>
</Flex>
<ChevronRight />
</Card>
)}
<P size='3xl' weight='bold'>
{formatted}
</P>
<Flex gap='md'>
<Card isHoverable isPressable flex={1} gap='lg' padding='lg' style={{ backgroundColor: '#3A1F12' }}>
<SolidCreditCard color='primary-500' />
<P color='primary-500' weight='bold'>
Buy
</P>
</Card>
<Card isHoverable isPressable flex={1} gap='lg' padding='lg' style={{ backgroundColor: '#3A1F12' }}>
<QrCode color='primary-500' />
<P color='primary-500' weight='bold'>
Receive
</P>
</Card>
</Flex>
<Tabs fullWidth size='s'>
<TabsItem key={ProfileDrawerTabs.Tokens} title={<Trans>Tokens</Trans>}>
<ProfileTokenList />
</TabsItem>
<TabsItem key={ProfileDrawerTabs.Activity} title={<Trans>Activity</Trans>}>
<TransactionList
data={transactions}
isInitialLoading={isTransactionsInitialLoading}
onProveSuccess={refetchTransaction.bridge}
onRelaySuccess={refetchTransaction.bridge}
/>
</TabsItem>
</Tabs>
</Flex>
</Drawer>
);
};

export { ProfileDrawer };
47 changes: 47 additions & 0 deletions apps/evm/src/components/ProfileDrawer/ProfileTag.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
'use client';

import { UserProfile } from '@dynamic-labs/sdk-react-core';
import { Flex, Span } from '@gobob/ui';
import { truncateBtcAddress, truncateEthAddress } from '@gobob/utils';
import ProfileAvatar from 'boring-avatars';
import { Address } from 'viem';

const sizeMap = {
s: {
icon: '1.5rem',
text: 's'
},
md: {
icon: '2rem',
text: 'md'
}
} as const;

const ProfileTag = ({
evmAddress,
btcAddress,
user,
size = 's'
}: {
btcAddress?: string;
evmAddress?: Address;
user?: UserProfile;
size?: 's' | 'md';
}) => {
const displayedAddress = evmAddress
? truncateEthAddress(evmAddress)
: btcAddress
? truncateBtcAddress(btcAddress)
: undefined;

return (
<Flex alignItems='center' elementType='span' gap='md'>
{user?.userId ? <ProfileAvatar name={user.userId} size={sizeMap[size].icon} /> : undefined}
<Span size={sizeMap[size].text} weight='semibold'>
{displayedAddress}
</Span>
</Flex>
);
};

export { ProfileTag };
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import { Flex, Span, ArrowDownCircle } from '@gobob/ui';
import styled from 'styled-components';

type StyledExpandIconProps = {
$isExpanded?: boolean;
};

const StyledSpan = styled(Span)`
display: inline-flex;
align-items: center;
position: relative;
margin-left: ${({ theme }) => theme.spacing('md')};
padding: 0 ${({ theme }) => theme.spacing('s')};
height: 24px;
border-radius: ${({ theme }) => theme.rounded('full')};
`;

const StyledSpinnerWrapper = styled.span`
position: absolute;
top: 0;
left: 50%;
transform: translateX(-50%);
`;

const StyledTransactionList = styled(Flex)`
overflow-y: auto;
flex: 1 1 auto;
`;

const StyledTransactionListWrapper = styled(Flex)`
overflow: hidden;
`;

const StyledDetailsButton = styled(Flex)`
font: inherit;
display: flex;
width: 100%;
flex-direction: column;
gap: ${({ theme }) => theme.spacing('md')};
padding: ${({ theme }) => `${theme.spacing('md')} 0`};
`;

const StyledExpandIcon = styled(ArrowDownCircle)<StyledExpandIconProps>`
${({ theme }) => theme.transition('common', 'normal')};
transform: ${({ $isExpanded }) => ($isExpanded ? 'rotate(-180deg)' : 'rotate(0deg)')};
`;

export {
StyledDetailsButton,
StyledExpandIcon,
StyledSpan,
StyledSpinnerWrapper,
StyledTransactionList,
StyledTransactionListWrapper
};
Loading

0 comments on commit 1314b2a

Please sign in to comment.