Skip to content

Commit

Permalink
feat: creat swap page ui
Browse files Browse the repository at this point in the history
  • Loading branch information
rozanagy committed Nov 12, 2024
1 parent ad95f39 commit 36cc5b0
Show file tree
Hide file tree
Showing 10 changed files with 317 additions and 0 deletions.
4 changes: 4 additions & 0 deletions public/images/gear-icon.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions public/images/swap-arrow.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 2 additions & 0 deletions src/app/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { Route } from 'react-router-dom';

import { AppLayout } from '@components/app.layout';
import { MerchantDetails } from '@components/proof-of-reserve/components/merchant-details/merchant-details';
import { Swap } from '@components/swap/swap';
import { getWagmiConfiguration } from '@functions/configuration.functions';
import { AttestorDetailsPage } from '@pages/attestor-details/attestor-details-page';
import { AttestorDetailsSelectPage } from '@pages/attestor-details/attestor-details-select-page';
Expand Down Expand Up @@ -47,6 +48,7 @@ export function App(): React.JSX.Element {
/>
<Route path="/merchant-details/:name" element={<MerchantDetails />} />
<Route path="/mint-withdraw" element={<Dashboard />} />
<Route path="/swap" element={<Swap />} />
</AppLayout>
</ProofOfReserveContextProvider>
</BalanceContextProvider>
Expand Down
128 changes: 128 additions & 0 deletions src/app/components/swap/components/swap-amount-card.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
import { ChevronDownIcon } from '@chakra-ui/icons';
import { HStack, Image, Text, VStack } from '@chakra-ui/react';

interface SwapAmountCardProps {
direction: string;
amount: number;
token: string;
inUSD: number;
balance: number;
gasFee?: number;
}

export function SwapAmountCard({
direction,
amount,
token,
inUSD,
balance,
gasFee,
}: SwapAmountCardProps): React.JSX.Element | null {
const isBTC = token === 'BTC';
const borderColor = isBTC ? 'white.01' : 'rgb(188, 143, 249)';
const tokenDisplay = isBTC ? 'BTC' : 'dlcBTC';
const tokenImage = isBTC ? '/images/logos/bitcoin-logo.svg' : '/images/logos/dlc-btc-logo.svg';

return (
<VStack
p={'15px'}
w={'100%'}
bg={'background.container.02'}
borderRadius={'md'}
border={'1px solid'}
spacing={'15px'}
borderColor={borderColor}
alignItems={'flex-start'}
boxShadow={'2px 2px 4px rgba(0, 0, 0, 0.5)'}
>
<Text color={'white'} fontWeight={'600'}>
{direction}
</Text>
<VStack
p={'15px'}
w={'100%'}
bg={'background.content.02'}
borderRadius={'md'}
border={'1px solid'}
spacing={'15px'}
borderColor={'white.03'}
alignItems={'flex-start'}
boxShadow={'2px 2px 4px rgba(0, 0, 0, 0.5)'}
>
<HStack w={'100%'} justifyContent={'space-between'}>
<Text
color={'white'}
fontWeight={'800'}
fontSize={'x-large'}
textShadow={'2px 2px 4px rgba(0, 0, 0, 0.5)'}
>
{amount}
</Text>
<HStack
px={'10px'}
py={'5px'}
w={'150px'}
bg={'white.03'}
borderRadius={'md'}
border={'1px solid'}
spacing={'5px'}
borderColor={'white.03'}
alignItems={'flex-start'}
boxShadow={'2px 2px 4px rgba(0, 0, 0, 0.5)'}
>
<Image src={tokenImage} alt={tokenDisplay} w={'35px'} h={'35px'} />
<Text color={'white'} fontWeight={'800'} fontSize={'x-large'}>
{tokenDisplay}
</Text>
{isBTC && <ChevronDownIcon boxSize={'35px'} color={'white'} />}
</HStack>
</HStack>
<HStack justifyContent={'space-between'} width={'100%'}>
<Text color={'white.03'} fontSize={'sm'}>
{inUSD}
</Text>
<Text color={'white.03'} fontSize={'sm'}>
Bal. {balance}
</Text>
</HStack>
</VStack>
{!isBTC && (
<VStack
p={'15px'}
w={'100%'}
bg={'background.container.02'}
borderRadius={'md'}
border={'1px dashed'}
spacing={'15px'}
borderColor={borderColor}
alignItems={'flex-start'}
>
<HStack w={'100%'} justifyContent={'space-between'}>
<Text color={'white.02'} fontSize={'sm'}>
Gas Fee
</Text>
<Text color={'white.02'} fontSize={'sm'} fontWeight={600}>
{gasFee}
</Text>
</HStack>
<HStack w={'100%'} justifyContent={'space-between'}>
<Text color={'white.02'} fontSize={'sm'}>
Rate
</Text>
<Text color={'white.02'} fontSize={'sm'} fontWeight={600}>
1 BTC = 1 dlcBTC
</Text>
</HStack>
<HStack w={'100%'} justifyContent={'space-between'}>
<Text color={'white.02'} fontSize={'sm'}>
Slippage Tolerance
</Text>
<Text color={'white.02'} fontSize={'sm'} fontWeight={600}>
Auto
</Text>
</HStack>
</VStack>
)}
</VStack>
);
}
15 changes: 15 additions & 0 deletions src/app/components/swap/components/swap-button.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import React from 'react';

import { Button } from '@chakra-ui/react';

interface SwapButtonProps {
onClick: () => void;
}

export function SwapButton({ onClick }: SwapButtonProps): React.JSX.Element {
return (
<Button onClick={onClick} w={'100%'} boxShadow={'2px 2px 4px rgba(0, 0, 0, 0.5)'}>
Swap
</Button>
);
}
75 changes: 75 additions & 0 deletions src/app/components/swap/components/swap-networks-menu.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import { Image, Menu, MenuButton, MenuItem, MenuList } from '@chakra-ui/react';
import { EthereumNetworkID } from 'dlc-btc-lib/models';
import { useAccount, useConfig, useSwitchChain } from 'wagmi';

interface SwapNetworksMenuProps {
isMenuOpen: boolean;
setIsMenuOpen: (isMenuOpen: boolean) => void;
}

const getNetworkLogo = (ethereumNetworkId?: EthereumNetworkID) => {
switch (ethereumNetworkId) {
case EthereumNetworkID.Arbitrum:
case EthereumNetworkID.ArbitrumSepolia:
return './images/logos/arbitrum-token.svg';
case EthereumNetworkID.Sepolia:
case EthereumNetworkID.Mainnet:
return './images/logos/eth-token.svg';
case EthereumNetworkID.BaseSepolia:
case EthereumNetworkID.Base:
return './images/logos/base-token.svg';
default:
return './images/logos/arbitrum-token.svg';
}
};

export function SwapNetworksMenu({
isMenuOpen,
setIsMenuOpen,
}: SwapNetworksMenuProps): React.JSX.Element | null {
const { chains } = useConfig();
const { chain, isConnected } = useAccount();
const { switchChain } = useSwitchChain();
//TODO: maybe add the network logo to the setstate?

if (!isConnected) {
return null;
}

return (
<Menu variant={'networkChange'} isOpen={isMenuOpen}>
<MenuButton
onClick={() => setIsMenuOpen(!isMenuOpen)}
h={'50px'}
w={'50px'}
bg={'background.content.02'}
border={'none'}
boxShadow={'2px 2px 4px rgba(0, 0, 0, 0.5)'}
>
<Image
src={getNetworkLogo(chain?.id.toString() as EthereumNetworkID)}
alt={'Selected network logo'}
w={'35px'}
ml={'7px'}
/>
</MenuButton>
<MenuList>
{chains.map(ethereumNetwork => {
return (
<MenuItem
key={ethereumNetwork.id}
value={ethereumNetwork.id}
onClick={() => {
switchChain({ chainId: ethereumNetwork.id });
setIsMenuOpen(!isMenuOpen);
getNetworkLogo(chain?.id.toString() as EthereumNetworkID);
}}
>
{ethereumNetwork.name}
</MenuItem>
);
})}
</MenuList>
</Menu>
);
}
29 changes: 29 additions & 0 deletions src/app/components/swap/components/swap-settings-menu.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { Image, Menu, MenuButton, MenuItem, MenuList } from '@chakra-ui/react';

interface SwapSettingsMenuProps {
isMenuOpen: boolean;
setIsMenuOpen: (isMenuOpen: boolean) => void;
}

export function SwapSettingsMenu({
isMenuOpen,
setIsMenuOpen,
}: SwapSettingsMenuProps): React.JSX.Element {
return (
<Menu variant={'networkChange'} isOpen={isMenuOpen}>
<MenuButton
onClick={() => setIsMenuOpen(!isMenuOpen)}
h={'50px'}
w={'50px'}
bg={'background.content.02'}
border={'none'}
boxShadow={'2px 2px 4px rgba(0, 0, 0, 0.5)'}
>
<Image src={'./images/gear-icon.svg'} alt={'Gear icon'} w={'30px'} ml={'9px'} />
</MenuButton>
<MenuList>
<MenuItem>Profile Settings</MenuItem>
</MenuList>
</Menu>
);
}
11 changes: 11 additions & 0 deletions src/app/components/swap/pages/swap-page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { PageLayout } from '@pages/components/page.layout';

import { Swap } from '../swap';

export function SwapPage(): React.JSX.Element {
return (
<PageLayout>
<Swap />
</PageLayout>
);
}
49 changes: 49 additions & 0 deletions src/app/components/swap/swap.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import { HStack, Text, VStack } from '@chakra-ui/react';

import { SwapAmountCard } from './components/swap-amount-card';
import { SwapButton } from './components/swap-button';
import { SwapNetworksMenu } from './components/swap-networks-menu';
import { SwapSettingsMenu } from './components/swap-settings-menu';

export function Swap(): React.JSX.Element {
return (
<VStack
alignItems={'flex-start'}
p={'24px'}
w={'500px'}
h={'750px'}
bg={'background.content.01'}
border={'1px solid'}
borderRadius={'md'}
borderColor={'white.03'}
spacing={'24px'}
>
<HStack w={'100%'} justifyContent={'space-between'}>
<Text color={'white'} fontSize={'xx-large'} fontWeight={'600'}>
Swap
</Text>
<HStack>
<SwapNetworksMenu isMenuOpen={false} setIsMenuOpen={() => {}} />
<SwapSettingsMenu isMenuOpen={false} setIsMenuOpen={() => {}} />
</HStack>
</HStack>

<SwapAmountCard
direction={'From'}
amount={120}
token={'BTC'}
inUSD={8245023.6}
balance={500}
/>
<SwapAmountCard
direction={'To'}
amount={120}
token={'dlcBTC'}
inUSD={8245023.6}
balance={0}
gasFee={670}
/>
<SwapButton onClick={() => {}} />
</VStack>
);
}
1 change: 1 addition & 0 deletions src/styles/app-theme.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ export const appTheme = extendTheme({
'background.website.01': 'rgba(0, 0, 0, 1)',
'background.container.01': 'rgba(23, 24, 29, 1)',
'background.content.01': 'rgba(51, 51, 51, 1)',
'background.content.02': 'rgba(77, 77, 77, 1)',
'grey.01': 'rgba(181, 182, 187, 1)',
'border.lightBlue.01': 'rgba(50, 201, 247,0.75)',
'border.white.01': 'rgba(255,255,255,0.25)',
Expand Down

0 comments on commit 36cc5b0

Please sign in to comment.