diff --git a/docs/superpowers/plans/2026-05-12-client-questionnaire.md b/docs/superpowers/plans/2026-05-12-client-questionnaire.md new file mode 100644 index 0000000..d1cfd00 --- /dev/null +++ b/docs/superpowers/plans/2026-05-12-client-questionnaire.md @@ -0,0 +1,782 @@ +# Client Questionnaire Form — Implementation Plan + +> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. + +**Goal:** Создать веб-форму на русском языке с 12 вопросами для сбора требований от клиента парка, с отправкой ответов в Airtable и на email. + +**Architecture:** Статичная HTML страница с vanilla JS. При отправке JS делает два запроса: POST в Airtable API (сохранить запись) и POST в EmailJS (отправить письмо). Хостинг на Netlify через GitHub. + +**Tech Stack:** HTML5, CSS3, Vanilla JS, Airtable API, EmailJS, Netlify + +--- + +## Структура файлов + +``` +C:\pro\Sunset Pass\ +├── index.html # Главная страница с формой +├── style.css # Стили +├── script.js # Логика отправки (Airtable + EmailJS) +├── success.html # Страница после успешной отправки +└── .env.example # Пример переменных (ключи API) +``` + +--- + +### Task 1: HTML структура формы + +**Files:** +- Create: `C:\pro\Sunset Pass\index.html` + +- [ ] **Step 1: Создать index.html с формой** + +```html + + + + + + Sunset Pass — Опросник + + + +
+
+

Sunset Pass

+

Опросник для разработки системы бронирования парка

+
+
+
+

Вопрос 1 из 12

+
+ +
+ + +
+

О парке

+ +
+ + + +
+ +
+ + + +
+ +
+ + + +
+ +
+ + + +
+
+ + +
+

О бронировании

+ +
+ + + +
+ +
+ + + +
+ +
+ + + +
+
+ + +
+

О воротах

+ +
+ + + +
+ +
+ + + +
+
+ + +
+

О дизайне и языке

+ +
+ + + +
+ +
+ + + +
+
+ + +
+

О сроках

+ +
+ + + +
+
+ + +
+

Ваши контактные данные

+
+ + +
+
+ + +
+
+ + +
+
+ + +

После отправки мы свяжемся с вами в течение 1-2 рабочих дней.

+ +
+
+ + + + + +``` + +- [ ] **Step 2: Проверить в браузере — форма отображается** + +Открыть `index.html` в браузере (двойной клик по файлу). +Ожидание: видны все 12 вопросов, поля для ввода работают. + +- [ ] **Step 3: Commit** + +```bash +git add index.html +git commit -m "feat: add questionnaire HTML structure with 12 questions" +``` + +--- + +### Task 2: CSS стили + +**Files:** +- Create: `C:\pro\Sunset Pass\style.css` + +- [ ] **Step 1: Создать style.css** + +```css +* { + box-sizing: border-box; + margin: 0; + padding: 0; +} + +body { + font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; + background: #f8f9fa; + color: #1a1a1a; + line-height: 1.6; +} + +.container { + max-width: 720px; + margin: 0 auto; + padding: 40px 20px 80px; +} + +header { + text-align: center; + margin-bottom: 48px; +} + +h1 { + font-size: 2rem; + font-weight: 700; + margin-bottom: 8px; + color: #1a1a1a; +} + +.subtitle { + color: #666; + font-size: 1rem; + margin-bottom: 24px; +} + +.progress-bar { + width: 100%; + height: 6px; + background: #e0e0e0; + border-radius: 3px; + overflow: hidden; + margin-bottom: 8px; +} + +.progress-fill { + height: 100%; + background: #2d6a4f; + border-radius: 3px; + transition: width 0.3s ease; + width: 0%; +} + +.progress-text { + font-size: 0.85rem; + color: #888; +} + +.section { + background: #fff; + border-radius: 12px; + padding: 32px; + margin-bottom: 24px; + box-shadow: 0 1px 4px rgba(0,0,0,0.06); +} + +.section h2 { + font-size: 1.1rem; + font-weight: 600; + color: #2d6a4f; + margin-bottom: 24px; + padding-bottom: 12px; + border-bottom: 2px solid #e8f5e9; +} + +.question { + margin-bottom: 28px; +} + +.question:last-child { + margin-bottom: 0; +} + +label { + display: block; + font-weight: 500; + margin-bottom: 8px; + font-size: 0.95rem; +} + +textarea, input[type="text"], input[type="email"], input[type="tel"] { + width: 100%; + padding: 12px 14px; + border: 1.5px solid #ddd; + border-radius: 8px; + font-size: 0.95rem; + font-family: inherit; + color: #1a1a1a; + background: #fafafa; + transition: border-color 0.2s; + resize: vertical; +} + +textarea { + min-height: 80px; +} + +textarea:focus, input:focus { + outline: none; + border-color: #2d6a4f; + background: #fff; +} + +textarea.comment { + min-height: 50px; + margin-top: 8px; + font-size: 0.88rem; + color: #555; + background: #f5f5f5; +} + +textarea.comment::placeholder { + color: #aaa; + font-style: italic; +} + +button[type="submit"] { + display: block; + width: 100%; + padding: 16px; + background: #2d6a4f; + color: #fff; + border: none; + border-radius: 10px; + font-size: 1.1rem; + font-weight: 600; + cursor: pointer; + transition: background 0.2s, transform 0.1s; + margin-top: 32px; +} + +button[type="submit"]:hover { + background: #1b4332; +} + +button[type="submit"]:active { + transform: scale(0.99); +} + +button[type="submit"]:disabled { + background: #aaa; + cursor: not-allowed; +} + +.submit-note { + text-align: center; + color: #888; + font-size: 0.85rem; + margin-top: 12px; +} + +.error-message { + background: #fff3f3; + border: 1px solid #f5c6cb; + color: #721c24; + padding: 12px 16px; + border-radius: 8px; + margin-top: 16px; + font-size: 0.9rem; + display: none; +} + +@media (max-width: 600px) { + .container { + padding: 24px 16px 60px; + } + + .section { + padding: 20px; + } + + h1 { + font-size: 1.5rem; + } +} +``` + +- [ ] **Step 2: Проверить в браузере — форма выглядит аккуратно** + +Обновить `index.html` в браузере. +Ожидание: белые карточки с секциями, зелёный акцент, прогресс-бар вверху. + +- [ ] **Step 3: Commit** + +```bash +git add style.css +git commit -m "feat: add questionnaire styles" +``` + +--- + +### Task 3: Страница успеха + +**Files:** +- Create: `C:\pro\Sunset Pass\success.html` + +- [ ] **Step 1: Создать success.html** + +```html + + + + + + Sunset Pass — Спасибо! + + + + +
+
+
+

Спасибо! Ответы получены.

+

Мы свяжемся с вами в течение 1-2 рабочих дней для обсуждения деталей проекта.

+
+
+ + +``` + +- [ ] **Step 2: Commit** + +```bash +git add success.html +git commit -m "feat: add success page" +``` + +--- + +### Task 4: Настройка Airtable + +- [ ] **Step 1: Создать аккаунт Airtable** + +Зайти на airtable.com → Sign up (бесплатно). + +- [ ] **Step 2: Создать новую Base** + +Нажать "Add a base" → "Start from scratch" → назвать "Sunset Pass Questionnaire". + +- [ ] **Step 3: Создать таблицу с полями** + +Переименовать таблицу в "Responses". Добавить поля (тип: Long text для всех textarea, Single line text для имени/email/телефона): + +| Имя поля | Тип | +|---|---| +| client_name | Single line text | +| client_email | Email | +| client_phone | Single line text | +| park_size | Long text | +| park_size_comment | Long text | +| max_people | Long text | +| max_people_comment | Long text | +| slot_duration | Long text | +| slot_duration_comment | Long text | +| working_hours | Long text | +| working_hours_comment | Long text | +| payment | Long text | +| payment_comment | Long text | +| cancellation | Long text | +| cancellation_comment | Long text | +| registration | Long text | +| registration_comment | Long text | +| gate_equipment | Long text | +| gate_equipment_comment | Long text | +| pin_generation | Long text | +| pin_generation_comment | Long text | +| branding | Long text | +| branding_comment | Long text | +| language | Long text | +| language_comment | Long text | +| deadline | Long text | +| deadline_comment | Long text | + +- [ ] **Step 4: Получить API ключ и Base ID** + +1. Зайти на airtable.com/create/tokens → "Create new token" +2. Дать название "sunset-pass", scope: `data.records:write`, выбрать свою Base +3. Скопировать токен (показывается только раз!) → сохранить + +Base ID найти: открыть Base → Help → API documentation → в URL будет `appXXXXXXXXXXXXXX` + +- [ ] **Step 5: Создать .env.example** + +```bash +# Airtable +AIRTABLE_TOKEN=patXXXXXXXXXXXXXX +AIRTABLE_BASE_ID=appXXXXXXXXXXXXXX +AIRTABLE_TABLE_NAME=Responses + +# EmailJS +EMAILJS_SERVICE_ID=service_XXXXXXX +EMAILJS_TEMPLATE_ID=template_XXXXXXX +EMAILJS_PUBLIC_KEY=XXXXXXXXXXXXXXXX +``` + +```bash +git add .env.example +git commit -m "docs: add .env.example with required API keys" +``` + +--- + +### Task 5: Настройка EmailJS + +- [ ] **Step 1: Создать аккаунт EmailJS** + +Зайти на emailjs.com → Sign up (бесплатно, 200 писем/месяц). + +- [ ] **Step 2: Добавить Email Service** + +Dashboard → Email Services → Add New Service → выбрать Gmail → Connect Account → войти через `anton.semenov.ser@gmail.com`. +Скопировать **Service ID** (вида `service_XXXXXXX`). + +- [ ] **Step 3: Создать Email Template** + +Dashboard → Email Templates → Create New Template. + +Subject: `Новый ответ на опросник Sunset Pass от {{client_name}}` + +Body: +``` +Новый ответ на опросник Sunset Pass + +Клиент: {{client_name}} +Email: {{client_email}} +Телефон: {{client_phone}} + +--- О ПАРКЕ --- +1. Размер парка: {{park_size}} + Комментарий: {{park_size_comment}} + +2. Макс. людей: {{max_people}} + Комментарий: {{max_people_comment}} + +3. Длительность слота: {{slot_duration}} + Комментарий: {{slot_duration_comment}} + +4. Часы работы: {{working_hours}} + Комментарий: {{working_hours_comment}} + +--- О БРОНИРОВАНИИ --- +5. Оплата: {{payment}} + Комментарий: {{payment_comment}} + +6. Отмена: {{cancellation}} + Комментарий: {{cancellation_comment}} + +7. Регистрация: {{registration}} + Комментарий: {{registration_comment}} + +--- О ВОРОТАХ --- +8. Оборудование: {{gate_equipment}} + Комментарий: {{gate_equipment_comment}} + +9. PIN генерация: {{pin_generation}} + Комментарий: {{pin_generation_comment}} + +--- О ДИЗАЙНЕ --- +10. Брендинг: {{branding}} + Комментарий: {{branding_comment}} + +11. Язык: {{language}} + Комментарий: {{language_comment}} + +--- О СРОКАХ --- +12. Дедлайн: {{deadline}} + Комментарий: {{deadline_comment}} +``` + +To email: `anton.semenov.ser@gmail.com` + +Скопировать **Template ID** (вида `template_XXXXXXX`). + +- [ ] **Step 4: Получить Public Key** + +Dashboard → Account → General → скопировать **Public Key**. + +--- + +### Task 6: JavaScript логика отправки + +**Files:** +- Create: `C:\pro\Sunset Pass\script.js` + +- [ ] **Step 1: Создать script.js** + +Заменить `YOUR_AIRTABLE_TOKEN`, `YOUR_BASE_ID`, `YOUR_EMAILJS_PUBLIC_KEY`, `YOUR_SERVICE_ID`, `YOUR_TEMPLATE_ID` на реальные значения из Task 4 и Task 5. + +```javascript +// Конфигурация — заменить на реальные ключи +const CONFIG = { + airtable: { + token: 'YOUR_AIRTABLE_TOKEN', + baseId: 'YOUR_BASE_ID', + tableName: 'Responses' + }, + emailjs: { + publicKey: 'YOUR_EMAILJS_PUBLIC_KEY', + serviceId: 'YOUR_SERVICE_ID', + templateId: 'YOUR_TEMPLATE_ID' + } +}; + +// Инициализация EmailJS +emailjs.init(CONFIG.emailjs.publicKey); + +// Прогресс-бар: обновляется при фокусе на вопросах +const questions = document.querySelectorAll('.question[data-index]'); +const progressFill = document.getElementById('progressFill'); +const progressText = document.getElementById('progressText'); +const total = 12; + +function updateProgress(index) { + const pct = Math.round((index / total) * 100); + progressFill.style.width = pct + '%'; + progressText.textContent = `Вопрос ${index} из ${total}`; +} + +questions.forEach(q => { + const textarea = q.querySelector('textarea:not(.comment)'); + if (textarea) { + textarea.addEventListener('focus', () => { + updateProgress(parseInt(q.dataset.index)); + }); + } +}); + +// Отправка формы +document.getElementById('questionnaireForm').addEventListener('submit', async function(e) { + e.preventDefault(); + + const btn = document.getElementById('submitBtn'); + btn.disabled = true; + btn.textContent = 'Отправляем...'; + + const form = e.target; + const data = {}; + const inputs = form.querySelectorAll('textarea, input'); + inputs.forEach(input => { + if (input.name) data[input.name] = input.value.trim(); + }); + + try { + // 1. Сохранить в Airtable + const airtableRes = await fetch( + `https://api.airtable.com/v0/${CONFIG.airtable.baseId}/${encodeURIComponent(CONFIG.airtable.tableName)}`, + { + method: 'POST', + headers: { + 'Authorization': `Bearer ${CONFIG.airtable.token}`, + 'Content-Type': 'application/json' + }, + body: JSON.stringify({ fields: data }) + } + ); + + if (!airtableRes.ok) { + const err = await airtableRes.json(); + throw new Error('Airtable: ' + (err.error?.message || airtableRes.status)); + } + + // 2. Отправить email через EmailJS + await emailjs.send( + CONFIG.emailjs.serviceId, + CONFIG.emailjs.templateId, + data + ); + + // 3. Перенаправить на страницу успеха + window.location.href = 'success.html'; + + } catch (err) { + console.error(err); + btn.disabled = false; + btn.textContent = 'Отправить ответы'; + alert('Ошибка при отправке: ' + err.message + '\n\nПопробуйте ещё раз или напишите нам напрямую.'); + } +}); +``` + +- [ ] **Step 2: Вставить реальные ключи в CONFIG** + +Открыть `script.js` и заменить: +- `YOUR_AIRTABLE_TOKEN` → токен из Task 4 Step 4 +- `YOUR_BASE_ID` → Base ID из Task 4 Step 4 +- `YOUR_EMAILJS_PUBLIC_KEY` → Public Key из Task 5 Step 4 +- `YOUR_SERVICE_ID` → Service ID из Task 5 Step 2 +- `YOUR_TEMPLATE_ID` → Template ID из Task 5 Step 3 + +- [ ] **Step 3: Проверить в браузере — заполнить форму и отправить** + +Открыть `index.html` → заполнить все поля → нажать "Отправить". +Ожидание: +- Редирект на `success.html` +- В Airtable появилась новая запись +- На `anton.semenov.ser@gmail.com` пришло письмо + +- [ ] **Step 4: Commit** + +```bash +git add script.js +git commit -m "feat: add form submission logic (Airtable + EmailJS)" +``` + +--- + +### Task 7: Деплой на Netlify + +- [ ] **Step 1: Создать .gitignore** + +``` +# Если будешь хранить реальные ключи в отдельном файле +.env +*.local +``` + +```bash +git add .gitignore +git commit -m "chore: add gitignore" +``` + +- [ ] **Step 2: Создать репозиторий на GitHub** + +Зайти на github.com → New repository → назвать `sunset-pass-questionnaire` → Public → Create. + +```bash +git remote add origin https://github.com/ТВО_ИМЯ/sunset-pass-questionnaire.git +git branch -M main +git push -u origin main +``` + +- [ ] **Step 3: Деплой на Netlify** + +Зайти на netlify.com → Sign up → "Import from Git" → выбрать GitHub → выбрать репозиторий `sunset-pass-questionnaire` → Deploy site. + +Через 1-2 минуты Netlify даст ссылку вида `https://random-name.netlify.app` — это и есть ссылка для клиента. + +- [ ] **Step 4: Финальная проверка** + +Открыть ссылку Netlify в браузере → заполнить форму → отправить. +Ожидание: всё работает так же как локально. + +- [ ] **Step 5: Commit финального состояния** + +```bash +git add . +git commit -m "chore: final state before sending to client" +git push +```