2025-12-11 11:30:18 +08:00

279 lines
10 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

'use client';
import React, { useState } from 'react';
import { MapPin, Phone, Mail } from 'lucide-react';
interface FormData {
name: string;
phone: string;
email: string;
description: string;
}
interface FormErrors {
name?: string;
phone?: string;
email?: string;
description?: string;
}
const Contact: React.FC = () => {
const [formData, setFormData] = useState<FormData>({
name: '',
phone: '',
email: '',
description: '',
});
const [errors, setErrors] = useState<FormErrors>({});
const [isSubmitting, setIsSubmitting] = useState(false);
const [submitStatus, setSubmitStatus] = useState<{type: 'success' | 'error', message: string} | null>(null);
const validateForm = (): boolean => {
const newErrors: FormErrors = {};
if (!formData.name.trim()) {
newErrors.name = '请输入姓名';
}
const phoneRegex = /^1[3-9]\d{9}$/;
if (!formData.phone.trim()) {
newErrors.phone = '请输入电话';
} else if (!phoneRegex.test(formData.phone)) {
newErrors.phone = '请输入正确的手机号';
}
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
if (!formData.email.trim()) {
newErrors.email = '请输入邮箱';
} else if (!emailRegex.test(formData.email)) {
newErrors.email = '请输入正确的邮箱地址';
}
if (!formData.description.trim()) {
newErrors.description = '请描述您的需求';
}
setErrors(newErrors);
return Object.keys(newErrors).length === 0;
};
const handleChange = (e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => {
const { name, value } = e.target;
setFormData(prev => ({ ...prev, [name]: value }));
// 清除该字段的错误
if (errors[name as keyof FormErrors]) {
setErrors(prev => ({ ...prev, [name]: undefined }));
}
};
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
if (!validateForm()) {
return;
}
setIsSubmitting(true);
setSubmitStatus(null);
try {
const response = await fetch('/api/messages', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(formData),
});
const data = await response.json();
if (response.ok) {
setSubmitStatus({
type: 'success',
message: data.message || '留言提交成功,我们会尽快与您联系!'
});
// 清空表单
setFormData({
name: '',
phone: '',
email: '',
description: '',
});
} else {
setSubmitStatus({
type: 'error',
message: data.error || '提交失败,请稍后再试'
});
}
} catch (error) {
console.error('提交错误:', error);
setSubmitStatus({
type: 'error',
message: '网络错误,请检查网络连接后重试'
});
} finally {
setIsSubmitting(false);
}
};
return (
<section id="contact" className="py-24 bg-feie-dark text-feie-white relative overflow-hidden">
{/* Abstract background element */}
<div className="absolute top-0 left-0 w-full h-full opacity-10 pointer-events-none">
<div className="absolute top-1/2 left-1/4 w-96 h-96 bg-feie-gold rounded-full blur-[120px]"></div>
</div>
<div className="container mx-auto px-6 relative z-10">
<div className="grid grid-cols-1 lg:grid-cols-2 gap-16">
<div className="space-y-8">
<div>
<h2 className="text-sm font-bold tracking-widest text-feie-gold uppercase mb-3"> Contact</h2>
<h3 className="text-4xl md:text-5xl font-serif leading-tight">
<br/>
<span className="text-feie-white/50"></span>
</h3>
</div>
<p className="text-gray-400 font-light text-lg">
</p>
<div className="space-y-6 pt-6">
<div className="flex items-start gap-4 group">
<div className="p-3 bg-white/5 rounded-sm group-hover:bg-feie-gold/20 transition-colors border border-white/10">
<MapPin className="w-6 h-6 text-feie-gold" />
</div>
<div>
<p className="text-sm text-gray-400 uppercase tracking-wider mb-1"></p>
<p className="text-xl font-serif">8181630</p>
</div>
</div>
<div className="flex items-start gap-4 group">
<div className="p-3 bg-white/5 rounded-sm group-hover:bg-feie-gold/20 transition-colors border border-white/10">
<Phone className="w-6 h-6 text-feie-gold" />
</div>
<div>
<p className="text-sm text-gray-400 uppercase tracking-wider mb-1"></p>
<p className="text-xl font-serif">19844561014</p>
</div>
</div>
<div className="flex items-start gap-4 group">
<div className="p-3 bg-white/5 rounded-sm group-hover:bg-feie-gold/20 transition-colors border border-white/10">
<Mail className="w-6 h-6 text-feie-gold" />
</div>
<div>
<p className="text-sm text-gray-400 uppercase tracking-wider mb-1"></p>
<a href="mailto:feie9454@gmail.com" className="text-xl font-serif hover:text-feie-gold transition-colors">
feie9454@gmail.com
</a>
</div>
</div>
</div>
</div>
<div className="bg-feie-cream p-8 md:p-10 rounded-sm text-feie-dark shadow-2xl">
<h4 className="text-2xl font-serif mb-6">线</h4>
{submitStatus && (
<div className={`mb-6 p-4 rounded ${
submitStatus.type === 'success'
? 'bg-green-100 text-green-800 border border-green-300'
: 'bg-red-100 text-red-800 border border-red-300'
}`}>
{submitStatus.message}
</div>
)}
<form className="space-y-6" onSubmit={handleSubmit}>
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
<div>
<label className="block text-sm font-bold uppercase tracking-wider text-gray-500 mb-2">
<span className="text-red-500">*</span>
</label>
<input
type="text"
name="name"
value={formData.name}
onChange={handleChange}
className={`w-full bg-white border-b-2 p-3 focus:border-feie-gold outline-none transition-colors ${
errors.name ? 'border-red-500' : 'border-gray-200'
}`}
placeholder="您的姓名"
/>
{errors.name && <p className="text-red-500 text-sm mt-1">{errors.name}</p>}
</div>
<div>
<label className="block text-sm font-bold uppercase tracking-wider text-gray-500 mb-2">
<span className="text-red-500">*</span>
</label>
<input
type="tel"
name="phone"
value={formData.phone}
onChange={handleChange}
className={`w-full bg-white border-b-2 p-3 focus:border-feie-gold outline-none transition-colors ${
errors.phone ? 'border-red-500' : 'border-gray-200'
}`}
placeholder="联系电话"
/>
{errors.phone && <p className="text-red-500 text-sm mt-1">{errors.phone}</p>}
</div>
</div>
<div>
<label className="block text-sm font-bold uppercase tracking-wider text-gray-500 mb-2">
<span className="text-red-500">*</span>
</label>
<input
type="email"
name="email"
value={formData.email}
onChange={handleChange}
className={`w-full bg-white border-b-2 p-3 focus:border-feie-gold outline-none transition-colors ${
errors.email ? 'border-red-500' : 'border-gray-200'
}`}
placeholder="example@email.com"
/>
{errors.email && <p className="text-red-500 text-sm mt-1">{errors.email}</p>}
</div>
<div>
<label className="block text-sm font-bold uppercase tracking-wider text-gray-500 mb-2">
<span className="text-red-500">*</span>
</label>
<textarea
rows={4}
name="description"
value={formData.description}
onChange={handleChange}
className={`w-full bg-white border-b-2 p-3 focus:border-feie-gold outline-none transition-colors resize-none ${
errors.description ? 'border-red-500' : 'border-gray-200'
}`}
placeholder="请简要描述您的需求..."
></textarea>
{errors.description && <p className="text-red-500 text-sm mt-1">{errors.description}</p>}
</div>
<button
type="submit"
disabled={isSubmitting}
className={`w-full py-4 font-serif font-bold uppercase tracking-widest transition-colors duration-300 ${
isSubmitting
? 'bg-gray-400 text-gray-200 cursor-not-allowed'
: 'bg-feie-dark text-feie-white hover:bg-feie-gold'
}`}
>
{isSubmitting ? '发送中...' : '发送信息'}
</button>
</form>
</div>
</div>
</div>
</section>
);
};
export default Contact;