216 lines
10 KiB
TypeScript
216 lines
10 KiB
TypeScript
import { X, Mail, Phone, MapPin, Clock, Calendar } from 'lucide-react';
|
||
import { useEffect, useState } from 'react';
|
||
import { createPortal } from 'react-dom';
|
||
|
||
interface ContactModalProps {
|
||
isOpen: boolean;
|
||
onClose: () => void;
|
||
}
|
||
|
||
export function ContactModal({ isOpen, onClose }: ContactModalProps) {
|
||
useEffect(() => {
|
||
if (isOpen) {
|
||
document.body.style.overflow = 'hidden';
|
||
} else {
|
||
document.body.style.overflow = 'unset';
|
||
}
|
||
return () => {
|
||
document.body.style.overflow = 'unset';
|
||
};
|
||
}, [isOpen]);
|
||
|
||
if (!isOpen) return null;
|
||
|
||
const modalContent = (
|
||
<div
|
||
className="fixed inset-0 z-[9999] flex items-center justify-center p-4 bg-black/60 backdrop-blur-sm"
|
||
onClick={onClose}
|
||
>
|
||
<div
|
||
className="relative bg-white rounded-2xl w-full max-w-[700px] max-h-[90vh] overflow-y-auto shadow-2xl"
|
||
onClick={(e) => e.stopPropagation()}
|
||
>
|
||
{/* Заголовок */}
|
||
<div className="sticky top-0 bg-white border-b border-gray-100 px-6 py-5 flex items-start justify-between z-10 rounded-t-2xl">
|
||
<div>
|
||
<h2 className="text-2xl text-gray-900">
|
||
Обсудим ваш проект
|
||
</h2>
|
||
<p className="text-sm text-gray-600 mt-1">
|
||
Оставьте заявку — перезвоним в течение часа
|
||
</p>
|
||
</div>
|
||
<button
|
||
onClick={onClose}
|
||
className="w-9 h-9 flex items-center justify-center rounded-lg hover:bg-gray-100 transition-colors flex-shrink-0 ml-4"
|
||
>
|
||
<X className="w-5 h-5 text-gray-500" />
|
||
</button>
|
||
</div>
|
||
|
||
{/* Форма */}
|
||
<div className="p-8">
|
||
<form className="space-y-5">
|
||
<div className="grid md:grid-cols-2 gap-5">
|
||
<div>
|
||
<input
|
||
type="text"
|
||
id="modal-name"
|
||
className="w-full px-4 py-3 bg-gray-50 border border-gray-200 rounded-xl focus:outline-none focus:ring-2 focus:ring-blue-500 focus:bg-white transition-all"
|
||
placeholder="Ваше имя"
|
||
required
|
||
/>
|
||
</div>
|
||
|
||
<div>
|
||
<input
|
||
type="text"
|
||
id="modal-company"
|
||
className="w-full px-4 py-3 bg-gray-50 border border-gray-200 rounded-xl focus:outline-none focus:ring-2 focus:ring-blue-500 focus:bg-white transition-all"
|
||
placeholder="Компания"
|
||
/>
|
||
</div>
|
||
</div>
|
||
|
||
<div className="grid md:grid-cols-2 gap-5">
|
||
<div>
|
||
<input
|
||
type="email"
|
||
id="modal-email"
|
||
className="w-full px-4 py-3 bg-gray-50 border border-gray-200 rounded-xl focus:outline-none focus:ring-2 focus:ring-blue-500 focus:bg-white transition-all"
|
||
placeholder="Email"
|
||
required
|
||
/>
|
||
</div>
|
||
|
||
<div>
|
||
<input
|
||
type="tel"
|
||
id="modal-phone"
|
||
className="w-full px-4 py-3 bg-gray-50 border border-gray-200 rounded-xl focus:outline-none focus:ring-2 focus:ring-blue-500 focus:bg-white transition-all"
|
||
placeholder="Телефон"
|
||
required
|
||
/>
|
||
</div>
|
||
</div>
|
||
|
||
{/* Для чего нужна покупка и Сроки */}
|
||
<div className="grid md:grid-cols-2 gap-5">
|
||
<div>
|
||
<label htmlFor="modal-purpose" className="block text-sm text-gray-700 mb-2">Какую задачу решаете?</label>
|
||
<select
|
||
id="modal-purpose"
|
||
className="w-full px-4 py-3 bg-gray-50 border border-gray-200 rounded-xl focus:outline-none focus:ring-2 focus:ring-blue-500 focus:bg-white transition-all"
|
||
required
|
||
>
|
||
<option value="">Выберите цель покупки</option>
|
||
<option value="emergency" selected>🔥 Всё горит, нужна помощь!</option>
|
||
<option value="modernization">Модернизация инфраструктуры</option>
|
||
<option value="software-replacement">Замена импортного ПО на российское</option>
|
||
<option value="capacity-expansion">Расширение мощностей</option>
|
||
<option value="new-infrastructure">Создание новой инфраструктуры</option>
|
||
<option value="security-improvement">Повышение безопасности</option>
|
||
<option value="automation">Автоматизация процессов</option>
|
||
<option value="cloud-migration">Миграция в облако</option>
|
||
<option value="disaster-recovery">Резервирование и восстановление</option>
|
||
<option value="compliance">Соответствие требованиям регуляторов</option>
|
||
<option value="other">Другое</option>
|
||
</select>
|
||
</div>
|
||
|
||
<div>
|
||
<label htmlFor="modal-timeline" className="block text-sm text-gray-700 mb-2">Сроки реализации</label>
|
||
<select
|
||
id="modal-timeline"
|
||
className="w-full px-4 py-3 bg-gray-50 border border-gray-200 rounded-xl focus:outline-none focus:ring-2 focus:ring-blue-500 focus:bg-white transition-all"
|
||
required
|
||
>
|
||
<option value="">Выберите срок</option>
|
||
<option value="yesterday" selected>Еще вчера</option>
|
||
<option value="urgent">Срочно (до 1 месяца)</option>
|
||
<option value="1-3-months">1-3 месяца</option>
|
||
<option value="3-6-months">3-6 месяцев</option>
|
||
<option value="6-12-months">6-12 месяцев</option>
|
||
<option value="12-months-plus">Более 12 месяцев</option>
|
||
<option value="planning">На стадии планирования</option>
|
||
</select>
|
||
</div>
|
||
</div>
|
||
|
||
{/* Комментарий к задаче */}
|
||
<div>
|
||
<label htmlFor="modal-task" className="block text-sm text-gray-700 mb-2">Комментарий к задаче</label>
|
||
<textarea
|
||
id="modal-task"
|
||
rows={4}
|
||
className="w-full px-4 py-3 bg-gray-50 border border-gray-200 rounded-xl focus:outline-none focus:ring-2 focus:ring-blue-500 focus:bg-white transition-all resize-none"
|
||
placeholder="Дополнительная информация, требования, бюджет..."
|
||
></textarea>
|
||
</div>
|
||
|
||
{/* Слоты для встречи в ВКС */}
|
||
<div>
|
||
<label className="block text-sm text-gray-700 mb-2 flex items-center gap-2">
|
||
<Calendar className="w-4 h-4" />
|
||
Предпочитаемое время для встречи в ВКС (выберите 2 варианта)
|
||
</label>
|
||
<div className="grid md:grid-cols-2 gap-4">
|
||
<div>
|
||
<label htmlFor="slot1" className="block text-xs text-gray-600 mb-1">Вариант 1</label>
|
||
<input
|
||
type="datetime-local"
|
||
id="slot1"
|
||
className="w-full px-4 py-3 bg-gray-50 border border-gray-200 rounded-xl focus:outline-none focus:ring-2 focus:ring-blue-500 focus:bg-white transition-all"
|
||
/>
|
||
</div>
|
||
<div>
|
||
<label htmlFor="slot2" className="block text-xs text-gray-600 mb-1">Вариант 2</label>
|
||
<input
|
||
type="datetime-local"
|
||
id="slot2"
|
||
className="w-full px-4 py-3 bg-gray-50 border border-gray-200 rounded-xl focus:outline-none focus:ring-2 focus:ring-blue-500 focus:bg-white transition-all"
|
||
/>
|
||
</div>
|
||
</div>
|
||
<p className="text-xs text-gray-500 mt-2">Мы отправим вам приглашение в ВКС на один из выбранных слотов</p>
|
||
</div>
|
||
|
||
<div className="flex flex-col sm:flex-row items-center gap-4">
|
||
<button
|
||
type="submit"
|
||
className="w-full sm:w-auto px-8 py-3 bg-blue-600 text-white rounded-xl hover:bg-blue-700 transition-all"
|
||
>
|
||
Отправить заявку
|
||
</button>
|
||
<p className="text-sm text-gray-500">
|
||
Нажимая кнопку, вы соглашаетесь с политикой конфиденциальности
|
||
</p>
|
||
</div>
|
||
</form>
|
||
|
||
{/* Контакты компактно */}
|
||
<div className="mt-8 pt-8 border-t border-gray-100 flex flex-wrap justify-center gap-6 text-sm text-gray-600">
|
||
<a href="tel:+74951234567" className="flex items-center gap-2 hover:text-blue-600 transition-colors">
|
||
<Phone className="w-4 h-4" />
|
||
<span>+7 (495) 123-45-67</span>
|
||
</a>
|
||
<a href="mailto:info@softclick.ru" className="flex items-center gap-2 hover:text-blue-600 transition-colors">
|
||
<Mail className="w-4 h-4" />
|
||
<span>info@softclick.ru</span>
|
||
</a>
|
||
<div className="flex items-center gap-2">
|
||
<MapPin className="w-4 h-4" />
|
||
<span>Москва, Пресненская наб., 12</span>
|
||
</div>
|
||
<div className="flex items-center gap-2">
|
||
<Clock className="w-4 h-4" />
|
||
<span>Пн-Пт 9:00–18:00</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
);
|
||
|
||
return createPortal(modalContent, document.body);
|
||
} |