404 Page (#19)

This commit is contained in:
Fede Álvarez 2022-04-06 17:30:06 +02:00 committed by GitHub
parent 6e5279a3c0
commit 3d7434f9cf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 389 additions and 107 deletions

View File

@ -21,12 +21,14 @@ import s from './footer.module.scss'
export const Footer = () => {
const [show, setShow] = useState(true)
const [is404, setIs404] = useState(false)
const router = useRouter()
useEffect(() => {
if (
router?.pathname === '/terms-of-use' ||
router?.pathname === '/privacy-policy'
router?.pathname === '/privacy-policy' ||
router?.pathname === '/404'
) {
setShow(false)
} else {
@ -34,6 +36,14 @@ export const Footer = () => {
}
}, [router?.pathname])
useEffect(() => {
if (router?.pathname === '/404') {
setIs404(true)
} else {
setIs404(false)
}
}, [router?.pathname])
return (
<>
{show && (
@ -73,113 +83,116 @@ export const Footer = () => {
</Container>
</Section>
)}
<footer className={s.footer}>
<Container className={s['container']}>
<div className={s['logo']}>
<Link variant="unstyled" href="/">
<LogoFooter />
<span className="sr-only">Laconic</span>
</Link>
</div>
<nav>
<ul>
{DevelopersLinks.map((link) => {
return (
<li key={link.title}>
<Link href={link.href} variant="nav">
{link.title}
</Link>
</li>
)
})}
</ul>
<ul>
{ProductsLinks.map((link) => {
return (
<li key={link.title}>
<Link href={link.href} variant="nav">
{link.title}
</Link>
</li>
)
})}
</ul>
<ul>
{AboutLinks.map((link) => {
return (
<li key={link.title}>
<Link href={link.href} variant="nav">
{link.title}
</Link>
</li>
)
})}
</ul>
<ul>
{CommunityLinks.map((link) => {
return (
<li key={link.title}>
<Link href={link.href} variant="nav">
{link.title}
</Link>
</li>
)
})}
</ul>
<ul className={s['connect__links']}>
<li>
<Link href="/connect" variant="nav">
Connect
</Link>
</li>
<li>
{ConnectLinks.map((link, index) => {
return (
<div key={`${link.title}-${index}`}>
<Link href={link.href} variant="unstyled">
<span className="sr-only">{link.title}</span>
{link.logo && link.logo}
</Link>
</div>
)
})}
</li>
</ul>
</nav>
</Container>
<Container>
<nav className={s['sub__footer']}>
<ul className={s['connect__links__mobile']}>
<li>
{ConnectLinks.map((link, index) => {
return (
<div key={`${link.title}-${index}`}>
<Link href={link.href} variant="unstyled">
<span className="sr-only">{link.title}</span>
{link.logo && link.logo}
</Link>
</div>
)
})}
</li>
</ul>
<ul className={s['sub__footer__links']}>
<li>
<Link href="/privacy-policy" variant="nav">
Privacy Policy
</Link>
<Link href="/terms-of-use" variant="nav">
Terms of Use
</Link>
</li>
<li>
<p>Laconic, The Source of Proof</p>
</li>
</ul>
</nav>
</Container>
</footer>
{!is404 && (
<footer className={s.footer}>
<Container className={s['container']}>
<div className={s['logo']}>
<Link variant="unstyled" href="/">
<LogoFooter />
<span className="sr-only">Laconic</span>
</Link>
</div>
<nav>
<ul>
{DevelopersLinks.map((link) => {
return (
<li key={link.title}>
<Link href={link.href} variant="nav">
{link.title}
</Link>
</li>
)
})}
</ul>
<ul>
{ProductsLinks.map((link) => {
return (
<li key={link.title}>
<Link href={link.href} variant="nav">
{link.title}
</Link>
</li>
)
})}
</ul>
<ul>
{AboutLinks.map((link) => {
return (
<li key={link.title}>
<Link href={link.href} variant="nav">
{link.title}
</Link>
</li>
)
})}
</ul>
<ul>
{CommunityLinks.map((link) => {
return (
<li key={link.title}>
<Link href={link.href} variant="nav">
{link.title}
</Link>
</li>
)
})}
</ul>
<ul className={s['connect__links']}>
<li>
<Link href="/connect" variant="nav">
Connect
</Link>
</li>
<li>
{ConnectLinks.map((link, index) => {
return (
<div key={`${link.title}-${index}`}>
<Link href={link.href} variant="unstyled">
<span className="sr-only">{link.title}</span>
{link.logo && link.logo}
</Link>
</div>
)
})}
</li>
</ul>
</nav>
</Container>
<Container>
<nav className={s['sub__footer']}>
<ul className={s['connect__links__mobile']}>
<li>
{ConnectLinks.map((link, index) => {
return (
<div key={`${link.title}-${index}`}>
<Link href={link.href} variant="unstyled">
<span className="sr-only">{link.title}</span>
{link.logo && link.logo}
</Link>
</div>
)
})}
</li>
</ul>
<ul className={s['sub__footer__links']}>
<li>
<Link href="/privacy-policy" variant="nav">
Privacy Policy
</Link>
<Link href="/terms-of-use" variant="nav">
Terms of Use
</Link>
</li>
<li>
<p>Laconic, The Source of Proof</p>
</li>
</ul>
</nav>
</Container>
</footer>
)}
</>
)
}

View File

@ -0,0 +1,184 @@
@import '~/css/helpers';
.section {
position: fixed;
right: 0;
bottom: 0;
left: 0;
display: flex;
align-items: center;
flex-direction: column;
justify-content: center;
width: 100%;
height: calc(var(--vh) * 100);
text-align: center;
*:not(.gradient) {
z-index: 1;
}
@media screen and (max-width: 800px) {
background-image: url('/images/hero-mobile.png');
background-repeat: no-repeat;
background-position: 50% 15%;
background-size: 100%;
}
@supports (aspect-ratio: 16 / 9) {
aspect-ratio: 16 / 9;
}
&::after,
&::before {
position: absolute;
z-index: -1;
top: 50%;
left: 50%;
width: 100%;
height: 101%;
content: '';
transform: translate(-50%, -50%);
pointer-events: none;
background: linear-gradient(
0deg,
var(--color-black) 15%,
rgb(9 9 121 / 0) 50%,
var(--color-black) 100%
);
@supports (aspect-ratio: 16 / 9) {
aspect-ratio: 16 / 9;
}
@media screen and (max-width: 800px) {
content: initial;
}
}
&::before {
width: 120%;
height: 115%;
background: radial-gradient(
ellipse farthest-corner at center center,
rgb(4 4 4 / 0.25) 55%,
var(--color-black) 0
);
filter: blur(tovw(80px, 'default', 40px));
}
.line {
width: tovw(3px, 'default', 2px);
height: tovw(72px, 'default', 56px);
margin: tovw(37px, 'default', 20px) auto tovw(23px, 'default', 20px) auto;
}
.flag {
width: tovw(36px, 'default', 22px);
height: tovw(20px, 'default', 20px);
margin: 0 auto 0 tovw(8px, 'default', 6px);
}
h1 {
@media screen and (max-width: 800px) {
font-size: tovw(50px, 'mobile', 71px);
margin-top: auto;
}
}
p {
font-family: var(--font-dm-mono), sans-serif;
font-size: tovw(18px, 'default', 18px);
margin: 0 auto;
}
a {
margin-top: tovw(32px, 'default', 32px);
text-decoration: none;
@media screen and (max-width: 800px) {
width: 100%;
margin-top: auto;
margin-bottom: tovw(25px, 'mobile');
}
}
.scroll {
position: absolute;
bottom: 5%;
left: tovw(56px, 'default', 16px);
display: grid;
align-items: flex-end;
width: calc(100% - (tovw(56px, 'default', 16px) * 2));
grid-template-columns: repeat(2, 1fr);
grid-template-rows: 1fr;
@media screen and (max-width: 800px) {
display: none;
}
ul {
margin: 0;
padding: 0;
list-style-type: none;
}
p,
li {
font-family: var(--font-dm-mono);
font-size: tovw(12px, 'default', 11px);
line-height: 1.7;
width: 100%;
text-align: right;
text-transform: uppercase;
font-variant-numeric: tabular-nums;
}
> div {
&:first-of-type {
display: flex;
align-items: flex-end;
justify-self: flex-start;
@media screen and (max-width: 800px) {
display: none;
}
}
&:last-of-type {
text-align: right;
justify-self: flex-end;
span {
display: inline-block;
width: tovw(60px, 'default', 55px);
}
}
}
}
.gradient {
position: absolute;
bottom: 0;
left: 0;
width: 100%;
height: tovw(740px, 'default', 740px);
background: linear-gradient(
180deg,
rgb(0 0 244 / 0) 1.63%,
rgb(0 0 244 / 0.9) 63.96%
);
@media screen and (max-width: 800px) {
height: 70%;
}
}
.video {
position: absolute;
z-index: -2;
top: 0;
left: 0;
width: 100%;
height: 100%;
user-select: none;
pointer-events: none;
}
}

View File

@ -0,0 +1,69 @@
import clsx from 'clsx'
import { useEffect, useState } from 'react'
import Flag from '~/components/icons/flag'
import Line from '~/components/icons/line'
import Section from '~/components/layout/section'
import { ButtonLink } from '~/components/primitives/button'
import Heading from '~/components/primitives/heading'
import s from './hero.module.scss'
const Hero = () => {
const [position, setPosition] = useState({ x: 0, y: 0 })
useEffect(() => {
const setFromEvent = (e: { clientX: any; clientY: any }) =>
setPosition({ x: e.clientX, y: e.clientY })
window.addEventListener('mousemove', setFromEvent)
return () => {
window.removeEventListener('mousemove', setFromEvent)
}
}, [])
return (
<Section className={s['section']}>
<video
autoPlay
className={clsx('hide-on-mobile', s['video'])}
controls={false}
loop
muted
preload="true"
>
<source src="/videos/hero-grid.mp4" type="video/mp4" />
</video>
<Heading as="h1" variant="xl" centered>
Page not found
</Heading>
<Line className={s['line']} />
<p>ERROR 404</p>
<ButtonLink href="/" variant="default" size="large">
Bring me back home
</ButtonLink>
<div className={s['scroll']}>
<div>
<p>C:</p>
<Flag className={s['flag']} />
</div>
<div className="hide-on-mobile">
<p>404</p>
<ul>
<li>
H:
<span>{position.x} PX</span>
</li>
<li>
V:
<span>{position.y} PX</span>
</li>
</ul>
</div>
</div>
<div className={s.gradient} />
</Section>
)
}
export default Hero

16
src/pages/404.tsx Normal file
View File

@ -0,0 +1,16 @@
import { Meta } from '~/components/common/meta'
import { PageLayout } from '~/components/layout/page'
import Hero from '~/components/sections/404/hero'
import { Page } from './_app'
const NotFoundPage: Page = () => {
return (
<PageLayout>
<Meta />
<Hero />
</PageLayout>
)
}
export default NotFoundPage