Skip to content

Commit ecd3e99

Browse files
(SP: 3) [Frontend] Complete About page redesign: add topics, sponsors, and stats
1 parent d7c63a3 commit ecd3e99

18 files changed

Lines changed: 7817 additions & 10451 deletions
Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,29 @@
1+
import { getPlatformStats } from "@/lib/about/stats"
2+
import { getSponsors } from "@/lib/about/github-sponsors"
3+
14
import { HeroSection } from "@/components/about/HeroSection"
5+
import { TopicsSection } from "@/components/about/TopicsSection"
26
import { FeaturesSection } from "@/components/about/FeaturesSection"
37
import { PricingSection } from "@/components/about/PricingSection"
48
import { CommunitySection } from "@/components/about/CommunitySection"
59

6-
export default function AboutPage() {
10+
export default async function AboutPage() {
11+
const [stats, sponsors] = await Promise.all([
12+
getPlatformStats(),
13+
getSponsors()
14+
])
15+
716
return (
8-
<main className="min-h-screen bg-neutral-950 text-white">
9-
<HeroSection />
17+
<main className="min-h-screen bg-gray-50 dark:bg-black overflow-hidden text-gray-900 dark:text-white
18+
w-[100vw] relative left-[50%] right-[50%] -ml-[50vw] -mr-[50vw]"
19+
>
20+
21+
<HeroSection stats={stats} />
22+
<TopicsSection />
1023
<FeaturesSection />
11-
<PricingSection />
24+
<PricingSection sponsors={sponsors} />
1225
<CommunitySection />
26+
1327
</main>
1428
)
15-
}
29+
}

frontend/app/[locale]/contacts/page.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,4 +44,4 @@ export default function ContactsPage() {
4444
</ul>
4545
</main>
4646
);
47-
}
47+
}

frontend/app/globals.css

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,3 +197,32 @@
197197
--border: color-mix(in oklab, var(--foreground) 18%, var(--background));
198198
--input: color-mix(in oklab, var(--foreground) 18%, var(--background));
199199
}
200+
201+
/* about-community */
202+
@keyframes scroll {
203+
from { transform: translateX(0); }
204+
to { transform: translateX(-100%); }
205+
}
206+
207+
.animate-scroll {
208+
animation: scroll 40s linear infinite;
209+
}
210+
211+
.pause-on-hover:hover .animate-scroll {
212+
animation-play-state: paused;
213+
}
214+
215+
/* Vertical Marquee Animation */
216+
@keyframes marquee-vertical {
217+
0% { transform: translateY(0); }
218+
100% { transform: translateY(-50%); } /* Рухаємось на 50%, бо контент дубльовано */
219+
}
220+
221+
.animate-marquee-vertical {
222+
animation: marquee-vertical var(--duration, 40s) linear infinite;
223+
}
224+
225+
/* Зупинка при наведенні мишкою, щоб роздивитися */
226+
.hover\:pause:hover .animate-marquee-vertical {
227+
animation-play-state: paused;
228+
}
Lines changed: 92 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -1,90 +1,87 @@
11
"use client"
22

3-
import { motion } from "framer-motion"
4-
import { MessageCircle } from "lucide-react"
5-
import { useTranslations } from "next-intl"
3+
import { MessageCircle, Github, ArrowRight, ExternalLink } from "lucide-react"
4+
import { TESTIMONIALS } from "@/data/about"
65

7-
const testimonialData = [
8-
{
9-
name: "Alex Chen",
10-
role: "Frontend Engineer @ Meta",
11-
avatar: "AC",
12-
platform: "LinkedIn",
13-
},
14-
{
15-
name: "Sarah Johnson",
16-
role: "Senior SWE @ Google",
17-
avatar: "SJ",
18-
platform: "Twitter",
19-
},
20-
{
21-
name: "Marcus Williams",
22-
role: "Backend Developer @ Stripe",
23-
avatar: "MW",
24-
platform: "Twitter",
25-
},
26-
{
27-
name: "Emily Park",
28-
role: "Full Stack @ Vercel",
29-
avatar: "EP",
30-
platform: "LinkedIn",
31-
},
32-
{
33-
name: "David Kim",
34-
role: "Staff Engineer @ Netflix",
35-
avatar: "DK",
36-
platform: "Twitter",
37-
},
38-
{
39-
name: "Lisa Thompson",
40-
role: "Engineering Manager @ Amazon",
41-
avatar: "LT",
42-
platform: "LinkedIn",
43-
},
44-
]
6+
import Link from "next/link"
457

468
export function CommunitySection() {
47-
const t = useTranslations("about.community")
9+
return (
10+
<section className="w-full py-16 md:py-24 relative overflow-hidden bg-gray-50 dark:bg-transparent">
11+
12+
<div className="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 w-[300px] h-[300px] bg-[#1e5eff]/5 dark:bg-[#ff2d55]/5 blur-[80px] rounded-full pointer-events-none" />
4813

49-
const testimonials = testimonialData.map((data, index) => ({
50-
...data,
51-
content: t(`testimonials.${index}`),
52-
}))
14+
<div className="w-full relative z-10">
15+
16+
<div className="max-w-7xl mx-auto px-4 mb-12 text-center">
17+
<div className="inline-flex items-center gap-2 px-3 py-1 rounded-full border border-gray-200 dark:border-white/10 bg-white dark:bg-white/5 text-gray-500 dark:text-gray-400 text-[10px] font-bold uppercase tracking-widest mb-4">
18+
<MessageCircle size={10} /> Community Love
19+
</div>
20+
21+
<h2 className="text-3xl md:text-4xl font-black tracking-tight text-gray-900 dark:text-white mb-4">
22+
Approved by <span className="text-transparent bg-clip-text bg-gradient-to-r from-[#1e5eff] to-[#174ad6] dark:from-[#ff2d55] dark:to-[#e0264b]">Survivors</span>
23+
</h2>
24+
<p className="text-gray-600 dark:text-gray-400 max-w-xl mx-auto text-base font-light leading-relaxed">
25+
Join thousands of developers who stopped guessing and started shipping. Real feedback from real engineers.
26+
</p>
27+
</div>
5328

54-
return (
55-
<section className="overflow-hidden px-6 py-24 bg-background transition-colors duration-300">
56-
<div className="mx-auto max-w-6xl">
57-
<motion.div
58-
initial={{ opacity: 0, y: 20 }}
59-
whileInView={{ opacity: 1, y: 0 }}
60-
viewport={{ once: true }}
61-
transition={{ duration: 0.6 }}
62-
className="mb-16 text-center"
63-
>
64-
<h2 className="text-3xl font-bold text-foreground md:text-4xl transition-colors duration-300">
65-
{t("title")}
66-
</h2>
67-
<p className="mt-4 text-muted-foreground transition-colors duration-300">
68-
{t("subtitle")}
69-
</p>
70-
</motion.div>
29+
{/* Infinite Scroll Container */}
30+
<div className="relative w-full pause-on-hover mb-16">
31+
32+
{/* Fade Edges */}
33+
<div className="pointer-events-none absolute left-0 top-0 z-10 h-full w-12 md:w-32 bg-gradient-to-r from-gray-50 dark:from-background to-transparent" />
34+
<div className="pointer-events-none absolute right-0 top-0 z-10 h-full w-12 md:w-32 bg-gradient-to-l from-gray-50 dark:from-background to-transparent" />
7135

72-
<div className="relative">
73-
<div className="pointer-events-none absolute left-0 top-0 z-10 h-full w-32 bg-gradient-to-r from-background to-transparent transition-colors duration-300" />
74-
<div className="pointer-events-none absolute right-0 top-0 z-10 h-full w-32 bg-gradient-to-l from-background to-transparent transition-colors duration-300" />
36+
<div className="flex w-max min-w-full">
37+
<div className="flex shrink-0 gap-4 px-2 animate-scroll">
38+
{TESTIMONIALS.map((testimonial, index) => (
39+
<TestimonialCard key={`loop1-${index}`} {...testimonial} />
40+
))}
41+
</div>
42+
<div className="flex shrink-0 gap-4 px-2 animate-scroll" aria-hidden="true">
43+
{TESTIMONIALS.map((testimonial, index) => (
44+
<TestimonialCard key={`loop2-${index}`} {...testimonial} />
45+
))}
46+
</div>
47+
</div>
48+
</div>
49+
50+
<div className="max-w-7xl mx-auto px-4 text-center">
51+
<Link
52+
href="https://github.com/DevLoversTeam/devlovers.net/discussions"
53+
target="_blank"
54+
className="group relative inline-flex flex-col md:flex-row items-center justify-center gap-4 p-1.5 pl-6 pr-1.5 rounded-full
55+
bg-white dark:bg-white/5 border border-gray-200 dark:border-white/10
56+
transition-all duration-300 ease-out
57+
hover:scale-[1.02]
58+
hover:border-[#1e5eff]/50 dark:hover:border-[#ff2d55]/50
59+
hover:shadow-[0_0_30px_-5px_rgba(30,94,255,0.15)] dark:hover:shadow-[0_0_30px_-5px_rgba(255,45,85,0.15)]"
60+
>
61+
<div className="flex flex-col items-start md:items-center">
62+
<span className="text-sm text-gray-700 dark:text-gray-200 font-medium">
63+
Have a success story or feature request?
64+
</span>
65+
</div>
66+
67+
<span className="flex items-center gap-2 px-5 py-2.5 rounded-full
68+
bg-gray-900 dark:bg-white text-white dark:text-black
69+
text-xs font-bold uppercase tracking-wider
70+
transition-all duration-300
71+
group-hover:bg-[#1e5eff] dark:group-hover:bg-[#ff2d55]
72+
group-hover:text-white dark:group-hover:text-white"
73+
>
74+
<Github size={14} />
75+
Join Discussion
76+
<ArrowRight size={12} className="group-hover:translate-x-1 transition-transform" />
77+
</span>
78+
</Link>
79+
80+
<p className="mt-6 text-[10px] text-gray-400 dark:text-gray-600 uppercase tracking-widest font-bold opacity-60">
81+
We read every single thread
82+
</p>
83+
</div>
7584

76-
<div className="flex gap-6 overflow-hidden">
77-
<motion.div
78-
animate={{ x: [0, -1920] }}
79-
transition={{ duration: 60, repeat: Number.POSITIVE_INFINITY, ease: "linear" }}
80-
className="flex shrink-0 gap-6"
81-
>
82-
{[...testimonials, ...testimonials].map((testimonial, index) => (
83-
<TestimonialCard key={index} {...testimonial} />
84-
))}
85-
</motion.div>
86-
</div>
87-
</div>
8885
</div>
8986
</section>
9087
)
@@ -96,34 +93,34 @@ function TestimonialCard({
9693
avatar,
9794
content,
9895
platform,
99-
}: {
100-
name: string
101-
role: string
102-
avatar: string
103-
content: string
104-
platform: string
105-
}) {
96+
icon: Icon,
97+
color
98+
}: any) {
10699
return (
107-
<div className="w-80 shrink-0 rounded-2xl border border-border bg-card p-6 backdrop-blur-sm transition-colors duration-300">
108-
<div className="mb-4 flex items-start justify-between">
100+
<div className="w-[280px] md:w-[320px] shrink-0 rounded-xl border border-gray-200 dark:border-white/10 bg-white dark:bg-[#0f0f0f] p-5 shadow-sm hover:shadow-md transition-all duration-300 hover:border-gray-300 dark:hover:border-white/20 hover:-translate-y-1">
101+
<div className="mb-3 flex items-start justify-between">
109102
<div className="flex items-center gap-3">
110-
<div className="flex h-10 w-10 items-center justify-center rounded-full bg-gradient-to-br from-[#2C7FFF] to-sky-400 text-sm font-bold text-white shadow-lg shadow-[#2C7FFF]/20">
103+
<div className="flex h-9 w-9 items-center justify-center rounded-full bg-gray-100 dark:bg-white/10 border border-gray-200 dark:border-white/5 text-xs font-bold text-gray-700 dark:text-gray-200">
111104
{avatar}
112105
</div>
113106
<div>
114-
<div className="font-semibold text-foreground transition-colors duration-300">{name}</div>
115-
<div className="text-xs text-muted-foreground transition-colors duration-300">{role}</div>
107+
<div className="font-bold text-gray-900 dark:text-white text-sm leading-none mb-1">{name}</div>
108+
<div className="text-[10px] uppercase tracking-wide text-gray-500 font-medium">{role}</div>
116109
</div>
117110
</div>
118111

119-
<div className="flex h-6 w-6 items-center justify-center rounded-full bg-muted transition-colors duration-300">
120-
<MessageCircle className="h-3 w-3 text-muted-foreground" />
112+
<div className={`flex h-7 w-7 items-center justify-center rounded-full ${color}`}>
113+
<Icon size={12} />
121114
</div>
122115
</div>
123116

124-
<p className="text-sm leading-relaxed text-muted-foreground transition-colors duration-300">{content}</p>
117+
<p className="text-sm leading-relaxed text-gray-600 dark:text-gray-300 font-normal">
118+
&quot;{content}&quot;
119+
</p>
125120

126-
<div className="mt-4 text-xs text-muted-foreground/60 transition-colors duration-300">via {platform}</div>
121+
<div className="mt-3 text-[10px] text-gray-400 dark:text-gray-600 font-mono flex items-center gap-1">
122+
via {platform} <ExternalLink size={8} />
123+
</div>
127124
</div>
128125
)
129-
}
126+
}

0 commit comments

Comments
 (0)