-
Notifications
You must be signed in to change notification settings - Fork 26
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
7 changed files
with
478 additions
and
1 deletion.
There are no files selected for viewing
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,168 @@ | ||
import {cloneElement, useMemo, useState} from 'react'; | ||
import Link from 'next/link'; | ||
import {useRouter} from 'next/router'; | ||
import {motion} from 'framer-motion'; | ||
import {cl} from '@builtbymom/web3/utils'; | ||
import {Popover, Transition} from '@headlessui/react'; | ||
|
||
import {V3Logo} from '../icons/V3Logo'; | ||
import {APPS} from './YearnApps'; | ||
|
||
import type {AnimationProps} from 'framer-motion'; | ||
import type {ReactElement} from 'react'; | ||
|
||
type TMotionDiv = { | ||
animate: AnimationProps['animate']; | ||
name: string; | ||
children: ReactElement; | ||
}; | ||
|
||
const transition = {duration: 0.4, ease: 'easeInOut'}; | ||
const variants = { | ||
initial: {y: -80, opacity: 0, transition}, | ||
enter: {y: 0, opacity: 1, transition}, | ||
exit: {y: -80, opacity: 0, transition} | ||
}; | ||
function MotionDiv({animate, name, children}: TMotionDiv): ReactElement { | ||
return ( | ||
<motion.div | ||
key={name} | ||
initial={'initial'} | ||
animate={animate} | ||
variants={variants} | ||
className={'absolute cursor-pointer'}> | ||
{children} | ||
</motion.div> | ||
); | ||
} | ||
|
||
function Logo(): ReactElement { | ||
const {pathname} = useRouter(); | ||
|
||
return ( | ||
<> | ||
{Object.values(APPS).map(({name, pathCheck, icon}): ReactElement => { | ||
return ( | ||
<MotionDiv | ||
name={name} | ||
animate={pathname.includes(pathCheck) ? 'enter' : 'exit'}> | ||
{icon} | ||
</MotionDiv> | ||
); | ||
})} | ||
</> | ||
); | ||
} | ||
|
||
export function LogoPopover(): ReactElement { | ||
const [isShowing, set_isShowing] = useState(false); | ||
const router = useRouter(); | ||
|
||
const currentApp = useMemo(() => { | ||
const pageURI = router.pathname.toLowerCase(); | ||
return Object.values(APPS).find(({pathCheck}): boolean => pageURI.includes(pathCheck)) || APPS.Vaults; | ||
}, [router]); | ||
|
||
return ( | ||
<> | ||
<Popover | ||
onMouseEnter={(): void => set_isShowing(true)} | ||
onMouseLeave={(): void => set_isShowing(false)}> | ||
<div | ||
onClick={(): void => set_isShowing(false)} | ||
onMouseEnter={(): void => set_isShowing(false)} | ||
className={cl( | ||
'fixed inset-0 bg-black backdrop-blur-sm transition-opacity', | ||
!isShowing ? 'opacity-0 pointer-events-none' : 'opacity-0 pointer-events-auto' | ||
)} | ||
/> | ||
<Popover.Button className={'z-20 flex items-center'}> | ||
<Link href={'/'}> | ||
<span className={'sr-only'}>{'Back to home'}</span> | ||
<Logo /> | ||
</Link> | ||
</Popover.Button> | ||
|
||
<Transition.Root show={isShowing}> | ||
<Transition.Child | ||
as={'div'} | ||
enter={'transition ease-out duration-200'} | ||
enterFrom={'opacity-0 translate-y-1'} | ||
enterTo={'opacity-100 translate-y-0'} | ||
leave={'transition ease-in duration-150'} | ||
leaveFrom={'opacity-100 translate-y-0'} | ||
leaveTo={'opacity-0 translate-y-1'} | ||
className={'relative z-[9999999]'}> | ||
<Popover.Panel | ||
className={'absolute left-1/2 z-20 w-80 -translate-x-1/2 px-4 pt-6 sm:px-0 md:w-[800px]'}> | ||
<div className={'overflow-hidden pt-4 shadow-xl'}> | ||
<div | ||
className={cl( | ||
'relative grid grid-cols-2 gap-2 border p-6 md:grid-cols-5', | ||
currentApp?.name === 'V3' | ||
? 'bg-[#000520] border-neutral-200/60 rounded-sm' | ||
: 'bg-[#F4F4F4] dark:bg-[#282828] border-transparent' | ||
)}> | ||
<div className={'col-span-3 grid grid-cols-2 gap-2 md:grid-cols-3'}> | ||
{[...Object.values(APPS)] | ||
.filter(({name}): boolean => name !== 'V3 Vaults') | ||
.map(({name, href, icon}): ReactElement => { | ||
return ( | ||
<Link | ||
prefetch={false} | ||
key={name} | ||
href={href} | ||
onClick={(): void => set_isShowing(false)}> | ||
<div | ||
onClick={(): void => set_isShowing(false)} | ||
className={cl( | ||
'flex cursor-pointer border flex-col items-center justify-center transition-colors p-4', | ||
currentApp?.name !== 'V3 Vaults' | ||
? 'bg-[#EBEBEB] border-transparent hover:bg-[#c3c3c380] dark:bg-[#0C0C0C] hover:dark:bg-[#3d3d3d80]' | ||
: 'bg-[#000520] hover:bg-[#33374d80] border-[#151C40]' | ||
)}> | ||
<div>{cloneElement(icon, {className: 'w-8 h-8'})}</div> | ||
<div className={'pt-2 text-center'}> | ||
<b className={'text-base'}>{name}</b> | ||
</div> | ||
</div> | ||
</Link> | ||
); | ||
})} | ||
</div> | ||
<div className={'col-span-2 grid grid-cols-2 gap-2 md:grid-cols-3'}> | ||
<Link | ||
prefetch={false} | ||
key={APPS.V3.name} | ||
href={APPS.V3.href} | ||
className={'col-span-3 row-span-2'} | ||
onClick={(): void => set_isShowing(false)}> | ||
<div | ||
className={cl( | ||
'relative flex h-full w-full cursor-pointer flex-col items-center justify-center transition-all rounded-sm p-4', | ||
'bg-[#010A3B] hover:brightness-125' | ||
)}> | ||
<div className={'z-10 flex w-full flex-col items-center'}> | ||
<V3Logo className={'h-20'} /> | ||
<div className={'-mb-2 pt-4 text-center'}> | ||
<p | ||
className={cl( | ||
'font-bold text-black dark:text-white text-sm', | ||
'whitespace-break-spaces' | ||
)}> | ||
{'Discover\nBrand New Vaults'} | ||
</p> | ||
</div> | ||
</div> | ||
</div> | ||
</Link> | ||
</div> | ||
</div> | ||
</div> | ||
</Popover.Panel> | ||
</Transition.Child> | ||
</Transition.Root> | ||
</Popover> | ||
</> | ||
); | ||
} |
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,135 @@ | ||
import Image from 'next/image'; | ||
|
||
import {LogoYearn} from '../icons/LogoYearn'; | ||
import {VEYFI_DYFI_ADDRESS, YCRV_TOKEN_ADDRESS} from '../utils/constants'; | ||
import {ImageWithFallback} from './ImageWithFallback'; | ||
|
||
export const APPS = { | ||
V3: { | ||
name: 'V3 Vaults', | ||
href: 'https://yearn.fi/v3', | ||
pathCheck: 'yearn.fi/v3', | ||
icon: ( | ||
<LogoYearn | ||
className={'size-8'} | ||
back={'text-pink-400'} | ||
front={'text-white'} | ||
/> | ||
) | ||
}, | ||
Juiced: { | ||
name: 'Juiced Vaults', | ||
href: 'https://juiced.yearn.fi', | ||
pathCheck: 'juiced.yearn.fi', | ||
icon: ( | ||
<Image | ||
className={'size-8'} | ||
src={'/juiced.png'} | ||
width={64} | ||
height={64} | ||
alt={'juiced'} | ||
loading={'eager'} | ||
priority | ||
/> | ||
) | ||
}, | ||
Vaults: { | ||
name: 'Vaults', | ||
href: 'https://yearn.fi/vaults', | ||
pathCheck: 'yearn.fi/vaults', | ||
icon: ( | ||
<LogoYearn | ||
className={'size-8'} | ||
back={'text-[#f472b6]'} | ||
front={'text-white'} | ||
/> | ||
) | ||
}, | ||
yCRV: { | ||
name: 'yCRV', | ||
href: 'https://ycrv.yearn.fi', | ||
pathCheck: 'ycrv.yearn.fi', | ||
icon: ( | ||
<ImageWithFallback | ||
alt={'yCRV'} | ||
className={'size-8'} | ||
width={64} | ||
height={64} | ||
src={`${process.env.SMOL_ASSETS_URL}/token/1/${YCRV_TOKEN_ADDRESS}/logo-128.png`} | ||
loading={'eager'} | ||
priority | ||
/> | ||
) | ||
}, | ||
veYFI: { | ||
name: 'veYFI', | ||
href: 'https://veyfi.yearn.fi', | ||
pathCheck: 'veyfi.yearn.fi', | ||
icon: ( | ||
<ImageWithFallback | ||
alt={'veYFI'} | ||
className={'size-8'} | ||
width={64} | ||
height={64} | ||
src={`${process.env.SMOL_ASSETS_URL}/token/1/${VEYFI_DYFI_ADDRESS}/logo-128.png`} | ||
loading={'eager'} | ||
priority | ||
/> | ||
) | ||
}, | ||
yETH: { | ||
name: 'yETH', | ||
href: 'https://yeth.yearn.fi', | ||
pathCheck: 'yeth.yearn.fi', | ||
icon: ( | ||
<ImageWithFallback | ||
alt={'yETH'} | ||
className={'size-8'} | ||
width={64} | ||
height={64} | ||
src={`${process.env.SMOL_ASSETS_URL}/token/1/0x1BED97CBC3c24A4fb5C069C6E311a967386131f7/logo-128.png`} | ||
loading={'eager'} | ||
priority | ||
/> | ||
) | ||
}, | ||
yPrisma: { | ||
name: 'yPrisma', | ||
href: 'https://yprisma.yearn.fi', | ||
pathCheck: 'yprisma.yearn.fi', | ||
icon: ( | ||
<ImageWithFallback | ||
priority | ||
src={`${process.env.SMOL_ASSETS_URL}/token/1/0xe3668873d944e4a949da05fc8bde419eff543882/logo-128.png`} | ||
className={'size-8'} | ||
width={64} | ||
height={64} | ||
alt={'yPrisma'} | ||
/> | ||
) | ||
}, | ||
yBribe: { | ||
name: 'yBribe', | ||
href: 'https://ybribe.yearn.fi', | ||
pathCheck: 'ybribe.yearn.fi', | ||
icon: ( | ||
<LogoYearn | ||
className={'size-8'} | ||
back={'text-neutral-900'} | ||
front={'text-neutral-0'} | ||
/> | ||
) | ||
}, | ||
yFactory: { | ||
name: 'yFactory', | ||
href: 'https://factory.yearn.fi', | ||
pathCheck: 'factory.yearn.fi', | ||
icon: ( | ||
<LogoYearn | ||
className={'size-8'} | ||
back={'text-neutral-900'} | ||
front={'text-neutral-0'} | ||
/> | ||
) | ||
} | ||
}; |
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,30 @@ | ||
import type {ReactElement} from 'react'; | ||
|
||
export function LogoYearn(props: React.SVGProps<SVGSVGElement> & {back?: string; front?: string}): ReactElement { | ||
return ( | ||
<svg | ||
{...props} | ||
width={'32'} | ||
height={'32'} | ||
viewBox={'0 0 32 32'} | ||
fill={'none'} | ||
xmlns={'http://www.w3.org/2000/svg'}> | ||
<circle | ||
cx={'16'} | ||
cy={'16'} | ||
r={'16'} | ||
fill={'currentColor'} | ||
className={props?.back || 'text-neutral-900'} | ||
/> | ||
<path | ||
fillRule={'evenodd'} | ||
clipRule={'evenodd'} | ||
d={ | ||
'M9.3268 6.28268L8.06787 7.56538L11.1398 10.6947L14.2117 13.8241V16.737V19.65H16.0018H17.7919V16.737V13.8241L20.8563 10.7023L23.9208 7.58056L22.654 6.29121L21.3873 5.00185L18.7111 7.72075C17.2392 9.21616 16.0203 10.4396 16.0025 10.4396C15.9846 10.4396 14.764 9.21573 13.2901 7.71982C11.8161 6.22392 10.6046 5 10.5979 5C10.5912 5 10.0192 5.57722 9.3268 6.28268ZM7.90755 13.8008C7.5069 14.6625 7.27486 15.4051 7.12543 16.3036C6.6982 18.8726 7.37349 21.5183 8.98149 23.5752C9.24682 23.9146 10.0275 24.7095 10.3584 24.9773C11.8479 26.1823 13.5436 26.85 15.4457 26.9802C16.5835 27.0581 17.7212 26.9061 18.8387 26.527C22.0686 25.4312 24.4006 22.6027 24.905 19.1692C25.099 17.848 24.9943 16.4347 24.6057 15.1313C24.4512 14.613 24.1382 13.8366 23.9746 13.5658L23.912 13.4623L22.55 14.8485C21.4514 15.9666 21.1913 16.2467 21.2053 16.2965C21.3176 16.6973 21.3772 17.114 21.3932 17.6101C21.4242 18.5714 21.2749 19.3484 20.9033 20.1599C20.181 21.7375 18.7717 22.8635 17.0486 23.2396C16.7494 23.3049 16.6394 23.3123 15.9866 23.3114C15.346 23.3104 15.2202 23.3019 14.9399 23.2402C13.2315 22.8641 11.8879 21.7996 11.1299 20.2217C10.7873 19.5086 10.6322 18.8486 10.6088 18.0043C10.5919 17.3937 10.625 17.0245 10.7396 16.5439L10.8134 16.2348L9.45584 14.8517C8.70918 14.0909 8.09011 13.4685 8.08016 13.4685C8.07018 13.4685 7.9925 13.618 7.90755 13.8008Z' | ||
} | ||
fill={'currentColor'} | ||
className={props?.front || 'text-neutral-900'} | ||
/> | ||
</svg> | ||
); | ||
} |
Oops, something went wrong.