From c4e9a9294b9c61244f3ca9fd5be55d2342add954 Mon Sep 17 00:00:00 2001 From: Ruslan Date: Thu, 14 May 2026 10:08:35 +0300 Subject: [PATCH] feat: contact form modal with Telegram, enlarge Made by button --- static/css/index.css | 24 +++++---- templates/index.html | 116 ++++++++++++++++++++++++++++++++++++++++++- zkart_app/routes.py | 40 +++++++++++++++ 3 files changed, 168 insertions(+), 12 deletions(-) diff --git a/static/css/index.css b/static/css/index.css index b683e55..a0e5170 100644 --- a/static/css/index.css +++ b/static/css/index.css @@ -522,16 +522,20 @@ line-height: 1.1; z-index: 5; } - .credit .name { + #btn-contact-ruslan { font-family: Caveat, cursive; - font-size: 14px; + font-size: 42px; color: #1c3f7c; + background: none; + border: none; + cursor: pointer; + padding: 0; + line-height: 1; + transition: opacity .15s ease, transform .15s ease; } - .credit a { - font-size: 7px; - color: #2f5fae; - text-decoration: none; - font-weight: 700; + #btn-contact-ruslan:hover { + opacity: .75; + transform: scale(1.04); } @media (max-width: 980px) { @@ -539,8 +543,7 @@ .board { grid-template-columns: 1fr; } .hero { padding: 20px; } .credit { right: 8px; bottom: 6px; } - .credit .name { font-size: 8px; } - .credit a { font-size: 6px; } + #btn-contact-ruslan { font-size: 28px; } } @media (max-width: 768px) { @@ -637,8 +640,9 @@ background: rgba(255, 255, 255, .86); border: 1px solid #dbe6ff; border-radius: 10px; - padding: 4px 6px; + padding: 4px 8px; } + #btn-contact-ruslan { font-size: 24px; } } @media (max-width: 420px) { diff --git a/templates/index.html b/templates/index.html index d408122..a7faecd 100644 --- a/templates/index.html +++ b/templates/index.html @@ -61,11 +61,22 @@
-
Made by Galyaviev
- RGalyaviev@mont.com +
+ + + + diff --git a/zkart_app/routes.py b/zkart_app/routes.py index c3ec581..308c0f1 100644 --- a/zkart_app/routes.py +++ b/zkart_app/routes.py @@ -805,6 +805,46 @@ def health(): return {"status": "ok"} +@bp.post("/api/contact") +def contact(): + import re as _re + data = request.get_json(silent=True) or {} + name = str(data.get("name", "")).strip() + email = str(data.get("email", "")).strip() + phone = str(data.get("phone", "")).strip() + text = str(data.get("text", "")).strip() + + if not all([name, email, phone, text]): + return jsonify({"detail": "Заполните все обязательные поля"}), 422 + if not _re.match(r"^[^\s@]+@[^\s@]+\.[^\s@]+$", email): + return jsonify({"detail": "Некорректный email"}), 422 + if not _re.match(r"^[\+\d][\d\s\-\(\)]{6,18}$", phone): + return jsonify({"detail": "Некорректный номер телефона"}), 422 + + divider = "━" * 22 + msg = ( + f"🔔 *Сообщение через форму*\n{divider}\n\n" + f"👤 *Имя:* {name}\n" + f"📧 *Email:* {email}\n" + f"📱 *Телефон:* {phone}\n\n" + f"💬 *Сообщение:*\n{text}" + ) + payload = json.dumps({ + "chat_id": TELEGRAM_CHAT_ID, + "text": msg, + "parse_mode": "Markdown", + }).encode() + url = f"https://api.telegram.org/bot{TELEGRAM_BOT_TOKEN}/sendMessage" + try: + req = Request(url, data=payload, headers={"Content-Type": "application/json"}) + with urlopen(req, timeout=10) as resp: + resp.read() + except Exception as e: + return jsonify({"detail": f"Ошибка отправки: {e}"}), 502 + + return jsonify({"ok": True}) + + @bp.get("/assets/mont-logo") def mont_logo(): return send_from_directory(BASE_DIR, "mont_logo.png")