Skip to content

Commit

Permalink
Merge pull request #14 from scalarorg/develop
Browse files Browse the repository at this point in the history
feat: add 404 page
  • Loading branch information
huongnguyenduc authored Feb 6, 2024
2 parents 9323322 + b3077c6 commit 172e882
Show file tree
Hide file tree
Showing 9 changed files with 325 additions and 191 deletions.
87 changes: 87 additions & 0 deletions app/(routes)/404/_components/hero-not-found.tsx
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>
);
}
28 changes: 28 additions & 0 deletions app/(routes)/404/page.tsx
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 app/(routes)/_components/cta/components/subscription.tsx
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>
);
}
Loading

0 comments on commit 172e882

Please sign in to comment.