From 9c1859182317b43059059264492a257616e06757 Mon Sep 17 00:00:00 2001 From: apuc Date: Wed, 22 Apr 2026 18:19:33 +0300 Subject: [PATCH] first --- .gitignore | 3 + main.py | 16 ++ requirements.txt | 4 + server.py | 389 +++++++++++++++++++++++++++++++++++++ server_simple.py | 108 +++++++++++ static/css/style.css | 444 +++++++++++++++++++++++++++++++++++++++++++ static/js/main.js | 63 ++++++ templates/index.html | 195 +++++++++++++++++++ 8 files changed, 1222 insertions(+) create mode 100644 .gitignore create mode 100644 main.py create mode 100644 requirements.txt create mode 100644 server.py create mode 100644 server_simple.py create mode 100644 static/css/style.css create mode 100644 static/js/main.js create mode 100644 templates/index.html diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..32ed5f8 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +.idea +.venv +data \ No newline at end of file diff --git a/main.py b/main.py new file mode 100644 index 0000000..5596b44 --- /dev/null +++ b/main.py @@ -0,0 +1,16 @@ +# This is a sample Python script. + +# Press Shift+F10 to execute it or replace it with your code. +# Press Double Shift to search everywhere for classes, files, tool windows, actions, and settings. + + +def print_hi(name): + # Use a breakpoint in the code line below to debug your script. + print(f'Hi, {name}') # Press Ctrl+F8 to toggle the breakpoint. + + +# Press the green button in the gutter to run the script. +if __name__ == '__main__': + print_hi('PyCharm') + +# See PyCharm help at https://www.jetbrains.com/help/pycharm/ diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..4057b56 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,4 @@ +fastapi==0.104.1 +uvicorn==0.24.0 +python-multipart==0.0.6 +jinja2==3.1.2 \ No newline at end of file diff --git a/server.py b/server.py new file mode 100644 index 0000000..458cfef --- /dev/null +++ b/server.py @@ -0,0 +1,389 @@ +# server.py +import re +import json +from datetime import datetime +from pathlib import Path +from fastapi import FastAPI, Request, Form +from fastapi.responses import HTMLResponse, JSONResponse +from fastapi.staticfiles import StaticFiles +from typing import Optional + +# ==================== КОНФИГУРАЦИЯ ==================== +HOST = "0.0.0.0" +PORT = 8000 +DEBUG = True + +BASE_DIR = Path(__file__).parent +TEMPLATES_DIR = BASE_DIR / "templates" +STATIC_DIR = BASE_DIR / "static" +DATA_DIR = BASE_DIR / "data" + +# Создаем необходимые папки +TEMPLATES_DIR.mkdir(exist_ok=True) +STATIC_DIR.mkdir(exist_ok=True) +DATA_DIR.mkdir(exist_ok=True) + +# Создаем подпапки для статики +(STATIC_DIR / "css").mkdir(exist_ok=True) +(STATIC_DIR / "js").mkdir(exist_ok=True) + +# ==================== ИНИЦИАЛИЗАЦИЯ FASTAPI ==================== +app = FastAPI(title="БС Патриот - Регистрация на круглый стол", debug=DEBUG) + +# Подключаем статические файлы +app.mount("/static", StaticFiles(directory=str(STATIC_DIR)), name="static") + + +# ==================== ВСПОМОГАТЕЛЬНЫЕ ФУНКЦИИ ==================== +def save_registration_to_file(data: dict) -> dict: + """Сохраняет заявку в JSON-файл""" + filepath = DATA_DIR / "registrations.json" + + registrations = [] + if filepath.exists(): + try: + with open(filepath, 'r', encoding='utf-8') as f: + registrations = json.load(f) + except (json.JSONDecodeError, IOError): + registrations = [] + + new_record = { + "id": len(registrations) + 1, + "created_at": datetime.now().isoformat(), + "fullname": data.get("fullname"), + "email": data.get("email"), + "phone": data.get("phone"), + "company": data.get("company"), + "businessSize": data.get("businessSize", ""), + "message": data.get("message", ""), + "status": "pending" + } + + registrations.append(new_record) + + with open(filepath, 'w', encoding='utf-8') as f: + json.dump(registrations, f, ensure_ascii=False, indent=2) + + return new_record + + +def get_html_content() -> str: + """Читает HTML файл или возвращает fallback""" + html_path = TEMPLATES_DIR / "index.html" + if html_path.exists(): + with open(html_path, 'r', encoding='utf-8') as f: + return f.read() + else: + return get_fallback_html() + + +def get_fallback_html() -> str: + """Fallback HTML если файл шаблона не найден""" + return """ + + + + + Круглый стол | БС «Патриот» + + + + + +
+
Закрытый клуб предпринимателей
+

Круглый стол с бизнес-сообществом «Патриот»

+

26 апреля 2026, начало в 11:00

+

Вход по рекомендации

+ +
+

557+

участников

+

125+

выездов в зону СВО

+

30+

комитетов

+
+ +
+

Регистрация на мероприятие

+
+ + + + + + + + +
+
+
+
+ + + +""" + + +# ==================== МАРШРУТЫ ==================== +@app.get("/", response_class=HTMLResponse) +async def get_landing_page(): + """Главная страница - посадочный лендинг мероприятия""" + return HTMLResponse(content=get_html_content(), status_code=200) + + +@app.post("/api/register") +async def register( + fullname: str = Form(...), + email: str = Form(...), + phone: str = Form(...), + company: str = Form(...), + businessSize: Optional[str] = Form(None), + message: Optional[str] = Form(None), + agree: Optional[str] = Form(None) +): + """API-эндпоинт для регистрации участников""" + + print(f"Received data: fullname={fullname}, email={email}, phone={phone}, company={company}, agree={agree}") + + # Валидация + if not agree or agree != "true": + return JSONResponse( + status_code=400, + content={"success": False, "message": "Необходимо согласие с условиями"} + ) + + if not fullname or len(fullname.strip()) < 2: + return JSONResponse( + status_code=400, + content={"success": False, "message": "Введите корректное ФИО"} + ) + + email_pattern = r'^[^\s@]+@([^\s@.,]+\.)+[^\s@.,]{2,}$' + if not re.match(email_pattern, email): + return JSONResponse( + status_code=400, + content={"success": False, "message": "Введите корректный email"} + ) + + digits_only = re.sub(r'\D', '', phone) + if len(digits_only) < 10: + return JSONResponse( + status_code=400, + content={"success": False, "message": "Введите корректный номер телефона (минимум 10 цифр)"} + ) + + if not company or len(company.strip()) < 1: + return JSONResponse( + status_code=400, + content={"success": False, "message": "Укажите название компании"} + ) + + data = { + "fullname": fullname.strip(), + "email": email.strip().lower(), + "phone": phone.strip(), + "company": company.strip(), + "businessSize": businessSize if businessSize else "", + "message": message.strip() if message else "", + } + + try: + saved = save_registration_to_file(data) + print(f"Saved registration: {saved}") + return JSONResponse(content={ + "success": True, + "message": "Заявка успешно отправлена! Менеджер сообщества свяжется с вами в ближайшее время." + }) + except Exception as e: + print(f"Error saving registration: {e}") + return JSONResponse( + status_code=500, + content={"success": False, "message": f"Ошибка сервера: {str(e)}"} + ) + + +@app.get("/admin/registrations", response_class=HTMLResponse) +async def admin_registrations(): + """Админка для просмотра заявок""" + filepath = DATA_DIR / "registrations.json" + registrations = [] + if filepath.exists(): + try: + with open(filepath, 'r', encoding='utf-8') as f: + registrations = json.load(f) + except: + registrations = [] + + registrations.sort(key=lambda x: x.get("created_at", ""), reverse=True) + + # Используем обычное форматирование строки без .format() + html = f""" + + + + + Админка | Заявки на круглый стол + + + +
+

📋 Заявки на круглый стол «Патриот»

+
📊 Всего заявок: {len(registrations)}
+
+ + + + + + + + + + + + + + + + """ + + for reg in registrations: + created = reg.get("created_at", "")[:16].replace("T", " ") + status_class = "status-pending" if reg.get('status') == 'pending' else "" + message_text = reg.get('message', '—')[:100] + if len(reg.get('message', '')) > 100: + message_text += "..." + + html += f""" + + + + + + + + + + + + """ + + html += """ + +
IDДатаФИОEmailТелефонКомпанияОборотСообщениеСтатус
{reg.get('id', '—')}{created}{reg.get('fullname', '—')}{reg.get('email', '—')}{reg.get('phone', '—')}{reg.get('company', '—')}{reg.get('businessSize', '—')}{message_text}{reg.get('status', 'pending')}
+
+ ← Вернуться на главную +
+ + + """ + + return HTMLResponse(content=html, status_code=200) + + +@app.get("/health") +async def health_check(): + """Health check для хостинга""" + return {"status": "ok", "timestamp": datetime.now().isoformat()} + + +# ==================== ЗАПУСК ==================== +if __name__ == "__main__": + import uvicorn + + print("=" * 60) + print("🚀 Сервер для посадочной страницы БС «Патриот»") + print(f"📁 Шаблоны: {TEMPLATES_DIR}") + print(f"📁 Статика: {STATIC_DIR}") + print(f"📁 Данные: {DATA_DIR}") + print("=" * 60) + print(f"✨ Главная страница: http://localhost:{PORT}") + print(f"🔧 Админка: http://localhost:{PORT}/admin/registrations") + print("=" * 60) + print("💡 Для остановки сервера нажмите Ctrl+C") + print("=" * 60) + + uvicorn.run( + app, + host=HOST, + port=PORT, + log_level="info" + ) \ No newline at end of file diff --git a/server_simple.py b/server_simple.py new file mode 100644 index 0000000..5d6cbd0 --- /dev/null +++ b/server_simple.py @@ -0,0 +1,108 @@ +# server_simple.py - упрощенная версия без Jinja2 +import re +import json +from datetime import datetime +from pathlib import Path +from fastapi import FastAPI, Form +from fastapi.responses import HTMLResponse, JSONResponse +from fastapi.staticfiles import StaticFiles + +# ==================== КОНФИГУРАЦИЯ ==================== +HOST = "0.0.0.0" +PORT = 8000 + +BASE_DIR = Path(__file__).parent +STATIC_DIR = BASE_DIR / "static" +DATA_DIR = BASE_DIR / "data" + +STATIC_DIR.mkdir(exist_ok=True) +DATA_DIR.mkdir(exist_ok=True) +(STATIC_DIR / "css").mkdir(exist_ok=True) +(STATIC_DIR / "js").mkdir(exist_ok=True) + +app = FastAPI() +app.mount("/static", StaticFiles(directory=str(STATIC_DIR)), name="static") + +# Читаем HTML файл +HTML_FILE = BASE_DIR / "templates" / "index.html" + + +def save_registration_to_file(data: dict) -> dict: + filepath = DATA_DIR / "registrations.json" + registrations = [] + if filepath.exists(): + try: + with open(filepath, 'r', encoding='utf-8') as f: + registrations = json.load(f) + except: + registrations = [] + + new_record = { + "id": len(registrations) + 1, + "created_at": datetime.now().isoformat(), + **data, + "status": "pending" + } + registrations.append(new_record) + with open(filepath, 'w', encoding='utf-8') as f: + json.dump(registrations, f, ensure_ascii=False, indent=2) + return new_record + + +@app.get("/", response_class=HTMLResponse) +async def get_landing_page(): + if HTML_FILE.exists(): + with open(HTML_FILE, 'r', encoding='utf-8') as f: + return HTMLResponse(content=f.read()) + else: + return HTMLResponse(content="

Файл templates/index.html не найден

") + + +@app.post("/api/register") +async def register( + fullname: str = Form(...), + email: str = Form(...), + phone: str = Form(...), + company: str = Form(...), + businessSize: str = Form(""), + message: str = Form(""), + agree: bool = Form(False) +): + if not agree: + return JSONResponse(status_code=400, content={"success": False, "message": "Необходимо согласие"}) + + data = { + "fullname": fullname.strip(), + "email": email.strip().lower(), + "phone": phone.strip(), + "company": company.strip(), + "businessSize": businessSize, + "message": message.strip(), + } + + try: + save_registration_to_file(data) + return JSONResponse(content={"success": True, "message": "Заявка отправлена!"}) + except Exception as e: + return JSONResponse(status_code=500, content={"success": False, "message": str(e)}) + + +@app.get("/admin/registrations", response_class=HTMLResponse) +async def admin_registrations(): + filepath = DATA_DIR / "registrations.json" + registrations = [] + if filepath.exists(): + with open(filepath, 'r', encoding='utf-8') as f: + registrations = json.load(f) + + html = "

Заявки

" + for r in registrations: + html += f"" + html += "
{r.get('fullname')}{r.get('email')}
Назад" + return HTMLResponse(content=html) + + +if __name__ == "__main__": + import uvicorn + + uvicorn.run(app, host=HOST, port=PORT) \ No newline at end of file diff --git a/static/css/style.css b/static/css/style.css new file mode 100644 index 0000000..eff2560 --- /dev/null +++ b/static/css/style.css @@ -0,0 +1,444 @@ +* { + margin: 0; + padding: 0; + box-sizing: border-box; +} + +body { + font-family: 'Inter', sans-serif; + background-color: #fefcf5; + color: #1a1f2b; + line-height: 1.4; + scroll-behavior: smooth; +} + +.container { + max-width: 1280px; + margin: 0 auto; + padding: 0 24px; +} + +.section { + padding: 80px 0; +} + +.section-sm { + padding: 60px 0; +} + +.bg-light { + background-color: #ffffff; +} + +.bg-gentle { + background-color: #f8f6f0; +} + +.btn { + display: inline-flex; + align-items: center; + gap: 12px; + padding: 14px 32px; + border-radius: 60px; + font-weight: 600; + font-size: 1rem; + text-decoration: none; + transition: all 0.25s ease; + cursor: pointer; + border: none; + background: none; + font-family: inherit; +} + +.btn-primary { + background: #c52a1c; + color: white; + box-shadow: 0 8px 20px rgba(197, 42, 28, 0.25); +} + +.btn-primary:hover { + background: #9e2015; + transform: translateY(-3px); + box-shadow: 0 14px 28px rgba(197, 42, 28, 0.35); +} + +.btn-outline { + border: 2px solid #c52a1c; + color: #c52a1c; + background: transparent; +} + +.btn-outline:hover { + background: #c52a1c; + color: white; + transform: translateY(-2px); +} + +h1, h2, h3 { + font-weight: 700; + letter-spacing: -0.02em; +} + +h1 { + font-size: 3.2rem; + line-height: 1.2; +} + +h2 { + font-size: 2.4rem; + margin-bottom: 1.5rem; +} + +.badge { + background: rgba(197, 42, 28, 0.12); + color: #c52a1c; + padding: 6px 18px; + border-radius: 40px; + font-size: 0.85rem; + font-weight: 600; + display: inline-block; + margin-bottom: 20px; +} + +.navbar { + display: flex; + justify-content: space-between; + align-items: center; + padding: 20px 0; + flex-wrap: wrap; +} + +.logo { + font-weight: 800; + font-size: 1.6rem; + letter-spacing: -0.02em; +} + +.logo span { + color: #c52a1c; +} + +.nav-links { + display: flex; + gap: 32px; + align-items: center; +} + +.nav-links a { + text-decoration: none; + color: #1a1f2b; + font-weight: 500; + transition: color 0.2s; +} + +.nav-links a:hover { + color: #c52a1c; +} + +.hero { + display: flex; + flex-wrap: wrap; + align-items: center; + justify-content: space-between; + gap: 48px; +} + +.hero-content { + flex: 1.2; +} + +.hero-description { + font-size: 1.2rem; + margin: 24px 0 20px; + color: #2e3a48; + line-height: 1.4; +} + +.hero-buttons { + display: flex; + gap: 20px; + flex-wrap: wrap; +} + +.hero-info { + margin-top: 32px; + display: flex; + gap: 24px; + flex-wrap: wrap; +} + +.hero-stats { + flex: 0.9; + background: white; + padding: 32px; + border-radius: 32px; + box-shadow: 0 20px 35px -12px rgba(0,0,0,0.08); + border: 1px solid #edeae2; +} + +.stats-title { + font-weight: 600; + font-size: 1rem; + border-bottom: 2px solid #c52a1c; + display: inline-block; + margin-bottom: 16px; +} + +.stat-grid { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 24px; + margin-top: 20px; +} + +.stat-item h4 { + font-size: 2rem; + font-weight: 800; + color: #c52a1c; +} + +.stats-note { + font-size: 0.8rem; + margin-top: 20px; + color: #5e6f8d; +} + +.about-grid { + display: flex; + flex-wrap: wrap; + gap: 40px; + justify-content: space-between; +} + +.about-content { + flex: 1.2; +} + +.about-content p { + font-size: 1.05rem; + line-height: 1.5; + margin-bottom: 24px; +} + +.values-list { + display: flex; + gap: 16px; + flex-wrap: wrap; +} + +.values-list span { + background: #f4f2ec; + padding: 6px 14px; + border-radius: 40px; +} + +.about-quote { + flex: 0.8; + background: #fefaf2; + border-radius: 32px; + padding: 28px; +} + +.about-quote p { + font-style: italic; + margin: 12px 0; +} + +.quote-author { + font-weight: 600; + margin-top: 16px; +} + +.section-header { + text-align: center; + max-width: 700px; + margin: 0 auto 40px; +} + +.cards-grid { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); + gap: 32px; + margin-top: 32px; +} + +.card { + background: white; + padding: 28px; + border-radius: 28px; + box-shadow: 0 8px 24px rgba(0,0,0,0.03); + transition: transform 0.2s, box-shadow 0.2s; + border: 1px solid #efebe3; +} + +.card:hover { + transform: translateY(-6px); + box-shadow: 0 20px 30px -12px rgba(0,0,0,0.1); +} + +.card i { + font-size: 2.2rem; + color: #c52a1c; + margin-bottom: 20px; +} + +.agenda-list { + background: white; + border-radius: 32px; + overflow: hidden; + border: 1px solid #e9e5db; +} + +.agenda-item { + display: flex; + padding: 20px 28px; + border-bottom: 1px solid #efebe3; + align-items: flex-start; + gap: 20px; + flex-wrap: wrap; +} + +.agenda-time { + font-weight: 700; + min-width: 100px; + color: #c52a1c; +} + +.stats-wrapper { + display: flex; + flex-wrap: wrap; + gap: 40px; + align-items: center; +} + +.stats-info { + flex: 1; +} + +.stats-info ul { + margin-top: 20px; + list-style: none; +} + +.stats-info li { + margin-bottom: 12px; +} + +.stats-cta { + flex: 1; + background: #ffffff; + border-radius: 32px; + padding: 32px; + text-align: center; + box-shadow: 0 10px 25px rgba(0,0,0,0.02); +} + +.stats-cta i { + font-size: 3rem; + color: #c52a1c; + margin-bottom: 16px; + display: inline-block; +} + +.form-card { + background: white; + border-radius: 36px; + padding: 40px; + box-shadow: 0 20px 40px rgba(0,0,0,0.05); + border: 1px solid #eae5db; + max-width: 700px; + margin: 0 auto; +} + +.input-group { + margin-bottom: 20px; +} + +input, select, textarea { + width: 100%; + padding: 14px 20px; + border-radius: 60px; + border: 1.5px solid #e2dcd0; + font-family: 'Inter', sans-serif; + font-size: 1rem; + transition: 0.2s; + background: #fff; +} + +input:focus, select:focus, textarea:focus { + outline: none; + border-color: #c52a1c; + box-shadow: 0 0 0 3px rgba(197,42,28,0.1); +} + +textarea { + border-radius: 28px; + resize: vertical; +} + +.submit-btn { + width: 100%; + justify-content: center; +} + +.form-message { + margin-top: 16px; + font-size: 0.9rem; + font-weight: 500; +} + +.success-msg { + color: #1f8a4c; + background: #e0f2e9; + padding: 12px; + border-radius: 60px; + text-align: center; +} + +.error-msg { + color: #c52a1c; + background: #ffe8e5; + padding: 12px; + border-radius: 60px; + text-align: center; +} + +.form-note { + font-size: 0.75rem; + color: #7a7c7f; + margin-top: 20px; + text-align: center; +} + +footer { + background: #0a1a2f; + color: #b9c7d9; + padding: 48px 0; + text-align: center; +} + +.footer-logo { + font-weight: 800; + font-size: 1.4rem; + margin-bottom: 24px; +} + +footer a { + color: #c9a87c; + text-decoration: none; +} + +@media (max-width: 900px) { + h1 { font-size: 2.4rem; } + h2 { font-size: 1.9rem; } + .hero { flex-direction: column; } + .navbar { flex-direction: column; gap: 16px; } + .nav-links { gap: 20px; flex-wrap: wrap; justify-content: center; } + .section { padding: 50px 0; } + .form-card { padding: 28px; } +} + +@media (max-width: 550px) { + .container { padding: 0 20px; } + .btn { padding: 10px 22px; } +} \ No newline at end of file diff --git a/static/js/main.js b/static/js/main.js new file mode 100644 index 0000000..57e7866 --- /dev/null +++ b/static/js/main.js @@ -0,0 +1,63 @@ +// Обработка формы регистрации +const form = document.getElementById('registrationForm'); +const feedbackDiv = document.getElementById('formFeedback'); + +if (form) { + form.addEventListener('submit', async function(e) { + e.preventDefault(); + + if (feedbackDiv) { + feedbackDiv.innerHTML = ''; + feedbackDiv.className = 'form-message'; + } + + const formData = new FormData(form); + const submitBtn = form.querySelector('button[type="submit"]'); + const originalText = submitBtn.innerHTML; + + submitBtn.disabled = true; + submitBtn.innerHTML = ' Отправка...'; + + try { + const response = await fetch('/api/register', { + method: 'POST', + body: formData + }); + const data = await response.json(); + + if (feedbackDiv) { + if (data.success) { + feedbackDiv.innerHTML = '
✅ ' + data.message + '
'; + form.reset(); + } else { + feedbackDiv.innerHTML = '
❌ ' + data.message + '
'; + } + } + } catch (err) { + console.error('Error:', err); + if (feedbackDiv) { + feedbackDiv.innerHTML = '
❌ Ошибка соединения. Попробуйте позже.
'; + } + } finally { + submitBtn.disabled = false; + submitBtn.innerHTML = originalText; + + setTimeout(() => { + if (feedbackDiv) feedbackDiv.innerHTML = ''; + }, 5000); + } + }); +} + +// Плавная прокрутка для якорных ссылок +document.querySelectorAll('a[href^="#"]').forEach(anchor => { + anchor.addEventListener('click', function(e) { + const hash = this.getAttribute('href'); + if (hash === '#') return; + const target = document.querySelector(hash); + if (target) { + e.preventDefault(); + target.scrollIntoView({ behavior: 'smooth', block: 'start' }); + } + }); +}); \ No newline at end of file diff --git a/templates/index.html b/templates/index.html new file mode 100644 index 0000000..d031bdd --- /dev/null +++ b/templates/index.html @@ -0,0 +1,195 @@ + + + + + + Круглый стол | БС «Патриот» | Бизнес-сообщество предпринимателей + + + + + +
+
+ +
+
+ +
+
+
+
+
+
Закрытый клуб предпринимателей
+

Круглый стол
с бизнес‑сообществом «Патриот»

+

Объединяем лидеров, которые строят будущее России. Живой диалог, реальные кейсы и партнёрство без формальностей.

+ +
+
26 апреля 2026, начало в 11:00
+
Вход по рекомендации
+
+
+
+
Сообщество в цифрах
+
+

557+

участников

+

125+

выездов в зону СВО

+

30+

комитетов

+

250+

предпринимателей c 1 млрд+

+
+

По данным сайта сообщества

+
+
+
+
+ +
+
+
Миссия и ценности
+
+
+

Бизнес как
социальная миссия

+

Сообщество «Предприниматели Патриоты» объединяет активных владельцев бизнеса, героев СВО, олимпийских чемпионов и лидеров мнений. Мы создаём среду, где бренд «Сделано в России» становится знаком качества и силы.

+

На круглом столе встретятся ЛПР, чтобы обсудить реальные инструменты масштабирования, социальные проекты и укрепление делового суверенитета. Закрытый клуб — только для единомышленников.

+
+ Патриотизм + Соц. ответственность + Лидерство + Личный пример +
+
+
+ +

«Мы хотим, чтобы слово „патриот“ ассоциировалось с надёжным партнёром и лидером рынка. Встреча за круглым столом — место честного диалога без галстуков».

+

— Вячеслав Варяников, основатель сообщества

+
+
+
+
+ +
+
+
+
Почему участвовать
+

Формат доверия и пользы

+
+
+

Топ-нетворкинг

Встреча с первыми лицами компаний, членами комитетов и экспертами с выручкой от 1 млрд.

+

Реальные проекты

Совместные инициативы, социальные программы и коммерческие коллаборации.

+

Живые кейсы

Разбор практических ситуаций от участников сообщества «Патриот» без купюр.

+

Закрытый клуб

Доступ по рекомендации — среда, где ценят репутацию и патриотизм.

+
+
+
+ +
+
+
+
Программа круглого стола
+

Стратегия, партнёрство, развитие

+

Камерная встреча с живым обсуждением. Формат — открытый микрофон, панельные дискуссии и кофе-брейк.

+
+
+
11:00 – 11:30
Сбор кофе, приветственный кофе-брейк
Неформальное знакомство участников.
+
11:30 – 12:30
Панель «Бизнес и социальная ответственность»
Как проекты помощи и поддержка СВО влияют на репутацию и прибыль.
+
12:30 – 13:30
Круглый стол «Точки роста: импортозамещение и экспорт»
Успешные стратегии участников сообщества.
+
13:30 – 14:30
Обед и нетворкинг
Живое общение, обмен контактами.
+
14:30 – 15:45
Открытый диалог с основателями комитетов
Ответы на вопросы, разбор запросов участников.
+
15:45 – 16:00
Заключение, анонс совместных проектов
Формирование рабочих групп.
+
+
+
+ +
+
+
+
+
Сообщество Патриот.РФ
+

Объединяя лидеров
для побед России

+

Мы растем: от 557 участников до масштабных гуманитарных миссий. 125+ выездов, 600+ детей под опекой предпринимателей и 10+ млн подписчиков в общем охвате.

+
    +
  • 250+ предпринимателей c оборотом от 1 млрд руб.
  • +
  • 30 комитетов: спорт, обучение, соцпроекты
  • +
  • Ежемесячные стратегические сессии с героями СВО
  • +
+
+
+ +

Присоединиться к 557+

+

Участники сообщества получают поддержку государства, гранты и надежные B2B-связи. Круглый стол — ваш шанс войти в закрытый пул.

+ Подать заявку +
+
+
+
+ +
+
+
+
Участие строго по отбору
+

Стать участником круглого стола

+

Заполните анкету — модератор сообщества свяжется с вами для подтверждения. Вход для предпринимателей, топ-менеджеров и партнёров, разделяющих ценности «Патриота».

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

После одобрения вы получите персональное приглашение. Количество мест ограничено.

+
+
+
+
+ + + + + + \ No newline at end of file