project setup

This commit is contained in:
Sone
2025-11-02 10:00:53 +01:00
parent 75bd171804
commit 7cb4c5345e
51 changed files with 3616 additions and 0 deletions
+218
View File
@@ -0,0 +1,218 @@
"use client";
import { useForm, SubmitHandler } from "react-hook-form";
import { z } from "zod";
import { zodResolver } from "@hookform/resolvers/zod";
import { contactSchema } from "@/schemas/schemas";
import { toast } from "react-toastify";
type FormValues = z.infer<typeof contactSchema>;
const GetStartedPage = () => {
const {
register,
handleSubmit,
formState: { errors, isSubmitting },
reset,
watch,
setValue,
} = useForm<FormValues>({ resolver: zodResolver(contactSchema) });
const onSubmit: SubmitHandler<FormValues> = async (data) => {
try {
const res = await fetch("/api/contact", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(data),
});
if (!res.ok) throw new Error("Request failed");
toast.success("Thank you! We'll be in touch.");
reset();
} catch (e) {
toast.error("Failed to save contact. Please try again.");
}
};
return (
<div className="mx-auto w-full max-w-6xl px-4 sm:px-6 lg:px-8 py-6 sm:py-12">
<div className="text-center mb-6">
<h1 className="text-2xl md:text-3xl font-mono font-extrabold">
Join Us on This Journey
</h1>
<p className="mt-4 mb-4 max-w-4xl mx-auto text-sm sm:text-base font-mono">
Be a part of something innovative. As our early adapters, you will be
one of the key players making a change in how staying safe online is
important yet effortless. You will get exclusive early access to our
newest solutions and influence the development, while staying
protected in the process.
</p>
</div>
<div className="relative rounded-3xl border-4 border-[var(--color-3)] px-10 sm:px-14 py-8 shadow-[0_0_20px_rgba(255,255,255,0.5)]">
<form
onSubmit={handleSubmit(onSubmit)}
className="relative z-10 space-y-4"
>
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
<div>
<label className="sr-only">First name</label>
<input
placeholder="First name"
{...register("firstName")}
className="w-full border border-[var(--color-3)] outline-none rounded-sm px-3 py-0.5 text-sm"
/>
{errors.firstName && (
<p className="!text-[var(--color-8)] opacity-100 text-xs mt-1">
{errors.firstName.message}
</p>
)}
</div>
<div>
<label className="sr-only">Last name</label>
<input
placeholder="Last name"
{...register("lastName")}
className="w-full border border-[var(--color-3)] outline-none rounded-sm px-3 py-0.5 text-sm"
/>
{errors.lastName && (
<p className="!text-[var(--color-8)] opacity-100 text-xs mt-1">
{errors.lastName.message}
</p>
)}
</div>
<div>
<label className="sr-only">Company name</label>
<input
placeholder="Company name"
{...register("companyName")}
className="w-full border border-[var(--color-3)] outline-none rounded-sm px-3 py-0.5 text-sm"
/>
{errors.companyName && (
<p className="!text-[var(--color-8)] opacity-100 text-xs mt-1">
{errors.companyName.message}
</p>
)}
</div>
<div>
<label className="sr-only">Address</label>
<input
placeholder="Address"
{...register("address")}
className="w-full border border-[var(--color-3)] outline-none rounded-sm px-3 py-0.5 text-sm"
/>
{errors.address && (
<p className="!text-[var(--color-8)] opacity-100 text-xs mt-1">
{errors.address.message}
</p>
)}
</div>
<div>
<label className="sr-only">Email</label>
<input
placeholder="Email"
type="email"
{...register("email")}
className="w-full border border-[var(--color-3)] outline-none rounded-sm px-3 py-0.5 text-sm"
/>
{errors.email && (
<p className="!text-[var(--color-8)] opacity-100 text-xs mt-1">
{errors.email.message}
</p>
)}
</div>
<div>
<label className="sr-only">Phone number</label>
<input
placeholder="Phone number"
{...register("phone")}
className="w-full border border-[var(--color-3)] outline-none rounded-sm px-3 py-0.5 text-sm"
/>
{errors.phone && (
<p className="!text-[var(--color-8)] opacity-100 text-xs mt-1">
{errors.phone.message}
</p>
)}
</div>
</div>
<div>
<label className="sr-only">Industry type</label>
<input
placeholder="Industry type"
{...register("industry")}
className="w-full border border-[var(--color-3)] outline-none rounded-sm px-3 py-0.5 text-sm"
/>
{errors.industry && (
<p className="!text-[var(--color-8)] opacity-100 text-xs mt-1">
{errors.industry.message}
</p>
)}
</div>
<div>
<label className="sr-only">Additional notes</label>
<textarea
placeholder="Additional notes"
rows={8}
{...register("notes")}
className="w-full border border-[var(--color-3)] outline-none rounded-sm px-3 py-1 text-sm"
/>
</div>
<div className="flex items-center gap-2 ml-6">
<div className="relative">
<input
type="checkbox"
id="subscribe"
{...register("subscribe")}
className="sr-only"
/>
<div
className={`w-4 h-4 border-2 border-[var(--color-3)] cursor-pointer flex items-center justify-center transition-colors shadow-[0_0_10px_rgba(255,255,255,0.2)] ${
watch("subscribe") ? "bg-[var(--color-3)]" : "bg-transparent"
}`}
onClick={() => setValue("subscribe", !watch("subscribe"))}
>
{watch("subscribe") && (
<svg
className="w-3 h-3 text-white"
fill="currentColor"
viewBox="0 0 20 20"
>
<path
fillRule="evenodd"
d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z"
clipRule="evenodd"
/>
</svg>
)}
</div>
</div>
<label
htmlFor="subscribe"
className="text-xs sm:text-sm font-mono cursor-pointer"
>
Sign up for our email list for updates, promotions, and more.
</label>
</div>
<div className="flex justify-center pt-2">
<button
type="submit"
disabled={isSubmitting}
className="px-6 py-3 font-mono text-sm text-white bg-[var(--color-3)] rounded-xl disabled:opacity-50 cursor-pointer"
>
{isSubmitting ? "Sending..." : "Send"}
</button>
</div>
</form>
{/* White glow */}
<div className="pointer-events-none absolute inset-0 rounded-3xl shadow-[0_0_5px_rgba(255,255,255,0.4)] z-0"></div>
</div>
</div>
);
};
export default GetStartedPage;