diff --git a/package-lock.json b/package-lock.json index 3c126735..a0264674 100644 --- a/package-lock.json +++ b/package-lock.json @@ -25,6 +25,8 @@ "d3-fisheye": "^2.0.1", "gcode-toolpath": "^2.2.0", "geokdbush": "^1.1.0", + "i18next": "^25.7.3", + "i18next-browser-languagedetector": "^8.2.0", "javascript-algorithms": "0.0.5", "kdbush": "^4.0.2", "konva": "^9.2.0", @@ -43,6 +45,7 @@ "react-dom": "^18.3.1", "react-error-boundary": "^4.0.13", "react-ga4": "^2.1.0", + "react-i18next": "^16.5.0", "react-icons": "^5.2.1", "react-konva": "^18.2.10", "react-redux": "^9.1.2", @@ -133,6 +136,7 @@ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.24.5.tgz", "integrity": "sha512-tVQRucExLQ02Boi4vdPp49svNGcfL2GhdTCT9aldhXgCJVAI21EtRfBettiuLUwce/7r6bFdgs6JFkcdTiFttA==", "dev": true, + "peer": true, "dependencies": { "@ampproject/remapping": "^2.2.0", "@babel/code-frame": "^7.24.2", @@ -1923,12 +1927,10 @@ "dev": true }, "node_modules/@babel/runtime": { - "version": "7.24.5", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.5.tgz", - "integrity": "sha512-Nms86NXrsaeU9vbBJKni6gXiEXZ4CVpYVzEjDH9Sb8vmZ3UljyA1GSOJl/6LGPO8EHLuSF9H+IxNXHPX8QHJ4g==", - "dependencies": { - "regenerator-runtime": "^0.14.0" - }, + "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.28.4.tgz", + "integrity": "sha512-Q/N6JNWvIvPnLDvjlE1OUBLPQHH6l3CltCEsHIujp45zQUSSh8K+gHnaEX45yAT1nyngnINhvWtzN+Nb9D8RAQ==", + "license": "MIT", "engines": { "node": ">=6.9.0" } @@ -2002,6 +2004,7 @@ "version": "6.1.0", "resolved": "https://registry.npmjs.org/@dnd-kit/core/-/core-6.1.0.tgz", "integrity": "sha512-J3cQBClB4TVxwGo3KEjssGEXNJqGVWx17aRTZ1ob0FliR5IjYgTxl5YJbKTzA6IzrtelotH19v6y7uoIRUZPSg==", + "peer": true, "dependencies": { "@dnd-kit/accessibility": "^3.1.0", "@dnd-kit/utilities": "^3.2.2", @@ -2197,7 +2200,6 @@ "os": [ "aix" ], - "peer": true, "engines": { "node": ">=12" } @@ -2214,7 +2216,6 @@ "os": [ "android" ], - "peer": true, "engines": { "node": ">=12" } @@ -2231,7 +2232,6 @@ "os": [ "android" ], - "peer": true, "engines": { "node": ">=12" } @@ -2248,7 +2248,6 @@ "os": [ "android" ], - "peer": true, "engines": { "node": ">=12" } @@ -2265,7 +2264,6 @@ "os": [ "darwin" ], - "peer": true, "engines": { "node": ">=12" } @@ -2282,7 +2280,6 @@ "os": [ "darwin" ], - "peer": true, "engines": { "node": ">=12" } @@ -2299,7 +2296,6 @@ "os": [ "freebsd" ], - "peer": true, "engines": { "node": ">=12" } @@ -2316,7 +2312,6 @@ "os": [ "freebsd" ], - "peer": true, "engines": { "node": ">=12" } @@ -2333,7 +2328,6 @@ "os": [ "linux" ], - "peer": true, "engines": { "node": ">=12" } @@ -2350,7 +2344,6 @@ "os": [ "linux" ], - "peer": true, "engines": { "node": ">=12" } @@ -2367,7 +2360,6 @@ "os": [ "linux" ], - "peer": true, "engines": { "node": ">=12" } @@ -2384,7 +2376,6 @@ "os": [ "linux" ], - "peer": true, "engines": { "node": ">=12" } @@ -2401,7 +2392,6 @@ "os": [ "linux" ], - "peer": true, "engines": { "node": ">=12" } @@ -2418,7 +2408,6 @@ "os": [ "linux" ], - "peer": true, "engines": { "node": ">=12" } @@ -2435,7 +2424,6 @@ "os": [ "linux" ], - "peer": true, "engines": { "node": ">=12" } @@ -2452,7 +2440,6 @@ "os": [ "linux" ], - "peer": true, "engines": { "node": ">=12" } @@ -2469,7 +2456,6 @@ "os": [ "linux" ], - "peer": true, "engines": { "node": ">=12" } @@ -2486,7 +2472,6 @@ "os": [ "netbsd" ], - "peer": true, "engines": { "node": ">=12" } @@ -2503,7 +2488,6 @@ "os": [ "openbsd" ], - "peer": true, "engines": { "node": ">=12" } @@ -2520,7 +2504,6 @@ "os": [ "sunos" ], - "peer": true, "engines": { "node": ">=12" } @@ -2537,7 +2520,6 @@ "os": [ "win32" ], - "peer": true, "engines": { "node": ">=12" } @@ -2554,7 +2536,6 @@ "os": [ "win32" ], - "peer": true, "engines": { "node": ">=12" } @@ -2571,7 +2552,6 @@ "os": [ "win32" ], - "peer": true, "engines": { "node": ">=12" } @@ -3597,6 +3577,7 @@ "version": "2.11.8", "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz", "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==", + "peer": true, "funding": { "type": "opencollective", "url": "https://opencollective.com/popperjs" @@ -4005,6 +3986,7 @@ "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.8.0.tgz", "integrity": "sha512-KgKQly1pv0l4ltcftP59uQZCi4HUYswCLbTqVZEJu7uLX8CTLyswqMLqLN+2QFz4jCptqWVV4SB7vdxcH2+0kQ==", "dev": true, + "peer": true, "dependencies": { "@typescript-eslint/scope-manager": "7.8.0", "@typescript-eslint/types": "7.8.0", @@ -4256,6 +4238,7 @@ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz", "integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==", "dev": true, + "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -5015,6 +4998,7 @@ "url": "https://github.com/sponsors/ai" } ], + "peer": true, "dependencies": { "caniuse-lite": "^1.0.30001587", "electron-to-chromium": "^1.4.668", @@ -5139,6 +5123,7 @@ "resolved": "https://registry.npmjs.org/canvas/-/canvas-2.11.2.tgz", "integrity": "sha512-ItanGBMrmRV7Py2Z+Xhs7cT+FNt5K0vPL4p9EZ/UX/Mu7hFbkxSjKF2KVtPwX7UYWp7dRKnrTvReflgrItJbdw==", "hasInstallScript": true, + "peer": true, "dependencies": { "@mapbox/node-pre-gyp": "^1.0.0", "nan": "^2.17.0", @@ -5972,6 +5957,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-3.0.0.tgz", "integrity": "sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==", + "peer": true, "engines": { "node": ">=12" } @@ -6665,6 +6651,7 @@ "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz", "integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==", "dev": true, + "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", @@ -6720,6 +6707,7 @@ "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-9.1.0.tgz", "integrity": "sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==", "dev": true, + "peer": true, "bin": { "eslint-config-prettier": "bin/cli.js" }, @@ -8012,6 +8000,15 @@ "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", "dev": true }, + "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/http-proxy-agent": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", @@ -8053,6 +8050,47 @@ "node": ">=10.17.0" } }, + "node_modules/i18next": { + "version": "25.7.3", + "resolved": "https://registry.npmjs.org/i18next/-/i18next-25.7.3.tgz", + "integrity": "sha512-2XaT+HpYGuc2uTExq9TVRhLsso+Dxym6PWaKpn36wfBmTI779OQ7iP/XaZHzrnGyzU4SHpFrTYLKfVyBfAhVNA==", + "funding": [ + { + "type": "individual", + "url": "https://locize.com" + }, + { + "type": "individual", + "url": "https://locize.com/i18next.html" + }, + { + "type": "individual", + "url": "https://www.i18next.com/how-to/faq#i18next-is-awesome.-how-can-i-support-the-project" + } + ], + "license": "MIT", + "peer": true, + "dependencies": { + "@babel/runtime": "^7.28.4" + }, + "peerDependencies": { + "typescript": "^5" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/i18next-browser-languagedetector": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/i18next-browser-languagedetector/-/i18next-browser-languagedetector-8.2.0.tgz", + "integrity": "sha512-P+3zEKLnOF0qmiesW383vsLdtQVyKtCNA9cjSoKCppTKPQVfKd2W8hbVo5ZhNJKDqeM7BOcvNoKJOjpHh4Js9g==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.23.2" + } + }, "node_modules/iconv-lite": { "version": "0.6.3", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", @@ -8827,6 +8865,7 @@ "resolved": "https://registry.npmjs.org/jest/-/jest-29.7.0.tgz", "integrity": "sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==", "dev": true, + "peer": true, "dependencies": { "@jest/core": "^29.7.0", "@jest/types": "^29.6.3", @@ -10607,7 +10646,8 @@ "type": "github", "url": "https://github.com/sponsors/lavrton" } - ] + ], + "peer": true }, "node_modules/leven": { "version": "3.1.0", @@ -11701,6 +11741,7 @@ "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.2.5.tgz", "integrity": "sha512-3/GWa9aOC0YeD7LUfvOG2NiDyhOWRvt1k+rcKhOuYnMY24iiCphgneUfJDyFXd6rZCAnuLBv6UeAULtrhT/F4A==", "dev": true, + "peer": true, "bin": { "prettier": "bin/prettier.cjs" }, @@ -11965,6 +12006,7 @@ "version": "18.3.1", "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==", + "peer": true, "dependencies": { "loose-envify": "^1.1.0" }, @@ -12005,6 +12047,7 @@ "version": "18.3.1", "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz", "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==", + "peer": true, "dependencies": { "loose-envify": "^1.1.0", "scheduler": "^0.23.2" @@ -12029,6 +12072,33 @@ "resolved": "https://registry.npmjs.org/react-ga4/-/react-ga4-2.1.0.tgz", "integrity": "sha512-ZKS7PGNFqqMd3PJ6+C2Jtz/o1iU9ggiy8Y8nUeksgVuvNISbmrQtJiZNvC/TjDsqD0QlU5Wkgs7i+w9+OjHhhQ==" }, + "node_modules/react-i18next": { + "version": "16.5.0", + "resolved": "https://registry.npmjs.org/react-i18next/-/react-i18next-16.5.0.tgz", + "integrity": "sha512-IMpPTyCTKxEj8klCrLKUTIUa8uYTd851+jcu2fJuUB9Agkk9Qq8asw4omyeHVnOXHrLgQJGTm5zTvn8HpaPiqw==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.27.6", + "html-parse-stringify": "^3.0.1", + "use-sync-external-store": "^1.6.0" + }, + "peerDependencies": { + "i18next": ">= 25.6.2", + "react": ">= 16.8.0", + "typescript": "^5" + }, + "peerDependenciesMeta": { + "react-dom": { + "optional": true + }, + "react-native": { + "optional": true + }, + "typescript": { + "optional": true + } + } + }, "node_modules/react-icons": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/react-icons/-/react-icons-5.2.1.tgz", @@ -12096,6 +12166,7 @@ "version": "9.1.2", "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-9.1.2.tgz", "integrity": "sha512-0OA4dhM1W48l3uzmv6B7TXPCGmokUU4p1M44DGN2/D9a1FjVPukVjER1PcPX97jIg6aUeLq1XJo1IpfbgULn0w==", + "peer": true, "dependencies": { "@types/use-sync-external-store": "^0.0.3", "use-sync-external-store": "^1.0.0" @@ -12227,7 +12298,8 @@ "node_modules/redux": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/redux/-/redux-5.0.1.tgz", - "integrity": "sha512-M9/ELqF6fy8FwmkpnF0S3YKOqMyoWJ4+CS5Efg2ct3oY9daQvd/Pc71FpGZsVsbl3Cpb+IIcjBDUnnyBdQbq4w==" + "integrity": "sha512-M9/ELqF6fy8FwmkpnF0S3YKOqMyoWJ4+CS5Efg2ct3oY9daQvd/Pc71FpGZsVsbl3Cpb+IIcjBDUnnyBdQbq4w==", + "peer": true }, "node_modules/redux-mock-store": { "version": "1.5.4", @@ -12284,11 +12356,6 @@ "node": ">=4" } }, - "node_modules/regenerator-runtime": { - "version": "0.14.0", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz", - "integrity": "sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA==" - }, "node_modules/regenerator-transform": { "version": "0.15.2", "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.2.tgz", @@ -12372,7 +12439,8 @@ "node_modules/reselect": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/reselect/-/reselect-5.1.0.tgz", - "integrity": "sha512-aw7jcGLDpSgNDyWBQLv2cedml85qd95/iszJjN988zX1t7AVRJi19d9kto5+W7oCfQ94gyo40dVbT6g2k4/kXg==" + "integrity": "sha512-aw7jcGLDpSgNDyWBQLv2cedml85qd95/iszJjN988zX1t7AVRJi19d9kto5+W7oCfQ94gyo40dVbT6g2k4/kXg==", + "peer": true }, "node_modules/resolve": { "version": "1.22.8", @@ -12566,6 +12634,7 @@ "version": "1.77.1", "resolved": "https://registry.npmjs.org/sass/-/sass-1.77.1.tgz", "integrity": "sha512-OMEyfirt9XEfyvocduUIOlUSkWOXS/LAt6oblR/ISXCTukyavjex+zQNm51pPCOiFKY1QpWvEH1EeCkgyV3I6w==", + "peer": true, "dependencies": { "chokidar": ">=3.0.0 <4.0.0", "immutable": "^4.0.0", @@ -13326,7 +13395,7 @@ "version": "5.4.5", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz", "integrity": "sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==", - "dev": true, + "devOptional": true, "peer": true, "bin": { "tsc": "bin/tsc", @@ -13499,11 +13568,12 @@ } }, "node_modules/use-sync-external-store": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz", - "integrity": "sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==", + "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" + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "node_modules/util": { @@ -13560,6 +13630,7 @@ "resolved": "https://registry.npmjs.org/vite/-/vite-4.5.5.tgz", "integrity": "sha512-ifW3Lb2sMdX+WU91s3R0FyQlAyLxOzCSCP37ujw0+r5POeHPwe6udWVIElKQq8gk3t7b8rkmvqC6IHBpCff4GQ==", "dev": true, + "peer": true, "dependencies": { "esbuild": "^0.18.10", "postcss": "^8.4.27", @@ -14021,6 +14092,15 @@ "integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==", "dev": true }, + "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/w3c-xmlserializer": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-4.0.0.tgz", diff --git a/package.json b/package.json index 3e997d75..14901388 100644 --- a/package.json +++ b/package.json @@ -21,6 +21,8 @@ "d3-fisheye": "^2.0.1", "gcode-toolpath": "^2.2.0", "geokdbush": "^1.1.0", + "i18next": "^25.7.3", + "i18next-browser-languagedetector": "^8.2.0", "javascript-algorithms": "0.0.5", "kdbush": "^4.0.2", "konva": "^9.2.0", @@ -39,6 +41,7 @@ "react-dom": "^18.3.1", "react-error-boundary": "^4.0.13", "react-ga4": "^2.1.0", + "react-i18next": "^16.5.0", "react-icons": "^5.2.1", "react-konva": "^18.2.10", "react-redux": "^9.1.2", diff --git a/public/fonts/SourceHanSerifCN-Bold.ttf b/public/fonts/SourceHanSerifCN-Bold.ttf new file mode 100644 index 00000000..df94403c Binary files /dev/null and b/public/fonts/SourceHanSerifCN-Bold.ttf differ diff --git a/public/fonts/SourceHanSerifCN-Regular.ttf b/public/fonts/SourceHanSerifCN-Regular.ttf new file mode 100644 index 00000000..dbafe4ea Binary files /dev/null and b/public/fonts/SourceHanSerifCN-Regular.ttf differ diff --git a/src/components/DropdownOption.js b/src/components/DropdownOption.js index 30f3b0e8..c48b5765 100644 --- a/src/components/DropdownOption.js +++ b/src/components/DropdownOption.js @@ -22,7 +22,13 @@ const DropdownOption = ({ choices = Array.isArray(choices) ? choices.map((choice) => { - return { value: choice, label: choice } + if(typeof choice === 'object') { + return { value: choice.value, label: choice.title } + } + else { + return { value: choice, label: choice } + } + }) : Object.keys(choices).map((key) => { return { value: key, label: choices[key] } diff --git a/src/components/LanguageSelector.js b/src/components/LanguageSelector.js new file mode 100644 index 00000000..e764d3d7 --- /dev/null +++ b/src/components/LanguageSelector.js @@ -0,0 +1,67 @@ +import React from "react" +import { useTranslation } from "react-i18next" +import { Dropdown } from "react-bootstrap" + +const LanguageSelector = () => { + const { i18n, t } = useTranslation() + + const changeLanguage = (lng) => { + if (i18n.language !== lng) { + i18n.changeLanguage(lng) + // 刷新整个页面以更新语言 + // window.location.reload() + } + } + + const getCurrentLanguageLabel = () => { + switch (i18n.language) { + case "zh": + return t("language.chinese") + case "en": + default: + return t("language.english") + } + } + + return ( + + { + e.target.style.backgroundColor = 'white'; + e.target.style.color = 'black'; + }} + onMouseLeave={(e) => { + e.target.style.backgroundColor = 'transparent'; + e.target.style.color = 'white'; + }} + > + {getCurrentLanguageLabel()} + + + + changeLanguage("en")} + active={i18n.language === "en"} + > + {t("language.english")} + + changeLanguage("zh")} + active={i18n.language === "zh"} + > + {t("language.chinese")} + + + + ) +} + +export default LanguageSelector \ No newline at end of file diff --git a/src/components/QuadrantButtonsOption.js b/src/components/QuadrantButtonsOption.js index 9cf3b4ba..8dd3b228 100644 --- a/src/components/QuadrantButtonsOption.js +++ b/src/components/QuadrantButtonsOption.js @@ -1,4 +1,5 @@ import React from "react" +import { useTranslation } from "react-i18next" import Col from "react-bootstrap/Col" import Row from "react-bootstrap/Row" import Form from "react-bootstrap/Form" @@ -6,6 +7,7 @@ import ToggleButton from "react-bootstrap/ToggleButton" import ToggleButtonGroup from "react-bootstrap/ToggleButtonGroup" const QuadrantButtonsOption = (props) => { + const { t } = useTranslation() const option = props.options[props.optionKey] const { data } = props const value = data[props.optionKey] @@ -35,6 +37,7 @@ const QuadrantButtonsOption = (props) => { type="checkbox" name="origin" className="flex-wrap" + style={{ width: '100%' }} value={value} onChange={handleChange} > @@ -43,36 +46,36 @@ const QuadrantButtonsOption = (props) => { value={1} id="origin-upper-left" className="px-4" - style={{ borderRadius: 0 }} + style={{ borderRadius: 0, width: '50%' }} > - upper left + {t('machine.rect.upperLeft')} - upper right + {t('machine.rect.upperRight')} - lower left + {t('machine.rect.lowerLeft')} - lower right + {t('machine.rect.lowerRight')} diff --git a/src/components/ToggleButtonOption.js b/src/components/ToggleButtonOption.js index 6f45cf1c..8e82bb30 100644 --- a/src/components/ToggleButtonOption.js +++ b/src/components/ToggleButtonOption.js @@ -41,7 +41,20 @@ const ToggleButtonOption = (props) => { onChange={handleChange} > {option.choices.map((choice) => { - return ( + if(typeof choice === 'object') { + return ( + + {choice.title} + + ) + } + else { + return ( { {choice} ) + } + })} diff --git a/src/features/app/About.js b/src/features/app/About.js index c9581540..242632f4 100644 --- a/src/features/app/About.js +++ b/src/features/app/About.js @@ -1,4 +1,5 @@ import React from "react" +import { useTranslation } from "react-i18next" import Container from "react-bootstrap/Container" import Row from "react-bootstrap/Row" import Col from "react-bootstrap/Col" @@ -9,6 +10,8 @@ import { SANDIFY_VERSION } from "@/features/app/appSlice" import "./About.scss" const About = () => { + const { t } = useTranslation() + return (