From a2ba21c188edf2bea6d85270ad41b361c7349700 Mon Sep 17 00:00:00 2001 From: Yevhenii Datsenko Date: Wed, 28 Jan 2026 15:55:55 +0200 Subject: [PATCH 1/7] (SP 2) [Frontend] Update Features section content and improve mobile UX - Features Section: Refined feature content and visuals. - Mobile UX: Improved responsive layout and scaling for feature cards and interactive elements. - Visual Enhancements: Added dynamic particle background effects to the Pricing section. --- frontend/app/globals.css | 38 ++ .../components/about/CommunitySection.tsx | 59 +- frontend/components/about/FeaturesSection.tsx | 641 ++++++++++-------- frontend/components/about/HeroSection.tsx | 20 +- frontend/components/about/PricingSection.tsx | 72 +- frontend/components/about/SponsorsWall.tsx | 17 +- frontend/components/about/TopicsSection.tsx | 8 +- frontend/components/ui/gradient-badge.tsx | 22 + frontend/components/ui/particle-canvas.tsx | 348 ++++++++++ frontend/components/ui/section-heading.tsx | 25 + 10 files changed, 873 insertions(+), 377 deletions(-) create mode 100644 frontend/components/ui/gradient-badge.tsx create mode 100644 frontend/components/ui/particle-canvas.tsx create mode 100644 frontend/components/ui/section-heading.tsx diff --git a/frontend/app/globals.css b/frontend/app/globals.css index a5a92c93..c789b40e 100644 --- a/frontend/app/globals.css +++ b/frontend/app/globals.css @@ -331,6 +331,44 @@ --card-rotate-offset: 3deg; animation-delay: 0.8s; } + + /* Feature bubble floating animation */ + .animate-float { + animation: float 3s ease-in-out infinite; + will-change: transform; + } + + /* Slow spinning for orbit rings */ + .animate-spin-slow { + animation: spin 20s linear infinite; + } + + .animate-spin-slower { + animation: spin 30s linear infinite reverse; + } + + /* Dashed line flow animation */ + .animate-dash-flow { + animation: dash-flow 2s linear infinite; + } +} + +@keyframes float { + 0%, 100% { + transform: translateY(0); + } + 50% { + transform: translateY(-8px); + } +} + +@keyframes dash-flow { + 0% { + stroke-dashoffset: 0; + } + 100% { + stroke-dashoffset: 20; + } } /* Shop theme: scoped overrides (must not affect platform pages) */ diff --git a/frontend/components/about/CommunitySection.tsx b/frontend/components/about/CommunitySection.tsx index f8232dd5..dd37aceb 100644 --- a/frontend/components/about/CommunitySection.tsx +++ b/frontend/components/about/CommunitySection.tsx @@ -1,32 +1,31 @@ "use client" -import { MessageCircle, Github, ArrowRight, ExternalLink } from "lucide-react" -import { TESTIMONIALS, type Testimonial } from "@/data/about" - +import { Github, ArrowRight, ExternalLink, MessageCircle } from "lucide-react" import Link from "next/link" +import { TESTIMONIALS, type Testimonial } from "@/data/about" +import { GradientBadge } from "@/components/ui/gradient-badge" +import { SectionHeading } from "@/components/ui/section-heading" export function CommunitySection() { return ( -
+
-
-
- Community Love -
+
+ -

- Approved by Survivors -

-

- Join thousands of developers who stopped guessing and started shipping. Real feedback from real engineers. -

+
-
+
@@ -45,25 +44,23 @@ export function CommunitySection() {
-
-
- - Have a success story or feature request? - +
+
- + Join Discussion - +
@@ -94,8 +91,8 @@ export function CommunitySection() { -

- We read every single thread +

+ We read every single thread

@@ -114,7 +111,7 @@ function TestimonialCard({ color }: Testimonial) { return ( -
+
diff --git a/frontend/components/about/FeaturesSection.tsx b/frontend/components/about/FeaturesSection.tsx index 3d1839b5..38dd2711 100644 --- a/frontend/components/about/FeaturesSection.tsx +++ b/frontend/components/about/FeaturesSection.tsx @@ -1,336 +1,395 @@ "use client" -import { useState } from "react" +import { useState, useEffect } from "react" import { motion, AnimatePresence } from "framer-motion" import { Link } from "@/i18n/routing" -import { MessageCircle, Brain, Trophy, User, ShoppingBag } from "lucide-react" +import { + MessageCircle, Brain, Trophy, User, ShoppingBag, BookOpen, + Globe, Cpu, Shield, Languages, Clock, Lightbulb, Target, + Medal, Users, Flame, Zap, BarChart3, TrendingUp, Tag, History, + CreditCard, Package, Sparkles, PenTool, CalendarDays, + Search, Save, Activity, UserCircle, Bell, + LucideIcon +} from "lucide-react" +import { SectionHeading } from "@/components/ui/section-heading" -const tMock = (key: string) => { - const map: any = { - "title": "Everything you need to", - "titleHighlight": "get hired", - "subtitle": "Stop searching for scattered info. We curated the ultimate toolkit to crack technical interviews.", - - "qa.title": "Q&A", - "qa.description": "No fluff. Just a massive library of real interview questions with precise, recruiter-approved answers.", - - "quiz.title": "Quizzes", - "quiz.description": "Validate your confidence. Fast-paced interactive quizzes to spot your weak points before the interviewer does.", - - "leaderboard.title": "Leaderboard", - "leaderboard.description": "Gamify your prep. Earn points for every correct answer, keep your streak alive, and rank up against others.", - - "profile.title": "Analytics", - "profile.description": "Don't fly blind. Visualize your progress with detailed charts to see exactly which topics you've mastered.", - - "shop.title": "Shop", - "shop.description": "Upgrade your setup. High-quality developer apparel, desk accessories, and digital assets available for purchase.", - } - return map[key] || key +interface Feature { + icon: LucideIcon + label: string + desc: string + x: number + y: number + size: number } -export function FeaturesSection() { - const t = tMock - const [activeTab, setActiveTab] = useState("qa") - - const features = [ - { id: "qa", icon: MessageCircle, href: "/q&a" }, - { id: "quiz", icon: Brain, href: "/quizzes" }, - { id: "leaderboard", icon: Trophy, href: "/leaderboard" }, - { id: "profile", icon: User, href: "/profile" }, - { id: "shop", icon: ShoppingBag, href: "/shop" }, - ] +interface Page { + id: string + icon: LucideIcon + href: string + features: Feature[] +} - const activeFeature = features.find((f) => f.id === activeTab) - const activeHref = activeFeature ? activeFeature.href : "/" +const translations: Record = { + "title": "Features designed to", + "titleHighlight": "make you unstoppable", + "subtitle": "Stop searching for scattered info. We curated the ultimate toolkit to crack technical interviews.", + "qa.title": "Q&A", + "qa.description": "No fluff. Just a massive library of real interview questions with precise, recruiter-approved answers.", + "quiz.title": "Quizzes", + "quiz.description": "Validate your confidence. Fast-paced interactive quizzes to spot your weak points before the interviewer does.", + "leaderboard.title": "Leaderboard", + "leaderboard.description": "Gamify your prep. Earn points for every correct answer, keep your streak alive, and rank up against others.", + "blog.title": "Blog", + "blog.description": "Stay updated. detailed articles on tech trends, coding tutorials, and industry insights to keep you ahead of the curve.", + "profile.title": "Analytics", + "profile.description": "Don't fly blind. Visualize your progress with detailed charts to see exactly which topics you've mastered.", + "shop.title": "Shop", + "shop.description": "Upgrade your setup. High-quality developer apparel, desk accessories, and digital assets available for purchase.", +} - return ( -
- -
-
-
+const t = (key: string) => translations[key] || key -
- -
-

- {t("title")} {t("titleHighlight")} -

-

- {t("subtitle")} -

-
+const decorativeDots = [ + { x: '5%', y: '20%', size: 8 }, + { x: '10%', y: '75%', size: 6 }, + { x: '18%', y: '40%', size: 5 }, + { x: '92%', y: '25%', size: 7 }, + { x: '88%', y: '70%', size: 6 }, + { x: '82%', y: '45%', size: 5 }, + { x: '7%', y: '55%', size: 7 }, + { x: '95%', y: '55%', size: 8 }, + { x: '15%', y: '85%', size: 6 }, + { x: '85%', y: '15%', size: 5 }, + { x: '3%', y: '35%', size: 6 }, + { x: '97%', y: '80%', size: 7 }, +] -
- -
+const pages: Page[] = [ + { + id: "qa", + icon: MessageCircle, + href: "/q&a", + features: [ + { icon: Globe, label: "3 Languages", desc: "EN, UK & PL supported", x: -120, y: -120, size: 88 }, + { icon: Cpu, label: "AI Helper", desc: "Select text for AI explain", x: 120, y: -120, size: 88 }, + { icon: Lightbulb, label: "Smart Cache", desc: "Highlights learned terms", x: -120, y: 120, size: 88 }, + { icon: Search, label: "Tech Filter", desc: "React, Git, JS & more", x: 120, y: 120, size: 88 }, + ] + }, + { + id: "quiz", + icon: Brain, + href: "/quizzes", + features: [ + { icon: Clock, label: "Smart Timer", desc: "Race against the total time", x: -120, y: -120, size: 88 }, + { icon: Shield, label: "Anti-Cheat", desc: "Focus loss detection", x: 120, y: -120, size: 88 }, + { icon: Save, label: "Auto Sync", desc: "Saves progress post-login", x: -120, y: 120, size: 88 }, + { icon: BarChart3, label: "Tracking", desc: "Best scores & attempts", x: 120, y: 120, size: 88 }, + ] + }, + { + id: "leaderboard", + icon: Trophy, + href: "/leaderboard", + features: [ + { icon: Medal, label: "The Podium", desc: "Top 3 exclusive spotlight", x: -120, y: -120, size: 88 }, + { icon: Globe, label: "Global Rank", desc: "Compete worldwide", x: 120, y: -120, size: 88 }, + { icon: Zap, label: "XP System", desc: "Points for every answer", x: -120, y: 120, size: 88 }, + { icon: Activity, label: "Live Feed", desc: "Real-time rank updates", x: 120, y: 120, size: 88 }, + ] + }, + { + id: "profile", + icon: User, + href: "/dashboard", + features: [ + { icon: BarChart3, label: "Stats Hub", desc: "Visualize your growth", x: -120, y: -120, size: 88 }, + { icon: History, label: "History", desc: "Track learning streaks", x: 120, y: -120, size: 88 }, + { icon: UserCircle, label: "Identity", desc: "Manage role & profile", x: -120, y: 120, size: 88 }, + { icon: Bell, label: "Reminders", desc: "Finish incomplete quizzes", x: 120, y: 120, size: 88 }, + ] + }, + { + id: "blog", + icon: BookOpen, + href: "/blog", + features: [ + { icon: TrendingUp, label: "Tech Trends", desc: "Stay ahead of the curve", x: -120, y: -120, size: 88 }, + { icon: PenTool, label: "Tutorials", desc: "Step-by-step guides", x: 120, y: -120, size: 88 }, + { icon: BookOpen, label: "Deep Dives", desc: "In-depth analysis", x: -120, y: 120, size: 88 }, + { icon: Users, label: "Community", desc: "Written by developers", x: 120, y: 120, size: 88 }, + ] + }, + { + id: "shop", + icon: ShoppingBag, + href: "/shop", + features: [ + { icon: Sparkles, label: "New Drops", desc: "Regular fresh content", x: -120, y: -120, size: 88 }, + { icon: Tag, label: "Curated", desc: "Dev-focused collections", x: 120, y: -120, size: 88 }, + { icon: CreditCard, label: "Checkout", desc: "Seamless Stripe flow", x: -120, y: 120, size: 88 }, + { icon: Package, label: "Premium", desc: "High-quality material", x: 120, y: 120, size: 88 }, + ] + }, +] - -
+
- -
-
-
-
-
-
- -
- https:// - devlovers.net/{activeTab} -
-
- -
- - -
- -
- {activeTab === 'qa' && } - {activeTab === 'quiz' && } - {activeTab === 'leaderboard' && } - {activeTab === 'profile' && } - {activeTab === 'shop' && } + +
+
+ +
+
+
{feature.label}
+
{feature.desc}
+
- -
- - -
+
- -
- -
-
- {features.map((feature) => { - const isActive = activeTab === feature.id - return ( - - ) - })} -
-
- -
- - -

- {t(`${activeTab}.description`)} -

-
-
-
-
-
- ) + + ) } -function QAVisual() { +function CentralIcon({ page }: { page: Page }) { + const Icon = page.icon + return ( -
+ -
-
-
Question
-
-
-
+
- -
- +
+
+ +
+ + ) +} - -
-
-
Correct Answer
-
-
-
-
- +function DecorativeDots() { + return ( +