enable translation

Seto Elkahfi committed Mar 6, 2019 at 17:21 UTC d62ace22d0e55b8a8adce72a33f9d30b63812ea9
9 files changed +126 -17
src/components/About.js
+11 -2
@@ -1,10 +1,19 @@
1 import React from 'react';
2 +import { FormattedMessage } from 'react-intl';
3
4 const About = () => (
5 <div>
5 - <h1>About</h1>
6 + <h1>
7 + <FormattedMessage id="about.title"
8 + defaultMessage="About"
9 + description="About page title"/>
10 + </h1>
11 <p style={{lineHeight: "150%"}}>iOS developer with experience in AR, web development (PHP, Rails, JavaScript), and Android development.</p>
7 - <h2 style={{marginTop: 8}}>Skills</h2>
12 + <h2 style={{marginTop: 8}}>
13 + <FormattedMessage id="about.skills"
14 + defaultMessage="Skills"
15 + description="About page skills"/>
16 + </h2>
17 <p style={{lineHeight: "150%"}}>Objective-C, Swift (iOS, Vapor), Ruby (Ruby on Rails), PHP (CodeIgniter), JavaScript (ReactJS, jQuery), Java (Android)</p>
18 <p style={{lineHeight: "150%"}}>MacOS, Linux, Windows</p>
19 <p style={{lineHeight: "150%"}}>iMovie, Adobe Premiere Pro, Adobe Photoshop, Adobe Audition</p>
src/components/Contact.js
+6 -1
@@ -1,8 +1,13 @@
1 import React from 'react';
2 +import { FormattedMessage } from 'react-intl';
3
4 const Contact = () => (
5 <div>
5 - <h1>Contact</h1>
6 + <h1>
7 + <FormattedMessage id="contact.title"
8 + defaultMessage="Contact"
9 + description="Contact page title"/>
10 + </h1>
11 <p style={{lineHeight: "150%"}}>Contact me via email: setoelkahfi[at]gmail[dot]com.</p>
12 <p style={{lineHeight: "150%"}}>or reach me directly via my social channel.</p>
13 </div>
src/components/Cv.js
+7 -2
@@ -1,4 +1,5 @@
1 import React from 'react';
2 +import { FormattedMessage } from 'react-intl';
3
4 const linkStyle = {
5 display: 'inline-block',
@@ -20,10 +21,14 @@ const linkStyle = {
21
22 const Cv = () => (
23 <div>
23 - <h1>CV</h1>
24 + <h1>
25 + <FormattedMessage id="cv.title"
26 + defaultMessage="CV"
27 + description="CV page title"/>
28 + </h1>
29 <p style={{lineHeight: "150%"}}><a style={linkStyle} href="https://docs.google.com/document/d/1O2NgIv8DIJIlH6H6Py71qQSi8T6Y9YNfa8TaTlUdywc/edit?usp=sharing" alt="Latest CV" target="_blank" rel="noopener noreferrer" >latest</a></p>
30 <p style={{lineHeight: "150%"}}>or just visit my LinkedIn profile</p>
31 </div>
32 );
33
29 -export default Cv;
\ No newline at end of file
34 +export default Cv;
src/components/Header.js
+22 -5
@@ -1,5 +1,6 @@
1 import React from 'react';
2 import { Link } from 'react-router-dom';
3 +import { FormattedMessage } from 'react-intl';
4
5 const linkStyle = {
6 color: '#fff',
@@ -15,13 +16,29 @@ const Header = () => (
16 <header>
17 <nav>
18 <ul>
18 - <li style={listStyle}><Link to='/' style={linkStyle}>Home</Link></li>
19 - <li style={listStyle}><Link to='/about' style={linkStyle}>About</Link></li>
20 - <li style={listStyle}><Link to='/cv' style={linkStyle}>CV</Link></li>
21 - <li style={listStyle}><Link to='/contact' style={linkStyle}>Contact</Link></li>
19 + <li style={listStyle}><Link to='/' style={linkStyle}>
20 + <FormattedMessage id="header.home"
21 + defaultMessage="Home"
22 + description="Home link"/>
23 + </Link></li>
24 + <li style={listStyle}><Link to='/about' style={linkStyle}>
25 + <FormattedMessage id="header.about"
26 + defaultMessage="About"
27 + description="About link"/>
28 + </Link></li>
29 + <li style={listStyle}><Link to='/cv' style={linkStyle}>
30 + <FormattedMessage id="header.cv"
31 + defaultMessage="CV"
32 + description="CV link"/>
33 + </Link></li>
34 + <li style={listStyle}><Link to='/contact' style={linkStyle}>
35 + <FormattedMessage id="header.contact"
36 + defaultMessage="Contact"
37 + description="Contact link"/>
38 + </Link></li>
39 </ul>
40 </nav>
41 </header>
42 );
43
27 -export default Header;
\ No newline at end of file
44 +export default Header;
src/components/Home.js
+17 -7
@@ -1,5 +1,6 @@
1 import React, { Component } from 'react';
2 import ReactRotatingText from 'react-rotating-text';
3 +import { FormattedMessage } from 'react-intl';
4
5 const pStyle = {
6 lineHeight: '32pt',
@@ -48,29 +49,38 @@ class Home extends Component {
49
50 shuffle(array) {
51 var currentIndex = array.length, temporaryValue, randomIndex;
51 -
52 +
53 // While there remain elements to shuffle...
54 while (0 !== currentIndex) {
54 -
55 +
56 // Pick a remaining element...
57 randomIndex = Math.floor(Math.random() * currentIndex);
58 currentIndex -= 1;
58 -
59 +
60 // And swap it with the current element.
61 temporaryValue = array[currentIndex];
62 array[currentIndex] = array[randomIndex];
63 array[randomIndex] = temporaryValue;
64 }
64 -
65 +
66 return array;
67 }
68
69 render() {
70 return (
71 <div>
71 - <h1>Hello, my name is Seto Elkahfi.</h1>
72 - <p style={this.state.pStyle}>I am <ReactRotatingText style={this.state.wordStyle} items={this.state.alterEgos}/></p>
73 - </div>
72 + <h1>
73 + <FormattedMessage id="home.title"
74 + defaultMessage="Hello, my name is {name}"
75 + description="Welcome message"
76 + values={{ name: 'Seto Elkahi' }}/>
77 + </h1>
78 + <p style={this.state.pStyle}>
79 + <FormattedMessage id="home.iam"
80 + defaultMessage="I'm "
81 + description="My self description"/>
82 + <ReactRotatingText style={this.state.wordStyle} items={this.state.alterEgos}/></p>
83 + </div>
84 );
85 }
86 }
src/index.js
+27
@@ -4,13 +4,40 @@ import App from './components/App';
4 import * as serviceWorker from './serviceWorker';
5 import { BrowserRouter } from 'react-router-dom';
6 import Firebase, { FirebaseContext } from './components/Firebase';
7 +import { IntlProvider } from 'react-intl';
8 +import { addLocaleData } from "react-intl";
9 +import locale_en from 'react-intl/locale-data/en';
10 +import locale_se from 'react-intl/locale-data/se';
11 +import locale_id from 'react-intl/locale-data/id';
12 +import messages_se from "./translations/se.json";
13 +import messages_id from "./translations/id.json";
14 +import messages_en from "./translations/en.json";
15 +
16 +addLocaleData([...locale_en, ...locale_id, ...locale_se]);
17 +
18 +const messages = {
19 + "se": messages_se,
20 + "id": messages_id,
21 + "en": messages_en
22 +};
23 +
24 +
25 +var language = "en"; // language without region code
26 +
27 +if (window.location.hostname === "id.setoelkahfi" || window.location.hostname === "setoelkahfi.web.id") {
28 + language = "id";
29 +} else if (window.location.hostname === "se.setoelkahfi" || window.location.hostname === "seto.elkahfi.se") {
30 + language = "se";
31 +}
32
33 render((
34 + <IntlProvider locale={language} messages={messages[language]}>
35 <BrowserRouter>
36 <FirebaseContext.Provider value={new Firebase()}>
37 <App />
38 </FirebaseContext.Provider>
39 </BrowserRouter>
40 + </IntlProvider>
41 ), document.getElementById('root'));
42
43 // If you want your app to work offline and load faster, you can change
src/translations/en.json new
+12
@@ -0,0 +1,12 @@
1 +{
2 + "header.home": "Home",
3 + "header.about": "About",
4 + "header.cv": "CV",
5 + "header.contact": "Contact",
6 + "home.title": "Hello, my name is {name}.",
7 + "home.iam": "I'm ",
8 + "about.title": "About",
9 + "about.skills": "Skills",
10 + "cv.title": "CV",
11 + "contact.title": "Contact"
12 +}
src/translations/id.json new
+12
@@ -0,0 +1,12 @@
1 + {
2 + "header.home": "Beranda",
3 + "header.about": "Tentang",
4 + "header.cv": "CV",
5 + "header.contact": "Kontak",
6 + "home.title": "Halo, nama saya {name}.",
7 + "home.iam": "Saya ",
8 + "about.title": "Tentang",
9 + "about.skills": "Keterampilan",
10 + "cv.title": "CV",
11 + "contact.title": "Kontak"
12 + }
src/translations/se.json new
+12
@@ -0,0 +1,12 @@
1 + {
2 + "header.home": "Hem",
3 + "header.about": "Om",
4 + "header.cv": "CV",
5 + "header.contact": "Kontakt",
6 + "home.title": "Tjena, jag heter {name}.",
7 + "home.iam": "Jag ",
8 + "about.title": "Om",
9 + "about.skills": "Kompetens",
10 + "cv.title": "CV",
11 + "contact.title": "Kontakt"
12 + }