This commit is contained in:
2026-03-10 18:31:23 +01:00
parent 66225e4662
commit 4455605394
180 changed files with 9005 additions and 0 deletions

View File

@@ -0,0 +1,136 @@
"use client";
import { FormEvent, useState } from "react";
import Link from "next/link";
import { motion } from "framer-motion";
import { siteConfig } from "@/data/site-content";
type Status = { success: boolean; message: string } | null;
export function HomeCTASection() {
const [formData, setFormData] = useState({ name: "", phone: "", message: "" });
const [status, setStatus] = useState<Status>(null);
const [submitting, setSubmitting] = useState(false);
async function handleSubmit(e: FormEvent<HTMLFormElement>) {
e.preventDefault();
setSubmitting(true);
setStatus(null);
try {
const res = await fetch("/api/contact", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ ...formData, email: "", projectType: "general-question" }),
});
const data = await res.json() as { success: boolean; message: string };
setStatus(data);
if (data.success) setFormData({ name: "", phone: "", message: "" });
} catch {
setStatus({ success: false, message: "Something went wrong. Please call us directly." });
} finally {
setSubmitting(false);
}
}
return (
<section className="home-cta-section">
<div className="container">
<div className="home-cta-grid">
{/* Left — copy */}
<motion.div
className="home-cta-copy"
initial={{ opacity: 0, x: -30 }}
whileInView={{ opacity: 1, x: 0 }}
transition={{ duration: 0.6, ease: "easeOut" }}
viewport={{ once: true, amount: 0.3 }}
>
<span className="eyebrow" style={{ color: "var(--primary)" }}>GET STARTED</span>
<h2>Ready to Start Your Project?</h2>
<p>
Visit our yard or drop us a message. We'll get back to you with the right
materials, quantities, and delivery details.
</p>
<div className="home-cta-contact-items">
<a href={siteConfig.phoneHref} className="home-cta-contact-item">
<span className="home-cta-contact-icon">📞</span>
<span>{siteConfig.phoneDisplay}</span>
</a>
<div className="home-cta-contact-item">
<span className="home-cta-contact-icon">📍</span>
<span>{siteConfig.address.street}, {siteConfig.address.cityStateZip}</span>
</div>
<div className="home-cta-contact-item">
<span className="home-cta-contact-icon">🕐</span>
<span>Mon Fri &nbsp;8 AM 5 PM</span>
</div>
</div>
<Link href="/contact" className="button button-outline home-cta-full-link">
Full Contact Page
</Link>
</motion.div>
{/* Right — quick form */}
<motion.div
className="home-cta-form-wrap"
initial={{ opacity: 0, x: 30 }}
whileInView={{ opacity: 1, x: 0 }}
transition={{ duration: 0.6, ease: "easeOut", delay: 0.1 }}
viewport={{ once: true, amount: 0.3 }}
>
<div className="home-cta-form-card">
<h3>Send a Quick Message</h3>
<p style={{ fontSize: "0.875rem", marginBottom: "1.5rem" }}>
We'll respond during business hours.
</p>
{status?.success ? (
<div className="home-cta-success">
<span></span>
<p>{status.message}</p>
</div>
) : (
<form onSubmit={handleSubmit} className="home-cta-form" noValidate>
<div className="home-cta-row">
<input
type="text"
placeholder="Your name"
required
value={formData.name}
onChange={(e) => setFormData((p) => ({ ...p, name: e.target.value }))}
className="home-cta-input"
/>
<input
type="tel"
placeholder="Phone number"
value={formData.phone}
onChange={(e) => setFormData((p) => ({ ...p, phone: e.target.value }))}
className="home-cta-input"
/>
</div>
<textarea
placeholder="What material do you need? Approximate quantity?"
rows={4}
value={formData.message}
onChange={(e) => setFormData((p) => ({ ...p, message: e.target.value }))}
className="home-cta-input home-cta-textarea"
/>
{status && !status.success && (
<p className="home-cta-error">{status.message}</p>
)}
<button
type="submit"
className="button button-primary"
disabled={submitting}
style={{ width: "100%" }}
>
{submitting ? "Sending…" : "Send Message →"}
</button>
</form>
)}
</div>
</motion.div>
</div>
</div>
</section>
);
}