; // ----------------------------- // Component // -----------------------"> ; // ----------------------------- // Component // -----------------------"> ; // ----------------------------- // Component // -----------------------">

Screenshot 2025-09-15 at 8.09.30 PM.png

import React from "react";
import { useForm } from "react-hook-form";
import { z } from "zod";
import { zodResolver } from "@hookform/resolvers/zod";
// shadcn/ui primitives (make sure they're installed via `npx shadcn@latest add form input textarea button toast`)
import {
  Form,
  FormControl,
  FormField,
  FormItem,
  FormLabel,
  FormMessage,
} from "@/components/ui/form";
import { Input } from "@/components/ui/input";
import { Textarea } from "@/components/ui/textarea";
import { Button } from "@/components/ui/button";
import { useToast } from "@/hooks/use-toast";

// -----------------------------
// Validation schema
// -----------------------------
const ContactSchema = z.object({
  email: z.string().email("Enter a valid email"),
  message: z
    .string()
    .min(10, "Message should be at least 10 characters")
    .max(2000, "Message is too long"),
});

type ContactValues = z.infer<typeof ContactSchema>;

// -----------------------------
// Component
// -----------------------------
export default function ContactForm({
  className = "",
}: {
  className?: string;
}) {
  const { toast } = useToast();

  const form = useForm<ContactValues>({
    resolver: zodResolver(ContactSchema),
    defaultValues: { email: "", message: "" },
    mode: "onBlur",
  });

  async function onSubmit(values: ContactValues) {
    try {
      const res = await fetch("/api/contact", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify(values),
      });

      if (!res.ok) {
        const t = await res.text();
        throw new Error(t || "Failed to send message");
      }

      form.reset();
      toast({
        title: "Message sent",
        description: "I'll get back to you soon.",
      });
    } catch (err: any) {
      toast({
        title: "Something went wrong",
        description: err?.message ?? "Please try again in a moment.",
        variant: "destructive",
      });
    }
  }

  return (
    <div className={`max-w-2xl mx-auto ${className}`}>
      <div className="mb-6">
        <h1 className="text-2xl font-bold text-white mb-2">Get In Touch</h1>
        <p className="text-slate-400">
          Let's discuss your next photography project
        </p>
      </div>
      <Form {...form}>
        <form
          onSubmit={form.handleSubmit(onSubmit)}
          className="space-y-6 bg-slate-900/50 backdrop-blur-sm p-8 rounded-3xl border border-slate-700/50 shadow-2xl"
        >
          <FormField
            control={form.control}
            name="email"
            render={({ field }) => (
              <FormItem>
                <FormLabel className="text-slate-200 text-base font-medium">
                  Email Address
                </FormLabel>
                <FormControl>
                  <Input
                    placeholder="[email protected]"
                    type="email"
                    className="bg-slate-800/50 border-slate-600/50 text-white placeholder:text-slate-400 h-11 rounded-xl focus:border-blue-400 transition-colors"
                    {...field}
                  />
                </FormControl>
                <FormMessage className="text-red-400" />
              </FormItem>
            )}
          />

          <FormField
            control={form.control}
            name="message"
            render={({ field }) => (
              <FormItem>
                <FormLabel className="text-slate-200 text-base font-medium">
                  Your Message
                </FormLabel>
                <FormControl>
                  <Textarea
                    placeholder="Tell me about your photography needs, vision, or any questions you have..."
                    className="min-h-[120px] bg-slate-800/50 border-slate-600/50 text-white placeholder:text-slate-400 rounded-xl focus:border-blue-400 transition-colors resize-none"
                    {...field}
                  />
                </FormControl>
                <FormMessage className="text-red-400" />
              </FormItem>
            )}
          />

          <div className="flex items-center justify-between pt-2">
            <div className="text-slate-400 text-sm">
              I'll respond within 24 hours
            </div>
            <div className="bg-gradient-to-b from-stone-300/40 to-transparent p-[4px] rounded-[16px]">
              <div className="relative inline-flex items-center justify-center group">
                {/* Glow background */}
                <div
                  className="absolute inset-0 rounded-xl blur-lg opacity-60
               bg-gradient-to-r from-blue-500 via-sky-500 to-white
               transition-all duration-1000 group-hover:opacity-100 group-hover:duration-200"
                ></div>

                {/* Functional Send Button */}
                <button
                  type="submit"
                  disabled={form.formState.isSubmitting}
                  className="group relative inline-flex items-center justify-center text-base 
               rounded-xl bg-gray-900 px-8 py-3 font-semibold text-white
               transition-all duration-200 
               hover:bg-gray-800 hover:shadow-lg hover:-translate-y-0.5 hover:shadow-gray-600/30
               disabled:opacity-50 disabled:cursor-not-allowed"
                >
                  {form.formState.isSubmitting ? (
                    <>
                      Sending...
                      <svg
                        className="ml-2 w-4 h-4 animate-spin stroke-white"
                        xmlns="<http://www.w3.org/2000/svg>"
                        fill="none"
                        viewBox="0 0 24 24"
                      >
                        <circle
                          className="opacity-25"
                          cx="12"
                          cy="12"
                          r="10"
                          stroke="currentColor"
                          strokeWidth="4"
                        />
                        <path
                          className="opacity-75"
                          fill="currentColor"
                          d="M4 12a8 8 0 018-8v4l3-3-3-3v4a12 12 0 100 24v-4l-3 3 3 3v-4a8 8 0 01-8-8z"
                        />
                      </svg>
                    </>
                  ) : (
                    <>
                      Send Message
                      <svg
                        aria-hidden="true"
                        viewBox="0 0 10 10"
                        height="12"
                        width="12"
                        fill="none"
                        className="mt-0.5 ml-2 -mr-1 stroke-white stroke-2"
                      >
                        <path
                          d="M0 5h7"
                          className="transition opacity-0 group-hover:opacity-100"
                        />
                        <path
                          d="M1 1l4 4-4 4"
                          className="transition group-hover:translate-x-[3px]"
                        />
                      </svg>
                    </>
                  )}
                </button>
              </div>
            </div>
          </div>
        </form>
      </Form>
    </div>
  );
}

/* =============================================================
   BACKEND OPTIONS (pick ONE; do NOT run both)
   -------------------------------------------------------------
   1) Next.js App Router + Resend (preferred for serverless)
   2) Express server + Nodemailer (for Vite/CRA + own backend)
   ============================================================= */

/*
1) Next.js (app/api/contact/route.ts) + Resend
----------------------------------------------
Install:  npm i resend zod
Env:      RESEND_API_KEY=...  [email protected]  [email protected]

// app/api/contact/route.ts
import { NextResponse } from "next/server";
import { Resend } from "resend";
import { z } from "zod";

const Body = z.object({ email: z.string().email(), message: z.string().min(10).max(2000) });
const resend = new Resend(process.env.RESEND_API_KEY!);

export async function POST(req: Request) {
  try {
    const json = await req.json();
    const { email, message } = Body.parse(json);

    await resend.emails.send({
      from: process.env.CONTACT_FROM!,
      to: process.env.CONTACT_TO!,
      subject: `New contact from ${email}`,
      text: message,
    });

    return NextResponse.json({ ok: true });
  } catch (err: any) {
    console.error(err);
    return new NextResponse(err?.message || "Bad Request", { status: 400 });
  }
}

- Deploy on Vercel and map env vars. The client POST in ContactForm hits "/api/contact".
- For nicer emails, send `react` content with a simple JSX template using Resend.

2) Express + Nodemailer (Vite/CRA)
----------------------------------
Install:  npm i express nodemailer zod cors  &&  npm i -D @types/express
Env:      SMTP_HOST, SMTP_PORT, SMTP_USER, SMTP_PASS, CONTACT_TO, CONTACT_FROM

// server/index.ts
import */