1- import { useState } from "react" ;
1+ import { useState , Fragment } from "react" ;
22import { Link } from "react-router-dom" ;
33import {
44 Timer , BarChart3 , Receipt , Users , FolderOpen ,
@@ -10,36 +10,36 @@ import s from "./landing-page.module.css";
1010
1111/* ─── Feature data ─── */
1212const 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
2121const 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
3838const 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