Skip to content

Commit 51cd49e

Browse files
committed
feat(landing): restore i18n translations for all 12 languages
1 parent cfb516b commit 51cd49e

2 files changed

Lines changed: 975 additions & 135 deletions

File tree

src/components/landing/landing-page.tsx

Lines changed: 63 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { useState } from "react";
1+
import { useState, Fragment } from "react";
22
import { Link } from "react-router-dom";
33
import {
44
Timer, BarChart3, Receipt, Users, FolderOpen,
@@ -10,36 +10,36 @@ import s from "./landing-page.module.css";
1010

1111
/* ─── Feature data ─── */
1212
const FEATURES = [
13-
{ icon: FolderOpen, title: "Projects & Clients", desc: "Manage all your work and contacts in one place" },
14-
{ icon: Clock, title: "Time Tracking", desc: "One-click timer with billable hours" },
15-
{ icon: Receipt, title: "Invoicing", desc: "Generate and send professional invoices" },
16-
{ icon: Users, title: "Sales Funnels", desc: "Track deals from lead to close" },
17-
{ icon: BarChart3, title: "Reports", desc: "See where your time and money go" },
18-
{ icon: DollarSign, title: "Multi-currency", desc: "USD, EUR, GBP, UAH, PLN" },
13+
{ icon: Clock, titleKey: "feat.time.title", descKey: "feat.time.desc" },
14+
{ icon: FolderOpen, titleKey: "feat.projects.title", descKey: "feat.projects.desc" },
15+
{ icon: Receipt, titleKey: "feat.invoices.title", descKey: "feat.invoices.desc" },
16+
{ icon: BarChart3, titleKey: "feat.reports.title", descKey: "feat.reports.desc" },
17+
{ icon: DollarSign, titleKey: "feat.currency.title", descKey: "feat.currency.desc" },
18+
{ icon: FileText, titleKey: "feat.pdf.title", descKey: "feat.pdf.desc" },
1919
];
2020

2121
const STEPS = [
22-
{ num: "1", title: "Start Timer", desc: "Track your work session" },
23-
{ num: "2", title: "Create Invoice", desc: "Auto-generate from tracked time" },
24-
{ num: "3", title: "Get Paid", desc: "Send to client and mark as paid" },
22+
{ num: "1", titleKey: "howit.step1.title", descKey: "howit.step1.desc" },
23+
{ num: "2", titleKey: "howit.step2.title", descKey: "howit.step2.desc" },
24+
{ num: "3", titleKey: "howit.step3.title", descKey: "howit.step3.desc" },
2525
];
2626

27-
const PRICING_FEATURES = [
28-
"Unlimited clients & projects",
29-
"Time tracking & sessions",
30-
"Invoice generation & PDF export",
31-
"Sales funnels & pipelines",
32-
"Multi-currency support",
33-
"Reports & analytics",
34-
"Google sign-in",
35-
"Data stored securely in cloud",
27+
const PRICING_FEATURE_KEYS = [
28+
"pricing.feat.tracking",
29+
"pricing.feat.projects",
30+
"pricing.feat.invoices",
31+
"pricing.feat.pdf",
32+
"pricing.feat.currency",
33+
"pricing.feat.reports",
34+
"pricing.feat.google",
35+
"pricing.feat.cloud",
3636
];
3737

3838
const FAQ_ITEMS = [
39-
{ q: "Is it really free?", a: "Yes, Logr is completely free during beta." },
40-
{ q: "Do I need to create an account?", a: "Yes, sign in with Google." },
41-
{ q: "Can I export my data?", a: "Yes, download invoices as PDF." },
42-
{ q: "Is my data secure?", a: "Yes, stored in Supabase with encryption." },
39+
{ qKey: "faq.q1", aKey: "faq.a1" },
40+
{ qKey: "faq.q2", aKey: "faq.a2" },
41+
{ qKey: "faq.q3", aKey: "faq.a3" },
42+
{ qKey: "faq.q4", aKey: "faq.a4" },
4343
];
4444

4545
/* ─── FAQ Accordion Item ─── */
@@ -67,32 +67,32 @@ export function LandingPage() {
6767
<span className={s.logoName}>Logr</span>
6868
</div>
6969
<div className={s.navLinks}>
70-
<a href="#how-it-works" className={s.navLink}>How it Works</a>
71-
<a href="#features" className={s.navLink}>Features</a>
72-
<a href="#pricing" className={s.navLink}>Pricing</a>
70+
<a href="#how-it-works" className={s.navLink}>{t("nav.howItWorks")}</a>
71+
<a href="#features" className={s.navLink}>{t("nav.features")}</a>
72+
<a href="#pricing" className={s.navLink}>{t("nav.pricing")}</a>
7373
</div>
74-
<Link to="/app" className={s.navCta}>Try for Free</Link>
74+
<Link to="/app" className={s.navCta}>{t("hero.tryFree")}</Link>
7575
</div>
7676
</nav>
7777

7878
{/* ── Hero ── */}
7979
<section className={s.hero}>
8080
<div className={s.heroInner}>
81-
<p className={s.heroLabel}>Free CRM for freelancers</p>
81+
<p className={s.heroLabel}>{t("hero.label")}</p>
8282
<h1 className={s.heroTitle}>
83-
Manage clients.<br />
84-
Track time.<br />
85-
Get paid.
83+
{t("hero.newTitle").split("\n").map((line, i) => (
84+
<Fragment key={i}>{i > 0 && <br />}{line}</Fragment>
85+
))}
8686
</h1>
8787
<p className={s.heroDesc}>
88-
Projects, time tracking, invoicing, and sales funnels - everything a freelancer needs in one place.
88+
{t("hero.newDesc")}
8989
</p>
9090
<div className={s.heroActions}>
9191
<Link to="/app" className={s.heroPrimary}>
92-
Try for Free <ArrowRight style={{ width: 16, height: 16 }} />
92+
{t("hero.tryFree")} <ArrowRight style={{ width: 16, height: 16 }} />
9393
</Link>
9494
<a href="#how-it-works" className={s.heroSecondary}>
95-
See How It Works
95+
{t("hero.seeHow")}
9696
</a>
9797
</div>
9898
</div>
@@ -110,8 +110,8 @@ export function LandingPage() {
110110
<div className={s.previewBody}>
111111
<div className={s.previewTopRow}>
112112
<div>
113-
<div className={s.previewGreeting}>Good evening 👋</div>
114-
<div className={s.previewSub}>3 projects active</div>
113+
<div className={s.previewGreeting}>{t("preview.greeting")}</div>
114+
<div className={s.previewSub}>{t("preview.sub")}</div>
115115
</div>
116116
<div className={s.previewTimer}>
117117
<span className={s.previewTimerDot} />
@@ -121,10 +121,10 @@ export function LandingPage() {
121121
</div>
122122
<div className={s.previewCards}>
123123
{[
124-
{ label: "Today", value: "4h 12m", sub: "+18%" },
125-
{ label: "This Week", value: "22h 45m", sub: "Target: 40h" },
126-
{ label: "Unpaid", value: "$3,450", sub: "2 invoices" },
127-
{ label: "Pipeline", value: "$12,800", sub: "5 deals" },
124+
{ label: t("preview.today"), value: "4h 12m", sub: "+18%" },
125+
{ label: t("preview.week"), value: "22h 45m", sub: "Target: 40h" },
126+
{ label: t("preview.unpaid"), value: "$3,450", sub: "2 invoices" },
127+
{ label: t("preview.pipeline"), value: "$12,800", sub: "5 deals" },
128128
].map((c) => (
129129
<div key={c.label} className={s.previewCard}>
130130
<div className={s.previewCardLabel}>{c.label}</div>
@@ -141,19 +141,19 @@ export function LandingPage() {
141141
{/* ── Features ── */}
142142
<section id="features" className={s.features}>
143143
<div className={s.sectionCenter}>
144-
<h2 className={s.sectionTitle}>Your freelance business, organized</h2>
145-
<p className={s.sectionDesc}>Clients, projects, time, invoices, and deals - all in one clean tool.</p>
144+
<h2 className={s.sectionTitle}>{t("features.title")}</h2>
145+
<p className={s.sectionDesc}>{t("features.desc")}</p>
146146
</div>
147147
<div className={s.featuresGrid}>
148148
{FEATURES.map((f) => {
149149
const Icon = f.icon;
150150
return (
151-
<div key={f.title} className={s.featureItem}>
151+
<div key={f.titleKey} className={s.featureItem}>
152152
<div className={s.featureIcon}>
153153
<Icon className={s.featureIconSvg} />
154154
</div>
155-
<h3 className={s.featureName}>{f.title}</h3>
156-
<p className={s.featureDesc}>{f.desc}</p>
155+
<h3 className={s.featureName}>{t(f.titleKey)}</h3>
156+
<p className={s.featureDesc}>{t(f.descKey)}</p>
157157
</div>
158158
);
159159
})}
@@ -163,15 +163,15 @@ export function LandingPage() {
163163
{/* ── How it Works ── */}
164164
<section id="how-it-works" className={s.howItWorks}>
165165
<div className={s.sectionCenter}>
166-
<h2 className={s.sectionTitle}>How it works</h2>
167-
<p className={s.sectionDesc}>Three simple steps to get paid for your work.</p>
166+
<h2 className={s.sectionTitle}>{t("howit.title")}</h2>
167+
<p className={s.sectionDesc}>{t("howit.desc")}</p>
168168
</div>
169169
<div className={s.stepsGrid}>
170170
{STEPS.map((step) => (
171171
<div key={step.num} className={s.stepItem}>
172172
<div className={s.stepNum}>{step.num}</div>
173-
<h3 className={s.stepTitle}>{step.title}</h3>
174-
<p className={s.stepDesc}>{step.desc}</p>
173+
<h3 className={s.stepTitle}>{t(step.titleKey)}</h3>
174+
<p className={s.stepDesc}>{t(step.descKey)}</p>
175175
</div>
176176
))}
177177
</div>
@@ -180,51 +180,51 @@ export function LandingPage() {
180180
{/* ── Pricing ── */}
181181
<section id="pricing" className={s.pricing}>
182182
<div className={s.sectionCenter}>
183-
<h2 className={s.sectionTitle}>Simple pricing</h2>
184-
<p className={s.sectionDesc}>Free while in beta. No credit card required.</p>
183+
<h2 className={s.sectionTitle}>{t("pricing.title")}</h2>
184+
<p className={s.sectionDesc}>{t("pricing.desc")}</p>
185185
</div>
186186
<div className={s.pricingCard}>
187187
<div className={s.pricingHeader}>
188-
<span className={s.pricingTier}>Free</span>
188+
<span className={s.pricingTier}>{t("pricing.free")}</span>
189189
<div className={s.pricingPrice}>
190190
<span className={s.pricingAmount}>$0</span>
191-
<span className={s.pricingPeriod}>/forever</span>
191+
<span className={s.pricingPeriod}>{t("pricing.forever")}</span>
192192
</div>
193-
<p className={s.pricingDesc}>Everything included. No limits during beta.</p>
193+
<p className={s.pricingDesc}>{t("pricing.freeLabel")}</p>
194194
</div>
195195
<ul className={s.pricingFeatures}>
196-
{PRICING_FEATURES.map((f) => (
197-
<li key={f} className={s.pricingFeature}>
198-
<Check className={s.pricingCheckIcon} /> {f}
196+
{PRICING_FEATURE_KEYS.map((key) => (
197+
<li key={key} className={s.pricingFeature}>
198+
<Check className={s.pricingCheckIcon} /> {t(key)}
199199
</li>
200200
))}
201201
</ul>
202202
<Link to="/app" className={s.pricingCta}>
203-
Get Started Free <ArrowRight style={{ width: 16, height: 16 }} />
203+
{t("pricing.tryFree")} <ArrowRight style={{ width: 16, height: 16 }} />
204204
</Link>
205205
</div>
206206
</section>
207207

208208
{/* ── FAQ ── */}
209209
<section className={s.faq}>
210210
<div className={s.sectionCenter}>
211-
<h2 className={s.sectionTitle}>Frequently asked questions</h2>
211+
<h2 className={s.sectionTitle}>{t("faq.title")}</h2>
212212
</div>
213213
<div className={s.faqList}>
214214
{FAQ_ITEMS.map((item) => (
215-
<FaqItem key={item.q} q={item.q} a={item.a} />
215+
<FaqItem key={item.qKey} q={t(item.qKey)} a={t(item.aKey)} />
216216
))}
217217
</div>
218218
</section>
219219

220220
{/* ── Footer ── */}
221221
<footer className={s.footer}>
222222
<div className={s.footerInner}>
223-
<span className={s.footerCopy}>Logr © 2025</span>
223+
<span className={s.footerCopy}>{t("footer.copy")}</span>
224224
<div className={s.footerLinks}>
225225
<a href="https://github.com/zerox9dev/logr" target="_blank" rel="noopener noreferrer" className={s.footerLink}>GitHub</a>
226-
<a href="/privacy" className={s.footerLink}>Privacy</a>
227-
<a href="mailto:zerox9dev.work@icloud.com" className={s.footerLink}>Contact</a>
226+
<a href="/privacy" className={s.footerLink}>{t("footer.privacy")}</a>
227+
<a href="mailto:zerox9dev.work@icloud.com" className={s.footerLink}>{t("footer.contact")}</a>
228228
</div>
229229
</div>
230230
</footer>

0 commit comments

Comments
 (0)