161 lines
5.5 KiB
TypeScript
161 lines
5.5 KiB
TypeScript
'use client'
|
||
|
||
import { useState } from 'react'
|
||
import { Send } from 'lucide-react'
|
||
|
||
interface ContactFormData {
|
||
name: string
|
||
email: string
|
||
phone: string
|
||
company: string
|
||
message: string
|
||
}
|
||
|
||
export default function ContactForm() {
|
||
const [formData, setFormData] = useState<ContactFormData>({
|
||
name: '',
|
||
email: '',
|
||
phone: '',
|
||
company: '',
|
||
message: ''
|
||
})
|
||
const [isSubmitting, setIsSubmitting] = useState(false)
|
||
const [submitStatus, setSubmitStatus] = useState<'idle' | 'success' | 'error'>('idle')
|
||
|
||
const handleSubmit = async (e: React.FormEvent) => {
|
||
e.preventDefault()
|
||
setIsSubmitting(true)
|
||
setSubmitStatus('idle')
|
||
|
||
try {
|
||
const apiUrl = process.env.NEXT_PUBLIC_API_URL || 'http://localhost:8000'
|
||
const response = await fetch(`${apiUrl}/api/v1/contact`, {
|
||
method: 'POST',
|
||
headers: {
|
||
'Content-Type': 'application/json',
|
||
},
|
||
body: JSON.stringify(formData),
|
||
})
|
||
|
||
if (response.ok) {
|
||
setSubmitStatus('success')
|
||
setFormData({ name: '', email: '', phone: '', company: '', message: '' })
|
||
} else {
|
||
setSubmitStatus('error')
|
||
}
|
||
} catch (error) {
|
||
setSubmitStatus('error')
|
||
} finally {
|
||
setIsSubmitting(false)
|
||
}
|
||
}
|
||
|
||
return (
|
||
<form onSubmit={handleSubmit} className="bg-white rounded-2xl shadow-lg p-8 md:p-12">
|
||
<div className="grid md:grid-cols-2 gap-6 mb-6">
|
||
<div>
|
||
<label htmlFor="name" className="block text-sm font-medium text-gray-700 mb-2">
|
||
Ваше имя *
|
||
</label>
|
||
<input
|
||
type="text"
|
||
id="name"
|
||
required
|
||
className="w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-primary-500 focus:border-transparent"
|
||
value={formData.name}
|
||
onChange={(e) => setFormData({ ...formData, name: e.target.value })}
|
||
placeholder="Иван Иванов"
|
||
/>
|
||
</div>
|
||
<div>
|
||
<label htmlFor="email" className="block text-sm font-medium text-gray-700 mb-2">
|
||
Email *
|
||
</label>
|
||
<input
|
||
type="email"
|
||
id="email"
|
||
required
|
||
className="w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-primary-500 focus:border-transparent"
|
||
value={formData.email}
|
||
onChange={(e) => setFormData({ ...formData, email: e.target.value })}
|
||
placeholder="ivan@company.com"
|
||
/>
|
||
</div>
|
||
</div>
|
||
|
||
<div className="grid md:grid-cols-2 gap-6 mb-6">
|
||
<div>
|
||
<label htmlFor="phone" className="block text-sm font-medium text-gray-700 mb-2">
|
||
Телефон
|
||
</label>
|
||
<input
|
||
type="tel"
|
||
id="phone"
|
||
className="w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-primary-500 focus:border-transparent"
|
||
value={formData.phone}
|
||
onChange={(e) => setFormData({ ...formData, phone: e.target.value })}
|
||
placeholder="+7 (999) 123-45-67"
|
||
/>
|
||
</div>
|
||
<div>
|
||
<label htmlFor="company" className="block text-sm font-medium text-gray-700 mb-2">
|
||
Компания
|
||
</label>
|
||
<input
|
||
type="text"
|
||
id="company"
|
||
className="w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-primary-500 focus:border-transparent"
|
||
value={formData.company}
|
||
onChange={(e) => setFormData({ ...formData, company: e.target.value })}
|
||
placeholder="Название компании"
|
||
/>
|
||
</div>
|
||
</div>
|
||
|
||
<div className="mb-6">
|
||
<label htmlFor="message" className="block text-sm font-medium text-gray-700 mb-2">
|
||
Сообщение
|
||
</label>
|
||
<textarea
|
||
id="message"
|
||
rows={4}
|
||
className="w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-primary-500 focus:border-transparent resize-none"
|
||
value={formData.message}
|
||
onChange={(e) => setFormData({ ...formData, message: e.target.value })}
|
||
placeholder="Расскажите о вашей компании и задачах..."
|
||
/>
|
||
</div>
|
||
|
||
{submitStatus === 'success' && (
|
||
<div className="mb-6 p-4 bg-green-50 border border-green-200 rounded-lg text-green-800">
|
||
Спасибо! Мы свяжемся с вами в ближайшее время.
|
||
</div>
|
||
)}
|
||
|
||
{submitStatus === 'error' && (
|
||
<div className="mb-6 p-4 bg-red-50 border border-red-200 rounded-lg text-red-800">
|
||
Произошла ошибка. Попробуйте ещё раз или напишите нам на email.
|
||
</div>
|
||
)}
|
||
|
||
<button
|
||
type="submit"
|
||
disabled={isSubmitting}
|
||
className="w-full inline-flex items-center justify-center px-8 py-4 bg-primary-600 text-white font-semibold rounded-lg hover:bg-primary-700 focus:ring-2 focus:ring-primary-500 focus:ring-offset-2 transition-colors disabled:opacity-50 disabled:cursor-not-allowed"
|
||
>
|
||
{isSubmitting ? (
|
||
<>
|
||
<div className="animate-spin rounded-full h-5 w-5 border-b-2 border-white mr-3"></div>
|
||
Отправка...
|
||
</>
|
||
) : (
|
||
<>
|
||
<Send className="h-5 w-5 mr-2" />
|
||
Отправить заявку
|
||
</>
|
||
)}
|
||
</button>
|
||
</form>
|
||
)
|
||
}
|