From 0be6b30713aa2e914cd6bbb70a62f02f80f29a9b Mon Sep 17 00:00:00 2001 From: houseassassin Date: Wed, 20 May 2026 12:22:58 +0300 Subject: [PATCH] feat: landing page (hero, features, pricing, how-to, FAQ) --- src/components/landing/FAQSection.tsx | 32 ++++++++++++ src/components/landing/FeaturesSection.tsx | 31 ++++++++++++ src/components/landing/HeroSection.tsx | 58 ++++++++++++++++++++++ src/components/landing/HowToSection.tsx | 36 ++++++++++++++ src/components/landing/PricingSection.tsx | 54 ++++++++++++++++++++ src/pages/Landing.tsx | 24 ++++++++- 6 files changed, 234 insertions(+), 1 deletion(-) create mode 100644 src/components/landing/FAQSection.tsx create mode 100644 src/components/landing/FeaturesSection.tsx create mode 100644 src/components/landing/HeroSection.tsx create mode 100644 src/components/landing/HowToSection.tsx create mode 100644 src/components/landing/PricingSection.tsx diff --git a/src/components/landing/FAQSection.tsx b/src/components/landing/FAQSection.tsx new file mode 100644 index 0000000..f8a9038 --- /dev/null +++ b/src/components/landing/FAQSection.tsx @@ -0,0 +1,32 @@ +import { useState } from "react"; +import { ChevronDown } from "lucide-react"; + +const faqs = [ + { q: "На каких устройствах работает?", a: "iOS, Android, Windows, macOS, Linux — на всех. Одна подписка до 5 устройств." }, + { q: "Какие протоколы используются?", a: "WireGuard, AmneziaWG и VLESS. Обходят любые блокировки, включая DPI." }, + { q: "Есть ли ограничения по трафику?", a: "Нет. Все тарифы — неограниченный трафик на весь срок подписки." }, + { q: "Как быстро приходит доступ?", a: "Мгновенно после оплаты. QR-код для подключения доступен сразу в кабинете." }, + { q: "Как продлить подписку?", a: "В личном кабинете раздел «Мои ключи» → кнопка продлить, или через Telegram-бот." }, + { q: "Возможен возврат средств?", a: "Да, в течение 24 часов после покупки если VPN не заработал. Пишите в поддержку." }, +]; + +export function FAQSection() { + const [open, setOpen] = useState(null); + return ( +
+

Частые вопросы

+
+ {faqs.map(({ q, a }, i) => ( +
+ + {open === i &&
{a}
} +
+ ))} +
+
+ ); +} diff --git a/src/components/landing/FeaturesSection.tsx b/src/components/landing/FeaturesSection.tsx new file mode 100644 index 0000000..5b70c88 --- /dev/null +++ b/src/components/landing/FeaturesSection.tsx @@ -0,0 +1,31 @@ +import { GlassCard } from "../ui/GlassCard"; +import { Zap, Lock, Smartphone, Globe, Headphones, Shield } from "lucide-react"; + +const features = [ + { icon: Zap, title: "До 10 Гбит/с", desc: "Высокоскоростные серверы без троттлинга" }, + { icon: Lock, title: "Шифрование", desc: "AES-256 + ChaCha20. Никаких логов." }, + { icon: Smartphone, title: "До 5 устройств", desc: "Один аккаунт на все ваши гаджеты" }, + { icon: Globe, title: "WireGuard + VLESS", desc: "Современные протоколы, работают везде" }, + { icon: Headphones, title: "Поддержка 24/7", desc: "Telegram-бот отвечает мгновенно" }, + { icon: Shield, title: "AmneziaWG", desc: "Обходит DPI и блокировки провайдеров" }, +]; + +export function FeaturesSection() { + return ( +
+

Почему Aura?

+

Всё что нужно для безопасного интернета

+
+ {features.map(({ icon: Icon, title, desc }) => ( + +
+ +
+

{title}

+

{desc}

+
+ ))} +
+
+ ); +} diff --git a/src/components/landing/HeroSection.tsx b/src/components/landing/HeroSection.tsx new file mode 100644 index 0000000..f0a79f7 --- /dev/null +++ b/src/components/landing/HeroSection.tsx @@ -0,0 +1,58 @@ +import { motion } from "framer-motion"; +import { Link } from "react-router-dom"; +import { Button } from "../ui/Button"; +import { Shield, Zap, Lock } from "lucide-react"; + +export function HeroSection() { + return ( +
+ {/* Background glow */} +
+
+
+
+ + {/* Floating icons */} + + + + + + + + {/* Content */} +
+ +
+ Быстро. Безопасно. Анонимно. +
+

+ + Свобода + +
+ в сети +

+

+ VPN-сервис нового поколения. WireGuard и VLESS протоколы, мгновенное подключение через QR-код. +

+
+ + + + + + +
+

Также доступно в Telegram боте

+
+
+
+ ); +} diff --git a/src/components/landing/HowToSection.tsx b/src/components/landing/HowToSection.tsx new file mode 100644 index 0000000..3a94a7c --- /dev/null +++ b/src/components/landing/HowToSection.tsx @@ -0,0 +1,36 @@ +import { ShoppingCart, Download, QrCode, Wifi } from "lucide-react"; + +const steps = [ + { icon: ShoppingCart, title: "Купить подписку", desc: "Выбери тариф и оплати через СБП или карту" }, + { icon: Download, title: "Скачай приложение", desc: "Hiddify, V2rayTun или AmneziaVPN — для любого устройства" }, + { icon: QrCode, title: "Отсканируй QR", desc: "Открой личный кабинет и отсканируй QR прямо в приложении" }, + { icon: Wifi, title: "Работает!", desc: "VPN подключён. Безопасный и быстрый интернет" }, +]; + +export function HowToSection() { + return ( +
+

Как подключиться

+

4 простых шага

+
+
+
+ {steps.map(({ icon: Icon, title, desc }, i) => ( +
+
+
+ +
+ + {i + 1} + +
+

{title}

+

{desc}

+
+ ))} +
+
+
+ ); +} diff --git a/src/components/landing/PricingSection.tsx b/src/components/landing/PricingSection.tsx new file mode 100644 index 0000000..54d2ec6 --- /dev/null +++ b/src/components/landing/PricingSection.tsx @@ -0,0 +1,54 @@ +import { useEffect, useState } from "react"; +import { api } from "../../api/client"; +import { GlassCard } from "../ui/GlassCard"; +import { Button } from "../ui/Button"; +import { Check } from "lucide-react"; +import { Link } from "react-router-dom"; + +interface Tariff { id: number; name: string; duration_days: number; price_rub: number; } + +export function PricingSection() { + const [tariffs, setTariffs] = useState([]); + + useEffect(() => { + api.action("tariffs").then((r) => { if (r.ok) setTariffs(r.tariffs); }); + }, []); + + const perks = ["Неограниченный трафик", "До 5 устройств", "WireGuard + VLESS", "Поддержка 24/7"]; + + return ( +
+

Тарифы

+

Без скрытых платежей

+
+ {tariffs.map((t, i) => { + const popular = i === 1; + return ( + + {popular && ( +
+ Популярный +
+ )} +
{t.name}
+
{t.price_rub}
+
{t.duration_days} дней
+
    + {perks.map((p) => ( +
  • + {p} +
  • + ))} +
+ + + +
+ ); + })} +
+
+ ); +} diff --git a/src/pages/Landing.tsx b/src/pages/Landing.tsx index 2304eaf..0126b75 100644 --- a/src/pages/Landing.tsx +++ b/src/pages/Landing.tsx @@ -1 +1,23 @@ -export default function Landing() { return
Landing
; } +import { Navbar } from "../components/layout/Navbar"; +import { Footer } from "../components/layout/Footer"; +import { HeroSection } from "../components/landing/HeroSection"; +import { FeaturesSection } from "../components/landing/FeaturesSection"; +import { PricingSection } from "../components/landing/PricingSection"; +import { HowToSection } from "../components/landing/HowToSection"; +import { FAQSection } from "../components/landing/FAQSection"; + +export default function Landing() { + return ( +
+ +
+ + + + + +
+
+ ); +}