Skip to content

Commit ecc820f

Browse files
authored
Merge pull request #95 from DevLoversTeam/feature/multilingual-about
Feature/multilingual about
2 parents a08c581 + a6b2e5c commit ecc820f

11 files changed

Lines changed: 411 additions & 115 deletions

File tree

frontend/components/about/CommunitySection.tsx

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,54 +2,55 @@
22

33
import { motion } from "framer-motion"
44
import { MessageCircle } from "lucide-react"
5+
import { useTranslations } from "next-intl"
56

6-
const testimonials = [
7+
const testimonialData = [
78
{
89
name: "Alex Chen",
910
role: "Frontend Engineer @ Meta",
1011
avatar: "AC",
11-
content: "DevLovers helped me nail my system design interviews. The community is incredibly supportive!",
1212
platform: "LinkedIn",
1313
},
1414
{
1515
name: "Sarah Johnson",
1616
role: "Senior SWE @ Google",
1717
avatar: "SJ",
18-
content: "Finally, a free resource that actually prepares you for real interviews. The questions are spot-on.",
1918
platform: "Twitter",
2019
},
2120
{
2221
name: "Marcus Williams",
2322
role: "Backend Developer @ Stripe",
2423
avatar: "MW",
25-
content: "Went from struggling with DSA to getting multiple offers. Can't recommend this enough! 🚀",
2624
platform: "Twitter",
2725
},
2826
{
2927
name: "Emily Park",
3028
role: "Full Stack @ Vercel",
3129
avatar: "EP",
32-
content: "The interactive quizzes are addictive. I've learned more here than months of LeetCode grinding.",
3330
platform: "LinkedIn",
3431
},
3532
{
3633
name: "David Kim",
3734
role: "Staff Engineer @ Netflix",
3835
avatar: "DK",
39-
content:
40-
"Love the community challenges! Great way to practice under pressure. This is the future of interview prep.",
4136
platform: "Twitter",
4237
},
4338
{
4439
name: "Lisa Thompson",
4540
role: "Engineering Manager @ Amazon",
4641
avatar: "LT",
47-
content: "I recommend DevLovers to all my mentees. It's become essential for anyone preparing for tech interviews.",
4842
platform: "LinkedIn",
4943
},
5044
]
5145

5246
export function CommunitySection() {
47+
const t = useTranslations("about.community")
48+
49+
const testimonials = testimonialData.map((data, index) => ({
50+
...data,
51+
content: t(`testimonials.${index}`),
52+
}))
53+
5354
return (
5455
<section className="overflow-hidden px-6 py-24 bg-background transition-colors duration-300">
5556
<div className="mx-auto max-w-6xl">
@@ -61,10 +62,10 @@ export function CommunitySection() {
6162
className="mb-16 text-center"
6263
>
6364
<h2 className="text-3xl font-bold text-foreground md:text-4xl transition-colors duration-300">
64-
Trusted by the Community
65+
{t("title")}
6566
</h2>
6667
<p className="mt-4 text-muted-foreground transition-colors duration-300">
67-
Join thousands of developers who&apos;ve leveled up their interview skills
68+
{t("subtitle")}
6869
</p>
6970
</motion.div>
7071

@@ -114,15 +115,15 @@ function TestimonialCard({
114115
<div className="text-xs text-muted-foreground transition-colors duration-300">{role}</div>
115116
</div>
116117
</div>
117-
118+
118119
<div className="flex h-6 w-6 items-center justify-center rounded-full bg-muted transition-colors duration-300">
119120
<MessageCircle className="h-3 w-3 text-muted-foreground" />
120121
</div>
121122
</div>
122-
123+
123124
<p className="text-sm leading-relaxed text-muted-foreground transition-colors duration-300">{content}</p>
124-
125+
125126
<div className="mt-4 text-xs text-muted-foreground/60 transition-colors duration-300">via {platform}</div>
126127
</div>
127128
)
128-
}
129+
}

frontend/components/about/FeaturesSection.tsx

Lines changed: 36 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import type React from "react"
44
import Link from "next/link"
55
import { MessageCircle, Brain, Trophy, User, ShoppingBag, Star, Flame, Target } from "lucide-react"
6+
import { useTranslations } from "next-intl"
67

78
interface FeatureCardProps {
89
icon: React.ReactNode
@@ -14,9 +15,11 @@ interface FeatureCardProps {
1415
}
1516

1617
function FeatureCard({ icon, title, description, href, className = "", children }: FeatureCardProps) {
18+
const t = useTranslations("about.features")
19+
1720
return (
1821
<div
19-
className={`group relative overflow-hidden rounded-2xl border p-6 transition-all duration-300 hover:scale-[1.02]
22+
className={`group relative overflow-hidden rounded-2xl border p-6 transition-all duration-300 hover:scale-[1.02]
2023
bg-white border-gray-200 shadow-sm hover:border-blue-500/50 hover:shadow-blue-500/10
2124
dark:bg-white/5 dark:border-white/10 dark:backdrop-blur-md dark:hover:bg-white/10 dark:hover:border-blue-500/50
2225
${className}`}
@@ -39,11 +42,11 @@ function FeatureCard({ icon, title, description, href, className = "", children
3942

4043
<Link
4144
href={href}
42-
className="mt-4 inline-block w-fit rounded-lg border px-4 py-2 text-sm font-medium transition-all duration-300
45+
className="mt-4 inline-block w-fit rounded-lg border px-4 py-2 text-sm font-medium transition-all duration-300
4346
border-gray-200 text-gray-700 hover:border-blue-500 hover:bg-blue-50 hover:text-blue-700
4447
dark:border-white/20 dark:text-white/80 dark:hover:border-blue-500/50 dark:hover:bg-blue-500/10 dark:hover:text-white"
4548
>
46-
Learn more
49+
{t("learnMore")}
4750
</Link>
4851
</div>
4952
</div>
@@ -76,9 +79,12 @@ function AchievementBadge({ icon, label }: { icon: React.ReactNode; label: strin
7679
}
7780

7881
export function FeaturesSection() {
82+
const t = useTranslations("about.features")
83+
const tProfile = useTranslations("about.features.profile")
84+
7985
return (
8086
<section className="relative px-4 py-20 sm:px-6 lg:px-8 transition-colors duration-300 bg-white dark:bg-transparent">
81-
87+
8288
<div className="absolute inset-0 overflow-hidden pointer-events-none">
8389
<div className="absolute left-1/4 top-1/4 h-96 w-96 rounded-full bg-blue-400/10 blur-3xl dark:bg-blue-500/10" />
8490
<div className="absolute bottom-1/4 right-1/4 h-96 w-96 rounded-full bg-blue-400/10 blur-3xl dark:bg-blue-600/10" />
@@ -87,36 +93,36 @@ export function FeaturesSection() {
8793
<div className="relative mx-auto max-w-6xl">
8894
<div className="mb-12 text-center">
8995
<h2 className="mb-4 text-4xl font-bold text-gray-900 dark:text-white md:text-5xl">
90-
Powerful <span className="text-blue-600 dark:text-blue-400">Features</span>
96+
{t("title")} <span className="text-blue-600 dark:text-blue-400">{t("titleHighlight")}</span>
9197
</h2>
9298
<p className="mx-auto max-w-2xl text-gray-600 dark:text-gray-400">
93-
Everything you need to create engaging learning experiences and track progress effectively.
99+
{t("subtitle")}
94100
</p>
95101
</div>
96102

97103
<div className="grid auto-rows-[minmax(200px,auto)] grid-cols-1 gap-4 md:grid-cols-2 lg:grid-cols-3">
98-
104+
99105
<FeatureCard
100106
icon={<MessageCircle className="h-7 w-7" />}
101-
title="Q&A"
102-
description="Access a curated collection of the most frequent and relevant technical interview questions. Get clear answers to the real challenges recruiters actually ask."
107+
title={t("qa.title")}
108+
description={t("qa.description")}
103109
href="/q&a"
104110
className="lg:row-span-1"
105111
/>
106112

107113
<FeatureCard
108114
icon={<Brain className="h-7 w-7" />}
109-
title="Quiz"
110-
description="Master technical interviews with our adaptive quizzes. Cover topics from React to Algorithms, track your weak spots, and level up your skills."
115+
title={t("quiz.title")}
116+
description={t("quiz.description")}
111117
href="/quiz"
112118
className="lg:row-span-1"
113119
/>
114120

115121
<FeatureCard
116122
icon={<User className="h-7 w-7" />}
117-
title="Profile"
118-
description="Your central hub for progress tracking. Visualize your growth, manage your achievements, and customize your learning path."
119-
href="/profile"
123+
title={t("profile.title")}
124+
description={t("profile.description")}
125+
href="/profile"
120126
className="md:col-span-2 lg:col-span-1 lg:row-span-2"
121127
>
122128
<div className="mt-4 space-y-4 rounded-xl border p-4 bg-gray-50 border-gray-100 dark:bg-white/5 dark:border-white/10">
@@ -126,44 +132,44 @@ export function FeaturesSection() {
126132
</div>
127133
<div>
128134
<p className="font-semibold text-gray-900 dark:text-white">John Doe</p>
129-
<p className="text-xs text-gray-500 dark:text-gray-400">Level 12 • Pro Learner</p>
135+
<p className="text-xs text-gray-500 dark:text-gray-400">{tProfile("level")}</p>
130136
</div>
131137
</div>
132138
<div>
133-
<p className="mb-2 text-xs font-medium uppercase tracking-wider text-gray-500 dark:text-gray-500">Achievements</p>
139+
<p className="mb-2 text-xs font-medium uppercase tracking-wider text-gray-500 dark:text-gray-500">{tProfile("achievements")}</p>
134140
<div className="flex justify-around">
135-
<AchievementBadge icon={<Star className="h-5 w-5" />} label="Star" />
136-
<AchievementBadge icon={<Flame className="h-5 w-5" />} label="Streak" />
137-
<AchievementBadge icon={<Target className="h-5 w-5" />} label="Focus" />
138-
<AchievementBadge icon={<Trophy className="h-5 w-5" />} label="Champ" />
141+
<AchievementBadge icon={<Star className="h-5 w-5" />} label={tProfile("badges.star")} />
142+
<AchievementBadge icon={<Flame className="h-5 w-5" />} label={tProfile("badges.streak")} />
143+
<AchievementBadge icon={<Target className="h-5 w-5" />} label={tProfile("badges.focus")} />
144+
<AchievementBadge icon={<Trophy className="h-5 w-5" />} label={tProfile("badges.champ")} />
139145
</div>
140146
</div>
141147
<div className="space-y-3">
142-
<p className="text-xs font-medium uppercase tracking-wider text-gray-500 dark:text-gray-500">Progress</p>
143-
<ProgressBar label="Course Completion" value={78} color="bg-gradient-to-r from-blue-500 to-blue-400" />
144-
<ProgressBar label="Quiz Accuracy" value={92} color="bg-gradient-to-r from-emerald-500 to-emerald-400" />
145-
<ProgressBar label="Weekly Goal" value={65} color="bg-gradient-to-r from-amber-500 to-amber-400" />
148+
<p className="text-xs font-medium uppercase tracking-wider text-gray-500 dark:text-gray-500">{tProfile("progress")}</p>
149+
<ProgressBar label={tProfile("courseCompletion")} value={78} color="bg-gradient-to-r from-blue-500 to-blue-400" />
150+
<ProgressBar label={tProfile("quizAccuracy")} value={92} color="bg-gradient-to-r from-emerald-500 to-emerald-400" />
151+
<ProgressBar label={tProfile("weeklyGoal")} value={65} color="bg-gradient-to-r from-amber-500 to-amber-400" />
146152
</div>
147153
</div>
148154
</FeatureCard>
149155

150156
<FeatureCard
151157
icon={<Trophy className="h-7 w-7" />}
152-
title="Leaderboard"
153-
description="Compete with top developers globally. Earn points for correct answers, maintain streaks, and showcase your expertise on the global ranking."
158+
title={t("leaderboard.title")}
159+
description={t("leaderboard.description")}
154160
href="/leaderboard"
155161
className="lg:row-span-1"
156162
/>
157163

158164
<FeatureCard
159165
icon={<ShoppingBag className="h-7 w-7" />}
160-
title="Shop"
161-
description="Turn your hard work into rewards. Exchange your earned coins for exclusive merch, premium course access, or unique profile customization."
162-
href="/shop"
166+
title={t("shop.title")}
167+
description={t("shop.description")}
168+
href="/shop"
163169
className="lg:row-span-1"
164170
/>
165171
</div>
166172
</div>
167173
</section>
168174
)
169-
}
175+
}

frontend/components/about/HeroSection.tsx

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,11 @@
33
import { motion } from "framer-motion"
44
import { Heart, Sparkles } from "lucide-react"
55
import { StatsSection } from "@/components/about/StatsSection"
6+
import { useTranslations } from "next-intl"
67

78
export function HeroSection() {
9+
const t = useTranslations("about.hero")
10+
811
return (
912
<section className="relative flex flex-col items-center justify-center px-6 py-24 bg-background transition-colors duration-300 overflow-hidden">
1013
<div className="pointer-events-none absolute inset-0 overflow-hidden">
@@ -42,16 +45,16 @@ export function HeroSection() {
4245
className="mb-6 inline-flex items-center gap-2 rounded-full border border-[#2C7FFF]/20 bg-[#2C7FFF]/5 px-4 py-1.5 text-sm font-medium text-[#2C7FFF]"
4346
>
4447
<Sparkles className="h-4 w-4" />
45-
<span>Our Story</span>
48+
<span>{t("badge")}</span>
4649
</motion.div>
4750

4851
<h2 className="mb-6 text-balance text-3xl font-bold tracking-tight text-foreground md:text-5xl transition-colors duration-300">
49-
Driven by passion, <br />
50-
built for <span className="text-[#2C7FFF]">community growth</span>
52+
{t("title")} <br />
53+
<span className="text-[#2C7FFF]">{t("titleHighlight")}</span>
5154
</h2>
5255

5356
<p className="max-w-2xl text-pretty text-lg text-muted-foreground md:text-xl transition-colors duration-300 mb-12">
54-
DevLovers started as a simple university project. We noticed a gap in how developers prepare for interviews — scattered resources and lack of structure. We built a unified ecosystem where knowledge meets practice.
57+
{t("description")}
5558
</p>
5659

5760
<div className="w-full h-px bg-gradient-to-r from-transparent via-border to-transparent mb-12 opacity-50" />
@@ -60,4 +63,4 @@ export function HeroSection() {
6063
</motion.div>
6164
</section>
6265
)
63-
}
66+
}

0 commit comments

Comments
 (0)