/* Contact + Footer */ function getPublicContact() { return window.__PUBLIC_DATA__?.contact || {}; } function externalTarget(url) { return /^https?:\/\//.test(url || '') ? { target: '_blank', rel: 'noopener noreferrer' } : {}; } function Contact({ setRoute }) { const [tags, setTags] = React.useState(['SEO-аудит']); const allTags = ['SEO-аудит', 'Микроразметка', 'PHP/MySQL', 'VPS/Docker', 'API-интеграция', 'Готовый сайт', 'Другое']; const toggle = (t) => setTags((cur) => cur.includes(t) ? cur.filter(x => x !== t) : [...cur, t]); const contact = getPublicContact(); const channels = [ contact.email && { ico: '@', name: contact.email, sub: 'почта · приоритет для аудитов', href: contact.email_href }, contact.telegram_url && { ico: 'T', name: contact.telegram_label || 'Telegram', sub: 'Telegram · быстрые задачи', href: contact.telegram_url }, contact.phone && { ico: '+', name: contact.phone, sub: 'телефон · если удобнее голосом', href: contact.phone_href }, contact.primary_platform_url && { ico: '$', name: 'Безопасная сделка', sub: 'через фриланс-площадку', href: '#', route: 'platforms' }, ].filter(Boolean); const [submitted, setSubmitted] = React.useState(false); const [submitError, setSubmitError] = React.useState(''); const onSubmit = async (e) => { e.preventDefault(); const form = e.currentTarget; const consent = form.querySelector('input[name="pd_consent"]'); if (!consent?.checked) { setSubmitted(false); setSubmitError('Нужно подтвердить согласие на обработку персональных данных.'); return; } setSubmitError(''); const payload = new FormData(form); payload.set('task_type', tags.join(', ').slice(0, 80) || 'Другое'); payload.set('pd_consent', 'yes'); payload.set('website', ''); try { const res = await fetch(window.__CONTACT_ENDPOINT__ || '/contact/', { method: 'POST', body: payload, credentials: 'same-origin', }); if (!res.ok) throw new Error('submit failed'); setSubmitted(true); form.reset(); setTimeout(() => setSubmitted(false), 4000); } catch (err) { setSubmitted(false); window.location.href = '/contact/'; } }; return (
// форма заявки Опишите задачу — предложу формат Если задача нестандартная, пришлите ссылку, описание проблемы и ожидания. Отвечаю обычно в течение пары часов.
{channels.map((c, i) => ( {c.ico}
{c.name}
{c.sub}
))}
$ winetlab new-task ● ready
{allTags.map(t => ( ))}