diff --git a/package.json b/package.json index 078b9cb..1554abc 100644 --- a/package.json +++ b/package.json @@ -10,8 +10,10 @@ "preview": "vite preview" }, "dependencies": { + "i18next": "^23.4.6", "react": "^18.2.0", "react-dom": "^18.2.0", + "react-i18next": "^13.2.1", "styled-components": "^6.0.7" }, "devDependencies": { diff --git a/src/App.tsx b/src/App.tsx index 44c7607..65f71ae 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -3,6 +3,7 @@ import { theme } from './theme'; import { GlobalStyles } from './components/styles/Global.styled'; import Navbar from './components/Navbar'; import LandingSection from './components/LandingSection'; +import './i18n'; function App() { return ( diff --git a/src/components/Navbar.tsx b/src/components/Navbar.tsx index 5f956c2..2e75763 100644 --- a/src/components/Navbar.tsx +++ b/src/components/Navbar.tsx @@ -1,4 +1,11 @@ -import { StyledNavbar, StyledNavlink, StyledNavlinkBrand, StyledNavlinkList } from './styles/Navbar.styled'; +import { useTranslation } from 'react-i18next'; +import { + StyledLangButton, + StyledNavbar, + StyledNavlink, + StyledNavlinkBrand, + StyledNavlinkList, +} from './styles/Navbar.styled'; interface NavLink { title: string; @@ -6,46 +13,62 @@ interface NavLink { } function NavlinkList(props: { navlinks: NavLink[] }) { + const { t } = useTranslation(); + return ( <> {props.navlinks.map((navlink) => ( - {navlink.title} + {t(`navbar.${navlink.title}`)} ))} + + ); } -function NavlinkBrand(props: { name: string }) { - return {props.name}; +function LanguageChoice() { + const { i18n } = useTranslation(); + + function changeLanguage() { + i18n.changeLanguage(i18n.language == 'pl' ? 'en' : 'pl'); + } + + return ( + <> + {i18n.language} + + ); } const navlinks = [ + // { + // title: 'home', + // href: '#', + // }, { - title: 'HOME', + title: 'about', href: '#', }, { - title: 'ABOUT', + title: 'projects', href: '#', }, { - title: 'PROJECTS', - href: '#', - }, - { - title: 'CONTACT', + title: 'contact', href: '#', }, ]; export default function Navbar() { + const { t } = useTranslation(); + return ( - + {t('navbar.title')} ); diff --git a/src/components/styles/Global.styled.ts b/src/components/styles/Global.styled.ts index ef22ebe..961ffbc 100644 --- a/src/components/styles/Global.styled.ts +++ b/src/components/styles/Global.styled.ts @@ -46,6 +46,10 @@ export const GlobalStyles = createGlobalStyle` } } + button { + border: none; + } + @keyframes typing { to { left: 100% } } diff --git a/src/components/styles/Navbar.styled.ts b/src/components/styles/Navbar.styled.ts index 1fa04cb..20621dc 100644 --- a/src/components/styles/Navbar.styled.ts +++ b/src/components/styles/Navbar.styled.ts @@ -19,6 +19,7 @@ export const StyledNavlinkBrand = styled.div` export const StyledNavlinkList = styled.div` display: flex; + align-items: center; gap: 1em; font-size: 1.1em; `; @@ -27,3 +28,15 @@ export const StyledNavlink = styled.a` /* color: black; */ font-weight: bold; `; + +export const StyledLangButton = styled.button` + font-size: 1em; + font-weight: bold; + + padding: 0.25em 1em; + text-transform: uppercase; + cursor: pointer; + + border: 1px solid ${({ theme }) => theme.colors.primary}; + background: none; +`; diff --git a/src/i18n.ts b/src/i18n.ts new file mode 100644 index 0000000..6231fac --- /dev/null +++ b/src/i18n.ts @@ -0,0 +1,25 @@ +import i18n from 'i18next'; +import { initReactI18next } from 'react-i18next'; + +import localePL from './locales/pl.json'; +import localeEN from './locales/en.json'; + +const resources = { + en: { + translation: localeEN, + }, + pl: { + translation: localePL, + }, +}; + +i18n.use(initReactI18next).init({ + resources, + lng: 'pl', + + interpolation: { + escapeValue: false, + }, +}); + +export default i18n; diff --git a/src/locales/en.json b/src/locales/en.json new file mode 100644 index 0000000..0072346 --- /dev/null +++ b/src/locales/en.json @@ -0,0 +1,9 @@ +{ + "navbar": { + "title": "Spythere Portfolio", + "home": "HOME", + "about": "ABOUT", + "projects": "PROJECTS", + "contact": "CONTACT" + } +} diff --git a/src/locales/pl.json b/src/locales/pl.json new file mode 100644 index 0000000..a87e9c0 --- /dev/null +++ b/src/locales/pl.json @@ -0,0 +1,9 @@ +{ + "navbar": { + "title": "Spythere Portfolio", + "home": "", + "about": "O MNIE", + "projects": "PROJEKTY", + "contact": "KONTAKT" + } +} diff --git a/yarn.lock b/yarn.lock index 015af8e..ba42bfe 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1034,7 +1034,7 @@ resolved "https://registry.yarnpkg.com/@babel/regjsgen/-/regjsgen-0.8.0.tgz#f0ba69b075e1f05fb2825b7fad991e7adbb18310" integrity sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA== -"@babel/runtime@^7.8.4": +"@babel/runtime@^7.22.5", "@babel/runtime@^7.8.4": version "7.22.11" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.22.11.tgz#7a9ba3bbe406ad6f9e8dd4da2ece453eb23a77a4" integrity sha512-ee7jVNlWN09+KftVOu9n7S8gQzD/Z6hN/I8VBRXW4P1+Xe7kJGXMwu8vds4aGIMHZnNbdpSWCfZZtinytpcAvA== @@ -2023,6 +2023,20 @@ has@^1.0.3: dependencies: function-bind "^1.1.1" +html-parse-stringify@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/html-parse-stringify/-/html-parse-stringify-3.0.1.tgz#dfc1017347ce9f77c8141a507f233040c59c55d2" + integrity sha512-KknJ50kTInJ7qIScF3jeaFRpMpE8/lfiTdzf/twXyPBLAGrLRTmkz3AdTnKeh40X8k9L2fdYwEp/42WGXIRGcg== + dependencies: + void-elements "3.1.0" + +i18next@^23.4.6: + version "23.4.6" + resolved "https://registry.yarnpkg.com/i18next/-/i18next-23.4.6.tgz#10211e72d5bd29e274baae99c6cc0178b93a93f8" + integrity sha512-jBE8bui969Ygv7TVYp0pwDZB7+he0qsU+nz7EcfdqSh+QvKjEfl9YPRQd/KrGiMhTYFGkeuPaeITenKK/bSFDg== + dependencies: + "@babel/runtime" "^7.22.5" + ignore@^5.2.0, ignore@^5.2.4: version "5.2.4" resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.4.tgz#a291c0c6178ff1b960befe47fcdec301674a6324" @@ -2365,6 +2379,14 @@ react-dom@^18.2.0: loose-envify "^1.1.0" scheduler "^0.23.0" +react-i18next@^13.2.1: + version "13.2.1" + resolved "https://registry.yarnpkg.com/react-i18next/-/react-i18next-13.2.1.tgz#57cf7c07778281bdb1e0a1fd60ca5fcc35c0a786" + integrity sha512-XhMsnGgJnytWfi2Q70HMYfm+zysPUu1Pz+It6I87WwaeclGY+W8W1c11uENEMNg+Xb+mNrGuo8GEDuQDOgO+oQ== + dependencies: + "@babel/runtime" "^7.22.5" + html-parse-stringify "^3.0.1" + react-refresh@^0.14.0: version "0.14.0" resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.14.0.tgz#4e02825378a5f227079554d4284889354e5f553e" @@ -2686,6 +2708,11 @@ vite@^4.4.5: optionalDependencies: fsevents "~2.3.2" +void-elements@3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/void-elements/-/void-elements-3.1.0.tgz#614f7fbf8d801f0bb5f0661f5b2f5785750e4f09" + integrity sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w== + which@^2.0.1: version "2.0.2" resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1"