diff --git a/package-lock.json b/package-lock.json index 2da836e..d6c11ad 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,19 +10,26 @@ "dependencies": { "@react-spring/parallax": "^9.7.1", "@react-spring/web": "^9.7.1", + "animate.css": "^4.1.1", "chart.js": "^3.9.1", + "chartjs-plugin-datalabels": "^2.2.0", + "i18next": "^22.4.14", "localforage": "^1.10.0", "match-sorter": "^6.3.1", "randomcolor": "^0.6.2", "react": "^18.2.0", "react-chartjs-2": "^4.3.1", + "react-copy-to-clipboard": "^5.1.0", "react-dom": "^18.2.0", + "react-i18next": "^12.2.0", "react-icons": "^4.7.1", "react-router-dom": "^6.8.2", + "recharts": "^2.5.0", "sort-by": "^0.0.2" }, "devDependencies": { "@types/react": "^18.0.27", + "@types/react-copy-to-clipboard": "^5.0.4", "@types/react-dom": "^18.0.10", "@types/react-router-dom": "^5.3.3", "autoprefixer": "^10.4.13", @@ -597,6 +604,60 @@ "node": ">=14" } }, + "node_modules/@types/d3-array": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/d3-array/-/d3-array-3.0.4.tgz", + "integrity": "sha512-nwvEkG9vYOc0Ic7G7kwgviY4AQlTfYGIZ0fqB7CQHXGyYM6nO7kJh5EguSNA3jfh4rq7Sb7eMVq8isuvg2/miQ==" + }, + "node_modules/@types/d3-color": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@types/d3-color/-/d3-color-3.1.0.tgz", + "integrity": "sha512-HKuicPHJuvPgCD+np6Se9MQvS6OCbJmOjGvylzMJRlDwUXjKTTXs6Pwgk79O09Vj/ho3u1ofXnhFOaEWWPrlwA==" + }, + "node_modules/@types/d3-ease": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/d3-ease/-/d3-ease-3.0.0.tgz", + "integrity": "sha512-aMo4eaAOijJjA6uU+GIeW018dvy9+oH5Y2VPPzjjfxevvGQ/oRDs+tfYC9b50Q4BygRR8yE2QCLsrT0WtAVseA==" + }, + "node_modules/@types/d3-interpolate": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/d3-interpolate/-/d3-interpolate-3.0.1.tgz", + "integrity": "sha512-jx5leotSeac3jr0RePOH1KdR9rISG91QIE4Q2PYTu4OymLTZfA3SrnURSLzKH48HmXVUru50b8nje4E79oQSQw==", + "dependencies": { + "@types/d3-color": "*" + } + }, + "node_modules/@types/d3-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/d3-path/-/d3-path-3.0.0.tgz", + "integrity": "sha512-0g/A+mZXgFkQxN3HniRDbXMN79K3CdTpLsevj+PXiTcb2hVyvkZUBg37StmgCQkaD84cUJ4uaDAWq7UJOQy2Tg==" + }, + "node_modules/@types/d3-scale": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-4.0.3.tgz", + "integrity": "sha512-PATBiMCpvHJSMtZAMEhc2WyL+hnzarKzI6wAHYjhsonjWJYGq5BXTzQjv4l8m2jO183/4wZ90rKvSeT7o72xNQ==", + "dependencies": { + "@types/d3-time": "*" + } + }, + "node_modules/@types/d3-shape": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@types/d3-shape/-/d3-shape-3.1.1.tgz", + "integrity": "sha512-6Uh86YFF7LGg4PQkuO2oG6EMBRLuW9cbavUW46zkIO5kuS2PfTqo2o9SkgtQzguBHbLgNnU90UNsITpsX1My+A==", + "dependencies": { + "@types/d3-path": "*" + } + }, + "node_modules/@types/d3-time": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/d3-time/-/d3-time-3.0.0.tgz", + "integrity": "sha512-sZLCdHvBUcNby1cB6Fd3ZBrABbjz3v1Vm90nysCQ6Vt7vd6e/h9Lt7SiJUoEX0l4Dzc7P5llKyhqSi1ycSf1Hg==" + }, + "node_modules/@types/d3-timer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/d3-timer/-/d3-timer-3.0.0.tgz", + "integrity": "sha512-HNB/9GHqu7Fo8AQiugyJbv6ZxYz58wef0esl4Mv828w1ZKpAshw/uFWVDUcIB9KKFeFKoxS3cHY07FFgtTRZ1g==" + }, "node_modules/@types/history": { "version": "4.7.11", "resolved": "https://registry.npmjs.org/@types/history/-/history-4.7.11.tgz", @@ -620,6 +681,15 @@ "csstype": "^3.0.2" } }, + "node_modules/@types/react-copy-to-clipboard": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/@types/react-copy-to-clipboard/-/react-copy-to-clipboard-5.0.4.tgz", + "integrity": "sha512-otTJsJpofYAeaIeOwV5xBUGpo6exXG2HX7X4nseToCB2VgPEBxGBHCm/FecZ676doNR7HCSTVtmohxfG2b3/yQ==", + "dev": true, + "dependencies": { + "@types/react": "*" + } + }, "node_modules/@types/react-dom": { "version": "18.0.11", "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.0.11.tgz", @@ -688,6 +758,11 @@ "node": ">=0.4.0" } }, + "node_modules/animate.css": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/animate.css/-/animate.css-4.1.1.tgz", + "integrity": "sha512-+mRmCTv6SbCmtYJCN4faJMNFVNN5EuCTTprDTAo7YzIGji2KADmakjVA3+8mVDkZ2Bf09vayB35lSQIex2+QaQ==" + }, "node_modules/anymatch": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", @@ -827,6 +902,14 @@ "resolved": "https://registry.npmjs.org/chart.js/-/chart.js-3.9.1.tgz", "integrity": "sha512-Ro2JbLmvg83gXF5F4sniaQ+lTbSv18E+TIf2cOeiH1Iqd2PGFOtem+DUufMZsCJwFE7ywPOpfXFBwRTGq7dh6w==" }, + "node_modules/chartjs-plugin-datalabels": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/chartjs-plugin-datalabels/-/chartjs-plugin-datalabels-2.2.0.tgz", + "integrity": "sha512-14ZU30lH7n89oq+A4bWaJPnAG8a7ZTk7dKf48YAzMvJjQtjrgg5Dpk9f+LbjCF6bpx3RAGTeL13IXpKQYyRvlw==", + "peerDependencies": { + "chart.js": ">=3.0.0" + } + }, "node_modules/chokidar": { "version": "3.5.3", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", @@ -866,6 +949,11 @@ "node": ">= 6" } }, + "node_modules/classnames": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.3.2.tgz", + "integrity": "sha512-CSbhY4cFEJRe6/GQzIk5qXZ4Jeg5pcsP7b5peFSDpffpe1cqjASH/n9UTjBwOp6XpMSTwQ8Za2K5V02ueA7Tmw==" + }, "node_modules/color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", @@ -880,6 +968,19 @@ "optional": true, "peer": true }, + "node_modules/copy-to-clipboard": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/copy-to-clipboard/-/copy-to-clipboard-3.3.3.tgz", + "integrity": "sha512-2KV8NhB5JqC3ky0r9PMCAZKbUHSwtEo4CwCs0KXgruG43gX5PMqDEBbVU4OUzw2MuAWUfsuFmWvEKG5QRfSnJA==", + "dependencies": { + "toggle-selection": "^1.0.6" + } + }, + "node_modules/css-unit-converter": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/css-unit-converter/-/css-unit-converter-1.1.2.tgz", + "integrity": "sha512-IiJwMC8rdZE0+xiEZHeru6YoONC4rfPMqGm2W85jMIbkFvv5nFTwJVFHam2eFrN6txmoUYFAFXiv8ICVeTO0MA==" + }, "node_modules/cssesc": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", @@ -898,6 +999,121 @@ "integrity": "sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw==", "dev": true }, + "node_modules/d3-array": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-3.2.3.tgz", + "integrity": "sha512-JRHwbQQ84XuAESWhvIPaUV4/1UYTBOLiOPGWqgFDHZS1D5QN9c57FbH3QpEnQMYiOXNzKUQyGTZf+EVO7RT5TQ==", + "dependencies": { + "internmap": "1 - 2" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-color": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-3.1.0.tgz", + "integrity": "sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-ease": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-3.0.1.tgz", + "integrity": "sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-format": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-3.1.0.tgz", + "integrity": "sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-interpolate": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-3.0.1.tgz", + "integrity": "sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==", + "dependencies": { + "d3-color": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-path": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-3.1.0.tgz", + "integrity": "sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-scale": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-4.0.2.tgz", + "integrity": "sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==", + "dependencies": { + "d3-array": "2.10.0 - 3", + "d3-format": "1 - 3", + "d3-interpolate": "1.2.0 - 3", + "d3-time": "2.1.1 - 3", + "d3-time-format": "2 - 4" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-shape": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-3.2.0.tgz", + "integrity": "sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==", + "dependencies": { + "d3-path": "^3.1.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-time": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-3.1.0.tgz", + "integrity": "sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==", + "dependencies": { + "d3-array": "2 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-time-format": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-4.1.0.tgz", + "integrity": "sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==", + "dependencies": { + "d3-time": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-timer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-3.0.1.tgz", + "integrity": "sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==", + "engines": { + "node": ">=12" + } + }, + "node_modules/decimal.js-light": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/decimal.js-light/-/decimal.js-light-2.5.1.tgz", + "integrity": "sha512-qIMFpTMZmny+MMIitAB6D7iVPEorVw6YQRWkvarTkT4tBeSLLiHzcwj6q0MmYSFCiVpiqPJTJEYIrpcPzVEIvg==" + }, "node_modules/defined": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.1.tgz", @@ -936,6 +1152,14 @@ "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==", "dev": true }, + "node_modules/dom-helpers": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-3.4.0.tgz", + "integrity": "sha512-LnuPJ+dwqKDIyotW1VzmOZ5TONUN7CwkCR5hrgawTUbkBGYdeoNLZo6nNfGkCrjtE1nXXaj7iMMpDa8/d9WoIA==", + "dependencies": { + "@babel/runtime": "^7.1.2" + } + }, "node_modules/electron-to-chromium": { "version": "1.4.317", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.317.tgz", @@ -988,6 +1212,16 @@ "node": ">=6" } }, + "node_modules/eventemitter3": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==" + }, + "node_modules/fast-equals": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/fast-equals/-/fast-equals-4.0.3.tgz", + "integrity": "sha512-G3BSX9cfKttjr+2o1O22tYMLq0DPluZnYtq1rXumE1SpL/F/SLIfHx08WYQoWSIpeMYf8sRbJ8++71+v6Pnxfg==" + }, "node_modules/fast-glob": { "version": "3.2.12", "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz", @@ -1094,11 +1328,49 @@ "node": ">= 0.4.0" } }, + "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/i18next": { + "version": "22.4.14", + "resolved": "https://registry.npmjs.org/i18next/-/i18next-22.4.14.tgz", + "integrity": "sha512-VtLPtbdwGn0+DAeE00YkiKKXadkwg+rBUV+0v8v0ikEjwdiJ0gmYChVE4GIa9HXymY6wKapkL93vGT7xpq6aTw==", + "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/immediate": { "version": "3.0.6", "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz", "integrity": "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==" }, + "node_modules/internmap": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/internmap/-/internmap-2.0.3.tgz", + "integrity": "sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==", + "engines": { + "node": ">=12" + } + }, "node_modules/is-binary-path": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", @@ -1183,6 +1455,11 @@ "lie": "3.1.1" } }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, "node_modules/loose-envify": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", @@ -1270,6 +1547,14 @@ "node": ">=0.10.0" } }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/object-hash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz", @@ -1439,6 +1724,16 @@ "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", "dev": true }, + "node_modules/prop-types": { + "version": "15.8.1", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", + "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", + "dependencies": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.13.1" + } + }, "node_modules/queue-microtask": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", @@ -1496,6 +1791,18 @@ "react": "^16.8.0 || ^17.0.0 || ^18.0.0" } }, + "node_modules/react-copy-to-clipboard": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/react-copy-to-clipboard/-/react-copy-to-clipboard-5.1.0.tgz", + "integrity": "sha512-k61RsNgAayIJNoy9yDsYzDe/yAZAzEbEgcz3DZMhF686LEyukcE1hzurxe85JandPUG+yTfGVFzuEw3xt8WP/A==", + "dependencies": { + "copy-to-clipboard": "^3.3.1", + "prop-types": "^15.8.1" + }, + "peerDependencies": { + "react": "^15.3.0 || 16 || 17 || 18" + } + }, "node_modules/react-dom": { "version": "18.2.0", "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz", @@ -1508,6 +1815,27 @@ "react": "^18.2.0" } }, + "node_modules/react-i18next": { + "version": "12.2.0", + "resolved": "https://registry.npmjs.org/react-i18next/-/react-i18next-12.2.0.tgz", + "integrity": "sha512-5XeVgSygaGfyFmDd2WcXvINRw2WEC1XviW1LXY/xLOEMzsCFRwKqfnHN+hUjla8ZipbVJR27GCMSuTr0BhBBBQ==", + "dependencies": { + "@babel/runtime": "^7.20.6", + "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-icons": { "version": "4.8.0", "resolved": "https://registry.npmjs.org/react-icons/-/react-icons-4.8.0.tgz", @@ -1516,6 +1844,28 @@ "react": "*" } }, + "node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + }, + "node_modules/react-lifecycles-compat": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz", + "integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==" + }, + "node_modules/react-resize-detector": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/react-resize-detector/-/react-resize-detector-8.1.0.tgz", + "integrity": "sha512-S7szxlaIuiy5UqLhLL1KY3aoyGHbZzsTpYal9eYMwCyKqoqoVLCmIgAgNyIM1FhnP2KyBygASJxdhejrzjMb+w==", + "dependencies": { + "lodash": "^4.17.21" + }, + "peerDependencies": { + "react": "^16.0.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.0.0 || ^17.0.0 || ^18.0.0" + } + }, "node_modules/react-router": { "version": "6.8.2", "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.8.2.tgz", @@ -1546,6 +1896,35 @@ "react-dom": ">=16.8" } }, + "node_modules/react-smooth": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/react-smooth/-/react-smooth-2.0.2.tgz", + "integrity": "sha512-pgqSp1q8rAGtF1bXQE0m3CHGLNfZZh5oA5o1tsPLXRHnKtkujMIJ8Ws5nO1mTySZf1c4vgwlEk+pHi3Ln6eYLw==", + "dependencies": { + "fast-equals": "^4.0.3", + "react-transition-group": "2.9.0" + }, + "peerDependencies": { + "prop-types": "^15.6.0", + "react": "^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/react-transition-group": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-2.9.0.tgz", + "integrity": "sha512-+HzNTCHpeQyl4MJ/bdE0u6XRMe9+XG/+aL4mCxVN4DnPBQ0/5bfHWPDuOZUzYdMj94daZaZdCCc1Dzt9R/xSSg==", + "dependencies": { + "dom-helpers": "^3.4.0", + "loose-envify": "^1.4.0", + "prop-types": "^15.6.2", + "react-lifecycles-compat": "^3.0.4" + }, + "peerDependencies": { + "react": ">=15.0.0", + "react-dom": ">=15.0.0" + } + }, "node_modules/read-cache": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", @@ -1567,6 +1946,52 @@ "node": ">=8.10.0" } }, + "node_modules/recharts": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/recharts/-/recharts-2.5.0.tgz", + "integrity": "sha512-0EQYz3iA18r1Uq8VqGZ4dABW52AKBnio37kJgnztIqprELJXpOEsa0SzkqU1vjAhpCXCv52Dx1hiL9119xsqsQ==", + "dependencies": { + "classnames": "^2.2.5", + "eventemitter3": "^4.0.1", + "lodash": "^4.17.19", + "react-is": "^16.10.2", + "react-resize-detector": "^8.0.4", + "react-smooth": "^2.0.2", + "recharts-scale": "^0.4.4", + "reduce-css-calc": "^2.1.8", + "victory-vendor": "^36.6.8" + }, + "engines": { + "node": ">=12" + }, + "peerDependencies": { + "prop-types": "^15.6.0", + "react": "^16.0.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.0.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/recharts-scale": { + "version": "0.4.5", + "resolved": "https://registry.npmjs.org/recharts-scale/-/recharts-scale-0.4.5.tgz", + "integrity": "sha512-kivNFO+0OcUNu7jQquLXAxz1FIwZj8nrj+YkOKc5694NbjCvcT6aSZiIzNzd2Kul4o4rTto8QVR9lMNtxD4G1w==", + "dependencies": { + "decimal.js-light": "^2.4.1" + } + }, + "node_modules/reduce-css-calc": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/reduce-css-calc/-/reduce-css-calc-2.1.8.tgz", + "integrity": "sha512-8liAVezDmUcH+tdzoEGrhfbGcP7nOV4NkGE3a74+qqvE7nt9i4sKLGBuZNOnpI4WiGksiNPklZxva80061QiPg==", + "dependencies": { + "css-unit-converter": "^1.1.1", + "postcss-value-parser": "^3.3.0" + } + }, + "node_modules/reduce-css-calc/node_modules/postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" + }, "node_modules/regenerator-runtime": { "version": "0.13.11", "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", @@ -1804,6 +2229,11 @@ "node": ">=8.0" } }, + "node_modules/toggle-selection": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/toggle-selection/-/toggle-selection-1.0.6.tgz", + "integrity": "sha512-BiZS+C1OS8g/q2RRbJmy59xpyghNBqrr6k5L/uKBGRsTfxmu3ffiRnd8mlGPUVayg8pvfi5urfnu8TU7DVOkLQ==" + }, "node_modules/typescript": { "version": "4.9.5", "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", @@ -1849,6 +2279,27 @@ "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", "dev": true }, + "node_modules/victory-vendor": { + "version": "36.6.8", + "resolved": "https://registry.npmjs.org/victory-vendor/-/victory-vendor-36.6.8.tgz", + "integrity": "sha512-H3kyQ+2zgjMPvbPqAl7Vwm2FD5dU7/4bCTQakFQnpIsfDljeOMDojRsrmJfwh4oAlNnWhpAf+mbAoLh8u7dwyQ==", + "dependencies": { + "@types/d3-array": "^3.0.3", + "@types/d3-ease": "^3.0.0", + "@types/d3-interpolate": "^3.0.1", + "@types/d3-scale": "^4.0.2", + "@types/d3-shape": "^3.1.0", + "@types/d3-time": "^3.0.0", + "@types/d3-timer": "^3.0.0", + "d3-array": "^3.1.6", + "d3-ease": "^3.0.1", + "d3-interpolate": "^3.0.1", + "d3-scale": "^4.0.2", + "d3-shape": "^3.1.0", + "d3-time": "^3.0.0", + "d3-timer": "^3.0.1" + } + }, "node_modules/vite": { "version": "4.1.4", "resolved": "https://registry.npmjs.org/vite/-/vite-4.1.4.tgz", @@ -1898,6 +2349,14 @@ } } }, + "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/xtend": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", diff --git a/package.json b/package.json index 20c43a5..1801de1 100644 --- a/package.json +++ b/package.json @@ -11,19 +11,26 @@ "dependencies": { "@react-spring/parallax": "^9.7.1", "@react-spring/web": "^9.7.1", + "animate.css": "^4.1.1", "chart.js": "^3.9.1", + "chartjs-plugin-datalabels": "^2.2.0", + "i18next": "^22.4.14", "localforage": "^1.10.0", "match-sorter": "^6.3.1", "randomcolor": "^0.6.2", "react": "^18.2.0", "react-chartjs-2": "^4.3.1", + "react-copy-to-clipboard": "^5.1.0", "react-dom": "^18.2.0", + "react-i18next": "^12.2.0", "react-icons": "^4.7.1", "react-router-dom": "^6.8.2", + "recharts": "^2.5.0", "sort-by": "^0.0.2" }, "devDependencies": { "@types/react": "^18.0.27", + "@types/react-copy-to-clipboard": "^5.0.4", "@types/react-dom": "^18.0.10", "@types/react-router-dom": "^5.3.3", "autoprefixer": "^10.4.13", diff --git a/src/i18n/en/aboutSection.json b/src/i18n/en/aboutSection.json new file mode 100644 index 0000000..e79552b --- /dev/null +++ b/src/i18n/en/aboutSection.json @@ -0,0 +1,7 @@ +{ + "title1": "WHAT IS SGPT?", + "title2": "SGPT SOLUTION", + "content1": "SGPT Token is a complementary token created on the blockchain platform to provide a platform for small and medium-sized businesses (SMBs) to create and manage an internal Q&A system. SGPT Token will be used to conduct transactions on the platform and provide benefits to members of the internal Q&A system. SGPT Token will also be used to reward members who make positive contributions to the system.", + "content2": "The SGPT Token is a solution to the problems associated with traditional payment methods for chat bot services. The token is built on blockchain technology, which ensures that transactions are fast, secure, and transparent. Moreover, the use of the SGPT Token eliminates the need for traditional payment methods, which are often costly and inconvenient." + +} \ No newline at end of file diff --git a/src/i18n/en/firstSection.json b/src/i18n/en/firstSection.json new file mode 100644 index 0000000..f38278a --- /dev/null +++ b/src/i18n/en/firstSection.json @@ -0,0 +1,7 @@ +{ + "title": "A digital currency payment for chat bot services", + "content": "The SGPT Token is a digital currency designed to facilitate payments for services provided by the SGPT chat bot. The chat bot is a powerful tool that utilizes artificial intelligence to communicate with users and provide valuable information and services.", + "addressBSC": "Address on BSC", + "address": "0x3c97331438e90680a17c35905ffc2b8ef760f844", + "joinOur": "Join Our Community" +} \ No newline at end of file diff --git a/src/i18n/i18n.ts b/src/i18n/i18n.ts new file mode 100644 index 0000000..6b37f92 --- /dev/null +++ b/src/i18n/i18n.ts @@ -0,0 +1,25 @@ +import i18n from "i18next"; +import { useTranslation, initReactI18next } from "react-i18next"; +import FirstSection_EN from "./en/firstSection.json" +import FirstSection_VI from "./vi/firstSection.json" +export const locales = { + en: 'English', + vi: 'Việt Nam' +} +export const resources = { + en: { + firstSection: FirstSection_EN + }, + vi: { + firstSection: FirstSection_VI + + }, +}; +i18n.use(initReactI18next).init({ + resources, + lng: "en", + fallbackLng: "en", + interpolation: { + escapeValue: false, // react already safes from xss + }, +}); diff --git a/src/i18n/vi/aboutSection.json b/src/i18n/vi/aboutSection.json new file mode 100644 index 0000000..33830ad --- /dev/null +++ b/src/i18n/vi/aboutSection.json @@ -0,0 +1,7 @@ +{ + "title1": "SGPT là gì?", + "title2": "Giải pháp SGPT ", + "content1": "SGPT Token là mã thông báo bổ sung được tạo trên nền tảng chuỗi khối để cung cấp nền tảng cho các doanh nghiệp vừa và nhỏ (SMBs) tạo và quản lý hệ thống hỏi đáp nội bộ. SGPT token sẽ được sử dụng để thực hiện các giao dịch trên nền tảng và cung cấp lợi ích cho các thành viên của hệ thống hỏi đáp nội bộ. SGPT token cũng sẽ được sử dụng để thưởng cho các thành viên có đóng góp tích cực cho hệ thống.", + "content2": "SGPT Token là một giải pháp cho các vấn đề liên quan đến phương thức thanh toán truyền thống cho các dịch vụ chatbot trò chuyện. Mã thông báo được xây dựng trên công nghệ chuỗi khối, đảm bảo rằng các giao dịch diễn ra nhanh chóng, an toàn và minh bạch. Hơn nữa, việc sử dụng SGPT Token giúp loại bỏ nhu cầu về các phương thức thanh toán truyền thống, thường tốn kém và bất tiện." + +} \ No newline at end of file diff --git a/src/i18n/vi/firstSection.json b/src/i18n/vi/firstSection.json new file mode 100644 index 0000000..40e66be --- /dev/null +++ b/src/i18n/vi/firstSection.json @@ -0,0 +1,7 @@ +{ + "title": "Thanh toán bằng tiền kỹ thuật số cho các dịch vụ chatbot", + "content": "SGPT Token là một loại tiền kỹ thuật số được thiết kế để hỗ trợ thanh toán cho các dịch vụ do chatbot SGPT cung cấp. Chat bot là một công cụ mạnh mẽ sử dụng trí tuệ nhân tạo để giao tiếp với người dùng và cung cấp thông tin và dịch vụ có giá trị", + "addressBSC": "Địa chỉ trên BSC", + "address": "0x3c97331438e90680a17c35905ffc2b8ef760f844", + "joinOur": "Tham gia cùng chúng tôi" +} \ No newline at end of file diff --git a/src/index.css b/src/index.css index 3af7e8e..311ef38 100644 --- a/src/index.css +++ b/src/index.css @@ -13,7 +13,41 @@ transform: translateX(0); } } +@keyframes show-list-language { + 0% { + opacity: 0; + transform: translateY(-80%); + } + 100% { + opacity: 1; + transform: translateY(0%); + } + +} + + +@keyframes show-list-line { + 0% { + opacity: 0; + width: 0%; + } + 100% { + opacity: 1; + width: 100%; + } + +} +.animate-show{ + transition: all 0.3s ease ; +} +.animate-show-list-language{ + transition: animation 0.5s ease; + animation: show-list-language 0.3s ease; +} +.animate-show-line{ + animation: show-list-line 0.3s ease; +} .animate-slide-loop { animation-name: slide-loop; animation-duration: 3s; diff --git a/src/main.tsx b/src/main.tsx index 02055fd..ffebc30 100644 --- a/src/main.tsx +++ b/src/main.tsx @@ -2,6 +2,7 @@ import React from "react"; import ReactDOM from "react-dom/client"; import App from "./App"; import "./index.css"; +import "./i18n/i18n"; ReactDOM.createRoot(document.getElementById("root") as HTMLElement).render( diff --git a/src/shared/components/Header.tsx b/src/shared/components/Header.tsx index 2ecff36..4b1e4bb 100644 --- a/src/shared/components/Header.tsx +++ b/src/shared/components/Header.tsx @@ -1,8 +1,12 @@ import React, { useEffect } from "react"; +import {useTranslation } from "react-i18next"; import Button from "./Button"; import robotLogo from "../../assets/images/robot-logo.png"; import { BsNewspaper, BsGithub } from "react-icons/bs"; import Whitepaper from "../../assets/Whitepaper.pdf"; +import { MdLanguage } from "react-icons/md"; +import { locales, resources } from "../../i18n/i18n"; + type Props = {}; const menuItems = [ @@ -32,7 +36,11 @@ const Header = (props: Props) => { const [isScrolled, setIsScrolled] = React.useState(false); const [isOpenMenu, setIsOpenMenu] = React.useState(false); const [isMobile, setIsMobile] = React.useState(false); - + const { i18n } = useTranslation(); + const currentLanguage = locales[i18n.language as keyof typeof locales ] + const languages = Object.keys(resources) + console.log(Object.keys(resources)); + console.log(currentLanguage); React.useEffect(() => { // check is mobile if (window.innerWidth <= 768) { @@ -40,6 +48,7 @@ const Header = (props: Props) => { } else { setIsMobile(false); } + console.log(window.innerWidth); if (window.innerWidth <= 1024) { setIsScrolled(true); @@ -52,7 +61,7 @@ const Header = (props: Props) => { } }); } - }, []); + }, [window.innerWidth]); const jumpToSection = (section: string) => { console.log("section", section); @@ -61,26 +70,37 @@ const Header = (props: Props) => { element.scrollIntoView({ behavior: "smooth" }); } }; + const backToHome = () => { + const element = document.getElementById("home"); + if (element) { + element.scrollIntoView({ behavior: "smooth" }); + } + }; const openLocalPdf = () => { const pdf = Whitepaper; window.open(pdf); }; - + const changeLanguage = (lng: string)=>{ + i18n.changeLanguage(lng) + } return ( <> {isScrolled ? ( -
-
-
-
+
+
+
backToHome()} + > +
-

+

SGPT

@@ -133,7 +153,7 @@ const Header = (props: Props) => { { // Mobile menu isMobile && isOpenMenu ? ( -
+
    {menuItems.map((item) => ( @@ -182,16 +202,31 @@ const Header = (props: Props) => { SGPT
- +
+ + {currentLanguage} +
+
    + {languages.map((lng)=>( + <> +
  • changeLanguage(lng)}> + {locales[lng as keyof typeof locales]} +
    +
  • + + + ))} +
+
    {menuItems.map((item) => (
  • jumpToSection(item.id)} > -

    +

    {item.name}

  • diff --git a/src/shared/components/animated/QnASection.css b/src/shared/components/animated/QnASection.css index 7ab212f..dfa07e7 100644 --- a/src/shared/components/animated/QnASection.css +++ b/src/shared/components/animated/QnASection.css @@ -1,15 +1,19 @@ -/* .list-answer { - animation: modalFadeIn ease 0.5s; - background-color: red; -} -@keyframes modalFadeIn { - 0% { - opacity: 0; - transform: translateY(-150px); - } +.iconDropDown { + transform: rotate(0deg); + transition: transform 1.5s; +} +.iconDropUp { + transition: transform 1.5s; + transform: rotate(180deg); +} + +.listItem__QnA{ + max-height: 0; + overflow: hidden; + transition: all 1.5s ease; +} +.listItem__QnA-active{ + max-height: 100vh; +} + - 100% { - opacity: 1; - transform: translateY(0px); - } -} */ diff --git a/src/shared/components/backtotop/index.tsx b/src/shared/components/backtotop/index.tsx index 5accff6..fa1f057 100644 --- a/src/shared/components/backtotop/index.tsx +++ b/src/shared/components/backtotop/index.tsx @@ -1,7 +1,15 @@ import { useState } from "react"; import robotLogo from "../../../assets/images/robot-coin1.png"; import { MdOutlineKeyboardDoubleArrowUp } from "react-icons/md"; -import { VscFoldUp } from "react-icons/vsc"; +import { + VscArrowCircleUp, + VscArrowUp, + VscFoldUp, + VscGroupByRefType, + VscThumbsup, + VscTriangleUp, + VscVariableGroup, +} from "react-icons/vsc"; const BackToTopButton = () => { const [isVisible, setIsVisible] = useState(false); @@ -26,17 +34,17 @@ const BackToTopButton = () => {
    - + back - + {/* 👆 - + */}
    ); }; diff --git a/src/shared/components/home/AboutSection.tsx b/src/shared/components/home/AboutSection.tsx index 2ed52c3..62a0381 100644 --- a/src/shared/components/home/AboutSection.tsx +++ b/src/shared/components/home/AboutSection.tsx @@ -26,7 +26,7 @@ const AboutSection = (props: Props) => { {/*

    {typedText}

    */} -

    +

    SGPT Token is a complementary token created on the blockchain platform to provide a platform for small and medium-sized @@ -45,7 +45,7 @@ const AboutSection = (props: Props) => {

    SGPT Solution

    -

    +

    {/*

    {typedText}

    */} The SGPT Token is a solution to the problems associated with diff --git a/src/shared/components/home/FirstSection.tsx b/src/shared/components/home/FirstSection.tsx index ec5666a..aa34e66 100644 --- a/src/shared/components/home/FirstSection.tsx +++ b/src/shared/components/home/FirstSection.tsx @@ -1,8 +1,11 @@ +import { CopyToClipboard } from "react-copy-to-clipboard"; +import { useTranslation } from "react-i18next"; import robotImage from "../../../assets/images/robot-2.png"; import robotImage2 from "../../../assets/images/robot-coin1.png"; import robotBgr from "../../../assets/images/robot-bgr.png"; import VideoSGPTBg from "../../../assets/sgpt-bg.mp4"; import Button from "../Button"; + import { BsFacebook, BsDiscord, @@ -49,6 +52,7 @@ const socials = [ ]; const FirstSection = () => { + const {t} = useTranslation('firstSection') const address = "0x3c97331438e90680a17c35905ffc2b8ef760f844"; const truncateAddress = (address: string) => { return address.slice(0, 5) + "......" + address.slice(-5); @@ -64,7 +68,7 @@ const FirstSection = () => { }); return ( @@ -82,67 +86,62 @@ const FirstSection = () => {
-
-
-
+
+
+

- A digital currency payment for chat bot services + {t('title')} + {/* A digital currency payment for chat bot services */}

- The SGPT Token is a digital currency designed to facilitate - payments for services provided by the SGPT chat bot. The chat bot - is a powerful tool that utilizes artificial intelligence to - communicate with users and provide valuable information and - services. + {t('content')}

- -
-
-
+
+
+

- Address on BSC{" "} + {t('addressBSC')}

-
+
{truncateAddress(address)} - + + + +
+
+
+
+ +

+ {t('Community')} +

+ +
+
+ {socials.map((social) => ( + + ))}
- {/*
-
- -

- Join Our Community{' '} -

- -
-
- {socials.map((social) => ( - - ))} -
-
*/}
diff --git a/src/shared/components/home/QnASection.tsx b/src/shared/components/home/QnASection.tsx index 1f4f1cf..5d98af4 100644 --- a/src/shared/components/home/QnASection.tsx +++ b/src/shared/components/home/QnASection.tsx @@ -13,27 +13,32 @@ const QnASection = (props: Props) => { const listQnA = [ { id: 1, - title: "Abc", + title: + "What is Fight Out?", bgcolor: "bg-[#CC99FF]", contents: [ { id: 1, - content: "12sdfsd3", + content: + "Fight Out is changing the blueprint for metaverses. At its heart, Fight Out is a gaming platform that rewards users for competing and winning in a variety of contest modes. A player's ability to compete and how much they are rewarded is determined in part by their avatar’s attributes. Stats are increased through the Fight Out app by training in real -life.", bgcolor: "bg-[#9999FF]", }, { id: 2, - content: "123ádsa", + content: + "Fight Out is changing the blueprint for metaverses. At its heart, Fight Out is a gaming platform that rewards users for competing and winning in a variety of contest modes. A player's ability to compete and how much they are rewarded is determined in part by their avatar’s attributes. Stats are increased through the Fight Out app by training in real -life.", bgcolor: "bg-[#6699FF]", }, { id: 3, - content: "123ádas", + content: + "Fight Out is changing the blueprint for metaverses. At its heart, Fight Out is a gaming platform that rewards users for competing and winning in a variety of contest modes. A player's ability to compete and how much they are rewarded is determined in part by their avatar’s attributes. Stats are increased through the Fight Out app by training in real -life.", bgcolor: "bg-[#3399FF]", }, { id: 4, - content: "123ádasd", + content: + "Fight Out is changing the blueprint for metaverses. At its heart, Fight Out is a gaming platform that rewards users for competing and winning in a variety of contest modes. A player's ability to compete and how much they are rewarded is determined in part by their avatar’s attributes. Stats are increased through the Fight Out app by training in real -life.", bgcolor: "bg-[#0099FF]", }, ], @@ -43,6 +48,62 @@ const QnASection = (props: Props) => { title: "Abcd", bgcolor: "bg-[#CC66FF]", + contents: [ + { + id: 1, + bgcolor: "bg-[#9966FF]", + content: "ádasffjk12", + }, + { + id: 2, + bgcolor: "bg-[#6666FF]", + content: "ádasffj1k", + }, + { + id: 3, + bgcolor: "bg-[#3366FF]", + content: "ádasffj12k", + }, + { + id: 4, + bgcolor: "bg-[#0066FF]", + content: "ádasffj123k", + }, + ], + }, + { + id: 3, + title: "Abcd", + bgcolor: "bg-[#CC66FF]", + + contents: [ + { + id: 1, + bgcolor: "bg-[#9966FF]", + content: "ádasffjk12", + }, + { + id: 2, + bgcolor: "bg-[#6666FF]", + content: "ádasffj1k", + }, + { + id: 3, + bgcolor: "bg-[#3366FF]", + content: "ádasffj12k", + }, + { + id: 4, + bgcolor: "bg-[#0066FF]", + content: "ádasffj123k", + }, + ], + }, + { + id: 4, + title: "Abcd", + bgcolor: "bg-[#CC66FF]", + contents: [ { id: 1, @@ -67,13 +128,16 @@ const QnASection = (props: Props) => { ], }, ]; - const showListItem = (id: string) => { - const element = document.getElementById(`${id}`); + const showListItem = (id: string, iconDropDown: string) => { + const iconDropDownid = document.getElementById(`${iconDropDown}`); // const ulhidden = document.querySelector(`#${id} ul`); const ulhidden = document.querySelector(`#${id}>ul`); console.log(ulhidden); - ulhidden?.classList.toggle("hidden"); - ulhidden?.classList.toggle("flex"); + ulhidden?.classList.toggle("listItem__QnA-active"); + // ulhidden?.classList.toggle("showListQnA"); + // ulhidden?.classList.toggle("hiddenListQnA"); + iconDropDownid?.classList.toggle("iconDropUp"); + iconDropDownid?.classList.toggle("iconDropDown"); }; const [isVisible, setIsVisible] = useState(false); @@ -83,7 +147,7 @@ const QnASection = (props: Props) => { ([entry]) => { setIsVisible(entry.isIntersecting); }, - { threshold: 0.5 } + { threshold: 0.2 } ); if (!section) { @@ -108,7 +172,6 @@ const QnASection = (props: Props) => { to: { opacity: isVisible ? 1 : 0, }, - config: { duration: 1000, }, @@ -116,10 +179,10 @@ const QnASection = (props: Props) => { return (
-
+

FAQS

@@ -131,44 +194,50 @@ const QnASection = (props: Props) => {
-
    +
      {listQnA.map((item, index) => { return (
    • + showListItem("title" + item.id, index + item.title) + } > -
      +
      - + {item.title}
      showListItem(item.title)} + > - +
      -
        +
          {item.contents.map((list, index) => { return (
        • - + {list.content}
        • diff --git a/src/shared/components/home/RoadMap.tsx b/src/shared/components/home/RoadMap.tsx index 0c7a1c2..39dc876 100644 --- a/src/shared/components/home/RoadMap.tsx +++ b/src/shared/components/home/RoadMap.tsx @@ -37,18 +37,40 @@ const roadMapData = [ "CEOAI Bot Creator and integration with AI.", ], }, + { + phase: "Phase 4", + listTitle: [ + "Swap Development and Launch", + "Merchandise Launch", + "Tier 1 CEX Listings", + "CEO Bridge to ETH, Arbitrium and Polygon", + "10 Million MarketCap Milestone", + "CEOAI Bot Creator and integration with AI.", + ], + }, + { + phase: "Phase 5", + listTitle: [ + "Swap Development and Launch", + "Merchandise Launch", + "Tier 1 CEX Listings", + "CEO Bridge to ETH, Arbitrium and Polygon", + "10 Million MarketCap Milestone", + "CEOAI Bot Creator and integration with AI.", + ], + }, ]; const RoadMap = (props: Props) => { const [isVisible, setIsVisible] = useState(false); useEffect(() => { - const section = document.querySelector(".animate-on-scroll"); + const section = document.getElementById("roadmap"); const observer = new IntersectionObserver( ([entry]) => { setIsVisible(entry.isIntersecting); }, - { threshold: 0.5 } + { threshold: 0.1 } ); if (!section) { @@ -67,7 +89,14 @@ const RoadMap = (props: Props) => { const styles = useSpring({ opacity: isVisible ? 1 : 0, - transform: isVisible ? "translateX(0)" : "translateX(100px)", + transform: isVisible ? "scaleX(1)" : "scaleX(0)", + config: { + duration: 500, + }, + }); + const styles1 = useSpring({ + opacity: isVisible ? 1 : 0, + transform: isVisible ? "scaleY(1)" : "scaleY(0)", config: { duration: 500, }, @@ -78,21 +107,27 @@ const RoadMap = (props: Props) => { className="container mx-auto text-white md:min-h-[60vh] animate-on-scroll py-20 relative" id="roadmap" > -
          +

          Road Map

          {/*
          */} - + {roadMapData.map((item, index) => { return (
          -
          - -

          +
          +

          {item.phase}

            @@ -100,7 +135,7 @@ const RoadMap = (props: Props) => { return (
          1. { const [isVisible, setIsVisible] = useState(false); @@ -73,7 +91,7 @@ const TokenomicsSection = (props: Props) => { ([entry]) => { setIsVisible(entry.isIntersecting); }, - { threshold: 0.5 } + { threshold: 0.4 } ); if (!section) { @@ -92,83 +110,131 @@ const TokenomicsSection = (props: Props) => { const styles = useSpring({ opacity: isVisible ? 1 : 0, - transform: isVisible ? "translateY(0)" : "translateY(100px)", + transform: isVisible ? "scaleX(1)" : "scaleX(0.5)", config: { - duration: 500, + duration: 300, }, }); - const textCenter = { + + const plugins = { id: "textCenter", - beforeDatasetsDraw(chart: any, arg: any, pluginsOptions: any) { - const { ctx, data } = chart; - ctx.save(); - ctx.fillStyle = "#fff"; - ctx.font = "bolder 30px sen"; - ctx.textAlign = "center"; - ctx.textBaseline = "middle"; - ctx.fillText( - `TOTAL SUPPLE`, - chart.getDatasetMeta(0).data[0].x, - chart.getDatasetMeta(0).data[0].y - 20 - ); - ctx.fillText( - `20,000,000 SGPT`, - chart.getDatasetMeta(0).data[0].x, - chart.getDatasetMeta(0).data[0].y + 25 - ); - }, + datalabels: {}, + // beforeDatasetsDraw(chart: any, arg: any, pluginsOptions: any) { + // const { ctx, data } = chart; + // ctx.save(); + // ctx.fillStyle = "#fff"; + // ctx.font = "bolder 30px sen"; + // ctx.textAlign = "center"; + // ctx.textBaseline = "middle"; + // ctx.fillText( + // `TOTAL SUPPLE`, + // chart.getDatasetMeta(0).data[0].x, + // chart.getDatasetMeta(0).data[0].y - 20 + // ); + // ctx.fillText( + // `20,000,000 SGPT`, + // chart.getDatasetMeta(0).data[0].x, + // chart.getDatasetMeta(0).data[0].y + 25 + // ); + // }, }; const [userData, setUserData] = useState({ - labels: tokenomics.map((data) => data.title), + labels: tokenomics.map((data) => data.name), datasets: [ { - // label: "text", + label: "text", data: tokenomics.map((data) => data.precent), backgroundColor: tokenomics.map((data) => data.color), - // cutout: "10%", - borderWidth: 2, - delay: 100, + // cutout: "40%", + borderWidth: 1, + datalabels: { + font: { + weight: "bold", + }, + anchor: "center", //start, center, end + rotation: function (ctx: any) { + const valuesBefore = ctx.dataset.data + .slice(0, ctx.dataIndex) + .reduce( + (a: number, b: number) => Number(a) + Number(b), + 1 as number + ); + const sum = ctx.dataset.data.reduce( + (a: number, b: number) => Number(a) + Number(b), + 1 as number + ); + const rotation = + ((valuesBefore + ctx.dataset.data[ctx.dataIndex] / 2) / sum) * + 360; + return rotation < 180 ? rotation - 95 : rotation + 90; + }, + // formatter: function (value: any, context: any) { + // return context.chart.data.labels[context.dataIndex]; + // }, + // anchor: "end", + align: "center", + offset: -30, + }, }, ], }); - const labelText = { + const options = { + layout: {}, hoverBorderWidth: 4, plugins: { legend: { display: false, }, + datalabels: { + font: { + + size: window.innerWidth > 1024 ? 20 : window.innerWidth > 768 ? 16 : 10, + }, + color: "#fff", + formatter: (context: any, agrs: any) => { + const index = agrs.dataIndex; + return agrs.chart.data.labels[index]; + }, + }, tooltip: { callbacks: { label: (context: any) => { - return ` ${context.label}`; + return ` ${tokenomics[context.dataIndex].title}`; }, }, }, }, }; - + ChartJS.register(ChartDataLabels); return (
            -

            +

            Tokenomics

            -
            -
            - - +
            +
            + +
            -
            + {/*
              {tokenomics.map((item, index) => { return (
              { ); })}
            -
            +
            */}
            diff --git a/src/shared/components/home/text b/src/shared/components/home/text index d9c80c2..676e7a9 100644 --- a/src/shared/components/home/text +++ b/src/shared/components/home/text @@ -1,26 +1,541 @@ -
            -
            -
            -
            - {index + 1} - {/* */} -
            -
            -

            {item.phase}

            -
              - {item.listTitle.map((listItem, index) => { - return ( -
            1. - -

              {listItem}

              -
            2. - ); - })} -
            -
            -
            -
            -
            \ No newline at end of file +// +// +// + +// +// import { useSpring, animated } from "@react-spring/web"; +// import { useEffect, useState } from "react"; +// import { Pie } from "react-chartjs-2"; +// import "chart.js/auto"; +// import { +// Chart as ChartJS, +// ArcElement, +// Tooltip, +// Legend, +// ChartData, +// } from "chart.js"; +// import ChartDataLabels from "chartjs-plugin-datalabels"; +// import { Context } from "chartjs-plugin-datalabels"; +// import tokenomicChart from "../../../assets/images/tokenomic-chart.png"; + +// import "animate.css"; +// type Props = {}; +// ChartJS.register(ArcElement, Tooltip, Legend); +// const tokenomics = [ +// { +// name: "Liquidity", +// title: "Liquidity - 5% 1,000,000 SGPT", +// precent: "5", +// description: " ", +// color: "#86eae9", +// bgcolor: "bg-[#86eae9]", +// }, +// { +// name: "Private Sale", +// title: "Private Sale - 17% 3,400,000 SGPT", +// description: " ", +// precent: "17", +// color: "#5dbdd3", +// bgcolor: "bg-[#5dbdd3]", +// }, +// { +// name: "Stacking & Farming", +// title: "Stacking & Farming - 15% 3,000,000 SGPT", +// description: " ", +// precent: "15", +// color: "#4591b8", +// bgcolor: "bg-[#4591b8]", +// }, +// { +// name: "Marketing & Promotion", +// title: "Marketing & Promotion - 15% 3,000,000 SGPT", +// description: " ", +// precent: "15", +// color: "#3b6696", +// bgcolor: "bg-[#3b6696]", +// }, +// { +// name: "Public Sale", +// title: "Public Sale - 14% 2,800,000 SGPT", +// description: " ", +// precent: "14", +// color: "#353c6e", +// bgcolor: "bg-[#353c6e]", +// }, +// { +// name: "Reward & Q&A", +// title: "Reward & Q&A - 10% 2,000,000 SGPT", +// description: " ", +// precent: "10", +// color: "#705788", +// bgcolor: "bg-[#705788]", +// }, +// { +// name: "Advisor", +// title: "Advisor - 10% 2,000,000 SGPT", +// description: " ", +// precent: "10", +// color: "#a5769e", +// bgcolor: "bg-[#a5769e]", +// }, +// { +// name: "Treasury", +// title: "Treasury - 14% 2,800,000 SGPT", +// description: " ", +// precent: "14", +// color: "#d59ab3", +// bgcolor: "bg-[#d59ab3]", +// }, +// ]; +// const TokenomicsSection = (props: Props) => { +// const [isVisible, setIsVisible] = useState(false); + +// useEffect(() => { +// const section = document.getElementById("tokenomics"); +// const observer = new IntersectionObserver( +// ([entry]) => { +// setIsVisible(entry.isIntersecting); +// }, +// { threshold: 0 } +// ); + +// if (!section) { +// return; +// } +// observer.observe(section); + +// return () => { +// observer.unobserve(section); +// }; +// }, []); + +// useEffect(() => { +// console.log("isVisible", isVisible); +// }, [isVisible]); + +// const styles = useSpring({ +// opacity: isVisible ? 1 : 0, +// transform: isVisible ? "scaleX(1)" : "scaleX(0.5)", +// config: { +// duration: 300, +// }, +// }); +// const styles1 = useSpring({ +// opacity: isVisible ? 1 : 0, +// transform: isVisible ? "scaleX(1)" : "scaleX(0.3)", +// config: { +// duration: 500, +// }, +// }); + +// const plugins = { +// id: "textCenter", +// // beforeDatasetsDraw(chart: any, arg: any, pluginsOptions: any) { +// // const { ctx, data } = chart; +// // ctx.save(); +// // ctx.fillStyle = "#fff"; +// // ctx.font = "bolder 30px sen"; +// // ctx.textAlign = "center"; +// // ctx.textBaseline = "middle"; +// // ctx.fillText( +// // `TOTAL SUPPLE`, +// // chart.getDatasetMeta(0).data[0].x, +// // chart.getDatasetMeta(0).data[0].y - 20 +// // ); +// // ctx.fillText( +// // `20,000,000 SGPT`, +// // chart.getDatasetMeta(0).data[0].x, +// // chart.getDatasetMeta(0).data[0].y + 25 +// // ); +// // }, +// }; +// const [userData, setUserData] = useState({ +// labels: tokenomics.map((data) => data.name), +// datasets: [ +// { +// label: "text", +// data: tokenomics.map((data) => data.precent), +// backgroundColor: tokenomics.map((data) => data.color), +// // cutout: "40%", +// borderWidth: 1, +// datalabels: { +// font: { +// weight: "bold", +// }, +// anchor: "end", +// align: "start", +// offset: -30, +// }, +// }, +// ], +// }); +// const options = { +// layout: { +// padding: { +// top: 50, +// bottom: 50, +// right: 50, +// left: 50, +// }, +// }, +// hoverBorderWidth: 4, +// plugins: { +// legend: { +// display: false, +// }, +// datalabels: { +// font: { +// size: 22, +// }, +// color: "#fff", +// formatter: (context: any, agrs: any) => { +// const index = agrs.dataIndex; +// console.log(agrs); +// return agrs.chart.data.labels[index]; +// }, +// }, +// tooltip: { +// callbacks: { +// label: (context: any) => { +// const num = ((20000000 * context.parsed) / 100).toLocaleString( +// "en-us" +// ); +// return ` ${context.label} ${context.parsed}% - ${num} SGPT`; +// }, +// }, +// }, +// }, +// }; +// ChartJS.register(ChartDataLabels); +// return ( +//
            +//
            +//

            +// Tokenomics +//

            +//
            +//
            +// +// +// +//
            + +// {/*
            +//
              +// {tokenomics.map((item, index) => { +// return ( +// +//
              +//

              +// {item.title} +//

              +//

              {item.description}

              +//
              +// ); +// })} +//
            +//
            */} +//
            +//
            +//
            +// ); +// }; + +// export default TokenomicsSection; --> +// // Qna + +// // import { useSpring, animated } from "@react-spring/web"; +// // import React, { useEffect, useRef, useState } from "react"; +// // import { +// // VscArrowDown, +// // VscChevronDown, +// // VscDebugBreakpointLog, +// // VscDiffAdded, +// // } from "react-icons/vsc"; +// // import "../animated/QnASection.css"; +// // type Props = {}; + +// // const QnASection = (props: Props) => { +// // const listQnA = [ +// // { +// // id: 1, +// // title: +// // "What is Fight Out dfgbdjka dfgh dfsgdfsh dfhsdf dfhjfsgjrt eryery dfhdfh jytjrty dfhdfh sdgsdg?", +// // bgcolor: "bg-[#CC99FF]", +// // contents: [ +// // { +// // id: 1, +// // content: +// // "Fight Out is changing the blueprint for metaverses. At its heart, Fight Out is a gaming platform that rewards users for competing and winning in a variety of contest modes. A player's ability to compete and how much they are rewarded is determined in part by their avatar’s attributes. Stats are increased through the Fight Out app by training in real -life.", +// // bgcolor: "bg-[#9999FF]", +// // }, +// // { +// // id: 2, +// // content: +// // "Fight Out is changing the blueprint for metaverses. At its heart, Fight Out is a gaming platform that rewards users for competing and winning in a variety of contest modes. A player's ability to compete and how much they are rewarded is determined in part by their avatar’s attributes. Stats are increased through the Fight Out app by training in real -life.", +// // bgcolor: "bg-[#6699FF]", +// // }, +// // { +// // id: 3, +// // content: +// // "Fight Out is changing the blueprint for metaverses. At its heart, Fight Out is a gaming platform that rewards users for competing and winning in a variety of contest modes. A player's ability to compete and how much they are rewarded is determined in part by their avatar’s attributes. Stats are increased through the Fight Out app by training in real -life.", +// // bgcolor: "bg-[#3399FF]", +// // }, +// // { +// // id: 4, +// // content: +// // "Fight Out is changing the blueprint for metaverses. At its heart, Fight Out is a gaming platform that rewards users for competing and winning in a variety of contest modes. A player's ability to compete and how much they are rewarded is determined in part by their avatar’s attributes. Stats are increased through the Fight Out app by training in real -life.", +// // bgcolor: "bg-[#0099FF]", +// // }, +// // ], +// // }, +// // { +// // id: 2, +// // title: "Abcd", +// // bgcolor: "bg-[#CC66FF]", + +// // contents: [ +// // { +// // id: 1, +// // bgcolor: "bg-[#9966FF]", +// // content: "ádasffjk12", +// // }, +// // { +// // id: 2, +// // bgcolor: "bg-[#6666FF]", +// // content: "ádasffj1k", +// // }, +// // { +// // id: 3, +// // bgcolor: "bg-[#3366FF]", +// // content: "ádasffj12k", +// // }, +// // { +// // id: 4, +// // bgcolor: "bg-[#0066FF]", +// // content: "ádasffj123k", +// // }, +// // ], +// // }, +// // { +// // id: 3, +// // title: "Abcd", +// // bgcolor: "bg-[#CC66FF]", + +// // contents: [ +// // { +// // id: 1, +// // bgcolor: "bg-[#9966FF]", +// // content: "ádasffjk12", +// // }, +// // { +// // id: 2, +// // bgcolor: "bg-[#6666FF]", +// // content: "ádasffj1k", +// // }, +// // { +// // id: 3, +// // bgcolor: "bg-[#3366FF]", +// // content: "ádasffj12k", +// // }, +// // { +// // id: 4, +// // bgcolor: "bg-[#0066FF]", +// // content: "ádasffj123k", +// // }, +// // ], +// // }, +// // { +// // id: 4, +// // title: "Abcd", +// // bgcolor: "bg-[#CC66FF]", + +// // contents: [ +// // { +// // id: 1, +// // bgcolor: "bg-[#9966FF]", +// // content: "ádasffjk12", +// // }, +// // { +// // id: 2, +// // bgcolor: "bg-[#6666FF]", +// // content: "ádasffj1k", +// // }, +// // { +// // id: 3, +// // bgcolor: "bg-[#3366FF]", +// // content: "ádasffj12k", +// // }, +// // { +// // id: 4, +// // bgcolor: "bg-[#0066FF]", +// // content: "ádasffj123k", +// // }, +// // ], +// // }, +// // ]; +// // const showListItem = (id: string, iconDropDown: string) => { +// // const iconDropDownid = document.getElementById(`${iconDropDown}`); +// // // const ulhidden = document.querySelector(`#${id} ul`); +// // const ulhidden = document.querySelector(`#${id}>ul`); +// // console.log(ulhidden); +// // ulhidden?.classList.toggle("block"); +// // ulhidden?.classList.toggle("showListQnA"); +// // ulhidden?.classList.toggle("hiddenListQnA"); +// // iconDropDownid?.classList.toggle("iconDropUp"); +// // iconDropDownid?.classList.toggle("iconDropDown"); +// // }; +// // const [isVisible, setIsVisible] = useState(false); + +// // useEffect(() => { +// // const section = document.querySelector("#qna"); +// // const observer = new IntersectionObserver( +// // ([entry]) => { +// // setIsVisible(entry.isIntersecting); +// // }, +// // { threshold: 0.2 } +// // ); + +// // if (!section) { +// // return; +// // } +// // observer.observe(section); + +// // return () => { +// // observer.unobserve(section); +// // }; +// // }, []); + +// // useEffect(() => { +// // console.log("isVisible", isVisible); +// // }, [isVisible]); + +// // const styles = useSpring({ +// // opacity: isVisible ? 1 : 0, +// // from: { +// // opacity: 0, +// // }, +// // to: { +// // opacity: isVisible ? 1 : 0, +// // }, +// // config: { +// // duration: 1000, +// // }, +// // }); + +// // return ( +// //
            +// //
            +// //

            +// // FAQS +// //

            +// //

            +// // See some of the most frequently asked questions about Fight +// // {/* Out here. Got a question that’s not on the list? Let us know +// // below! */} +// //

            +// //
            + +// // +// //
              +// // {listQnA.map((item, index) => { +// // return ( +// //
            • +// //
              +// //
              +// // +// // {item.title} +// // +// //
              +// // showListItem("title" + item.id, index + item.title) +// // } +// // > +// // +// //
              +// //
              +// //
                +// // {item.contents.map((list, index) => { +// // return ( +// //
              • +// //
                +// // +// // {list.content} +// // +// //
              • +// // ); +// // })} +// //
              +// //
            • +// // ); +// // })} +// //
            +// //
            +// //
            +// // ); +// // }; + +// // export default QnASection; diff --git a/tailwind.config.cjs b/tailwind.config.cjs index b9b890c..4549a87 100644 --- a/tailwind.config.cjs +++ b/tailwind.config.cjs @@ -5,13 +5,8 @@ module.exports = { extend: { keyframes: { listShowdown: { - "0%": { opacity: 0, transform: "translateY(-150px)" }, - "50%": { opacity: 0, transform: "translateY(-75px)" }, - "100%": { opacity: 1, transform: "translateY(0px)" }, - }, - listHidden: { - "100%": { opacity: 0, transform: "translateY(-150px)" }, - "0%": { opacity: 1, transform: "translateY(0px)" }, + "0%": { height: "0px", opacity: 0, transform: "translateY(-150px)" }, + "100%": { height: "164px", opacity: 1, transform: "translateY(0px)" }, }, }, },