added i18next language lib and some style fixes
This commit is contained in:
Generated
+249
-14
@@ -21,10 +21,15 @@
|
|||||||
"framer-motion": "^7.4.0",
|
"framer-motion": "^7.4.0",
|
||||||
"freeice": "^2.2.2",
|
"freeice": "^2.2.2",
|
||||||
"html-react-parser": "^3.0.4",
|
"html-react-parser": "^3.0.4",
|
||||||
|
"i18next": "^22.4.6",
|
||||||
|
"i18next-browser-languagedetector": "^7.0.1",
|
||||||
|
"i18next-http-backend": "^2.1.1",
|
||||||
|
"js-cookie": "^3.0.1",
|
||||||
"peer": "^0.6.1",
|
"peer": "^0.6.1",
|
||||||
"peerjs": "^1.4.7",
|
"peerjs": "^1.4.7",
|
||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
"react-dom": "^18.2.0",
|
"react-dom": "^18.2.0",
|
||||||
|
"react-i18next": "^12.1.1",
|
||||||
"react-player": "^2.11.0",
|
"react-player": "^2.11.0",
|
||||||
"react-redux": "^8.0.5",
|
"react-redux": "^8.0.5",
|
||||||
"react-router-dom": "^5.2.0",
|
"react-router-dom": "^5.2.0",
|
||||||
@@ -36,6 +41,7 @@
|
|||||||
"web-vitals": "^2.1.4"
|
"web-vitals": "^2.1.4"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@types/js-cookie": "^3.0.2",
|
||||||
"@types/react-router-dom": "^5.3.3",
|
"@types/react-router-dom": "^5.3.3",
|
||||||
"@types/react-transition-group": "^4.4.5"
|
"@types/react-transition-group": "^4.4.5"
|
||||||
}
|
}
|
||||||
@@ -1814,11 +1820,11 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@babel/runtime": {
|
"node_modules/@babel/runtime": {
|
||||||
"version": "7.19.0",
|
"version": "7.20.7",
|
||||||
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.19.0.tgz",
|
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.20.7.tgz",
|
||||||
"integrity": "sha512-eR8Lo9hnDS7tqkO7NsV+mKvCmv5boaXFSZ70DnfhcgiEne8hv9oCEd36Klw74EtizEqLsy4YnW8UWwpBVolHZA==",
|
"integrity": "sha512-UF0tvkUtxwAgZ5W/KrkHf0Rn0fdnLDU9ScxBrEVNUprE/MzirjK4MJUX1/BVDv00Sv8cljtukVK1aky++X1SjQ==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"regenerator-runtime": "^0.13.4"
|
"regenerator-runtime": "^0.13.11"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=6.9.0"
|
"node": ">=6.9.0"
|
||||||
@@ -3952,6 +3958,12 @@
|
|||||||
"pretty-format": "^27.0.0"
|
"pretty-format": "^27.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@types/js-cookie": {
|
||||||
|
"version": "3.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/js-cookie/-/js-cookie-3.0.2.tgz",
|
||||||
|
"integrity": "sha512-6+0ekgfusHftJNYpihfkMu8BWdeHs9EOJuGcSofErjstGPfPGEu9yTu4t460lTzzAMl2cM5zngQJqPMHbbnvYA==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"node_modules/@types/json-schema": {
|
"node_modules/@types/json-schema": {
|
||||||
"version": "7.0.11",
|
"version": "7.0.11",
|
||||||
"resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz",
|
"resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz",
|
||||||
@@ -5889,6 +5901,14 @@
|
|||||||
"node": ">=10"
|
"node": ">=10"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/cross-fetch": {
|
||||||
|
"version": "3.1.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.5.tgz",
|
||||||
|
"integrity": "sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw==",
|
||||||
|
"dependencies": {
|
||||||
|
"node-fetch": "2.6.7"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/cross-spawn": {
|
"node_modules/cross-spawn": {
|
||||||
"version": "7.0.3",
|
"version": "7.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
|
||||||
@@ -8827,6 +8847,14 @@
|
|||||||
"node": ">=12"
|
"node": ">=12"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"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==",
|
||||||
|
"dependencies": {
|
||||||
|
"void-elements": "3.1.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/html-react-parser": {
|
"node_modules/html-react-parser": {
|
||||||
"version": "3.0.4",
|
"version": "3.0.4",
|
||||||
"resolved": "https://registry.npmjs.org/html-react-parser/-/html-react-parser-3.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/html-react-parser/-/html-react-parser-3.0.4.tgz",
|
||||||
@@ -8989,6 +9017,44 @@
|
|||||||
"node": ">=10.17.0"
|
"node": ">=10.17.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/i18next": {
|
||||||
|
"version": "22.4.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/i18next/-/i18next-22.4.6.tgz",
|
||||||
|
"integrity": "sha512-9Tm1ezxWyzV+306CIDMBbYBitC1jedQyYuuLtIv7oxjp2ohh8eyxP9xytIf+2bbQfhH784IQKPSYp+Zq9+YSbw==",
|
||||||
|
"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"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"dependencies": {
|
||||||
|
"@babel/runtime": "^7.20.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/i18next-browser-languagedetector": {
|
||||||
|
"version": "7.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/i18next-browser-languagedetector/-/i18next-browser-languagedetector-7.0.1.tgz",
|
||||||
|
"integrity": "sha512-Pa5kFwaczXJAeHE56CHG2aWzFBMJNUNghf0Pm4SwSrEMps/PTKqW90EYWlIvhuYStf3Sn1K0vw+gH3+TLdkH1g==",
|
||||||
|
"dependencies": {
|
||||||
|
"@babel/runtime": "^7.19.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/i18next-http-backend": {
|
||||||
|
"version": "2.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/i18next-http-backend/-/i18next-http-backend-2.1.1.tgz",
|
||||||
|
"integrity": "sha512-jByfUCDVgQ8+/Wens7queQhYYvMcGTW/lR4IJJNEDDXnmqjLrwi8ubXKpmp76/JIWEZHffNdWqnxFJcTVGeaOw==",
|
||||||
|
"dependencies": {
|
||||||
|
"cross-fetch": "3.1.5"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/iconv-lite": {
|
"node_modules/iconv-lite": {
|
||||||
"version": "0.6.3",
|
"version": "0.6.3",
|
||||||
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
|
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
|
||||||
@@ -11507,6 +11573,14 @@
|
|||||||
"url": "https://github.com/chalk/supports-color?sponsor=1"
|
"url": "https://github.com/chalk/supports-color?sponsor=1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/js-cookie": {
|
||||||
|
"version": "3.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/js-cookie/-/js-cookie-3.0.1.tgz",
|
||||||
|
"integrity": "sha512-+0rgsUXZu4ncpPxRL+lNEptWMOWl9etvPHc/koSRp6MPwpRYAhmk0dUG00J4bxVV3r9uUzfo24wW0knS07SKSw==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/js-sdsl": {
|
"node_modules/js-sdsl": {
|
||||||
"version": "4.1.4",
|
"version": "4.1.4",
|
||||||
"resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.1.4.tgz",
|
"resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.1.4.tgz",
|
||||||
@@ -12130,6 +12204,44 @@
|
|||||||
"tslib": "^2.0.3"
|
"tslib": "^2.0.3"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/node-fetch": {
|
||||||
|
"version": "2.6.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz",
|
||||||
|
"integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"whatwg-url": "^5.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": "4.x || >=6.0.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"encoding": "^0.1.0"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"encoding": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/node-fetch/node_modules/tr46": {
|
||||||
|
"version": "0.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
|
||||||
|
"integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw=="
|
||||||
|
},
|
||||||
|
"node_modules/node-fetch/node_modules/webidl-conversions": {
|
||||||
|
"version": "3.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
|
||||||
|
"integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="
|
||||||
|
},
|
||||||
|
"node_modules/node-fetch/node_modules/whatwg-url": {
|
||||||
|
"version": "5.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
|
||||||
|
"integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
|
||||||
|
"dependencies": {
|
||||||
|
"tr46": "~0.0.3",
|
||||||
|
"webidl-conversions": "^3.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/node-forge": {
|
"node_modules/node-forge": {
|
||||||
"version": "1.3.1",
|
"version": "1.3.1",
|
||||||
"resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz",
|
"resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz",
|
||||||
@@ -14510,6 +14622,27 @@
|
|||||||
"resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-3.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-3.2.0.tgz",
|
||||||
"integrity": "sha512-rtGImPZ0YyLrscKI9xTpV8psd6I8VAtjKCzQDlzyDvqJA8XOW78TXYQwNRNd8g8JZnDu8q9Fu/1v4HPAVwVdHA=="
|
"integrity": "sha512-rtGImPZ0YyLrscKI9xTpV8psd6I8VAtjKCzQDlzyDvqJA8XOW78TXYQwNRNd8g8JZnDu8q9Fu/1v4HPAVwVdHA=="
|
||||||
},
|
},
|
||||||
|
"node_modules/react-i18next": {
|
||||||
|
"version": "12.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-i18next/-/react-i18next-12.1.1.tgz",
|
||||||
|
"integrity": "sha512-mFdieOI0LDy84q3JuZU6Aou1DoWW2fhapcTGeBS8+vWSJuViuoCLQAMYSb0QoHhXS8B0WKUOPpx4cffAP7r/aA==",
|
||||||
|
"dependencies": {
|
||||||
|
"@babel/runtime": "^7.14.5",
|
||||||
|
"html-parse-stringify": "^3.0.1"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"i18next": ">= 19.0.0",
|
||||||
|
"react": ">= 16.8.0"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"react-dom": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"react-native": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/react-is": {
|
"node_modules/react-is": {
|
||||||
"version": "17.0.2",
|
"version": "17.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
|
||||||
@@ -14840,9 +14973,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/regenerator-runtime": {
|
"node_modules/regenerator-runtime": {
|
||||||
"version": "0.13.9",
|
"version": "0.13.11",
|
||||||
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz",
|
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz",
|
||||||
"integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA=="
|
"integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg=="
|
||||||
},
|
},
|
||||||
"node_modules/regenerator-transform": {
|
"node_modules/regenerator-transform": {
|
||||||
"version": "0.15.0",
|
"version": "0.15.0",
|
||||||
@@ -16692,6 +16825,14 @@
|
|||||||
"node": ">= 0.8"
|
"node": ">= 0.8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"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==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.10.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/w3c-hr-time": {
|
"node_modules/w3c-hr-time": {
|
||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz",
|
||||||
@@ -18825,11 +18966,11 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@babel/runtime": {
|
"@babel/runtime": {
|
||||||
"version": "7.19.0",
|
"version": "7.20.7",
|
||||||
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.19.0.tgz",
|
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.20.7.tgz",
|
||||||
"integrity": "sha512-eR8Lo9hnDS7tqkO7NsV+mKvCmv5boaXFSZ70DnfhcgiEne8hv9oCEd36Klw74EtizEqLsy4YnW8UWwpBVolHZA==",
|
"integrity": "sha512-UF0tvkUtxwAgZ5W/KrkHf0Rn0fdnLDU9ScxBrEVNUprE/MzirjK4MJUX1/BVDv00Sv8cljtukVK1aky++X1SjQ==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"regenerator-runtime": "^0.13.4"
|
"regenerator-runtime": "^0.13.11"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@babel/runtime-corejs3": {
|
"@babel/runtime-corejs3": {
|
||||||
@@ -20333,6 +20474,12 @@
|
|||||||
"pretty-format": "^27.0.0"
|
"pretty-format": "^27.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"@types/js-cookie": {
|
||||||
|
"version": "3.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/js-cookie/-/js-cookie-3.0.2.tgz",
|
||||||
|
"integrity": "sha512-6+0ekgfusHftJNYpihfkMu8BWdeHs9EOJuGcSofErjstGPfPGEu9yTu4t460lTzzAMl2cM5zngQJqPMHbbnvYA==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"@types/json-schema": {
|
"@types/json-schema": {
|
||||||
"version": "7.0.11",
|
"version": "7.0.11",
|
||||||
"resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz",
|
"resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz",
|
||||||
@@ -21808,6 +21955,14 @@
|
|||||||
"yaml": "^1.10.0"
|
"yaml": "^1.10.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"cross-fetch": {
|
||||||
|
"version": "3.1.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.5.tgz",
|
||||||
|
"integrity": "sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw==",
|
||||||
|
"requires": {
|
||||||
|
"node-fetch": "2.6.7"
|
||||||
|
}
|
||||||
|
},
|
||||||
"cross-spawn": {
|
"cross-spawn": {
|
||||||
"version": "7.0.3",
|
"version": "7.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
|
||||||
@@ -23924,6 +24079,14 @@
|
|||||||
"terser": "^5.10.0"
|
"terser": "^5.10.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"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==",
|
||||||
|
"requires": {
|
||||||
|
"void-elements": "3.1.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"html-react-parser": {
|
"html-react-parser": {
|
||||||
"version": "3.0.4",
|
"version": "3.0.4",
|
||||||
"resolved": "https://registry.npmjs.org/html-react-parser/-/html-react-parser-3.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/html-react-parser/-/html-react-parser-3.0.4.tgz",
|
||||||
@@ -24036,6 +24199,30 @@
|
|||||||
"resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz",
|
||||||
"integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw=="
|
"integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw=="
|
||||||
},
|
},
|
||||||
|
"i18next": {
|
||||||
|
"version": "22.4.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/i18next/-/i18next-22.4.6.tgz",
|
||||||
|
"integrity": "sha512-9Tm1ezxWyzV+306CIDMBbYBitC1jedQyYuuLtIv7oxjp2ohh8eyxP9xytIf+2bbQfhH784IQKPSYp+Zq9+YSbw==",
|
||||||
|
"requires": {
|
||||||
|
"@babel/runtime": "^7.20.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"i18next-browser-languagedetector": {
|
||||||
|
"version": "7.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/i18next-browser-languagedetector/-/i18next-browser-languagedetector-7.0.1.tgz",
|
||||||
|
"integrity": "sha512-Pa5kFwaczXJAeHE56CHG2aWzFBMJNUNghf0Pm4SwSrEMps/PTKqW90EYWlIvhuYStf3Sn1K0vw+gH3+TLdkH1g==",
|
||||||
|
"requires": {
|
||||||
|
"@babel/runtime": "^7.19.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"i18next-http-backend": {
|
||||||
|
"version": "2.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/i18next-http-backend/-/i18next-http-backend-2.1.1.tgz",
|
||||||
|
"integrity": "sha512-jByfUCDVgQ8+/Wens7queQhYYvMcGTW/lR4IJJNEDDXnmqjLrwi8ubXKpmp76/JIWEZHffNdWqnxFJcTVGeaOw==",
|
||||||
|
"requires": {
|
||||||
|
"cross-fetch": "3.1.5"
|
||||||
|
}
|
||||||
|
},
|
||||||
"iconv-lite": {
|
"iconv-lite": {
|
||||||
"version": "0.6.3",
|
"version": "0.6.3",
|
||||||
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
|
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
|
||||||
@@ -25845,6 +26032,11 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"js-cookie": {
|
||||||
|
"version": "3.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/js-cookie/-/js-cookie-3.0.1.tgz",
|
||||||
|
"integrity": "sha512-+0rgsUXZu4ncpPxRL+lNEptWMOWl9etvPHc/koSRp6MPwpRYAhmk0dUG00J4bxVV3r9uUzfo24wW0knS07SKSw=="
|
||||||
|
},
|
||||||
"js-sdsl": {
|
"js-sdsl": {
|
||||||
"version": "4.1.4",
|
"version": "4.1.4",
|
||||||
"resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.1.4.tgz",
|
"resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.1.4.tgz",
|
||||||
@@ -26315,6 +26507,35 @@
|
|||||||
"tslib": "^2.0.3"
|
"tslib": "^2.0.3"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node-fetch": {
|
||||||
|
"version": "2.6.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz",
|
||||||
|
"integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==",
|
||||||
|
"requires": {
|
||||||
|
"whatwg-url": "^5.0.0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"tr46": {
|
||||||
|
"version": "0.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
|
||||||
|
"integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw=="
|
||||||
|
},
|
||||||
|
"webidl-conversions": {
|
||||||
|
"version": "3.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
|
||||||
|
"integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="
|
||||||
|
},
|
||||||
|
"whatwg-url": {
|
||||||
|
"version": "5.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
|
||||||
|
"integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
|
||||||
|
"requires": {
|
||||||
|
"tr46": "~0.0.3",
|
||||||
|
"webidl-conversions": "^3.0.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"node-forge": {
|
"node-forge": {
|
||||||
"version": "1.3.1",
|
"version": "1.3.1",
|
||||||
"resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz",
|
"resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz",
|
||||||
@@ -27856,6 +28077,15 @@
|
|||||||
"resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-3.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-3.2.0.tgz",
|
||||||
"integrity": "sha512-rtGImPZ0YyLrscKI9xTpV8psd6I8VAtjKCzQDlzyDvqJA8XOW78TXYQwNRNd8g8JZnDu8q9Fu/1v4HPAVwVdHA=="
|
"integrity": "sha512-rtGImPZ0YyLrscKI9xTpV8psd6I8VAtjKCzQDlzyDvqJA8XOW78TXYQwNRNd8g8JZnDu8q9Fu/1v4HPAVwVdHA=="
|
||||||
},
|
},
|
||||||
|
"react-i18next": {
|
||||||
|
"version": "12.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-i18next/-/react-i18next-12.1.1.tgz",
|
||||||
|
"integrity": "sha512-mFdieOI0LDy84q3JuZU6Aou1DoWW2fhapcTGeBS8+vWSJuViuoCLQAMYSb0QoHhXS8B0WKUOPpx4cffAP7r/aA==",
|
||||||
|
"requires": {
|
||||||
|
"@babel/runtime": "^7.14.5",
|
||||||
|
"html-parse-stringify": "^3.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"react-is": {
|
"react-is": {
|
||||||
"version": "17.0.2",
|
"version": "17.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
|
||||||
@@ -28110,9 +28340,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"regenerator-runtime": {
|
"regenerator-runtime": {
|
||||||
"version": "0.13.9",
|
"version": "0.13.11",
|
||||||
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz",
|
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz",
|
||||||
"integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA=="
|
"integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg=="
|
||||||
},
|
},
|
||||||
"regenerator-transform": {
|
"regenerator-transform": {
|
||||||
"version": "0.15.0",
|
"version": "0.15.0",
|
||||||
@@ -29487,6 +29717,11 @@
|
|||||||
"resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
|
||||||
"integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg=="
|
"integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg=="
|
||||||
},
|
},
|
||||||
|
"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=="
|
||||||
|
},
|
||||||
"w3c-hr-time": {
|
"w3c-hr-time": {
|
||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz",
|
||||||
|
|||||||
@@ -16,10 +16,15 @@
|
|||||||
"framer-motion": "^7.4.0",
|
"framer-motion": "^7.4.0",
|
||||||
"freeice": "^2.2.2",
|
"freeice": "^2.2.2",
|
||||||
"html-react-parser": "^3.0.4",
|
"html-react-parser": "^3.0.4",
|
||||||
|
"i18next": "^22.4.6",
|
||||||
|
"i18next-browser-languagedetector": "^7.0.1",
|
||||||
|
"i18next-http-backend": "^2.1.1",
|
||||||
|
"js-cookie": "^3.0.1",
|
||||||
"peer": "^0.6.1",
|
"peer": "^0.6.1",
|
||||||
"peerjs": "^1.4.7",
|
"peerjs": "^1.4.7",
|
||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
"react-dom": "^18.2.0",
|
"react-dom": "^18.2.0",
|
||||||
|
"react-i18next": "^12.1.1",
|
||||||
"react-player": "^2.11.0",
|
"react-player": "^2.11.0",
|
||||||
"react-redux": "^8.0.5",
|
"react-redux": "^8.0.5",
|
||||||
"react-router-dom": "^5.2.0",
|
"react-router-dom": "^5.2.0",
|
||||||
@@ -55,6 +60,7 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@types/js-cookie": "^3.0.2",
|
||||||
"@types/react-router-dom": "^5.3.3",
|
"@types/react-router-dom": "^5.3.3",
|
||||||
"@types/react-transition-group": "^4.4.5"
|
"@types/react-transition-group": "^4.4.5"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,28 @@
|
|||||||
|
{
|
||||||
|
"demo-title": "Available demonstrations",
|
||||||
|
"popup-main-title": "Start new demonstration",
|
||||||
|
"popup-main-caption": "Connect to an existing one",
|
||||||
|
"popup-main-select": "Select residential complex",
|
||||||
|
"popup-main-btn-start": "Start",
|
||||||
|
"popup-main-btn-connect": "Connect",
|
||||||
|
"popup-connect-title": "Connection code",
|
||||||
|
"popup-connect-btn-mode": "Select demonstration mode",
|
||||||
|
"popup-connect-btn-continue": "Continue",
|
||||||
|
"fullscreen-control-btn": "Expand",
|
||||||
|
"fullscreen-control-btn-active": "Collapse",
|
||||||
|
"request-control-btn": "Request control",
|
||||||
|
"request-control-btn-disable": "Stop control",
|
||||||
|
"mute-control-btn": "Turn On Mic",
|
||||||
|
"mute-control-btn-disable": "Turn Off Mic",
|
||||||
|
"share-contro-btn": "Share",
|
||||||
|
"popup-control-invite-title": "Invite to the demonstration",
|
||||||
|
"popup-control-code": "Connection code",
|
||||||
|
"popup-control-link": "Link for connection",
|
||||||
|
"popup-control-btn": "Copy",
|
||||||
|
"popup-control-btn-active": "Copied!",
|
||||||
|
"language-control-btn": "Language",
|
||||||
|
"exit-control-btn": "Exit presintation",
|
||||||
|
"popup-control-exit-title": "Are you sure you want to end the demo?",
|
||||||
|
"popup-control-yes": "Finish",
|
||||||
|
"popup-control-no": "Stay"
|
||||||
|
}
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
{
|
||||||
|
"demo-title": "Доступные демонстрации",
|
||||||
|
"popup-main-title": "Начать новую демонстрацию",
|
||||||
|
"popup-main-caption": "Подключиться к существующией",
|
||||||
|
"popup-main-select": "Выбор жилого комплекса",
|
||||||
|
"popup-main-btn-start": "Начать",
|
||||||
|
"popup-main-btn-connect": "Подключиться",
|
||||||
|
"popup-connect-title": "Код подключения к демонстрации",
|
||||||
|
"popup-connect-btn-mode": "Выбор способа демонстрации",
|
||||||
|
"popup-connect-btn-continue": "Продолжить",
|
||||||
|
"fullscreen-control-btn": "Развернуть",
|
||||||
|
"fullscreen-control-btn-active": "Свернуть",
|
||||||
|
"request-control-btn": "Запрос управления",
|
||||||
|
"request-control-btn-disable": "Запрет управления",
|
||||||
|
"mute-control-btn": "Включить микрофон",
|
||||||
|
"mute-control-btn-disable": "Выключить микрофон",
|
||||||
|
"share-contro-btn": "Поделиться",
|
||||||
|
"popup-control-invite-title": "Пригласить на демонстрацию",
|
||||||
|
"popup-control-code": "Код подключения",
|
||||||
|
"popup-control-link": "Ссылка для подключения",
|
||||||
|
"popup-control-btn": "Скопировать",
|
||||||
|
"popup-control-btn-active": "Скопировано",
|
||||||
|
"language-control-btn": "Язык",
|
||||||
|
"exit-control-btn": "Завершить презентацию",
|
||||||
|
"popup-control-exit-title": "Вы уверены, что хотите закончить демонстрацию??",
|
||||||
|
"popup-control-yes": "Закончить",
|
||||||
|
"popup-control-no": "Остаться"
|
||||||
|
|
||||||
|
}
|
||||||
+12
-68
@@ -10,14 +10,12 @@ import { PlayerComponent } from "./components/playerComponent/playerComponent";
|
|||||||
import { useAppDispatch, useAppSelector } from "./hooks/redux";
|
import { useAppDispatch, useAppSelector } from "./hooks/redux";
|
||||||
import { fetchCards } from "./store/reducers/ActionCreator";
|
import { fetchCards } from "./store/reducers/ActionCreator";
|
||||||
import { cardSlice } from "./store/reducers/cardSlice";
|
import { cardSlice } from "./store/reducers/cardSlice";
|
||||||
|
import { languageSlice } from "./store/reducers/languageSlice";
|
||||||
import { ICards } from "./models/ICards";
|
import { ICards } from "./models/ICards";
|
||||||
import textRU from "./utils/textRU";
|
import { useTranslation } from "react-i18next";
|
||||||
import textEN from "./utils/textEN";
|
import cookies from "js-cookie";
|
||||||
|
|
||||||
|
const App: React.FC<any> = () => {
|
||||||
function App() {
|
|
||||||
const [language, setLanguage] = useState<string>("");
|
|
||||||
const [text, setText] = useState(textRU);
|
|
||||||
const [visible, setVisible] = useState({
|
const [visible, setVisible] = useState({
|
||||||
popup1: true,
|
popup1: true,
|
||||||
popup2: false,
|
popup2: false,
|
||||||
@@ -26,11 +24,12 @@ function App() {
|
|||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
const history = useHistory();
|
const history = useHistory();
|
||||||
const { handleCurrentCard } = cardSlice.actions;
|
const { handleCurrentCard } = cardSlice.actions;
|
||||||
|
const { handleChangeLanguage } = languageSlice.actions;
|
||||||
const { cards } = useAppSelector((state) => state.cardReducer);
|
const { cards } = useAppSelector((state) => state.cardReducer);
|
||||||
const savedLanguage = localStorage.getItem("savedLang");
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
dispatch(fetchCards());
|
dispatch(fetchCards());
|
||||||
|
dispatch(handleChangeLanguage(cookies.get("i18next")));
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const handleCards = (card: ICards) => {
|
const handleCards = (card: ICards) => {
|
||||||
@@ -42,61 +41,14 @@ function App() {
|
|||||||
history.push("/");
|
history.push("/");
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
const { t } = useTranslation();
|
||||||
if (savedLanguage !== null) {
|
|
||||||
setSavedLanguage();
|
|
||||||
} else {
|
|
||||||
setInitialLanguage();
|
|
||||||
}
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
function setSavedLanguage() {
|
|
||||||
if (savedLanguage === "RU") {
|
|
||||||
setLanguage("RU");
|
|
||||||
localStorage.setItem("lang", "RU");
|
|
||||||
setText(textRU);
|
|
||||||
} else if (savedLanguage === "EN") {
|
|
||||||
setLanguage("EN");
|
|
||||||
localStorage.setItem("lang", "EN");
|
|
||||||
setText(textEN);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function setInitialLanguage() {
|
|
||||||
if (window.navigator.language === "ru") {
|
|
||||||
setLanguage("RU");
|
|
||||||
localStorage.setItem("lang", "RU");
|
|
||||||
setText(textRU);
|
|
||||||
} else {
|
|
||||||
setLanguage("EN");
|
|
||||||
setText(textEN);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function changeLanguage(language: string) {
|
|
||||||
if (language === "RU") {
|
|
||||||
setLanguage(language);
|
|
||||||
setText(textRU);
|
|
||||||
localStorage.setItem("savedLang", "RU");
|
|
||||||
localStorage.setItem("lang", "RU");
|
|
||||||
} else {
|
|
||||||
setLanguage("EN");
|
|
||||||
localStorage.setItem("lang", "EN");
|
|
||||||
localStorage.setItem("savedLang", "EN");
|
|
||||||
setText(textEN);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Switch>
|
<Switch>
|
||||||
<Route exact path="/">
|
<Route exact path="/">
|
||||||
<Header
|
<Header></Header>
|
||||||
text={text.footer}
|
|
||||||
language={language}
|
|
||||||
changeLanguage={changeLanguage}
|
|
||||||
></Header>
|
|
||||||
<div className="main">
|
<div className="main">
|
||||||
<h3 className="demos__tittle">{text.demos.title}</h3>
|
<h3 className="demos__tittle">{t("demo-title")}</h3>
|
||||||
<div className="demo__container">
|
<div className="demo__container">
|
||||||
{cards.map((i: any) => (
|
{cards.map((i: any) => (
|
||||||
<Demos
|
<Demos
|
||||||
@@ -111,17 +63,9 @@ function App() {
|
|||||||
<Route path="/connect-page">
|
<Route path="/connect-page">
|
||||||
<div className="background">
|
<div className="background">
|
||||||
<div className="blur">
|
<div className="blur">
|
||||||
<Header
|
<Header></Header>
|
||||||
text={text.footer}
|
|
||||||
language={language}
|
|
||||||
changeLanguage={changeLanguage}
|
|
||||||
></Header>
|
|
||||||
<div className="content__container">
|
<div className="content__container">
|
||||||
<Main
|
<Main visible={visible} setVisible={setVisible}></Main>
|
||||||
visible={visible}
|
|
||||||
setVisible={setVisible}
|
|
||||||
text={text}
|
|
||||||
></Main>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -134,6 +78,6 @@ function App() {
|
|||||||
</Route>
|
</Route>
|
||||||
</Switch>
|
</Switch>
|
||||||
);
|
);
|
||||||
}
|
};
|
||||||
|
|
||||||
export default App;
|
export default App;
|
||||||
|
|||||||
@@ -8,12 +8,15 @@ import React, { useState, useEffect } from "react";
|
|||||||
export const ControlPanel: React.FC<any> = ({
|
export const ControlPanel: React.FC<any> = ({
|
||||||
handleOpenSharePopup,
|
handleOpenSharePopup,
|
||||||
handleOpenExitPopup,
|
handleOpenExitPopup,
|
||||||
|
handleMuteClick,
|
||||||
|
isMuted
|
||||||
}) => {
|
}) => {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="toolbar-field-part">
|
<div className="toolbar-field-part">
|
||||||
<div className="toolbar-button-container-border-line"></div>
|
<div className="toolbar-button-container-border-line"></div>
|
||||||
<ControlButton onClick={() => console.log("click!")}></ControlButton>
|
<ControlButton onClick={() => console.log("click!")}></ControlButton>
|
||||||
<MicroButton></MicroButton>
|
<MicroButton isMuted={isMuted} onClick={handleMuteClick}></MicroButton>
|
||||||
<div className="toolbar-button-container-border-line"></div>
|
<div className="toolbar-button-container-border-line"></div>
|
||||||
<ShareButton onClick={handleOpenSharePopup}></ShareButton>
|
<ShareButton onClick={handleOpenSharePopup}></ShareButton>
|
||||||
<LanguageButton onClick={() => console.log("click!")}></LanguageButton>
|
<LanguageButton onClick={() => console.log("click!")}></LanguageButton>
|
||||||
|
|||||||
@@ -1,19 +1,36 @@
|
|||||||
import '../PopupShare/sharePopup.css'
|
import "../PopupShare/sharePopup.css";
|
||||||
import './ExitPopup.css'
|
import "./ExitPopup.css";
|
||||||
import { TSidebarPopup } from '../../utils/types'
|
import { TSidebarPopup } from "../../utils/types";
|
||||||
|
import { useTranslation } from "react-i18next";
|
||||||
|
|
||||||
export const ExitPopup: React.FC<TSidebarPopup> = ({ setClose, onExit }) => {
|
export const ExitPopup: React.FC<TSidebarPopup> = ({ setClose, onExit }) => {
|
||||||
|
const { t } = useTranslation();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='exit-popup-container'>
|
<div className="exit-popup-container">
|
||||||
<div className='mobile-users-part-header exit-popup-header'>
|
<div className="mobile-users-part-header exit-popup-header">
|
||||||
<span className='mobile-users-part-header-title exit-popup-button-title'>Вы уверены, что хотите закончить демонстрацию?</span>
|
<span className="mobile-users-part-header-title exit-popup-button-title">
|
||||||
<button onClick={() => setClose()} className='mobile-users-part-header-close-button'></button>
|
{t("popup-control-exit-title")}
|
||||||
</div>
|
</span>
|
||||||
<div className='exit-popup-button-container'>
|
<button
|
||||||
<button onClick={() => setClose()} className='exit-popup-button exit-popup-button_confirm'>Остаться</button>
|
onClick={() => setClose()}
|
||||||
<button onClick={() => onExit?.()} className='exit-popup-button exit-popup-button_finish'>Закончить</button>
|
className="mobile-users-part-header-close-button"
|
||||||
</div>
|
></button>
|
||||||
</div>
|
</div>
|
||||||
)
|
<div className="exit-popup-button-container">
|
||||||
}
|
<button
|
||||||
|
onClick={() => setClose()}
|
||||||
|
className="exit-popup-button exit-popup-button_confirm"
|
||||||
|
>
|
||||||
|
{t("popup-control-no")}
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
onClick={() => onExit?.()}
|
||||||
|
className="exit-popup-button exit-popup-button_finish"
|
||||||
|
>
|
||||||
|
{t("popup-control-yes")}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|||||||
@@ -1,12 +1,38 @@
|
|||||||
import '../sidebar/toolbar.css'
|
import "../sidebar/toolbar.css";
|
||||||
|
import { languageSlice } from "../../store/reducers/languageSlice";
|
||||||
|
import { useAppDispatch, useAppSelector } from "../../hooks/redux";
|
||||||
|
|
||||||
export const LanguagePopup: React.FC<any> = ({ setOpen}) => {
|
export const LanguagePopup: React.FC<any> = ({ setOpen }) => {
|
||||||
return (<div className="toolbar-language-popup">
|
const { handleChangeLanguage } = languageSlice.actions;
|
||||||
<div className='toolbar-button-area '>
|
|
||||||
<button onClick={() => setOpen(false)} className='toolbar-button toolbar-button.language.ru'>RU</button>
|
const buttons = [{ value: "ru" }, { value: "en" }];
|
||||||
|
const dispatch = useAppDispatch();
|
||||||
|
|
||||||
|
const onChange = (value: string) => {
|
||||||
|
dispatch(handleChangeLanguage(value));
|
||||||
|
setOpen(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
const { currentLang } = useAppSelector((state) => state.languageReducer);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="toolbar-language-popup">
|
||||||
|
{buttons.map((i) => (
|
||||||
|
<div className="toolbar-button-area">
|
||||||
|
<button
|
||||||
|
key={i.value}
|
||||||
|
value={i.value}
|
||||||
|
onClick={(e: any) => onChange(e.target.value)}
|
||||||
|
className={
|
||||||
|
currentLang === i.value
|
||||||
|
? "toolbar-button toolbar-button-active"
|
||||||
|
: "toolbar-button"
|
||||||
|
}
|
||||||
|
>
|
||||||
|
{i.value.toUpperCase()}
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div className='toolbar-button-area '>
|
))}
|
||||||
<button onClick={() => setOpen(false)} className='toolbar-button toolbar-button.language.en'>EN</button>
|
</div>
|
||||||
</div>
|
);
|
||||||
</div>)
|
};
|
||||||
}
|
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ import {
|
|||||||
connectSession,
|
connectSession,
|
||||||
} from "../../store/reducers/ActionCreator";
|
} from "../../store/reducers/ActionCreator";
|
||||||
|
|
||||||
export const Main: React.FC<any> = ({ text, visible, setVisible }) => {
|
export const Main: React.FC<any> = ({ visible, setVisible }) => {
|
||||||
const [value, setValue] = useState<string>("");
|
const [value, setValue] = useState<string>("");
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
const { popup1, popup2 } = visible;
|
const { popup1, popup2 } = visible;
|
||||||
@@ -33,7 +33,6 @@ export const Main: React.FC<any> = ({ text, visible, setVisible }) => {
|
|||||||
isLoading={isLoading}
|
isLoading={isLoading}
|
||||||
logo={currentCard?.image.logo}
|
logo={currentCard?.image.logo}
|
||||||
onConnect={() => dispatch(createSession(currentCard.title))}
|
onConnect={() => dispatch(createSession(currentCard.title))}
|
||||||
text={text.popupConnect}
|
|
||||||
visible={visible}
|
visible={visible}
|
||||||
setVisible={setVisible}
|
setVisible={setVisible}
|
||||||
></PopupConnect>
|
></PopupConnect>
|
||||||
@@ -55,7 +54,6 @@ export const Main: React.FC<any> = ({ text, visible, setVisible }) => {
|
|||||||
onConnect={() => dispatch(connectSession(value))}
|
onConnect={() => dispatch(connectSession(value))}
|
||||||
visible={visible}
|
visible={visible}
|
||||||
setVisible={setVisible}
|
setVisible={setVisible}
|
||||||
text={text.popupConnectEx}
|
|
||||||
></PopupConnectEx>
|
></PopupConnectEx>
|
||||||
</motion.div>
|
</motion.div>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import './sharePopup.css'
|
import './sharePopup.css'
|
||||||
import { useState, useEffect } from 'react'
|
import { useState, useEffect } from 'react'
|
||||||
import { TSidebarPopup } from '../../utils/types'
|
import { TSidebarPopup } from '../../utils/types'
|
||||||
|
import { useTranslation } from 'react-i18next'
|
||||||
|
|
||||||
export const PopupShare: React.FC<any> = ({ setClose, data }) => {
|
export const PopupShare: React.FC<any> = ({ setClose, data }) => {
|
||||||
const [copy, setCopy] = useState(false)
|
const [copy, setCopy] = useState(false)
|
||||||
@@ -19,26 +20,28 @@ export const PopupShare: React.FC<any> = ({ setClose, data }) => {
|
|||||||
|
|
||||||
useEffect(() => () => setCopy(false), []);
|
useEffect(() => () => setCopy(false), []);
|
||||||
|
|
||||||
|
const {t} = useTranslation();
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='share-popup-container'>
|
<div className='share-popup-container'>
|
||||||
<div className='mobile-users-part-header share-header-popup'>
|
<div className='mobile-users-part-header share-header-popup'>
|
||||||
<span className='mobile-users-part-header-title'>Пригласить на демонстрацию</span>
|
<span className='mobile-users-part-header-title'>{t('popup-control-invite-title')}</span>
|
||||||
<button onClick={closePopup} className='mobile-users-part-header-close-button'></button>
|
<button onClick={closePopup} className='mobile-users-part-header-close-button'></button>
|
||||||
</div>
|
</div>
|
||||||
<div className='share-popup-data-container'>
|
<div className='share-popup-data-container'>
|
||||||
<span className='share-popup-data-title'>Код подключения</span>
|
<span className='share-popup-data-title'>{t('popup-control-code')}</span>
|
||||||
<input className='share-popup-data-input share-popup-data-input code' value={data.connection_code} readOnly></input>
|
<input className='share-popup-data-input share-popup-data-input code' value={data.connection_code} readOnly></input>
|
||||||
</div>
|
</div>
|
||||||
<div className='border-line'></div>
|
<div className='border-line'></div>
|
||||||
<div className='share-popup-data-container'>
|
<div className='share-popup-data-container'>
|
||||||
<span className='share-popup-data-title'>Ссылка для подключения</span>
|
<span className='share-popup-data-title'>{t('popup-control-link')}</span>
|
||||||
<input className='share-popup-data-input href' value={window.location.href} readOnly></input>
|
<input className='share-popup-data-input href' value={window.location.href} readOnly></input>
|
||||||
</div>
|
</div>
|
||||||
<div className='share-popup-data-container'>
|
<div className='share-popup-data-container'>
|
||||||
<button className='share-popup-copy-button '>
|
<button className='share-popup-copy-button '>
|
||||||
<span className='share-popup-copy-button-icon'></span>
|
<span className='share-popup-copy-button-icon'></span>
|
||||||
<span onClick={copyLink} className='share-popup-copy-button-title'>{copy ? 'Скопировано' : 'Скопировать'}</span>
|
<span onClick={copyLink} className='share-popup-copy-button-title'>{copy ? t('popup-control-btn-active') : t('popup-control-btn')}</span>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -139,7 +139,11 @@
|
|||||||
|
|
||||||
@media screen and (min-width: 1600px) {
|
@media screen and (min-width: 1600px) {
|
||||||
.demo__icon {
|
.demo__icon {
|
||||||
top: 57%;
|
top: 56%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.demo_image {
|
||||||
|
height: 360px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.title__demo {
|
.title__demo {
|
||||||
@@ -157,6 +161,14 @@
|
|||||||
.caption2 {
|
.caption2 {
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.demo {
|
||||||
|
height: 700px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.demo__container {
|
||||||
|
gap: 30px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media screen and (max-width: 1279px) {
|
@media screen and (max-width: 1279px) {
|
||||||
@@ -202,6 +214,10 @@
|
|||||||
gap: 12px;
|
gap: 12px;
|
||||||
padding: 24px;
|
padding: 24px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.demo {
|
||||||
|
height: 434px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media screen and (max-width: 1024px) {
|
@media screen and (max-width: 1024px) {
|
||||||
@@ -256,6 +272,9 @@
|
|||||||
.demos__tittle {
|
.demos__tittle {
|
||||||
font-size: 28px;
|
font-size: 28px;
|
||||||
width: 300px;
|
width: 300px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.demo {
|
||||||
|
height: 436px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,9 +3,12 @@ import "../../styles/styles.css";
|
|||||||
import building1 from "./building1.png";
|
import building1 from "./building1.png";
|
||||||
import iconButton from "./iconButton.svg";
|
import iconButton from "./iconButton.svg";
|
||||||
import { Link } from "react-router-dom";
|
import { Link } from "react-router-dom";
|
||||||
|
import { useAppSelector } from "../../hooks/redux";
|
||||||
|
|
||||||
export const Demos: React.FC<any> = ({ item, onClick }) => {
|
export const Demos: React.FC<any> = ({ item, onClick }) => {
|
||||||
console.log(item)
|
const { currentLang } = useAppSelector((state) => state.languageReducer);
|
||||||
|
|
||||||
|
console.log(currentLang);
|
||||||
return (
|
return (
|
||||||
<div onClick={() => onClick()} className="main-block__container">
|
<div onClick={() => onClick()} className="main-block__container">
|
||||||
<div className="demos_container">
|
<div className="demos_container">
|
||||||
@@ -20,13 +23,27 @@ export const Demos: React.FC<any> = ({ item, onClick }) => {
|
|||||||
></img>
|
></img>
|
||||||
<div className="demo_info">
|
<div className="demo_info">
|
||||||
<div className="title__block">
|
<div className="title__block">
|
||||||
<h4 className="title__demo">{item.title_full.ru}</h4>
|
<h4 className="title__demo">
|
||||||
|
{currentLang === "ru" ? item.title_full.ru : item.title_full.en}
|
||||||
|
</h4>
|
||||||
<p className="caption">{item.location.ru}</p>
|
<p className="caption">{item.location.ru}</p>
|
||||||
</div>
|
</div>
|
||||||
<div className="body__block">
|
<div className="body__block">
|
||||||
<div className="description__container">
|
<div className="description__container">
|
||||||
<p className="caption1">{item.description.ru}</p>
|
<p className="caption1">
|
||||||
{item.description_second ? <p className="caption">{item.description_second.ru}</p> : <></>}
|
{currentLang === "ru"
|
||||||
|
? item.description.ru
|
||||||
|
: item.description.en}
|
||||||
|
</p>
|
||||||
|
{item.description_second ? (
|
||||||
|
<p className="caption">
|
||||||
|
{currentLang === "ru"
|
||||||
|
? item.description_second.ru
|
||||||
|
: item.description_second.en}
|
||||||
|
</p>
|
||||||
|
) : (
|
||||||
|
<></>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -4,81 +4,118 @@ import chevron from "./chevronIcon.svg";
|
|||||||
import "./header.css";
|
import "./header.css";
|
||||||
import "../../styles/styles.css";
|
import "../../styles/styles.css";
|
||||||
import { useLocation } from "react-router-dom";
|
import { useLocation } from "react-router-dom";
|
||||||
|
import { useAppSelector, useAppDispatch } from "../../hooks/redux";
|
||||||
|
import { languageSlice } from "../../store/reducers/languageSlice";
|
||||||
|
|
||||||
export type THeader = {
|
export type THeader = {
|
||||||
language: string;
|
language: string;
|
||||||
changeLanguage: (language: string) => void;
|
changeLanguage: (language: string) => void;
|
||||||
text?: any;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export const Header: React.FC<THeader> =
|
export const Header: React.FC = ({}) => {
|
||||||
({ changeLanguage, language, text }) => {
|
const [open, setOpen] = useState<boolean>(false);
|
||||||
const [open, setOpen] = useState<boolean>(false)
|
const [menuOpen, setMenuOpen] = useState(false);
|
||||||
const [menuOpen, setMenuOpen] = useState(false)
|
const [opacity, setOpacity] = useState(false);
|
||||||
const [opacity, setOpacity] = useState(false)
|
const location = useLocation();
|
||||||
const userLanguage = language === 'RU';
|
|
||||||
const location = useLocation()
|
|
||||||
console.log(location)
|
|
||||||
|
|
||||||
|
const { handleChangeLanguage } = languageSlice.actions;
|
||||||
|
const { currentLang } = useAppSelector((state) => state.languageReducer);
|
||||||
|
const dispatch = useAppDispatch();
|
||||||
|
|
||||||
function handleUpdateLanguage(value: string) {
|
function handleUpdateLanguage(value: string) {
|
||||||
changeLanguage(value)
|
dispatch(handleChangeLanguage(value));
|
||||||
setOpen(prev => !prev)
|
setOpen((prev) => !prev);
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleOpen() {
|
function handleOpen() {
|
||||||
setOpen(prev => !prev)
|
setOpen((prev) => !prev);
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleOpacity() {
|
function handleOpacity() {
|
||||||
setOpacity(true)
|
setOpacity(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
const style = {
|
const style = {
|
||||||
background: 'rgba(235, 235, 235, 0.2'
|
background: "rgba(235, 235, 235, 0.2",
|
||||||
};
|
};
|
||||||
|
|
||||||
const iconTransform = {
|
const iconTransform = {
|
||||||
transform: 'rotate(-90deg)'
|
transform: "rotate(-90deg)",
|
||||||
} as CSSProperties
|
} as CSSProperties;
|
||||||
|
|
||||||
const setBackground = opacity && !open as boolean;
|
const setBackground = opacity && (!open as boolean);
|
||||||
|
|
||||||
function setOpacityAndMenu() {
|
function setOpacityAndMenu() {
|
||||||
setMenuOpen(true)
|
setMenuOpen(true);
|
||||||
const targetElement = document.querySelector('body') as HTMLElement
|
const targetElement = document.querySelector("body") as HTMLElement;
|
||||||
targetElement.style.overflow = 'hidden'
|
targetElement.style.overflow = "hidden";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function openMenu() {
|
||||||
|
setMenuOpen(false);
|
||||||
|
const targetElement = document.querySelector("body") as HTMLElement;
|
||||||
|
targetElement.style.overflow = "visible";
|
||||||
|
}
|
||||||
|
|
||||||
function openMenu() {
|
return (
|
||||||
setMenuOpen(false)
|
<div
|
||||||
const targetElement = document.querySelector('body') as HTMLElement
|
className={
|
||||||
targetElement.style.overflow = 'visible'
|
location.pathname === "connect-page" ? "header" : "header-main"
|
||||||
|
}
|
||||||
}
|
>
|
||||||
|
<div className="header-container">
|
||||||
return (
|
<img className="header-logo" alt="company-logo" src={logo} />
|
||||||
<div className={location.pathname === 'connect-page' ? 'header' : 'header-main'}>
|
<div className="header-buttons">
|
||||||
<div className="header-container">
|
<div
|
||||||
<img className="header-logo" alt="company-logo" src={logo} />
|
className={
|
||||||
<div className="header-buttons">
|
open
|
||||||
<div className={open ? "header-lang-button header-lang-button_active" : 'header-lang-button header-lang-button_disabled'} style={setBackground ? style : { background: 'transparent' }}>
|
? "header-lang-button header-lang-button_active"
|
||||||
<img alt="img" src={chevron} className="header-select__icon" style={open ? iconTransform : {
|
: "header-lang-button header-lang-button_disabled"
|
||||||
transform: 'rotate(0deg)'
|
}
|
||||||
}}></img>
|
style={setBackground ? style : { background: "transparent" }}
|
||||||
<div className="wrapper__button">
|
>
|
||||||
<div onMouseEnter={handleOpacity} onMouseLeave={() => setOpacity(false)} onClick={handleOpen} className=" header-lang-button-picked">{language}</div>
|
<img
|
||||||
|
alt="img"
|
||||||
|
src={chevron}
|
||||||
|
className="header-select__icon"
|
||||||
|
style={
|
||||||
|
open
|
||||||
|
? iconTransform
|
||||||
|
: {
|
||||||
|
transform: "rotate(0deg)",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
></img>
|
||||||
|
<div className="wrapper__button">
|
||||||
|
<div
|
||||||
|
onMouseEnter={handleOpacity}
|
||||||
|
onMouseLeave={() => setOpacity(false)}
|
||||||
|
onClick={handleOpen}
|
||||||
|
className=" header-lang-button-picked"
|
||||||
|
>
|
||||||
|
{currentLang.toLocaleUpperCase()}
|
||||||
</div>
|
</div>
|
||||||
{language === 'RU' ? (<button value={'EN'} onClick={(e: any) => handleUpdateLanguage(e.target.value)} className="header-lang-button-text">EN</button>
|
|
||||||
) : (<button onClick={(e: any) => handleUpdateLanguage(e.target.value)} value={'RU'} className="header-lang-button-text">RU</button>)}
|
|
||||||
</div>
|
</div>
|
||||||
|
{currentLang === "ru" ? (
|
||||||
|
<button
|
||||||
|
value={"en"}
|
||||||
|
onClick={(e: any) => handleUpdateLanguage(e.target.value)}
|
||||||
|
className="header-lang-button-text"
|
||||||
|
>
|
||||||
|
EN
|
||||||
|
</button>
|
||||||
|
) : (
|
||||||
|
<button
|
||||||
|
onClick={(e: any) => handleUpdateLanguage(e.target.value)}
|
||||||
|
value={"ru"}
|
||||||
|
className="header-lang-button-text"
|
||||||
|
>
|
||||||
|
RU
|
||||||
|
</button>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
);
|
);
|
||||||
}
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,22 +1,18 @@
|
|||||||
import { useHistory } from "react-router-dom";
|
import { useHistory } from "react-router-dom";
|
||||||
import { useAppSelector } from "../../hooks/redux";
|
|
||||||
import "../../styles/styles.css";
|
import "../../styles/styles.css";
|
||||||
import { PayloadAction } from "@reduxjs/toolkit";
|
import { useTranslation } from "react-i18next";
|
||||||
import { IData } from "../../models/IData";
|
|
||||||
import { sessionState } from "../../store/reducers/sessionSlice";
|
|
||||||
|
|
||||||
export const PopupConnect: React.FC<any> = ({
|
export const PopupConnect: React.FC<any> = ({
|
||||||
setVisible,
|
setVisible,
|
||||||
text,
|
|
||||||
onConnect,
|
onConnect,
|
||||||
logo,
|
logo,
|
||||||
isLoading
|
isLoading,
|
||||||
}) => {
|
}) => {
|
||||||
const history = useHistory();
|
const history = useHistory();
|
||||||
|
const { t } = useTranslation();
|
||||||
|
|
||||||
const handleConnect = () => {
|
const handleConnect = () => {
|
||||||
onConnect().then((res: any) => {
|
onConnect().then((res: any) => {
|
||||||
console.log(res);
|
|
||||||
if (!res.error) {
|
if (!res.error) {
|
||||||
history.push(`/stream/${res.payload.connection_code}`);
|
history.push(`/stream/${res.payload.connection_code}`);
|
||||||
} else {
|
} else {
|
||||||
@@ -30,18 +26,18 @@ export const PopupConnect: React.FC<any> = ({
|
|||||||
<img alt="logoRC" className="logo__popup" src={logo}></img>
|
<img alt="logoRC" className="logo__popup" src={logo}></img>
|
||||||
<div className="popup">
|
<div className="popup">
|
||||||
<div className="button__container">
|
<div className="button__container">
|
||||||
<p className="button__title">{text.caption} </p>
|
<p className="button__title">{t("popup-main-title")} </p>
|
||||||
<button
|
<button
|
||||||
disabled={isLoading}
|
disabled={isLoading}
|
||||||
onClick={handleConnect}
|
onClick={handleConnect}
|
||||||
className="button"
|
className="button"
|
||||||
>
|
>
|
||||||
{text.button.connectEx}
|
{t("popup-main-btn-start")}
|
||||||
</button>
|
</button>
|
||||||
<span className="line"></span>
|
<span className="line"></span>
|
||||||
</div>
|
</div>
|
||||||
<div className="button__container">
|
<div className="button__container">
|
||||||
<p className="button__title">{text.caption1} </p>
|
<p className="button__title">{t("popup-main-caption")} </p>
|
||||||
<button
|
<button
|
||||||
className="button button__disabled"
|
className="button button__disabled"
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
@@ -51,11 +47,11 @@ export const PopupConnect: React.FC<any> = ({
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
{text.button.connectNew}
|
{t("popup-main-btn-connect")}
|
||||||
</button>
|
</button>
|
||||||
<span className="line"></span>
|
<span className="line"></span>
|
||||||
<button onClick={() => history.goBack()} className="popup__caption">
|
<button onClick={() => history.goBack()} className="popup__caption">
|
||||||
{text.caption2}
|
{t("popup-main-select")}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
import "../../styles/styles.css";
|
import "../../styles/styles.css";
|
||||||
import "./popupConnect.css";
|
import "./popupConnect.css";
|
||||||
import { useHistory } from "react-router-dom";
|
import { useHistory } from "react-router-dom";
|
||||||
|
import { useTranslation } from "react-i18next";
|
||||||
|
|
||||||
export const PopupConnectEx: React.FC<any> = ({
|
export const PopupConnectEx: React.FC<any> = ({
|
||||||
setVisible,
|
setVisible,
|
||||||
text,
|
|
||||||
onConnect,
|
onConnect,
|
||||||
logo,
|
logo,
|
||||||
setValue,
|
setValue,
|
||||||
@@ -12,6 +12,7 @@ export const PopupConnectEx: React.FC<any> = ({
|
|||||||
isLoading,
|
isLoading,
|
||||||
}) => {
|
}) => {
|
||||||
const history = useHistory();
|
const history = useHistory();
|
||||||
|
const { t } = useTranslation();
|
||||||
|
|
||||||
const handleConnect = () => {
|
const handleConnect = () => {
|
||||||
onConnect().then((res: any) => {
|
onConnect().then((res: any) => {
|
||||||
@@ -28,7 +29,7 @@ export const PopupConnectEx: React.FC<any> = ({
|
|||||||
<div className="popup__container">
|
<div className="popup__container">
|
||||||
<div className="popup__content">
|
<div className="popup__content">
|
||||||
<img alt="logoRC" className="logo__popup_ex" src={logo}></img>
|
<img alt="logoRC" className="logo__popup_ex" src={logo}></img>
|
||||||
<p className="popup__title">{text.caption}</p>
|
<p className="popup__title">{t("popup-connect-title")}</p>
|
||||||
<input
|
<input
|
||||||
value={value}
|
value={value}
|
||||||
onChange={(e) => setValue(e.target.value)}
|
onChange={(e) => setValue(e.target.value)}
|
||||||
@@ -42,7 +43,7 @@ export const PopupConnectEx: React.FC<any> = ({
|
|||||||
!!value || isLoading ? "button" : "button button__disabled"
|
!!value || isLoading ? "button" : "button button__disabled"
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
{text.button}
|
{t("popup-connect-btn-continue")}
|
||||||
</button>
|
</button>
|
||||||
<span className="line"></span>
|
<span className="line"></span>
|
||||||
<button
|
<button
|
||||||
@@ -54,7 +55,7 @@ export const PopupConnectEx: React.FC<any> = ({
|
|||||||
}
|
}
|
||||||
className="popup__caption"
|
className="popup__caption"
|
||||||
>
|
>
|
||||||
{text.caption1}
|
{t("popup-connect-btn-mode")}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import "./toolbar.css";
|
import "./toolbar.css";
|
||||||
import React, { useState, useEffect, useCallback } from "react";
|
import React, { useState, useEffect } from "react";
|
||||||
import { UserList } from "../UserList/UserList";
|
import { UserList } from "../UserList/UserList";
|
||||||
import { FullscreenButton } from "../ui/FullscreenButton/FullscreenButton";
|
import { FullscreenButton } from "../ui/FullscreenButton/FullscreenButton";
|
||||||
import { PopupShare } from "../PopupShare/PopupShare";
|
import { PopupShare } from "../PopupShare/PopupShare";
|
||||||
@@ -8,7 +8,6 @@ import { ControlPanel } from "../ControlPanel/ControlPanel";
|
|||||||
import { AnimatePresence, motion } from "framer-motion";
|
import { AnimatePresence, motion } from "framer-motion";
|
||||||
import { sidebarVariants, popupAnimation } from "../../utils/animationProps";
|
import { sidebarVariants, popupAnimation } from "../../utils/animationProps";
|
||||||
|
|
||||||
|
|
||||||
type link = {
|
type link = {
|
||||||
id: string;
|
id: string;
|
||||||
};
|
};
|
||||||
@@ -16,29 +15,22 @@ const userLocal = {
|
|||||||
id: Math.floor(Math.random() * 100),
|
id: Math.floor(Math.random() * 100),
|
||||||
};
|
};
|
||||||
|
|
||||||
export const Sidebar: React.FC<any> = ({
|
export const Sidebar: React.FC<any> = ({ closeStream, data }) => {
|
||||||
closeStream,
|
|
||||||
data,
|
|
||||||
}) => {
|
|
||||||
const [open, setOpen] = useState(true);
|
const [open, setOpen] = useState(true);
|
||||||
const [popup, setPopup] = useState({
|
const [popup, setPopup] = useState({
|
||||||
popup1: false,
|
popup1: false,
|
||||||
popup2: false,
|
popup2: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const [selected, setSelected] = useState(false);
|
const [selected, setSelected] = useState(false);
|
||||||
const [icon, setIcon] = useState("");
|
const [icon, setIcon] = useState("");
|
||||||
|
|
||||||
const [isMuted, setMuted] = useState(true);
|
const [isMuted, setMuted] = useState(true);
|
||||||
|
|
||||||
|
|
||||||
const handleMuteClick = () => {
|
const handleMuteClick = () => {
|
||||||
setMuted((prev) => !prev);
|
setMuted((prev) => !prev);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
function handleClosePopups() {
|
function handleClosePopups() {
|
||||||
setPopup({
|
setPopup({
|
||||||
popup1: false,
|
popup1: false,
|
||||||
@@ -65,7 +57,6 @@ export const Sidebar: React.FC<any> = ({
|
|||||||
setSelected(false);
|
setSelected(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
useEffect(() => () => unmountComponent(), []);
|
useEffect(() => () => unmountComponent(), []);
|
||||||
|
|
||||||
function unmountComponent() {
|
function unmountComponent() {
|
||||||
@@ -77,7 +68,6 @@ export const Sidebar: React.FC<any> = ({
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<motion.div
|
<motion.div
|
||||||
@@ -88,12 +78,11 @@ export const Sidebar: React.FC<any> = ({
|
|||||||
<div className="toolbar-field">
|
<div className="toolbar-field">
|
||||||
<div className="toolbar-field-part">
|
<div className="toolbar-field-part">
|
||||||
<FullscreenButton></FullscreenButton>
|
<FullscreenButton></FullscreenButton>
|
||||||
<UserList
|
<UserList selected={selected} setSelected={setSelected}></UserList>
|
||||||
selected={selected}
|
|
||||||
setSelected={setSelected}
|
|
||||||
></UserList>
|
|
||||||
</div>
|
</div>
|
||||||
<ControlPanel
|
<ControlPanel
|
||||||
|
isMuted={isMuted}
|
||||||
|
handleMuteClick={handleMuteClick}
|
||||||
handleOpenSharePopup={handleOpenSharePopup}
|
handleOpenSharePopup={handleOpenSharePopup}
|
||||||
handleOpenExitPopup={handleOpenExitPopup}
|
handleOpenExitPopup={handleOpenExitPopup}
|
||||||
></ControlPanel>
|
></ControlPanel>
|
||||||
|
|||||||
@@ -151,6 +151,10 @@
|
|||||||
padding: 0px;
|
padding: 0px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.toolbar-button-active {
|
||||||
|
background: #567ece;
|
||||||
|
}
|
||||||
|
|
||||||
.user-icon {
|
.user-icon {
|
||||||
position: relative;
|
position: relative;
|
||||||
width: 40px;
|
width: 40px;
|
||||||
|
|||||||
@@ -8,8 +8,8 @@ export const ControlButton: React.FC<THOC> = ({ onClick }) => {
|
|||||||
const [active, setActive] = useState(false);
|
const [active, setActive] = useState(false);
|
||||||
const button = {
|
const button = {
|
||||||
icon: control,
|
icon: control,
|
||||||
active: "Запрет управления",
|
active: "request-control-btn",
|
||||||
inactive: "Запрос управления",
|
inactive: "request-control-btn-disable",
|
||||||
type: "control",
|
type: "control",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -7,8 +7,8 @@ export const ExitButton: React.FC<THOC> = ({ onClick }) => {
|
|||||||
const [active, setActive] = useState(false);
|
const [active, setActive] = useState(false);
|
||||||
const button = {
|
const button = {
|
||||||
icon: exit,
|
icon: exit,
|
||||||
active: "Завершить презентацию",
|
active: "exit-control-btn",
|
||||||
inactive: "Завершить презентацию",
|
inactive: "exit-control-btn",
|
||||||
type: "exit",
|
type: "exit",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -3,43 +3,40 @@ import { Button } from "../button/button";
|
|||||||
import fullscreen from "../../../images/icons/fullscreen.svg";
|
import fullscreen from "../../../images/icons/fullscreen.svg";
|
||||||
import fullscreenOff from "../../../images/icons/fullscreenOff.svg";
|
import fullscreenOff from "../../../images/icons/fullscreenOff.svg";
|
||||||
|
|
||||||
|
export const FullscreenButton = ({}) => {
|
||||||
export const FullscreenButton = ({ }) => {
|
|
||||||
const [active, setActive] = useState(false);
|
const [active, setActive] = useState(false);
|
||||||
const [button, setButton] = useState({
|
const [button, setButton] = useState({
|
||||||
icon: fullscreen,
|
icon: fullscreen,
|
||||||
active: "Развернуть",
|
inactive: "fullscreen-control-btn",
|
||||||
inactive: "Свернуть",
|
active: "fullscreen-control-btn-active",
|
||||||
type: "fullscreen",
|
type: "fullscreen",
|
||||||
|
});
|
||||||
})
|
|
||||||
|
|
||||||
function handleClick() {
|
function handleClick() {
|
||||||
setActive((prev) => !prev);
|
setActive((prev) => !prev);
|
||||||
setButton({
|
setButton({
|
||||||
icon: active ? fullscreen : fullscreenOff,
|
icon: active ? fullscreen : fullscreenOff,
|
||||||
active: "Развернуть",
|
inactive: "fullscreen-control-btn",
|
||||||
inactive: "Свернуть",
|
active: "fullscreen-control-btn-active",
|
||||||
type: "fullscreen",
|
type: "fullscreen",
|
||||||
})
|
});
|
||||||
|
|
||||||
if (active) {
|
if (active) {
|
||||||
document.exitFullscreen()
|
document.exitFullscreen();
|
||||||
} else {
|
} else {
|
||||||
document.body.requestFullscreen()
|
document.body.requestFullscreen();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
return () => {
|
return () => {
|
||||||
document.exitFullscreen()
|
document.exitFullscreen();
|
||||||
}
|
};
|
||||||
}, [])
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="toolbar-button-area">
|
<div className="toolbar-button-area">
|
||||||
<Button button={button} active={active} onClick={handleClick}></Button>
|
<Button button={button} active={active} onClick={handleClick}></Button>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -6,33 +6,31 @@ import { AnimatePresence, motion } from "framer-motion";
|
|||||||
const container = {
|
const container = {
|
||||||
hidden: {
|
hidden: {
|
||||||
opacity: 0,
|
opacity: 0,
|
||||||
transition: { duration: 0.2, ease: 'easeOut' }
|
transition: { duration: 0.2, ease: "easeOut" },
|
||||||
},
|
},
|
||||||
show: {
|
show: {
|
||||||
opacity: 1,
|
opacity: 1,
|
||||||
transition: { delay: 0.15, duration: 0.2, ease: 'easeIn' },
|
transition: { delay: 0.15, duration: 0.2, ease: "easeIn" },
|
||||||
},
|
},
|
||||||
exit: {
|
exit: {
|
||||||
opacity: 0,
|
opacity: 0,
|
||||||
transition: { duration: 0.2, ease: 'easeOut' }
|
transition: { duration: 0.2, ease: "easeOut" },
|
||||||
}
|
},
|
||||||
}
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
export const LanguageButton: React.FC<any> = ({ hover, setHover }) => {
|
export const LanguageButton: React.FC<any> = ({ hover, setHover }) => {
|
||||||
const [active, setActive] = useState(false);
|
const [active, setActive] = useState(false);
|
||||||
const [open, setOpen] = useState(false)
|
const [open, setOpen] = useState(false);
|
||||||
|
|
||||||
const button = {
|
const button = {
|
||||||
icon: microOn,
|
icon: microOn,
|
||||||
active: "Язык",
|
active: "language-control-btn",
|
||||||
inactive: "Язык",
|
inactive: "language-control-btn",
|
||||||
type: "language",
|
type: "language",
|
||||||
};
|
};
|
||||||
|
|
||||||
function handleClick() {
|
function handleClick() {
|
||||||
setOpen(true)
|
setOpen(true);
|
||||||
setActive((prev) => !prev);
|
setActive((prev) => !prev);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -40,14 +38,17 @@ export const LanguageButton: React.FC<any> = ({ hover, setHover }) => {
|
|||||||
<div className="toolbar-button-area">
|
<div className="toolbar-button-area">
|
||||||
<Button button={button} onClick={handleClick}></Button>
|
<Button button={button} onClick={handleClick}></Button>
|
||||||
<AnimatePresence>
|
<AnimatePresence>
|
||||||
{open && (<motion.div
|
{open && (
|
||||||
variants={container}
|
<motion.div
|
||||||
initial={'hidden'}
|
variants={container}
|
||||||
animate={'show'}
|
initial={"hidden"}
|
||||||
exit={'hidden'}>
|
animate={"show"}
|
||||||
<LanguagePopup setOpen={setOpen}></LanguagePopup>
|
exit={"hidden"}
|
||||||
</motion.div>)}
|
>
|
||||||
|
<LanguagePopup setOpen={setOpen}></LanguagePopup>
|
||||||
|
</motion.div>
|
||||||
|
)}
|
||||||
</AnimatePresence>
|
</AnimatePresence>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,23 +1,22 @@
|
|||||||
import { useState } from "react";
|
|
||||||
import { Button } from "../button/button";
|
import { Button } from "../button/button";
|
||||||
import microOn from "../../../images/icons/MicroOn.svg";
|
import microOn from "../../../images/icons/MicroOn.svg";
|
||||||
import { THOC } from "../../../utils/types";
|
|
||||||
|
|
||||||
export const MicroButton: React.FC<any> = ({ onClick, isMuted }) => {
|
export const MicroButton: React.FC<any> = ({
|
||||||
|
onClick,
|
||||||
|
isMuted,
|
||||||
|
translation,
|
||||||
|
}) => {
|
||||||
const button = {
|
const button = {
|
||||||
icon: microOn,
|
icon: microOn,
|
||||||
active: "Включить микрофон",
|
active: "mute-control-btn",
|
||||||
inactive: "Выключить микрофон",
|
inactive: "mute-control-btn-disable",
|
||||||
type: "microphone",
|
type: "microphone",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function handleClick() {
|
function handleClick() {
|
||||||
onClick()
|
onClick();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="toolbar-button-area">
|
<div className="toolbar-button-area">
|
||||||
<Button button={button} active={isMuted} onClick={handleClick}></Button>
|
<Button button={button} active={isMuted} onClick={handleClick}></Button>
|
||||||
|
|||||||
@@ -6,8 +6,8 @@ export const ShareButton: React.FC<any> = ({ onClick }) => {
|
|||||||
|
|
||||||
const button = {
|
const button = {
|
||||||
icon: share,
|
icon: share,
|
||||||
active: "Поделиться",
|
active: "share-contro-btn",
|
||||||
inactive: "Поделиться",
|
inactive: "share-contro-btn",
|
||||||
type: "share",
|
type: "share",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,45 +1,59 @@
|
|||||||
import "../../sidebar/toolbar.css";
|
import "../../sidebar/toolbar.css";
|
||||||
import disabledImg from "../../../images/icons/line.svg";
|
import disabledImg from "../../../images/icons/line.svg";
|
||||||
import { useEffect, useState } from "react";
|
import { useState } from "react";
|
||||||
import { AnimatePresence, motion } from "framer-motion";
|
import { AnimatePresence, motion } from "framer-motion";
|
||||||
import { animationButton } from "../../../utils/animationProps";
|
import { animationButton } from "../../../utils/animationProps";
|
||||||
import { TButton } from "../../../utils/types";
|
import { useTranslation } from "react-i18next";
|
||||||
|
import { useAppSelector } from "../../../hooks/redux";
|
||||||
export const Button: React.FC<any> = ({ button, onClick, active }) => {
|
export const Button: React.FC<any> = ({ button, onClick, active }) => {
|
||||||
|
const [hover, setHover] = useState(false);
|
||||||
|
const { currentLang } = useAppSelector((state) => state.languageReducer);
|
||||||
|
|
||||||
const [hover, setHover] = useState(false)
|
const typeButton = button.type !== "fullscreen" && button.type !== "language";
|
||||||
|
|
||||||
const typeButton =
|
|
||||||
button.type !== 'fullscreen' && button.type !== 'language'
|
|
||||||
|
|
||||||
function handleClick() {
|
function handleClick() {
|
||||||
onClick()
|
onClick();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const { t } = useTranslation();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div >
|
<div>
|
||||||
<motion.button
|
<motion.button
|
||||||
onClick={handleClick}
|
onClick={handleClick}
|
||||||
onHoverStart={() => setHover(true)}
|
onHoverStart={() => setHover(true)}
|
||||||
onHoverEnd={() => setHover(false)}
|
onHoverEnd={() => setHover(false)}
|
||||||
className={button.type === 'exit' ? 'toolbar-button_exit toolbar-button' : 'toolbar-button'}>
|
className={
|
||||||
|
button.type === "exit"
|
||||||
|
? "toolbar-button_exit toolbar-button"
|
||||||
|
: "toolbar-button"
|
||||||
|
}
|
||||||
|
>
|
||||||
{button.type === "language" ? (
|
{button.type === "language" ? (
|
||||||
<span className="language-caption">EN</span>
|
<span className="language-caption">{currentLang.toUpperCase()}</span>
|
||||||
) : (
|
) : (
|
||||||
<img alt="icon" className="toolbar-icon" src={button.icon} />
|
<img alt="icon" className="toolbar-icon" src={button.icon} />
|
||||||
)}
|
)}
|
||||||
{active && typeButton && <img alt="iconDisabled" className="toolbar-disabled" src={disabledImg}></img>}
|
{active && typeButton && (
|
||||||
|
<img
|
||||||
|
alt="iconDisabled"
|
||||||
|
className="toolbar-disabled"
|
||||||
|
src={disabledImg}
|
||||||
|
></img>
|
||||||
|
)}
|
||||||
</motion.button>
|
</motion.button>
|
||||||
<AnimatePresence>
|
<AnimatePresence>
|
||||||
{hover && (
|
{hover && (
|
||||||
<motion.div variants={animationButton}
|
<motion.div
|
||||||
initial={'hidden'}
|
variants={animationButton}
|
||||||
animate={'show'}
|
initial={"hidden"}
|
||||||
exit={'hidden'}
|
animate={"show"}
|
||||||
className="toolbar-button-description-container">
|
exit={"hidden"}
|
||||||
|
className="toolbar-button-description-container"
|
||||||
|
>
|
||||||
<span className="toolbar-button-description-triangle"></span>
|
<span className="toolbar-button-description-triangle"></span>
|
||||||
<span className="toolbar-button-description-rectangle">
|
<span className="toolbar-button-description-rectangle">
|
||||||
{active ? button.active : button.inactive}
|
{active ? t(button.active) : t(button.inactive)}
|
||||||
</span>
|
</span>
|
||||||
</motion.div>
|
</motion.div>
|
||||||
)}
|
)}
|
||||||
|
|||||||
+35
-10
@@ -1,22 +1,47 @@
|
|||||||
import React from 'react';
|
import React, { Suspense, useEffect } from "react";
|
||||||
import ReactDOM from 'react-dom/client';
|
import ReactDOM from "react-dom/client";
|
||||||
import './index.css';
|
|
||||||
import App from './App';
|
import "./index.css";
|
||||||
import reportWebVitals from './reportWebVitals';
|
import App from "./App";
|
||||||
|
import reportWebVitals from "./reportWebVitals";
|
||||||
import { BrowserRouter } from "react-router-dom";
|
import { BrowserRouter } from "react-router-dom";
|
||||||
import {Provider} from "react-redux";
|
import { Provider } from "react-redux";
|
||||||
import {setupStore} from "./store/store";
|
import { setupStore } from "./store/store";
|
||||||
|
|
||||||
|
import i18next from "i18next";
|
||||||
|
import { initReactI18next } from "react-i18next";
|
||||||
|
import HttpApi from "i18next-http-backend";
|
||||||
|
import LanguageDetector from "i18next-browser-languagedetector";
|
||||||
|
|
||||||
const store = setupStore();
|
const store = setupStore();
|
||||||
|
|
||||||
|
i18next
|
||||||
|
.use(HttpApi)
|
||||||
|
.use(LanguageDetector)
|
||||||
|
.use(initReactI18next)
|
||||||
|
.init({
|
||||||
|
supportedLngs: ["en", "ru"],
|
||||||
|
fallbackLng: "en",
|
||||||
|
debug: false,
|
||||||
|
// Options for language detector
|
||||||
|
detection: {
|
||||||
|
order: ["cookie", "navigator"],
|
||||||
|
caches: ["cookie"],
|
||||||
|
},
|
||||||
|
// react: { useSuspense: false },
|
||||||
|
backend: {
|
||||||
|
loadPath: "/assets/locales/{{lng}}/translation.json",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
const root = ReactDOM.createRoot(
|
const root = ReactDOM.createRoot(
|
||||||
document.getElementById('root') as HTMLElement
|
document.getElementById("root") as HTMLElement
|
||||||
);
|
);
|
||||||
|
|
||||||
root.render(
|
root.render(
|
||||||
<BrowserRouter>
|
<BrowserRouter>
|
||||||
<Provider store={store}>
|
<Provider store={store}>
|
||||||
<App />
|
<App />
|
||||||
</Provider>
|
</Provider>
|
||||||
</BrowserRouter>
|
</BrowserRouter>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ export const cardSlice = createSlice({
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
extraReducers: {
|
extraReducers: {
|
||||||
|
|
||||||
[fetchCards.fulfilled.type]: (state, action: PayloadAction<ICards[]>) => {
|
[fetchCards.fulfilled.type]: (state, action: PayloadAction<ICards[]>) => {
|
||||||
state.isLoading = false;
|
state.isLoading = false;
|
||||||
state.error = "";
|
state.error = "";
|
||||||
|
|||||||
@@ -0,0 +1,25 @@
|
|||||||
|
import { createSlice, PayloadAction } from "@reduxjs/toolkit";
|
||||||
|
import i18next from "i18next";
|
||||||
|
|
||||||
|
interface LanguageState {
|
||||||
|
currentLang: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
const initialState: LanguageState = {
|
||||||
|
currentLang: '',
|
||||||
|
};
|
||||||
|
|
||||||
|
export const languageSlice = createSlice({
|
||||||
|
name: "language",
|
||||||
|
initialState,
|
||||||
|
reducers: {
|
||||||
|
handleChangeLanguage(state, action: PayloadAction<string>) {
|
||||||
|
i18next.changeLanguage(action.payload);
|
||||||
|
state.currentLang = action.payload;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
export default languageSlice.reducer;
|
||||||
|
|
||||||
@@ -1,10 +1,12 @@
|
|||||||
import { combineReducers, configureStore } from "@reduxjs/toolkit";
|
import { combineReducers, configureStore } from "@reduxjs/toolkit";
|
||||||
import cardReducer from "./reducers/cardSlice";
|
import cardReducer from "./reducers/cardSlice";
|
||||||
import sessionReducer from "./reducers/sessionSlice";
|
import sessionReducer from "./reducers/sessionSlice";
|
||||||
|
import languageReducer from "./reducers/languageSlice";
|
||||||
|
|
||||||
const rootReducer = combineReducers({
|
const rootReducer = combineReducers({
|
||||||
cardReducer,
|
cardReducer,
|
||||||
sessionReducer,
|
sessionReducer,
|
||||||
|
languageReducer,
|
||||||
});
|
});
|
||||||
|
|
||||||
export const setupStore = () => {
|
export const setupStore = () => {
|
||||||
|
|||||||
+27
-46
@@ -63,7 +63,7 @@
|
|||||||
font-size: 64px;
|
font-size: 64px;
|
||||||
line-height: 100%;
|
line-height: 100%;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
background-image: linear-gradient(56.75deg, #D375FF 19.74%, #798FFF 82.32%);
|
background-image: linear-gradient(56.75deg, #d375ff 19.74%, #798fff 82.32%);
|
||||||
background-size: 100%;
|
background-size: 100%;
|
||||||
background-repeat: repeat;
|
background-repeat: repeat;
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
@@ -76,7 +76,7 @@
|
|||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
line-height: 100%;
|
line-height: 100%;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
background-image: linear-gradient(56.75deg, #D375FF 19.74%, #798FFF 82.32%);
|
background-image: linear-gradient(56.75deg, #d375ff 19.74%, #798fff 82.32%);
|
||||||
background-size: 100%;
|
background-size: 100%;
|
||||||
background-repeat: repeat;
|
background-repeat: repeat;
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
@@ -109,7 +109,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.main-block__button {
|
.main-block__button {
|
||||||
font-family: 'GilroyWebRegular';
|
font-family: "GilroyWebRegular";
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
@@ -154,24 +154,21 @@
|
|||||||
border: 1px solid #ffffff;
|
border: 1px solid #ffffff;
|
||||||
}
|
}
|
||||||
|
|
||||||
.main-block__button:hover>div>img {
|
.main-block__button:hover > div > img {
|
||||||
transition: opacity ease-out 0.2s;
|
transition: opacity ease-out 0.2s;
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
.main-block__button:hover {
|
.main-block__button:hover {
|
||||||
border: 1px solid #FFFFFF;
|
border: 1px solid #ffffff;
|
||||||
transition: border ease-out 0.2s;
|
transition: border ease-out 0.2s;
|
||||||
}
|
}
|
||||||
|
|
||||||
.link {
|
.link {
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@media screen and (min-width: 1600px) {
|
@media screen and (min-width: 1600px) {
|
||||||
|
|
||||||
.main-block__title {
|
.main-block__title {
|
||||||
font-size: 76px;
|
font-size: 76px;
|
||||||
}
|
}
|
||||||
@@ -215,7 +212,6 @@
|
|||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
font-size: 20px;
|
font-size: 20px;
|
||||||
line-height: 125%;
|
line-height: 125%;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.main-block__icon_container {
|
.main-block__icon_container {
|
||||||
@@ -284,12 +280,27 @@
|
|||||||
line-height: 20px;
|
line-height: 20px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button:hover {
|
||||||
|
background: #6a92e2;
|
||||||
|
transition: 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button:disabled {
|
||||||
|
background-color: #404040;
|
||||||
|
transition: 0.3 ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button__disabled:hover {
|
||||||
|
background: #595959;
|
||||||
|
transition: 0.3 ease;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.button__disabled {
|
.button__disabled {
|
||||||
background-color: #404040;
|
background-color: #404040;
|
||||||
transition: background-color 0.3 ease;
|
transition: 0.3 ease;
|
||||||
}
|
}
|
||||||
|
|
||||||
.line {
|
.line {
|
||||||
@@ -313,25 +324,23 @@
|
|||||||
color: #ffffff;
|
color: #ffffff;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.popup__caption:hover {
|
||||||
|
opacity: 0.8;
|
||||||
|
transition: 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
@media screen and (max-width: 1279px) {
|
@media screen and (max-width: 1279px) {
|
||||||
.main-block__container {
|
.main-block__container {
|
||||||
gap: 44px;
|
gap: 44px;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@media screen and (max-width: 1024px) {
|
@media screen and (max-width: 1024px) {
|
||||||
|
|
||||||
.main-block__container {
|
.main-block__container {
|
||||||
margin: 30px 12px 60px;
|
margin: 30px 12px 60px;
|
||||||
gap: 40px;
|
gap: 40px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
.main-block__caption {
|
.main-block__caption {
|
||||||
font-size: 2.8vw;
|
font-size: 2.8vw;
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
@@ -351,8 +360,6 @@
|
|||||||
line-height: 140%;
|
line-height: 140%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
.main-block__title {
|
.main-block__title {
|
||||||
font-size: 10.6vw;
|
font-size: 10.6vw;
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
@@ -367,7 +374,6 @@
|
|||||||
line-height: 100%;
|
line-height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
.main-block_subblock {
|
.main-block_subblock {
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
line-height: 140%;
|
line-height: 140%;
|
||||||
@@ -379,16 +385,12 @@
|
|||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
line-height: 100%;
|
line-height: 100%;
|
||||||
font-size: 6.25vw;
|
font-size: 6.25vw;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
.main-block__title_gardient_small {
|
.main-block__title_gardient_small {
|
||||||
font-size: 6.25vw;
|
font-size: 6.25vw;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
.main-block__subblock-container {
|
.main-block__subblock-container {
|
||||||
display: block;
|
display: block;
|
||||||
margin: 0 0;
|
margin: 0 0;
|
||||||
@@ -397,11 +399,8 @@
|
|||||||
.main-block_subblock {
|
.main-block_subblock {
|
||||||
width: 80%;
|
width: 80%;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
font-size: 3vw
|
font-size: 3vw;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@media screen and (max-width: 639px) {
|
@media screen and (max-width: 639px) {
|
||||||
@@ -411,7 +410,6 @@
|
|||||||
height: 100%;
|
height: 100%;
|
||||||
padding: 32px 10px 67px;
|
padding: 32px 10px 67px;
|
||||||
height: 100vh;
|
height: 100vh;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.logo__popup {
|
.logo__popup {
|
||||||
@@ -440,10 +438,8 @@
|
|||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
padding-top: 14px;
|
padding-top: 14px;
|
||||||
padding-bottom: 14px;
|
padding-bottom: 14px;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
.main-block_subblock {
|
.main-block_subblock {
|
||||||
gap: 30px;
|
gap: 30px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
@@ -453,7 +449,6 @@
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
margin-top: 10px;
|
margin-top: 10px;
|
||||||
font-size: 3.6vw;
|
font-size: 3.6vw;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.main-block__caption {
|
.main-block__caption {
|
||||||
@@ -465,13 +460,8 @@
|
|||||||
font-style: normal;
|
font-style: normal;
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
line-height: 140%;
|
line-height: 140%;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
.main-block__button {
|
.main-block__button {
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
@@ -486,10 +476,6 @@
|
|||||||
line-height: 140%;
|
line-height: 140%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
.main-block__title_gardient {
|
.main-block__title_gardient {
|
||||||
font-size: 13.3vw;
|
font-size: 13.3vw;
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
@@ -506,7 +492,6 @@
|
|||||||
font-style: normal;
|
font-style: normal;
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
line-height: 100%;
|
line-height: 100%;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.main-block__title_small {
|
.main-block__title_small {
|
||||||
@@ -514,7 +499,6 @@
|
|||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
line-height: 100%;
|
line-height: 100%;
|
||||||
font-size: 9.25vw;
|
font-size: 9.25vw;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.main-block_subblock {
|
.main-block_subblock {
|
||||||
@@ -522,7 +506,4 @@
|
|||||||
line-height: 140%;
|
line-height: 140%;
|
||||||
font-size: 4.5vw;
|
font-size: 4.5vw;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|||||||
Reference in New Issue
Block a user