jingrow/components/contact/Contact1.jsx

339 lines
17 KiB
JavaScript

"use client";
import React, { useEffect, useState } from "react";
import axios from "axios";
export default function Contact1({ ssrData }) {
const [data, setData] = useState(ssrData || null);
const [loading, setLoading] = useState(!ssrData);
const [error, setError] = useState(null);
const [modal, setModal] = useState({ open: false, message: '', type: 'success' });
useEffect(() => {
if (!ssrData) {
setLoading(true);
axios.get("/api/get-component-data", { params: { component_name: "Contact" } })
.then(res => setData(res.data.data))
.catch(() => setError("Failed to get Contact data"))
.finally(() => setLoading(false));
} else {
setLoading(false);
}
}, [ssrData]);
if (loading) return <div className="text-center py-20">Loading...</div>;
if (error) return null;
if (!data) return null;
const contacts = Array.isArray(data.items) ? data.items : [];
const [form, setForm] = useState({
name: '',
phone: '',
email: '',
department: '',
message: ''
});
const [submitting, setSubmitting] = useState(false);
const [submitResult, setSubmitResult] = useState(null);
function handleInputChange(e) {
const { name, value } = e.target;
setForm(prev => ({ ...prev, [name]: value }));
}
async function handleSubmit(e) {
e.preventDefault();
setSubmitting(true);
setSubmitResult(null);
try {
const content = [
`Name: ${form.name}`,
`Phone: ${form.phone}`,
`Email: ${form.email}`,
`Department: ${form.department}`,
`Message:<br>${form.message.replace(/\n/g, '<br>')}`
].join("<br>");
const res = await axios.post('/api/send-email', {
subject: `Website Contact Form: ${form.name}`,
content
});
if (res.data.success) {
setModal({ open: true, message: res.data.message || 'Email sent successfully!', type: 'success' });
setSubmitResult(null);
setForm({ name: '', phone: '', email: '', department: '', message: '' });
} else {
setModal({ open: true, message: res.data.error || 'Failed to send', type: 'error' });
setSubmitResult(null);
}
} catch (err) {
setModal({ open: true, message: err?.response?.data?.error || err.message || 'Failed to send', type: 'error' });
setSubmitResult(null);
} finally {
setSubmitting(false);
}
}
function closeModal() {
setModal({ open: false, message: '', type: 'success' });
}
return (
<section className="wrapper !bg-[#ffffff] relative border-0 upper-end before:top-[-4rem] before:border-l-transparent before:border-r-[100vw] before:border-t-[4rem] before:border-[#fefefe] before:content-[''] before:block before:absolute before:z-0 before:border-y-transparent before:border-0 before:border-solid before:right-0">
<div className="container pb-12">
<div className="flex flex-wrap mx-[-15px] !mb-[4.5rem] md:!mb-24">
<div className="xl:w-10/12 w-full flex-[0_0_auto] !px-[15px] max-w-full !mx-auto !mt-[-9rem]">
<div className="card">
<div className="flex flex-wrap mx-0">
<div className="xl:w-6/12 lg:w-6/12 w-full flex-[0_0_auto] max-w-full !self-stretch">
<div className="map map-full rounded-t-[0.4rem] rounded-lg-start h-full min-h-[15rem]">
<iframe
src="https://www.google.com/maps/embed?pb=!1m14!1m8!1m3!1d3308.116930443662!2d-117.6923042!3d33.9895302!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x80dcccd7e575dffd%3A0x30aebc3ca15ed41d!2s14508%20Central%20Ave%2C%20Chino%2C%20CA%2091710%2C%20USA!5e0!3m2!1sen!2sjp!4v1712719609523!5m2!1sen!2sjp"
style={{ width: "100%", height: "100%", border: 0 }}
allowFullScreen=""
/>
</div>
</div>
<div className="xl:w-6/12 lg:w-6/12 w-full flex-[0_0_auto] xl:!px-[35px] lg:!px-[20px] !px-[15px] !my-[50px] max-w-full">
<div className="flex flex-col gap-5">
{contacts.map((item, idx) => (
<div className="flex flex-row items-start gap-3" key={idx}>
{(item.item_html_code || item.item_icon) && (
<div className="w-8 h-8 flex items-center justify-center text-xl">
{item.item_html_code ? (
<span style={{ display: 'inline-block', width: '2rem', height: '2rem' }}
dangerouslySetInnerHTML={{ __html: item.item_html_code }} />
) : (
<img src={item.item_icon} alt="icon" style={{ width: '2rem', height: '2rem', objectFit: 'contain' }} />
)}
</div>
)}
<div className="min-w-[90px]">
{item.item_title}
</div>
<div className="break-all">
{/(mail)/i.test(item.item_title) ? (
<a href={`mailto:${item.item_subtitle || item.item_value || ''}`} className="!text-inherit hover:!text-[#1fc76f]">
{item.item_subtitle || item.item_value || ''}
</a>
) : /(phone)/i.test(item.item_title) ? (
<a href={`tel:${item.item_subtitle || item.item_value || ''}`} className="hover:underline">
{item.item_subtitle || item.item_value || ''}
</a>
) : (
<span>{item.item_subtitle || item.item_value || ''}</span>
)}
</div>
</div>
))}
</div>
</div>
{/*/column */}
</div>
{/*/.row */}
</div>
{/* /.card */}
</div>
{/* /column */}
</div>
{/* /.row */}
<div className="flex flex-wrap mx-[-15px]">
<div className="xl:w-8/12 xl:!ml-[16.66666667%] lg:w-10/12 lg:!ml-[8.33333333%] w-full flex-[0_0_auto] !px-[15px] max-w-full">
<h2 className="!text-[calc(1.305rem_+_0.66vw)] font-bold xl:!text-[1.8rem] !leading-[1.3] !mb-3 !text-center">
{data.title}
</h2>
<p className="lead !leading-[1.65] text-[0.9rem] font-medium !text-center !mb-10">
{data.description}
</p>
<form
className="contact-form needs-validation"
onSubmit={handleSubmit}
>
<div className="messages" />
{/* Modal for feedback */}
{modal.open && (
<div style={{
position: 'fixed',
top: 0,
left: 0,
width: '100vw',
height: '100vh',
background: 'rgba(0,0,0,0.3)',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
zIndex: 9999
}}>
<div style={{
background: '#fff',
borderRadius: '16px',
padding: '2.5rem 3.5rem',
minWidth: '390px',
maxWidth: '96vw',
boxShadow: '0 8px 32px rgba(0,0,0,0.18)',
textAlign: 'center',
color: modal.type === 'success' ? '#1fc76f' : '#e53e3e',
fontWeight: 500
}}>
<div style={{ fontSize: '1.1rem', marginBottom: '1.5rem' }}>{modal.message}</div>
<button
type="button"
onClick={closeModal}
style={{
background: modal.type === 'success' ? '#1fc76f' : '#e53e3e',
color: '#fff',
border: 'none',
borderRadius: '24px',
padding: '0.5rem 2rem',
fontSize: '1rem',
cursor: 'pointer',
boxShadow: '0 2px 8px rgba(0,0,0,0.08)'
}}
>OK</button>
</div>
</div>
)}
<div className="flex flex-wrap mx-[-10px]">
<div className="xl:w-6/12 lg:w-6/12 md:w-6/12 w-full flex-[0_0_auto] !px-[15px] max-w-full">
<div className="form-floating relative !mb-4">
<input
id="form_name"
type="text"
name="name"
className="form-control relative block w-full text-[.75rem] font-medium !text-[#60697b] bg-[#fefefe] bg-clip-padding border shadow-[0_0_1.25rem_rgba(30,34,40,0.04)] rounded-[0.4rem] border-solid border-[rgba(8,60,130,0.07)] transition-[border-color] duration-[0.15s] ease-in-out focus:shadow-[0_0_1.25rem_rgba(30,34,40,0.04),unset] focus-visible:!border-[rgba(63,120,224,0.5)] placeholder:!text-[#959ca9] placeholder:opacity-100 m-0 !pr-9 p-[.6rem_1rem] h-[calc(2.5rem_+_2px)] min-h-[calc(2.5rem_+_2px)] !leading-[1.25]"
placeholder=""
required
value={form.name}
onChange={handleInputChange}
/>
<label
htmlFor="form_name"
className="!text-[#959ca9] !mb-2 !inline-block text-[.75rem] !absolute !z-[2] h-full overflow-hidden text-start text-ellipsis whitespace-nowrap pointer-events-none border origin-[0_0] px-4 py-[0.6rem] border-solid border-transparent left-0 top-0 font-Manrope"
>
Name *
</label>
<div className="valid-feedback">Looks good!</div>
<div className="invalid-feedback">
Please enter your first name.
</div>
</div>
</div>
{/* /column */}
<div className="xl:w-6/12 lg:w-6/12 md:w-6/12 w-full flex-[0_0_auto] !px-[15px] max-w-full">
<div className="form-floating relative !mb-4">
<input
id="form_phone"
type="text"
name="phone"
className="form-control relative block w-full text-[.75rem] font-medium !text-[#60697b] bg-[#fefefe] bg-clip-padding border shadow-[0_0_1.25rem_rgba(30,34,40,0.04)] rounded-[0.4rem] border-solid border-[rgba(8,60,130,0.07)] transition-[border-color] duration-[0.15s] ease-in-out focus:shadow-[0_0_1.25rem_rgba(30,34,40,0.04),unset] focus-visible:!border-[rgba(63,120,224,0.5)] placeholder:!text-[#959ca9] placeholder:opacity-100 m-0 !pr-9 p-[.6rem_1rem] h-[calc(2.5rem_+_2px)] min-h-[calc(2.5rem_+_2px)] !leading-[1.25]"
placeholder=""
value={form.phone}
onChange={handleInputChange}
/>
<label
htmlFor="form_phone"
className="!text-[#959ca9] !mb-2 !inline-block text-[.75rem] !absolute !z-[2] h-full overflow-hidden text-start text-ellipsis whitespace-nowrap pointer-events-none border origin-[0_0] px-4 py-[0.6rem] border-solid border-transparent left-0 top-0 font-Manrope"
>
Phone
</label>
<div className="valid-feedback">Looks good!</div>
<div className="invalid-feedback">
Please enter your phone number.
</div>
</div>
</div>
{/* /column */}
<div className="xl:w-6/12 lg:w-6/12 md:w-6/12 w-full flex-[0_0_auto] !px-[15px] max-w-full">
<div className="form-floating relative !mb-4">
<input
id="form_email"
type="email"
name="email"
className="form-control relative block w-full text-[.75rem] font-medium !text-[#60697b] bg-[#fefefe] bg-clip-padding border shadow-[0_0_1.25rem_rgba(30,34,40,0.04)] rounded-[0.4rem] border-solid border-[rgba(8,60,130,0.07)] transition-[border-color] duration-[0.15s] ease-in-out focus:shadow-[0_0_1.25rem_rgba(30,34,40,0.04),unset] focus-visible:!border-[rgba(63,120,224,0.5)] placeholder:!text-[#959ca9] placeholder:opacity-100 m-0 !pr-9 p-[.6rem_1rem] h-[calc(2.5rem_+_2px)] min-h-[calc(2.5rem_+_2px)] !leading-[1.25]"
placeholder=""
required
value={form.email}
onChange={handleInputChange}
/>
<label
htmlFor="form_email"
className="!text-[#959ca9] !mb-2 !inline-block text-[.75rem] !absolute !z-[2] h-full overflow-hidden text-start text-ellipsis whitespace-nowrap pointer-events-none border origin-[0_0] px-4 py-[0.6rem] border-solid border-transparent left-0 top-0 font-Manrope"
>
Email *
</label>
<div className="valid-feedback">Looks good!</div>
<div className="invalid-feedback">
Please provide a valid email address.
</div>
</div>
</div>
{/* /column */}
<div className="xl:w-6/12 lg:w-6/12 md:w-6/12 w-full flex-[0_0_auto] !px-[15px] max-w-full">
<div className="form-select-wrapper !mb-4">
<select
className="form-select"
id="form-select"
name="department"
value={form.department}
onChange={handleInputChange}
>
<option value="">Select a department</option>
<option value="Sales">Sales</option>
<option value="Marketing">Marketing</option>
<option value="Customer Support">Customer Support</option>
</select>
<div className="valid-feedback">Looks good!</div>
<div className="invalid-feedback">
Please select a department.
</div>
</div>
</div>
{/* /column */}
<div className="w-full flex-[0_0_auto] !px-[15px] max-w-full">
<div className="form-floating relative !mb-4">
<textarea
id="form_message"
name="message"
className="form-control relative block w-full text-[.75rem] font-medium !text-[#60697b] bg-[#fefefe] bg-clip-padding border shadow-[0_0_1.25rem_rgba(30,34,40,0.04)] rounded-[0.4rem] border-solid border-[rgba(8,60,130,0.07)] transition-[border-color] duration-[0.15s] ease-in-out focus:shadow-[0_0_1.25rem_rgba(30,34,40,0.04),unset] focus-visible:!border-[rgba(63,120,224,0.5)] placeholder:!text-[#959ca9] placeholder:opacity-100 m-0 !pr-9 p-[.6rem_1rem] h-[calc(2.5rem_+_2px)] min-h-[calc(2.5rem_+_2px)] !leading-[1.25]"
placeholder=""
style={{ height: 150 }}
required
value={form.message}
onChange={handleInputChange}
/>
<label
htmlFor="form_message"
className="!text-[#959ca9] !mb-2 !inline-block text-[.75rem] !absolute !z-[2] h-full overflow-hidden text-start text-ellipsis whitespace-nowrap pointer-events-none border origin-[0_0] px-4 py-[0.6rem] border-solid border-transparent left-0 top-0 font-Manrope"
>
Message *
</label>
<div className="valid-feedback">Looks good!</div>
<div className="invalid-feedback">
Please enter your messsage.
</div>
</div>
</div>
{/* /column */}
<div className="w-full flex-[0_0_auto] !px-[15px] max-w-full !text-center">
<input
type="submit"
className="btn btn-primary !text-white !bg-[#1fc76f] border-[#1fc76f] hover:text-white hover:bg-[#1fc76f] hover:!border-[#1fc76f] active:text-white active:bg-[#1fc76f] active:border-[#1fc76f] disabled:text-white disabled:bg-[#1fc76f] disabled:border-[#1fc76f] !rounded-[50rem] btn-send !mb-3 hover:translate-y-[-0.15rem] hover:shadow-[0_0.25rem_0.75rem_rgba(30,34,40,0.15)]"
value={submitting ? 'Sending...' : (data.button_text || 'Submit')}
disabled={submitting}
/>
</div>
{/* /column */}
</div>
{/* /.row */}
</form>
{/* /form */}
</div>
{/* /column */}
</div>
{/* /.row */}
</div>
{/* /.container */}
</section>
);
}