-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #14 from scalarorg/develop
feat: add 404 page
- Loading branch information
Showing
9 changed files
with
325 additions
and
191 deletions.
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
import BuildingValueBackground from "@/public/building-value.webp"; | ||
import Image from "next/image"; | ||
import HeroBackgroundBottom from "@/public/hero-background-bottom.webp"; | ||
import { Subscription } from "@/app/(routes)/_components/cta/components/subscription"; | ||
import { SolarNavigate } from "@/app/(routes)/_components/hero-solar-system/solar-navigate"; | ||
import Link from "next/link"; | ||
|
||
export function HeroNotFound() { | ||
return ( | ||
<div className={"relative text-neutral-2 z-0 overflow-hidden"}> | ||
<Image | ||
src={BuildingValueBackground} | ||
alt={"Building value background"} | ||
className={ | ||
"absolute top-0 left-1/2 inset-x-0 -translate-x-1/2 w-full -z-[9] object-cover object-center aspect-[1920/2196]" | ||
} | ||
/> | ||
<Image | ||
src={HeroBackgroundBottom} | ||
alt={"Building value background"} | ||
className={ | ||
"absolute bottom-0 left-1/2 inset-x-0 w-full -translate-x-1/2 -z-10 object-cover object-center aspect-[1920/1873]" | ||
} | ||
/> | ||
<Image | ||
src={HeroBackgroundBottom} | ||
alt={"Building value background"} | ||
className={ | ||
"absolute top-1/2 -translate-y-1/2 left-1/2 inset-x-0 w-full -translate-x-1/2 -z-10 object-cover object-center aspect-[1920/1873]" | ||
} | ||
/> | ||
<div | ||
className={ | ||
"pt-[32vw] container space-y-[22px] sm:space-y-12 md:space-y-16 lg:space-y-20 xl:space-y-24 2xl:space-y-32" | ||
} | ||
> | ||
<div id={"intro"} className={"max-sm:hidden sm:pb-[21px]"}></div> | ||
<div className={"flex flex-col items-center"}> | ||
<h1 | ||
className={ | ||
"3xl:leading-[200px] text-center 3xl:text-[200px] text-[128px] leading-[128px] font-semibold text-neutral-1 sm:text-[140px] md:text-[152px] lg:text-[164px] xl:text-[176px] 2xl:text-[188px]" | ||
} | ||
> | ||
404 | ||
</h1> | ||
<div | ||
className={ | ||
"space-y-6 3xl:space-y-[68px] text-center flex flex-col items-center sm:space-y-8 md:space-y-10 lg:space-y-12 xl:space-y-14 2xl:space-y-16" | ||
} | ||
> | ||
<p | ||
className={ | ||
"3xl:text-[54px] 3xl:leading-[67.5px] text-[31px] font-semibold leading-[46.5px] text-neutral-1 sm:text-[36px] lg:text-[42px] xl:text-[45px] 2xl:text-[50px]" | ||
} | ||
> | ||
Page not found | ||
</p> | ||
<p | ||
className={ | ||
"text-base leading-[24px] 3xl:text-[34px] sm:text-lg lg:text-xl 2xl:text-2xl" | ||
} | ||
> | ||
This page is under construction | ||
<br /> | ||
Please come back later | ||
</p> | ||
<Link href={"/"} passHref> | ||
<SolarNavigate | ||
className={"text-lg lg:text-xl xl:text-2xl text-neutral-1"} | ||
large | ||
> | ||
Go Home | ||
</SolarNavigate> | ||
</Link> | ||
</div> | ||
</div> | ||
</div> | ||
<div | ||
className={ | ||
"pt-[75px] 3xl:pt-[335px] mb-[49px] 3xl:mb-[122px] sm:pt-[120px] md:pt-[165px] lg:pt-[200px] xl:pt-[240px] 2xl:pt-[320px] sm:mb-[60px] md:mb-[70px] lg:mb-[80px] xl:mb-[85px] 2xl:mb-[90px]" | ||
} | ||
> | ||
<Subscription /> | ||
</div> | ||
</div> | ||
); | ||
} |
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,28 @@ | ||
import Image from "next/image"; | ||
import HighlightRight from "@/public/icon/highlight-right.svg"; | ||
import HighlightLeft from "@/public/icon/highlight-left.svg"; | ||
import { HeroNotFound } from "./_components/hero-not-found"; | ||
|
||
export default function NotFound() { | ||
return ( | ||
<div className={"bg-black relative overflow-hidden"}> | ||
<div className={"relative"}> | ||
<Image | ||
src={HighlightRight} | ||
alt={"Highlight right"} | ||
className={ | ||
"absolute top-0 -right-[10%] z-10 max-sm:w-[75%] max-2xl:w-[60%] pointer-events-none" | ||
} | ||
/> | ||
<Image | ||
src={HighlightLeft} | ||
alt={"Highlight left"} | ||
className={ | ||
"absolute top-0 -left-[10%] z-10 max-sm:w-[75%] max-2xl:w-[60%] pointer-events-none" | ||
} | ||
/> | ||
<HeroNotFound /> | ||
</div> | ||
</div> | ||
); | ||
} |
150 changes: 150 additions & 0 deletions
150
app/(routes)/_components/cta/components/subscription.tsx
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,150 @@ | ||
"use client"; | ||
|
||
import { useForm } from "react-hook-form"; | ||
import { zodResolver } from "@hookform/resolvers/zod"; | ||
import { toast } from "@/components/ui/use-toast"; | ||
import * as z from "zod"; | ||
import { cn } from "@/lib/utils"; | ||
import { FadeIn } from "@/components/motion/fade-in"; | ||
import { AlertTriangleIcon } from "lucide-react"; | ||
|
||
type FormValues = { | ||
email: string; | ||
}; | ||
|
||
const schema = z.object({ | ||
email: z.string().email("Please enter a valid email address"), | ||
}); | ||
|
||
export type SchemaSubscribeForm = z.infer<typeof schema>; | ||
|
||
export function Subscription() { | ||
const { | ||
register, | ||
handleSubmit, | ||
formState: { errors, isSubmitting }, | ||
} = useForm<FormValues>({ resolver: zodResolver(schema) }); | ||
|
||
const onSubmit = handleSubmit(async ({ email }) => { | ||
const result = await fetch("/api/subscribe", { | ||
method: "POST", | ||
headers: { | ||
"Content-Type": "application/json", | ||
}, | ||
body: JSON.stringify({ email }), | ||
}); | ||
|
||
if (result.status === 200) { | ||
toast({ | ||
variant: "success", | ||
title: "Subscribe successfully!", | ||
description: "Thank you for subscribing to our newsletter!", | ||
}); | ||
} else { | ||
toast({ | ||
variant: "destructive", | ||
title: "Subscribe failed!", | ||
description: "Please try again later.", | ||
}); | ||
} | ||
}); | ||
return ( | ||
<div className="flex flex-col container gap-[44px] bg-transparent border-none w-full lg:w-[590px] 2xl:w-[750px] lg:px-0"> | ||
<div className={cn("flex flex-col gap-[28px]")}> | ||
<FadeIn | ||
options={{ | ||
direction: "right", | ||
duration: 0.65, | ||
type: "tween", | ||
delay: 0, | ||
}} | ||
> | ||
<label | ||
className={cn( | ||
"font-bold text-[31px] md:text-[27px] 2xl:[text-34px] leading-[46.5px] md:leading-[47.6px] text-neutral-1", | ||
)} | ||
> | ||
Don't Miss Out,{" "} | ||
<span className={cn("text-primary-cyan-500")}>Subscribe</span>{" "} | ||
Today! | ||
</label> | ||
</FadeIn> | ||
<FadeIn | ||
options={{ | ||
direction: "right", | ||
duration: 0.65, | ||
type: "tween", | ||
delay: 0.1, | ||
}} | ||
> | ||
<label | ||
className={cn( | ||
"text-[14px] leading-[20px] 2xl:text-lg 2xl:leading-[27px] text-neutral-4 text-left", | ||
)} | ||
> | ||
Stay updated and be among the first to receive exciting | ||
announcements, exclusive updates, and special offers from our | ||
project. Join us at the forefront of new discoveries! | ||
</label> | ||
</FadeIn> | ||
</div> | ||
|
||
{/* Form */} | ||
<FadeIn | ||
options={{ | ||
direction: "up", | ||
duration: 0.65, | ||
type: "tween", | ||
delay: 0.15, | ||
}} | ||
> | ||
<form className={cn("flex flex-col gap-[10px]")} onSubmit={onSubmit}> | ||
<div className={cn("relative")}> | ||
<input | ||
className={cn( | ||
`w-full bg-transparent h-[48px] lg:h-[75px] 2xl:h-[93px] outline-none text-neutral-5 text-[18px] leading-[27px] px-[16px] lg:py-[16px] border border-primary-cyan-500 hover:border-primary-cyan-800 rounded-xl select:hidden hover:transition focus:border-2 fo focus:shadow-button-active focus:border-primary-cyan-500 | ||
${errors.email && "border-accent-warning-500"} | ||
`, | ||
)} | ||
placeholder="Your email" | ||
type="email" | ||
{...register("email")} | ||
/> | ||
|
||
<button | ||
type="submit" | ||
className={cn( | ||
`absolute top-1/2 -translate-y-1/2 right-2.5 md:right-[16px] py-[6px] px-[20px] md:py-[10px] md:px-[24px] 2xl:py-[14px] 2xl:px-[32px] bg-primary-cyan-500 text-white rounded-lg border border-primary-cyan-500 hover:text-white hover:bg-black font-bold hover:transition-all duration-500 lg:text-neutral-10 lg:hover:text-primary-cyan-500 hover:shadow-button-hover | ||
${ | ||
errors.email && | ||
"bg-accent-warning-50 border-accent-warning-50 hover:bg-accent-warning-50 lg:hover:text-neutral-10 hover:shadow-none" | ||
} | ||
`, | ||
)} | ||
disabled={(errors.email && true) || isSubmitting} | ||
> | ||
<span | ||
className={`md:text-[18px] md:leading-[22px] 2xl:text-[22px] 2xl:leading-[33px] ${ | ||
errors.email && "text-neutral-10" | ||
}`} | ||
> | ||
{isSubmitting ? "Subscribing..." : "Subscribe"} | ||
</span> | ||
</button> | ||
</div> | ||
|
||
{errors?.email && ( | ||
<p | ||
className={cn( | ||
"flex gap-2 2xl:gap-[10px] font-normal text-base 2xl:text-[18px] leading-[27px] text-accent-warning-500", | ||
)} | ||
> | ||
<AlertTriangleIcon className={"w-4"} /> | ||
{errors.email.message} | ||
</p> | ||
)} | ||
</form> | ||
</FadeIn> | ||
</div> | ||
); | ||
} |
Oops, something went wrong.