Repository: thenewboston-developers/Website
Pull request #1902 (2021-06-27 05:29:35)

Analytics

angle943: Currently blocked by this issue: https://github.com/thenewboston-developers/Website-API/issues/120
angle943: Note to whoever wants to test this branch: I've added fake data to `api.thenewboston.com`, so when testing locally, change `.env.development` file to use that api, instead of `api-dev`
angle943: depends on this to be in production: https://github.com/thenewboston-developers/Website-API/pull/139

Patch:
diff --git a/package-lock.json b/package-lock.json
index 67fc4c9..78a04e7 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -36,6 +36,7 @@
         "react-syntax-highlighter": "^15.3.0",
         "react-toastify": "^6.0.8",
         "react-tsparticles": "^1.29.2",
+        "recharts": "^2.0.9",
         "sass": "^1.32.8",
         "yup": "^0.31.0"
       },
@@ -2871,6 +2872,32 @@
         "@babel/types": "^7.3.0"
       }
     },
+    "node_modules/@types/d3-path": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/@types/d3-path/-/d3-path-2.0.1.tgz",
+      "integrity": "sha512-6K8LaFlztlhZO7mwsZg7ClRsdLg3FJRzIIi6SZXDWmmSJc2x8dd2VkESbLXdk3p8cuvz71f36S0y8Zv2AxqvQw=="
+    },
+    "node_modules/@types/d3-scale": {
+      "version": "3.3.2",
+      "resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-3.3.2.tgz",
+      "integrity": "sha512-gGqr7x1ost9px3FvIfUMi5XA/F/yAf4UkUDtdQhpH92XCT0Oa7zkkRzY61gPVJq+DxpHn/btouw5ohWkbBsCzQ==",
+      "dependencies": {
+        "@types/d3-time": "^2"
+      }
+    },
+    "node_modules/@types/d3-shape": {
+      "version": "2.1.3",
+      "resolved": "https://registry.npmjs.org/@types/d3-shape/-/d3-shape-2.1.3.tgz",
+      "integrity": "sha512-HAhCel3wP93kh4/rq+7atLdybcESZ5bRHDEZUojClyZWsRuEMo3A52NGYJSh48SxfxEU6RZIVbZL2YFZ2OAlzQ==",
+      "dependencies": {
+        "@types/d3-path": "^2"
+      }
+    },
+    "node_modules/@types/d3-time": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/@types/d3-time/-/d3-time-2.1.1.tgz",
+      "integrity": "sha512-9MVYlmIgmRR31C5b4FVSWtuMmBHh2mOWQYfl7XAYOa8dsnb7iEmUmRSWSFgXFtkjxO65d7hTUHQC+RhR/9IWFg=="
+    },
     "node_modules/@types/eslint": {
       "version": "7.2.6",
       "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-7.2.6.tgz",
@@ -3199,6 +3226,11 @@
         "@types/react": "*"
       }
     },
+    "node_modules/@types/resize-observer-browser": {
+      "version": "0.1.6",
+      "resolved": "https://registry.npmjs.org/@types/resize-observer-browser/-/resize-observer-browser-0.1.6.tgz",
+      "integrity": "sha512-61IfTac0s9jvNtBCpyo86QeaN8qqpMGHdK0uGKCCIy2dt5/Yk84VduHIdWAcmkC5QvdkPL0p5eWYgUZtHKKUVg=="
+    },
     "node_modules/@types/resolve": {
       "version": "0.0.8",
       "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-0.0.8.tgz",
@@ -5379,6 +5411,11 @@
         "node": ">=0.10.0"
       }
     },
+    "node_modules/classnames": {
+      "version": "2.3.1",
+      "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.3.1.tgz",
+      "integrity": "sha512-OlQdbZ7gLfGarSqxesMesDa5uz7KFbID8Kpq/SxIoNGDqY8lSYs0D+hhtBXhcdB3rcbXArFr7vlHheLk1voeNA=="
+    },
     "node_modules/clean-css": {
       "version": "4.2.3",
       "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.2.3.tgz",
@@ -6190,6 +6227,11 @@
         "node": ">=8.0.0"
       }
     },
+    "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/css-what": {
       "version": "3.4.2",
       "resolved": "https://registry.npmjs.org/css-what/-/css-what-3.4.2.tgz",
@@ -6423,6 +6465,73 @@
         "type": "^1.0.1"
       }
     },
+    "node_modules/d3-array": {
+      "version": "2.12.1",
+      "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-2.12.1.tgz",
+      "integrity": "sha512-B0ErZK/66mHtEsR1TkPEEkwdy+WDesimkM5gpZr5Dsg54BiTA5RXtYW5qTLIAcekaS9xfZrzBLF/OAkB3Qn1YQ==",
+      "dependencies": {
+        "internmap": "^1.0.0"
+      }
+    },
+    "node_modules/d3-color": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-2.0.0.tgz",
+      "integrity": "sha512-SPXi0TSKPD4g9tw0NMZFnR95XVgUZiBH+uUTqQuDu1OsE2zomHU7ho0FISciaPvosimixwHFl3WHLGabv6dDgQ=="
+    },
+    "node_modules/d3-format": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-2.0.0.tgz",
+      "integrity": "sha512-Ab3S6XuE/Q+flY96HXT0jOXcM4EAClYFnRGY5zsjRGNy6qCYrQsMffs7cV5Q9xejb35zxW5hf/guKw34kvIKsA=="
+    },
+    "node_modules/d3-interpolate": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-2.0.1.tgz",
+      "integrity": "sha512-c5UhwwTs/yybcmTpAVqwSFl6vrQ8JZJoT5F7xNFK9pymv5C0Ymcc9/LIJHtYIggg/yS9YHw8i8O8tgb9pupjeQ==",
+      "dependencies": {
+        "d3-color": "1 - 2"
+      }
+    },
+    "node_modules/d3-path": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-2.0.0.tgz",
+      "integrity": "sha512-ZwZQxKhBnv9yHaiWd6ZU4x5BtCQ7pXszEV9CU6kRgwIQVQGLMv1oiL4M+MK/n79sYzsj+gcgpPQSctJUsLN7fA=="
+    },
+    "node_modules/d3-scale": {
+      "version": "3.3.0",
+      "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-3.3.0.tgz",
+      "integrity": "sha512-1JGp44NQCt5d1g+Yy+GeOnZP7xHo0ii8zsQp6PGzd+C1/dl0KGsp9A7Mxwp+1D1o4unbTTxVdU/ZOIEBoeZPbQ==",
+      "dependencies": {
+        "d3-array": "^2.3.0",
+        "d3-format": "1 - 2",
+        "d3-interpolate": "1.2.0 - 2",
+        "d3-time": "^2.1.1",
+        "d3-time-format": "2 - 3"
+      }
+    },
+    "node_modules/d3-shape": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-2.1.0.tgz",
+      "integrity": "sha512-PnjUqfM2PpskbSLTJvAzp2Wv4CZsnAgTfcVRTwW03QR3MkXF8Uo7B1y/lWkAsmbKwuecto++4NlsYcvYpXpTHA==",
+      "dependencies": {
+        "d3-path": "1 - 2"
+      }
+    },
+    "node_modules/d3-time": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-2.1.1.tgz",
+      "integrity": "sha512-/eIQe/eR4kCQwq7yxi7z4c6qEXf2IYGcjoWB5OOQy4Tq9Uv39/947qlDcN2TLkiTzQWzvnsuYPB9TrWaNfipKQ==",
+      "dependencies": {
+        "d3-array": "2"
+      }
+    },
+    "node_modules/d3-time-format": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-3.0.0.tgz",
+      "integrity": "sha512-UXJh6EKsHBTjopVqZBhFysQcoXSv/5yLONZvkQ5Kk3qbwiUYkdX17Xa1PT6U1ZWXGGfB1ey5L8dKMlFq2DO0Ag==",
+      "dependencies": {
+        "d3-time": "1 - 2"
+      }
+    },
     "node_modules/damerau-levenshtein": {
       "version": "1.0.6",
       "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.6.tgz",
@@ -6494,6 +6603,11 @@
       "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.2.1.tgz",
       "integrity": "sha512-KaL7+6Fw6i5A2XSnsbhm/6B+NuEA7TZ4vqxnd5tXz9sbKtrN9Srj8ab4vKVdK8YAqZO9P1kg45Y6YLoduPf+kw=="
     },
+    "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/decode-uri-component": {
       "version": "0.2.0",
       "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz",
@@ -8701,6 +8815,11 @@
       "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==",
       "dev": true
     },
+    "node_modules/fast-equals": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/fast-equals/-/fast-equals-2.0.3.tgz",
+      "integrity": "sha512-0EMw4TTUxsMDpDkCg0rXor2gsg+npVrMIHbEhvD0HZyIhUX6AktC/yasm+qKwfyswd06Qy95ZKk8p2crTo0iPA=="
+    },
     "node_modules/fast-glob": {
       "version": "3.2.4",
       "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.4.tgz",
@@ -10440,6 +10559,11 @@
         "node": ">= 0.4"
       }
     },
+    "node_modules/internmap": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/internmap/-/internmap-1.0.1.tgz",
+      "integrity": "sha512-lDB5YccMydFBtasVtxnZ3MRBHuaoE8GKsppq+EchKL2U4nK/DmEpPHNH8MZe5HkMtpSiTSOZwfN0tzYjO/lJEw=="
+    },
     "node_modules/invariant": {
       "version": "2.2.4",
       "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz",
@@ -14044,6 +14168,11 @@
       "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz",
       "integrity": "sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0="
     },
+    "node_modules/lodash.debounce": {
+      "version": "4.0.8",
+      "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz",
+      "integrity": "sha1-gteb/zCmfEAF/9XiUVMArZyk168="
+    },
     "node_modules/lodash.memoize": {
       "version": "4.1.2",
       "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz",
@@ -17782,6 +17911,11 @@
       "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-measure": {
       "version": "2.5.2",
       "resolved": "https://registry.npmjs.org/react-measure/-/react-measure-2.5.2.tgz",
@@ -17832,6 +17966,21 @@
         "node": ">=0.10.0"
       }
     },
+    "node_modules/react-resize-detector": {
+      "version": "6.7.4",
+      "resolved": "https://registry.npmjs.org/react-resize-detector/-/react-resize-detector-6.7.4.tgz",
+      "integrity": "sha512-wzvGmUdEDMhiUHVZGnl4kuyj/TEQhvbB5LyAGkbYXetwJ2O+u/zftmPvU+kxiO1h+d9aUqQBKcNLS7TvB3ytqA==",
+      "dependencies": {
+        "@types/resize-observer-browser": "^0.1.5",
+        "lodash.debounce": "^4.0.8",
+        "lodash.throttle": "^4.1.1",
+        "resize-observer-polyfill": "^1.5.1"
+      },
+      "peerDependencies": {
+        "react": "^16.0.0 || ^17.0.0",
+        "react-dom": "^16.0.0 || ^17.0.0"
+      }
+    },
     "node_modules/react-router": {
       "version": "5.2.0",
       "resolved": "https://registry.npmjs.org/react-router/-/react-router-5.2.0.tgz",
@@ -18017,6 +18166,44 @@
         "react-transition-group": "^4.3.0"
       }
     },
+    "node_modules/react-smooth": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/react-smooth/-/react-smooth-2.0.0.tgz",
+      "integrity": "sha512-wK4dBBR6P21otowgMT9toZk+GngMplGS1O5gk+2WSiHEXIrQgDvhR5IIlT74Vtu//qpTcipkgo21dD7a7AUNxw==",
+      "dependencies": {
+        "fast-equals": "^2.0.0",
+        "raf": "^3.4.0",
+        "react-transition-group": "2.9.0"
+      },
+      "peerDependencies": {
+        "prop-types": "^15.6.0",
+        "react": "^15.0.0 || ^16.0.0 || ^17.0.0",
+        "react-dom": "^15.0.0 || ^16.0.0 || ^17.0.0"
+      }
+    },
+    "node_modules/react-smooth/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/react-smooth/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/react-syntax-highlighter": {
       "version": "15.3.0",
       "resolved": "https://registry.npmjs.org/react-syntax-highlighter/-/react-syntax-highlighter-15.3.0.tgz",
@@ -18097,6 +18284,43 @@
         "node": ">=8.10.0"
       }
     },
+    "node_modules/recharts": {
+      "version": "2.0.10",
+      "resolved": "https://registry.npmjs.org/recharts/-/recharts-2.0.10.tgz",
+      "integrity": "sha512-yVIlHXPiSgxg8z+qApVnBcGVCLpluqNbXJenK3jKxsCb/FJzh77wyEztS6kXLXSC1RCZa7UABmBPBhqspMCF+g==",
+      "dependencies": {
+        "@types/d3-scale": "^3.0.0",
+        "@types/d3-shape": "^2.0.0",
+        "classnames": "^2.2.5",
+        "d3-interpolate": "^2.0.1",
+        "d3-scale": "^3.2.3",
+        "d3-shape": "^2.0.0",
+        "eventemitter3": "^4.0.1",
+        "lodash": "^4.17.19",
+        "react-is": "16.10.2",
+        "react-resize-detector": "^6.6.3",
+        "react-smooth": "^2.0.0",
+        "recharts-scale": "^0.4.4",
+        "reduce-css-calc": "^2.1.8"
+      },
+      "peerDependencies": {
+        "react": "^16.0.0 || ^17.0.0",
+        "react-dom": "^16.0.0 || ^17.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/recharts/node_modules/react-is": {
+      "version": "16.10.2",
+      "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.10.2.tgz",
+      "integrity": "sha512-INBT1QEgtcCCgvccr5/86CfD71fw9EPmDxgiJX4I2Ddr6ZsV6iFXsuby+qWJPtmNuMY0zByTsG4468P7nHuNWA=="
+    },
     "node_modules/recursive-readdir": {
       "version": "2.2.2",
       "resolved": "https://registry.npmjs.org/recursive-readdir/-/recursive-readdir-2.2.2.tgz",
@@ -18121,6 +18345,20 @@
         "node": ">=8"
       }
     },
+    "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/redux": {
       "version": "4.0.5",
       "resolved": "https://registry.npmjs.org/redux/-/redux-4.0.5.tgz",
@@ -25903,6 +26141,32 @@
         "@babel/types": "^7.3.0"
       }
     },
+    "@types/d3-path": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/@types/d3-path/-/d3-path-2.0.1.tgz",
+      "integrity": "sha512-6K8LaFlztlhZO7mwsZg7ClRsdLg3FJRzIIi6SZXDWmmSJc2x8dd2VkESbLXdk3p8cuvz71f36S0y8Zv2AxqvQw=="
+    },
+    "@types/d3-scale": {
+      "version": "3.3.2",
+      "resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-3.3.2.tgz",
+      "integrity": "sha512-gGqr7x1ost9px3FvIfUMi5XA/F/yAf4UkUDtdQhpH92XCT0Oa7zkkRzY61gPVJq+DxpHn/btouw5ohWkbBsCzQ==",
+      "requires": {
+        "@types/d3-time": "^2"
+      }
+    },
+    "@types/d3-shape": {
+      "version": "2.1.3",
+      "resolved": "https://registry.npmjs.org/@types/d3-shape/-/d3-shape-2.1.3.tgz",
+      "integrity": "sha512-HAhCel3wP93kh4/rq+7atLdybcESZ5bRHDEZUojClyZWsRuEMo3A52NGYJSh48SxfxEU6RZIVbZL2YFZ2OAlzQ==",
+      "requires": {
+        "@types/d3-path": "^2"
+      }
+    },
+    "@types/d3-time": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/@types/d3-time/-/d3-time-2.1.1.tgz",
+      "integrity": "sha512-9MVYlmIgmRR31C5b4FVSWtuMmBHh2mOWQYfl7XAYOa8dsnb7iEmUmRSWSFgXFtkjxO65d7hTUHQC+RhR/9IWFg=="
+    },
     "@types/eslint": {
       "version": "7.2.6",
       "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-7.2.6.tgz",
@@ -26233,6 +26497,11 @@
         "@types/react": "*"
       }
     },
+    "@types/resize-observer-browser": {
+      "version": "0.1.6",
+      "resolved": "https://registry.npmjs.org/@types/resize-observer-browser/-/resize-observer-browser-0.1.6.tgz",
+      "integrity": "sha512-61IfTac0s9jvNtBCpyo86QeaN8qqpMGHdK0uGKCCIy2dt5/Yk84VduHIdWAcmkC5QvdkPL0p5eWYgUZtHKKUVg=="
+    },
     "@types/resolve": {
       "version": "0.0.8",
       "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-0.0.8.tgz",
@@ -28117,6 +28386,11 @@
         }
       }
     },
+    "classnames": {
+      "version": "2.3.1",
+      "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.3.1.tgz",
+      "integrity": "sha512-OlQdbZ7gLfGarSqxesMesDa5uz7KFbID8Kpq/SxIoNGDqY8lSYs0D+hhtBXhcdB3rcbXArFr7vlHheLk1voeNA=="
+    },
     "clean-css": {
       "version": "4.2.3",
       "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.2.3.tgz",
@@ -28778,6 +29052,11 @@
         "source-map": "^0.6.1"
       }
     },
+    "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=="
+    },
     "css-what": {
       "version": "3.4.2",
       "resolved": "https://registry.npmjs.org/css-what/-/css-what-3.4.2.tgz",
@@ -28969,6 +29248,73 @@
         "type": "^1.0.1"
       }
     },
+    "d3-array": {
+      "version": "2.12.1",
+      "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-2.12.1.tgz",
+      "integrity": "sha512-B0ErZK/66mHtEsR1TkPEEkwdy+WDesimkM5gpZr5Dsg54BiTA5RXtYW5qTLIAcekaS9xfZrzBLF/OAkB3Qn1YQ==",
+      "requires": {
+        "internmap": "^1.0.0"
+      }
+    },
+    "d3-color": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-2.0.0.tgz",
+      "integrity": "sha512-SPXi0TSKPD4g9tw0NMZFnR95XVgUZiBH+uUTqQuDu1OsE2zomHU7ho0FISciaPvosimixwHFl3WHLGabv6dDgQ=="
+    },
+    "d3-format": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-2.0.0.tgz",
+      "integrity": "sha512-Ab3S6XuE/Q+flY96HXT0jOXcM4EAClYFnRGY5zsjRGNy6qCYrQsMffs7cV5Q9xejb35zxW5hf/guKw34kvIKsA=="
+    },
+    "d3-interpolate": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-2.0.1.tgz",
+      "integrity": "sha512-c5UhwwTs/yybcmTpAVqwSFl6vrQ8JZJoT5F7xNFK9pymv5C0Ymcc9/LIJHtYIggg/yS9YHw8i8O8tgb9pupjeQ==",
+      "requires": {
+        "d3-color": "1 - 2"
+      }
+    },
+    "d3-path": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-2.0.0.tgz",
+      "integrity": "sha512-ZwZQxKhBnv9yHaiWd6ZU4x5BtCQ7pXszEV9CU6kRgwIQVQGLMv1oiL4M+MK/n79sYzsj+gcgpPQSctJUsLN7fA=="
+    },
+    "d3-scale": {
+      "version": "3.3.0",
+      "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-3.3.0.tgz",
+      "integrity": "sha512-1JGp44NQCt5d1g+Yy+GeOnZP7xHo0ii8zsQp6PGzd+C1/dl0KGsp9A7Mxwp+1D1o4unbTTxVdU/ZOIEBoeZPbQ==",
+      "requires": {
+        "d3-array": "^2.3.0",
+        "d3-format": "1 - 2",
+        "d3-interpolate": "1.2.0 - 2",
+        "d3-time": "^2.1.1",
+        "d3-time-format": "2 - 3"
+      }
+    },
+    "d3-shape": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-2.1.0.tgz",
+      "integrity": "sha512-PnjUqfM2PpskbSLTJvAzp2Wv4CZsnAgTfcVRTwW03QR3MkXF8Uo7B1y/lWkAsmbKwuecto++4NlsYcvYpXpTHA==",
+      "requires": {
+        "d3-path": "1 - 2"
+      }
+    },
+    "d3-time": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-2.1.1.tgz",
+      "integrity": "sha512-/eIQe/eR4kCQwq7yxi7z4c6qEXf2IYGcjoWB5OOQy4Tq9Uv39/947qlDcN2TLkiTzQWzvnsuYPB9TrWaNfipKQ==",
+      "requires": {
+        "d3-array": "2"
+      }
+    },
+    "d3-time-format": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-3.0.0.tgz",
+      "integrity": "sha512-UXJh6EKsHBTjopVqZBhFysQcoXSv/5yLONZvkQ5Kk3qbwiUYkdX17Xa1PT6U1ZWXGGfB1ey5L8dKMlFq2DO0Ag==",
+      "requires": {
+        "d3-time": "1 - 2"
+      }
+    },
     "damerau-levenshtein": {
       "version": "1.0.6",
       "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.6.tgz",
@@ -29025,6 +29371,11 @@
       "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.2.1.tgz",
       "integrity": "sha512-KaL7+6Fw6i5A2XSnsbhm/6B+NuEA7TZ4vqxnd5tXz9sbKtrN9Srj8ab4vKVdK8YAqZO9P1kg45Y6YLoduPf+kw=="
     },
+    "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=="
+    },
     "decode-uri-component": {
       "version": "0.2.0",
       "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz",
@@ -30801,6 +31152,11 @@
       "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==",
       "dev": true
     },
+    "fast-equals": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/fast-equals/-/fast-equals-2.0.3.tgz",
+      "integrity": "sha512-0EMw4TTUxsMDpDkCg0rXor2gsg+npVrMIHbEhvD0HZyIhUX6AktC/yasm+qKwfyswd06Qy95ZKk8p2crTo0iPA=="
+    },
     "fast-glob": {
       "version": "3.2.4",
       "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.4.tgz",
@@ -32222,6 +32578,11 @@
         "side-channel": "^1.0.2"
       }
     },
+    "internmap": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/internmap/-/internmap-1.0.1.tgz",
+      "integrity": "sha512-lDB5YccMydFBtasVtxnZ3MRBHuaoE8GKsppq+EchKL2U4nK/DmEpPHNH8MZe5HkMtpSiTSOZwfN0tzYjO/lJEw=="
+    },
     "invariant": {
       "version": "2.2.4",
       "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz",
@@ -35035,6 +35396,11 @@
       "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz",
       "integrity": "sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0="
     },
+    "lodash.debounce": {
+      "version": "4.0.8",
+      "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz",
+      "integrity": "sha1-gteb/zCmfEAF/9XiUVMArZyk168="
+    },
     "lodash.memoize": {
       "version": "4.1.2",
       "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz",
@@ -38135,6 +38501,11 @@
       "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
       "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
     },
+    "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=="
+    },
     "react-measure": {
       "version": "2.5.2",
       "resolved": "https://registry.npmjs.org/react-measure/-/react-measure-2.5.2.tgz",
@@ -38175,6 +38546,17 @@
       "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.8.3.tgz",
       "integrity": "sha512-X8jZHc7nCMjaCqoU+V2I0cOhNW+QMBwSUkeXnTi8IPe6zaRWfn60ZzvFDZqWPfmSJfjub7dDW1SP0jaHWLu/hg=="
     },
+    "react-resize-detector": {
+      "version": "6.7.4",
+      "resolved": "https://registry.npmjs.org/react-resize-detector/-/react-resize-detector-6.7.4.tgz",
+      "integrity": "sha512-wzvGmUdEDMhiUHVZGnl4kuyj/TEQhvbB5LyAGkbYXetwJ2O+u/zftmPvU+kxiO1h+d9aUqQBKcNLS7TvB3ytqA==",
+      "requires": {
+        "@types/resize-observer-browser": "^0.1.5",
+        "lodash.debounce": "^4.0.8",
+        "lodash.throttle": "^4.1.1",
+        "resize-observer-polyfill": "^1.5.1"
+      }
+    },
     "react-router": {
       "version": "5.2.0",
       "resolved": "https://registry.npmjs.org/react-router/-/react-router-5.2.0.tgz",
@@ -38335,6 +38717,37 @@
         "react-transition-group": "^4.3.0"
       }
     },
+    "react-smooth": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/react-smooth/-/react-smooth-2.0.0.tgz",
+      "integrity": "sha512-wK4dBBR6P21otowgMT9toZk+GngMplGS1O5gk+2WSiHEXIrQgDvhR5IIlT74Vtu//qpTcipkgo21dD7a7AUNxw==",
+      "requires": {
+        "fast-equals": "^2.0.0",
+        "raf": "^3.4.0",
+        "react-transition-group": "2.9.0"
+      },
+      "dependencies": {
+        "dom-helpers": {
+          "version": "3.4.0",
+          "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-3.4.0.tgz",
+          "integrity": "sha512-LnuPJ+dwqKDIyotW1VzmOZ5TONUN7CwkCR5hrgawTUbkBGYdeoNLZo6nNfGkCrjtE1nXXaj7iMMpDa8/d9WoIA==",
+          "requires": {
+            "@babel/runtime": "^7.1.2"
+          }
+        },
+        "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==",
+          "requires": {
+            "dom-helpers": "^3.4.0",
+            "loose-envify": "^1.4.0",
+            "prop-types": "^15.6.2",
+            "react-lifecycles-compat": "^3.0.4"
+          }
+        }
+      }
+    },
     "react-syntax-highlighter": {
       "version": "15.3.0",
       "resolved": "https://registry.npmjs.org/react-syntax-highlighter/-/react-syntax-highlighter-15.3.0.tgz",
@@ -38407,6 +38820,41 @@
         "picomatch": "^2.2.1"
       }
     },
+    "recharts": {
+      "version": "2.0.10",
+      "resolved": "https://registry.npmjs.org/recharts/-/recharts-2.0.10.tgz",
+      "integrity": "sha512-yVIlHXPiSgxg8z+qApVnBcGVCLpluqNbXJenK3jKxsCb/FJzh77wyEztS6kXLXSC1RCZa7UABmBPBhqspMCF+g==",
+      "requires": {
+        "@types/d3-scale": "^3.0.0",
+        "@types/d3-shape": "^2.0.0",
+        "classnames": "^2.2.5",
+        "d3-interpolate": "^2.0.1",
+        "d3-scale": "^3.2.3",
+        "d3-shape": "^2.0.0",
+        "eventemitter3": "^4.0.1",
+        "lodash": "^4.17.19",
+        "react-is": "16.10.2",
+        "react-resize-detector": "^6.6.3",
+        "react-smooth": "^2.0.0",
+        "recharts-scale": "^0.4.4",
+        "reduce-css-calc": "^2.1.8"
+      },
+      "dependencies": {
+        "react-is": {
+          "version": "16.10.2",
+          "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.10.2.tgz",
+          "integrity": "sha512-INBT1QEgtcCCgvccr5/86CfD71fw9EPmDxgiJX4I2Ddr6ZsV6iFXsuby+qWJPtmNuMY0zByTsG4468P7nHuNWA=="
+        }
+      }
+    },
+    "recharts-scale": {
+      "version": "0.4.5",
+      "resolved": "https://registry.npmjs.org/recharts-scale/-/recharts-scale-0.4.5.tgz",
+      "integrity": "sha512-kivNFO+0OcUNu7jQquLXAxz1FIwZj8nrj+YkOKc5694NbjCvcT6aSZiIzNzd2Kul4o4rTto8QVR9lMNtxD4G1w==",
+      "requires": {
+        "decimal.js-light": "^2.4.1"
+      }
+    },
     "recursive-readdir": {
       "version": "2.2.2",
       "resolved": "https://registry.npmjs.org/recursive-readdir/-/recursive-readdir-2.2.2.tgz",
@@ -38425,6 +38873,22 @@
         "strip-indent": "^3.0.0"
       }
     },
+    "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==",
+      "requires": {
+        "css-unit-converter": "^1.1.1",
+        "postcss-value-parser": "^3.3.0"
+      },
+      "dependencies": {
+        "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=="
+        }
+      }
+    },
     "redux": {
       "version": "4.0.5",
       "resolved": "https://registry.npmjs.org/redux/-/redux-4.0.5.tgz",
diff --git a/package.json b/package.json
index 680282d..2fe307d 100644
--- a/package.json
+++ b/package.json
@@ -31,6 +31,7 @@
     "react-syntax-highlighter": "^15.3.0",
     "react-toastify": "^6.0.8",
     "react-tsparticles": "^1.29.2",
+    "recharts": "^2.0.9",
     "sass": "^1.32.8",
     "yup": "^0.31.0"
   },
diff --git a/src/apis/analytics/index.ts b/src/apis/analytics/index.ts
new file mode 100644
index 0000000..1037f5c
--- /dev/null
+++ b/src/apis/analytics/index.ts
@@ -0,0 +1,26 @@
+import axios from 'axios';
+
+import {Analytics, AnalyticsCategory} from 'types/analytics';
+import {PaginatedResponse} from 'types/api';
+
+export async function getAnalytics(category: string): Promise<Analytics[]> {
+  const response = await axios.get<PaginatedResponse<Analytics>>(
+    `${process.env.REACT_APP_BACKEND_API}/analytics?category=${category}`,
+  );
+
+  if (!response.data) {
+    throw new Error('Error while fetching analytics data, please try again.');
+  }
+  return response.data.results;
+}
+
+export async function getAnalyticsCategories(): Promise<AnalyticsCategory[]> {
+  const response = await axios.get<PaginatedResponse<AnalyticsCategory>>(
+    `${process.env.REACT_APP_BACKEND_API}/analytics_categories`,
+  );
+
+  if (!response.data) {
+    throw new Error('Error while fetching analytics categories data, please try again.');
+  }
+  return response.data.results;
+}
diff --git a/src/components/FlatNavLinks/FlatNavLinks.scss b/src/components/FlatNavLinks/FlatNavLinks.scss
index f6781e2..b2685b1 100644
--- a/src/components/FlatNavLinks/FlatNavLinks.scss
+++ b/src/components/FlatNavLinks/FlatNavLinks.scss
@@ -1,3 +1,5 @@
+@import 'styles/font-mixins';
+
 .FlatNavLinks {
   margin-top: 30px;
   padding: 1px;
@@ -7,7 +9,7 @@
     background: transparent;
     border: 0;
     border-radius: 6px;
-    color: var(--color-sail-gray-400);
+    color: var(--color-gray-500);
     cursor: pointer;
     display: flex;
     font-weight: var(--font-weight-medium);
@@ -18,13 +20,14 @@
     transition: background-color 0.1s;
     width: 100%;
 
-    &:hover {
-      background: var(--color-sail-gray-100);
+    &:hover,
+    &--active {
+      @extend %h4;
+      color: var(--color-blue-900);
     }
 
     &--active {
-      background: var(--color-sail-gray-100);
-      color: var(--color-primary);
+      font-weight: var(--font-weight-bold);
     }
   }
 
diff --git a/src/components/Layout/index.tsx b/src/components/Layout/index.tsx
index b82a94f..4422b52 100644
--- a/src/components/Layout/index.tsx
+++ b/src/components/Layout/index.tsx
@@ -1,7 +1,8 @@
 import React, {FC, ReactNode, useEffect} from 'react';
 import {useLocation} from 'react-router-dom';
 
-import {Container, Footer, GoToTop} from 'components';
+import {Container, GoToTop} from 'components';
+import Footer from 'containers/Footer';
 import TopNav from 'containers/TopNav';
 import './Layout.scss';
 
diff --git a/src/components/index.ts b/src/components/index.ts
index 6310bee..eacdb32 100644
--- a/src/components/index.ts
+++ b/src/components/index.ts
@@ -25,7 +25,6 @@ import DropdownInput from './DropdownInput';
 import EmptyPage from './EmptyPage';
 import FaqDropdownCard from './FaqDropdownCard';
 import FlatNavLinks from './FlatNavLinks';
-import Footer from './Footer';
 import {Button, ErrorMessage, Input} from './FormElements';
 import GoToTop from './GoToTop';
 import HashLink from './HashLink';
@@ -83,7 +82,6 @@ export {
   ErrorMessage,
   FaqDropdownCard,
   FlatNavLinks,
-  Footer,
   GoToTop,
   HashLink,
   Input,
diff --git a/src/containers/Analytics/Analytics.scss b/src/containers/Analytics/Analytics.scss
new file mode 100644
index 0000000..14be948
--- /dev/null
+++ b/src/containers/Analytics/Analytics.scss
@@ -0,0 +1,120 @@
+@import 'styles/font-mixins';
+
+$border: 1px solid var(--color-gray-075);
+$footer-height: 348px;
+$icon-container-height: 78px;
+$top-nav-height: 60px;
+
+.Analytics {
+  display: grid;
+  grid-template-columns: 352px auto;
+  grid-template-rows: [icon-start title-start] 78px [icon-end left-menu-start] 29px [title-end main-start] min-content [left-menu-end main-end];
+
+  @media (max-width: 992px) {
+    grid-template-columns: auto;
+    grid-template-rows: unset;
+  }
+
+  &__icon-container {
+    align-items: center;
+    border-bottom: $border;
+    border-right: $border;
+    display: flex;
+    padding: 0 24px;
+
+    @media (max-width: 992px) {
+      height: 64px;
+      padding: 0 48px;
+    }
+
+    @media (max-width: 768px) {
+      padding: 0 24px;
+    }
+  }
+
+  &__icon-text {
+    font-size: var(--font-size-h3);
+    margin-left: 16px;
+  }
+
+  &__left-menu {
+    border-right: $border;
+    grid-column: 1 / span 1;
+    grid-row: left-menu-start / left-menu-end;
+    min-height: calc(100vh - #{$top-nav-height + $footer-height + $icon-container-height});
+    padding-bottom: 30px;
+
+    @media (max-width: 992px) {
+      display: none;
+    }
+  }
+
+  &__loading-container {
+    display: flex;
+    justify-content: center;
+    margin-top: 30px;
+  }
+
+  &__main-container {
+    grid-column: 2 / -1;
+    grid-row: main-start / main-end;
+    margin-bottom: 170px;
+
+    @media (max-width: 992px) {
+      grid-column: unset;
+      grid-row: unset;
+      padding: 0 12px;
+    }
+
+    @media (max-width: 768px) {
+      padding: 0;
+    }
+  }
+
+  &__title {
+    @extend %display2;
+    display: inline;
+    margin-right: 16px;
+  }
+
+  &__title-container {
+    border-bottom: $border;
+    grid-column: 2 / -1;
+    grid-row: title-start / title-end;
+    padding: 32px;
+
+    @media (max-width: 992px) {
+      grid-column: unset;
+      grid-row: unset;
+      padding: 32px 48px;
+    }
+
+    @media (max-width: 768px) {
+      border-bottom: none;
+      padding: 32px 24px;
+    }
+  }
+
+  &__weekly {
+    color: var(--color-gray-200);
+    font-size: var(--font-size-h2);
+    font-weight: var(--font-weight-light);
+  }
+
+  &__wrapper {
+    border-top: $border;
+  }
+
+  .AnalyticsGraph {
+    border-bottom: $border;
+    border-right: $border;
+
+    &:nth-child(even) {
+      border-right: none;
+    }
+
+    @media (max-width: 768px) {
+      border-right: none;
+    }
+  }
+}
diff --git a/src/containers/Analytics/AnalyticsGraph/AnalyticsGraph.scss b/src/containers/Analytics/AnalyticsGraph/AnalyticsGraph.scss
new file mode 100644
index 0000000..e0d0a2e
--- /dev/null
+++ b/src/containers/Analytics/AnalyticsGraph/AnalyticsGraph.scss
@@ -0,0 +1,11 @@
+@import 'styles/font-mixins';
+
+.AnalyticsGraph {
+  padding: 32px;
+
+  &__title {
+    @extend %h3;
+    display: block;
+    margin-bottom: 28px;
+  }
+}
diff --git a/src/containers/Analytics/AnalyticsGraph/index.tsx b/src/containers/Analytics/AnalyticsGraph/index.tsx
new file mode 100644
index 0000000..c289a0c
--- /dev/null
+++ b/src/containers/Analytics/AnalyticsGraph/index.tsx
@@ -0,0 +1,40 @@
+import React, {FC} from 'react';
+import format from 'date-fns/format';
+import parseISO from 'date-fns/parseISO';
+import {CartesianGrid, Line, LineChart, ResponsiveContainer, XAxis, YAxis} from 'recharts';
+
+import {AnalyticsData} from 'types/analytics';
+import './AnalyticsGraph.scss';
+
+interface AnalyticsGraphProps {
+  data: AnalyticsData[];
+  title: string;
+}
+
+const styledTick = {fill: '#4f566b', fontSize: 9};
+
+const AnalyticsGraph: FC<AnalyticsGraphProps> = ({data, title}) => {
+  const formatDate = (date: string | number) => {
+    if (date === 'auto' || typeof date === 'number') return '';
+
+    return date.toString().length ? format(parseISO(date), 'MMM dd') : '';
+  };
+
+  return (
+    <div className="AnalyticsGraph">
+      <span className="AnalyticsGraph__title">{title}</span>
+      {/* width can't be 100% due to some responsive bug */}
+      {/* https://stackoverflow.com/questions/50891591/recharts-responsive-container-does-not-resize-correctly-in-flexbox */}
+      <ResponsiveContainer width="99%" height={225}>
+        <LineChart data={data}>
+          <CartesianGrid strokeDasharray="3 3" />
+          <XAxis dataKey="date" tick={styledTick} tickFormatter={formatDate} tickMargin={5} />
+          <YAxis tick={styledTick} tickMargin={5} />
+          <Line type="monotone" dataKey="value" stroke="#7dabf8" />
+        </LineChart>
+      </ResponsiveContainer>
+    </div>
+  );
+};
+
+export default AnalyticsGraph;
diff --git a/src/containers/Analytics/AnalyticsIcon.tsx b/src/containers/Analytics/AnalyticsIcon.tsx
new file mode 100644
index 0000000..b28e807
--- /dev/null
+++ b/src/containers/Analytics/AnalyticsIcon.tsx
@@ -0,0 +1,56 @@
+import React, {FC} from 'react';
+
+const AnalyticsIcon: FC = () => {
+  return (
+    <svg width="38" height="38" viewBox="0 0 38 38" fill="none" xmlns="http://www.w3.org/2000/svg">
+      <g filter="url(#filter0_d)">
+        <rect x="3" y="3" width="32" height="32" rx="6" fill="white" />
+      </g>
+      <path
+        opacity="0.23"
+        d="M13.5031 17.8979C14.7188 15.7737 17.9277 14.8614 20.4419 15.0169C21.1284 15.0594 22.5096 15.1449 23.5881 15.9073C25.6593 17.3715 25.3403 20.432 23.3576 22.2339C23.1023 22.4659 21.335 24.0206 18.5809 23.9998C16.5645 23.9846 15.1492 23.1331 14.9771 23.027C14.7597 22.893 14.2802 22.5745 13.8481 22.0693C12.8327 20.8823 12.7435 19.2252 13.5031 17.8979Z"
+        fill="url(#paint0_linear)"
+      />
+      <path
+        d="M12.25 11.125H11.125V25.75C11.125 26.0484 11.2435 26.3345 11.4545 26.5455C11.6655 26.7565 11.9516 26.875 12.25 26.875H26.875V25.75H12.25V11.125Z"
+        fill="#FA8389"
+      />
+      <path
+        d="M26.875 15.0625H22.9375V16.1875H24.9569L20.6875 20.4569L18.2744 18.0381C18.2221 17.9854 18.1599 17.9436 18.0913 17.915C18.0228 17.8864 17.9493 17.8717 17.875 17.8717C17.8007 17.8717 17.7272 17.8864 17.6587 17.915C17.5901 17.9436 17.5279 17.9854 17.4756 18.0381L13.375 22.1444L14.1681 22.9375L17.875 19.2306L20.2881 21.6494C20.3404 21.7021 20.4026 21.7439 20.4712 21.7725C20.5397 21.8011 20.6132 21.8158 20.6875 21.8158C20.7618 21.8158 20.8353 21.8011 20.9038 21.7725C20.9724 21.7439 21.0346 21.7021 21.0869 21.6494L25.75 16.9806V19H26.875V15.0625Z"
+        fill="#FA8389"
+      />
+      <defs>
+        <filter
+          id="filter0_d"
+          x="0"
+          y="0"
+          width="38"
+          height="38"
+          filterUnits="userSpaceOnUse"
+          colorInterpolationFilters="sRGB"
+        >
+          <feFlood floodOpacity="0" result="BackgroundImageFix" />
+          <feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" />
+          <feOffset />
+          <feGaussianBlur stdDeviation="1.5" />
+          <feColorMatrix type="matrix" values="0 0 0 0 0.568627 0 0 0 0 0.701961 0 0 0 0 0.980392 0 0 0 0.19 0" />
+          <feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow" />
+          <feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow" result="shape" />
+        </filter>
+        <linearGradient
+          id="paint0_linear"
+          x1="12.2702"
+          y1="13.8299"
+          x2="18.4796"
+          y2="22.7953"
+          gradientUnits="userSpaceOnUse"
+        >
+          <stop stopColor="#DAE3FE" />
+          <stop offset="1" stopColor="#E9EFFD" />
+        </linearGradient>
+      </defs>
+    </svg>
+  );
+};
+
+export default AnalyticsIcon;
diff --git a/src/containers/Analytics/AnalyticsMobileDropdown/AnalyticsMobileDropdown.scss b/src/containers/Analytics/AnalyticsMobileDropdown/AnalyticsMobileDropdown.scss
new file mode 100644
index 0000000..254b251
--- /dev/null
+++ b/src/containers/Analytics/AnalyticsMobileDropdown/AnalyticsMobileDropdown.scss
@@ -0,0 +1,43 @@
+@import 'styles/font-mixins';
+
+$border: 1px solid var(--color-gray-075);
+
+.AnalyticsMobileDropdown {
+  align-items: center;
+  background: var(--color-white);
+  border-bottom: $border;
+  border-left: none;
+  border-right: none;
+  border-top: none;
+  cursor: pointer;
+  display: flex;
+  height: 56px;
+  justify-content: space-between;
+  padding: 0 48px;
+
+  @media (max-width: 768px) {
+    padding: 0 24px;
+  }
+
+  &__dropdown {
+    width: calc(100vw - 2 * 24px - 2 * 12px); // subtracting side margin and also padding of popover
+
+    @media (max-width: 576px) {
+      width: calc(100vw - 2 * 8px - 2 * 12px);
+    }
+  }
+
+  &__toggle {
+    transform: rotate(0deg);
+    transition: transform 0.3s;
+
+    &--open {
+      transform: rotate(180deg);
+    }
+  }
+
+  &__type {
+    @extend %h3;
+    font-weight: var(--font-weight-bold);
+  }
+}
diff --git a/src/containers/Analytics/AnalyticsMobileDropdown/index.tsx b/src/containers/Analytics/AnalyticsMobileDropdown/index.tsx
new file mode 100644
index 0000000..a7ebde2
--- /dev/null
+++ b/src/containers/Analytics/AnalyticsMobileDropdown/index.tsx
@@ -0,0 +1,57 @@
+import React, {FC, ReactNode, useCallback, useState} from 'react';
+import clsx from 'clsx';
+import {Icon, IconType} from '@thenewboston/ui';
+
+import {Popover} from 'components';
+import {useWindowDimensions} from 'hooks';
+import {AnalyticsCategory} from 'types/analytics';
+
+import './AnalyticsMobileDropdown.scss';
+
+interface AnalyticsMobileDropdownProps {
+  navLinks: ReactNode;
+  selectedCategory: AnalyticsCategory | null;
+}
+
+const AnalyticsMobileDropdown: FC<AnalyticsMobileDropdownProps> = ({navLinks, selectedCategory}) => {
+  const [anchorEl, setAnchorEl] = useState<HTMLButtonElement | null>(null);
+  const {clientWidth} = useWindowDimensions();
+
+  const popoverIsOpen = !!anchorEl;
+
+  const unsetAnchorEl = useCallback(() => {
+    setAnchorEl(null);
+  }, [setAnchorEl]);
+
+  const handleButtonClick = (e: React.MouseEvent<HTMLButtonElement, MouseEvent>): void => {
+    if (!anchorEl) {
+      setAnchorEl(e.currentTarget);
+      return;
+    }
+    unsetAnchorEl();
+  };
+
+  return (
+    <>
+      <button className="AnalyticsMobileDropdown" onClick={handleButtonClick}>
+        <span className="AnalyticsMobileDropdown__type">{selectedCategory?.title || ''}</span>
+        <Icon
+          className={clsx('AnalyticsMobileDropdown__toggle', {'AnalyticsMobileDropdown__toggle--open': popoverIsOpen})}
+          icon={IconType.chevronDown}
+          size={24}
+        />
+      </button>
+      <Popover
+        anchorEl={anchorEl}
+        anchorOrigin={{horizontal: 'left', vertical: 'bottom'}}
+        transformOffset={{horizontal: clientWidth > 768 ? 24 : 8, vertical: 0}}
+        closePopover={unsetAnchorEl}
+        open={popoverIsOpen}
+      >
+        <div className="AnalyticsMobileDropdown__dropdown">{navLinks}</div>
+      </Popover>
+    </>
+  );
+};
+
+export default AnalyticsMobileDropdown;
diff --git a/src/containers/Analytics/SelectedAnalytics/SelectedAnalytics.scss b/src/containers/Analytics/SelectedAnalytics/SelectedAnalytics.scss
new file mode 100644
index 0000000..42325cc
--- /dev/null
+++ b/src/containers/Analytics/SelectedAnalytics/SelectedAnalytics.scss
@@ -0,0 +1,21 @@
+.SelectedAnalytics {
+  display: grid;
+  grid-template-columns: 1fr 1fr;
+
+  @media (max-width: 768px) {
+    display: block;
+  }
+
+  &__loading-container {
+    display: flex;
+    justify-content: center;
+    margin-top: 30px;
+  }
+
+  &__no-results {
+    color: var(--color-neutral-600);
+    display: flex;
+    justify-content: center;
+    margin-top: 30px;
+  }
+}
diff --git a/src/containers/Analytics/SelectedAnalytics/index.tsx b/src/containers/Analytics/SelectedAnalytics/index.tsx
new file mode 100644
index 0000000..91b68af
--- /dev/null
+++ b/src/containers/Analytics/SelectedAnalytics/index.tsx
@@ -0,0 +1,56 @@
+import React, {FC, useEffect, useState} from 'react';
+
+import {getAnalytics} from 'apis/analytics';
+import {Loader} from 'components';
+import {Analytics, AnalyticsCategory} from 'types/analytics';
+import {displayErrorToast} from 'utils/toast';
+
+import AnalyticsGraph from '../AnalyticsGraph';
+import './SelectedAnalytics.scss';
+
+interface ComponentProps {
+  selectedCategory: AnalyticsCategory | null;
+}
+
+const SelectedAnalytics: FC<ComponentProps> = ({selectedCategory}) => {
+  const [analytics, setAnalytics] = useState<Analytics[]>([]);
+  const [loading, setLoading] = useState<boolean>(false);
+
+  useEffect(() => {
+    if (selectedCategory) {
+      (async () => {
+        setLoading(true);
+        try {
+          const analyticsResponse = await getAnalytics(selectedCategory.key);
+          setAnalytics(analyticsResponse);
+        } catch (error) {
+          displayErrorToast('Network Error');
+        } finally {
+          setLoading(false);
+        }
+      })();
+    }
+  }, [selectedCategory]);
+
+  if (loading) {
+    return (
+      <div className="SelectedAnalytics__loading-container">
+        <Loader />
+      </div>
+    );
+  }
+
+  if (!analytics.length) {
+    return <div className="SelectedAnalytics__no-results">There are no analytics to display for this category.</div>;
+  }
+
+  return (
+    <div className="SelectedAnalytics">
+      {analytics.map((analytic) => (
+        <AnalyticsGraph data={analytic.data} key={analytic.pk} title={analytic.title} />
+      ))}
+    </div>
+  );
+};
+
+export default SelectedAnalytics;
diff --git a/src/containers/Analytics/index.tsx b/src/containers/Analytics/index.tsx
new file mode 100644
index 0000000..09e44de
--- /dev/null
+++ b/src/containers/Analytics/index.tsx
@@ -0,0 +1,111 @@
+import React, {FC, ReactNode, useCallback, useEffect, useMemo, useState} from 'react';
+import {useHistory, useParams} from 'react-router-dom';
+
+import {getAnalyticsCategories} from 'apis/analytics';
+import {Container, FlatNavLinks, PageTitle, Loader} from 'components';
+import {useWindowDimensions} from 'hooks';
+import {AnalyticsCategory, AnalyticsUrlParams} from 'types/analytics';
+import {displayErrorToast} from 'utils/toast';
+
+import AnalyticsIcon from './AnalyticsIcon';
+import AnalyticsMobileDropdown from './AnalyticsMobileDropdown';
+import SelectedAnalytics from './SelectedAnalytics';
+import './Analytics.scss';
+
+const Analytics: FC = () => {
+  const history = useHistory();
+  const {type} = useParams<AnalyticsUrlParams>();
+  const [categories, setCategories] = useState<AnalyticsCategory[]>([]);
+  const [loading, setLoading] = useState<boolean>(true);
+  const [selectedCategory, setSelectedCategory] = useState<AnalyticsCategory | null>(null);
+  const {clientWidth} = useWindowDimensions();
+
+  useEffect(() => {
+    (async () => {
+      setLoading(true);
+      try {
+        const analyticsCategoriesResponse = await getAnalyticsCategories();
+        if (analyticsCategoriesResponse.length) {
+          setCategories(analyticsCategoriesResponse);
+        }
+      } catch (error) {
+        displayErrorToast('Network Error');
+      } finally {
+        setLoading(false);
+      }
+    })();
+  }, []);
+
+  useEffect(() => {
+    if (type && categories.length) {
+      const categoryType = categories.find((category) => category.key === type);
+
+      if (!categoryType) {
+        history.replace(`/analytics/${categories[0].key}`);
+      } else {
+        setSelectedCategory(categoryType);
+      }
+    }
+
+    if (!type && categories.length) {
+      history.replace(`/analytics/${categories[0].key}`);
+    }
+  }, [categories, history, type]);
+
+  const analyticsNavOptions = useMemo(() => {
+    return categories.map((category) => ({pathname: category.key, title: category.title}));
+  }, [categories]);
+
+  const title = useMemo(() => {
+    if (selectedCategory) {
+      return `${selectedCategory.title} Analytics`;
+    }
+
+    return 'Analytics';
+  }, [selectedCategory]);
+
+  const handleNavOptionClick = useCallback(
+    (option: string) => (): void => {
+      history.push(`/analytics/${option}`);
+    },
+    [history],
+  );
+
+  const renderNavLinks = useCallback((): ReactNode => {
+    if (!type) return null;
+    return (
+      <FlatNavLinks handleOptionClick={handleNavOptionClick} options={analyticsNavOptions} selectedOption={type} />
+    );
+  }, [analyticsNavOptions, handleNavOptionClick, type]);
+
+  return (
+    <div className="Analytics__wrapper">
+      <PageTitle ogDescription={title} title={title} />
+      {loading ? (
+        <div className="Analytics__loading-container">
+          <Loader />
+        </div>
+      ) : (
+        <Container className="Analytics">
+          <div className="Analytics__icon-container">
+            <AnalyticsIcon />
+            <span className="Analytics__icon-text">Analytics Dashboard</span>
+          </div>
+          {clientWidth <= 992 && (
+            <AnalyticsMobileDropdown navLinks={renderNavLinks()} selectedCategory={selectedCategory} />
+          )}
+          <aside className="Analytics__left-menu">{renderNavLinks()}</aside>
+          <div className="Analytics__title-container">
+            <h1 className="Analytics__title">{title}</h1>
+            <span className="Analytics__weekly">WEEKLY</span>
+          </div>
+          <div className="Analytics__main-container">
+            <SelectedAnalytics selectedCategory={selectedCategory} />
+          </div>
+        </Container>
+      )}
+    </div>
+  );
+};
+
+export default Analytics;
diff --git a/src/containers/App.tsx b/src/containers/App.tsx
index a8b0ae7..714bc44 100644
--- a/src/containers/App.tsx
+++ b/src/containers/App.tsx
@@ -4,7 +4,7 @@ import {BrowserRouter as Router, Redirect, Route, Switch} from 'react-router-dom
 import {Layout} from 'components';
 import withSuspense from 'hoc/withSuspense';
 
-import Wallet from './Wallet';
+import Analytics from './Analytics';
 import ArchitectureDeepDive from './LivingWhitepaper/containers/ArchitectureDeepDive';
 import Assets from './Assets';
 import BankApi from './Api/BankApi';
@@ -35,6 +35,7 @@ import StyleGuide from './StyleGuide';
 import Tasks from './Tasks';
 import Teams from './Teams';
 import TermsOfUse from './TermsOfUse';
+import Wallet from './Wallet';
 
 /**
  * Lazy load pages that may contribute a lot to the bundle size
@@ -76,6 +77,7 @@ const App: FC = () => {
       <Layout>
         <Switch>
           <Route exact path="/" component={Home} />
+          <Route exact path="/analytics/:type?" component={Analytics} />
           <Route exact path="/guidelines" component={Guidelines} />
           <Route exact path="/create-account" render={() => <CreateAccount disabled />} />
           <Route exact path="/donate" component={Donate} />
diff --git a/src/components/Footer/FooterNavList/FooterNavList.scss b/src/containers/Footer/FooterNavList/FooterNavList.scss
similarity index 100%
rename from src/components/Footer/FooterNavList/FooterNavList.scss
rename to src/containers/Footer/FooterNavList/FooterNavList.scss
diff --git a/src/components/Footer/FooterNavList/FooterNavList.test.tsx b/src/containers/Footer/FooterNavList/FooterNavList.test.tsx
similarity index 100%
rename from src/components/Footer/FooterNavList/FooterNavList.test.tsx
rename to src/containers/Footer/FooterNavList/FooterNavList.test.tsx
diff --git a/src/components/Footer/FooterNavList/index.tsx b/src/containers/Footer/FooterNavList/index.tsx
similarity index 100%
rename from src/components/Footer/FooterNavList/index.tsx
rename to src/containers/Footer/FooterNavList/index.tsx
diff --git a/src/components/Footer/index.tsx b/src/containers/Footer/index.tsx
similarity index 98%
rename from src/components/Footer/index.tsx
rename to src/containers/Footer/index.tsx
index 7be3f45..dda3643 100644
--- a/src/components/Footer/index.tsx
+++ b/src/containers/Footer/index.tsx
@@ -25,6 +25,7 @@ const navLists = [
         title: 'Projects',
         url: '/projects/overview',
       },
+      {title: 'Analytics', url: '/analytics'},
     ],
   },
   {
diff --git a/src/containers/TopNav/TopNavDesktopItems/index.tsx b/src/containers/TopNav/TopNavDesktopItems/index.tsx
index d34a629..9b4d028 100644
--- a/src/containers/TopNav/TopNavDesktopItems/index.tsx
+++ b/src/containers/TopNav/TopNavDesktopItems/index.tsx
@@ -59,6 +59,12 @@ const getStartedPopoverItems: TopNavPopoverItemType[] = [
     title: 'Projects',
     to: '/projects',
   },
+  {
+    description: 'Real time analytics',
+    iconType: IconType.chartAreaspline,
+    title: 'Analytics',
+    to: '/analytics',
+  },
 ];
 
 const resourcesPopoverItems: TopNavPopoverItemType[] = [
diff --git a/src/containers/TopNav/TopNavMobileMenu/index.tsx b/src/containers/TopNav/TopNavMobileMenu/index.tsx
index ab90548..c9f58b4 100644
--- a/src/containers/TopNav/TopNavMobileMenu/index.tsx
+++ b/src/containers/TopNav/TopNavMobileMenu/index.tsx
@@ -56,6 +56,7 @@ const TopNavMobileMenu: FC<ComponentProps> = ({closeMenu, menuOpen, smallDevice,
               <>
                 {renderMobileLink('Tasks', '/tasks')}
                 {renderMobileLink('Projects', '/projects/overview')}
+                {renderMobileLink('Analytics', '/analytics')}
               </>,
             )}
             {renderColumn(
diff --git a/src/data/teams.json b/src/data/teams.json
index e451012..e5dc542 100644
--- a/src/data/teams.json
+++ b/src/data/teams.json
@@ -180,7 +180,7 @@
           "githubUsername": "manishram",
           "profileImage": "https://avatars0.githubusercontent.com/u/22790904?s=400&u=643810e6c9d5686df409132b01863f9e065df6c1&v=4"
         },
-        "hourlyRate": 800
+        "hourlyRate": 900
       },
       {
         "title": "Head of Human Resources",
@@ -265,7 +265,7 @@
           "githubUsername": "kashikushi",
           "profileImage": "https://avatars.githubusercontent.com/u/35629401?v=4"
         },
-        "hourlyRate": 1200
+        "hourlyRate": 900
       }
     ],
     "responsibilities": [
diff --git a/src/types/analytics.ts b/src/types/analytics.ts
new file mode 100644
index 0000000..7186d34
--- /dev/null
+++ b/src/types/analytics.ts
@@ -0,0 +1,20 @@
+export interface AnalyticsUrlParams {
+  type?: string;
+}
+
+export interface Analytics {
+  data: AnalyticsData[];
+  pk: string;
+  title: string;
+}
+
+export interface AnalyticsCategory {
+  key: string;
+  title: string;
+  analytics: Analytics[];
+}
+
+export interface AnalyticsData {
+  date: string;
+  value: number;
+}


Test patch:
diff --git a/src/components/Footer/Footer.scss b/src/containers/Footer/Footer.scss
similarity index 100%
rename from src/components/Footer/Footer.scss
rename to src/containers/Footer/Footer.scss
diff --git a/src/components/Footer/Footer.test.tsx b/src/containers/Footer/Footer.test.tsx
similarity index 98%
rename from src/components/Footer/Footer.test.tsx
rename to src/containers/Footer/Footer.test.tsx
index aab2a8f..e4621f2 100644
--- a/src/components/Footer/Footer.test.tsx
+++ b/src/containers/Footer/Footer.test.tsx
@@ -4,7 +4,7 @@ import {BrowserRouter as Router} from 'react-router-dom';
 import '@testing-library/jest-dom/extend-expect';
 
 import {SocialMedia} from 'types/social-media';
-import Footer from './index';
+import Footer from '.';
 
 interface Props {
   className?: string;