diff --git a/package-lock.json b/package-lock.json
index cf5ce13149ddf9f8388b52d03f3d91634a810856..8632471f7922cd60888c8936c07eea5d4876e2e9 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -10,7 +10,9 @@
       "dependencies": {
         "@chakra-ui/react": "^2.8.1",
         "react": "^18.2.0",
-        "react-dom": "^18.2.0"
+        "react-dom": "^18.2.0",
+        "react-router-dom": "^6.18.0",
+        "recharts": "^2.9.3"
       },
       "devDependencies": {
         "@types/react": "^18.2.15",
@@ -2270,6 +2272,14 @@
         "url": "https://opencollective.com/popperjs"
       }
     },
+    "node_modules/@remix-run/router": {
+      "version": "1.11.0",
+      "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.11.0.tgz",
+      "integrity": "sha512-BHdhcWgeiudl91HvVa2wxqZjSHbheSgIiDvxrF1VjFzBzpTtuDPkOdOi3Iqvc08kXtFkLjhbS+ML9aM8mJS+wQ==",
+      "engines": {
+        "node": ">=14.0.0"
+      }
+    },
     "node_modules/@types/babel__core": {
       "version": "7.20.3",
       "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.3.tgz",
@@ -2311,6 +2321,60 @@
         "@babel/types": "^7.20.7"
       }
     },
+    "node_modules/@types/d3-array": {
+      "version": "3.2.1",
+      "resolved": "https://registry.npmjs.org/@types/d3-array/-/d3-array-3.2.1.tgz",
+      "integrity": "sha512-Y2Jn2idRrLzUfAKV2LyRImR+y4oa2AntrgID95SHJxuMUrkNXmanDSed71sRNZysveJVt1hLLemQZIady0FpEg=="
+    },
+    "node_modules/@types/d3-color": {
+      "version": "3.1.3",
+      "resolved": "https://registry.npmjs.org/@types/d3-color/-/d3-color-3.1.3.tgz",
+      "integrity": "sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A=="
+    },
+    "node_modules/@types/d3-ease": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/@types/d3-ease/-/d3-ease-3.0.2.tgz",
+      "integrity": "sha512-NcV1JjO5oDzoK26oMzbILE6HW7uVXOHLQvHshBUW4UMdZGfiY6v5BeQwh9a9tCzv+CeefZQHJt5SRgK154RtiA=="
+    },
+    "node_modules/@types/d3-interpolate": {
+      "version": "3.0.4",
+      "resolved": "https://registry.npmjs.org/@types/d3-interpolate/-/d3-interpolate-3.0.4.tgz",
+      "integrity": "sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA==",
+      "dependencies": {
+        "@types/d3-color": "*"
+      }
+    },
+    "node_modules/@types/d3-path": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/@types/d3-path/-/d3-path-3.0.2.tgz",
+      "integrity": "sha512-WAIEVlOCdd/NKRYTsqCpOMHQHemKBEINf8YXMYOtXH0GA7SY0dqMB78P3Uhgfy+4X+/Mlw2wDtlETkN6kQUCMA=="
+    },
+    "node_modules/@types/d3-scale": {
+      "version": "4.0.8",
+      "resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-4.0.8.tgz",
+      "integrity": "sha512-gkK1VVTr5iNiYJ7vWDI+yUFFlszhNMtVeneJ6lUTKPjprsvLLI9/tgEGiXJOnlINJA8FyA88gfnQsHbybVZrYQ==",
+      "dependencies": {
+        "@types/d3-time": "*"
+      }
+    },
+    "node_modules/@types/d3-shape": {
+      "version": "3.1.5",
+      "resolved": "https://registry.npmjs.org/@types/d3-shape/-/d3-shape-3.1.5.tgz",
+      "integrity": "sha512-dfEWpZJ1Pdg8meLlICX1M3WBIpxnaH2eQV2eY43Y5ysRJOTAV9f3/R++lgJKFstfrEOE2zdJ0sv5qwr2Bkic6Q==",
+      "dependencies": {
+        "@types/d3-path": "*"
+      }
+    },
+    "node_modules/@types/d3-time": {
+      "version": "3.0.3",
+      "resolved": "https://registry.npmjs.org/@types/d3-time/-/d3-time-3.0.3.tgz",
+      "integrity": "sha512-2p6olUZ4w3s+07q3Tm2dbiMZy5pCDfYwtLXXHUnVzXgQlZ/OyPtUz6OL382BkOuGlLXqfT+wqv8Fw2v8/0geBw=="
+    },
+    "node_modules/@types/d3-timer": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/@types/d3-timer/-/d3-timer-3.0.2.tgz",
+      "integrity": "sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw=="
+    },
     "node_modules/@types/json-schema": {
       "version": "7.0.14",
       "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.14.tgz",
@@ -2866,6 +2930,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-convert": {
       "version": "1.9.3",
       "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
@@ -2952,6 +3021,116 @@
       "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.2.tgz",
       "integrity": "sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ=="
     },
+    "node_modules/d3-array": {
+      "version": "3.2.4",
+      "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-3.2.4.tgz",
+      "integrity": "sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==",
+      "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/debug": {
       "version": "4.3.4",
       "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
@@ -2969,6 +3148,11 @@
         }
       }
     },
+    "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/deep-is": {
       "version": "0.1.4",
       "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz",
@@ -3004,6 +3188,14 @@
         "node": ">=6.0.0"
       }
     },
+    "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.563",
       "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.563.tgz",
@@ -3333,12 +3525,25 @@
         "node": ">=0.10.0"
       }
     },
+    "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-deep-equal": {
       "version": "3.1.3",
       "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
       "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
       "dev": true
     },
+    "node_modules/fast-equals": {
+      "version": "5.0.1",
+      "resolved": "https://registry.npmjs.org/fast-equals/-/fast-equals-5.0.1.tgz",
+      "integrity": "sha512-WF1Wi8PwwSY7/6Kx0vKXtw8RwuSGoM1bvDaJbu7MxDlR1vovZjIAKrnzyrThgAjm6JDTu0fVgWXDlMGspodfoQ==",
+      "engines": {
+        "node": ">=6.0.0"
+      }
+    },
     "node_modules/fast-glob": {
       "version": "3.3.1",
       "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.1.tgz",
@@ -3710,6 +3915,14 @@
       "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
       "dev": true
     },
+    "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/invariant": {
       "version": "2.2.4",
       "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz",
@@ -3901,6 +4114,11 @@
         "url": "https://github.com/sponsors/sindresorhus"
       }
     },
+    "node_modules/lodash": {
+      "version": "4.17.21",
+      "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
+      "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
+    },
     "node_modules/lodash.merge": {
       "version": "4.6.2",
       "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
@@ -4305,6 +4523,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-refresh": {
       "version": "0.14.0",
       "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.14.0.tgz",
@@ -4359,6 +4582,62 @@
         }
       }
     },
+    "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.18.0",
+      "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.18.0.tgz",
+      "integrity": "sha512-vk2y7Dsy8wI02eRRaRmOs9g2o+aE72YCx5q9VasT1N9v+lrdB79tIqrjMfByHiY5+6aYkH2rUa5X839nwWGPDg==",
+      "dependencies": {
+        "@remix-run/router": "1.11.0"
+      },
+      "engines": {
+        "node": ">=14.0.0"
+      },
+      "peerDependencies": {
+        "react": ">=16.8"
+      }
+    },
+    "node_modules/react-router-dom": {
+      "version": "6.18.0",
+      "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.18.0.tgz",
+      "integrity": "sha512-Ubrue4+Ercc/BoDkFQfc6og5zRQ4A8YxSO3Knsne+eRbZ+IepAsK249XBH/XaFuOYOYr3L3r13CXTLvYt5JDjw==",
+      "dependencies": {
+        "@remix-run/router": "1.11.0",
+        "react-router": "6.18.0"
+      },
+      "engines": {
+        "node": ">=14.0.0"
+      },
+      "peerDependencies": {
+        "react": ">=16.8",
+        "react-dom": ">=16.8"
+      }
+    },
+    "node_modules/react-smooth": {
+      "version": "2.0.5",
+      "resolved": "https://registry.npmjs.org/react-smooth/-/react-smooth-2.0.5.tgz",
+      "integrity": "sha512-BMP2Ad42tD60h0JW6BFaib+RJuV5dsXJK9Baxiv/HlNFjvRLqA9xrNKxVWnUIZPQfzUwGXIlU/dSYLU+54YGQA==",
+      "dependencies": {
+        "fast-equals": "^5.0.0",
+        "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-style-singleton": {
       "version": "2.2.1",
       "resolved": "https://registry.npmjs.org/react-style-singleton/-/react-style-singleton-2.2.1.tgz",
@@ -4381,6 +4660,21 @@
         }
       }
     },
+    "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/readdirp": {
       "version": "3.6.0",
       "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
@@ -4393,6 +4687,38 @@
         "node": ">=8.10.0"
       }
     },
+    "node_modules/recharts": {
+      "version": "2.9.3",
+      "resolved": "https://registry.npmjs.org/recharts/-/recharts-2.9.3.tgz",
+      "integrity": "sha512-B61sKrDlTxHvYwOCw8eYrD6rTA2a2hJg0avaY8qFI1ZYdHKvU18+J5u7sBMFg//wfJ/C5RL5+HsXt5e8tcJNLg==",
+      "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.4",
+        "recharts-scale": "^0.4.4",
+        "tiny-invariant": "^1.3.1",
+        "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/regenerator-runtime": {
       "version": "0.14.0",
       "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz",
@@ -4799,6 +5125,27 @@
         }
       }
     },
+    "node_modules/victory-vendor": {
+      "version": "36.6.12",
+      "resolved": "https://registry.npmjs.org/victory-vendor/-/victory-vendor-36.6.12.tgz",
+      "integrity": "sha512-pJrTkNHln+D83vDCCSUf0ZfxBvIaVrFHmrBOsnnLAbdqfudRACAj51He2zU94/IWq9464oTADcPVkmWAfNMwgA==",
+      "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.5.0",
       "resolved": "https://registry.npmjs.org/vite/-/vite-4.5.0.tgz",
diff --git a/package.json b/package.json
index 54151cca0f230d169e9e4d689ef9438df8bd1a3b..542dc8fff6914078972bfcaade14645f9c630dbf 100644
--- a/package.json
+++ b/package.json
@@ -13,7 +13,9 @@
   "dependencies": {
     "@chakra-ui/react": "^2.8.1",
     "react": "^18.2.0",
-    "react-dom": "^18.2.0"
+    "react-dom": "^18.2.0",
+    "react-router-dom": "^6.18.0",
+    "recharts": "^2.9.3"
   },
   "devDependencies": {
     "@types/react": "^18.2.15",
diff --git a/src/App.tsx b/src/App.tsx
index f9e3eb4ed27ba3fa8140f3eb0b86e5139de5ab52..56ed4a96c1053efb9653d1c1d167cb287162e4db 100644
--- a/src/App.tsx
+++ b/src/App.tsx
@@ -1,12 +1,14 @@
-import './App.css'
-import Login from './Login'
-// import Register from './Register'
+// import './App.css'
+// // import Login from './Login'
+// // import Register from './Register'
+// import TweetAnalytic from './component/TweetAnalytic'
 
-function App() {
-  return (
-    // <Register />
-    <Login />
-  )
-}
+// function App() {
+//   return (
+//     // <Register />
+//     // <Login />
+//     <TweetAnalytic />
+//   )
+// }
 
-export default App
+// export default App
diff --git a/src/Register.tsx b/src/Register.tsx
deleted file mode 100644
index ecfd0462e7ad84674fa4ec2e23f7a6ee62bd0370..0000000000000000000000000000000000000000
--- a/src/Register.tsx
+++ /dev/null
@@ -1,90 +0,0 @@
-import {
-    Box,
-    VStack,
-    Heading, 
-} from '@chakra-ui/layout'
-import { FormControl,
-        FormLabel,
-       } from '@chakra-ui/form-control'
-import { Button } from '@chakra-ui/react'
-import React from 'react'
-import { Input } from '@chakra-ui/react'
-
-function Register() {
-    const [name, setName] = React.useState('')
-    const [username, setUsername] = React.useState('')
-    const [password, setPassword] = React.useState('')
-
-    const register = () => {
-        if (/\s/.test(username) || /\s/.test(password)) {
-            alert('Invalid username or password')
-        }
-        else if(name==='' || username==='' || password===''){
-            alert('Please fill all the fields')
-        }
-        else if (username.length < 5 || password.length < 5) {
-            alert('Username and password must be at least 5 characters')
-        }
-        else {
-            console.log('Registering...')
-            console.log(name)
-            console.log(username)
-            console.log(password)
-            // nanti disini register ke API
-        }
-    }
-
-  return (
-      <Box
-      w={['full','md']}
-      p={[8,10]}
-      mx='auto'
-      border={['none','1px solid gray']}
-      mt={[20,'10hv']}
-      borderRadius={10}
-      borderColor={['','gray.200']}
-      >
-        <VStack
-        spacing={4}
-        align='flex-start'
-        w='full'
-        >
-          <VStack
-          spacing={1}
-          w={['full']}
-          align={['flex-start','center']}
-          >
-            <Heading>
-              Register
-            </Heading>
-          </VStack>
-          <FormControl>
-              <FormLabel>
-                Name
-              </FormLabel>
-              <Input variant={'filled'} value={name} onChange={(e)=>setName(e.target.value)}   /> 
-          </FormControl>
-          <FormControl>
-              <FormLabel>
-                Username
-              </FormLabel>
-              <Input variant={'filled'} value={username} onChange={(e)=>setUsername(e.target.value)}/>
-          </FormControl>
-          <FormControl>
-              <FormLabel>
-                Password
-              </FormLabel>
-              <Input variant={'filled'} type='password' value={password} onChange={(e)=>setPassword(e.target.value)}/>
-          </FormControl>
-          <Button colorScheme='facebook' w={'full'} onClick={register}>
-            Register
-          </Button>
-        </VStack>
-        <FormLabel>
-          Already have an account? <a href='#'>Login</a>
-        </FormLabel>
-      </Box>
-  )
-}
-
-export default Register
\ No newline at end of file
diff --git a/src/component/BoxContent.tsx b/src/component/BoxContent.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..aedae91725d8126fb4477ecdda6cc8d83205a508
--- /dev/null
+++ b/src/component/BoxContent.tsx
@@ -0,0 +1,43 @@
+import {Box,Text, Button} from '@chakra-ui/react';
+import { useLocation } from "react-router-dom"
+// import React from 'react';
+
+const BoxContent = ({ data }:any) => {
+    const location = useLocation()
+    const params = new URLSearchParams(location.search)
+    const id = params.get('id');
+    let buttondetail;
+    if(id === null){
+        buttondetail = <Button colorScheme='blue' mt='10px' onClick={() => window.location.href='/tweet-analytic?id='+data.post_id}>
+        Detail
+    </Button>
+    }
+    else{
+        
+    }
+    return (
+        <Box border='1px solid gray' borderRadius='10px' p='20px' mt='20px' wordBreak='break-word'>
+            <Box borderBottom='1px solid gray' pb='10px' mb='10px' wordBreak='break-word'>
+                <Text>
+                    @{data.username}
+                </Text>
+                <Text>
+                    {data.name}
+                </Text>
+            </Box>
+            <Box>
+                <Text>
+                    {data.body}
+                </Text>
+            </Box>
+            {buttondetail}
+            <Text>
+                Post ID : {data.post_id}
+            </Text>
+            <Text>
+                Create At : {data.date_created}
+            </Text>
+        </Box>
+    );
+}
+export default BoxContent;
\ No newline at end of file
diff --git a/src/component/Home.tsx b/src/component/Home.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..7cb6173d7bb9a3d99a8e5817afe78bd9ab65271b
--- /dev/null
+++ b/src/component/Home.tsx
@@ -0,0 +1,52 @@
+import {useState,useEffect} from "react";
+import Navbar from "./Navbar";
+import {Text,Box, Center} from "@chakra-ui/react";
+import LineChartAssetsHome from "./LineChartAssetsHome";
+
+
+function Home(){
+    // const [username,setUsername] = useState('');
+    const [name,setName] = useState('');
+    const [followData,setFollowData] = useState<any[]>([]);
+    const nama = 'Sulthan'
+    useEffect(()=>{
+        // setUsername(localStorage.getItem('username')!);
+        setName(nama);
+        setFollowData(FollowData);
+    },[])
+    const FollowData = [
+        { day : 'Mon' , total : 1000 },
+        { day : 'Tue' , total : 3000 },
+        { day : 'Wed' , total : 2000 },
+        { day : 'Thu' , total : 5000 },
+        { day : 'Fri' , total : 4000 },
+        { day : 'Sat' , total : 3000 },
+        { day : 'Sun' , total : 1000 },
+    ];
+    if(localStorage.getItem('username') === null){
+        window.location.href = '/login';
+    }
+    return(
+        <div>
+        <Box marginTop='80px'>
+        <Navbar/>
+        <Box>
+        <Box textAlign="center" paddingTop="40px" >
+        <Text fontSize="4xl" fontWeight="bold" fontFamily="heading" color="teal.500">
+            Welcome Back {name}!
+        </Text>
+        <Text fontSize="xl" fontFamily="body" color="gray.600" marginTop="4">
+        Analytic Follow
+        </Text>
+        <Center>
+        <LineChartAssetsHome data={followData} />
+        </Center>
+        </Box>
+        </Box>
+        </Box>
+        </div>
+        
+    )
+}
+
+export default Home;
\ No newline at end of file
diff --git a/src/component/LineChartAssets.tsx b/src/component/LineChartAssets.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..b0dd785234c33700e22c9cc07248edd51ec13b54
--- /dev/null
+++ b/src/component/LineChartAssets.tsx
@@ -0,0 +1,28 @@
+// import React from 'react';
+import { LineChart, Line, XAxis, YAxis, CartesianGrid, Tooltip, Legend} from 'recharts';
+
+
+const LineChartAssets = ({ data }:any) => {
+    return (
+        <LineChart
+          data={data}
+          width={200}
+          height={100}
+          margin={{
+            top: 0,
+            // right: 30,
+            // left: -15,
+            bottom: 0,
+          }}
+        >
+          <CartesianGrid strokeDasharray="3 3" />
+          <XAxis dataKey="day" />
+          <YAxis />
+          <Tooltip />
+          <Legend />
+          <Line type="monotone" dataKey="total" stroke="#8884d8" activeDot={{ r: 8 }} />
+        </LineChart>
+    );
+}
+
+export default LineChartAssets;
\ No newline at end of file
diff --git a/src/component/LineChartAssetsHome.tsx b/src/component/LineChartAssetsHome.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..d7cfff9018038c9588e991d66b1671ccd6b18a89
--- /dev/null
+++ b/src/component/LineChartAssetsHome.tsx
@@ -0,0 +1,28 @@
+// import React from 'react';
+import { LineChart, Line, XAxis, YAxis, CartesianGrid, Tooltip, Legend} from 'recharts';
+
+
+const LineChartAssetsHome = ({ data }:any) => {
+    return (
+        <LineChart
+          data={data}
+          width={500}
+          height={400}
+          margin={{
+            top: 10,
+            // right: 30,
+            left: -15,
+            bottom: 0,
+          }}
+        >
+          <CartesianGrid strokeDasharray="3 3" />
+          <XAxis dataKey="day" />
+          <YAxis />
+          <Tooltip />
+          <Legend />
+          <Line type="monotone" dataKey="total" stroke="#8884d8" activeDot={{ r: 8 }} />
+        </LineChart>
+    );
+}
+
+export default LineChartAssetsHome;
\ No newline at end of file
diff --git a/src/Login.tsx b/src/component/Login.tsx
similarity index 91%
rename from src/Login.tsx
rename to src/component/Login.tsx
index 05e36f99f13315262426756b5be246d22f03f04b..c9494abaab9f67933815898f92f3ac98b2634e69 100644
--- a/src/Login.tsx
+++ b/src/component/Login.tsx
@@ -23,6 +23,8 @@ function Login() {
           console.log(username)
           console.log(password)
           // nanti disini login ke API
+          localStorage.setItem('username', username)
+          window.location.href = '/home'
       }
   }
   return (
@@ -67,7 +69,7 @@ function Login() {
           </Button>
         </VStack>
         <FormLabel>
-          Don't have an account? <a href='#'>Register</a>
+          Don't have an account? <a href='http://localhost:8008/login'>Register</a>
         </FormLabel>
       </Box>
   )
diff --git a/src/component/Navbar.tsx b/src/component/Navbar.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..1416ef736d291b659464c721f84715e6d54e0192
--- /dev/null
+++ b/src/component/Navbar.tsx
@@ -0,0 +1,43 @@
+import { Link } from 'react-router-dom';
+import { Box, Flex, Text } from '@chakra-ui/react';
+const Navbar = () => {
+    return (
+    <Flex
+        as="nav"
+        align="center"
+        justify="space-between"
+        height='80px'
+        bg="teal.500"
+        color="white"
+        position="fixed"
+        top="0"  
+
+        width="100%"
+        zIndex="1000" 
+    >
+        <Text fontSize="xl" fontWeight="bold" marginLeft={4}>
+        Analytic
+        </Text>
+
+        <Box display="flex" alignItems="center">
+        <Box marginRight={4}>
+            <Link to="/home">
+                Home
+            </Link>
+        </Box >
+        <Box marginRight={4}>
+            <Link to="/tweet-analytic">
+                Analytic
+            </Link>
+        </Box>
+        <Box marginRight={4}>
+            <Link to="/login" onClick={()=>{localStorage.removeItem('username')}}>
+                Logout
+            </Link>
+        </Box>
+        </Box>
+    </Flex>
+    );
+};
+
+export default Navbar;
\ No newline at end of file
diff --git a/src/component/TweetAnalytic.tsx b/src/component/TweetAnalytic.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..602d160ad9bd71842ff9d2e03dd744f2e45a3918
--- /dev/null
+++ b/src/component/TweetAnalytic.tsx
@@ -0,0 +1,190 @@
+import {useState,useEffect} from 'react'
+import LineChartAssets from './LineChartAssets';
+import {Box, Text} from '@chakra-ui/react';
+import BoxContent from './BoxContent';
+import Navbar from './Navbar';
+import { useLocation } from "react-router-dom"
+
+interface Data {
+    day: string;
+    total: number;
+}
+interface Content{
+    username : string;
+    id : number;
+    name : string;
+    post_id : number;
+    body : string;
+    date_created : string;
+    path : string;
+}
+function TweetAnalytic(){
+    if(localStorage.getItem('username') === null){
+        window.location.href = '/login';
+    }
+    const location = useLocation()
+    const params = new URLSearchParams(location.search)
+    const id = params.get('id');
+    if(id === null){
+        console.log('all');
+    }
+    else{
+        console.log(id);
+    }
+    const initialData = [
+        { day : 'Mon' , total : 0 },
+        { day : 'Tue' , total : 0 },
+        { day : 'Wed' , total : 0 },
+        { day : 'Thu' , total : 0 },
+        { day : 'Fri' , total : 0 },
+        { day : 'Sat' , total : 0 },
+        { day : 'Sun' , total : 0 },
+    ];
+    const [replyData, setReplyData] = useState<Data[]>(initialData);
+    const [likeData, setLikeData] = useState<Data[]>(initialData);
+    const [viewData, setViewData] = useState<Data[]>(initialData);
+    const [content, setContent] = useState<Content[]>([]);
+
+    //Dummy Data
+    const LikeData = [
+        { day : 'Mon' , total : 1000 },
+        { day : 'Tue' , total : 3000 },
+        { day : 'Wed' , total : 2000 },
+        { day : 'Thu' , total : 5000 },
+        { day : 'Fri' , total : 4000 },
+        { day : 'Sat' , total : 3000 },
+        { day : 'Sun' , total : 1000 },
+    ];
+    
+    const ViewsData = [
+        { day : 'Mon' , total : 1000 },
+        { day : 'Tue' , total : 3000 },
+        { day : 'Wed' , total : 2000 },
+        { day : 'Thu' , total : 5000 },
+        { day : 'Fri' , total : 4000 },
+        { day : 'Sat' , total : 3000 },
+        { day : 'Sun' , total : 1000 },
+    ];
+
+    const RepliesData = [
+        { day: 'Mon', total: 1000 },
+        { day: 'Tue', total: 3000 },
+        { day: 'Wed', total: 2000 },
+        { day: 'Thu', total: 5000 },
+        { day: 'Fri', total: 4000 },
+        { day: 'Sat', total: 3000 },
+        { day: 'Sun', total: 1000 },
+    ];
+
+    const ContentData = [
+        {
+            username: 'user1',
+            id: 1,
+            name: 'user1',
+            post_id: 1,
+            body: 'tweet1',
+            date_created: '2021-05-31',
+            path: 'https://pbs.twimg.com/media/E2Zu8mTUcAAGzDg?format=jpg&name=small'
+        },
+        {
+            username: 'user2',
+            id: 2,
+            name: 'user2',
+            post_id: 2,
+            body: 'tweet2',
+            date_created: '2021-05-31',
+            path: 'https://pbs.twimg.com/media/E2Zu8mTUcAAGzDg?format=jpg&name=small'
+        },
+        {
+            username: 'user3',
+            id: 3,
+            name: 'user3',
+            post_id: 3,
+            body: 'tweet3',
+            date_created: '2021-05-31',
+            path: 'https://pbs.twimg.com/media/E2Zu8mTUcAAGzDg?format=jpg&name=small'
+        },
+        {
+            username: 'user4',
+            id: 4,
+            name: 'user4',
+            post_id: 4,
+            body: 'tweet4',
+            date_created: '2021-05-31',
+            path: 'https://pbs.twimg.com/media/E2Zu8mTUcAAGzDg?format=jpg&name=small'
+        },
+        {
+            username: 'user5',
+            id: 5,
+            name: 'user5',
+            post_id: 5,
+            body: 'tweet5',
+            date_created: '2021-05-31',
+            path: 'https://pbs.twimg.com/media/E2Zu8mTUcAAGzDg?format=jpg&name=small'
+        },
+        {
+            username: 'user6',
+            id: 6,
+            name: 'user6',
+            post_id: 6,
+            body: 'tweet6',
+            date_created: '2021-05-31',
+            path: 'https://pbs.twimg.com/media/E2Zu8mTUcAAGzDg?format=jpg&name=small'
+        },
+        {
+            username: 'user7',
+            id: 7,
+            name: 'user7',
+            post_id: 7,
+            body: 'tweet7',
+            date_created: '2021-05-31',
+            path: 'https://pbs.twimg.com/media/E2Zu8mTUcAAGzDg?format=jpg&name=small'
+        },
+    ];
+        
+
+    //Set Data
+    useEffect(() => {
+        setLikeData(LikeData);
+        setViewData(ViewsData);
+        setReplyData(RepliesData);
+        setContent(ContentData);
+    }, [])
+
+    const makeContentBox = () => {
+        let contentBox = [];
+        for (let i = 0; i < content.length; i++) {
+            contentBox.push(<BoxContent data={content[i]} key={content[i].id} />)
+        }
+        return contentBox;
+    }
+    return (
+        <div>
+            <Navbar />
+            <Box
+            marginRight="240px"
+            marginTop="80px"
+            >
+                {makeContentBox()}
+            </Box>
+            <Box
+            position="fixed"
+            right="0"
+            top="78px"
+            height="100vh"
+            width="240px"  
+            overflowX="auto"
+            padding="4">
+                <Text fontSize="xl" fontWeight="bold">Like</Text>
+                <LineChartAssets data={likeData} />
+                <Text fontSize="xl" fontWeight="bold">Views</Text>
+                <LineChartAssets data={viewData} />
+                <Text fontSize="xl" fontWeight="bold">Replies</Text>
+                <LineChartAssets data={replyData} />
+            </Box>
+            
+        </div>
+    )
+}
+
+export default TweetAnalytic;
\ No newline at end of file
diff --git a/src/main.tsx b/src/main.tsx
index 117a0df4894f881296e6bdf463aac310b5179c1b..82dee2ff552275945e0c9af25fe244ff8b615dd2 100644
--- a/src/main.tsx
+++ b/src/main.tsx
@@ -1,13 +1,14 @@
 import React from 'react'
 import ReactDOM from 'react-dom/client'
-import App from './App.tsx'
+// import App from './App.tsx'
 import './index.css'
 import { ChakraProvider } from '@chakra-ui/react'
+import Routes from './router/router'
 
 ReactDOM.createRoot(document.getElementById('root')!).render(
   <React.StrictMode>
     <ChakraProvider>
-      <App />
+      <Routes />
     </ChakraProvider>
   </React.StrictMode>,
 )
diff --git a/src/router/router.tsx b/src/router/router.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..040ee71b32fcb530fccf4fc1fafc4c48a60d2852
--- /dev/null
+++ b/src/router/router.tsx
@@ -0,0 +1,26 @@
+import { createBrowserRouter, RouterProvider } from 'react-router-dom'
+import Login from '../component/Login'
+import TweetAnalytic from '../component/TweetAnalytic'
+import Home from '../component/Home'
+
+const routesList = createBrowserRouter([
+    {
+        path: '/login',
+        element: <Login />,
+    },
+    {
+        path: '/home',
+        element: <Home />,
+    },
+    {
+        path: '/tweet-analytic?',
+        element: <TweetAnalytic />,
+    },
+    
+  ])
+  
+  const Routes = () => {
+    return <RouterProvider router={routesList} />
+  }
+  
+  export default Routes
\ No newline at end of file