358 lines
16 KiB
TypeScript
358 lines
16 KiB
TypeScript
'use client';
|
|
|
|
import { useState, useEffect, ChangeEvent, FormEvent } from 'react';
|
|
import type { Metadata } from 'next';
|
|
import { Phone, Mail, MapPin, Instagram, Facebook, Twitter, Youtube } from 'lucide-react';
|
|
import ReCAPTCHA from "react-google-recaptcha";
|
|
import axios from "axios";
|
|
import styles from './contact.module.css';
|
|
|
|
interface FormData {
|
|
name: string;
|
|
phone: string;
|
|
email: string;
|
|
subject: string;
|
|
message: string;
|
|
company: string;
|
|
}
|
|
|
|
interface FormErrors {
|
|
name?: string;
|
|
phone?: string;
|
|
email?: string;
|
|
subject?: string;
|
|
message?: string;
|
|
company?: string;
|
|
captcha?: string;
|
|
}
|
|
|
|
export default function ContactPage() {
|
|
const [formData, setFormData] = useState<FormData>({
|
|
name: '',
|
|
email: '',
|
|
company: '',
|
|
subject: '',
|
|
message: '',
|
|
phone: '',
|
|
});
|
|
|
|
const [formErrors, setFormErrors] = useState<FormErrors>({});
|
|
const [captchaToken, setCaptchaToken] = useState<string | null>(null);
|
|
const [alert, setAlert] = useState<{ show: boolean; type: string; message: string }>({
|
|
show: false,
|
|
type: "",
|
|
message: "",
|
|
});
|
|
|
|
const handleChange = (e: ChangeEvent<HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement>) => {
|
|
setFormData({
|
|
...formData,
|
|
[e.target.name]: e.target.value,
|
|
});
|
|
};
|
|
|
|
const handleCaptchaChange = (token: string | null) => {
|
|
setCaptchaToken(token);
|
|
};
|
|
|
|
const handleSubmit = async (e: FormEvent) => {
|
|
e.preventDefault();
|
|
|
|
const errors: FormErrors = {};
|
|
if (!formData.name.trim()) errors.name = "Name is required.";
|
|
if (!formData.phone.trim()) errors.phone = "Phone number is required.";
|
|
if (!formData.email.trim()) errors.email = "Email is required.";
|
|
if (!formData.subject.trim()) errors.subject = "Subject is required.";
|
|
if (!formData.message.trim()) errors.message = "Message is required.";
|
|
if (!captchaToken) errors.captcha = "Please verify the CAPTCHA.";
|
|
|
|
setFormErrors(errors);
|
|
if (Object.keys(errors).length > 0) return;
|
|
|
|
const emailData = {
|
|
...formData,
|
|
message: `
|
|
<b>Name:</b> ${formData.name}<br />
|
|
<b>Phone:</b> ${formData.phone}<br />
|
|
<b>Email:</b> ${formData.email}<br />
|
|
<b>Subject:</b> ${formData.subject}<br /><br />
|
|
<b>Message:</b><br />${formData.message}
|
|
`,
|
|
to: "info@metatroncubesolutions.com",
|
|
senderName: "SocialBuddy Contact Form",
|
|
recaptchaToken: captchaToken,
|
|
};
|
|
|
|
try {
|
|
const res = await axios.post("https://mailserver.metatronnest.com/send", emailData, {
|
|
headers: { "Content-Type": "application/json" },
|
|
});
|
|
|
|
setAlert({
|
|
show: true,
|
|
type: "success",
|
|
message: res?.data?.message || "Message sent successfully!",
|
|
});
|
|
|
|
setFormData({ name: "", phone: "", email: "", subject: "", message: "", company: "" });
|
|
setCaptchaToken(null);
|
|
setFormErrors({});
|
|
} catch {
|
|
setAlert({
|
|
show: true,
|
|
type: "danger",
|
|
message: "Failed to send message. Please try again later.",
|
|
});
|
|
}
|
|
};
|
|
|
|
useEffect(() => {
|
|
if (alert.show) {
|
|
const timer = setTimeout(() => {
|
|
setAlert(prev => ({ ...prev, show: false }));
|
|
}, 5000);
|
|
return () => clearTimeout(timer);
|
|
}
|
|
}, [alert.show]);
|
|
|
|
const contactInfoCards = [
|
|
{
|
|
icon: <MapPin size={32} />,
|
|
title: 'Address',
|
|
value: 'London Eye, London',
|
|
link: '#',
|
|
},
|
|
{
|
|
icon: <Mail size={32} />,
|
|
title: 'Email',
|
|
value: 'mail@nursee.com',
|
|
link: 'mailto:mail@nursee.com',
|
|
},
|
|
{
|
|
icon: <Phone size={32} />,
|
|
title: 'Phone',
|
|
value: '(+081) 5678 1234',
|
|
link: 'tel:+08156781234',
|
|
},
|
|
];
|
|
|
|
return (
|
|
<div className={styles.contactPage}>
|
|
{/* Hero Section */}
|
|
<section className={styles.hero}>
|
|
<div className="container">
|
|
<div className={styles.heroContent}>
|
|
<h1 className={styles.heroTitle}>Contact Us</h1>
|
|
<div className={styles.breadcrumb}>
|
|
<a href="/">Home</a> / <span>Contact</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
{/* Contact Info Cards */}
|
|
<section className="section">
|
|
<div className="container">
|
|
<div className={styles.contactGrid}>
|
|
{contactInfoCards.map((info, index) => (
|
|
<a key={index} href={info.link} className={styles.contactCard}>
|
|
<div className={styles.cardIcon}>{info.icon}</div>
|
|
<h3 className={styles.cardTitle}>{info.title}</h3>
|
|
<p className={styles.cardValue}>{info.value}</p>
|
|
</a>
|
|
))}
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
{/* Contact Form Section */}
|
|
<section className={`section ${styles.formSection}`}>
|
|
<div className="container">
|
|
<div className={styles.formContainer}>
|
|
{/* Left Side: Get In Touch Info */}
|
|
<div className={styles.getInTouchInfo}>
|
|
<h2 className={styles.sectionTitle}>Get In Touch</h2>
|
|
<p className={styles.sectionDesc}>
|
|
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut elit tellus, luctus nec ullamcorper mattis, pulvinar dapibus leo.
|
|
</p>
|
|
|
|
<div className={styles.infoGrid}>
|
|
<div className={styles.infoItem}>
|
|
<div className={styles.iconBox}><Phone size={20} /></div>
|
|
<div>
|
|
<h4 className={styles.infoLabel}>Phone</h4>
|
|
<p className={styles.infoValue}>(+081) 5678 1234</p>
|
|
</div>
|
|
</div>
|
|
<div className={styles.infoItem}>
|
|
<div className={styles.iconBox}><Mail size={20} /></div>
|
|
<div>
|
|
<h4 className={styles.infoLabel}>Email</h4>
|
|
<p className={styles.infoValue}>mail@nursee.com</p>
|
|
</div>
|
|
</div>
|
|
<div className={styles.infoItem}>
|
|
<div className={styles.iconBox}><MapPin size={20} /></div>
|
|
<div>
|
|
<h4 className={styles.infoLabel}>Address</h4>
|
|
<p className={styles.infoValue}>London Eye, London</p>
|
|
</div>
|
|
</div>
|
|
<div className={styles.infoItem}>
|
|
<div className={styles.iconBox}><Instagram size={20} /></div>
|
|
<div>
|
|
<h4 className={styles.infoLabel}>Instagram</h4>
|
|
<p className={styles.infoValue}>nursee.com</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div className={styles.socialRow}>
|
|
<span className={styles.socialLabel}>Social Media</span>
|
|
<div className={styles.socialIconsRow}>
|
|
<a href="#"><Facebook size={20} /></a>
|
|
<a href="#"><Twitter size={20} /></a>
|
|
<a href="#"><Youtube size={20} /></a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Right Side: Form */}
|
|
<div className={styles.formWrapper}>
|
|
{alert.show && (
|
|
<div className={`p-4 mb-4 text-sm rounded-lg ${alert.type === "success" ? "text-green-800 bg-green-50" : "text-red-800 bg-red-50"}`} role="alert">
|
|
{alert.message}
|
|
</div>
|
|
)}
|
|
<form className={styles.contactForm} onSubmit={handleSubmit}>
|
|
<div className={styles.formRow}>
|
|
<div className={styles.formGroup}>
|
|
<label htmlFor="email" className={styles.label}>Email</label>
|
|
<input
|
|
type="email"
|
|
id="email"
|
|
name="email"
|
|
placeholder="Email"
|
|
value={formData.email}
|
|
onChange={handleChange}
|
|
className={styles.input}
|
|
/>
|
|
{formErrors.email && <small className="text-red-500 text-xs mt-1">{formErrors.email}</small>}
|
|
</div>
|
|
<div className={styles.formGroup}>
|
|
<label htmlFor="name" className={styles.label}>Name</label>
|
|
<input
|
|
type="text"
|
|
id="name"
|
|
name="name"
|
|
placeholder="Name"
|
|
value={formData.name}
|
|
onChange={handleChange}
|
|
className={styles.input}
|
|
/>
|
|
{formErrors.name && <small className="text-red-500 text-xs mt-1">{formErrors.name}</small>}
|
|
</div>
|
|
</div>
|
|
|
|
<div className={styles.formGroup}>
|
|
<label htmlFor="phone" className={styles.label}>Phone</label>
|
|
<input
|
|
type="tel"
|
|
id="phone"
|
|
name="phone"
|
|
placeholder="Phone"
|
|
value={formData.phone}
|
|
onChange={handleChange}
|
|
className={styles.input}
|
|
/>
|
|
{formErrors.phone && <small className="text-red-500 text-xs mt-1">{formErrors.phone}</small>}
|
|
</div>
|
|
|
|
<div className={styles.formGroup}>
|
|
<label htmlFor="subject" className={styles.label}>Subject</label>
|
|
<input
|
|
type="text"
|
|
id="subject"
|
|
name="subject"
|
|
placeholder="Subject"
|
|
value={formData.subject}
|
|
onChange={handleChange}
|
|
className={styles.input}
|
|
/>
|
|
{formErrors.subject && <small className="text-red-500 text-xs mt-1">{formErrors.subject}</small>}
|
|
</div>
|
|
|
|
<div className={styles.formGroup}>
|
|
<label htmlFor="message" className={styles.label}>Message</label>
|
|
<textarea
|
|
id="message"
|
|
name="message"
|
|
placeholder="Message"
|
|
value={formData.message}
|
|
onChange={handleChange}
|
|
className={styles.textarea}
|
|
rows={5}
|
|
/>
|
|
{formErrors.message && <small className="text-red-500 text-xs mt-1">{formErrors.message}</small>}
|
|
</div>
|
|
|
|
<div className={`${styles.formGroup} mb-4`}>
|
|
<ReCAPTCHA
|
|
sitekey="6Lea8ZYrAAAAAHaghaLjDx_K084IFATZby7Rzqhl"
|
|
onChange={handleCaptchaChange}
|
|
/>
|
|
{formErrors.captcha && <small className="text-red-500 text-xs mt-1">{formErrors.captcha}</small>}
|
|
</div>
|
|
|
|
<button type="submit" className={styles.submitBtn}>
|
|
Submit Now
|
|
</button>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
{/* Map Section */}
|
|
<section className={styles.mapSection}>
|
|
<div className="container" style={{ maxWidth: '100%', padding: 0 }}>
|
|
<iframe
|
|
src="https://www.google.com/maps/embed?pb=!1m18!1m12!1m3!1d2483.546465492652!2d-0.1216834237199462!3d51.503189710986916!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x487604b900d26973%3A0x4291f3172409ea92!2slastminute.com%20London%20Eye!5e0!3m2!1sen!2suk!4v1709999999999!5m2!1sen!2suk"
|
|
width="100%"
|
|
height="400"
|
|
style={{ border: 0 }}
|
|
allowFullScreen
|
|
loading="lazy"
|
|
referrerPolicy="no-referrer-when-downgrade"
|
|
></iframe>
|
|
</div>
|
|
</section>
|
|
|
|
{/* FAQ Quick Links */}
|
|
{/* <section className={styles.quickLinks}>
|
|
<div className="container">
|
|
<h2 className={styles.quickLinksTitle}>Looking for something specific?</h2>
|
|
<div className={styles.linksGrid}>
|
|
<a href="/docs" className={styles.linkCard}>
|
|
<span className={styles.linkIcon}>📚</span>
|
|
<span className={styles.linkText}>Documentation</span>
|
|
</a>
|
|
<a href="/pricing" className={styles.linkCard}>
|
|
<span className={styles.linkIcon}>💰</span>
|
|
<span className={styles.linkText}>Pricing</span>
|
|
</a>
|
|
<a href="/blog" className={styles.linkCard}>
|
|
<span className={styles.linkIcon}>📝</span>
|
|
<span className={styles.linkText}>Blog</span>
|
|
</a>
|
|
<a href="/features" className={styles.linkCard}>
|
|
<span className={styles.linkIcon}>✨</span>
|
|
<span className={styles.linkText}>Features</span>
|
|
</a>
|
|
</div>
|
|
</div>
|
|
</section> */}
|
|
</div>
|
|
);
|
|
}
|