Skip to content

Commit

Permalink
Merge pull request #18 from ugur-eren/feat/swap-page-new-design
Browse files Browse the repository at this point in the history
Feat: Swap page new design
  • Loading branch information
0xChqrles authored Aug 14, 2024
2 parents d309580 + 8287544 commit 1e64df8
Show file tree
Hide file tree
Showing 10 changed files with 242 additions and 40 deletions.
Binary file added client/src/assets/eur.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added client/src/assets/revolut.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added client/src/assets/usdc.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 3 additions & 2 deletions client/src/components/Button/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@ import styled from 'styled-components'

export const PrimaryButton = styled.button`
width: 100%;
padding: ${({ theme }) => theme.grids.md};
padding: 16px;
background-color: ${({ theme }) => theme.accent1};
border: 0;
border-radius: 6px;
border-radius: 12px;
font-weight: 500;
cursor: pointer;
&:disabled {
Expand Down
52 changes: 52 additions & 0 deletions client/src/components/CurrencyButton/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import { Currency } from 'src/constants/currencies'
import { ThemedText } from 'src/theme/components'
import { ChevronDown } from 'src/theme/components/icons'
import styled from 'styled-components'

import { Row } from '../Flex'

const CurrencyCard = styled(Row)`
background-color: ${({ theme }) => theme.bg2};
color: ${({ theme }) => theme.neutral1};
padding: ${({ theme }) => theme.grids.xs};
padding-right: ${({ theme }) => theme.grids.sm};
border: 1px solid ${({ theme }) => theme.border};
border-radius: 99px;
img {
width: 28px;
height: 28px;
border-radius: 28px;
}
`

type CurrencyButtonProps<
TSymbols extends string,
TCurrency extends Currency,
TAvailableCurrencies extends Record<TSymbols, TCurrency>
> = {
selectedCurrency: keyof TAvailableCurrencies
availableCurrencies: TAvailableCurrencies
}

export const CurrencyButton = <
TSymbols extends string,
TCurrency extends Currency,
TAvailableCurrencies extends Record<TSymbols, TCurrency>
>(
props: CurrencyButtonProps<TSymbols, TCurrency, TAvailableCurrencies>
) => {
const { selectedCurrency, availableCurrencies } = props

const currency = availableCurrencies[selectedCurrency]

return (
<CurrencyCard as="button" gap={4}>
<img src={currency.img} alt={currency.name} />

<ThemedText.Title fontWeight={500}>{currency.name}</ThemedText.Title>

<ChevronDown width={18} height={18} />
</CurrencyCard>
)
}
29 changes: 29 additions & 0 deletions client/src/constants/currencies.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import EURLogo from 'src/assets/eur.png'
import USDCLogo from 'src/assets/usdc.png'

export type Currency = {
img: string
name: string
}

export enum FIAT_CURRENCY {
EUR = 'EUR',
}

export enum TOKEN_CURRENCY {
USDC = 'USDC',
}

export const FIAT_CURRENCIES = {
[FIAT_CURRENCY.EUR]: {
img: EURLogo,
name: 'EUR',
},
}

export const TOKEN_CURRENCIES = {
[TOKEN_CURRENCY.USDC]: {
img: USDCLogo,
name: 'USDC',
},
}
167 changes: 132 additions & 35 deletions client/src/pages/Swap.tsx
Original file line number Diff line number Diff line change
@@ -1,73 +1,170 @@
import { ChangeEvent, useState } from 'react'
import RevolutLogo from 'src/assets/revolut.png'
import { PrimaryButton } from 'src/components/Button'
import { Card } from 'src/components/Card'
import { CurrencyButton } from 'src/components/CurrencyButton'
import { Column, Row } from 'src/components/Flex'
import { CurrencyInput } from 'src/components/Input'
import { FIAT_CURRENCIES, FIAT_CURRENCY, TOKEN_CURRENCIES, TOKEN_CURRENCY } from 'src/constants/currencies'
import { ThemedText } from 'src/theme/components'
import { ArrowDown } from 'src/theme/components/icons'
import { styled } from 'styled-components'

const Layout = styled(Column)`
margin: 0 auto;
justify-content: center;
gap: 16px;
height: 100vh;
`

const InputCardGroup = styled(Row)`
const Content = styled(Column)`
max-width: 460px;
width: 100%;
`

const Headline = styled(Row)`
width: 100%;
justify-content: space-between;
margin-bottom: ${({ theme }) => theme.grids.md};
`

const SwapCard = styled(Card)`
width: 460px;
const PlatformCard = styled(Row)`
border: 1px solid ${({ theme }) => theme.border};
border-radius: 12px;
img {
width: 48px;
height: 48px;
border-radius: 12px;
}
> div {
padding: ${({ theme }) => theme.grids.sm} ${({ theme }) => theme.grids.md};
}
`

const SwapCards = styled(Column)`
position: relative;
width: 100%;
`

const SwapCard = styled(Row)`
width: 100%;
background-color: ${({ theme }) => theme.bg3};
border-radius: 12px;
padding: ${({ theme }) => theme.grids.md} 16px;
`

const SwapCardContent = styled(Column)`
flex: 1;
align-items: flex-start;
input {
width: 100%;
padding-top: ${({ theme }) => theme.grids.md};
padding-bottom: ${({ theme }) => theme.grids.lg};
font-size: 42px;
font-weight: 600;
color: ${({ theme }) => theme.neutral1};
&::placeholder {
color: ${({ theme }) => theme.neutral2};
}
}
`

const ChangeButton = styled.button`
position: absolute;
top: 50%;
left: 50%;
display: flex;
align-items: center;
justify-content: center;
color: ${({ theme }) => theme.neutral1};
transform: translateX(-50%) translateY(-50%);
background-color: ${({ theme }) => theme.bg3};
border: 4px solid ${({ theme }) => theme.bg2};
border-radius: 6px;
padding: 6px;
cursor: pointer;
`

export default function SwapPage() {
const [inputRequestValue, setInputRequestValue] = useState<string>('')
const [inputSendValue, setInputSendValue] = useState<string>('')
const [swapType, setSwapType] = useState<'fiatToToken' | 'tokenToFiat'>('fiatToToken')
const [fiatCurrency, setFiatCurrency] = useState<FIAT_CURRENCY>(FIAT_CURRENCY.EUR)
const [tokenCurrency, setTokenCurrency] = useState<TOKEN_CURRENCY>(TOKEN_CURRENCY.USDC)

const handleRequestChange = (event: ChangeEvent<HTMLInputElement>) => {
const [inputSendValue, setInputSendValue] = useState('')
const [inputReceiveValue, setInputReceiveValue] = useState('')

const handleReceiveChange = (event: ChangeEvent<HTMLInputElement>) => {
const inputValue = event.target.value
const numericValue = inputValue.replace(/[^0-9]/g, '')
setInputRequestValue(numericValue)
setInputReceiveValue(numericValue)
}

const handleSendChange = (event: ChangeEvent<HTMLInputElement>) => {
const inputValue = event.target.value
const numericValue = inputValue.replace(/[^0-9]/g, '')
setInputSendValue(numericValue)
}

const handleChangeClick = () => {
setSwapType(swapType === 'fiatToToken' ? 'tokenToFiat' : 'fiatToToken')
setInputSendValue(inputReceiveValue)
setInputReceiveValue(inputSendValue)
}

return (
<Layout>
<SwapCard gap={16} alignItems="flex-start">
<ThemedText.HeadlineSmall>Swap</ThemedText.HeadlineSmall>

<Card gap={12} bg="surface">
<InputCardGroup gap={16}>
<ThemedText.BodyPrimary>Requesting</ThemedText.BodyPrimary>
<ThemedText.BodyPrimary>Balance: 0</ThemedText.BodyPrimary>
</InputCardGroup>

<InputCardGroup gap={16}>
<CurrencyInput placeholder="0" value={inputRequestValue} onChange={handleRequestChange} />
<ThemedText.HeadlineSmall>USDC</ThemedText.HeadlineSmall>
</InputCardGroup>
</Card>

<Card gap={12} bg="surface">
<InputCardGroup gap={16}>
<ThemedText.BodyPrimary>You send</ThemedText.BodyPrimary>
</InputCardGroup>

<InputCardGroup gap={16}>
<CurrencyInput placeholder="0" value={inputSendValue} onChange={handleSendChange} />
<ThemedText.HeadlineSmall>USD</ThemedText.HeadlineSmall>
</InputCardGroup>
</Card>
<Content gap={12}>
<Headline>
<ThemedText.HeadlineLarge>Swap</ThemedText.HeadlineLarge>

<PlatformCard>
<img src={RevolutLogo} alt="Revolut" />

<Column alignItems="flex-start">
<ThemedText.Title fontWeight={400}>Revolut</ThemedText.Title>
<ThemedText.BodyPrimary fontSize={12}>Platform</ThemedText.BodyPrimary>
</Column>
</PlatformCard>
</Headline>

<SwapCards gap={4}>
<SwapCard as="label">
<SwapCardContent>
<ThemedText.BodyPrimary fontSize={12}>Send</ThemedText.BodyPrimary>
<CurrencyInput placeholder="0.0" value={inputSendValue} onChange={handleSendChange} />
</SwapCardContent>

{swapType === 'fiatToToken' ? (
<CurrencyButton availableCurrencies={FIAT_CURRENCIES} selectedCurrency={fiatCurrency} />
) : (
<CurrencyButton availableCurrencies={TOKEN_CURRENCIES} selectedCurrency={tokenCurrency} />
)}
</SwapCard>

<SwapCard as="label">
<SwapCardContent>
<ThemedText.BodyPrimary fontSize={12}>Receive</ThemedText.BodyPrimary>
<CurrencyInput placeholder="0.0" value={inputReceiveValue} onChange={handleReceiveChange} />
</SwapCardContent>

{swapType === 'fiatToToken' ? (
<CurrencyButton availableCurrencies={TOKEN_CURRENCIES} selectedCurrency={tokenCurrency} />
) : (
<CurrencyButton availableCurrencies={FIAT_CURRENCIES} selectedCurrency={fiatCurrency} />
)}
</SwapCard>

<ChangeButton onClick={handleChangeClick}>
<ArrowDown width={18} height={18} />
</ChangeButton>
</SwapCards>

<PrimaryButton>
<ThemedText.Title>Swap</ThemedText.Title>
</PrimaryButton>
</SwapCard>
</Content>
</Layout>
)
}
7 changes: 4 additions & 3 deletions client/src/theme/colors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,25 +5,26 @@ const colors = {
black: '#000000',

neutral1_dark: '#ffffff',
neutral2_dark: 'rgba(235, 235, 245, 0.45)',
neutral2_dark: 'rgba(240, 247, 244, 0.5)',
}

const commonTheme = {
white: colors.white,
black: colors.black,

accent1: '#5E5CE6',
accent1: '#FF3864',
}

export const darkTheme = {
...commonTheme,

bg1: '#000000',
bg2: '#121216',
bg3: '#181F25',

surface: '#0D0D12',

border: '#636373',
border: 'rgba(240, 247, 244, 0.1)',

neutral1: colors.neutral1_dark,
neutral2: colors.neutral2_dark,
Expand Down
18 changes: 18 additions & 0 deletions client/src/theme/components/icons.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,21 @@ export const Starknet = (props: SVGProps) => (
<path d="M20.5,20.9,17,31.4a1.1,1.1,0,0,1-1.5.5,1.2,1.2,0,0,1-.5-.5L11.5,20.9a.8.8,0,0,0-.4-.4L.6,17a1.1,1.1,0,0,1-.5-1.5L.6,15l10.5-3.5a.8.8,0,0,0,.4-.4L15,.6A1.1,1.1,0,0,1,16.5.1l.5.5,3.5,10.5.4.4L31.4,15a1.1,1.1,0,0,1,.5,1.5,1.2,1.2,0,0,1-.5.5L20.9,20.5Z" />
</svg>
)

export const ChevronDown = (props: SVGProps) => (
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 14 9" fill="none" {...props}>
<path
d="M6.78125 8.02344C6.58333 8.02344 6.40625 7.94792 6.25 7.79688L0.203125 1.60938C0.135417 1.54167 0.0833333 1.46615 0.046875 1.38281C0.0104167 1.29427 -0.0078125 1.20052 -0.0078125 1.10156C-0.0078125 0.966146 0.0234375 0.84375 0.0859375 0.734375C0.148438 0.625 0.231771 0.539062 0.335938 0.476562C0.445312 0.414062 0.567708 0.382812 0.703125 0.382812C0.901042 0.382812 1.07031 0.450521 1.21094 0.585938L7.19531 6.70312H6.35938L12.3438 0.585938C12.4896 0.450521 12.6589 0.382812 12.8516 0.382812C12.987 0.382812 13.1068 0.414062 13.2109 0.476562C13.3203 0.539062 13.4062 0.625 13.4688 0.734375C13.5312 0.84375 13.5625 0.966146 13.5625 1.10156C13.5625 1.29427 13.4922 1.46094 13.3516 1.60156L7.30469 7.79688C7.23698 7.86979 7.15625 7.92708 7.0625 7.96875C6.97396 8.00521 6.88021 8.02344 6.78125 8.02344Z"
fill="currentColor"
/>
</svg>
)

export const ArrowDown = (props: SVGProps) => (
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 12 16" fill="none" {...props}>
<path
d="M5.91406 0.484375C6.11719 0.484375 6.28385 0.549479 6.41406 0.679688C6.54427 0.804688 6.60938 0.96875 6.60938 1.17188V11.4609L6.53125 13.7891L6.08594 13.6328L8.89062 10.5625L10.6719 8.8125C10.7344 8.75 10.8073 8.70312 10.8906 8.67188C10.9792 8.64062 11.0703 8.625 11.1641 8.625C11.3568 8.625 11.5156 8.6901 11.6406 8.82031C11.7708 8.95052 11.8359 9.11198 11.8359 9.30469C11.8359 9.49219 11.7656 9.66146 11.625 9.8125L6.4375 15.0078C6.36458 15.0859 6.28385 15.1432 6.19531 15.1797C6.10677 15.2214 6.01302 15.2422 5.91406 15.2422C5.82031 15.2422 5.72917 15.2214 5.64062 15.1797C5.55208 15.1432 5.46875 15.0859 5.39062 15.0078L0.210938 9.8125C0.0651042 9.66146 -0.0078125 9.49219 -0.0078125 9.30469C-0.0078125 9.11198 0.0546875 8.95052 0.179688 8.82031C0.309896 8.6901 0.471354 8.625 0.664062 8.625C0.757812 8.625 0.846354 8.64062 0.929688 8.67188C1.01823 8.70312 1.09375 8.75 1.15625 8.8125L2.9375 10.5625L5.73438 13.6328L5.29688 13.7891L5.21875 11.4609V1.17188C5.21875 0.96875 5.28385 0.804688 5.41406 0.679688C5.54427 0.549479 5.71094 0.484375 5.91406 0.484375Z"
fill="currentColor"
/>
</svg>
)
4 changes: 4 additions & 0 deletions client/src/theme/components/text.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@ export const ThemedText = {
return <TextWrapper {...props} />
},

HeadlineLarge(props: TextProps) {
return <TextWrapper fontWeight={500} fontSize={36} color="neutral1" fontFamily="Montserrat" {...props} />
},

HeadlineSmall(props: TextProps) {
return <TextWrapper fontWeight={500} fontSize={20} color="neutral1" fontFamily="Montserrat" {...props} />
},
Expand Down

0 comments on commit 1e64df8

Please sign in to comment.