Skip to content

Commit

Permalink
refactor: create a custom 404 page for app dir (#1116)
Browse files Browse the repository at this point in the history
* refactor: create a custom 404 page for app dir
  • Loading branch information
vnugent authored Mar 26, 2024
1 parent 64dcce5 commit f78b69e
Show file tree
Hide file tree
Showing 10 changed files with 297 additions and 9 deletions.
2 changes: 1 addition & 1 deletion src/app/(default)/area/[[...slug]]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ export default async function Page ({ params }: PageWithCatchAllUuidProps): Prom
* Extract and validate uuid as the first param in a catch-all route
*/
const parseUuidAsFirstParam = ({ params }: PageWithCatchAllUuidProps): string => {
if (params.slug.length === 0) {
if (params.slug == null || params.slug?.length === 0) {
notFound()
}

Expand Down
2 changes: 1 addition & 1 deletion src/app/(default)/components/DesktopHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ export const DesktopHeader: React.FC = () => {
<div className='flex items-center gap-6'><Logo />
<XSearchMinimal />
</div>
<div className='menu menu-horizontal rounded-box gap-2'>{nav}</div>
<div className='menu menu-horizontal rounded-box gap-2 px-0'>{nav}</div>
</header>
)
}
2 changes: 1 addition & 1 deletion src/app/(default)/components/LandingHero.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export const LandingHero: React.FC = () => {
}

export const HeroAlert: React.FC = () => (
<div className='mt-2 alert alert-warning'>
<div className='alert alert-warning'>
<span className='badge badge-sm badge-primary'>NEW</span>
<a href='/maps' className='underline flex items-center gap-1 text-sm'>Crag maps<ArrowRight size={20} /></a>
</div>)
4 changes: 2 additions & 2 deletions src/app/(default)/components/ui/AreaPageContainer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@ export const AreaPageContainer: React.FC<{
}> = ({ photoGallery, pageActions, breadcrumbs, map, children }) => {
return (
<article>
<div className='px-4 mb-2'>
<div className='default-page-margins my-2'>
<HeroAlert />
</div>
<div className='px-4 mx-auto max-w-5xl xl:max-w-7xl'>
<div className='default-page-margins'>
{photoGallery == null ? <GallerySkeleton /> : photoGallery}
<div className='flex justify-end py-4 border-b'>
{pageActions == null ? <AreaPageActionsSkeleton /> : pageActions}
Expand Down
7 changes: 4 additions & 3 deletions src/app/(default)/header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { MobileHeader } from './components/MobileHeader'
*/
export default async function Header (): Promise<any> {
return (
<div className='max-w-5xl mx-auto px-4 xl:px-0'>
<div className='default-page-margins'>
<DesktopHeader />
<MobileHeader />
</div>
Expand All @@ -24,10 +24,11 @@ export enum LogoSize {
/**
* Reusable logo component
*/
export const Logo: React.FC<{ size?: LogoSize, className?: string }> = ({ size = LogoSize.sm, className }) => {
export const Logo: React.FC<{ size?: LogoSize, className?: string, withText?: boolean }> = ({ size = LogoSize.sm, className, withText = false }) => {
return (
<a href='/'>
<a href='/' className='flex items-center gap-2'>
<OpenBetaLogo className={clx(size, className)} />
{withText && <span className='font-bold text-lg tracking-tight'>OpenBeta</span>}
</a>
)
}
8 changes: 8 additions & 0 deletions src/app/global.css
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,14 @@ A slightly deemphasized dotted underline for a tag in order to not competing wit
.minimal-scrollbar::-webkit-scrollbar-thumb {
@apply bg-neutral-300 rounded-full;
}

.default-page-margins {
@apply px-4 mx-auto max-w-5xl xl:max-w-7xl;
}

.narrow-page-margins {
@apply px-4 mx-auto max-w-5xl;
}
}

/**
Expand Down
19 changes: 19 additions & 0 deletions src/app/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import '@/public/fonts/fonts.css'
import './global.css'

/**
* Root layout for the not-found page
*/
export default function RootLayout ({
children
}: {
children: React.ReactNode
}): any {
return (
<html lang='en'>
<body>
{children}
</body>
</html>
)
}
53 changes: 53 additions & 0 deletions src/app/not-found.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import Link from 'next/link'
import { Metadata } from 'next'

import { Chat, House, GithubLogo } from '@phosphor-icons/react/dist/ssr'
import { Logo } from './(default)/header'
import { XSearchMinimal } from '@/components/search/XSearch'
import Alien from '@/assets/illustrations/alien-2-89'

export const metadata: Metadata = {
title: '404 Page not found - OpenBeta'
}

/**
* Global 404 page
*/
export default function NotFound (): any {
return (
<div className='narrow-page-margins'>
<header className='py-6'>
<Logo withText />
</header>

<main className='mt-8'>
<div className='flex items-center gap-16'>
<div className='flex flex-col gap-6 max-w-md'>
<h1 className='text-6xl text-secondary tracking-tight font-bold'>Oops!</h1>
<h2 className='text-xl font-normal'>We can't seem to find the page you're looking for.</h2>
<p className='text-sm'>Error code: 404</p>

<div>
<p className='text-sm font-light'>Some helpful links:</p>
<ul className='menu'>
<li className='hover:bg-transparent'><XSearchMinimal /></li>
<li>
<a className='link link-hover text-sm' href={process.env.NEXT_PUBLIC_DISCORD_INVITE}><Chat />Discord community</a>
</li>
<li>
<a className='link link-hover text-sm' href='https://github.com/OpenBeta/open-tacos/issues'><GithubLogo />GitHub issues</a>
</li>
<li>
<Link href='/' className='link link-hover text-sm'><House /> Home</Link>
</li>
</ul>
</div>
</div>
<div className='hidden md:block'>
<Alien className='w-80 fill-slate-200/50' />
</div>
</div>
</main>
</div>
)
}
207 changes: 207 additions & 0 deletions src/assets/illustrations/alien-2-89.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,207 @@
import * as React from 'react'
interface Props {
className?: string
}

const SvgComponent: React.FC<Props> = (props) => (
<svg
xmlns='http://www.w3.org/2000/svg'
xmlSpace='preserve'
id='Layer_1'
x={0}
y={0}
className='illustrations_image'
data-imageid='alien-2-89'
viewBox='0 0 500 500'
{...props}
>
<style>
{
'.st1{fill:#1b661e}.st3{fill:#21214f}.st5{fill:#ffcf49}.st10{fill:#68e1fd}.st12{fill:#7f3500}.st13{fill:#52af45}'
}
</style>
<g id='field'>
<path
d='m256.8 409 212.7-125.7c6.8-3.8 12.6-10 6-14.1L262 146.1c-3.2-2-8.1-3.3-11.3-1.4L27.4 274.3c-6.8 3.9-8 14.9-1.2 18.9l202.6 115.6c8.6 5 19.2 5.1 28 .2z'
style={{
fill: 'inherit'
}}
/>
<ellipse cx={245.2} cy={294.5} className='st1' rx={116.2} ry={47} />
</g>
<g id='ufo'>
<path
d='m174.8 142.1-44.6 137.3c-1.9 5.9-2.6 15.8-.1 21.5 8.1 18.5 42.2 42.2 123.7 40.7 76.1-1.4 107.6-29.4 107.8-45 .1-5.1.3-10.3-.5-13l-43-147.7'
style={{
opacity: 0.51,
fill: '#ffcf49'
}}
/>
<ellipse cx={248.6} cy={144} className='st3' rx={75.6} ry={39.7} />
<ellipse cx={248.6} cy={139.1} className='st3' rx={75.6} ry={39.7} />
<ellipse
cx={248.6}
cy={139.1}
rx={75.6}
ry={39.7}
style={{
opacity: 0.2,
fill: '#fff'
}}
/>
<circle cx={189} cy={132.2} r={4.2} className='st5' />
<circle cx={307.7} cy={132.2} r={4.2} className='st5' />
<circle cx={197.4} cy={151.7} r={4.2} className='st5' />
<circle cx={215.7} cy={160.8} r={4.2} className='st5' />
<circle cx={244.5} cy={166.7} r={4.2} className='st5' />
<circle cx={272} cy={162.5} r={4.2} className='st5' />
<circle cx={293.8} cy={149.5} r={4.2} className='st5' />
<circle cx={293.8} cy={117} r={4.2} className='st5' />
<circle cx={204.6} cy={117} r={4.2} className='st5' />
<path
d='M203 133.9s1.1-46.5 45.6-46.5c45.5 0 44.6 45 44.6 45s-2 24.2-45.6 24.2-44.6-22.7-44.6-22.7z'
style={{
fill: '#F15E40'
}}
/>
<path
d='M276.4 95.2c1.1 6.4 1.9 12.9 1.1 19.4-.7 7.7-4.2 14.9-9.9 20.2-6.8 6.1-15.9 10.1-24.7 12.3-10.1 2.4-20.5 2.6-30.7.5 6.3 4.8 17.2 9 36 9 43.6 0 45.6-24.2 45.6-24.2s.4-24.3-17.4-37.2z'
style={{
opacity: 0.3,
fill: '#21214f'
}}
/>
<path
d='M234.9 97c-1-1.7-3.2-2.3-4.9-1.3-6.9 3.4-12 9.5-14.2 16.8-1.3 4.4 5.6 6.3 6.9 1.9 1.6-5.6 5.6-10.1 10.9-12.6 1.7-.9 2.3-3.1 1.3-4.8z'
style={{
opacity: 0.7,
fill: '#fff'
}}
/>
</g>
<g id='alien'>
<ellipse
cx={250.6}
cy={311.1}
rx={65.8}
ry={13.8}
style={{
opacity: 0.32,
fill: '#21214f'
}}
/>
<path
d='M199.3 231.8c-.7.2-1.4.4-2 .8-4.2 2.3-5.4 7.1-4.1 11.5 3 10.2 17.3 11.4 23.7 3.8.3-.4.6-.8.8-1.2 1.8-3.6-2.1-8.1-4.6-10.2-3.3-2.9-9.1-5.8-13.8-4.7z'
className='st10'
/>
<path
d='M199.8 242.2c2.5-1.4 6.5-.8 8 1.7 2.1 3.4-6.9 4.2-8.6 3.4-2-1-1.7-3.5-.1-4.7.2-.2.4-.3.7-.4zM208.6 238.4s-5.5-2.7-4.9-4.8c.5-1.5 2.6-.6 3.5-.1 1.2.6 2 1.6 2.4 2.9.5 1 .7 3-1 2zM210 241l.1-.1c.1-.2.3-.3.5-.2.2.1.3.3.2.5l-.1.1c-.1.2-.3.3-.5.2-.2-.1-.3-.3-.2-.5zM209.4 242.4c.1-.2.3-.3.5-.2.2.1.3.3.2.5s-.3.3-.5.2c-.2-.2-.3-.4-.2-.5z'
className='st3'
/>
<path
d='M225.3 256.3s-4.4 2.2-13.6.4-16-1.9-20.8-10.1-6.2-15.3-9.6-14.4 3.5 6.3 1.3 7.5-8.5-4.9-9.3-1 4.8 2.6 8.5 6.9 11.5 14.6 20.2 19.3 22.2 3.6 25.6 1.5 7.1-15.4 3.1-23.6-11.4-12.6-12.2-24.2 1.6-18.9-1.2-20.1-.6 3.4-2.8 5.4-2.8-5-5.8-2.8.1 5.8.1 5.8c3 4.9 4.7 3.1 4.4 7.7s1 16.8 4.3 23.3 10.5 13.4 7.8 18.4z'
className='st10'
/>
<path
d='M227.4 240.9c1 .6 14.3 15.7 21.3 13.1s8.1-8.8 14.3-17 6.8-8.1 14.9-7.8 23.6-8.8 25.4-19.4 3.4-16.8 5.8-15.8 3.8 9.8 2.6 15.8-1.2 11-3.1 13.3-3.5 1.5-8.7 4.6-9.5 7.9-20.2 10.8-14.6 15.1-15.1 19.1 11.3-7.1 17.1 2.1 4 21.4 12.9 23.2 13.6 1.8 18.2 1.3 4.2 1.8-2.4 4.9-12.9.7-17 1.4-12.4-12.6-12.4-12.6c-3.7-8.6-1.6-15.9-12.2-10.1s-23.2 12.3-45.2-1.8'
className='st10'
/>
<path
d='M212.7 248.9c1.7-.4 6.4 12.7 9.5 10s6.3-6.8 5.2-9.9c0 0-6 1.1-9.6-2.4'
className='st10'
/>
</g>
<g id='tree2'>
<linearGradient
id='SVGID_1_'
x1={432.962}
x2={401.352}
y1={248.568}
y2={218.098}
gradientTransform='matrix(1 0 0 -1 0 502)'
gradientUnits='userSpaceOnUse'
>
<stop
offset={0.03}
style={{
stopColor: '#7f3500'
}}
/>
<stop
offset={1}
style={{
stopColor: '#9c6fce',
stopOpacity: 0
}}
/>
</linearGradient>
<path
d='m379.3 279.1 55.9-16.7 6.6 8.6-30.2 26.5-32.3-18.4z'
style={{
opacity: 0.46,
fill: 'url(#SVGID_1_)'
}}
/>
<path
d='M440.7 273.3v-40.2H432v40.5c3 .9 6.2 1 8.7-.3z'
className='st12'
/>
<path
d='M437.2 233.2v41.2c1.2-.1 2.4-.4 3.5-1v-40.2h-3.5z'
className='st12'
/>
<path
d='M448.5 236.8c5.4-.3 12.4-2.2 10.4-8.3-1.2-3.6-4.9-6.7-7.3-9.6s-1.9-4.8-4.5-7.5c2.3.1 5.5-.3 6.1-2.6.5-2-10-13.9-14.6-18.8-1-1.1-2.8-1.2-4-.3-5.4 4.3-19.3 15.8-17.3 19.1 1.2 2 3.5 2.7 5.6 2.9-5 5-10.7 11.2-11.2 17.9-.5 5.8 5.4 6.5 10.9 6.2-3.8 4.6-14.1 17.8-11.8 21.7 1.2 2.1 5.2 2.8 7.6 3.3 5.1 1 10.4 1.5 15.6 1.5 5.3.1 10.5-.7 15.5-2.3 2.8-.9 5.3-2.3 7.6-4.2 2.4-2.3 1.1-4.7-.5-7-2.7-3.9-5.4-7.9-8.1-12z'
className='st13'
/>
<path
d='M447.1 211.4s-6.6-.4-11.2-.3l23.4 19.2s.6-2.2-3.5-6.8c-3.3-3.8-6.1-7.8-8.7-12.1zM448.5 236.8h-13.6l22.2 19.1c1.4-1 1.8-2.9 1-4.4-1.5-2.6-9.6-14.7-9.6-14.7z'
className='st1'
/>
</g>
<g id='tree1'>
<linearGradient
id='SVGID_00000124861967462055410850000018374196565223367307_'
x1={83.834}
x2={61.134}
y1={234.176}
y2={210.966}
gradientTransform='matrix(1 0 0 -1 0 502)'
gradientUnits='userSpaceOnUse'
>
<stop
offset={0.03}
style={{
stopColor: '#7f3500'
}}
/>
<stop
offset={1}
style={{
stopColor: '#9c6fce',
stopOpacity: 0
}}
/>
</linearGradient>
<path
d='m91.4 275.5-8.9-3.7-37.6 19.8 18.7 12c7.8-5.5 20.4-22 27.8-28.1z'
style={{
fill: 'url(#SVGID_00000124861967462055410850000018374196565223367307_)'
}}
/>
<path
d='M85.8 277.1c2.2.5 3.8-.5 5.6-1.6v-62.7c0-.8-.6-1.4-1.4-1.4h-7.3c-.8 0-1.4.6-1.4 1.4v61.5c1.1 1.5 2.7 2.5 4.5 2.8z'
className='st12'
/>
<path
d='M111.3 225.1c-2.3-10.1-12.7-54.6-31-41.5-9.3 6.7-12 17.2-15.8 27.4-3.1 8.5-5.7 17.4-5.8 26.5-.3 18.5 18.5 20.8 32.9 20.7 8.3 0 20.2-4.9 22.1-14 1.2-5.4-.8-11.9-2-17.2-.1-.6-.3-1.3-.4-1.9z'
className='st13'
/>
<path
d='M112.2 227c-.1-.6-.3-1.3-.4-2-2.1-8.9-10.4-44.7-24.9-43.9 4.3 18.9 10.7 38.8 7.3 58.1-1.1 6.8-3.7 13.2-7.7 18.7 1.9.1 3.8.1 5.7.1 8.3 0 20.2-4.9 22.1-14 1-5.2-1-11.6-2.1-17z'
className='st1'
/>
</g>
</svg>
)
export default SvgComponent
2 changes: 1 addition & 1 deletion src/components/search/XSearch.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ export function XSearchMinimal ({ placeholder = 'Try "Cat In the Hat" or "Las Ve
placeholder={placeholder}
open={false}
label={
<button className='btn btn-outline btn-sm rounded-full no-animation border-2 shadow-md'>
<button className='btn btn-outline btn-md rounded-full no-animation border-2 shadow-md'>
<MagnifyingGlassIcon className='w-5 h-5 stroke-2' /> <span className='hidden md:block text-xs md:pr-1.5'>Climb search</span>
</button>
}
Expand Down

0 comments on commit f78b69e

Please sign in to comment.