2025-10-31 22:23:45 +01:00
|
|
|
'use client';
|
|
|
|
|
|
|
|
|
|
import React, { useState } from 'react';
|
|
|
|
|
import { Mail, Phone, Loader2 } from 'lucide-react';
|
|
|
|
|
import { validateEmail, sendContactFormEmail } from '../src/utils/email';
|
|
|
|
|
import { analytics } from '../src/utils/analytics';
|
|
|
|
|
|
|
|
|
|
export function ContactClient() {
|
|
|
|
|
const [formData, setFormData] = useState({
|
|
|
|
|
name: '',
|
|
|
|
|
email: '',
|
|
|
|
|
phone: '',
|
|
|
|
|
company: '',
|
|
|
|
|
message: ''
|
|
|
|
|
});
|
|
|
|
|
const [submitted, setSubmitted] = useState(false);
|
|
|
|
|
const [sending, setSending] = useState(false);
|
|
|
|
|
const [error, setError] = useState<string | null>(null);
|
|
|
|
|
|
|
|
|
|
const handleSubmit = async (e: React.FormEvent) => {
|
|
|
|
|
e.preventDefault();
|
|
|
|
|
setSending(true);
|
|
|
|
|
setError(null);
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
// Validate email
|
|
|
|
|
if (!validateEmail(formData.email)) {
|
|
|
|
|
throw new Error('Please enter a valid email address');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Send via SMTP backend
|
|
|
|
|
await sendContactFormEmail(formData, 'contact');
|
|
|
|
|
|
|
|
|
|
setSubmitted(true);
|
|
|
|
|
analytics.event('contact', 'form_submitted');
|
|
|
|
|
|
|
|
|
|
// Reset form after delay
|
|
|
|
|
setTimeout(() => {
|
|
|
|
|
setFormData({
|
|
|
|
|
name: '',
|
|
|
|
|
email: '',
|
|
|
|
|
phone: '',
|
|
|
|
|
company: '',
|
|
|
|
|
message: ''
|
|
|
|
|
});
|
|
|
|
|
setSubmitted(false);
|
|
|
|
|
}, 3000);
|
|
|
|
|
} catch (err) {
|
|
|
|
|
setError(err instanceof Error ? err.message : 'Failed to send message. Please try again.');
|
|
|
|
|
analytics.error(err as Error, 'Contact form submission failed');
|
|
|
|
|
} finally {
|
|
|
|
|
setSending(false);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const handleChange = (e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => {
|
|
|
|
|
const { name, value } = e.target;
|
|
|
|
|
setFormData(prev => ({
|
|
|
|
|
...prev,
|
|
|
|
|
[name]: value
|
|
|
|
|
}));
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
return (
|
2025-11-02 19:13:15 +01:00
|
|
|
<div className="max-w-4xl mx-auto pb-12 px-4 sm:px-6 lg:px-8">
|
2025-10-31 22:23:45 +01:00
|
|
|
<div className="text-center mb-12">
|
|
|
|
|
<h1 className="text-4xl font-bold text-gray-900 mb-4">Contact Us</h1>
|
|
|
|
|
<p className="text-xl text-gray-600">
|
|
|
|
|
Ready to start your sustainability journey? Get in touch with our team today.
|
|
|
|
|
</p>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div className="bg-white rounded-xl shadow-lg p-8 sm:p-12">
|
|
|
|
|
<div className="grid grid-cols-1 md:grid-cols-2 gap-8 sm:gap-12">
|
|
|
|
|
<div className="space-y-8">
|
|
|
|
|
<div>
|
|
|
|
|
<h2 className="text-2xl font-bold text-gray-900 mb-6">Get in Touch</h2>
|
|
|
|
|
<p className="text-gray-600 mb-8 text-justify">
|
|
|
|
|
Have questions about our carbon offsetting solutions? Our team is here to help you make a difference in maritime sustainability.
|
|
|
|
|
</p>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div className="space-y-6">
|
|
|
|
|
<div className="flex items-center space-x-4">
|
|
|
|
|
<Mail className="text-blue-600" size={24} />
|
|
|
|
|
<div>
|
|
|
|
|
<h3 className="font-semibold text-gray-900">Email Us</h3>
|
|
|
|
|
<a
|
|
|
|
|
href="mailto:info@puffinoffset.com"
|
|
|
|
|
className="text-blue-600 hover:text-blue-700"
|
|
|
|
|
>
|
|
|
|
|
info@puffinoffset.com
|
|
|
|
|
</a>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
<div className="flex items-center space-x-4">
|
|
|
|
|
<Phone className="text-blue-600" size={24} />
|
|
|
|
|
<div>
|
|
|
|
|
<h3 className="font-semibold text-gray-900">Call Us</h3>
|
|
|
|
|
<a
|
|
|
|
|
href="tel:+33671187253"
|
|
|
|
|
className="text-blue-600 hover:text-blue-700"
|
|
|
|
|
>
|
|
|
|
|
+33 6 71 18 72 53
|
|
|
|
|
</a>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<form onSubmit={handleSubmit} className="space-y-6">
|
|
|
|
|
{submitted && (
|
|
|
|
|
<div className="bg-green-50 border border-green-200 rounded-lg p-4 mb-6">
|
|
|
|
|
<p className="text-green-700">
|
|
|
|
|
Thank you for your message. Your email client will open shortly.
|
|
|
|
|
</p>
|
|
|
|
|
</div>
|
|
|
|
|
)}
|
|
|
|
|
|
|
|
|
|
{error && (
|
|
|
|
|
<div className="bg-red-50 border border-red-200 rounded-lg p-4 mb-6">
|
|
|
|
|
<p className="text-red-700">{error}</p>
|
|
|
|
|
</div>
|
|
|
|
|
)}
|
|
|
|
|
|
|
|
|
|
<div>
|
|
|
|
|
<label htmlFor="name" className="block text-sm font-medium text-gray-700 mb-1">
|
|
|
|
|
Name *
|
|
|
|
|
</label>
|
|
|
|
|
<input
|
|
|
|
|
type="text"
|
|
|
|
|
id="name"
|
|
|
|
|
name="name"
|
|
|
|
|
value={formData.name}
|
|
|
|
|
onChange={handleChange}
|
|
|
|
|
className="w-full px-4 py-2 border rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
|
|
|
|
|
required
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
<div>
|
|
|
|
|
<label htmlFor="email" className="block text-sm font-medium text-gray-700 mb-1">
|
|
|
|
|
Email *
|
|
|
|
|
</label>
|
|
|
|
|
<input
|
|
|
|
|
type="email"
|
|
|
|
|
id="email"
|
|
|
|
|
name="email"
|
|
|
|
|
value={formData.email}
|
|
|
|
|
onChange={handleChange}
|
|
|
|
|
className="w-full px-4 py-2 border rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
|
|
|
|
|
required
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
<div>
|
|
|
|
|
<label htmlFor="phone" className="block text-sm font-medium text-gray-700 mb-1">
|
|
|
|
|
Phone
|
|
|
|
|
</label>
|
|
|
|
|
<input
|
|
|
|
|
type="tel"
|
|
|
|
|
id="phone"
|
|
|
|
|
name="phone"
|
|
|
|
|
value={formData.phone}
|
|
|
|
|
onChange={handleChange}
|
|
|
|
|
className="w-full px-4 py-2 border rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
|
|
|
|
|
placeholder="+1 234 567 8900"
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
<div>
|
|
|
|
|
<label htmlFor="company" className="block text-sm font-medium text-gray-700 mb-1">
|
|
|
|
|
Company
|
|
|
|
|
</label>
|
|
|
|
|
<input
|
|
|
|
|
type="text"
|
|
|
|
|
id="company"
|
|
|
|
|
name="company"
|
|
|
|
|
value={formData.company}
|
|
|
|
|
onChange={handleChange}
|
|
|
|
|
className="w-full px-4 py-2 border rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
<div>
|
|
|
|
|
<label htmlFor="message" className="block text-sm font-medium text-gray-700 mb-1">
|
|
|
|
|
Message *
|
|
|
|
|
</label>
|
|
|
|
|
<textarea
|
|
|
|
|
id="message"
|
|
|
|
|
name="message"
|
|
|
|
|
value={formData.message}
|
|
|
|
|
onChange={handleChange}
|
|
|
|
|
rows={4}
|
|
|
|
|
className="w-full px-4 py-2 border rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
|
|
|
|
|
required
|
|
|
|
|
></textarea>
|
|
|
|
|
</div>
|
|
|
|
|
<button
|
|
|
|
|
type="submit"
|
|
|
|
|
disabled={sending}
|
|
|
|
|
className={`w-full flex items-center justify-center bg-blue-600 text-white py-3 rounded-lg transition-colors ${
|
|
|
|
|
sending ? 'opacity-50 cursor-not-allowed' : 'hover:bg-blue-700'
|
|
|
|
|
}`}
|
|
|
|
|
>
|
|
|
|
|
{sending ? (
|
|
|
|
|
<>
|
|
|
|
|
<Loader2 className="animate-spin mr-2" size={20} />
|
|
|
|
|
Preparing Email...
|
|
|
|
|
</>
|
|
|
|
|
) : (
|
|
|
|
|
'Send Message'
|
|
|
|
|
)}
|
|
|
|
|
</button>
|
|
|
|
|
<p className="text-sm text-gray-500 text-center">
|
|
|
|
|
* Required fields
|
|
|
|
|
</p>
|
|
|
|
|
</form>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
);
|
|
|
|
|
}
|