-
Notifications
You must be signed in to change notification settings - Fork 27
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #18 from ugur-eren/feat/swap-page-new-design
Feat: Swap page new design
- Loading branch information
Showing
10 changed files
with
242 additions
and
40 deletions.
There are no files selected for viewing
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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> | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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', | ||
}, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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> | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters