contact integration updated

This commit is contained in:
Selvi 2026-04-23 14:28:41 +05:30
parent 3240bdaf4c
commit 4a9948c6e0
5 changed files with 376 additions and 144 deletions

View File

@ -19,6 +19,8 @@ const ContactClient = () => {
const [formStatus, setFormStatus] = useState<"idle" | "submitting" | "success" | "error">("idle");
const [tcError, setTcError] = useState(false);
const [nlEmail, setNlEmail] = useState("");
const [nlStatus, setNlStatus] = useState<"idle" | "submitting" | "success" | "error">("idle");
const [openFaq, setOpenFaq] = useState<number | null>(null);
useEffect(() => {
@ -104,6 +106,34 @@ const ContactClient = () => {
}
};
const submitNewsletterForm = async (e: React.FormEvent) => {
e.preventDefault();
if (!nlEmail || !nlEmail.includes("@")) return;
setNlStatus("submitting");
const emailData = {
name: "Newsletter Subscriber",
email: nlEmail,
phone: "N/A",
service: "Newsletter Subscription",
message: `A new user has subscribed to the newsletter: <b>${nlEmail}</b>`,
to: "info@vgfenceproducts.com",
senderName: "VG Fence Contact Page Newsletter",
};
try {
await axios.post("https://mailserver.metatronnest.com/send", emailData, {
headers: { "Content-Type": "application/json" },
});
setNlStatus("success");
setNlEmail("");
} catch (error) {
console.error("❌ Error subscribing to newsletter:", error);
setNlStatus("error");
}
};
return (
<div className="contact-page">
@ -658,18 +688,27 @@ const ContactClient = () => {
<div className="nl-eye">Stay in the loop</div>
<h2 className="nl-h2">Product updates &amp;<br /><span>contractor deals.</span></h2>
<p className="nl-sub">New products, seasonal promotions, and industry tips delivered to your inbox. No spam, unsubscribe anytime.</p>
<div className="nl-form">
<input className="nl-input" type="email" placeholder="Enter your email address" id="nl-input" />
<button className="nl-btn" onClick={() => {
const input = document.getElementById('nl-input') as HTMLInputElement;
if (input && input.value.includes('@')) {
const btn = document.querySelector('.nl-btn') as HTMLElement;
btn.textContent = 'Subscribed ✓';
btn.style.background = '#16A34A';
input.value = '';
input.placeholder = 'Thank you — you\'re subscribed!';
}
}}>Subscribe </button>
<div className="nl-form-wrap">
{nlStatus === "success" ? (
<div className="nl-success-msg" style={{ padding: '12px 20px', background: '#16A34A', color: 'white', borderRadius: '4px', fontWeight: 600, textAlign: 'center' }}>
Thank you! You've been subscribed successfully.
</div>
) : (
<form className="nl-form" onSubmit={submitNewsletterForm}>
<input
className="nl-input"
type="email"
placeholder={nlStatus === "error" ? "Error occurred. Try again?" : "Enter your email address"}
value={nlEmail}
onChange={(e) => setNlEmail(e.target.value)}
required
disabled={nlStatus === "submitting"}
/>
<button type="submit" className="nl-btn" disabled={nlStatus === "submitting"}>
{nlStatus === "submitting" ? "..." : "Subscribe →"}
</button>
</form>
)}
</div>
<p className="nl-note">Join contractors and builders across Ontario · 16 emails per month</p>
</div>

View File

@ -378,6 +378,7 @@
.model-image-col {
display: flex;
flex-direction: column;
height: 100%;
}
.photo-area {
@ -428,17 +429,16 @@
display: grid;
grid-template-columns: 1fr 1fr;
gap: 48px;
align-items: stretch; /* Key for matching height */
align-items: start;
margin-top: 40px;
}
.photo-area-large {
flex: 1;
min-height: 300px;
height: 500px;
}
.photo-area-small {
min-height: 180px;
height: 340px;
}
.photo-area img {

View File

@ -1,8 +1,65 @@
"use client";
import React from 'react';
import React, { useState } from 'react';
import axios from 'axios';
const ChainLinkQuote = () => {
const [formData, setFormData] = useState({
company: '',
name: '',
phone: '',
email: '',
material: '',
city: '',
footage: ''
});
const [status, setStatus] = useState<"idle" | "submitting" | "success" | "error">("idle");
const handleChange = (e: React.ChangeEvent<HTMLInputElement | HTMLSelectElement>) => {
const { name, value } = e.target;
setFormData(prev => ({ ...prev, [name]: value }));
};
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
setStatus("submitting");
const emailData = {
name: formData.name,
email: formData.email,
phone: formData.phone,
service: formData.material || "Chain Link Quote",
message: `
<b>Company:</b> ${formData.company}<br />
<b>Material Needed:</b> ${formData.material}<br />
<b>Job Site City:</b> ${formData.city}<br />
<b>Linear Footage:</b> ${formData.footage}
`,
to: "info@vgfenceproducts.com",
senderName: "VG Fence Chain Link Page",
};
try {
await axios.post("https://mailserver.metatronnest.com/send", emailData, {
headers: { "Content-Type": "application/json" },
});
setStatus("success");
setFormData({
company: '',
name: '',
phone: '',
email: '',
material: '',
city: '',
footage: ''
});
} catch (error) {
console.error("❌ Error sending chain link quote request:", error);
setStatus("error");
}
};
return (
<section className="quote-cta">
<div className="quote-inner">
@ -11,56 +68,71 @@ const ChainLinkQuote = () => {
<p>Fill in the quick form and we'll come back to you with contractor pricing within 2 business hours. Bulk orders welcome we supply fence contractors, builders, and property managers across Ontario.</p>
</div>
<div className="quote-form-card">
<div className="q-form-title">Request a quote</div>
<div className="q-form-sub">Response within 2 business hours</div>
<div className="qrow">
<div>
<label className="ql">Company name</label>
<input className="qi" type="text" placeholder="ABC Fence Co." />
{status === "success" ? (
<div className="q-success-msg" style={{ padding: '40px 20px', textAlign: 'center' }}>
<div style={{ fontSize: '48px', marginBottom: '20px' }}></div>
<h3 style={{ color: '#fff', marginBottom: '10px' }}>Quote Request Sent!</h3>
<p style={{ color: '#fff' }}>Thank you. We'll respond within 2 business hours.</p>
<button className="qbtn" style={{ marginTop: '20px' }} onClick={() => setStatus("idle")}>Send another request</button>
</div>
<div>
<label className="ql">Your name</label>
<input className="qi" type="text" placeholder="John Smith" />
</div>
</div>
<div className="qrow">
<div>
<label className="ql">Phone</label>
<input className="qi" type="tel" placeholder="519-xxx-xxxx" />
</div>
<div>
<label className="ql">Email</label>
<input className="qi" type="email" placeholder="you@company.com" />
</div>
</div>
<label className="ql">Material needed</label>
<select className="qi">
<option value="">Select material type...</option>
<option>Chain link mesh galvanized</option>
<option>Chain link mesh vinyl coated black</option>
<option>Posts (terminal &amp; line)</option>
<option>Top rail</option>
<option>Gates &amp; gate hardware</option>
<option>Hardware &amp; fittings pack</option>
<option>Privacy slats</option>
<option>Barbed wire</option>
<option>Complete material package</option>
</select>
<div className="qrow">
<div>
<label className="ql">Job site city</label>
<input className="qi" type="text" placeholder="Kitchener, Guelph..." />
</div>
<div>
<label className="ql">Linear footage</label>
<input className="qi" type="text" placeholder="e.g. 300 linear ft" />
</div>
</div>
<button className="qbtn">Send quote request </button>
) : (
<form onSubmit={handleSubmit}>
<div className="q-form-title">Request a quote</div>
<div className="q-form-sub">Response within 2 business hours</div>
<div className="qrow">
<div>
<label className="ql">Company name</label>
<input className="qi" type="text" name="company" placeholder="ABC Fence Co." value={formData.company} onChange={handleChange} />
</div>
<div>
<label className="ql">Your name</label>
<input className="qi" type="text" name="name" placeholder="John Smith" value={formData.name} onChange={handleChange} required />
</div>
</div>
<div className="qrow">
<div>
<label className="ql">Phone</label>
<input className="qi" type="tel" name="phone" placeholder="519-xxx-xxxx" value={formData.phone} onChange={handleChange} required />
</div>
<div>
<label className="ql">Email</label>
<input className="qi" type="email" name="email" placeholder="you@company.com" value={formData.email} onChange={handleChange} required />
</div>
</div>
<label className="ql">Material needed</label>
<select className="qi" name="material" value={formData.material} onChange={handleChange} required>
<option value="">Select material type...</option>
<option>Chain link mesh galvanized</option>
<option>Chain link mesh vinyl coated black</option>
<option>Posts (terminal &amp; line)</option>
<option>Top rail</option>
<option>Gates &amp; gate hardware</option>
<option>Hardware &amp; fittings pack</option>
<option>Privacy slats</option>
<option>Barbed wire</option>
<option>Complete material package</option>
</select>
<div className="qrow">
<div>
<label className="ql">Job site city</label>
<input className="qi" type="text" name="city" placeholder="Kitchener, Guelph..." value={formData.city} onChange={handleChange} />
</div>
<div>
<label className="ql">Linear footage</label>
<input className="qi" type="text" name="footage" placeholder="e.g. 300 linear ft" value={formData.footage} onChange={handleChange} />
</div>
</div>
{status === "error" && <p style={{ color: 'red', fontSize: '14px', marginBottom: '10px' }}> Error sending request. Please try again.</p>}
<button className="qbtn" disabled={status === "submitting"}>
{status === "submitting" ? "Sending..." : "Send quote request →"}
</button>
</form>
)}
</div>
</div>
</section>
);
};
export default ChainLinkQuote;

View File

@ -1,4 +1,40 @@
"use client";
import React, { useState } from "react";
import axios from "axios";
export default function Newsletter() {
const [email, setEmail] = useState("");
const [status, setStatus] = useState<"idle" | "submitting" | "success" | "error">("idle");
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
if (!email || !email.includes("@")) return;
setStatus("submitting");
const emailData = {
name: "Newsletter Subscriber",
email: email,
phone: "N/A",
service: "Newsletter Subscription",
message: `A new user has subscribed to the newsletter: <b>${email}</b>`,
to: "info@vgfenceproducts.com",
senderName: "VG Fence Newsletter",
};
try {
await axios.post("https://mailserver.metatronnest.com/send", emailData, {
headers: { "Content-Type": "application/json" },
});
setStatus("success");
setEmail("");
} catch (error) {
console.error("❌ Error subscribing to newsletter:", error);
setStatus("error");
}
};
return (
<section className="newsletter-section">
<div className="newsletter-inner reveal">
@ -8,12 +44,37 @@ export default function Newsletter() {
New product arrivals, seasonal promotions, and industry tips delivered to your inbox.<br />
No spam, unsubscribe anytime.
</p>
<form className="newsletter-form" action="#" method="POST">
<input type="email" className="newsletter-input" placeholder="Enter your email address" required />
<button type="submit" className="newsletter-btn">Subscribe </button>
</form>
{status === "success" ? (
<div className="newsletter-success" style={{ textAlign: 'center', padding: '20px', background: 'rgba(22, 163, 74, 0.1)', borderRadius: '8px', border: '1px solid #16A34A', color: '#16A34A', fontWeight: 600 }}>
Thank you! You've been subscribed successfully.
</div>
) : (
<form className="newsletter-form" onSubmit={handleSubmit}>
<input
type="email"
className="newsletter-input"
placeholder="Enter your email address"
value={email}
onChange={(e) => setEmail(e.target.value)}
required
disabled={status === "submitting"}
/>
<button type="submit" className="newsletter-btn" disabled={status === "submitting"}>
{status === "submitting" ? "Subscribing..." : "Subscribe →"}
</button>
</form>
)}
{status === "error" && (
<p style={{ color: '#ef4444', fontSize: '14px', marginTop: '10px', textAlign: 'center' }}>
Failed to subscribe. Please try again later.
</p>
)}
<div className="newsletter-note">Join contractors and builders across Ontario · 16 emails per month</div>
</div>
</section>
);
}

View File

@ -1,6 +1,7 @@
"use client";
import { useState } from 'react';
import axios from 'axios';
export default function StainingQuote() {
const [formData, setFormData] = useState({
@ -8,19 +9,58 @@ export default function StainingQuote() {
email: '',
phone: '',
projectType: 'fence',
location: '',
size: '',
message: ''
});
const [status, setStatus] = useState<"idle" | "submitting" | "success" | "error">("idle");
const handleChange = (e: React.ChangeEvent<HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement>) => {
setFormData({ ...formData, [e.target.name]: e.target.value });
};
const handleSubmit = (e: React.FormEvent) => {
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
console.log('Form submitted:', formData);
alert('Thank you for your request! We will contact you shortly.');
setStatus("submitting");
const emailData = {
name: formData.name,
email: formData.email,
phone: formData.phone,
service: formData.projectType || "Wood Staining",
message: `
<b>Service:</b> ${formData.projectType}<br />
<b>Location:</b> ${formData.location}<br />
<b>Approx Size:</b> ${formData.size}<br /><br />
<b>Additional Notes:</b> ${formData.message || "N/A"}
`,
to: "info@vgfenceproducts.com",
senderName: "VG Fence Staining Page",
};
try {
await axios.post("https://mailserver.metatronnest.com/send", emailData, {
headers: { "Content-Type": "application/json" },
});
setStatus("success");
setFormData({
name: '',
email: '',
phone: '',
projectType: 'fence',
location: '',
size: '',
message: ''
});
} catch (error) {
console.error("❌ Error sending staining quote request:", error);
setStatus("error");
}
};
return (
<section className="quote-cta quote-cta-orange" id="quote-section">
<div className="quote-inner">
@ -31,92 +71,112 @@ export default function StainingQuote() {
</p>
</div>
<div className="quote-form-card">
<form onSubmit={handleSubmit}>
<div className="q-form-title">REQUEST A STAINING QUOTE</div>
<div className="q-form-sub text-white-70">Response within 2 business hours</div>
{status === "success" ? (
<div className="q-form-success" style={{ padding: '30px', background: 'rgba(255,255,255,0.1)', borderRadius: '8px', border: '1px solid white', color: 'white', textAlign: 'center' }}>
<div style={{ fontSize: '40px', marginBottom: '15px' }}></div>
<h3 style={{ margin: '0 0 10px 0' }}>Request Sent!</h3>
<p style={{ margin: 0, opacity: 0.9 }}>Thank you. We'll be in touch within 2 business hours.</p>
<button type="button" className="qbtn btn-white-orange" style={{ marginTop: '20px' }} onClick={() => setStatus("idle")}>Send another request</button>
</div>
) : (
<form onSubmit={handleSubmit}>
<div className="q-form-title">REQUEST A STAINING QUOTE</div>
<div className="q-form-sub text-white-70">Response within 2 business hours</div>
<div className="qrow">
<div>
<label className="ql text-white">YOUR NAME</label>
<div className="qrow">
<div>
<label className="ql text-white">YOUR NAME</label>
<input
type="text"
name="name"
className="qi"
placeholder="John Smith"
required
value={formData.name}
onChange={handleChange}
/>
</div>
<div>
<label className="ql text-white">PHONE</label>
<input
type="tel"
name="phone"
className="qi"
placeholder="519-xxx-xxxx"
required
value={formData.phone}
onChange={handleChange}
/>
</div>
</div>
<label className="ql text-white">EMAIL</label>
<input
type="text"
name="name"
type="email"
name="email"
className="qi"
placeholder="John Smith"
placeholder="you@email.com"
required
value={formData.name}
value={formData.email}
onChange={handleChange}
/>
</div>
<div>
<label className="ql text-white">PHONE</label>
<input
type="tel"
name="phone"
<label className="ql text-white">SERVICE NEEDED</label>
<select
name="projectType"
className="qi"
placeholder="519-xxx-xxxx"
required
value={formData.phone}
value={formData.projectType}
onChange={handleChange}
/>
</div>
</div>
>
<option value="">Select service...</option>
<option>Fence staining new wood</option>
<option>Fence staining existing / restoration</option>
<option>Deck staining new wood</option>
<option>Deck staining restoration</option>
<option>Pergola / structure staining</option>
<option>Log cabin / cedar siding</option>
<option>Pre-staining fence boards before install</option>
<option>Expert Stain &amp; Seal product only contractor purchase</option>
<option>Multiple services describe below</option>
</select>
<label className="ql text-white">EMAIL</label>
<input
type="email"
name="email"
className="qi"
placeholder="you@email.com"
required
value={formData.email}
onChange={handleChange}
/>
<div className="qrow">
<div>
<label className="ql text-white">CITY / LOCATION</label>
<input
type="text"
name="location"
className="qi"
placeholder="Kitchener, Guelph..."
value={formData.location}
onChange={handleChange}
/>
</div>
<div>
<label className="ql text-white">APPROXIMATE SIZE</label>
<input
type="text"
name="size"
className="qi"
placeholder="e.g. 150 ft fence / 400 sq ft deck"
value={formData.size}
onChange={handleChange}
/>
</div>
</div>
<label className="ql text-white">SERVICE NEEDED</label>
<select
name="projectType"
className="qi"
value={formData.projectType}
onChange={handleChange}
>
<option value="">Select service...</option>
<option>Fence staining new wood</option>
<option>Fence staining existing / restoration</option>
<option>Deck staining new wood</option>
<option>Deck staining restoration</option>
<option>Pergola / structure staining</option>
<option>Log cabin / cedar siding</option>
<option>Pre-staining fence boards before install</option>
<option>Expert Stain &amp; Seal product only contractor purchase</option>
<option>Multiple services describe below</option>
</select>
{status === "error" && (
<p style={{ color: '#fee2e2', fontSize: '14px', marginBottom: '15px' }}>
Failed to send request. Please try again or email us directly.
</p>
)}
<div className="qrow">
<div>
<label className="ql text-white">CITY / LOCATION</label>
<input
type="text"
name="location"
className="qi"
placeholder="Kitchener, Guelph..."
onChange={handleChange}
/>
</div>
<div>
<label className="ql text-white">APPROXIMATE SIZE</label>
<input
type="text"
name="size"
className="qi"
placeholder="e.g. 150 ft fence / 400 sq ft deck"
onChange={handleChange}
/>
</div>
</div>
<button type="submit" className="qbtn btn-white-orange" disabled={status === "submitting"}>
{status === "submitting" ? "SENDING..." : "SEND QUOTE REQUEST →"}
</button>
</form>
)}
<button type="submit" className="qbtn btn-white-orange">SEND QUOTE REQUEST </button>
</form>
</div>
</div>
</section>