Fertig
This commit is contained in:
136
components/home-cta-section.tsx
Normal file
136
components/home-cta-section.tsx
Normal 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 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>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user