diff --git a/package-lock.json b/package-lock.json index 884076d..6367832 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,12 +10,14 @@ "dependencies": { "@tailwindcss/vite": "^4.2.2", "framer-motion": "^12.38.0", + "i18next": "^26.3.0", "leaflet": "^1.9.4", "lucide-react": "^1.16.0", "posthog-js": "^1.376.2", "react": "^19.2.4", "react-dom": "^19.2.4", "react-hot-toast": "^2.6.0", + "react-i18next": "^17.0.8", "react-leaflet": "^5.0.0", "react-router-dom": "^7.14.0", "tailwindcss": "^4.2.2" @@ -230,6 +232,15 @@ "node": ">=6.0.0" } }, + "node_modules/@babel/runtime": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.29.7.tgz", + "integrity": "sha512-Nq8OhGWiZIZGV6hLHoyAKLLcJihP/xFeBMGJoUrxTX2psI8dCifzLhZISFb+VWS3wFMRDmCGw5R+dOySCqPLhw==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@babel/template": { "version": "7.28.6", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.28.6.tgz", @@ -2735,6 +2746,43 @@ "hermes-estree": "0.25.1" } }, + "node_modules/html-parse-stringify": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/html-parse-stringify/-/html-parse-stringify-3.0.1.tgz", + "integrity": "sha512-KknJ50kTInJ7qIScF3jeaFRpMpE8/lfiTdzf/twXyPBLAGrLRTmkz3AdTnKeh40X8k9L2fdYwEp/42WGXIRGcg==", + "license": "MIT", + "dependencies": { + "void-elements": "3.1.0" + } + }, + "node_modules/i18next": { + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/i18next/-/i18next-26.3.0.tgz", + "integrity": "sha512-gHSgGpUXVmuqE2El1W61DmxeyeTlFfZgdJRWMo9jScAn5pu7TuTuiccb1zh3E2J9hEBVGJ23+96x0ieBhfuIHA==", + "funding": [ + { + "type": "individual", + "url": "https://www.locize.com/i18next" + }, + { + "type": "individual", + "url": "https://www.i18next.com/how-to/faq#i18next-is-awesome.-how-can-i-support-the-project" + }, + { + "type": "individual", + "url": "https://www.locize.com" + } + ], + "license": "MIT", + "peerDependencies": { + "typescript": "^5 || ^6" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, "node_modules/ignore": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", @@ -3539,6 +3587,33 @@ "react-dom": ">=16" } }, + "node_modules/react-i18next": { + "version": "17.0.8", + "resolved": "https://registry.npmjs.org/react-i18next/-/react-i18next-17.0.8.tgz", + "integrity": "sha512-0ooKbGLU8JXhe1zwpQUWIeXSgLPOfwJmgheWRIUpcoA0CpyabpGhayjdG+/eA5esC1AQ8h2jWpXjJfzQzeDOCw==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.29.2", + "html-parse-stringify": "^3.0.1", + "use-sync-external-store": "^1.6.0" + }, + "peerDependencies": { + "i18next": ">= 26.2.0", + "react": ">= 16.8.0", + "typescript": "^5 || ^6" + }, + "peerDependenciesMeta": { + "react-dom": { + "optional": true + }, + "react-native": { + "optional": true + }, + "typescript": { + "optional": true + } + } + }, "node_modules/react-leaflet": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/react-leaflet/-/react-leaflet-5.0.0.tgz", @@ -3862,7 +3937,7 @@ "version": "6.0.3", "resolved": "https://registry.npmjs.org/typescript/-/typescript-6.0.3.tgz", "integrity": "sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw==", - "dev": true, + "devOptional": true, "license": "Apache-2.0", "bin": { "tsc": "bin/tsc", @@ -3943,6 +4018,15 @@ "punycode": "^2.1.0" } }, + "node_modules/use-sync-external-store": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.6.0.tgz", + "integrity": "sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w==", + "license": "MIT", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, "node_modules/vite": { "version": "8.0.3", "resolved": "https://registry.npmjs.org/vite/-/vite-8.0.3.tgz", @@ -4020,6 +4104,15 @@ } } }, + "node_modules/void-elements": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-3.1.0.tgz", + "integrity": "sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/web-vitals": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/web-vitals/-/web-vitals-5.2.0.tgz", diff --git a/package.json b/package.json index 06bf502..7d279d0 100644 --- a/package.json +++ b/package.json @@ -18,12 +18,14 @@ "dependencies": { "@tailwindcss/vite": "^4.2.2", "framer-motion": "^12.38.0", + "i18next": "^26.3.0", "leaflet": "^1.9.4", "lucide-react": "^1.16.0", "posthog-js": "^1.376.2", "react": "^19.2.4", "react-dom": "^19.2.4", "react-hot-toast": "^2.6.0", + "react-i18next": "^17.0.8", "react-leaflet": "^5.0.0", "react-router-dom": "^7.14.0", "tailwindcss": "^4.2.2" diff --git a/src/components/Navbar.tsx b/src/components/Navbar.tsx index 9c6456b..3cc0393 100644 --- a/src/components/Navbar.tsx +++ b/src/components/Navbar.tsx @@ -1,3 +1,4 @@ +import { useTranslation } from "react-i18next"; import { Link, useLocation, useNavigate } from 'react-router-dom'; import { useState, useRef, useEffect } from 'react'; import { usePostHog } from 'posthog-js/react'; @@ -14,6 +15,7 @@ export default function Navbar() { const [profile, setProfile] = useState(null); const [loggedIn, setLoggedIn] = useState(isAuthenticated()); const dropdownRef = useRef(null); + const { t, i18n } = useTranslation(); useEffect(() => { let ignore = false; @@ -53,9 +55,9 @@ export default function Navbar() { }; const links = [ - { to: '/', label: 'HOME' }, - { to: '/scanner', label: 'SCANNER' }, - { to: '/map', label: 'TRUST_MAP' }, + { to: '/', label: t('home') }, + { to: '/scanner', label: t('scanner') }, + { to: '/map', label: t('trustMap') }, ]; return ( @@ -92,6 +94,15 @@ export default function Navbar() { {/* Auth Button & Theme Toggle */}
+ {/* Theme Toggle Button */}