merge main
This commit is contained in:
commit
b4c1b8631e
|
@ -42,11 +42,7 @@ const Layout = ({ children }: { children: ReactNode }) => {
|
|||
return (
|
||||
<div className={`flex-grow bg-th-bkg-1 text-th-fgd-1 transition-all`}>
|
||||
<div className="flex">
|
||||
<div
|
||||
className={
|
||||
isCollapsed ? 'mr-14' : 'mr-[220px] lg:mr-[250px] xl:mr-[280px]'
|
||||
}
|
||||
>
|
||||
<div>
|
||||
<div className={`fixed z-20 h-screen`}>
|
||||
<button
|
||||
className="absolute -right-4 top-1/2 z-20 h-10 w-4 -translate-y-1/2 transform rounded-none rounded-r bg-th-bkg-4 focus:outline-none"
|
||||
|
@ -63,7 +59,11 @@ const Layout = ({ children }: { children: ReactNode }) => {
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="w-full overflow-hidden">
|
||||
<div
|
||||
className={`w-full overflow-hidden transition-all duration-500 ease-in-out ${
|
||||
isCollapsed ? 'pl-20' : 'pl-44 lg:pl-56'
|
||||
}`}
|
||||
>
|
||||
<div className="flex h-14 items-center justify-between border-b border-th-bkg-3 bg-th-bkg-1 px-6">
|
||||
<div className="flex items-center text-th-fgd-3">
|
||||
<span className="mb-0 mr-2">
|
||||
|
|
|
@ -27,77 +27,64 @@ const SideNav = ({ collapsed }: { collapsed: boolean }) => {
|
|||
return (
|
||||
<div
|
||||
className={`flex flex-col justify-between transition-all duration-500 ease-in-out ${
|
||||
collapsed ? 'w-14' : 'w-[220px] lg:w-[250px] xl:w-[280px]'
|
||||
collapsed ? 'w-20' : 'w-44 lg:w-56'
|
||||
} min-h-screen border-r border-th-bkg-3 bg-th-bkg-1`}
|
||||
>
|
||||
<div className="mb-2">
|
||||
<div className="my-2">
|
||||
<Link href={'/'} shallow={true}>
|
||||
<div
|
||||
className={`flex h-14 w-full items-center justify-start border-b border-th-bkg-3 px-3`}
|
||||
className={`h-14 items-center transition-all duration-500 ease-in-out ${
|
||||
collapsed ? 'justify-center' : 'justify-start'
|
||||
} px-5 py-2`}
|
||||
>
|
||||
<div className={`flex flex-shrink-0 cursor-pointer items-center`}>
|
||||
<img
|
||||
className={`h-8 w-auto`}
|
||||
className={`h-9 w-auto`}
|
||||
src="/logos/logo-mark.svg"
|
||||
alt="next"
|
||||
/>
|
||||
<Transition
|
||||
appear={true}
|
||||
show={!collapsed}
|
||||
as={Fragment}
|
||||
enter="transition-all ease-in duration-300"
|
||||
enter="transition-all ease-in duration-200"
|
||||
enterFrom="opacity-50"
|
||||
enterTo="opacity-100"
|
||||
leave="transition ease-out duration-300"
|
||||
leave="transition ease-out duration-200"
|
||||
leaveFrom="opacity-100"
|
||||
leaveTo="opacity-0"
|
||||
>
|
||||
<span className="ml-2 text-lg font-bold text-th-fgd-1">
|
||||
<span className="ml-4 text-lg font-bold text-th-fgd-1">
|
||||
Mango
|
||||
</span>
|
||||
</Transition>
|
||||
</div>
|
||||
</div>
|
||||
</Link>
|
||||
<div className={`flex flex-col items-start space-y-3.5 px-3 pt-4`}>
|
||||
<div className={`mt-3 flex flex-col items-start`}>
|
||||
<MenuItem
|
||||
active={pathname === '/'}
|
||||
collapsed={collapsed}
|
||||
icon={<HomeIcon className="h-5 w-5" />}
|
||||
icon={<HomeIcon className="h-6 w-6" />}
|
||||
title={t('portfolio')}
|
||||
pagePath="/"
|
||||
/>
|
||||
<MenuItem
|
||||
active={pathname === '/trade'}
|
||||
collapsed={collapsed}
|
||||
icon={<TradeIcon className="h-5 w-5" />}
|
||||
icon={<TradeIcon className="h-6 w-6" />}
|
||||
title={t('trade')}
|
||||
pagePath="/trade"
|
||||
/>
|
||||
<MenuItem
|
||||
active={pathname === '/markets'}
|
||||
collapsed={collapsed}
|
||||
icon={<BtcMonoIcon className="h-4 w-4" />}
|
||||
title={t('markets')}
|
||||
pagePath="/markets"
|
||||
/>
|
||||
<MenuItem
|
||||
active={pathname === '/borrow'}
|
||||
collapsed={collapsed}
|
||||
icon={<CashIcon className="h-5 w-5" />}
|
||||
title={t('borrow')}
|
||||
pagePath="/borrow"
|
||||
/>
|
||||
<MenuItem
|
||||
active={pathname === '/stats'}
|
||||
collapsed={collapsed}
|
||||
icon={<ChartBarIcon className="h-5 w-5" />}
|
||||
icon={<ChartBarIcon className="h-6 w-6" />}
|
||||
title={t('stats')}
|
||||
pagePath="/stats"
|
||||
/>
|
||||
<ExpandableMenuItem
|
||||
collapsed={collapsed}
|
||||
icon={<DotsHorizontalIcon className="h-5 w-5" />}
|
||||
icon={<DotsHorizontalIcon className="h-6 w-6" />}
|
||||
pathname={pathname}
|
||||
title={t('more')}
|
||||
>
|
||||
|
@ -162,62 +149,41 @@ const MenuItem = ({
|
|||
hideIconBg?: boolean
|
||||
isExternal?: boolean
|
||||
}) => {
|
||||
return !isExternal ? (
|
||||
return (
|
||||
<Link href={pagePath} shallow={true}>
|
||||
<div className="cursor-pointer">
|
||||
<a
|
||||
className={`flex w-full items-center hover:brightness-[1.1] ${
|
||||
active ? 'text-th-primary' : 'text-th-fgd-1'
|
||||
}`}
|
||||
>
|
||||
<div
|
||||
className={
|
||||
hideIconBg
|
||||
? ''
|
||||
: 'flex h-8 w-8 items-center justify-center rounded-full bg-th-bkg-3'
|
||||
}
|
||||
>
|
||||
{icon}
|
||||
<a
|
||||
className={`flex cursor-pointer px-5 py-2 hover:brightness-[1.1] ${
|
||||
active ? 'text-th-primary' : 'text-th-fgd-1'
|
||||
}`}
|
||||
>
|
||||
<div className="flex w-full items-center justify-between">
|
||||
<div className="flex items-center">
|
||||
<div
|
||||
className={
|
||||
hideIconBg
|
||||
? ''
|
||||
: 'flex h-10 w-10 items-center justify-center rounded-full bg-th-bkg-3'
|
||||
}
|
||||
>
|
||||
{icon}
|
||||
</div>
|
||||
<Transition
|
||||
show={!collapsed}
|
||||
as={Fragment}
|
||||
enter="transition-all ease-in duration-300"
|
||||
enterFrom="opacity-50"
|
||||
enterTo="opacity-100"
|
||||
leave="transition ease-out duration-300"
|
||||
leaveFrom="opacity-100"
|
||||
leaveTo="opacity-0"
|
||||
>
|
||||
<span className="ml-3 lg:text-base">{title}</span>
|
||||
</Transition>
|
||||
</div>
|
||||
<Transition
|
||||
appear={true}
|
||||
show={!collapsed}
|
||||
as={Fragment}
|
||||
enter="transition-all ease-in duration-300"
|
||||
enterFrom="opacity-50"
|
||||
enterTo="opacity-100"
|
||||
leave="transition ease-out duration-300"
|
||||
leaveFrom="opacity-100"
|
||||
leaveTo="opacity-0"
|
||||
>
|
||||
<span className="ml-2">{title}</span>
|
||||
</Transition>
|
||||
</a>
|
||||
</div>
|
||||
</Link>
|
||||
) : (
|
||||
<a
|
||||
href={pagePath}
|
||||
className={`flex items-center justify-between hover:brightness-[1.1] ${
|
||||
active ? 'text-th-primary' : 'text-th-fgd-1'
|
||||
}`}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
<div className="flex items-center">
|
||||
<div
|
||||
className={
|
||||
hideIconBg
|
||||
? ''
|
||||
: 'flex h-8 w-8 items-center justify-center rounded-full bg-th-bkg-3'
|
||||
}
|
||||
>
|
||||
{icon}
|
||||
{isExternal ? <ExternalLinkIcon className="h-4 w-4" /> : null}
|
||||
</div>
|
||||
{!collapsed ? <span className="ml-2">{title}</span> : null}
|
||||
</div>
|
||||
<ExternalLinkIcon className="h-4 w-4" />
|
||||
</a>
|
||||
</a>
|
||||
</Link>
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -253,7 +219,7 @@ const ExpandableMenuItem = ({
|
|||
if (collapsed) {
|
||||
setShowMenu(false)
|
||||
}
|
||||
}, [collapsed, pathname])
|
||||
}, [collapsed])
|
||||
|
||||
const toggleMenu = () => {
|
||||
setShowMenu(!showMenu)
|
||||
|
@ -268,7 +234,7 @@ const ExpandableMenuItem = ({
|
|||
onMouseLeave={
|
||||
!alignBottom ? () => onHoverMenu(showMenu, 'onMouseLeave') : undefined
|
||||
}
|
||||
className="relative z-30"
|
||||
className="relative z-30 px-5 py-2"
|
||||
onClick={() => toggleMenu()}
|
||||
role="button"
|
||||
>
|
||||
|
@ -280,7 +246,7 @@ const ExpandableMenuItem = ({
|
|||
className={` ${
|
||||
hideIconBg
|
||||
? ''
|
||||
: 'flex h-8 w-8 items-center justify-center rounded-full bg-th-bkg-3'
|
||||
: 'flex h-10 w-10 items-center justify-center rounded-full bg-th-bkg-3'
|
||||
} ${
|
||||
alignBottom
|
||||
? 'flex h-14 w-14 items-center justify-center hover:bg-th-bkg-2'
|
||||
|
@ -291,7 +257,6 @@ const ExpandableMenuItem = ({
|
|||
</div>
|
||||
</Popover.Button>
|
||||
<Transition
|
||||
appear={true}
|
||||
show={showMenu}
|
||||
as={Fragment}
|
||||
enter="transition-all ease-in duration-300"
|
||||
|
@ -302,7 +267,7 @@ const ExpandableMenuItem = ({
|
|||
leaveTo="opacity-0"
|
||||
>
|
||||
<Popover.Panel
|
||||
className={`absolute z-20 space-y-2 rounded-md rounded-l-none border border-th-bkg-3 bg-th-bkg-1 p-4 ${
|
||||
className={`absolute z-20 rounded-md rounded-l-none border border-th-bkg-3 bg-th-bkg-1 px-5 py-2 ${
|
||||
alignBottom
|
||||
? 'bottom-0 left-[55px] w-72 rounded-b-none p-0'
|
||||
: 'top-1/2 left-[43px] w-56 -translate-y-1/2 transform'
|
||||
|
@ -318,7 +283,9 @@ const ExpandableMenuItem = ({
|
|||
<div
|
||||
onClick={() => setShowMenu(!showMenu)}
|
||||
role="button"
|
||||
className={`w-full ${alignBottom ? 'h-14 px-3 hover:bg-th-bkg-2' : ''}`}
|
||||
className={`w-full px-5 py-2 ${
|
||||
alignBottom ? 'h-14 px-3 hover:bg-th-bkg-2' : ''
|
||||
}`}
|
||||
>
|
||||
<Disclosure.Button
|
||||
className={`flex h-full w-full items-center justify-between rounded-none hover:text-th-primary`}
|
||||
|
@ -328,7 +295,7 @@ const ExpandableMenuItem = ({
|
|||
className={
|
||||
hideIconBg
|
||||
? ''
|
||||
: 'flex h-8 w-8 items-center justify-center rounded-full bg-th-bkg-3'
|
||||
: 'flex h-10 w-10 items-center justify-center rounded-full bg-th-bkg-3'
|
||||
}
|
||||
>
|
||||
{icon}
|
||||
|
@ -344,7 +311,7 @@ const ExpandableMenuItem = ({
|
|||
leaveFrom="opacity-100"
|
||||
leaveTo="opacity-0"
|
||||
>
|
||||
<span className="ml-2">{title}</span>
|
||||
<span className="ml-3 lg:text-base">{title}</span>
|
||||
</Transition>
|
||||
</div>
|
||||
<ChevronDownIcon
|
||||
|
@ -366,9 +333,7 @@ const ExpandableMenuItem = ({
|
|||
leaveTo="opacity-0 max-h-0"
|
||||
>
|
||||
<Disclosure.Panel className="w-full overflow-hidden">
|
||||
<div className={`space-y-2 ${!alignBottom ? 'p-2 pt-0' : ''}`}>
|
||||
{children}
|
||||
</div>
|
||||
<div className={`${!alignBottom ? 'ml-4' : ''}`}>{children}</div>
|
||||
</Disclosure.Panel>
|
||||
</Transition>
|
||||
</Disclosure>
|
||||
|
|
|
@ -4,7 +4,6 @@ import { toUiDecimals } from '@blockworks-foundation/mango-v4'
|
|||
import { Jupiter, RouteInfo } from '@jup-ag/core'
|
||||
|
||||
import mangoStore, { CLUSTER } from '../../store/state'
|
||||
import SelectedRoute from './SelectedRoute'
|
||||
import RoutesModal from './RoutesModal'
|
||||
import RouteFeeInfo from './RouteFeeInfo'
|
||||
import { TokenInfo } from '../../types/jupiter'
|
||||
|
@ -143,25 +142,12 @@ const JupiterRoutes = ({
|
|||
className="flex w-full justify-center py-3"
|
||||
disabled={!connected}
|
||||
>
|
||||
{submitting ? <Loading className="mr-2 h-5 w-5" /> : null} Swap
|
||||
{submitting ? <Loading className="mr-2 h-5 w-5" /> : null}
|
||||
{connected ? 'Swap' : 'Connect wallet'}
|
||||
</Button>
|
||||
</div>
|
||||
{routes?.length && selectedRoute && outputTokenInfo ? (
|
||||
<>
|
||||
<div
|
||||
role="button"
|
||||
className="mt-8 w-full"
|
||||
onClick={() => {
|
||||
setShowRoutesModal(true)
|
||||
}}
|
||||
>
|
||||
<SelectedRoute
|
||||
routes={routes}
|
||||
selectedRoute={selectedRoute}
|
||||
inputTokenSymbol={inputToken}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<RouteFeeInfo
|
||||
selectedRoute={selectedRoute}
|
||||
amountIn={amountIn}
|
||||
|
@ -171,6 +157,7 @@ const JupiterRoutes = ({
|
|||
)}
|
||||
inputTokenSymbol={inputToken}
|
||||
outputTokenInfo={outputTokenInfo}
|
||||
showRoutesModal={() => setShowRoutesModal(true)}
|
||||
/>
|
||||
{showRoutesModal ? (
|
||||
<RoutesModal
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
import {
|
||||
ArrowSmRightIcon,
|
||||
ChevronRightIcon,
|
||||
CogIcon,
|
||||
InformationCircleIcon,
|
||||
RefreshIcon,
|
||||
|
@ -16,6 +18,7 @@ type RouteFeeInfoProps = {
|
|||
amountOut: number
|
||||
outputTokenInfo: TokenInfo
|
||||
inputTokenSymbol: string
|
||||
showRoutesModal: () => void
|
||||
}
|
||||
|
||||
const RouteFeeInfo = ({
|
||||
|
@ -24,6 +27,7 @@ const RouteFeeInfo = ({
|
|||
amountOut,
|
||||
outputTokenInfo,
|
||||
inputTokenSymbol,
|
||||
showRoutesModal,
|
||||
}: RouteFeeInfoProps) => {
|
||||
const tokens = mangoStore.getState().jupiterTokens
|
||||
const connected = mangoStore((s) => s.connected)
|
||||
|
@ -45,10 +49,36 @@ const RouteFeeInfo = ({
|
|||
}, [selectedRoute, connected])
|
||||
|
||||
return (
|
||||
<div className="mt-4 space-y-2 px-1 text-xs text-th-fgd-4">
|
||||
<div className="mt-6 space-y-2 px-1 text-xs text-th-fgd-4">
|
||||
<div className="mb-4 flex items-center justify-between">
|
||||
<div className="text-sm font-bold text-th-fgd-1">Swap Details</div>
|
||||
</div>
|
||||
<div className="flex items-center justify-between">
|
||||
<span>Swap Route</span>
|
||||
<div
|
||||
className="flex items-center rounded border border-th-bkg-4 p-1 pl-2 hover:cursor-pointer hover:border-th-fgd-4"
|
||||
role="button"
|
||||
onClick={showRoutesModal}
|
||||
>
|
||||
<span className="overflow-ellipsis whitespace-nowrap text-th-fgd-1">
|
||||
{selectedRoute?.marketInfos.map((info, index) => {
|
||||
let includeSeparator = false
|
||||
if (
|
||||
selectedRoute?.marketInfos.length > 1 &&
|
||||
index !== selectedRoute?.marketInfos.length - 1
|
||||
) {
|
||||
includeSeparator = true
|
||||
}
|
||||
return (
|
||||
<span key={index}>{`${info.amm.label} ${
|
||||
includeSeparator ? 'x ' : ''
|
||||
}`}</span>
|
||||
)
|
||||
})}
|
||||
</span>
|
||||
<ChevronRightIcon className="ml-2 h-3 w-3" />
|
||||
</div>
|
||||
</div>
|
||||
{amountOut && amountIn ? (
|
||||
<div className="flex justify-between">
|
||||
<span>Rate</span>
|
||||
|
|
|
@ -1,69 +0,0 @@
|
|||
import { RouteInfo } from '@jup-ag/core'
|
||||
import mangoStore from '../../store/state'
|
||||
|
||||
type SelectedRouteProps = {
|
||||
routes: RouteInfo[]
|
||||
selectedRoute: RouteInfo
|
||||
inputTokenSymbol: string
|
||||
}
|
||||
|
||||
const SelectedRoute = ({
|
||||
routes,
|
||||
selectedRoute,
|
||||
inputTokenSymbol,
|
||||
}: SelectedRouteProps) => {
|
||||
const tokens = mangoStore((s) => s.jupiterTokens)
|
||||
|
||||
return (
|
||||
<div className="rounded-md p-px hover:bg-gradient-to-tl hover:from-gradient-start hover:via-gradient-mid hover:to-gradient-end">
|
||||
<div className="relative rounded-md border border-th-bkg-4 bg-th-bkg-2 px-3 pb-4 pt-4 hover:cursor-pointer">
|
||||
{selectedRoute === routes[0] ? (
|
||||
<div className="absolute -top-2 rounded-sm bg-th-primary px-1 text-xs font-bold text-th-bkg-1">
|
||||
Best Swap
|
||||
</div>
|
||||
) : null}
|
||||
<div className="flex items-center justify-between">
|
||||
<div>
|
||||
<span className="overflow-ellipsis whitespace-nowrap text-sm font-bold text-th-fgd-1">
|
||||
{selectedRoute?.marketInfos.map((info, index) => {
|
||||
let includeSeparator = false
|
||||
if (
|
||||
selectedRoute?.marketInfos.length > 1 &&
|
||||
index !== selectedRoute?.marketInfos.length - 1
|
||||
) {
|
||||
includeSeparator = true
|
||||
}
|
||||
return (
|
||||
<span key={index}>{`${info.amm.label} ${
|
||||
includeSeparator ? 'x ' : ''
|
||||
}`}</span>
|
||||
)
|
||||
})}
|
||||
</span>
|
||||
<div className="mr-2 mt-0.5 text-xs text-th-fgd-3">
|
||||
{inputTokenSymbol} →{' '}
|
||||
{selectedRoute?.marketInfos.map((r, index) => {
|
||||
const showArrow =
|
||||
index !== selectedRoute?.marketInfos.length - 1 ? true : false
|
||||
return (
|
||||
<span key={index}>
|
||||
<span>
|
||||
{
|
||||
tokens.find(
|
||||
(item) => item?.address === r?.outputMint?.toString()
|
||||
)?.symbol
|
||||
}
|
||||
</span>
|
||||
{showArrow ? ' → ' : ''}
|
||||
</span>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default SelectedRoute
|
|
@ -11,6 +11,7 @@ import {
|
|||
} from 'recharts'
|
||||
import LineChartIcon from '../icons/LineChartIcon'
|
||||
import ContentBox from '../shared/ContentBox'
|
||||
import { GREEN, RED } from '../../styles/colors'
|
||||
|
||||
dayjs.extend(relativeTime)
|
||||
|
||||
|
@ -241,15 +242,23 @@ const SwapTokenChart: FunctionComponent<SwapTokenChartProps> = ({
|
|||
x2="0"
|
||||
y2="1"
|
||||
>
|
||||
<stop offset="0%" stopColor="#ffba24" stopOpacity={0.3} />
|
||||
<stop offset="80%" stopColor="#ffba24" stopOpacity={0} />
|
||||
<stop
|
||||
offset="0%"
|
||||
stopColor={chartChange >= 0 ? GREEN : RED}
|
||||
stopOpacity={0.15}
|
||||
/>
|
||||
<stop
|
||||
offset="99%"
|
||||
stopColor={chartChange >= 0 ? GREEN : RED}
|
||||
stopOpacity={0}
|
||||
/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<Area
|
||||
isAnimationActive={true}
|
||||
type="monotone"
|
||||
dataKey="price"
|
||||
stroke="#ffba24"
|
||||
stroke={chartChange >= 0 ? GREEN : RED}
|
||||
fill="url(#gradientArea)"
|
||||
/>
|
||||
<XAxis
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
export const PRIMARY = '#F2C94C'
|
||||
export const GREEN = '#AFD803'
|
||||
export const RED = '#F84638'
|
Loading…
Reference in New Issue