Skip to content

Commit

Permalink
add the basic ui
Browse files Browse the repository at this point in the history
  • Loading branch information
reallybeard committed Jan 8, 2024
1 parent 9677078 commit 36c9199
Show file tree
Hide file tree
Showing 15 changed files with 563 additions and 136 deletions.
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@
"framer-motion": "^10.17.9",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-icons": "^4.12.0"
"react-icons": "^4.12.0",
"react-router-dom": "^6.21.1"
},
"devDependencies": {
"@types/inquirer": "^9.0.7",
Expand Down
41 changes: 0 additions & 41 deletions src/App.css
Original file line number Diff line number Diff line change
@@ -1,42 +1 @@
#root {
max-width: 1280px;
margin: 0 auto;
padding: 2rem;
text-align: center;
}

.logo {
height: 6em;
padding: 1.5em;
will-change: filter;
transition: filter 300ms;
}
.logo:hover {
filter: drop-shadow(0 0 2em #646cffaa);
}
.logo.react:hover {
filter: drop-shadow(0 0 2em #61dafbaa);
}

@keyframes logo-spin {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}

@media (prefers-reduced-motion: no-preference) {
a:nth-of-type(2) .logo {
animation: logo-spin infinite 20s linear;
}
}

.card {
padding: 2em;
}

.read-the-docs {
color: #888;
}
46 changes: 22 additions & 24 deletions src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,35 +1,33 @@
import './App.css'

import { useState } from 'react'
import { Center } from '@chakra-ui/react'
import { createBrowserRouter, RouterProvider } from 'react-router-dom'
import { SelectPair } from 'components/SelectPair'
import { Status } from 'components/Status/Status'
import { TradeInput } from 'components/TradeInput'

import reactLogo from './assets/react.svg'

import viteLogo from '/vite.svg'
const router = createBrowserRouter([
{
path: '/',
element: <SelectPair />,
},
{
path: '/input',
element: <TradeInput />,
},
{
path: '/status',
element: <Status />,
},
])

function App() {
const [count, setCount] = useState(0)

console.log(import.meta.env.VITE_FOO)

return (
<>
<div>
<a href='https://vitejs.dev' target='_blank' rel='noreferrer'>
<img src={viteLogo} className='logo' alt='Vite logo' />
</a>
<a href='https://react.dev' target='_blank' rel='noreferrer'>
<img src={reactLogo} className='logo react' alt='React logo' />
</a>
</div>
<h1>Vite + React</h1>
<div className='card'>
<button onClick={() => setCount(count => count + 1)}>count is {count}</button>
<p>
Edit <code>src/App.tsx</code> and save to test HMR
</p>
</div>
<p className='read-the-docs'>Click on the Vite and React logos to learn more</p>
</>
<Center width='full' height='100vh' flexDir='column'>
<RouterProvider router={router} />
</Center>
)
}

Expand Down
16 changes: 16 additions & 0 deletions src/components/AssetSelection.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { Avatar, Button, Text } from '@chakra-ui/react'

type AssetSelectionProps = {
onClick: () => void
label: string
}

export const AssetSelection: React.FC<AssetSelectionProps> = ({ label, onClick }) => {
return (
<Button flexDir='column' height='auto' py={4} gap={4} flex={1} onClick={onClick}>
<Text color='text.subtle'>{label}</Text>
<Avatar />
<Text>Bitcoin</Text>
</Button>
)
}
39 changes: 39 additions & 0 deletions src/components/SelectPair.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { Button, Card, CardBody, Flex, Heading, IconButton } from '@chakra-ui/react'
import { useCallback, useMemo } from 'react'
import { FaArrowRightArrowLeft } from 'react-icons/fa6'
import { useNavigate } from 'react-router-dom'

import { AssetSelection } from './AssetSelection'

export const SelectPair = () => {
const navigate = useNavigate()
const switchIcon = useMemo(() => <FaArrowRightArrowLeft />, [])
const handleSubmit = useCallback(() => {
navigate('/input')
}, [navigate])

const handleFromAssetClick = useCallback(() => {
console.info('asset click')
}, [])
const handleToAssetClick = useCallback(() => {
console.info('to asset click')
}, [])

return (
<Card width='full' maxWidth='450px'>
<CardBody display='flex' flexDir='column' gap={8}>
<Heading as='h4' fontSize='md' textAlign='center'>
Choose which assets to trade
</Heading>
<Flex alignItems='center' gap={4} color='text.subtle' width='full'>
<AssetSelection label='Deposit' onClick={handleFromAssetClick} />
<IconButton variant='ghost' icon={switchIcon} aria-label='Switch assets' />
<AssetSelection label='Recieve' onClick={handleToAssetClick} />
</Flex>
<Button size='lg' colorScheme='blue' onClick={handleSubmit}>
Continue
</Button>
</CardBody>
</Card>
)
}
166 changes: 166 additions & 0 deletions src/components/Status/Status.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
import {
Avatar,
Card,
CardBody,
CardFooter,
CardHeader,
Center,
Divider,
Flex,
IconButton,
Input,
InputGroup,
InputRightElement,
Stack,
Tag,
Text,
useSteps,
} from '@chakra-ui/react'
import { useCallback, useMemo } from 'react'
import { FaArrowDown, FaArrowRightArrowLeft, FaCheck, FaRegCopy } from 'react-icons/fa6'
import { useCopyToClipboard } from 'hooks/useCopyToClipboard'
import { BTCImage, ETHImage } from 'lib/const'

import type { StepProps } from './components/StatusStepper'
import { StatusStepper } from './components/StatusStepper'

const steps: StepProps[] = [
{
title: 'Awaiting Deposit',
icon: FaArrowDown,
},
{
title: 'Awaiting Exchange',
icon: FaArrowRightArrowLeft,
},
{
title: 'Trade Complete',
icon: FaCheck,
},
]

export const Status = () => {
const { activeStep } = useSteps({
index: 0,
count: steps.length,
})
const CopyIcon = useMemo(() => <FaRegCopy />, [])
const CheckIcon = useMemo(() => <FaCheck />, [])
const { copyToClipboard: copyToAddress, isCopied: isToAddressCopied } = useCopyToClipboard({
timeout: 3000,
})
const { copyToClipboard: copyDepositAddress, isCopied: isDepositAddressCopied } =
useCopyToClipboard({ timeout: 3000 })

const handleCopyToAddress = useCallback(() => {
copyToAddress('1234')
}, [copyToAddress])

const handleCopyDepositAddress = useCallback(() => {
copyDepositAddress('1234')
}, [copyDepositAddress])

return (
<Card width='full' maxW='465px'>
<CardHeader
bg='background.surface.raised.base'
display='flex'
justifyContent='center'
gap={1}
borderTopRadius='xl'
fontSize='sm'
py={2}
>
<Text color='text.subtle'>TX ID</Text>
<Text>0x124567</Text>
</CardHeader>
<CardBody display='flex' flexDir='row-reverse' gap={6} px={4}>
<Flex flexDir='column' gap={4}>
<Center boxSize='150px' bg='background.surface.raised.base' borderRadius='xl' />
<Tag colorScheme='green' size='sm' justifyContent='center'>
Time remaining 06:23
</Tag>
</Flex>
<Stack spacing={4} flex={1}>
<Stack>
<Text fontWeight='bold'>Send</Text>
<Flex alignItems='center' gap={2}>
<Avatar size='sm' src={BTCImage} />
<Text>0.002 BTC</Text>
</Flex>
</Stack>
<Stack>
<Text fontWeight='bold'>To</Text>
<InputGroup>
<Input isReadOnly value='bc1q8n6t65jpm6k0...x7gl' />
<InputRightElement>
<IconButton
borderRadius='lg'
size='sm'
variant='ghost'
icon={isToAddressCopied ? CheckIcon : CopyIcon}
aria-label='Copy address'
onClick={handleCopyToAddress}
/>
</InputRightElement>
</InputGroup>
</Stack>
<Divider borderColor='border.base' />
<Stack>
<Text fontWeight='bold'>You will receive</Text>
<Flex gap={2} alignItems='center'>
<Avatar size='xs' src={ETHImage} />
<Text>0.000158162 ETH</Text>
</Flex>
</Stack>
</Stack>
</CardBody>
<StatusStepper steps={steps} activeStep={activeStep} />
<CardFooter
flexDir='column'
gap={4}
px={4}
bg='background.surface.raised.base'
borderBottomRadius='xl'
>
<Text fontWeight='bold'>Order Details</Text>
<Stack>
<Flex width='full' justifyContent='space-between'>
<Flex alignItems='center' gap={2}>
<Avatar size='xs' src={BTCImage} />
<Text>Deposit</Text>
</Flex>
<Text color='text.subtle'>0.002 BTC</Text>
</Flex>
<Flex alignItems='center' gap={2}>
<Text>bc1q8n6t65jpm6k048ejvwgfa69xp5laqr2sexx7gl</Text>
<IconButton
size='sm'
variant='ghost'
icon={isDepositAddressCopied ? CheckIcon : CopyIcon}
aria-label='Copy deposit address'
onClick={handleCopyDepositAddress}
/>
</Flex>
</Stack>
<Stack>
<Flex width='full' justifyContent='space-between'>
<Flex alignItems='center' gap={2}>
<Avatar size='xs' src={ETHImage} />
<Text>Receive</Text>
</Flex>
<Text color='text.subtle'>0.00158162 ETH</Text>
</Flex>
<Flex alignItems='center' gap={2}>
<Text>0x1234484844949494949</Text>
</Flex>
</Stack>
<Divider borderColor='border.base' />
<Flex alignItems='center' justifyContent='space-between'>
<Text>Estimated Rate</Text>
<Text>1 BTC = 12.90126 ETH</Text>
</Flex>
</CardFooter>
</Card>
)
}
Loading

0 comments on commit 36c9199

Please sign in to comment.