Skip to content

Commit

Permalink
feat: migrate landing
Browse files Browse the repository at this point in the history
  • Loading branch information
w84april committed Nov 11, 2024
1 parent b9bdde5 commit ec77343
Show file tree
Hide file tree
Showing 20 changed files with 412 additions and 2 deletions.
5 changes: 5 additions & 0 deletions apps/common/components/WithFonts.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@ const aeonik = localFont({
variable: '--font-aeonik',
display: 'swap',
src: [
{
path: '../../../public/fonts/Aeonik-Light.ttf',
weight: '300',
style: 'normal'
},
{
path: '../../../public/fonts/Aeonik-Regular.woff2',
weight: '400',
Expand Down
20 changes: 20 additions & 0 deletions apps/landing/components/common/Button.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import {cl} from '@builtbymom/web3/utils';

import type {ButtonHTMLAttributes, ReactElement} from 'react';

const STYLE = {
primary: 'bg-primary hover:bg-[#004BE0]',
secondary: 'bg-transparent border border-white/30 hover:bg-white/10'
};

export function Button(
props: {variant?: 'primary' | 'secondary'} & ButtonHTMLAttributes<HTMLButtonElement>
): ReactElement {
const {variant = 'primary', ...rest} = props;

return (
<button className={cl('py-3 px-4 rounded-[4px] transition-colors', STYLE[variant], rest.className)}>
{rest.children}
</button>
);
}
44 changes: 44 additions & 0 deletions apps/landing/components/common/EarnCard.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import {type ReactElement, useState} from 'react';
import Image from 'next/image';

import {IconArrow} from '../icons/IconArrow';

export function EarnCard(props: {title: string; info: string; logoSrc: string; hoverLogoSrc: string}): ReactElement {
const [isHovering, set_isHovering] = useState(false);

return (
<div
onMouseEnter={() => set_isHovering(true)}
onMouseLeave={() => set_isHovering(false)}
style={{
background: isHovering
? '#0657F9'
: 'linear-gradient(180deg, rgba(12, 12, 12, 0.8) 0%, rgba(26, 26, 26, 0.8) 100%)'
}}
className={'group relative flex h-full overflow-hidden p-6'}>
<div className={'mt-auto flex items-end'}>
<div>
<p className={'text-[24px] group-hover:text-grey-900'}>{props.title}</p>
<p className={'text-grey-400 group-hover:text-grey-900'}>{props.info}</p>
</div>
<div>
<IconArrow className={'size-6 group-hover:text-grey-900'} />
</div>
</div>
<Image
className={'absolute -top-12 right-10'}
src={props.hoverLogoSrc}
width={200}
height={200}
alt={'app-logo'}
/>
<Image
className={'absolute -top-12 right-10 group-hover:opacity-0'}
src={props.logoSrc}
width={200}
height={200}
alt={'app-logo'}
/>
</div>
);
}
140 changes: 140 additions & 0 deletions apps/landing/components/common/Header.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
import {type ReactElement, useMemo, useState} from 'react';
import Link from 'next/link';
import {useRouter} from 'next/router';
import {AppName, APPS} from '@common/components/Apps';

import {IconYearnLogo} from '../icons/IconYearnLogo';

type TMenu = {path: string; label: string | ReactElement; target?: string};
type TNavbar = {nav: TMenu[]; currentPathName: string};

function Navbar({nav, currentPathName}: TNavbar): ReactElement {
return (
<nav className={'hidden items-center gap-6 md:flex'}>
{nav.map(
(option): ReactElement => (
<Link
key={option.path}
target={option.target}
href={option.path}>
<p className={`yearn--header-nav-item ${currentPathName === option.path ? 'active' : ''}`}>
{option?.label || 'Unknown'}
</p>
</Link>
)
)}
</nav>
);
}

export function LandingAppHeader(): ReactElement {
const {pathname} = useRouter();
const [isMenuOpen, set_isMenuOpen] = useState<boolean>(false);

const menu = useMemo((): TMenu[] => {
const HOME_MENU = {path: '/', label: 'Home'};

if (pathname.startsWith('/ycrv')) {
return [HOME_MENU, ...APPS[AppName.YCRV].menu];
}

if (pathname.startsWith('/v3')) {
return [HOME_MENU, ...APPS[AppName.VAULTSV3].menu];
}

if (pathname.startsWith('/vaults')) {
return [HOME_MENU, ...APPS[AppName.VAULTS].menu];
}

if (pathname.startsWith('/veyfi')) {
return [HOME_MENU, ...APPS[AppName.VEYFI].menu];
}

return [
HOME_MENU,
{
path: 'https://gov.yearn.fi/',
label: 'Governance',
target: '_blank'
},
{path: 'https://blog.yearn.fi/', label: 'Blog', target: '_blank'},
{path: 'https://docs.yearn.fi/', label: 'Docs', target: '_blank'},
{path: 'https://discord.gg/yearn', label: 'Support', target: '_blank'}
];
}, [pathname]);

return (
<div
id={'head'}
className={'inset-x-0 top-0 z-50 mt-7 w-full'}>
<div className={'w-full'}>
<header className={'yearn--header mx-auto max-w-6xl !px-0'}>
<div className={'flex md:hidden'}>
<button onClick={(): void => set_isMenuOpen(!isMenuOpen)}>
<span className={'sr-only'}>{'Open menu'}</span>
<svg
className={'text-neutral-500'}
width={'40'}
height={'40'}
viewBox={'0 0 40 40'}
fill={'none'}
xmlns={'http://www.w3.org/2000/svg'}>
<path
d={
'M2 2C1.44772 2 1 2.44772 1 3C1 3.55228 1.44772 4 2 4H22C22.5523 4 23 3.55228 23 3C23 2.44772 22.5523 2 22 2H2Z'
}
fill={'currentcolor'}
/>
<path
d={
'M2 8C1.44772 8 1 8.44772 1 9C1 9.55228 1.44772 10 2 10H14C14.5523 10 15 9.55228 15 9C15 8.44772 14.5523 8 14 8H2Z'
}
fill={'currentcolor'}
/>
<path
d={
'M1 15C1 14.4477 1.44772 14 2 14H22C22.5523 14 23 14.4477 23 15C23 15.5523 22.5523 16 22 16H2C1.44772 16 1 15.5523 1 15Z'
}
fill={'currentcolor'}
/>
<path
d={
'M2 20C1.44772 20 1 20.4477 1 21C1 21.5523 1.44772 22 2 22H14C14.5523 22 15 21.5523 15 21C15 20.4477 14.5523 20 14 20H2Z'
}
fill={'currentcolor'}
/>
</svg>
</button>
</div>
<div className={'flex justify-center'}>
<IconYearnLogo />
</div>
<Navbar
currentPathName={pathname || ''}
nav={menu}
/>
</header>
</div>
{/* <ModalMobileMenu
shouldUseWallets={true}
shouldUseNetworks={true}
isOpen={isMenuOpen}
onClose={(): void => set_isMenuOpen(false)}
supportedNetworks={[]}>
{menu?.map(
(option): ReactElement => (
<Link
key={option.path}
href={option.path}>
<div
className={'mobile-nav-item'}
onClick={(): void => set_isMenuOpen(false)}>
<p className={'font-bold'}>{option.label}</p>
</div>
</Link>
)
)}
</ModalMobileMenu> */}
</div>
);
}
32 changes: 32 additions & 0 deletions apps/landing/components/icons/IconArrow.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import React from 'react';

import type {ReactElement} from 'react';

function IconArrow(props: React.SVGProps<SVGSVGElement>): ReactElement {
return (
<svg
{...props}
width={'24'}
height={'24'}
viewBox={'0 0 24 24'}
fill={'none'}
xmlns={'http://www.w3.org/2000/svg'}>
<path
d={'M10 2H22V14'}
stroke={'currentColor'}
strokeWidth={'1.5'}
strokeLinecap={'round'}
strokeLinejoin={'round'}
/>
<path
d={'M22 2L2 22'}
stroke={'currentColor'}
strokeWidth={'1.5'}
strokeLinecap={'round'}
strokeLinejoin={'round'}
/>
</svg>
);
}

export {IconArrow};
32 changes: 32 additions & 0 deletions apps/landing/components/icons/IconYearnLogo.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import React from 'react';

import type {ReactElement} from 'react';

function IconYearnLogo(props: React.SVGProps<SVGSVGElement>): ReactElement {
return (
<svg
{...props}
width={'40'}
height={'40'}
viewBox={'0 0 64 64'}
fill={'none'}
xmlns={'http://www.w3.org/2000/svg'}>
<path
d={
'M64 32C64 49.6731 49.6731 64 32 64C14.3269 64 0 49.6731 0 32C0 14.3269 14.3269 0 32 0C49.6731 0 64 14.3269 64 32Z'
}
fill={'#ffffff'}
/>
<path
fillRule={'evenodd'}
clipRule={'evenodd'}
d={
'M18.6536 12.5654L16.1357 15.1308L22.2796 21.3894L28.4234 27.6482V33.4741V39.2999H32.0036H35.5838V33.4741V27.6482L41.7127 21.4047L47.8416 15.1611L45.3081 12.5824L42.7746 10.0037L37.4222 15.4415C34.4784 18.4323 32.0407 20.8793 32.005 20.8793C31.9692 20.8793 29.5281 18.4315 26.5802 15.4396C23.6322 12.4478 21.2093 10 21.1959 10C21.1824 10 20.0384 11.1544 18.6536 12.5654ZM15.8151 27.6016C15.0138 29.325 14.5497 30.8102 14.2509 32.6073C13.3964 37.7453 14.747 43.0367 17.963 47.1503C18.4936 47.8292 20.055 49.419 20.7168 49.9545C23.6957 52.3647 27.0873 53.7 30.8915 53.9604C33.1671 54.1162 35.4423 53.8122 37.6773 53.054C44.1373 50.8623 48.8012 45.2055 49.8099 38.3385C50.198 35.696 49.9886 32.8694 49.2114 30.2626C48.9024 29.2261 48.2763 27.6732 47.9491 27.1317L47.8239 26.9245L45.0999 29.697C42.9027 31.9333 42.3826 32.4934 42.4105 32.5931C42.6352 33.3947 42.7545 34.2281 42.7864 35.2202C42.8485 37.1427 42.5499 38.6969 41.8067 40.3199C40.3619 43.4751 37.5433 45.7269 34.0971 46.4792C33.4987 46.6098 33.2788 46.6247 31.9732 46.6227C30.692 46.6209 30.4403 46.6038 29.8797 46.4803C26.463 45.7282 23.7758 43.5992 22.2598 40.4435C21.5746 39.0171 21.2644 37.6972 21.2176 36.0086C21.1838 34.7874 21.25 34.0489 21.4793 33.0877L21.6268 32.4696L18.9117 29.7034C17.4184 28.1819 16.1802 26.9371 16.1603 26.9371C16.1404 26.9371 15.985 27.2361 15.8151 27.6016Z'
}
fill={'black'}
/>
</svg>
);
}

export {IconYearnLogo};
37 changes: 37 additions & 0 deletions apps/landing/components/sections/Hero.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import {Button} from '../common/Button';

import type {ReactElement} from 'react';

//todo: ask design to remove border
export function Hero(): ReactElement {
return (
<div className={'flex w-full justify-center'}>
<div
style={{
backgroundImage: "url('/landing/hero.png')",
backgroundRepeat: 'no-repeat',
backgroundSize: 'auto 100%',
backgroundPosition: 'center'
}}
className={
'relative mx-6 mt-6 flex h-[568px] w-full max-w-[2352px] flex-col items-center self-center rounded-lg border border-[#292929]'
}>
<div className={'mt-[88px] text-center'}>
<p className={'text-[80px] font-bold leading-[80px] text-white'}>{'THE DEFI WAY'}</p>
<p className={'text-[80px] font-bold leading-[80px] text-white'}>{'TO EARN CRYPTO'}</p>
<p className={'text-grey-400 mt-4'}>
{'Yearn is DeFi’s longest running, most battle tested, and most trusted yield protocol.'}
</p>
</div>
<div className={'mt-[72px] flex gap-2'}>
<Button className={'w-[192px] px-[15px]'}>{'DISCOVER PRODUCTS'}</Button>
<Button
variant={'secondary'}
className={'w-[192px]'}>
{'SUBMIT YOUR APP'}
</Button>
</div>
</div>
</div>
);
}
Loading

0 comments on commit ec77343

Please sign in to comment.