From ae6da4f851752c7b6f7c3c322fd798f4f300bbbc Mon Sep 17 00:00:00 2001
From: Ignacio <ignacio@forbole.com>
Date: Tue, 14 Nov 2023 19:01:50 +0800
Subject: [PATCH 1/8] chore: add new linting rule

---
 .eslintrc.cjs                                 |  7 +++--
 .gitignore                                    |  1 +
 package-lock.json                             |  1 +
 package.json                                  |  1 +
 src/components/arrow/index.tsx                | 29 ++++++++++---------
 .../footer/components/social_media/config.ts  |  7 -----
 .../footer/components/social_media/index.tsx  | 19 +++++++++---
 src/components/guide_nav/hooks.tsx            |  2 +-
 .../nav/components/lang_menu_button/index.tsx |  2 +-
 src/components/nav/hooks.tsx                  |  2 +-
 src/components/scroll_logo/index.tsx          |  2 +-
 src/hooks/get_screen_size.ts                  |  6 +++-
 src/screens/author/hooks.tsx                  |  2 +-
 .../blog/components/blog_posts/index.tsx      |  2 +-
 src/screens/blog/hooks.tsx                    |  2 +-
 src/screens/contact/hooks.tsx                 |  2 +-
 src/screens/developer_tools/hooks.tsx         |  9 ++----
 src/screens/enterprise_solution/hook.ts       |  2 +-
 .../components/network_info/hooks.tsx         | 12 +++++---
 .../components/network_info/index.tsx         |  2 +-
 .../components/calculator/index.tsx           |  2 +-
 .../components/calculate_rewards/hooks.tsx    |  6 ++++
 .../components/contact_card/hooks.tsx         |  2 +-
 .../hero/components/stats/hooks.tsx           |  4 +--
 .../components/network_card/index.tsx         |  4 +--
 .../networks/components/network_grid/hooks.ts | 24 +++++++++++++++
 .../networks/components/search_bar/index.tsx  | 11 +++----
 src/screens/tag/hooks.tsx                     |  2 +-
 src/styles/useColor.ts                        |  1 +
 src/utils/social_media_info.tsx               | 14 +--------
 30 files changed, 107 insertions(+), 75 deletions(-)
 delete mode 100644 src/components/footer/components/social_media/config.ts

diff --git a/.eslintrc.cjs b/.eslintrc.cjs
index 82f1e387..07a4eaa0 100644
--- a/.eslintrc.cjs
+++ b/.eslintrc.cjs
@@ -12,7 +12,7 @@ module.exports = {
     ecmaVersion: "latest",
     sourceType: "module",
   },
-  plugins: ["react", "@typescript-eslint", "prettier"],
+  plugins: ["react", "@typescript-eslint", "prettier", "react-hooks"],
   rules: {
     "arrow-body-style": "error",
     "camelcase": "off",
@@ -22,6 +22,7 @@ module.exports = {
     "no-unused-vars": "off",
     "object-shorthand": "error",
     "prefer-const": "error",
+    "prefer-template": "error",
     "quote-props": ["error", "consistent-as-needed"],
 
     "@typescript-eslint/no-shadow": "error",
@@ -57,7 +58,6 @@ module.exports = {
       },
     ],
 
-    "prefer-template": "error",
     "react/function-component-definition": "off",
     "react/jsx-boolean-value": "error",
     "react/jsx-one-expression-per-line": "off",
@@ -69,6 +69,9 @@ module.exports = {
     "react/react-in-jsx-scope": "off",
     "react/require-default-props": "off",
     "react/self-closing-comp": "error",
+
+    "react-hooks/exhaustive-deps": "error",
+    "react-hooks/rules-of-hooks": "error",
   },
   overrides: [
     {
diff --git a/.gitignore b/.gitignore
index 756c6859..f823dc14 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,6 +2,7 @@
 
 # Sitemaps
 public/*.xml
+test-results
 
 # dependencies
 /node_modules
diff --git a/package-lock.json b/package-lock.json
index b1a82092..e40912e5 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -74,6 +74,7 @@
         "eslint-plugin-jsx-a11y": "^6.8.0",
         "eslint-plugin-prettier": "^5.0.1",
         "eslint-plugin-react": "^7.33.2",
+        "eslint-plugin-react-hooks": "^4.6.0",
         "express": "^4.18.1",
         "nodemon": "^3.0.1",
         "postcss": "^8.4.27",
diff --git a/package.json b/package.json
index c43ea6b1..a1434090 100644
--- a/package.json
+++ b/package.json
@@ -84,6 +84,7 @@
     "eslint-plugin-jsx-a11y": "^6.8.0",
     "eslint-plugin-prettier": "^5.0.1",
     "eslint-plugin-react": "^7.33.2",
+    "eslint-plugin-react-hooks": "^4.6.0",
     "express": "^4.18.1",
     "nodemon": "^3.0.1",
     "postcss": "^8.4.27",
diff --git a/src/components/arrow/index.tsx b/src/components/arrow/index.tsx
index 64a73e20..8a7e3b8a 100644
--- a/src/components/arrow/index.tsx
+++ b/src/components/arrow/index.tsx
@@ -20,22 +20,23 @@ export default function Arraw({ className, sx, direction }: Props) {
   const theme = useTheme();
   const [rotate, setRotate] = useState(0);
 
-  function movePlayer() {
-    if (direction === Direction.Up) {
-      setRotate(180);
-    } else if (direction === Direction.Down) {
-      setRotate(0);
-    } else if (direction === Direction.Left) {
-      setRotate(90);
-    } else if (direction === Direction.Right) {
-      setRotate(-90);
-    } else {
-      setRotate(90);
-    }
-  }
   useEffect(() => {
+    function movePlayer() {
+      if (direction === Direction.Up) {
+        setRotate(180);
+      } else if (direction === Direction.Down) {
+        setRotate(0);
+      } else if (direction === Direction.Left) {
+        setRotate(90);
+      } else if (direction === Direction.Right) {
+        setRotate(-90);
+      } else {
+        setRotate(90);
+      }
+    }
+
     movePlayer();
-  }, []);
+  }, [direction]);
   return (
     <Box
       className={className}
diff --git a/src/components/footer/components/social_media/config.ts b/src/components/footer/components/social_media/config.ts
deleted file mode 100644
index 505cc9b9..00000000
--- a/src/components/footer/components/social_media/config.ts
+++ /dev/null
@@ -1,7 +0,0 @@
-export const socialKeys = [
-  "github",
-  "twitter",
-  "telegram",
-  "linkedIn",
-  "Instagram",
-];
diff --git a/src/components/footer/components/social_media/index.tsx b/src/components/footer/components/social_media/index.tsx
index 763ca564..551627ae 100644
--- a/src/components/footer/components/social_media/index.tsx
+++ b/src/components/footer/components/social_media/index.tsx
@@ -1,17 +1,28 @@
 import { Box, Input, Stack, useTheme } from "@mui/material";
 import CtaButton from "@src/components/cta-button";
-import { getSocialMediaInfo } from "@utils/social_media_info";
+import { socialMedia } from "@utils/social_media_info";
 import axios from "axios";
 import useTranslation from "next-translate/useTranslation";
+import { useRouter } from "next/router";
 import React from "react";
 import { ToastContent, toast } from "react-toastify";
 import validator from "validator";
 
 import classes from "./classes.module.css";
-import { socialKeys } from "./config";
 
 const SocialMedia = () => {
-  const socialMediaInfo = socialKeys.map((x) => getSocialMediaInfo(x));
+  const socialKeys = ["github", "twitter", "telegram", "linkedIn", "Instagram"];
+  const { locale } = useRouter();
+  const socialMediaInfo = socialKeys.map((keyParam: string) => {
+    let key = keyParam;
+    if (key === "Instagram") {
+      if (locale !== "en") {
+        key += "_zh";
+      }
+    }
+    return socialMedia[key] ?? {};
+  });
+
   const { t } = useTranslation("common");
   const theme = useTheme();
   const [inputs, setInputs] = React.useState({
@@ -26,7 +37,7 @@ const SocialMedia = () => {
     } else if (canSubmit) {
       setCanSubmit(false);
     }
-  }, [inputs]);
+  }, [inputs, canSubmit]);
   const handleInputChange = (event: any) => {
     const { name, value } = event.target;
     setInputs((input) => ({
diff --git a/src/components/guide_nav/hooks.tsx b/src/components/guide_nav/hooks.tsx
index 3322b3b1..0055753e 100644
--- a/src/components/guide_nav/hooks.tsx
+++ b/src/components/guide_nav/hooks.tsx
@@ -11,7 +11,7 @@ export const useNavHook = () => {
     if (window.pageYOffset > 0 && !displayBackground) {
       setDisplayBackground(true);
     }
-  }, []);
+  }, [displayBackground]);
 
   useScrollPosition(({ currPos }) => {
     if (currPos.y === 0 && displayBackground) {
diff --git a/src/components/nav/components/lang_menu_button/index.tsx b/src/components/nav/components/lang_menu_button/index.tsx
index 95e59e22..d5331311 100644
--- a/src/components/nav/components/lang_menu_button/index.tsx
+++ b/src/components/nav/components/lang_menu_button/index.tsx
@@ -35,7 +35,7 @@ const LangMenuButton = () => {
 
   React.useEffect(() => {
     onClose();
-  }, [lang]);
+  }, [lang, onClose]);
   const colors = useColor();
   let lan = "";
   switch (lang) {
diff --git a/src/components/nav/hooks.tsx b/src/components/nav/hooks.tsx
index 3322b3b1..0055753e 100644
--- a/src/components/nav/hooks.tsx
+++ b/src/components/nav/hooks.tsx
@@ -11,7 +11,7 @@ export const useNavHook = () => {
     if (window.pageYOffset > 0 && !displayBackground) {
       setDisplayBackground(true);
     }
-  }, []);
+  }, [displayBackground]);
 
   useScrollPosition(({ currPos }) => {
     if (currPos.y === 0 && displayBackground) {
diff --git a/src/components/scroll_logo/index.tsx b/src/components/scroll_logo/index.tsx
index 6cfe52d8..d8cede00 100644
--- a/src/components/scroll_logo/index.tsx
+++ b/src/components/scroll_logo/index.tsx
@@ -28,7 +28,7 @@ const ScrollLogo = () => {
         allNetworkData,
         allNetworkData.length / (onlyLargeScreen ? 4 : 3),
       ),
-    [onlyLargeScreen],
+    [onlyLargeScreen, allNetworkData],
   );
 
   return (
diff --git a/src/hooks/get_screen_size.ts b/src/hooks/get_screen_size.ts
index 254259b1..11ff8fa5 100644
--- a/src/hooks/get_screen_size.ts
+++ b/src/hooks/get_screen_size.ts
@@ -57,7 +57,11 @@ export const useWindowDimensions = () => {
     } else {
       setIsDesktop(false);
     }
-  }, [windowDimensions.width]);
+  }, [
+    windowDimensions.width,
+    theme?.breakpoints?.values?.tablet,
+    theme?.breakpoints?.values?.laptop,
+  ]);
 
   return { windowDimensions, isDesktop, isTablet, isMobile };
 };
diff --git a/src/screens/author/hooks.tsx b/src/screens/author/hooks.tsx
index 14a25a26..e92b0a5b 100644
--- a/src/screens/author/hooks.tsx
+++ b/src/screens/author/hooks.tsx
@@ -6,5 +6,5 @@ export const useBlogHook = (error: any, t: any) => {
     if (error) {
       toast.error(t("error"));
     }
-  }, [error]);
+  }, [error, t]);
 };
diff --git a/src/screens/blog/components/blog_posts/index.tsx b/src/screens/blog/components/blog_posts/index.tsx
index 3c79a94c..caea84bb 100644
--- a/src/screens/blog/components/blog_posts/index.tsx
+++ b/src/screens/blog/components/blog_posts/index.tsx
@@ -34,7 +34,7 @@ const BlogPosts = ({ main, blogs: blogsUpper, meta }: IProps) => {
       }
       return node;
     },
-    [lastView],
+    [lastView, isMobile],
   );
 
   const seeMorePages = (_e: any, { limit, blogs }: any) => {
diff --git a/src/screens/blog/hooks.tsx b/src/screens/blog/hooks.tsx
index 570c7e08..73b781fe 100644
--- a/src/screens/blog/hooks.tsx
+++ b/src/screens/blog/hooks.tsx
@@ -6,5 +6,5 @@ export const useBlogHook = (error: unknown, t: any) => {
     if (error) {
       toast.error(t("error"));
     }
-  }, [error]);
+  }, [error, t]);
 };
diff --git a/src/screens/contact/hooks.tsx b/src/screens/contact/hooks.tsx
index 644ca1dc..326d45d9 100644
--- a/src/screens/contact/hooks.tsx
+++ b/src/screens/contact/hooks.tsx
@@ -37,7 +37,7 @@ const useContactForm = () => {
     } else if (canSubmit) {
       setCanSubmit(false);
     }
-  }, [inputs]);
+  }, [inputs, canSubmit]);
   const get_started = React.useMemo(() => {
     const str = [];
     if (inputs.collaboration) {
diff --git a/src/screens/developer_tools/hooks.tsx b/src/screens/developer_tools/hooks.tsx
index d0102626..58d924c7 100644
--- a/src/screens/developer_tools/hooks.tsx
+++ b/src/screens/developer_tools/hooks.tsx
@@ -37,7 +37,7 @@ const useTalkModalForm = () => {
     } else if (canSubmit) {
       setCanSubmit(false);
     }
-  }, [inputs]);
+  }, [inputs, canSubmit]);
   const get_started = React.useMemo(() => {
     const str = [];
     if (inputs["Data API"]) {
@@ -53,12 +53,7 @@ const useTalkModalForm = () => {
       str.push("RPC Endpoints");
     }
     return str;
-  }, [
-    inputs["Data API"],
-    inputs.GraphQL,
-    inputs.Other,
-    inputs["RPC Endpoints"],
-  ]);
+  }, [inputs]);
 
   const handleSubmit = (event: any) => {
     if (event) {
diff --git a/src/screens/enterprise_solution/hook.ts b/src/screens/enterprise_solution/hook.ts
index c3a49da1..ae88f757 100644
--- a/src/screens/enterprise_solution/hook.ts
+++ b/src/screens/enterprise_solution/hook.ts
@@ -23,7 +23,7 @@ const useContactForm = () => {
     } else if (canSubmit) {
       setCanSubmit(false);
     }
-  }, [inputs]);
+  }, [inputs, canSubmit]);
 
   const handleSubmit = (event: any) => {
     if (event) {
diff --git a/src/screens/network_guides/components/network_info/hooks.tsx b/src/screens/network_guides/components/network_info/hooks.tsx
index a0fdaede..13af006f 100644
--- a/src/screens/network_guides/components/network_info/hooks.tsx
+++ b/src/screens/network_guides/components/network_info/hooks.tsx
@@ -50,7 +50,7 @@ export const useNetworkGuidesHook = () => {
       });
     }
     return cosmosNetworkGuides;
-  }, [cosmosComissionData, cosmosComissionLoading]);
+  }, [cosmosComissionData, cosmosComissionLoading, cosmosNetworkGuides]);
 
   useMemo(() => {
     if (!cosmosAPYLoading) {
@@ -73,7 +73,7 @@ export const useNetworkGuidesHook = () => {
       });
     }
     return cosmosNetworkGuides;
-  }, [cosmosAPYData, cosmosAPYLoading]);
+  }, [cosmosAPYData, cosmosAPYLoading, cosmosNetworkGuides]);
 
   useMemo(() => {
     if (!cosmosTVLLoading) {
@@ -96,7 +96,7 @@ export const useNetworkGuidesHook = () => {
       });
     }
     return cosmosNetworkGuides;
-  }, [cosmosTVLData, cosmosTVLLoading]);
+  }, [cosmosTVLData, cosmosTVLLoading, cosmosNetworkGuides]);
 
   useMemo(() => {
     if (!cosmosUnbondingTimeLoading) {
@@ -119,7 +119,11 @@ export const useNetworkGuidesHook = () => {
       });
     }
     return cosmosNetworkGuides;
-  }, [cosmosUnbondingTimeData, cosmosUnbondingTimeLoading]);
+  }, [
+    cosmosUnbondingTimeData,
+    cosmosUnbondingTimeLoading,
+    cosmosNetworkGuides,
+  ]);
 
   return {
     cosmosNetworkGuides,
diff --git a/src/screens/network_guides/components/network_info/index.tsx b/src/screens/network_guides/components/network_info/index.tsx
index 484e9a3c..0c8c33ed 100644
--- a/src/screens/network_guides/components/network_info/index.tsx
+++ b/src/screens/network_guides/components/network_info/index.tsx
@@ -53,7 +53,7 @@ const NetworkInfo = ({ post }: any) => {
       );
       setIsCopySuccess(true);
     },
-    [networkData?.address],
+    [networkData],
   );
   const coverImage = networkData
     ? `/images/guides/how_to_stake_${networkData.graphql}.png`
diff --git a/src/screens/staking/components/calculate_rewards/components/calculator/index.tsx b/src/screens/staking/components/calculate_rewards/components/calculator/index.tsx
index 7c22786a..6eadd053 100644
--- a/src/screens/staking/components/calculate_rewards/components/calculator/index.tsx
+++ b/src/screens/staking/components/calculate_rewards/components/calculator/index.tsx
@@ -44,7 +44,7 @@ const Calculator = (props: any) => {
     if (selectedToken === "") {
       setSelectedToken(networkData[0]);
     }
-  }, [selectedToken]);
+  }, [selectedToken, networkData, setSelectedToken]);
 
   const [isOpen, setIsOpen] = React.useState(false);
 
diff --git a/src/screens/staking/components/calculate_rewards/hooks.tsx b/src/screens/staking/components/calculate_rewards/hooks.tsx
index 5b2ec7cc..04ed1a70 100644
--- a/src/screens/staking/components/calculate_rewards/hooks.tsx
+++ b/src/screens/staking/components/calculate_rewards/hooks.tsx
@@ -75,6 +75,7 @@ export const useCalculateRewardsHook = () => {
       });
     }
     return stakingParamState;
+    // eslint-disable-next-line react-hooks/exhaustive-deps
   }, [
     cosmosCommissionLoading,
     cosmosCommissionData,
@@ -96,6 +97,7 @@ export const useCalculateRewardsHook = () => {
       });
     }
     return stakingParamState;
+    // eslint-disable-next-line react-hooks/exhaustive-deps
   }, [
     cosmosInflationLoading,
     cosmosInflationData,
@@ -117,6 +119,7 @@ export const useCalculateRewardsHook = () => {
       });
     }
     return stakingParamState;
+    // eslint-disable-next-line react-hooks/exhaustive-deps
   }, [cosmosBondedData, cosmosBondedLoading, selectedToken, setSelectedToken]);
 
   useMemo(() => {
@@ -133,6 +136,7 @@ export const useCalculateRewardsHook = () => {
       });
     }
     return stakingParamState;
+    // eslint-disable-next-line react-hooks/exhaustive-deps
   }, [cosmosSupplyData, cosmosSupplyLoading, selectedToken, setSelectedToken]);
 
   useMemo(() => {
@@ -149,6 +153,7 @@ export const useCalculateRewardsHook = () => {
         stakingRatio: ratio,
       }));
     }
+    // eslint-disable-next-line react-hooks/exhaustive-deps
   }, [
     cosmosBondedData,
     cosmosBondedLoading,
@@ -274,6 +279,7 @@ export const useCalculateRewardsHook = () => {
     if (tokens.value !== "" && monthlyPeriods !== 0) {
       handleDefaultCalculation();
     }
+    // eslint-disable-next-line react-hooks/exhaustive-deps
   }, [selectedToken, setSelectedToken, tokens, monthlyPeriods]);
 
   const handleChange = (e: any) => {
diff --git a/src/screens/staking/components/contact_forbole/components/contact_card/hooks.tsx b/src/screens/staking/components/contact_forbole/components/contact_card/hooks.tsx
index 04c0d314..36fb841e 100644
--- a/src/screens/staking/components/contact_forbole/components/contact_card/hooks.tsx
+++ b/src/screens/staking/components/contact_forbole/components/contact_card/hooks.tsx
@@ -21,7 +21,7 @@ const useContactCard = () => {
     } else if (canSubmit) {
       setCanSubmit(false);
     }
-  }, [inputs]);
+  }, [inputs, canSubmit]);
 
   const handleSubmit = (event: any) => {
     if (event) {
diff --git a/src/screens/staking/components/hero/components/stats/hooks.tsx b/src/screens/staking/components/hero/components/stats/hooks.tsx
index b82bc94d..08db33a0 100644
--- a/src/screens/staking/components/hero/components/stats/hooks.tsx
+++ b/src/screens/staking/components/hero/components/stats/hooks.tsx
@@ -219,7 +219,6 @@ export const useStatsHook = () => {
           }))
         : null,
     );
-    return stats;
   }, [
     cosmosTVL,
     elrondTotalTVL,
@@ -244,8 +243,7 @@ export const useStatsHook = () => {
           : null,
       );
     }
-    return stats;
-  }, [networkNumber]);
+  }, []);
 
   return stats;
 };
diff --git a/src/screens/staking/components/networks/components/network_grid/components/network_card/index.tsx b/src/screens/staking/components/networks/components/network_grid/components/network_card/index.tsx
index d9861d70..5d565379 100644
--- a/src/screens/staking/components/networks/components/network_grid/components/network_card/index.tsx
+++ b/src/screens/staking/components/networks/components/network_grid/components/network_card/index.tsx
@@ -46,7 +46,7 @@ const NetworkCard: FC<CardProp> = (props: CardProp) => {
   const handleExploreClick: MouseEventHandler<HTMLElement> = useCallback(
     (event) => {
       event.stopPropagation();
-      // if (network.delegate) window.open(network.delegate, '_top');
+
       if (network.guide)
         window.open(
           `${process.env.NEXT_PUBLIC_URL}/staking/${network.guide}`,
@@ -54,7 +54,7 @@ const NetworkCard: FC<CardProp> = (props: CardProp) => {
         );
       else if (network.delegate) window.open(network.delegate, "_top");
     },
-    [network.denom, network.key, network.delegate],
+    [network.delegate, network.guide],
   );
 
   /* A variable that is used to render the popover. */
diff --git a/src/screens/staking/components/networks/components/network_grid/hooks.ts b/src/screens/staking/components/networks/components/network_grid/hooks.ts
index dec9b112..38e909c6 100644
--- a/src/screens/staking/components/networks/components/network_grid/hooks.ts
+++ b/src/screens/staking/components/networks/components/network_grid/hooks.ts
@@ -90,6 +90,8 @@ export const useNetworkHook = () => {
       });
     }
     return cosmosNetworks;
+
+    // eslint-disable-next-line react-hooks/exhaustive-deps
   }, [cosmosBondedData, cosmosBondedLoading]);
 
   useMemo(() => {
@@ -109,6 +111,8 @@ export const useNetworkHook = () => {
       });
     }
     return cosmosNetworks;
+
+    // eslint-disable-next-line react-hooks/exhaustive-deps
   }, [cosmosAPYData, cosmosAPYLoading]);
 
   useMemo(() => {
@@ -128,6 +132,8 @@ export const useNetworkHook = () => {
       });
     }
     return cosmosNetworks;
+
+    // eslint-disable-next-line react-hooks/exhaustive-deps
   }, [cosmosTVLData, cosmosTVLLoading]);
 
   useMemo(() => {
@@ -146,6 +152,8 @@ export const useNetworkHook = () => {
           : null;
       });
     }
+
+    // eslint-disable-next-line react-hooks/exhaustive-deps
   }, [elrondBondedData, elrondBondedLoading]);
 
   useMemo(() => {
@@ -164,6 +172,8 @@ export const useNetworkHook = () => {
           : null;
       });
     }
+
+    // eslint-disable-next-line react-hooks/exhaustive-deps
   }, [elrondAPYData, elrondAPYLoading]);
 
   useMemo(() => {
@@ -182,6 +192,8 @@ export const useNetworkHook = () => {
           : null;
       });
     }
+
+    // eslint-disable-next-line react-hooks/exhaustive-deps
   }, [elrondTVLData, elrondTVLLoading]);
 
   useMemo(() => {
@@ -195,6 +207,8 @@ export const useNetworkHook = () => {
         },
       }));
     }
+
+    // eslint-disable-next-line react-hooks/exhaustive-deps
   }, [solanaTVLLoading, solanaTVLData]);
 
   useMemo(() => {
@@ -208,6 +222,8 @@ export const useNetworkHook = () => {
         },
       }));
     }
+
+    // eslint-disable-next-line react-hooks/exhaustive-deps
   }, [solanaBondedData, solanaBondedLoading]);
 
   useMemo(() => {
@@ -221,6 +237,8 @@ export const useNetworkHook = () => {
         },
       }));
     }
+
+    // eslint-disable-next-line react-hooks/exhaustive-deps
   }, [oasisTVLLoading, oasisTVLData]);
 
   useMemo(() => {
@@ -234,6 +252,8 @@ export const useNetworkHook = () => {
         },
       }));
     }
+
+    // eslint-disable-next-line react-hooks/exhaustive-deps
   }, [oasisBondedData, oasisBondedLoading]);
 
   useMemo(() => {
@@ -247,6 +267,8 @@ export const useNetworkHook = () => {
         },
       }));
     }
+
+    // eslint-disable-next-line react-hooks/exhaustive-deps
   }, [radixTVLLoading, radixTVLData]);
 
   useMemo(() => {
@@ -260,6 +282,8 @@ export const useNetworkHook = () => {
         },
       }));
     }
+
+    // eslint-disable-next-line react-hooks/exhaustive-deps
   }, [radixBondedData, radixBondedLoading]);
 
   return {
diff --git a/src/screens/staking/components/networks/components/search_bar/index.tsx b/src/screens/staking/components/networks/components/search_bar/index.tsx
index 11ab95cb..fca5c573 100644
--- a/src/screens/staking/components/networks/components/search_bar/index.tsx
+++ b/src/screens/staking/components/networks/components/search_bar/index.tsx
@@ -45,7 +45,7 @@ function scrollLock() {
  * an object that contains a startAdornment property.
  * @returns An object with the properties of InputProps and startAdornment.
  */
-function addSearch(InputProps: ComponentProps<typeof TextField>["InputProps"]) {
+function useSearch(InputProps: ComponentProps<typeof TextField>["InputProps"]) {
   const theme = useTheme();
   const startAdornment = (
     <InputAdornment position="start">
@@ -137,16 +137,17 @@ const SearchBar: FC<SearchBarProps> = () => {
   }));
   const styles = useStyles();
 
-  const renderInput: StyledAutocompleteProps["renderInput"] = useCallback(
+  const RenderInput: StyledAutocompleteProps["renderInput"] = useCallback(
     ({ InputProps, ...params }) => (
       <TextField
         {...params}
-        InputProps={addSearch(InputProps)}
+        // eslint-disable-next-line react-hooks/rules-of-hooks
+        InputProps={useSearch(InputProps)}
         placeholder={t("searchNetwork")}
         sx={styles.textField}
       />
     ),
-    [],
+    [styles.textField, t],
   );
   const [focused, setFocused] = useState(false);
   const handleFocus: FocusEventHandler = useCallback((event) => {
@@ -189,7 +190,7 @@ const SearchBar: FC<SearchBarProps> = () => {
         PaperComponent={PaperComponent}
         PopperComponent={PopperComponent}
         popupIcon={null}
-        renderInput={renderInput}
+        renderInput={RenderInput}
         renderOption={renderOption}
       />
       <Button
diff --git a/src/screens/tag/hooks.tsx b/src/screens/tag/hooks.tsx
index 14a25a26..e92b0a5b 100644
--- a/src/screens/tag/hooks.tsx
+++ b/src/screens/tag/hooks.tsx
@@ -6,5 +6,5 @@ export const useBlogHook = (error: any, t: any) => {
     if (error) {
       toast.error(t("error"));
     }
-  }, [error]);
+  }, [error, t]);
 };
diff --git a/src/styles/useColor.ts b/src/styles/useColor.ts
index f251c3bd..37ebb926 100644
--- a/src/styles/useColor.ts
+++ b/src/styles/useColor.ts
@@ -5,6 +5,7 @@ export default function useColor() {
   const theme = useTheme();
   const colorObj = theme.palette.custom.forbole;
   if (process.env.NODE_ENV !== "production") {
+    // eslint-disable-next-line react-hooks/rules-of-hooks
     useDebugValue(colorObj);
   }
 
diff --git a/src/utils/social_media_info.tsx b/src/utils/social_media_info.tsx
index cc914c46..5cb18f6c 100644
--- a/src/utils/social_media_info.tsx
+++ b/src/utils/social_media_info.tsx
@@ -1,5 +1,4 @@
 import { Github, Instagram, LinkedIn, Medium, Telegram, Twitter } from "@icons";
-import { useRouter } from "next/router";
 import { FunctionComponent } from "react";
 
 interface SocialMediaProps {
@@ -12,7 +11,7 @@ interface SocialMediasProps {
   [key: string]: SocialMediaProps;
 }
 
-const socialMedia: SocialMediasProps = {
+export const socialMedia: SocialMediasProps = {
   telegram: {
     key: "telegram",
     url: "https://t.me/forbole",
@@ -49,14 +48,3 @@ const socialMedia: SocialMediasProps = {
     component: Instagram,
   },
 };
-
-export const getSocialMediaInfo = (keyParam: string) => {
-  let key = keyParam;
-  const { locale } = useRouter();
-  if (key === "Instagram") {
-    if (locale !== "en") {
-      key += "_zh";
-    }
-  }
-  return socialMedia[key] ?? {};
-};

From 715dc30a4b023484ce9d3bea51ac05c34baced98 Mon Sep 17 00:00:00 2001
From: Ignacio <ignacio@forbole.com>
Date: Tue, 14 Nov 2023 19:15:54 +0800
Subject: [PATCH 2/8] fix: autocomplete key issue

---
 .../networks/components/search_bar/index.tsx        | 13 +++++++++----
 1 file changed, 9 insertions(+), 4 deletions(-)

diff --git a/src/screens/staking/components/networks/components/search_bar/index.tsx b/src/screens/staking/components/networks/components/search_bar/index.tsx
index fca5c573..03b93de4 100644
--- a/src/screens/staking/components/networks/components/search_bar/index.tsx
+++ b/src/screens/staking/components/networks/components/search_bar/index.tsx
@@ -131,10 +131,15 @@ const SearchBar: FC<SearchBarProps> = () => {
   const networkData: Array<Network> = keys
     .sort()
     .map((x: string) => getNetworkInfo(x));
-  const options = networkData.map((network) => ({
-    label: network.name,
-    network,
-  }));
+
+  const networkNames = networkData.map((network) => network.name);
+  const options = networkData
+    .map((network) => ({
+      label: network.name,
+      network,
+    }))
+    .filter((network, idx) => networkNames.indexOf(network.label) === idx);
+
   const styles = useStyles();
 
   const RenderInput: StyledAutocompleteProps["renderInput"] = useCallback(

From 47c9dd3f8c2b9633216333f16a885bd318c3ce08 Mon Sep 17 00:00:00 2001
From: Ignacio <ignacio@forbole.com>
Date: Tue, 14 Nov 2023 19:33:12 +0800
Subject: [PATCH 3/8] refactor: hook rules

---
 .../components/calculate_rewards/hooks.tsx    |  25 ++-
 .../networks/components/network_grid/hooks.ts | 189 +++++++++---------
 2 files changed, 117 insertions(+), 97 deletions(-)

diff --git a/src/screens/staking/components/calculate_rewards/hooks.tsx b/src/screens/staking/components/calculate_rewards/hooks.tsx
index 04ed1a70..d4879dc5 100644
--- a/src/screens/staking/components/calculate_rewards/hooks.tsx
+++ b/src/screens/staking/components/calculate_rewards/hooks.tsx
@@ -9,7 +9,7 @@ import { convertToMoney, convertWithDecimal } from "@utils/convert_to_money";
 import { getNetworkInfo } from "@utils/network_info";
 import axios from "axios";
 import * as R from "ramda";
-import { useEffect, useMemo, useState } from "react";
+import { useCallback, useEffect, useMemo, useState } from "react";
 
 import { getStakingParams } from "./config";
 import { defaultFunctions, networkFunctions, toFixed } from "./utils";
@@ -65,22 +65,24 @@ export const useCalculateRewardsHook = () => {
       const { eachCosmosCommission } = cosmosCommissionData;
       eachCosmosCommission.forEach((data: any) => {
         const key = selectedToken.graphql;
+        const commissionRateNew = parseFloat(data.commissionRate);
 
-        if (key === data.metric.instance) {
+        if (
+          key === data.metric.instance &&
+          stakingParamState?.commissionRate !== commissionRateNew
+        ) {
           setStakingParamState((prev) => ({
             ...prev,
-            commissionRate: parseFloat(data.commissionRate),
+            commissionRate: commissionRateNew,
           }));
         }
       });
     }
-    return stakingParamState;
-    // eslint-disable-next-line react-hooks/exhaustive-deps
   }, [
     cosmosCommissionLoading,
     cosmosCommissionData,
     selectedToken,
-    setSelectedToken,
+    stakingParamState?.commissionRate,
   ]);
 
   useMemo(() => {
@@ -162,7 +164,7 @@ export const useCalculateRewardsHook = () => {
     selectedToken,
   ]);
 
-  const handleDefaultCalculation = async () => {
+  const handleDefaultCalculation = useCallback(async () => {
     let networkFunction = networkFunctions[selectedToken.key] ?? null;
 
     if (
@@ -273,7 +275,14 @@ export const useCalculateRewardsHook = () => {
         amount: formatAnnualPrice,
       },
     });
-  };
+  }, [
+    commissionRate,
+    inflation,
+    monthlyPeriods,
+    selectedToken.key,
+    stakingRatio,
+    tokens?.value,
+  ]);
 
   useEffect(() => {
     if (tokens.value !== "" && monthlyPeriods !== 0) {
diff --git a/src/screens/staking/components/networks/components/network_grid/hooks.ts b/src/screens/staking/components/networks/components/network_grid/hooks.ts
index 38e909c6..72ca9b90 100644
--- a/src/screens/staking/components/networks/components/network_grid/hooks.ts
+++ b/src/screens/staking/components/networks/components/network_grid/hooks.ts
@@ -78,39 +78,40 @@ export const useNetworkHook = () => {
       const { eachCosmosBondedToken } = cosmosBondedData;
       eachCosmosBondedToken.forEach((data: any) => {
         const keys = Object.keys(cosmosNetworks);
-        keys.includes(data.metric.instance)
-          ? setCosmosNetworks((prev) => ({
-              ...prev,
-              [data.metric.instance]: {
-                ...cosmosNetworks[data.metric.instance],
-                bonded: data.bondedToken,
-              },
-            }))
-          : null;
+
+        if (
+          keys.includes(data.metric.instance) &&
+          cosmosNetworks?.[data.metric.instance]?.bonded !== data?.bondedToken
+        ) {
+          setCosmosNetworks((prev) => ({
+            ...prev,
+            [data.metric.instance]: {
+              ...cosmosNetworks[data.metric.instance],
+              bonded: data.bondedToken,
+            },
+          }));
+        }
       });
     }
-    return cosmosNetworks;
-
-    // eslint-disable-next-line react-hooks/exhaustive-deps
-  }, [cosmosBondedData, cosmosBondedLoading]);
+  }, [cosmosBondedData, cosmosBondedLoading, cosmosNetworks]);
 
   useMemo(() => {
     if (!cosmosAPYLoading) {
       const { eachCosmosAPY } = cosmosAPYData;
       eachCosmosAPY.forEach((data: any) => {
         const keys = Object.keys(cosmosNetworks);
-        keys.includes(data.metric.instance)
-          ? setCosmosNetworks((prev) => ({
-              ...prev,
-              [data.metric.instance]: {
-                ...cosmosNetworks[data.metric.instance],
-                APY: data.APY,
-              },
-            }))
-          : null;
+
+        if (keys.includes(data.metric.instance)) {
+          setCosmosNetworks((prev) => ({
+            ...prev,
+            [data.metric.instance]: {
+              ...cosmosNetworks[data.metric.instance],
+              APY: data.APY,
+            },
+          }));
+        }
       });
     }
-    return cosmosNetworks;
 
     // eslint-disable-next-line react-hooks/exhaustive-deps
   }, [cosmosAPYData, cosmosAPYLoading]);
@@ -120,15 +121,16 @@ export const useNetworkHook = () => {
       const { eachCosmosTVL } = cosmosTVLData;
       eachCosmosTVL.forEach((data: any) => {
         const keys = Object.keys(cosmosNetworks);
-        keys.includes(data.metric.instance)
-          ? setCosmosNetworks((prev) => ({
-              ...prev,
-              [data.metric.instance]: {
-                ...cosmosNetworks[data.metric.instance],
-                TVL: data.TVL,
-              },
-            }))
-          : null;
+
+        if (keys.includes(data.metric.instance)) {
+          setCosmosNetworks((prev) => ({
+            ...prev,
+            [data.metric.instance]: {
+              ...cosmosNetworks[data.metric.instance],
+              TVL: data.TVL,
+            },
+          }));
+        }
       });
     }
     return cosmosNetworks;
@@ -141,15 +143,16 @@ export const useNetworkHook = () => {
       const { elrondBondedToken } = elrondBondedData;
       elrondBondedToken.forEach((data: any) => {
         const key = Object.keys(elrondNetwork);
-        key.includes(data.metric.instance)
-          ? setElrondNetwork((prev) => ({
-              ...prev,
-              [data.metric.instance]: {
-                ...elrondNetwork[data.metric.instance],
-                bonded: elrondNetworkFunctions.converter(data.bondedToken),
-              },
-            }))
-          : null;
+
+        if (key.includes(data.metric.instance)) {
+          setElrondNetwork((prev) => ({
+            ...prev,
+            [data.metric.instance]: {
+              ...elrondNetwork[data.metric.instance],
+              bonded: elrondNetworkFunctions.converter(data.bondedToken),
+            },
+          }));
+        }
       });
     }
 
@@ -161,15 +164,15 @@ export const useNetworkHook = () => {
       const { elrondAPY } = elrondAPYData;
       elrondAPY.forEach((data: any) => {
         const key = Object.keys(elrondNetwork);
-        key.includes(data.metric.instance)
-          ? setElrondNetwork((prev) => ({
-              ...prev,
-              [data.metric.instance]: {
-                ...elrondNetwork[data.metric.instance],
-                APY: elrondNetworkFunctions.converter(data.APY),
-              },
-            }))
-          : null;
+        if (key.includes(data.metric.instance)) {
+          setElrondNetwork((prev) => ({
+            ...prev,
+            [data.metric.instance]: {
+              ...elrondNetwork[data.metric.instance],
+              APY: elrondNetworkFunctions.converter(data.APY),
+            },
+          }));
+        }
       });
     }
 
@@ -181,15 +184,15 @@ export const useNetworkHook = () => {
       const { elrondTVL } = elrondTVLData;
       elrondTVL.forEach((data: any) => {
         const key = Object.keys(elrondNetwork);
-        key.includes(data.metric.instance)
-          ? setElrondNetwork((prev) => ({
-              ...prev,
-              [data.metric.instance]: {
-                ...elrondNetwork[data.metric.instance],
-                TVL: elrondNetworkFunctions.converter(data.TVL),
-              },
-            }))
-          : null;
+        if (key.includes(data.metric.instance)) {
+          setElrondNetwork((prev) => ({
+            ...prev,
+            [data.metric.instance]: {
+              ...elrondNetwork[data.metric.instance],
+              TVL: elrondNetworkFunctions.converter(data.TVL),
+            },
+          }));
+        }
       });
     }
 
@@ -244,47 +247,55 @@ export const useNetworkHook = () => {
   useMemo(() => {
     if (!oasisBondedLoading) {
       const { oasisBondedToken } = oasisBondedData;
-      setOasisNetwork((prev) => ({
-        ...prev,
-        [oasisBondedToken[0].metric.instance]: {
-          ...oasisNetwork[oasisBondedToken[0].metric.instance],
-          bonded: oasisBondedToken[0].bondedToken,
-        },
-      }));
-    }
+      const key = oasisBondedToken[0].metric.instance;
+      const bonded = oasisBondedToken[0].bondedToken;
 
-    // eslint-disable-next-line react-hooks/exhaustive-deps
-  }, [oasisBondedData, oasisBondedLoading]);
+      if (oasisNetwork[key]?.bonded !== bonded) {
+        setOasisNetwork((prev) => ({
+          ...prev,
+          [key]: {
+            ...oasisNetwork[key],
+            bonded,
+          },
+        }));
+      }
+    }
+  }, [oasisBondedData, oasisBondedLoading, oasisNetwork]);
 
   useMemo(() => {
     if (!radixTVLLoading) {
       const { radixTVL } = radixTVLData;
-      setRadixNetwork((prev) => ({
-        ...prev,
-        [radixTVL[0].metric.instance]: {
-          ...radixNetwork[radixTVL[0].metric.instance],
-          TVL: radixTVL[0].TVL,
-        },
-      }));
-    }
+      const key = radixTVL[0].metric.instance;
+      const { TVL } = radixTVL[0];
 
-    // eslint-disable-next-line react-hooks/exhaustive-deps
-  }, [radixTVLLoading, radixTVLData]);
+      if (radixNetwork[key]?.TVL !== TVL) {
+        setRadixNetwork((prev) => ({
+          ...prev,
+          [key]: {
+            ...radixNetwork[key],
+            TVL,
+          },
+        }));
+      }
+    }
+  }, [radixTVLLoading, radixTVLData, radixNetwork]);
 
   useMemo(() => {
     if (!radixBondedLoading) {
       const { allRadixStakedTokens } = radixBondedData;
-      setRadixNetwork((prev) => ({
-        ...prev,
-        [allRadixStakedTokens[0].metric.instance]: {
-          ...oasisNetwork[allRadixStakedTokens[0].metric.instance],
-          bonded: allRadixStakedTokens[0].bondedToken,
-        },
-      }));
+      const key = allRadixStakedTokens[0].metric.instance;
+      const bonded = allRadixStakedTokens[0].bondedToken;
+      if (radixNetwork[key]?.bonded !== bonded) {
+        setRadixNetwork((prev) => ({
+          ...prev,
+          [key]: {
+            ...radixNetwork[key],
+            bonded,
+          },
+        }));
+      }
     }
-
-    // eslint-disable-next-line react-hooks/exhaustive-deps
-  }, [radixBondedData, radixBondedLoading]);
+  }, [radixBondedData, radixBondedLoading, radixNetwork]);
 
   return {
     cosmosNetworks,

From ecd6a53a0e19d90995ee67110b46247963f6c9c1 Mon Sep 17 00:00:00 2001
From: Ignacio <ignacio@forbole.com>
Date: Tue, 14 Nov 2023 19:41:03 +0800
Subject: [PATCH 4/8] chore: remove full ramda import

---
 src/components/layout/index.tsx               |  4 +-
 src/components/layout_val/index.tsx           |  4 +-
 src/models/tag.ts                             |  4 +-
 .../blog/components/blog_posts/index.tsx      |  8 +--
 .../components/calculate_rewards/hooks.tsx    |  4 +-
 .../components/calculate_rewards/utils.ts     | 50 +++++++++----------
 src/screens/terms_and_conditions/index.tsx    | 30 +++++------
 src/utils/network_functions.ts                | 24 ++++-----
 8 files changed, 61 insertions(+), 67 deletions(-)

diff --git a/src/components/layout/index.tsx b/src/components/layout/index.tsx
index cc479076..83cb364b 100644
--- a/src/components/layout/index.tsx
+++ b/src/components/layout/index.tsx
@@ -3,7 +3,7 @@ import useColor from "@src/styles/useColor";
 import useTranslation from "next-translate/useTranslation";
 import Head from "next/head";
 import { useRouter } from "next/router";
-import * as R from "ramda";
+import { concat, uniq } from "ramda";
 import { ReactNode, useEffect } from "react";
 import validator from "validator";
 
@@ -46,7 +46,7 @@ const Layout = ({
   let ogImage = image ?? `${url}/static/icons/favicon-96x96.png`;
   let metaTwitterImage = twitterImage ?? ogImage;
   const baseKeywords = ["Forbole", "blockchain", "social network"];
-  const formattedKeyworks = R.uniq(R.concat(keywords, baseKeywords));
+  const formattedKeyworks = uniq(concat(keywords, baseKeywords));
   if (!validator.isURL(ogImage)) {
     ogImage = `${url}${ogImage}`;
   }
diff --git a/src/components/layout_val/index.tsx b/src/components/layout_val/index.tsx
index 10dfa8d0..ebf3c4f1 100644
--- a/src/components/layout_val/index.tsx
+++ b/src/components/layout_val/index.tsx
@@ -2,7 +2,7 @@ import { Box, useTheme } from "@mui/material";
 import useTranslation from "next-translate/useTranslation";
 import Head from "next/head";
 import { useRouter } from "next/router";
-import * as R from "ramda";
+import { concat, uniq } from "ramda";
 import { ReactNode, RefObject } from "react";
 import validator from "validator";
 
@@ -43,7 +43,7 @@ const LayoutVal = ({
   let ogImage = image ?? `${url}/static/icons/favicon-96x96.png`;
   let metaTwitterImage = twitterImage ?? ogImage;
   const baseKeywords = ["Forbole", "blockchain", "social network"];
-  const formattedKeyworks = R.uniq(R.concat(keywords, baseKeywords));
+  const formattedKeyworks = uniq(concat(keywords, baseKeywords));
   if (!validator.isURL(ogImage)) {
     ogImage = `${url}${ogImage}`;
   }
diff --git a/src/models/tag.ts b/src/models/tag.ts
index 22fec1e4..4c819929 100644
--- a/src/models/tag.ts
+++ b/src/models/tag.ts
@@ -1,4 +1,4 @@
-import * as R from "ramda";
+import { pathOr } from "ramda";
 
 class Tag {
   public name: string;
@@ -21,7 +21,7 @@ class Tag {
       name: data.name,
       slug: data.slug ?? data.name,
       url: data.url ?? data.name,
-      count: { posts: R.pathOr("", ["count", "posts"], data) },
+      count: { posts: pathOr("", ["count", "posts"], data) },
     });
   }
 }
diff --git a/src/screens/blog/components/blog_posts/index.tsx b/src/screens/blog/components/blog_posts/index.tsx
index caea84bb..a4367151 100644
--- a/src/screens/blog/components/blog_posts/index.tsx
+++ b/src/screens/blog/components/blog_posts/index.tsx
@@ -2,7 +2,7 @@ import { useWindowDimensions } from "@hooks";
 import { Box, Button, Pagination, useTheme } from "@mui/material";
 import useTranslation from "next-translate/useTranslation";
 import { useRouter } from "next/router";
-import * as R from "ramda";
+import { pathOr } from "ramda";
 import React from "react";
 
 import Post from "./components/post";
@@ -17,9 +17,9 @@ const BlogPosts = ({ main, blogs: blogsUpper, meta }: IProps) => {
   const { windowDimensions, isMobile } = useWindowDimensions();
   const { width } = windowDimensions;
 
-  const currentPage = R.pathOr(0, ["pagination", "page"], meta);
-  const totalPages = R.pathOr(0, ["pagination", "pages"], meta);
-  const totalPosts = R.pathOr(0, ["pagination", "total"], meta);
+  const currentPage = pathOr(0, ["pagination", "page"], meta);
+  const totalPages = pathOr(0, ["pagination", "pages"], meta);
+  const totalPosts = pathOr(0, ["pagination", "total"], meta);
 
   const [limitUpper, setLimitUpper] = React.useState(15);
   const [lastView, setLastView] = React.useState(0);
diff --git a/src/screens/staking/components/calculate_rewards/hooks.tsx b/src/screens/staking/components/calculate_rewards/hooks.tsx
index d4879dc5..6125301e 100644
--- a/src/screens/staking/components/calculate_rewards/hooks.tsx
+++ b/src/screens/staking/components/calculate_rewards/hooks.tsx
@@ -8,7 +8,7 @@ import {
 import { convertToMoney, convertWithDecimal } from "@utils/convert_to_money";
 import { getNetworkInfo } from "@utils/network_info";
 import axios from "axios";
-import * as R from "ramda";
+import { pathOr } from "ramda";
 import { useCallback, useEffect, useMemo, useState } from "react";
 
 import { getStakingParams } from "./config";
@@ -292,7 +292,7 @@ export const useCalculateRewardsHook = () => {
   }, [selectedToken, setSelectedToken, tokens, monthlyPeriods]);
 
   const handleChange = (e: any) => {
-    const value: any = R.pathOr(0, ["target", "value"], e);
+    const value: any = pathOr(0, ["target", "value"], e);
     if (!value) {
       setTokens({
         value: "",
diff --git a/src/screens/staking/components/calculate_rewards/utils.ts b/src/screens/staking/components/calculate_rewards/utils.ts
index a91176c3..4bcc2654 100644
--- a/src/screens/staking/components/calculate_rewards/utils.ts
+++ b/src/screens/staking/components/calculate_rewards/utils.ts
@@ -1,4 +1,4 @@
-import * as R from "ramda";
+import { clone, pathOr } from "ramda";
 
 type NetworkDataProps = {
   bonded?: (data: any) => number;
@@ -55,74 +55,74 @@ const uSolanaToSolana = defaultConverter(1);
 
 export const defaultFunctions = (converter?: any) => ({
   bonded: (data: any) =>
-    converter(Number(R.pathOr(0, ["result", "bonded_tokens"], data))),
-  inflation: (data: any) => toFixed(Number(R.pathOr(0, ["result"], data))) ?? 0,
-  supply: (data: any) => converter(Number(R.pathOr(0, ["result"], data))),
+    converter(Number(pathOr(0, ["result", "bonded_tokens"], data))),
+  inflation: (data: any) => toFixed(Number(pathOr(0, ["result"], data))) ?? 0,
+  supply: (data: any) => converter(Number(pathOr(0, ["result"], data))),
   commissionRate: (data: any) =>
     Number(
-      R.pathOr(0, ["result", "commission", "commission_rates", "rate"], data),
+      pathOr(0, ["result", "commission", "commission_rates", "rate"], data),
     ),
   marketPrice: (data: any) =>
-    toFixed(Number(R.pathOr(0, ["market_data", "current_price", "usd"], data))),
+    toFixed(Number(pathOr(0, ["market_data", "current_price", "usd"], data))),
   converter,
 });
 
-const cosmos: any = R.clone(defaultFunctions(uAtomToAtom));
+const cosmos: any = clone(defaultFunctions(uAtomToAtom));
 cosmos.gecko = "https://api.coingecko.com/api/v3/coins/cosmos";
 
-const terra: any = R.clone(defaultFunctions(uLunaToLuna));
+const terra: any = clone(defaultFunctions(uLunaToLuna));
 terra.gecko = "https://api.coingecko.com/api/v3/coins/terra-luna";
 
-const kava: any = R.clone(defaultFunctions(uKavaToKava));
+const kava: any = clone(defaultFunctions(uKavaToKava));
 kava.gecko = "https://api.coingecko.com/api/v3/coins/kava";
 
-const akash: any = R.clone(defaultFunctions(uAktToAkash));
+const akash: any = clone(defaultFunctions(uAktToAkash));
 akash.gecko = "https://api.coingecko.com/api/v3/coins/akash-network";
 
-const band: any = R.clone(defaultFunctions(uBandToBand));
+const band: any = clone(defaultFunctions(uBandToBand));
 band.gecko = "https://api.coingecko.com/api/v3/coins/band-protocol";
 
-const iov: any = R.clone(defaultFunctions(uIovToIov));
+const iov: any = clone(defaultFunctions(uIovToIov));
 iov.gecko = "https://api.coingecko.com/api/v3/coins/starname";
 
-const likecoin: any = R.clone(defaultFunctions(nanoLikeToLike));
+const likecoin: any = clone(defaultFunctions(nanoLikeToLike));
 likecoin.gecko = "https://api.coingecko.com/api/v3/coins/likecoin";
 
-const vsys: any = R.clone(defaultFunctions(uBandToBand));
+const vsys: any = clone(defaultFunctions(uBandToBand));
 vsys.gecko = "https://api.coingecko.com/api/v3/coins/v-systems";
 
-const emoney: any = R.clone(defaultFunctions(uBandToBand));
+const emoney: any = clone(defaultFunctions(uBandToBand));
 emoney.gecko = "https://api.coingecko.com/api/v3/coins/iris-network";
 
-const iris: any = R.clone(defaultFunctions(uIrisToIris));
+const iris: any = clone(defaultFunctions(uIrisToIris));
 iris.gecko = "https://api.coingecko.com/api/v3/coins/iris-network";
 
-const cryptoOrg: any = R.clone(defaultFunctions(uCryptoOrgToCryptoOrg));
+const cryptoOrg: any = clone(defaultFunctions(uCryptoOrgToCryptoOrg));
 cryptoOrg.gecko = "https://api.coingecko.com/api/v3/coins/crypto-com-chain";
 
-const sentinel: any = R.clone(defaultFunctions(uSentinelToSentinel));
+const sentinel: any = clone(defaultFunctions(uSentinelToSentinel));
 sentinel.gecko = "https://api.coingecko.com/api/v3/coins/sentinel";
 
-const fetchAI: any = R.clone(defaultFunctions(uFetchAIToFetchAI));
+const fetchAI: any = clone(defaultFunctions(uFetchAIToFetchAI));
 fetchAI.gecko = "https://api.coingecko.com/api/v3/coins/fetch-ai";
 
 // Regen Network not listed on Coingecko yet
-const regen: any = R.clone(defaultFunctions(uRegenToRegen));
+const regen: any = clone(defaultFunctions(uRegenToRegen));
 // regen.gecko = "https://api.coingecko.com/api/v3/coins/regen-network";
 
-const bitsong: any = R.clone(defaultFunctions(uBitsongToBitsong));
+const bitsong: any = clone(defaultFunctions(uBitsongToBitsong));
 bitsong.gecko = "https://api.coingecko.com/api/v3/coins/bitsong";
 
-const oasis: any = R.clone(defaultFunctions(uOasisToOasis));
+const oasis: any = clone(defaultFunctions(uOasisToOasis));
 oasis.gecko = "https://api.coingecko.com/api/v3/coins/oasis-network";
 
-const kusama: any = R.clone(defaultFunctions(uKusamaToKusama));
+const kusama: any = clone(defaultFunctions(uKusamaToKusama));
 kusama.gecko = "https://api.coingecko.com/api/v3/coins/kusama";
 
-const flow: any = R.clone(defaultFunctions(uFlowToFlow));
+const flow: any = clone(defaultFunctions(uFlowToFlow));
 flow.gecko = "https://api.coingecko.com/api/v3/coins/flow";
 
-const solana: any = R.clone(defaultFunctions(uSolanaToSolana));
+const solana: any = clone(defaultFunctions(uSolanaToSolana));
 solana.gecko = "https://api.coingecko.com/api/v3/coins/solana";
 
 // available networks for calculations
diff --git a/src/screens/terms_and_conditions/index.tsx b/src/screens/terms_and_conditions/index.tsx
index 1d59d1d2..e9b96696 100644
--- a/src/screens/terms_and_conditions/index.tsx
+++ b/src/screens/terms_and_conditions/index.tsx
@@ -20,24 +20,18 @@ const TermsAndConditions = () => {
     window.scrollTo(0, ref.current.offsetTop - 100);
   };
   useEffect(() => {
-    // eslint-disable-next-line no-undef
-    (document.querySelectorAll(".t1") as NodeListOf<HTMLElement>).forEach(
-      (d) => {
-        if (!d.parentElement) return;
-        const h = d.parentElement.offsetHeight - 1;
-        // eslint-disable-next-line no-param-reassign
-        d.style.height = `${h}px`;
-      },
-    );
-    // eslint-disable-next-line no-undef
-    (document.querySelectorAll(".t2") as NodeListOf<HTMLElement>).forEach(
-      (d) => {
-        if (!d.parentElement) return;
-        const h = d.parentElement.offsetHeight - 1;
-        // eslint-disable-next-line no-param-reassign
-        d.style.height = `${h}px`;
-      },
-    );
+    document.querySelectorAll(".t1").forEach((d) => {
+      if (!d.parentElement) return;
+      const h = d.parentElement.offsetHeight - 1;
+      // eslint-disable-next-line no-param-reassign
+      (d as HTMLElement).style.height = `${h}px`;
+    });
+    document.querySelectorAll(".t2").forEach((d) => {
+      if (!d.parentElement) return;
+      const h = d.parentElement.offsetHeight - 1;
+      // eslint-disable-next-line no-param-reassign
+      (d as HTMLElement).style.height = `${h}px`;
+    });
   });
   return (
     <Layout footer title={t("title")}>
diff --git a/src/utils/network_functions.ts b/src/utils/network_functions.ts
index 6d084b7b..4351cad1 100644
--- a/src/utils/network_functions.ts
+++ b/src/utils/network_functions.ts
@@ -1,4 +1,4 @@
-import * as R from "ramda";
+import { clone, pathOr } from "ramda";
 
 const toFixed = (num: number): number => Number(num?.toFixed(2) ?? "0");
 
@@ -25,38 +25,38 @@ const uEGLDToEGLD = defaultConverter(1000000000000000000);
 const defaultFunctions = (converter: any) => ({
   gecko: "",
   marketPrice: (data: any) =>
-    toFixed(Number(R.pathOr(0, ["market_data", "current_price", "usd"], data))),
+    toFixed(Number(pathOr(0, ["market_data", "current_price", "usd"], data))),
   converter,
 });
 
-const cosmos = R.clone(defaultFunctions(uAtomToAtom));
+const cosmos = clone(defaultFunctions(uAtomToAtom));
 cosmos.gecko = "https://api.coingecko.com/api/v3/coins/cosmos";
 
-const terra = R.clone(defaultFunctions(uLunaToLuna));
+const terra = clone(defaultFunctions(uLunaToLuna));
 terra.gecko = "https://api.coingecko.com/api/v3/coins/terra-luna";
 
-const kava = R.clone(defaultFunctions(uKavaToKava));
+const kava = clone(defaultFunctions(uKavaToKava));
 kava.gecko = "https://api.coingecko.com/api/v3/coins/kava";
 
-const akash = R.clone(defaultFunctions(uAktToAkash));
+const akash = clone(defaultFunctions(uAktToAkash));
 akash.gecko = "https://api.coingecko.com/api/v3/coins/akash-network";
 
-const band = R.clone(defaultFunctions(uBandToBand));
+const band = clone(defaultFunctions(uBandToBand));
 band.gecko = "https://api.coingecko.com/api/v3/coins/band-protocol";
 
-const iov = R.clone(defaultFunctions(uIovToIov));
+const iov = clone(defaultFunctions(uIovToIov));
 iov.gecko = "https://api.coingecko.com/api/v3/coins/starname";
 
-const likecoin = R.clone(defaultFunctions(nanoLikeToLike));
+const likecoin = clone(defaultFunctions(nanoLikeToLike));
 likecoin.gecko = "https://api.coingecko.com/api/v3/coins/likecoin";
 
-const vsys = R.clone(defaultFunctions(uBandToBand));
+const vsys = clone(defaultFunctions(uBandToBand));
 vsys.gecko = "https://api.coingecko.com/api/v3/coins/v-systems";
 
-const emoney = R.clone(defaultFunctions(uBandToBand));
+const emoney = clone(defaultFunctions(uBandToBand));
 emoney.gecko = "https://api.coingecko.com/api/v3/coins/e-money";
 
-const elrond = R.clone(defaultFunctions(uEGLDToEGLD));
+const elrond = clone(defaultFunctions(uEGLDToEGLD));
 
 // networks needed for converter
 export const networkFunctions = {

From 0d59872790893ac3c9c0dce863851c17ee6ea879 Mon Sep 17 00:00:00 2001
From: Ignacio <ignacio@forbole.com>
Date: Tue, 14 Nov 2023 19:41:58 +0800
Subject: [PATCH 5/8] chore: remove lodash in favour of ramda

---
 package-lock.json | 11 ++---------
 package.json      |  2 --
 2 files changed, 2 insertions(+), 11 deletions(-)

diff --git a/package-lock.json b/package-lock.json
index e40912e5..8767bcca 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -27,7 +27,6 @@
         "graphql": "^16.6.0",
         "isomorphic-dompurify": "^1.9.0",
         "jsdom": "^22.1.0",
-        "lodash": "^4.17.21",
         "lottie-react": "^2.3.1",
         "markdown-to-jsx": "^7.1.9",
         "moment": "^2.29.4",
@@ -53,7 +52,6 @@
         "@trivago/prettier-plugin-sort-imports": "^4.2.1",
         "@types/cors": "^2.8.16",
         "@types/express": "^4.17.13",
-        "@types/lodash": "^4.14.185",
         "@types/node": "^20.9.0",
         "@types/nodemailer": "^6.4.4",
         "@types/ramda": "^0.29.8",
@@ -3460,12 +3458,6 @@
       "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==",
       "dev": true
     },
-    "node_modules/@types/lodash": {
-      "version": "4.14.201",
-      "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.201.tgz",
-      "integrity": "sha512-y9euML0cim1JrykNxADLfaG0FgD1g/yTHwUs/Jg9ZIU7WKj2/4IW9Lbb1WZbvck78W/lfGXFfe+u2EGfIJXdLQ==",
-      "dev": true
-    },
     "node_modules/@types/mime": {
       "version": "1.3.5",
       "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz",
@@ -7845,7 +7837,8 @@
     "node_modules/lodash": {
       "version": "4.17.21",
       "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
-      "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
+      "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
+      "dev": true
     },
     "node_modules/lodash.debounce": {
       "version": "4.0.8",
diff --git a/package.json b/package.json
index a1434090..a4b26eee 100644
--- a/package.json
+++ b/package.json
@@ -37,7 +37,6 @@
     "graphql": "^16.6.0",
     "isomorphic-dompurify": "^1.9.0",
     "jsdom": "^22.1.0",
-    "lodash": "^4.17.21",
     "lottie-react": "^2.3.1",
     "markdown-to-jsx": "^7.1.9",
     "moment": "^2.29.4",
@@ -63,7 +62,6 @@
     "@trivago/prettier-plugin-sort-imports": "^4.2.1",
     "@types/cors": "^2.8.16",
     "@types/express": "^4.17.13",
-    "@types/lodash": "^4.14.185",
     "@types/node": "^20.9.0",
     "@types/nodemailer": "^6.4.4",
     "@types/ramda": "^0.29.8",

From 81183077e43a8d5f4b5079d02b9752077cf5ed59 Mon Sep 17 00:00:00 2001
From: Ignacio <ignacio@forbole.com>
Date: Tue, 14 Nov 2023 19:46:02 +0800
Subject: [PATCH 6/8] chore: remove unused

---
 package-lock.json | 208 ----------------------------------------------
 package.json      |   3 -
 2 files changed, 211 deletions(-)

diff --git a/package-lock.json b/package-lock.json
index 8767bcca..e7365464 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -27,7 +27,6 @@
         "graphql": "^16.6.0",
         "isomorphic-dompurify": "^1.9.0",
         "jsdom": "^22.1.0",
-        "lottie-react": "^2.3.1",
         "markdown-to-jsx": "^7.1.9",
         "moment": "^2.29.4",
         "moment-timezone": "^0.5.41",
@@ -40,7 +39,6 @@
         "react": "^18.2.0",
         "react-dom": "^18.2.0",
         "react-toastify": "^9.0.3",
-        "react-twitter-embed": "^4.0.4",
         "recoil": "^0.7.7",
         "sharp": "^0.31.3",
         "swiper": "^6.8.4",
@@ -77,7 +75,6 @@
         "nodemon": "^3.0.1",
         "postcss": "^8.4.27",
         "prettier": "^3.0.3",
-        "react-dotenv": "^0.1.3",
         "ts-unused-exports": "^10.0.1",
         "typescript": "^5.2.2"
       }
@@ -4647,44 +4644,6 @@
         "node": ">=0.8.0"
       }
     },
-    "node_modules/cheerio": {
-      "version": "1.0.0-rc.12",
-      "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.12.tgz",
-      "integrity": "sha512-VqR8m68vM46BNnuZ5NtnGBKIE/DfN0cRIzg9n40EIq9NOv90ayxLBXA8fXC5gquFRGJSTRqBq25Jt2ECLR431Q==",
-      "dev": true,
-      "dependencies": {
-        "cheerio-select": "^2.1.0",
-        "dom-serializer": "^2.0.0",
-        "domhandler": "^5.0.3",
-        "domutils": "^3.0.1",
-        "htmlparser2": "^8.0.1",
-        "parse5": "^7.0.0",
-        "parse5-htmlparser2-tree-adapter": "^7.0.0"
-      },
-      "engines": {
-        "node": ">= 6"
-      },
-      "funding": {
-        "url": "https://github.com/cheeriojs/cheerio?sponsor=1"
-      }
-    },
-    "node_modules/cheerio-select": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-2.1.0.tgz",
-      "integrity": "sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==",
-      "dev": true,
-      "dependencies": {
-        "boolbase": "^1.0.0",
-        "css-select": "^5.1.0",
-        "css-what": "^6.1.0",
-        "domelementtype": "^2.3.0",
-        "domhandler": "^5.0.3",
-        "domutils": "^3.0.1"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/fb55"
-      }
-    },
     "node_modules/chokidar": {
       "version": "3.5.3",
       "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz",
@@ -4989,22 +4948,6 @@
         "node": ">= 8"
       }
     },
-    "node_modules/css-select": {
-      "version": "5.1.0",
-      "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz",
-      "integrity": "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==",
-      "dev": true,
-      "dependencies": {
-        "boolbase": "^1.0.0",
-        "css-what": "^6.1.0",
-        "domhandler": "^5.0.2",
-        "domutils": "^3.0.1",
-        "nth-check": "^2.0.1"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/fb55"
-      }
-    },
     "node_modules/css-tree": {
       "version": "1.1.3",
       "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.1.3.tgz",
@@ -5298,20 +5241,6 @@
         "csstype": "^3.0.2"
       }
     },
-    "node_modules/dom-serializer": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz",
-      "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==",
-      "dev": true,
-      "dependencies": {
-        "domelementtype": "^2.3.0",
-        "domhandler": "^5.0.2",
-        "entities": "^4.2.0"
-      },
-      "funding": {
-        "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1"
-      }
-    },
     "node_modules/dom7": {
       "version": "3.0.0",
       "resolved": "https://registry.npmjs.org/dom7/-/dom7-3.0.0.tgz",
@@ -5343,40 +5272,11 @@
         "node": ">=12"
       }
     },
-    "node_modules/domhandler": {
-      "version": "5.0.3",
-      "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz",
-      "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==",
-      "dev": true,
-      "dependencies": {
-        "domelementtype": "^2.3.0"
-      },
-      "engines": {
-        "node": ">= 4"
-      },
-      "funding": {
-        "url": "https://github.com/fb55/domhandler?sponsor=1"
-      }
-    },
     "node_modules/dompurify": {
       "version": "3.0.6",
       "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.0.6.tgz",
       "integrity": "sha512-ilkD8YEnnGh1zJ240uJsW7AzE+2qpbOUYjacomn3AvJ6J4JhKGSZ2nh4wUIXPZrEPppaCLx5jFe8T89Rk8tQ7w=="
     },
-    "node_modules/domutils": {
-      "version": "3.1.0",
-      "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz",
-      "integrity": "sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==",
-      "dev": true,
-      "dependencies": {
-        "dom-serializer": "^2.0.0",
-        "domelementtype": "^2.3.0",
-        "domhandler": "^5.0.3"
-      },
-      "funding": {
-        "url": "https://github.com/fb55/domutils?sponsor=1"
-      }
-    },
     "node_modules/dotenv": {
       "version": "16.3.1",
       "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.3.1.tgz",
@@ -6958,25 +6858,6 @@
         "html-tokenize": "bin/cmd.js"
       }
     },
-    "node_modules/htmlparser2": {
-      "version": "8.0.2",
-      "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.2.tgz",
-      "integrity": "sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==",
-      "dev": true,
-      "funding": [
-        "https://github.com/fb55/htmlparser2?sponsor=1",
-        {
-          "type": "github",
-          "url": "https://github.com/sponsors/fb55"
-        }
-      ],
-      "dependencies": {
-        "domelementtype": "^2.3.0",
-        "domhandler": "^5.0.3",
-        "domutils": "^3.0.1",
-        "entities": "^4.4.0"
-      }
-    },
     "node_modules/http-errors": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz",
@@ -7898,23 +7779,6 @@
         "loose-envify": "cli.js"
       }
     },
-    "node_modules/lottie-react": {
-      "version": "2.4.0",
-      "resolved": "https://registry.npmjs.org/lottie-react/-/lottie-react-2.4.0.tgz",
-      "integrity": "sha512-pDJGj+AQlnlyHvOHFK7vLdsDcvbuqvwPZdMlJ360wrzGFurXeKPr8SiRCjLf3LrNYKANQtSsh5dz9UYQHuqx4w==",
-      "dependencies": {
-        "lottie-web": "^5.10.2"
-      },
-      "peerDependencies": {
-        "react": "^16.8.0 || ^17.0.0 || ^18.0.0",
-        "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0"
-      }
-    },
-    "node_modules/lottie-web": {
-      "version": "5.12.2",
-      "resolved": "https://registry.npmjs.org/lottie-web/-/lottie-web-5.12.2.tgz",
-      "integrity": "sha512-uvhvYPC8kGPjXT3MyKMrL3JitEAmDMp30lVkuq/590Mw9ok6pWcFCwXJveo0t5uqYw1UREQHofD+jVpdjBv8wg=="
-    },
     "node_modules/lru-cache": {
       "version": "5.1.1",
       "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
@@ -8755,19 +8619,6 @@
         "url": "https://github.com/inikulin/parse5?sponsor=1"
       }
     },
-    "node_modules/parse5-htmlparser2-tree-adapter": {
-      "version": "7.0.0",
-      "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.0.0.tgz",
-      "integrity": "sha512-B77tOZrqqfUfnVcOrUvfdLbz4pu4RopLD/4vmu3HUPswwTA8OH0EMW9BlWR2B0RCoiZRAHEUu7IxeP1Pd1UU+g==",
-      "dev": true,
-      "dependencies": {
-        "domhandler": "^5.0.2",
-        "parse5": "^7.0.0"
-      },
-      "funding": {
-        "url": "https://github.com/inikulin/parse5?sponsor=1"
-      }
-    },
     "node_modules/parseurl": {
       "version": "1.3.3",
       "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
@@ -9161,45 +9012,6 @@
         "react": "^18.2.0"
       }
     },
-    "node_modules/react-dotenv": {
-      "version": "0.1.3",
-      "resolved": "https://registry.npmjs.org/react-dotenv/-/react-dotenv-0.1.3.tgz",
-      "integrity": "sha512-FUNnhN8urlpvq7bJ0Rjv9XtaaK9D/EPn2+TXWbhcz2eNiQz6+aOg8Y9qsssFsTuj9IWZkSJiHaq/ylRXTGjrmA==",
-      "dev": true,
-      "dependencies": {
-        "cheerio": "^1.0.0-rc.3",
-        "dotenv": "^8.2.0",
-        "lodash": "^4.17.20",
-        "prettier": "^2.1.2"
-      },
-      "bin": {
-        "react-dotenv": "src/cli.js"
-      }
-    },
-    "node_modules/react-dotenv/node_modules/dotenv": {
-      "version": "8.6.0",
-      "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-8.6.0.tgz",
-      "integrity": "sha512-IrPdXQsk2BbzvCBGBOTmmSH5SodmqZNt4ERAZDmW4CT+tL8VtvinqywuANaFu4bOMWki16nqf0e4oC0QIaDr/g==",
-      "dev": true,
-      "engines": {
-        "node": ">=10"
-      }
-    },
-    "node_modules/react-dotenv/node_modules/prettier": {
-      "version": "2.8.8",
-      "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz",
-      "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==",
-      "dev": true,
-      "bin": {
-        "prettier": "bin-prettier.js"
-      },
-      "engines": {
-        "node": ">=10.13.0"
-      },
-      "funding": {
-        "url": "https://github.com/prettier/prettier?sponsor=1"
-      }
-    },
     "node_modules/react-is": {
       "version": "18.2.0",
       "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz",
@@ -9240,21 +9052,6 @@
         "react-dom": ">=16.6.0"
       }
     },
-    "node_modules/react-twitter-embed": {
-      "version": "4.0.4",
-      "resolved": "https://registry.npmjs.org/react-twitter-embed/-/react-twitter-embed-4.0.4.tgz",
-      "integrity": "sha512-2JIL7qF+U62zRzpsh6SZDXNI3hRNVYf5vOZ1WRcMvwKouw+xC00PuFaD0aEp2wlyGaZ+f4x2VvX+uDadFQ3HVA==",
-      "dependencies": {
-        "scriptjs": "^2.5.9"
-      },
-      "engines": {
-        "node": ">=10"
-      },
-      "peerDependencies": {
-        "react": "^16.0.0 || ^17.0.0 || ^18.0.0",
-        "react-dom": "^16.0.0 || ^17.0.0 || ^18.0.0"
-      }
-    },
     "node_modules/readable-stream": {
       "version": "1.0.34",
       "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz",
@@ -9686,11 +9483,6 @@
         "loose-envify": "^1.1.0"
       }
     },
-    "node_modules/scriptjs": {
-      "version": "2.5.9",
-      "resolved": "https://registry.npmjs.org/scriptjs/-/scriptjs-2.5.9.tgz",
-      "integrity": "sha512-qGVDoreyYiP1pkQnbnFAUIS5AjenNwwQBdl7zeos9etl+hYKWahjRTfzAZZYBv5xNHx7vNKCmaLDQZ6Fr2AEXg=="
-    },
     "node_modules/semver": {
       "version": "6.3.1",
       "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
diff --git a/package.json b/package.json
index a4b26eee..b62b1de7 100644
--- a/package.json
+++ b/package.json
@@ -37,7 +37,6 @@
     "graphql": "^16.6.0",
     "isomorphic-dompurify": "^1.9.0",
     "jsdom": "^22.1.0",
-    "lottie-react": "^2.3.1",
     "markdown-to-jsx": "^7.1.9",
     "moment": "^2.29.4",
     "moment-timezone": "^0.5.41",
@@ -50,7 +49,6 @@
     "react": "^18.2.0",
     "react-dom": "^18.2.0",
     "react-toastify": "^9.0.3",
-    "react-twitter-embed": "^4.0.4",
     "recoil": "^0.7.7",
     "sharp": "^0.31.3",
     "swiper": "^6.8.4",
@@ -87,7 +85,6 @@
     "nodemon": "^3.0.1",
     "postcss": "^8.4.27",
     "prettier": "^3.0.3",
-    "react-dotenv": "^0.1.3",
     "ts-unused-exports": "^10.0.1",
     "typescript": "^5.2.2"
   },

From 953df0496099cb875addd8446e33ef23db7d5ab8 Mon Sep 17 00:00:00 2001
From: Ignacio <ignacio@forbole.com>
Date: Tue, 14 Nov 2023 19:50:00 +0800
Subject: [PATCH 7/8] fix: add staking page description

---
 public/locales/en/staking.json      | 1 +
 public/locales/zh-CN/staking.json   | 1 +
 public/locales/zh-HK/staking.json   | 1 +
 src/components/layout_val/index.tsx | 2 +-
 4 files changed, 4 insertions(+), 1 deletion(-)

diff --git a/public/locales/en/staking.json b/public/locales/en/staking.json
index 53143064..1591dd80 100644
--- a/public/locales/en/staking.json
+++ b/public/locales/en/staking.json
@@ -1,5 +1,6 @@
 {
   "FVH title": "Stake, earn and secure the networks with Forbole",
+  "description": "Stake, earn and secure the networks with Forbole",
   "annual reward": "Annual reward rate",
   "apy": "Annual Percentage Yield",
   "benefits bullet 1": "Earn your staking rewards, it allows you to earn rewards for securing the network with your contribution",
diff --git a/public/locales/zh-CN/staking.json b/public/locales/zh-CN/staking.json
index 53143064..1591dd80 100644
--- a/public/locales/zh-CN/staking.json
+++ b/public/locales/zh-CN/staking.json
@@ -1,5 +1,6 @@
 {
   "FVH title": "Stake, earn and secure the networks with Forbole",
+  "description": "Stake, earn and secure the networks with Forbole",
   "annual reward": "Annual reward rate",
   "apy": "Annual Percentage Yield",
   "benefits bullet 1": "Earn your staking rewards, it allows you to earn rewards for securing the network with your contribution",
diff --git a/public/locales/zh-HK/staking.json b/public/locales/zh-HK/staking.json
index 53143064..1591dd80 100644
--- a/public/locales/zh-HK/staking.json
+++ b/public/locales/zh-HK/staking.json
@@ -1,5 +1,6 @@
 {
   "FVH title": "Stake, earn and secure the networks with Forbole",
+  "description": "Stake, earn and secure the networks with Forbole",
   "annual reward": "Annual reward rate",
   "apy": "Annual Percentage Yield",
   "benefits bullet 1": "Earn your staking rewards, it allows you to earn rewards for securing the network with your contribution",
diff --git a/src/components/layout_val/index.tsx b/src/components/layout_val/index.tsx
index ebf3c4f1..795feba4 100644
--- a/src/components/layout_val/index.tsx
+++ b/src/components/layout_val/index.tsx
@@ -37,7 +37,7 @@ const LayoutVal = ({
 }: Props) => {
   const theme = useTheme();
   const router = useRouter();
-  const { t } = useTranslation();
+  const { t } = useTranslation("staking");
   const currentPath = router.asPath === "/" ? "/" : `${router.asPath}`;
   const url = process.env.NEXT_PUBLIC_URL;
   let ogImage = image ?? `${url}/static/icons/favicon-96x96.png`;

From 2b5f5a3469ec5ee066503ee35f365ee069c33995 Mon Sep 17 00:00:00 2001
From: Ignacio <ignacio@forbole.com>
Date: Tue, 14 Nov 2023 19:52:43 +0800
Subject: [PATCH 8/8] chore: remove unused dependencies

---
 package-lock.json | 14 --------------
 package.json      |  1 -
 2 files changed, 15 deletions(-)

diff --git a/package-lock.json b/package-lock.json
index e7365464..2dbddcce 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -17,7 +17,6 @@
         "@mui/material": "^5.14.3",
         "@n8tb1t/use-scroll-position": "^2.0.3",
         "@socialgouv/matomo-next": "^1.4.0",
-        "@splidejs/react-splide": "^0.7.12",
         "@tryghost/admin-api": "^1.13.0",
         "@tryghost/content-api": "^1.11.0",
         "axios": "^1.6.1",
@@ -2964,19 +2963,6 @@
         "next": ">= 9.5.5"
       }
     },
-    "node_modules/@splidejs/react-splide": {
-      "version": "0.7.12",
-      "resolved": "https://registry.npmjs.org/@splidejs/react-splide/-/react-splide-0.7.12.tgz",
-      "integrity": "sha512-UfXH+j47jsMc4x5HA/aOwuuHPqn6y9+ZTNYPWDRD8iLKvIVMZlzq2unjUEvyDAU+TTVPZOXkG2Ojeoz0P4AkZw==",
-      "dependencies": {
-        "@splidejs/splide": "^4.1.3"
-      }
-    },
-    "node_modules/@splidejs/splide": {
-      "version": "4.1.4",
-      "resolved": "https://registry.npmjs.org/@splidejs/splide/-/splide-4.1.4.tgz",
-      "integrity": "sha512-5I30evTJcAJQXt6vJ26g2xEkG+l1nXcpEw4xpKh0/FWQ8ozmAeTbtniVtVmz2sH1Es3vgfC4SS8B2X4o5JMptA=="
-    },
     "node_modules/@svgr/babel-plugin-add-jsx-attribute": {
       "version": "6.5.1",
       "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-6.5.1.tgz",
diff --git a/package.json b/package.json
index b62b1de7..f5d7884f 100644
--- a/package.json
+++ b/package.json
@@ -27,7 +27,6 @@
     "@mui/material": "^5.14.3",
     "@n8tb1t/use-scroll-position": "^2.0.3",
     "@socialgouv/matomo-next": "^1.4.0",
-    "@splidejs/react-splide": "^0.7.12",
     "@tryghost/admin-api": "^1.13.0",
     "@tryghost/content-api": "^1.11.0",
     "axios": "^1.6.1",