diff --git a/README.md b/README.md index 30fe18576..2dc2df070 100644 --- a/README.md +++ b/README.md @@ -105,6 +105,7 @@ To run the project locally: 2. Visit `http://localhost:3000` in your browser. ### Recommended Extensions + - Prettier - Open your command palette, choose your default formatter to be Prettier, and enable format on save. - ESLint diff --git a/app/(auth)/actions.ts b/app/(auth)/actions.ts index 3ebb98f20..bb766821b 100644 --- a/app/(auth)/actions.ts +++ b/app/(auth)/actions.ts @@ -91,6 +91,30 @@ export async function signup(formData: FormData) { redirect("/verification?email=" + data.email); } +// Contact form submission +export async function contactSubmit(formData: FormData) { + const supabase = createClient(); + + const { error } = await supabase.from("contact").insert([ + { + first_name: formData.get("first-name") as string, + last_name: formData.get("last-name") as string, + email: formData.get("email") as string, + company_name: formData.get("company-name") as string, + organisation_size: formData.get("organisation-size") as string, + job_title: formData.get("job-title") as string, + phone_number: formData.get("phone-number") as string, + message: formData.get("message") as string, + }, + ]); + + if (error) { + return { error: error.message }; + } + + revalidatePath("/", "layout"); +} + // OAuth sign-in with Google or GitHub export async function signinWithOAuth( provider: Provider, diff --git a/app/contact/page.tsx b/app/contact/page.tsx new file mode 100644 index 000000000..90ab64f9a --- /dev/null +++ b/app/contact/page.tsx @@ -0,0 +1,17 @@ +import ContactUs from "@/components/contact"; +import { constructMetadata } from "@/lib/utils"; +import { Metadata } from "next/types"; + +export const metadata: Metadata = constructMetadata({ + title: "Contact Us", + description: "Contact PearAI.", + canonical: "/contact", +}); + +export default function Pricing() { + return ( + <> + + + ); +} diff --git a/components/contact.tsx b/components/contact.tsx new file mode 100644 index 000000000..a998865bb --- /dev/null +++ b/components/contact.tsx @@ -0,0 +1,297 @@ +"use client"; +import Link from "next/link"; +import { useState } from "react"; +import { signup, signinWithOAuth, contactSubmit } from "@/app/(auth)/actions"; +import { Provider } from "@supabase/supabase-js"; +import { zodResolver } from "@hookform/resolvers/zod"; +import { useForm } from "react-hook-form"; +import { Button } from "@/components/ui/button"; +import { Input } from "@/components/ui/input"; +import { Select } from "@/components/ui/select"; +import { + Form, + FormField, + FormItem, + FormLabel, + FormControl, + FormMessage, +} from "@/components/ui/form"; +import { contactSchema, ContactFormData } from "@/utils/form-schema"; +import { toast } from "sonner"; +import { useRouter } from "next/navigation"; + +const organisationSizes = [ + { value: "1-10", label: "1-10 employees" }, + { value: "11-50", label: "11-50 employees" }, + { value: "51-200", label: "51-200 employees" }, + { value: "201-500", label: "201-500 employees" }, + { value: "501-1000", label: "501-1000 employees" }, + { value: "1001+", label: "1001+ employees" }, +]; + +export default function ContactUs() { + const [isSubmitting, setIsSubmitting] = useState(false); + const [errorMessage, setErrorMessage] = useState(null); + const form = useForm({ + resolver: zodResolver(contactSchema), + defaultValues: { + first_name: "", + last_name: "", + email: "", + job_title: "", + company_name: "", + organisation_size: "", + phone_number: "", + message: "", + }, + }); + const router = useRouter(); + + const handleContactSubmit = async (data: ContactFormData) => { + if (isSubmitting) return; + setIsSubmitting(true); + setErrorMessage(null); + + try { + const formData = new FormData(); + formData.append("first-name", data.first_name); + formData.append("last-name", data.last_name); + formData.append("email", data.email); + formData.append("job-title", data.job_title); + formData.append("company-name", data.company_name || ""); + formData.append("organisation-size", data.organisation_size); + formData.append("phone-number", data.phone_number || ""); + formData.append("message", data.message); + + const response = await contactSubmit(formData); + if (response?.error) { + setErrorMessage(response.error); + } else { + toast.success("Successfully submitted! We will get back to you soon."); + router.push("/about"); + } + } catch (error) { + setErrorMessage("An unexpected error occurred. Please try again."); + } finally { + setIsSubmitting(false); + } + }; + + return ( +
+
+
+
+

+ Looking for a custom{" "} + pricing option? Get in touch! +

+
+ +
+
+