From be500e3c97c29d066e4b0a51ed0781e416de255b Mon Sep 17 00:00:00 2001
From: druvkotwani <druvkotwani12@gmail.com>
Date: Wed, 7 Aug 2024 22:13:22 +0530
Subject: [PATCH 01/23] feat: small fix

---
 client/src/app/page.tsx | 1 -
 1 file changed, 1 deletion(-)

diff --git a/client/src/app/page.tsx b/client/src/app/page.tsx
index 4fef394..3d159ca 100644
--- a/client/src/app/page.tsx
+++ b/client/src/app/page.tsx
@@ -23,7 +23,6 @@ export default function Home() {
       const res = await fetch("/api/fetchdata");
       const data = await res.json();
       setDatas(data.data);
-      console.log(data.data);
       setLoading(false);
     } catch (error) {
       console.error("Error fetching messages:", error);

From de9c45da4846bfefe4a2498bbd532fd1d40da1a7 Mon Sep 17 00:00:00 2001
From: druvkotwani <druvkotwani12@gmail.com>
Date: Fri, 9 Aug 2024 14:53:02 +0530
Subject: [PATCH 02/23] feat: Add error handling to generateStats function for
 improved user experience

---
 client/src/app/components/Card.tsx          | 40 +++++++------
 client/src/app/components/GenerateStats.tsx |  6 ++
 client/src/app/components/SocialLinks.tsx   | 65 +++++----------------
 client/src/app/page.tsx                     | 52 +++++++++++++----
 4 files changed, 83 insertions(+), 80 deletions(-)

diff --git a/client/src/app/components/Card.tsx b/client/src/app/components/Card.tsx
index 3e8739b..335ca72 100644
--- a/client/src/app/components/Card.tsx
+++ b/client/src/app/components/Card.tsx
@@ -5,31 +5,37 @@ import SocialLinks from "./SocialLinks";
 
 export const data = {
   profileData: {
+    username: "druv_kotwani",
+    rank: 263817,
     image: "https://assets.leetcode.com/users/avatars/avatar_1672478903.png",
-    fullName: "John Doe",
-    username: "johndoe",
-    rank: "203432",
+    fullName: "Dhruv Kotwani",
   },
   aboutData: {
-    github: { link: "https://github.com/druvkotwani", text: "druvkotwani" },
-    twitter: { link: "https://twitter.com/druv_kotwani", text: "druv_kotwani" },
+    github: {
+      link: "https://github.com/druvkotwani",
+      text: "Github",
+    },
+    website: {
+      link: "https://dhruvkotwani.vercel.app",
+      text: "Website",
+    },
     linkedin: {
       link: "https://linkedin.com/in/dhruv-kotwani",
-      text: "dhruv-kotwani",
+      text: "LinkedIn",
     },
-    website: {
-      link: "https://dhruvkotwani.me",
-      text: "dhruvkotwani.vercel.app",
+    twitter: {
+      link: "https://twitter.com/druv_kotwani",
+      text: "Twitter",
     },
   },
-
-  totalSolved: 100,
-  easySolved: 50,
-  easyTotal: 100,
-  mediumSolved: 30,
-  mediumTotal: 50,
-  hardSolved: 20,
-  hardTotal: 50,
+  total: 3247,
+  easyTotal: 817,
+  mediumTotal: 1704,
+  hardTotal: 726,
+  totalSolved: 306,
+  easySolved: 175,
+  mediumSolved: 110,
+  hardSolved: 21,
 };
 
 export default function Card({ userData = data, index }: any) {
diff --git a/client/src/app/components/GenerateStats.tsx b/client/src/app/components/GenerateStats.tsx
index 48af1af..14dc456 100644
--- a/client/src/app/components/GenerateStats.tsx
+++ b/client/src/app/components/GenerateStats.tsx
@@ -50,6 +50,12 @@ const GenerateStats = ({ showStats, setShowStats }: any) => {
         body: JSON.stringify(data),
       });
       const result = await response.json();
+
+      if (!result.success) {
+        toast("👻 Username already exists in LeetBoard");
+        return;
+      }
+
       if (result.success) {
         setDatas([...datas, data]);
         toast("🥷Data added to the hall of fame");
diff --git a/client/src/app/components/SocialLinks.tsx b/client/src/app/components/SocialLinks.tsx
index 53926ca..42da24e 100644
--- a/client/src/app/components/SocialLinks.tsx
+++ b/client/src/app/components/SocialLinks.tsx
@@ -4,25 +4,14 @@ import Image from "next/image";
 import Link from "next/link";
 import { useState } from "react";
 const SocialLinks = ({ result, index }: any) => {
-  const [hovered, setHovered] = useState<string | null>(null);
-  const random = Math.floor(Math.random() * 1);
-
-  function truncateText(text: any, maxLength: any) {
-    if (text && text.length > maxLength) {
-      return text.substring(0, maxLength) + "...";
-    }
-    return text;
-  }
   return (
-    <div className="mt-4 mb-2 flex flex-col justify-self-start">
+    <div className="mt-2 mb-2 grid grid-cols-2 gap-2">
       {/* <p className="flex">
-                <iconify-icon icon="carbon:location" width="17" height="19" style={{ color: 'white', marginRight: '5px' }}></iconify-icon>
+                <iconify-icon icon="carbon:location" width="21" height="23" style={{ color: 'white', marginRight: '5px' }}></iconify-icon>
                 <span className='text-sm text-[#BDBEC3] '>India</span>
             </p> */}
       {result?.website?.link && (
         <Link
-          onMouseEnter={() => setHovered("website")}
-          onMouseLeave={() => setHovered(null)}
           target="_blank"
           rel="noreferrer"
           href={result?.website?.link}
@@ -30,22 +19,15 @@ const SocialLinks = ({ result, index }: any) => {
         >
           <Image
             src="/assets/icons/globe.svg"
-            width={17}
-            height={19}
+            width={25}
+            height={23}
             alt="Website"
-            className="mr-1"
+            className="mr-1 hover:scale-125 ease-in transition-all transform duration-300 hover:rotate-180"
           />
-          <span className="text-sm text-[#BDBEC3] ">
-            <p className={`${hovered === "website" ? "text-[#f7f7f7]" : ""}`}>
-              {truncateText(result?.website?.text, 10)}
-            </p>
-          </span>
         </Link>
       )}
       {result?.github?.link && (
         <Link
-          onMouseEnter={() => setHovered("github")}
-          onMouseLeave={() => setHovered(null)}
           target="_blank"
           rel="noreferrer"
           href={result?.github?.link}
@@ -53,22 +35,15 @@ const SocialLinks = ({ result, index }: any) => {
         >
           <Image
             src="/assets/icons/github.svg"
-            width={17}
-            height={19}
+            width={21}
+            height={23}
             alt="Github"
-            className="mr-1"
+            className="mr-1 hover:scale-125 ease-in transition-all transform duration-300 "
           />
-          <span className="text-sm text-[#BDBEC3] ">
-            <p className={`${hovered === "github" ? "text-[#f7f7f7]" : ""}`}>
-              {truncateText(result?.github?.text, 10)}
-            </p>
-          </span>
         </Link>
       )}
       {result?.twitter?.link && (
         <Link
-          onMouseEnter={() => setHovered("twitter")}
-          onMouseLeave={() => setHovered(null)}
           target="_blank"
           rel="noreferrer"
           href={result?.twitter?.link}
@@ -77,21 +52,14 @@ const SocialLinks = ({ result, index }: any) => {
           <Image
             src="/assets/icons/twitter.svg"
             alt="twitter"
-            width={17}
-            height={19}
-            className="mr-1"
+            width={21}
+            height={23}
+            className="mr-1 hover:scale-125 ease-in transition-all transform duration-300 "
           />
-          <span className="text-sm text-[#BDBEC3] ">
-            <p className={`${hovered === "twitter" ? "text-[#f7f7f7]" : ""}`}>
-              {truncateText(result?.twitter?.text, 10)}
-            </p>
-          </span>
         </Link>
       )}
       {result?.linkedin?.link && (
         <Link
-          onMouseEnter={() => setHovered("linkedin")}
-          onMouseLeave={() => setHovered(null)}
           target="_blank"
           rel="noreferrer"
           href={result?.linkedin?.link}
@@ -100,15 +68,10 @@ const SocialLinks = ({ result, index }: any) => {
           <Image
             src="/assets/icons/linkedin.svg"
             alt="linkedin"
-            width={17}
-            height={19}
-            className="mr-1"
+            width={21}
+            height={23}
+            className="mr-1 hover:scale-125 ease-in transition-all transform duration-300 "
           />
-          <span className="text-sm text-[#BDBEC3] ">
-            <p className={`${hovered === "linkedin" ? "text-[#f7f7f7]" : ""}`}>
-              {truncateText(result?.linkedin?.text, 10)}
-            </p>
-          </span>
         </Link>
       )}
     </div>
diff --git a/client/src/app/page.tsx b/client/src/app/page.tsx
index 3d159ca..32000ba 100644
--- a/client/src/app/page.tsx
+++ b/client/src/app/page.tsx
@@ -5,7 +5,7 @@ import Navbar from "./components/Navbar";
 import Card from "./components/Card";
 import Footer from "./components/Footer";
 import GenerateStats from "./components/GenerateStats";
-import { useContext, useEffect, useState } from "react";
+import { use, useContext, useEffect, useState } from "react";
 import PromotionCard from "./components/PromotionCard";
 import { DataContext } from "./context/DataContext";
 import { ToastContainer } from "react-toastify";
@@ -17,6 +17,7 @@ export default function Home() {
   const [loading, setLoading] = useState(true);
   const [search, setSearch] = useState<string>("");
   const [showStats, setShowStats] = useState(false);
+  const [sortBy, setSortBy] = useState("default");
 
   const fetchData = async () => {
     try {
@@ -33,9 +34,32 @@ export default function Home() {
     fetchData();
   }, [datas && datas.length]);
 
+  useEffect(() => {
+    setTimeout(() => {
+      setShowStats(true);
+    }, 5000);
+  }, []);
+
+  const handleSortChange = (e: React.ChangeEvent<HTMLSelectElement>) => {
+    setSortBy(e.target.value);
+  };
+
   const searchedData = datas?.filter((data: any) =>
     data.profileData.fullName.toLowerCase().includes(search.toLowerCase())
   );
+  const sorting = (data: any[]) => {
+    switch (sortBy) {
+      case "question-solved":
+        return data.slice().sort((a, b) => b.totalSolved - a.totalSolved);
+      case "default":
+      default:
+        return data.slice().sort((a, b) => {
+          return (
+            new Date(b.timeStamp).getTime() - new Date(a.timeStamp).getTime()
+          );
+        });
+    }
+  };
 
   return (
     <section className="px-4 lg:px-24 relative ">
@@ -55,7 +79,18 @@ export default function Home() {
 
       <GenerateStats showStats={showStats} setShowStats={setShowStats} />
 
-      <div className="mt-32  max-w-7xl mx-auto  place-items-center grid grid-cols-1 md:grid-cols-2 gap-y-8 xl:grid-cols-3 font-sourcecodepro gap-x-4">
+      <div className="w-full flex items-center justify-center  ">
+        <select
+          value={sortBy}
+          onChange={handleSortChange}
+          className="mt-28 rounded border-2 border-[#f7f7f7]  w-64 bg-[#0e0e0e] text-white p-2 font-sourcecodepro"
+        >
+          <option value="default">Sort By Default</option>
+          <option value="question-solved">Sort By Questions Solved</option>
+        </select>
+      </div>
+
+      <div className="mt-8  max-w-7xl mx-auto  place-items-center grid grid-cols-1 md:grid-cols-2 gap-y-8 xl:grid-cols-3 font-sourcecodepro gap-x-4">
         <PromotionCard />
         {loading ? (
           <>
@@ -64,16 +99,9 @@ export default function Home() {
             ))}
           </>
         ) : (
-          searchedData &&
-          searchedData
-            .sort(
-              (a: any, b: any) =>
-                new Date(b.timeStamp).getTime() -
-                new Date(a.timeStamp).getTime()
-            )
-            .map((userData: any, index: number) => (
-              <Card userData={userData} index={index} key={index} />
-            ))
+          sorting(searchedData).map((userData: any, index: number) => (
+            <Card userData={userData} index={index} key={index} />
+          ))
         )}
       </div>
 

From 36608ace9b245a7dc091188bbada7739024184ed Mon Sep 17 00:00:00 2001
From: druvkotwani <druvkotwani12@gmail.com>
Date: Sun, 11 Aug 2024 21:10:41 +0530
Subject: [PATCH 03/23] favicon updated

---
 client/src/app/favicon.ico | Bin 25931 -> 3646 bytes
 1 file changed, 0 insertions(+), 0 deletions(-)

diff --git a/client/src/app/favicon.ico b/client/src/app/favicon.ico
index 718d6fea4835ec2d246af9800eddb7ffb276240c..baf682e2df029fc6d41ce80895a0c5c3149768f3 100644
GIT binary patch
literal 3646
zcmeHKOKVd>6u$ldU)2_D6{@0C5M7A)TquGY7oxax>rN2Gof`$$ZUj*`))$J3k0eE{
z#z-(}VnY|js$GcKXkufr#g^QbygtvDo3Zy^CfD3Z5yTVDow+A-zHiRV$()H{%#%+?
zry<Wyqica-v>ArcCE6jnOO$rXnfZpXdV{4^gFMiHeE0#J9RRjJ1lq3yZP$S1H-OzC
z;QSk4)NBBxfgxklz@@jqmIuI+s}>Krs7vL2nQ-ra3Z%X@0Om2IQ~`=*pdxL*V6DFk
zEbazcM9JG)<7|;W=Mo?F0Q2~YJY`WOQw8Ag3*gW*;OHyhKrgWBmK7UgB==TX<368!
zZXWWHYj^^fE?Mkm5qOfe_E4=Y+ik*^%&8fAw>lo3O`*INT;`0OZ|5W6z0Au?beKAu
z8zUinj7RZt|1L^C)e{}2&Q{N#`$RtG&Pv(G-p~4xI!v8S?>%cB{0^KO1bRk*g5<AT
zm}|tfOEWxn|9XAm+Nr#F%H=XjrIK%@AEjs`;&0X+qncwTlR+|>L_8k%t*KNBxm?bH
zT`wlnG!cnJ5C{Yi3<jH0`rG4RpRu_mpU)#44*wAs{q0=L6Z^TOI4d%NbUKY#EQV+_
z>RS_u1hUy|^=ws`Y^$-^4Yq!<SVW;v@U6@z3bF06a0$Kms!mNlblA$~7n0|5_b_m>
z4|thz{+1M$F4z6?ea!>M;#TckbVcf!oL3`Liox0H&JUf<>1DkQjROazp0Q4|ezIMA
z8=$?O=&*G*<<Iqa{sq_}HAJ29t-{kTcahU6V5U~<)OdHR!{*t-HJX(DP%<$CTz&_v
zyEDtfc-BZf7lr`yH#`c*otw0OoCHqw11DtPkBjc@vF1;FbqCmd9|*}A&-wZh9bZCf
z)F#1OD0}~F&1(Cz?=dhi=7+&KRyRH7^2U4CU5fXq6*sNBPP$IcIT8K8g+2j$<Q{q?
hYSqQO+;iqixW40(8@k#%SDgQG|Lqk}|HJ-P`x9t$#%TZm

literal 25931
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
LrJugUA?W`A8`#=m


From bf18d78fe6c3486ca87001c0dd575b47db1a65b8 Mon Sep 17 00:00:00 2001
From: druvkotwani <druvkotwani12@gmail.com>
Date: Sun, 11 Aug 2024 21:17:27 +0530
Subject: [PATCH 04/23] favicon updated

---
 client/src/app/favicon.ico | Bin 3646 -> 187116 bytes
 1 file changed, 0 insertions(+), 0 deletions(-)

diff --git a/client/src/app/favicon.ico b/client/src/app/favicon.ico
index baf682e2df029fc6d41ce80895a0c5c3149768f3..c4042f8bbc8988724946f94ce9405ecd92c5dcef 100644
GIT binary patch
literal 187116
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%0D6t8hGuWu_Y;*dEzImX|@Q;
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
D_GDsG

literal 3646
zcmeHKOKVd>6u$ldU)2_D6{@0C5M7A)TquGY7oxax>rN2Gof`$$ZUj*`))$J3k0eE{
z#z-(}VnY|js$GcKXkufr#g^QbygtvDo3Zy^CfD3Z5yTVDow+A-zHiRV$()H{%#%+?
zry<Wyqica-v>ArcCE6jnOO$rXnfZpXdV{4^gFMiHeE0#J9RRjJ1lq3yZP$S1H-OzC
z;QSk4)NBBxfgxklz@@jqmIuI+s}>Krs7vL2nQ-ra3Z%X@0Om2IQ~`=*pdxL*V6DFk
zEbazcM9JG)<7|;W=Mo?F0Q2~YJY`WOQw8Ag3*gW*;OHyhKrgWBmK7UgB==TX<368!
zZXWWHYj^^fE?Mkm5qOfe_E4=Y+ik*^%&8fAw>lo3O`*INT;`0OZ|5W6z0Au?beKAu
z8zUinj7RZt|1L^C)e{}2&Q{N#`$RtG&Pv(G-p~4xI!v8S?>%cB{0^KO1bRk*g5<AT
zm}|tfOEWxn|9XAm+Nr#F%H=XjrIK%@AEjs`;&0X+qncwTlR+|>L_8k%t*KNBxm?bH
zT`wlnG!cnJ5C{Yi3<jH0`rG4RpRu_mpU)#44*wAs{q0=L6Z^TOI4d%NbUKY#EQV+_
z>RS_u1hUy|^=ws`Y^$-^4Yq!<SVW;v@U6@z3bF06a0$Kms!mNlblA$~7n0|5_b_m>
z4|thz{+1M$F4z6?ea!>M;#TckbVcf!oL3`Liox0H&JUf<>1DkQjROazp0Q4|ezIMA
z8=$?O=&*G*<<Iqa{sq_}HAJ29t-{kTcahU6V5U~<)OdHR!{*t-HJX(DP%<$CTz&_v
zyEDtfc-BZf7lr`yH#`c*otw0OoCHqw11DtPkBjc@vF1;FbqCmd9|*}A&-wZh9bZCf
z)F#1OD0}~F&1(Cz?=dhi=7+&KRyRH7^2U4CU5fXq6*sNBPP$IcIT8K8g+2j$<Q{q?
hYSqQO+;iqixW40(8@k#%SDgQG|Lqk}|HJ-P`x9t$#%TZm


From e06a5f4139f59748e01cf6140bbd63c56e79cdd1 Mon Sep 17 00:00:00 2001
From: Dhruv Kotwani <96691139+druvkotwani@users.noreply.github.com>
Date: Sun, 11 Aug 2024 21:25:08 +0530
Subject: [PATCH 05/23] Update README.md

---
 README.md | 68 +++++--------------------------------------------------
 1 file changed, 6 insertions(+), 62 deletions(-)

diff --git a/README.md b/README.md
index 4074ca5..5782a6b 100644
--- a/README.md
+++ b/README.md
@@ -10,11 +10,11 @@ A platform to create your LeetCode statistics and showcase your LeetCode profile
 ## Languages/Tools
 
 <a href="">
-    <img src="https://skillicons.dev/icons?i=tailwindcss,js,react,firebase,nodejs,vercel" />
+    <img src="https://skillicons.dev/icons?i=tailwindcss,js,react,mongodb,nodejs,vercel,typescript" />
   </a>
 
 ## 👩🏽‍💻 Demo
-Check out the website: [𝙻𝚎𝚎𝚝𝙲𝚘𝚍𝚎 𝙿𝚛𝚘𝚏𝚒𝚕𝚎𝚜](https://leetcode-profiles.vercel.app/)
+Check out the website: [𝙻𝚎𝚎𝚝𝙲𝚘𝚍𝚎 𝙿𝚛𝚘𝚏𝚒𝚕𝚎𝚜](https://leetcode-profiles-delta.vercel.app/)
 
 
 ## 🛠️ Installation Steps
@@ -27,80 +27,24 @@ Check out the website: [𝙻𝚎𝚎𝚝𝙲𝚘𝚍𝚎 𝙿𝚛𝚘𝚏𝚒
 - Enter the name of your new branch in the text box. (Branch names usually make a reference to what is being changed. Example: `FixMargin`).
 - Click on `Create branch <new branch name>` and this will automatically take you to your new branch. You can make edits on the main branch, but this may cause issues down the line. Best practice is to create a new branch for each separate issue you work on. That way, your `main` branch remains in sync with `leetcode-profiles` `main` branch.
 
-### 3. Setup Firebase:
-- Below are the steps to setup firebase.
-
-### 4. Edit:
+### 3. Edit:
 - Do the desired changes, you want.
 
-### 5. Raise a Pull Request:
+### 4. Raise a Pull Request:
 - And finally, create a [Pull Request](https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/creating-a-pull-request)!
 - Great job! 
 
 
-## Setting up Firebase 
-
-1. **Firebase Account Setup:**
-   - Sign up for a free Firebase account at [Firebase Console](https://console.firebase.google.com/).
-
-2. **Create a Firebase Project:**
-   - Create a new Firebase project via the Firebase Console.
-
-3. **Add Firebase to your web app:**
-   - Set up the firebase for your webapp and then Add Firebase SDK.
-
-4. **Create Database(firestore Database)**
-
-5. **Create a collection with the file format below (not necessary):**
-
-  
-   ### 👇🏽 File Format
-- `userName(String) = druv_kotwani`
-- `website(Map) = {link: https://dhruvkotwani.me/, text: dhruvkotwani.me}`
-- `badgeImg(String) = https://leetcode.com/static/images/badges/dcc-2023-10.png`
-- `mediumBeats(String) = 85.6%`
-- `easyBeats(String) = 96.9%`
-- `totalQuestions(Number) = 2940`
-- `fullName(String) = Dhruv Kotwani`
-- `github(Map) = {link: https://github.com/druvkotwani, text: druvkotwani}`
-- `image(String) = https://assets.leetcode.com/users/avatars/avatar_1672478903.png`
-- `hardBeats(String) = 77.62`
-- `totalSolved(Number) = 282`
-- `easySolved(String) = 165`
-- `linkedin(Map) = {link: https://linkedin.com/in/dhruv-kotwani, text: dhruv-kotwani}`
-- `rank(String) = 230,203`
-- `easyTotal(String) = 746`
-- `mediumSolved(String) = 97`
-- `hardTotal(String) = 645`
-- `hardSolved(String) = 20`
-- `twitter(Map) = {link: https://twitter.com/druv_kotwani, text: druv_kotwani}`
-- `mediumTotal(String) = 1549`
-
-6. **Replace the firebaseConfig inside firebase.js with your actual apiKeys, and rest of the data**
-7. **Add now you are good to go**
-
 ## 🚀 Running Frontend
 To run locally, just `cd` into the `client` and run the following commands to run node modules and serve the website locally.
 ```bash
-npm i
+yarn install 
 ```
 
 ```bash
-npm run dev
+yarn run dev
 ```
 
-## 🚀 Running Backend(only necessary if you had made changes in the api)
-To run locally, just `cd` into the `server` and run the following commands to run node modules and serve the website locally.
-```bash
-npm i
-```
-
-```bash
-node index.js
-```
-
-
-
 
 <hr/>
 

From fa02d80563b9a1f8a679d862972f889aef75b28b Mon Sep 17 00:00:00 2001
From: druvkotwani <druvkotwani12@gmail.com>
Date: Tue, 27 Aug 2024 11:01:04 +0530
Subject: [PATCH 06/23] feat: Added vercel analytics

---
 client/package.json       |  1 +
 client/src/app/layout.tsx |  2 ++
 client/yarn.lock          | 12 ++++++++++++
 3 files changed, 15 insertions(+)

diff --git a/client/package.json b/client/package.json
index 3cc214e..de05c21 100644
--- a/client/package.json
+++ b/client/package.json
@@ -9,6 +9,7 @@
     "lint": "next lint"
   },
   "dependencies": {
+    "@vercel/analytics": "^1.3.1",
     "axios": "^1.7.3",
     "mongoose": "^8.5.2",
     "next": "14.2.5",
diff --git a/client/src/app/layout.tsx b/client/src/app/layout.tsx
index ddd24ee..0ea16e1 100644
--- a/client/src/app/layout.tsx
+++ b/client/src/app/layout.tsx
@@ -2,6 +2,7 @@ import type { Metadata } from "next";
 import { Inter, Source_Code_Pro } from "next/font/google";
 import "./globals.css";
 import { DataProvider } from "./context/DataContext";
+import { Analytics } from "@vercel/analytics/react";
 
 const sourcecodepro = Source_Code_Pro({
   subsets: ["latin"],
@@ -22,6 +23,7 @@ export default function RootLayout({
     <html lang="en">
       <body className={sourcecodepro.variable}>
         <DataProvider>{children}</DataProvider>
+        <Analytics />
       </body>
     </html>
   );
diff --git a/client/yarn.lock b/client/yarn.lock
index f47bb94..abc16ae 100644
--- a/client/yarn.lock
+++ b/client/yarn.lock
@@ -305,6 +305,13 @@
   resolved "https://registry.yarnpkg.com/@ungap/structured-clone/-/structured-clone-1.2.0.tgz#756641adb587851b5ccb3e095daf27ae581c8406"
   integrity sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==
 
+"@vercel/analytics@^1.3.1":
+  version "1.3.1"
+  resolved "https://registry.yarnpkg.com/@vercel/analytics/-/analytics-1.3.1.tgz#e2b1deac1b5d14fa2e4fe36186ac5054c6385ae4"
+  integrity sha512-xhSlYgAuJ6Q4WQGkzYTLmXwhYl39sWjoMA3nHxfkvG+WdBT25c563a7QhwwKivEOZtPJXifYHR1m2ihoisbWyA==
+  dependencies:
+    server-only "^0.0.1"
+
 acorn-jsx@^5.3.2:
   version "5.3.2"
   resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937"
@@ -2410,6 +2417,11 @@ semver@^7.5.4:
   resolved "https://registry.yarnpkg.com/semver/-/semver-7.6.3.tgz#980f7b5550bc175fb4dc09403085627f9eb33143"
   integrity sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==
 
+server-only@^0.0.1:
+  version "0.0.1"
+  resolved "https://registry.yarnpkg.com/server-only/-/server-only-0.0.1.tgz#0f366bb6afb618c37c9255a314535dc412cd1c9e"
+  integrity sha512-qepMx2JxAa5jjfzxG79yPPq+8BuFToHd1hm7kI+Z4zAq1ftQiP7HcxMhDDItrbtwVeLg/cY2JnKnrcFkmiswNA==
+
 set-function-length@^1.2.1:
   version "1.2.2"
   resolved "https://registry.yarnpkg.com/set-function-length/-/set-function-length-1.2.2.tgz#aac72314198eaed975cf77b2c3b6b880695e5449"

From 3c27c273643723c824afcacec6d4c3b0453bb587 Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Tue, 27 Aug 2024 05:31:44 +0000
Subject: [PATCH 07/23] Bump micromatch from 4.0.7 to 4.0.8 in /client

Bumps [micromatch](https://github.com/micromatch/micromatch) from 4.0.7 to 4.0.8.
- [Release notes](https://github.com/micromatch/micromatch/releases)
- [Changelog](https://github.com/micromatch/micromatch/blob/master/CHANGELOG.md)
- [Commits](https://github.com/micromatch/micromatch/compare/4.0.7...4.0.8)

---
updated-dependencies:
- dependency-name: micromatch
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
---
 client/yarn.lock | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/client/yarn.lock b/client/yarn.lock
index abc16ae..5ae2a84 100644
--- a/client/yarn.lock
+++ b/client/yarn.lock
@@ -1852,9 +1852,9 @@ merge2@^1.3.0, merge2@^1.4.1:
   integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==
 
 micromatch@^4.0.4, micromatch@^4.0.5:
-  version "4.0.7"
-  resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.7.tgz#33e8190d9fe474a9895525f5618eee136d46c2e5"
-  integrity sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==
+  version "4.0.8"
+  resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.8.tgz#d66fa18f3a47076789320b9b1af32bd86d9fa202"
+  integrity sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==
   dependencies:
     braces "^3.0.3"
     picomatch "^2.3.1"

From 3665625149a0e783bfe2ceef50804dee5772ff33 Mon Sep 17 00:00:00 2001
From: druvkotwani <druvkotwani12@gmail.com>
Date: Tue, 27 Aug 2024 11:02:24 +0530
Subject: [PATCH 08/23] feat: Added Speed insights

---
 client/package.json       | 1 +
 client/src/app/layout.tsx | 2 ++
 client/yarn.lock          | 5 +++++
 3 files changed, 8 insertions(+)

diff --git a/client/package.json b/client/package.json
index de05c21..fbc2d72 100644
--- a/client/package.json
+++ b/client/package.json
@@ -10,6 +10,7 @@
   },
   "dependencies": {
     "@vercel/analytics": "^1.3.1",
+    "@vercel/speed-insights": "^1.0.12",
     "axios": "^1.7.3",
     "mongoose": "^8.5.2",
     "next": "14.2.5",
diff --git a/client/src/app/layout.tsx b/client/src/app/layout.tsx
index 0ea16e1..79e5542 100644
--- a/client/src/app/layout.tsx
+++ b/client/src/app/layout.tsx
@@ -3,6 +3,7 @@ import { Inter, Source_Code_Pro } from "next/font/google";
 import "./globals.css";
 import { DataProvider } from "./context/DataContext";
 import { Analytics } from "@vercel/analytics/react";
+import { SpeedInsights } from "@vercel/speed-insights/next";
 
 const sourcecodepro = Source_Code_Pro({
   subsets: ["latin"],
@@ -24,6 +25,7 @@ export default function RootLayout({
       <body className={sourcecodepro.variable}>
         <DataProvider>{children}</DataProvider>
         <Analytics />
+        <SpeedInsights />
       </body>
     </html>
   );
diff --git a/client/yarn.lock b/client/yarn.lock
index abc16ae..653e795 100644
--- a/client/yarn.lock
+++ b/client/yarn.lock
@@ -312,6 +312,11 @@
   dependencies:
     server-only "^0.0.1"
 
+"@vercel/speed-insights@^1.0.12":
+  version "1.0.12"
+  resolved "https://registry.yarnpkg.com/@vercel/speed-insights/-/speed-insights-1.0.12.tgz#71c2edffdedae98d34e306d7b0a573e6816898b4"
+  integrity sha512-ZGQ+a7bcfWJD2VYEp2R1LHvRAMyyaFBYytZXsfnbOMkeOvzGNVxUL7aVUvisIrTZjXTSsxG45DKX7yiw6nq2Jw==
+
 acorn-jsx@^5.3.2:
   version "5.3.2"
   resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937"

From 910723e25a1a87290dd83fd65f2eaae2166545c4 Mon Sep 17 00:00:00 2001
From: druvkotwani <druvkotwani12@gmail.com>
Date: Sun, 8 Sep 2024 20:00:35 +0530
Subject: [PATCH 09/23] feat: Add dependencies for react-calendar-heatmap and
 react-tooltip

---
 client/package.json                    |  5 ++-
 client/public/assets/icons/loading.svg |  6 +++
 client/public/assets/icons/money.svg   | 10 +++++
 client/public/assets/icons/money2.svg  |  6 +++
 client/yarn.lock                       | 55 +++++++++++++++++++++++++-
 5 files changed, 80 insertions(+), 2 deletions(-)
 create mode 100644 client/public/assets/icons/loading.svg
 create mode 100644 client/public/assets/icons/money.svg
 create mode 100644 client/public/assets/icons/money2.svg

diff --git a/client/package.json b/client/package.json
index fbc2d72..75bd137 100644
--- a/client/package.json
+++ b/client/package.json
@@ -9,14 +9,17 @@
     "lint": "next lint"
   },
   "dependencies": {
+    "@types/react-calendar-heatmap": "^1.6.7",
     "@vercel/analytics": "^1.3.1",
     "@vercel/speed-insights": "^1.0.12",
     "axios": "^1.7.3",
     "mongoose": "^8.5.2",
     "next": "14.2.5",
     "react": "^18",
+    "react-calendar-heatmap": "^1.9.0",
     "react-dom": "^18",
-    "react-toastify": "^10.0.5"
+    "react-toastify": "^10.0.5",
+    "react-tooltip": "^5.28.0"
   },
   "devDependencies": {
     "@types/node": "^20",
diff --git a/client/public/assets/icons/loading.svg b/client/public/assets/icons/loading.svg
new file mode 100644
index 0000000..02e78c4
--- /dev/null
+++ b/client/public/assets/icons/loading.svg
@@ -0,0 +1,6 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
+	<path fill="none" stroke="#999999" stroke-dasharray="16" stroke-dashoffset="16" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 3c4.97 0 9 4.03 9 9">
+		<animate fill="freeze" attributeName="stroke-dashoffset" dur="0.2s" values="16;0" />
+		<animateTransform attributeName="transform" dur="1.5s" repeatCount="indefinite" type="rotate" values="0 12 12;360 12 12" />
+	</path>
+</svg>
\ No newline at end of file
diff --git a/client/public/assets/icons/money.svg b/client/public/assets/icons/money.svg
new file mode 100644
index 0000000..1046586
--- /dev/null
+++ b/client/public/assets/icons/money.svg
@@ -0,0 +1,10 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 128 128">
+	<path fill="#ffca28" d="M93.46 39.45c6.71-1.49 15.45-8.15 16.78-11.43c.78-1.92-3.11-4.92-4.15-6.13c-2.38-2.76-1.42-4.12-.5-7.41c1.05-3.74-1.44-7.87-4.97-9.49s-7.75-1.11-11.3.47s-6.58 4.12-9.55 6.62c-2.17-1.37-5.63-7.42-11.23-3.49c-3.87 2.71-4.22 8.61-3.72 13.32c1.17 10.87 3.85 16.51 8.9 18.03c6.38 1.92 13.44.91 19.74-.49" />
+	<path fill="#e2a610" d="M104.36 8.18c-.85 14.65-15.14 24.37-21.92 28.65l4.4 3.78s2.79.06 6.61-1.16c6.55-2.08 16.12-7.96 16.78-11.43c.97-5.05-4.21-3.95-5.38-7.94c-.61-2.11 2.97-6.1-.49-11.9m-24.58 3.91s-2.55-2.61-4.44-3.8c-.94 1.77-1.61 3.69-1.94 5.67c-.59 3.48 0 8.42 1.39 12.1c.22.57 1.04.48 1.13-.12c1.2-7.91 3.86-13.85 3.86-13.85" />
+	<path fill="#ffca28" d="M61.96 38.16S30.77 41.53 16.7 68.61s-2.11 43.5 10.55 49.48s44.56 8.09 65.31 3.17s25.94-15.12 24.97-24.97c-1.41-14.38-14.77-23.22-14.77-23.22s.53-17.76-13.25-29.29c-12.23-10.24-27.55-5.62-27.55-5.62" />
+	<path fill="#6b4b46" d="M74.76 83.73c-6.69-8.44-14.59-9.57-17.12-12.6c-1.38-1.65-2.19-3.32-1.88-5.39c.33-2.2 2.88-3.72 4.86-4.09c2.31-.44 7.82-.21 12.45 4.2c1.1 1.04.7 2.66.67 4.11c-.08 3.11 4.37 6.13 7.97 3.53c3.61-2.61.84-8.42-1.49-11.24c-1.76-2.13-8.14-6.82-16.07-7.56c-2.23-.21-11.2-1.54-16.38 8.31c-1.49 2.83-2.04 9.67 5.76 15.45c1.63 1.21 10.09 5.51 12.44 8.3c4.07 4.83 1.28 9.08-1.9 9.64c-8.67 1.52-13.58-3.17-14.49-5.74c-.65-1.83.03-3.81-.81-5.53c-.86-1.77-2.62-2.47-4.48-1.88c-6.1 1.94-4.16 8.61-1.46 12.28c2.89 3.93 6.44 6.3 10.43 7.6c14.89 4.85 22.05-2.81 23.3-8.42c.92-4.11.82-7.67-1.8-10.97" />
+	<path fill="none" stroke="#6b4b46" stroke-miterlimit="10" stroke-width="5" d="M71.16 48.99c-12.67 27.06-14.85 61.23-14.85 61.23" />
+	<path fill="#6d4c41" d="M81.67 31.96c8.44 2.75 10.31 10.38 9.7 12.46c-.73 2.44-10.08-7.06-23.98-6.49c-4.86.2-3.45-2.78-1.2-4.5c2.97-2.27 7.96-3.91 15.48-1.47" />
+	<path fill="#6b4b46" d="M81.67 31.96c8.44 2.75 10.31 10.38 9.7 12.46c-.73 2.44-10.08-7.06-23.98-6.49c-4.86.2-3.45-2.78-1.2-4.5c2.97-2.27 7.96-3.91 15.48-1.47" />
+	<path fill="#e2a610" d="M96.49 58.86c1.06-.73 4.62.53 5.62 7.5c.49 3.41.64 6.71.64 6.71s-4.2-3.77-5.59-6.42c-1.75-3.35-2.43-6.59-.67-7.79" />
+</svg>
\ No newline at end of file
diff --git a/client/public/assets/icons/money2.svg b/client/public/assets/icons/money2.svg
new file mode 100644
index 0000000..8d454b3
--- /dev/null
+++ b/client/public/assets/icons/money2.svg
@@ -0,0 +1,6 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 32 32">
+	<g fill="#999999">
+		<path d="M15.84 19.345h.07c1.5.04 2.7 1.26 2.7 2.76c0 1.28-.87 2.35-2.05 2.67v1.12c0 .4-.32.72-.72.72s-.72-.32-.72-.72v-1.12a2.77 2.77 0 0 1-2.05-2.67c0-.4.32-.72.72-.72s.72.32.72.72c0 .74.59 1.33 1.32 1.33s1.33-.6 1.33-1.33s-.6-1.33-1.33-1.33h-.07a2.765 2.765 0 0 1-2.69-2.76c0-1.28.87-2.35 2.05-2.67v-1.12c0-.4.32-.72.72-.72s.72.32.72.72v1.12c1.18.32 2.05 1.39 2.05 2.67c0 .4-.32.72-.72.72s-.72-.32-.72-.72c0-.73-.6-1.33-1.33-1.33s-1.33.6-1.33 1.33s.6 1.33 1.33 1.33" />
+		<path d="m10.532 5.1l2.786 3.26l-.301.336C7.283 9.982 3 15.103 3 21.225c0 5.382 4.368 9.75 9.75 9.75h6.17c5.382 0 9.75-4.367 9.75-9.749c.01-6.123-4.273-11.244-10.007-12.53a1.1 1.1 0 0 0-.11-.615l2.37-2.713l.153-.236a1.956 1.956 0 0 0-2.892-2.423l-.843-1a2.02 2.02 0 0 0-3.008-.005l-.883.986a1.96 1.96 0 0 0-2.918 2.41m3.799 1.385l-1.696-1.96a1.98 1.98 0 0 0 2.365-.5l.8-1.038l.888 1.052a1.97 1.97 0 0 0 2.3.513L17.3 6.485zM5 21.225c0-5.988 4.852-10.84 10.84-10.84s10.84 4.852 10.83 10.838v.002a7.753 7.753 0 0 1-7.75 7.75h-6.17A7.753 7.753 0 0 1 5 21.225" />
+	</g>
+</svg>
\ No newline at end of file
diff --git a/client/yarn.lock b/client/yarn.lock
index 653e795..25fd1e6 100644
--- a/client/yarn.lock
+++ b/client/yarn.lock
@@ -39,6 +39,26 @@
   resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.57.0.tgz#a5417ae8427873f1dd08b70b3574b453e67b5f7f"
   integrity sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==
 
+"@floating-ui/core@^1.6.0":
+  version "1.6.7"
+  resolved "https://registry.yarnpkg.com/@floating-ui/core/-/core-1.6.7.tgz#7602367795a390ff0662efd1c7ae8ca74e75fb12"
+  integrity sha512-yDzVT/Lm101nQ5TCVeK65LtdN7Tj4Qpr9RTXJ2vPFLqtLxwOrpoxAHAJI8J3yYWUc40J0BDBheaitK5SJmno2g==
+  dependencies:
+    "@floating-ui/utils" "^0.2.7"
+
+"@floating-ui/dom@^1.6.1":
+  version "1.6.10"
+  resolved "https://registry.yarnpkg.com/@floating-ui/dom/-/dom-1.6.10.tgz#b74c32f34a50336c86dcf1f1c845cf3a39e26d6f"
+  integrity sha512-fskgCFv8J8OamCmyun8MfjB1Olfn+uZKjOKZ0vhYF3gRmEUXcGOjxWL8bBr7i4kIuPZ2KD2S3EUIOxnjC8kl2A==
+  dependencies:
+    "@floating-ui/core" "^1.6.0"
+    "@floating-ui/utils" "^0.2.7"
+
+"@floating-ui/utils@^0.2.7":
+  version "0.2.7"
+  resolved "https://registry.yarnpkg.com/@floating-ui/utils/-/utils-0.2.7.tgz#d0ece53ce99ab5a8e37ebdfe5e32452a2bfc073e"
+  integrity sha512-X8R8Oj771YRl/w+c1HqAC1szL8zWQRwFvgDwT129k9ACdBoud/+/rX9V0qiMl6LWUdP9voC2nDVZYPMQQsb6eA==
+
 "@humanwhocodes/config-array@^0.11.14":
   version "0.11.14"
   resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.11.14.tgz#d78e481a039f7566ecc9660b4ea7fe6b1fec442b"
@@ -227,6 +247,13 @@
   resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.12.tgz#12bb1e2be27293c1406acb6af1c3f3a1481d98c6"
   integrity sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q==
 
+"@types/react-calendar-heatmap@^1.6.7":
+  version "1.6.7"
+  resolved "https://registry.yarnpkg.com/@types/react-calendar-heatmap/-/react-calendar-heatmap-1.6.7.tgz#dec75660db7abb9b87a9ce9688221623e849d97b"
+  integrity sha512-xWBS9iOvw+aCidPk8QwCH69OCO7jnj6/9TjooqGQ9W+rA5m1aw36GjQMlSYKAg86otDeg9dzA+hSAIcvw/y9Rg==
+  dependencies:
+    "@types/react" "*"
+
 "@types/react-dom@^18":
   version "18.3.0"
   resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-18.3.0.tgz#0cbc818755d87066ab6ca74fbedb2547d74a82b0"
@@ -614,6 +641,11 @@ chokidar@^3.5.3:
   optionalDependencies:
     fsevents "~2.3.2"
 
+classnames@^2.3.0:
+  version "2.5.1"
+  resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.5.1.tgz#ba774c614be0f016da105c858e7159eae8e7687b"
+  integrity sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow==
+
 client-only@0.0.1:
   version "0.0.1"
   resolved "https://registry.yarnpkg.com/client-only/-/client-only-0.0.1.tgz#38bba5d403c41ab150bff64a95c85013cf73bca1"
@@ -1846,6 +1878,11 @@ lru-cache@^10.2.0:
   resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-10.4.3.tgz#410fc8a17b70e598013df257c2446b7f3383f119"
   integrity sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==
 
+memoize-one@^5.0.0:
+  version "5.2.1"
+  resolved "https://registry.yarnpkg.com/memoize-one/-/memoize-one-5.2.1.tgz#8337aa3c4335581839ec01c3d594090cebe8f00e"
+  integrity sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q==
+
 memory-pager@^1.0.2:
   version "1.5.0"
   resolved "https://registry.yarnpkg.com/memory-pager/-/memory-pager-1.5.0.tgz#d8751655d22d384682741c972f2c3d6dfa3e66b5"
@@ -2251,7 +2288,7 @@ prelude-ls@^1.2.1:
   resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396"
   integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==
 
-prop-types@^15.8.1:
+prop-types@^15.6.2, prop-types@^15.8.1:
   version "15.8.1"
   resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5"
   integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==
@@ -2275,6 +2312,14 @@ queue-microtask@^1.2.2:
   resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243"
   integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==
 
+react-calendar-heatmap@^1.9.0:
+  version "1.9.0"
+  resolved "https://registry.yarnpkg.com/react-calendar-heatmap/-/react-calendar-heatmap-1.9.0.tgz#b691310a150d9c52e4ede21ebaa79734fc170d18"
+  integrity sha512-mGed9any6QLOVckxwxC/eeP9s9wE8mTUW/FCE0V27xF9WOaCGuOftGSRH8DSDoSwgzMSVF6uuH7M1xvc+aZ8sg==
+  dependencies:
+    memoize-one "^5.0.0"
+    prop-types "^15.6.2"
+
 react-dom@^18:
   version "18.3.1"
   resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-18.3.1.tgz#c2265d79511b57d479b3dd3fdfa51536494c5cb4"
@@ -2295,6 +2340,14 @@ react-toastify@^10.0.5:
   dependencies:
     clsx "^2.1.0"
 
+react-tooltip@^5.28.0:
+  version "5.28.0"
+  resolved "https://registry.yarnpkg.com/react-tooltip/-/react-tooltip-5.28.0.tgz#c7b5343ab2d740a428494a3d8315515af1f26f46"
+  integrity sha512-R5cO3JPPXk6FRbBHMO0rI9nkUG/JKfalBSQfZedZYzmqaZQgq7GLzF8vcCWx6IhUCKg0yPqJhXIzmIO5ff15xg==
+  dependencies:
+    "@floating-ui/dom" "^1.6.1"
+    classnames "^2.3.0"
+
 react@^18:
   version "18.3.1"
   resolved "https://registry.yarnpkg.com/react/-/react-18.3.1.tgz#49ab892009c53933625bd16b2533fc754cab2891"

From c3342528aaf7ab2748544b7176e542c66f63f1db Mon Sep 17 00:00:00 2001
From: druvkotwani <druvkotwani12@gmail.com>
Date: Sun, 8 Sep 2024 20:01:11 +0530
Subject: [PATCH 10/23] Refactor Circle component class name + Added submission
 calendar into the api

---
 client/src/app/components/Circle.tsx |  2 +-
 client/src/pages/api/[username].ts   | 35 ++++++++++++++++++++++++++++
 2 files changed, 36 insertions(+), 1 deletion(-)

diff --git a/client/src/app/components/Circle.tsx b/client/src/app/components/Circle.tsx
index edc8eda..0700c54 100644
--- a/client/src/app/components/Circle.tsx
+++ b/client/src/app/components/Circle.tsx
@@ -29,7 +29,7 @@ const Circle = ({ total }: any) => {
               strokeWidth="5"
               strokeLinecap="round"
               stroke="#FFC11F"
-              className="cursor-pointer "
+              className=""
               strokeDasharray={`${dashLength} ${circumference}`}
               strokeDashoffset="0"
               data-difficulty="ALL"
diff --git a/client/src/pages/api/[username].ts b/client/src/pages/api/[username].ts
index e11d884..e21100d 100644
--- a/client/src/pages/api/[username].ts
+++ b/client/src/pages/api/[username].ts
@@ -91,18 +91,46 @@ export default async function handler(req: any, res: any) {
       username: username,
     },
   };
+  const payload3 = {
+    operationName: "userProfileCalendar",
+    query: `
+      query userProfileCalendar($username: String!, $year: Int) {
+        matchedUser(username: $username) {
+          userCalendar(year: $year) {
+            activeYears
+            streak
+            totalActiveDays
+            dccBadges {
+              timestamp
+              badge {
+                name
+                icon
+              }
+            }
+            submissionCalendar
+          }
+        }
+      }
+    `,
+    variables: {
+      username: username,
+    },
+  };
 
   try {
     const response1 = await axios.post(url, payload1, { headers });
     const response2 = await axios.post(url, payload2, { headers });
+    const response3 = await axios.post(url, payload3, { headers });
 
     const data1 = response1.data;
     const data2 = response2.data;
+    const data3 = response3.data;
 
     // Merge the data from both responses
     const combinedData = {
       userSessionProgress: data1.data,
       userPublicProfile: data2.data,
+      userProfileCalendar: data3.data,
     };
 
     const total = combinedData.userSessionProgress.allQuestionsCount[0].count;
@@ -151,6 +179,10 @@ export default async function handler(req: any, res: any) {
       },
     };
 
+    const calendarData = combinedData.userProfileCalendar.matchedUser;
+    const activeYears = calendarData.userCalendar.activeYears;
+    const submissionCalendar = calendarData.userCalendar.submissionCalendar;
+
     res.status(200).json({
       profileData,
       aboutData,
@@ -162,6 +194,9 @@ export default async function handler(req: any, res: any) {
       easySolved,
       mediumSolved,
       hardSolved,
+      calendarData,
+      activeYears,
+      submissionCalendar,
     });
   } catch (error) {
     console.error(error);

From 3dce7102b388fa6834efd3a6c3697df7eaf74c79 Mon Sep 17 00:00:00 2001
From: druvkotwani <druvkotwani12@gmail.com>
Date: Sun, 8 Sep 2024 20:01:26 +0530
Subject: [PATCH 11/23] css for heatmap

---
 client/src/app/globals.css | 49 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 49 insertions(+)

diff --git a/client/src/app/globals.css b/client/src/app/globals.css
index c28c3b3..1ce297c 100644
--- a/client/src/app/globals.css
+++ b/client/src/app/globals.css
@@ -137,3 +137,52 @@ body {
   left: 50px;
   top: 9px;
 }
+
+/* Leetcode Heatmap styles */
+.react-calendar-heatmap text {
+  font-size: 10px;
+  fill: #aaa;
+}
+
+.react-calendar-heatmap .react-calendar-heatmap-small-text {
+  font-size: 5px;
+}
+
+.react-calendar-heatmap rect:hover {
+  stroke: #555;
+  stroke-width: 1px;
+}
+.react-calendar-heatmap .color-empty {
+  fill: #393939;
+}
+.react-calendar-heatmap rect {
+  rx: 2px;
+  ry: 2px;
+}
+.react-calendar-heatmap .month-label {
+  fill: #9ca3af;
+}
+
+.react-calendar-heatmap .color-filled {
+  fill: #8cc665;
+}
+
+/*
+ * Github color scale
+ */
+
+.react-calendar-heatmap .color-github-0 {
+  fill: #eeeeee;
+}
+.react-calendar-heatmap .color-github-1 {
+  fill: #d6e685;
+}
+.react-calendar-heatmap .color-github-2 {
+  fill: #8cc665;
+}
+.react-calendar-heatmap .color-github-3 {
+  fill: #44a340;
+}
+.react-calendar-heatmap .color-github-4 {
+  fill: #1e6823;
+}

From f2eae8ece734ade1a21d2be1942af169aec03f24 Mon Sep 17 00:00:00 2001
From: druvkotwani <druvkotwani12@gmail.com>
Date: Sun, 8 Sep 2024 20:02:10 +0530
Subject: [PATCH 12/23] some improvements in Navbar + Data Context

---
 client/src/app/components/Navbar.tsx   | 59 +++++++++++++++-----------
 client/src/app/context/DataContext.tsx |  5 +++
 client/src/app/worth/page.tsx          | 15 +++++++
 3 files changed, 55 insertions(+), 24 deletions(-)
 create mode 100644 client/src/app/worth/page.tsx

diff --git a/client/src/app/components/Navbar.tsx b/client/src/app/components/Navbar.tsx
index 672831f..17c0eef 100644
--- a/client/src/app/components/Navbar.tsx
+++ b/client/src/app/components/Navbar.tsx
@@ -4,16 +4,25 @@ import Image from "next/image";
 import Link from "next/link";
 import React, { useState } from "react";
 
-type NavbarProps = {
-  search: string;
-  setSearch: React.Dispatch<React.SetStateAction<string>>;
-};
+interface NavbarProps {
+  search?: string;
+  setSearch?: (search: string) => void;
+  searchBarPresent?: boolean;
+}
 
-const Navbar: React.FC<NavbarProps> = ({ search, setSearch }) => {
+const Navbar: React.FC<NavbarProps> = ({
+  search,
+  setSearch,
+  searchBarPresent,
+}) => {
   const [hoveredItem, setHoveredItem] = useState<string | null>(null);
 
   return (
-    <nav className="bg-[#0e0e0e] z-10 border-b border-b-white fixed top-0 left-0 w-full md:px-8 px-4  py-4 flex justify-around items-center">
+    <nav
+      className={`bg-[#0e0e0e] z-10 border-b border-b-white fixed top-0 left-0 w-full md:px-8 px-4  py-4 flex ${
+        searchBarPresent ? "justify-around" : "justify-between !px-24"
+      } items-center`}
+    >
       {/* Logo */}
       <Link href="/">
         <Image
@@ -25,24 +34,26 @@ const Navbar: React.FC<NavbarProps> = ({ search, setSearch }) => {
       </Link>
 
       {/* Search */}
-      <form className="">
-        <div className="relative flex ">
-          <input
-            value={search}
-            onChange={(e) => setSearch(e.target.value)}
-            type="text"
-            placeholder="Search by username"
-            className="bg-[#1f1f1f] sm:w-[260px] w-[100px] font-sourcecodepro text-white rounded px-4 py-3  focus:outline-none pl-10"
-          />
-          <Image
-            src="/assets/icons/search.svg"
-            alt="Search Icon"
-            width={20}
-            height={20}
-            className="absolute left-2 -translate-y-1/2 top-1/2 "
-          />
-        </div>
-      </form>
+      {searchBarPresent && (
+        <form className="">
+          <div className="relative flex ">
+            <input
+              value={search}
+              onChange={(e) => setSearch && setSearch(e.target.value)}
+              type="text"
+              placeholder="Search by username"
+              className="bg-[#1f1f1f] sm:w-[260px] w-[100px] font-sourcecodepro text-white rounded px-4 py-3  focus:outline-none pl-10"
+            />
+            <Image
+              src="/assets/icons/search.svg"
+              alt="Search Icon"
+              width={20}
+              height={20}
+              className="absolute left-2 -translate-y-1/2 top-1/2 "
+            />
+          </div>
+        </form>
+      )}
 
       {/* Profile */}
 
diff --git a/client/src/app/context/DataContext.tsx b/client/src/app/context/DataContext.tsx
index 82d359c..86847d0 100644
--- a/client/src/app/context/DataContext.tsx
+++ b/client/src/app/context/DataContext.tsx
@@ -5,15 +5,20 @@ import { createContext, useState } from "react";
 export const DataContext = createContext({
   datas: [],
   setDatas: (datas: any) => {},
+  search: "",
+  setSearch: (search: string) => {},
 });
 
 export const DataProvider = ({ children }: any) => {
   const [datas, setDatas] = useState<any>();
+  const [search, setSearch] = useState<string>("");
   return (
     <DataContext.Provider
       value={{
         datas,
         setDatas,
+        search,
+        setSearch,
       }}
     >
       {children}
diff --git a/client/src/app/worth/page.tsx b/client/src/app/worth/page.tsx
new file mode 100644
index 0000000..625f8c3
--- /dev/null
+++ b/client/src/app/worth/page.tsx
@@ -0,0 +1,15 @@
+import "react-toastify/dist/ReactToastify.css";
+import Heatmap from "../components/Heatmap";
+import Navbar from "../components/Navbar";
+
+const Page = () => {
+  return (
+    <div className="relative">
+      <Navbar searchBarPresent={false} />
+
+      <Heatmap />
+    </div>
+  );
+};
+
+export default Page;

From d733bf7fcf70db7eb953c6c7a0a66e8e728dae2e Mon Sep 17 00:00:00 2001
From: druvkotwani <druvkotwani12@gmail.com>
Date: Sun, 8 Sep 2024 20:46:24 +0530
Subject: [PATCH 13/23] main page modified

---
 client/src/app/page.tsx | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/client/src/app/page.tsx b/client/src/app/page.tsx
index 32000ba..e0ff921 100644
--- a/client/src/app/page.tsx
+++ b/client/src/app/page.tsx
@@ -5,7 +5,7 @@ import Navbar from "./components/Navbar";
 import Card from "./components/Card";
 import Footer from "./components/Footer";
 import GenerateStats from "./components/GenerateStats";
-import { use, useContext, useEffect, useState } from "react";
+import { useContext, useEffect, useState } from "react";
 import PromotionCard from "./components/PromotionCard";
 import { DataContext } from "./context/DataContext";
 import { ToastContainer } from "react-toastify";
@@ -13,9 +13,8 @@ import "react-toastify/dist/ReactToastify.css";
 import Skeleton from "./components/Skeleton";
 
 export default function Home() {
-  const { datas, setDatas } = useContext(DataContext);
+  const { datas, setDatas, search, setSearch } = useContext(DataContext);
   const [loading, setLoading] = useState(true);
-  const [search, setSearch] = useState<string>("");
   const [showStats, setShowStats] = useState(false);
   const [sortBy, setSortBy] = useState("default");
 
@@ -75,7 +74,7 @@ export default function Home() {
         />
       </button>
 
-      <Navbar search={search} setSearch={setSearch} />
+      <Navbar search={search} setSearch={setSearch} searchBarPresent={true} />
 
       <GenerateStats showStats={showStats} setShowStats={setShowStats} />
 

From 333d5407fcd60780f5ea654387579593a0478e82 Mon Sep 17 00:00:00 2001
From: druvkotwani <druvkotwani12@gmail.com>
Date: Sun, 8 Sep 2024 20:47:14 +0530
Subject: [PATCH 14/23] main heatmap component + download functionality working

---
 client/package.json                   |   1 +
 client/src/app/components/Heatmap.tsx | 447 ++++++++++++++++++++++++++
 client/yarn.lock                      |  34 ++
 3 files changed, 482 insertions(+)
 create mode 100644 client/src/app/components/Heatmap.tsx

diff --git a/client/package.json b/client/package.json
index 75bd137..0bca9cf 100644
--- a/client/package.json
+++ b/client/package.json
@@ -13,6 +13,7 @@
     "@vercel/analytics": "^1.3.1",
     "@vercel/speed-insights": "^1.0.12",
     "axios": "^1.7.3",
+    "html2canvas": "^1.4.1",
     "mongoose": "^8.5.2",
     "next": "14.2.5",
     "react": "^18",
diff --git a/client/src/app/components/Heatmap.tsx b/client/src/app/components/Heatmap.tsx
new file mode 100644
index 0000000..7f6d1ec
--- /dev/null
+++ b/client/src/app/components/Heatmap.tsx
@@ -0,0 +1,447 @@
+"use client";
+
+import React, { useState, useEffect, useRef } from "react";
+import dynamic from "next/dynamic";
+import Image from "next/image";
+import { toast, ToastContainer } from "react-toastify";
+import "react-toastify/dist/ReactToastify.css";
+import { data as TempData } from "./Card";
+import Link from "next/link";
+import Circle from "./Circle";
+import Questions from "./Questions";
+import html2canvas from "html2canvas";
+
+const CalendarHeatmap = dynamic(() => import("react-calendar-heatmap"), {
+  ssr: false,
+});
+
+function convertSubmissionCalendar(submissionCalendar: any) {
+  // Parse the JSON string to convert it into a JavaScript object
+  const submissionCalendarData = JSON.parse(submissionCalendar);
+
+  return submissionCalendarData;
+}
+
+const submissionCalendarData = {
+  "1704067200": 2,
+  "1704153600": 4,
+  "1704240000": 3,
+  "1704326400": 1,
+  "1704412800": 2,
+  "1704499200": 1,
+  "1704585600": 3,
+  "1704672000": 1,
+  "1704758400": 2,
+  "1704844800": 1,
+  "1704931200": 1,
+  "1705017600": 1,
+  "1705104000": 1,
+  "1705190400": 1,
+  "1705276800": 1,
+  "1705363200": 1,
+  "1705449600": 1,
+  "1705520000": 1,
+  "1705536000": 1,
+  "1705622400": 1,
+  "1705708800": 1,
+  "1705795200": 1,
+  "1705881600": 1,
+  "1705968000": 1,
+  "1706054400": 1,
+  "1706140800": 1,
+  "1706227200": 1,
+
+  "1702080000": 8,
+  "1702166400": 4,
+  "1702252800": 2,
+  "1702339200": 1,
+  "1702425600": 1,
+  "1702512000": 1,
+  "1702598400": 1,
+  "1702684800": 1,
+  "1702771200": 1,
+  "1702857600": 1,
+  "1702944000": 1,
+  "1703030400": 1,
+  "1703116800": 1,
+  "1703203200": 1,
+  "1703289600": 1,
+  "1703376000": 1,
+  "1703402400": 1,
+
+  // Random data for each month of 2024
+  "1703443200": 3,
+  "1703529600": 5,
+  "1703616000": 2,
+  "1703702400": 4,
+  "1703788800": 1,
+  "1703875200": 2,
+  "1703961600": 6,
+  "1704048000": 3,
+  "1704134400": 5,
+  "1704220800": 2,
+  "1704307200": 4,
+  "1704393600": 1,
+  "1704480000": 3,
+  "1704566400": 5,
+  "1704652800": 2,
+  "1704739200": 4,
+
+  "1704825600": 6,
+  "1704912000": 1,
+  "1704998400": 2,
+  "1705084800": 3,
+  "1705171200": 5,
+  "1705257600": 4,
+  "1705344000": 1,
+  "1705430400": 3,
+  "1705516800": 5,
+  "1705603200": 2,
+  "1705689600": 4,
+  "1705776000": 6,
+  "1705862400": 1,
+  "1705948800": 2,
+  "1706035200": 3,
+
+  // More random values for the remaining months
+  "1706121600": 1,
+  "1706208000": 4,
+  "1706294400": 2,
+  "1706380800": 5,
+  "1706467200": 1,
+  "1706553600": 3,
+  "1706640000": 6,
+  "1706726400": 2,
+  "1706812800": 4,
+  "1706899200": 1,
+  "1706985600": 5,
+  "1707072000": 3,
+  "1707158400": 6,
+  "1707244800": 2,
+  "1707331200": 4,
+  "1707417600": 1,
+};
+
+export default function Heatmap() {
+  const [isMounted, setIsMounted] = useState(false);
+  const [username, setUsername] = useState("");
+  const [submissionCalendar, setSubmissionCalendar] = useState(
+    submissionCalendarData
+  );
+  const [loading, setLoading] = useState(false);
+  const [data, setData] = useState(TempData);
+  const [tooltip, setTooltip] = useState({
+    show: false,
+    content: "",
+    x: 0,
+    y: 0,
+  });
+
+  useEffect(() => {
+    setIsMounted(true);
+  }, []);
+
+  const generateStats = async (e: React.FormEvent) => {
+    setLoading(true);
+    e.preventDefault();
+
+    if (!username) {
+      return;
+    }
+
+    try {
+      const res = await fetch("/api/" + username);
+      if (!res.ok) {
+        toast("👻 User not found");
+        setLoading(false);
+        return;
+      }
+
+      const data = await res.json();
+      setData(data);
+      setSubmissionCalendar(convertSubmissionCalendar(data.submissionCalendar));
+      toast("🫡 Stats generated successfully");
+    } catch (error) {
+      console.error("An error occurred. Please try again later");
+      toast("😞 An error occurred. Please try again later");
+    } finally {
+      setLoading(false);
+    }
+  };
+
+  const today = new Date();
+  const endDate = today;
+  const startDate = new Date(
+    today.getFullYear() - 1,
+    today.getMonth(),
+    today.getDate() + 1
+  );
+
+  const values = Object.entries(submissionCalendar)
+    .map(([timestamp, count]) => ({
+      date: new Date(parseInt(timestamp) * 1000),
+      count: count,
+    }))
+    .filter((value) => value.date >= startDate && value.date <= endDate);
+
+  const formatDate = (date: Date) => {
+    const months = [
+      "Jan",
+      "Feb",
+      "Mar",
+      "Apr",
+      "May",
+      "Jun",
+      "Jul",
+      "Aug",
+      "Sep",
+      "Oct",
+      "Nov",
+      "Dec",
+    ];
+    return `${
+      months[date.getMonth()]
+    } ${date.getDate()}, ${date.getFullYear()}`;
+  };
+
+  const contentRef = useRef<HTMLDivElement>(null);
+
+  const downloadAsImage = async () => {
+    if (contentRef.current) {
+      try {
+        // Apply a background color to the element before capturing
+        contentRef.current.style.backgroundColor = "#1c1c1c";
+        contentRef.current.style.padding = "20px";
+        contentRef.current.style.borderRadius = "10px";
+
+        const canvas = await html2canvas(contentRef.current, {
+          scale: 2, // Increase scale for better quality
+          useCORS: true, // This can help with loading cross-origin images
+          logging: true, // This can help debug issues
+          backgroundColor: "#1c1c1c", // Set the background color
+        });
+
+        // Reset the inline styles after capturing
+        contentRef.current.style.backgroundColor = "";
+        contentRef.current.style.padding = "";
+        contentRef.current.style.borderRadius = "";
+
+        const image = canvas.toDataURL("image/png");
+        const link = document.createElement("a");
+        link.href = image;
+        link.download = "leetcode-stats.png";
+        link.click();
+        toast("🖼️ Image downloaded successfully");
+      } catch (error) {
+        console.error("Error generating image:", error);
+        toast("😞 Error generating image. Please try again.");
+      }
+    }
+  };
+
+  const handleMouseOver = (event: any, value: any) => {
+    if (value && value.date) {
+      const rect = event.target.getBoundingClientRect();
+      setTooltip({
+        show: true,
+        content: `${value.count} submission${
+          value.count !== 1 ? "s" : ""
+        } on ${formatDate(value.date)}`,
+        x: rect.left + window.scrollX,
+        y: rect.top + window.scrollY - 40,
+      });
+    }
+  };
+
+  const handleMouseLeave = () => {
+    setTooltip({ ...tooltip, show: false });
+  };
+
+  if (!isMounted) return null;
+
+  return (
+    <>
+      <div className="w-full font-sourcecodepro mt-24 relative mb-8">
+        <div className=" flex flex-col items-center justify-center  w-full">
+          <h1 className="text-3xl font-semibold mb-4  text-center bg-gradient-to-r from-[#09C4FF] to-[#f38d90]  bg-clip-text text-transparent">
+            Estimate LeetCode Worth Generator
+          </h1>
+
+          <form
+            onSubmit={generateStats}
+            className="flex items-center justify-center flex-col"
+          >
+            <div className="relative ">
+              <input
+                value={username}
+                onChange={(e) => setUsername(e.target.value)}
+                type="text"
+                placeholder="Enter the leetcode username"
+                className="bg-[#1f1f1f] pl-10 max-w-[600px] w-[300px] md:w-[450px] lg:w-[500px] h-[40px] text-white rounded px-4 py-6 md:text-lg text-base focus:outline-none"
+              />
+              <Image
+                src="/assets/icons/money.svg"
+                alt="MOney Icon"
+                width={24}
+                height={24}
+                className="absolute left-2 -translate-y-1/2 top-1/2 "
+              />
+            </div>
+
+            <div className="flex gap-2 ">
+              <button
+                type="submit"
+                disabled={!username || loading}
+                onClick={generateStats}
+                className={`border flex items-center text-center bg-gradient-to-r from-[#78ff09] to-[#f3ac8d]  bg-clip-text text-transparent justify-center gap-2 bg-[#010101] px-4 h-[40px] rounded-md  font-semibold text-lg mt-4  ${
+                  loading || !username
+                    ? "cursor-not-allowed opacity-50"
+                    : "cursor-pointer"
+                }`}
+              >
+                Generate
+                <Image
+                  src={
+                    loading
+                      ? "/assets/icons/loading.svg"
+                      : "/assets/icons/money2.svg"
+                  }
+                  alt="Money Icon"
+                  width={24}
+                  height={24}
+                  className=""
+                />{" "}
+                Worth
+              </button>
+              <button
+                type="button"
+                onClick={downloadAsImage}
+                disabled={!username || loading}
+                className={`border flex items-center text-center bg-gradient-to-r from-[#cb42b2] to-[#f38d90]  bg-clip-text text-transparent justify-center gap-2 px-4 h-[40px] rounded-md  font-semibold text-lg mt-4  ${
+                  loading || !username
+                    ? "cursor-not-allowed opacity-50"
+                    : "cursor-pointer"
+                }`}
+              >
+                Download Image
+              </button>
+            </div>
+          </form>
+        </div>
+
+        <div
+          ref={contentRef}
+          className="max-w-screen-sm mx-auto rounded border px-8  py-4 mt-8"
+        >
+          <div className="flex justify-between items-center md:flex-row flex-col">
+            <div className="flex flex-row md:gap-0 gap-2 md:flex-col">
+              <Image
+                src={data.profileData.image}
+                width={100}
+                height={100}
+                alt={data.profileData.fullName}
+                className="rounded-full"
+              />
+              <div className="flex flex-col justify-center items-start">
+                <h2 className="text-2xl font-semibold mt-2 text-white">
+                  {data.profileData.fullName}
+                </h2>
+                <p className="text-gray-400">@{data.profileData.username}</p>
+              </div>
+            </div>
+            <div className="h-40 w-[1px] rounded mx-1 bg-gray-600 hidden md:block" />
+            <div className="  lg:flex-row gap-5 items-center h-full justify-center hidden md:flex">
+              {/* Circle */}
+
+              <Circle total={data?.totalSolved} />
+
+              <div className="flex flex-col gap-3">
+                {/* Questions */}
+
+                <Questions
+                  type={"Easy"}
+                  solved={data?.easySolved}
+                  total={data?.easyTotal}
+                  line="bg-[#2db55d26]"
+                  line2="bg-[#01B8A2]"
+                />
+
+                <Questions
+                  type={"Medium"}
+                  solved={data?.mediumSolved}
+                  total={data?.mediumTotal}
+                  line="bg-[#ffb80026]"
+                  line2="bg-[#FFC11F]"
+                />
+
+                <Questions
+                  type={"Hard"}
+                  solved={data?.hardSolved}
+                  total={data?.hardTotal}
+                  line="bg-[#ef474326]"
+                  line2="bg-[#EF4642]"
+                />
+              </div>
+            </div>
+          </div>
+
+          <div className="mt-4">
+            <CalendarHeatmap
+              startDate={startDate}
+              endDate={endDate}
+              values={values}
+              classForValue={(value) => {
+                if (!value || value.count === 0) {
+                  return "color-empty";
+                }
+                return `color-github-${Math.min(value.count, 4)}`;
+              }}
+              onMouseOver={handleMouseOver}
+              onMouseLeave={handleMouseLeave}
+              gutterSize={2}
+              horizontal={true}
+            />
+
+            <h2 className="text-sm font-semibold mt-4 text-gray-400 text-center">
+              <span className="text-[#f3e58d] text-2xl">
+                {data.totalSolved * 10}$
+              </span>
+              <br />
+              Estimated Worth
+            </h2>
+
+            <p className="text-white mt-4 flex w-full items-center justify-center">
+              Get Yours at:&nbsp;
+              <Link
+                href="https://leetcode-profiles-delta.vercel.app/worth"
+                className="text-blue-300"
+              >
+                leetcode-profiles-delta.vercel.app
+              </Link>
+            </p>
+          </div>
+          {tooltip.show && (
+            <div
+              className="absolute bg-gray-800  text-white p-2 rounded shadow-lg text-sm z-10 pointer-events-none w-fit "
+              style={{ left: `${tooltip.x}px`, top: `${tooltip.y}px` }}
+            >
+              {tooltip.content}
+            </div>
+          )}
+        </div>
+      </div>
+      <ToastContainer
+        position="bottom-right"
+        autoClose={5000}
+        hideProgressBar={false}
+        newestOnTop={false}
+        closeOnClick
+        rtl={false}
+        pauseOnFocusLoss
+        draggable
+        pauseOnHover
+        theme="dark"
+      />
+    </>
+  );
+}
diff --git a/client/yarn.lock b/client/yarn.lock
index 25fd1e6..9f75c2c 100644
--- a/client/yarn.lock
+++ b/client/yarn.lock
@@ -553,6 +553,11 @@ balanced-match@^1.0.0:
   resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee"
   integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==
 
+base64-arraybuffer@^1.0.2:
+  version "1.0.2"
+  resolved "https://registry.yarnpkg.com/base64-arraybuffer/-/base64-arraybuffer-1.0.2.tgz#1c37589a7c4b0746e34bd1feb951da2df01c1bdc"
+  integrity sha512-I3yl4r9QB5ZRY3XuJVEPfc2XhZO6YweFPI+UovAzn+8/hb3oJ6lnysaFcjVpkCPfVWFUDvoZ8kmVDP7WyRtYtQ==
+
 binary-extensions@^2.0.0:
   version "2.3.0"
   resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.3.0.tgz#f6e14a97858d327252200242d4ccfe522c445522"
@@ -694,6 +699,13 @@ cross-spawn@^7.0.0, cross-spawn@^7.0.2:
     shebang-command "^2.0.0"
     which "^2.0.1"
 
+css-line-break@^2.1.0:
+  version "2.1.0"
+  resolved "https://registry.yarnpkg.com/css-line-break/-/css-line-break-2.1.0.tgz#bfef660dfa6f5397ea54116bb3cb4873edbc4fa0"
+  integrity sha512-FHcKFCZcAha3LwfVBhCQbW2nCNbkZXn7KVUJcsT5/P8YmfsVja0FMPJr0B903j/E69HUphKiV9iQArX8SDYA4w==
+  dependencies:
+    utrie "^1.0.2"
+
 cssesc@^3.0.0:
   version "3.0.0"
   resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee"
@@ -1489,6 +1501,14 @@ hasown@^2.0.0, hasown@^2.0.1, hasown@^2.0.2:
   dependencies:
     function-bind "^1.1.2"
 
+html2canvas@^1.4.1:
+  version "1.4.1"
+  resolved "https://registry.yarnpkg.com/html2canvas/-/html2canvas-1.4.1.tgz#7cef1888311b5011d507794a066041b14669a543"
+  integrity sha512-fPU6BHNpsyIhr8yyMpTLLxAbkaK8ArIBcmZIRiBLiDhjeqvXolaEmDGmELFuX9I4xDcaKKcJl+TKZLqruBbmWA==
+  dependencies:
+    css-line-break "^2.1.0"
+    text-segmentation "^1.0.3"
+
 ignore@^5.2.0:
   version "5.3.1"
   resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.3.1.tgz#5073e554cd42c5b33b394375f538b8593e34d4ef"
@@ -2748,6 +2768,13 @@ tapable@^2.2.0:
   resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.2.1.tgz#1967a73ef4060a82f12ab96af86d52fdb76eeca0"
   integrity sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==
 
+text-segmentation@^1.0.3:
+  version "1.0.3"
+  resolved "https://registry.yarnpkg.com/text-segmentation/-/text-segmentation-1.0.3.tgz#52a388159efffe746b24a63ba311b6ac9f2d7943"
+  integrity sha512-iOiPUo/BGnZ6+54OsWxZidGCsdU8YbE4PSpdPinp7DeMtUJNJBoJ/ouUSTJjHkh1KntHaltHl/gDs2FC4i5+Nw==
+  dependencies:
+    utrie "^1.0.2"
+
 text-table@^0.2.0:
   version "0.2.0"
   resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4"
@@ -2894,6 +2921,13 @@ util-deprecate@^1.0.2:
   resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"
   integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==
 
+utrie@^1.0.2:
+  version "1.0.2"
+  resolved "https://registry.yarnpkg.com/utrie/-/utrie-1.0.2.tgz#d42fe44de9bc0119c25de7f564a6ed1b2c87a645"
+  integrity sha512-1MLa5ouZiOmQzUbjbu9VmjLzn1QLXBhwpUa7kdLUQK+KQ5KA9I1vk5U4YHe/X2Ch7PYnJfWuWT+VbuxbGwljhw==
+  dependencies:
+    base64-arraybuffer "^1.0.2"
+
 webidl-conversions@^7.0.0:
   version "7.0.0"
   resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-7.0.0.tgz#256b4e1882be7debbf01d05f0aa2039778ea080a"

From c34270437bf477e96417aeb3c3d56552ac64e954 Mon Sep 17 00:00:00 2001
From: druvkotwani <druvkotwani12@gmail.com>
Date: Sun, 8 Sep 2024 21:16:04 +0530
Subject: [PATCH 15/23] added worthAlgo + addtemp data in card

---
 client/src/app/components/Card.tsx    |  7 +++++
 client/src/app/components/Heatmap.tsx | 39 ++++++++++++++++++++++++---
 2 files changed, 43 insertions(+), 3 deletions(-)

diff --git a/client/src/app/components/Card.tsx b/client/src/app/components/Card.tsx
index 335ca72..073112c 100644
--- a/client/src/app/components/Card.tsx
+++ b/client/src/app/components/Card.tsx
@@ -36,6 +36,13 @@ export const data = {
   easySolved: 175,
   mediumSolved: 110,
   hardSolved: 21,
+  activeYears: [2021, 2024],
+  calendarData: {
+    userCalendar: {
+      streak: 39,
+      totalActiveDays: 89,
+    },
+  },
 };
 
 export default function Card({ userData = data, index }: any) {
diff --git a/client/src/app/components/Heatmap.tsx b/client/src/app/components/Heatmap.tsx
index 7f6d1ec..c33f95a 100644
--- a/client/src/app/components/Heatmap.tsx
+++ b/client/src/app/components/Heatmap.tsx
@@ -122,6 +122,31 @@ const submissionCalendarData = {
   "1707417600": 1,
 };
 
+function worthCalculator(
+  streak: number,
+  easySolved: number,
+  mediumSolved: number,
+  hardSolved: number,
+  activeYears: number,
+  totalActiveDays: number
+) {
+  const easyPoints = 1;
+  const mediumPoints = 2;
+  const hardPoints = 5;
+  const streakPoints = streak >= 30 ? 10 : 5;
+  const activeYearPoints = 2;
+  const totalActiveDaysPoints = 10;
+
+  return (
+    easySolved * easyPoints +
+    mediumSolved * mediumPoints +
+    hardSolved * hardPoints +
+    streak * streakPoints +
+    activeYears * activeYearPoints +
+    totalActiveDays * totalActiveDaysPoints
+  );
+}
+
 export default function Heatmap() {
   const [isMounted, setIsMounted] = useState(false);
   const [username, setUsername] = useState("");
@@ -316,9 +341,9 @@ export default function Heatmap() {
               <button
                 type="button"
                 onClick={downloadAsImage}
-                disabled={!username || loading}
+                disabled={!data || loading}
                 className={`border flex items-center text-center bg-gradient-to-r from-[#cb42b2] to-[#f38d90]  bg-clip-text text-transparent justify-center gap-2 px-4 h-[40px] rounded-md  font-semibold text-lg mt-4  ${
-                  loading || !username
+                  loading || !data
                     ? "cursor-not-allowed opacity-50"
                     : "cursor-pointer"
                 }`}
@@ -404,7 +429,15 @@ export default function Heatmap() {
 
             <h2 className="text-sm font-semibold mt-4 text-gray-400 text-center">
               <span className="text-[#f3e58d] text-2xl">
-                {data.totalSolved * 10}$
+                {worthCalculator(
+                  data.easySolved,
+                  data.mediumSolved,
+                  data.hardSolved,
+                  data?.activeYears.length,
+                  data?.calendarData.userCalendar.streak,
+                  data?.calendarData.userCalendar.totalActiveDays
+                )}
+                $
               </span>
               <br />
               Estimated Worth

From ded2dbc60ec39317a648fbb1bb845dc785237df0 Mon Sep 17 00:00:00 2001
From: druvkotwani <druvkotwani12@gmail.com>
Date: Sun, 8 Sep 2024 21:45:48 +0530
Subject: [PATCH 16/23] added button to navigate to worth section + some minor
 fix in heatmap component

---
 client/src/app/components/Heatmap.tsx |  2 +-
 client/src/app/page.tsx               | 17 +++++++++++++++--
 2 files changed, 16 insertions(+), 3 deletions(-)

diff --git a/client/src/app/components/Heatmap.tsx b/client/src/app/components/Heatmap.tsx
index c33f95a..dddc084 100644
--- a/client/src/app/components/Heatmap.tsx
+++ b/client/src/app/components/Heatmap.tsx
@@ -443,7 +443,7 @@ export default function Heatmap() {
               Estimated Worth
             </h2>
 
-            <p className="text-white mt-4 flex w-full items-center justify-center">
+            <p className="text-white mt-4 flex w-full items-center justify-center flex-col md:flex-row">
               Get Yours at:&nbsp;
               <Link
                 href="https://leetcode-profiles-delta.vercel.app/worth"
diff --git a/client/src/app/page.tsx b/client/src/app/page.tsx
index e0ff921..6763ff9 100644
--- a/client/src/app/page.tsx
+++ b/client/src/app/page.tsx
@@ -11,6 +11,7 @@ import { DataContext } from "./context/DataContext";
 import { ToastContainer } from "react-toastify";
 import "react-toastify/dist/ReactToastify.css";
 import Skeleton from "./components/Skeleton";
+import Link from "next/link";
 
 export default function Home() {
   const { datas, setDatas, search, setSearch } = useContext(DataContext);
@@ -78,11 +79,23 @@ export default function Home() {
 
       <GenerateStats showStats={showStats} setShowStats={setShowStats} />
 
-      <div className="w-full flex items-center justify-center  ">
+      <div className="w-full max-w-7xl mx-auto flex flex-col lg:grid grid-cols-3 items-center justify-start gap-4 lg:gap-12 px-8 mt-28">
+        <Link
+          href="/worth"
+          className="flex w-fit  gap-2 rounded border-2 border-[#f7f7f7]  px-4 bg-gradient-to-r from-[#cb42b2] to-[#ecf576]  bg-clip-text text-transparent p-2 font-sourcecodepro font-bold"
+        >
+          <Image
+            src="/assets/icons/money.svg"
+            alt="Leetcode Logo"
+            width={24}
+            height={24}
+          />
+          LeetCode Worth
+        </Link>
         <select
           value={sortBy}
           onChange={handleSortChange}
-          className="mt-28 rounded border-2 border-[#f7f7f7]  w-64 bg-[#0e0e0e] text-white p-2 font-sourcecodepro"
+          className=" rounded border-2 border-[#f7f7f7]  w-64 bg-[#0e0e0e] text-white p-2 font-sourcecodepro"
         >
           <option value="default">Sort By Default</option>
           <option value="question-solved">Sort By Questions Solved</option>

From f37f2724af3bf637bea7353e4c106fd10f799467 Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Sun, 8 Sep 2024 16:19:44 +0000
Subject: [PATCH 17/23] Bump axios from 1.7.3 to 1.7.4 in /client

Bumps [axios](https://github.com/axios/axios) from 1.7.3 to 1.7.4.
- [Release notes](https://github.com/axios/axios/releases)
- [Changelog](https://github.com/axios/axios/blob/v1.x/CHANGELOG.md)
- [Commits](https://github.com/axios/axios/compare/v1.7.3...v1.7.4)

---
updated-dependencies:
- dependency-name: axios
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
---
 client/package.json | 2 +-
 client/yarn.lock    | 8 ++++----
 2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/client/package.json b/client/package.json
index 0bca9cf..7b5f84c 100644
--- a/client/package.json
+++ b/client/package.json
@@ -12,7 +12,7 @@
     "@types/react-calendar-heatmap": "^1.6.7",
     "@vercel/analytics": "^1.3.1",
     "@vercel/speed-insights": "^1.0.12",
-    "axios": "^1.7.3",
+    "axios": "^1.7.4",
     "html2canvas": "^1.4.1",
     "mongoose": "^8.5.2",
     "next": "14.2.5",
diff --git a/client/yarn.lock b/client/yarn.lock
index 9f75c2c..e41d235 100644
--- a/client/yarn.lock
+++ b/client/yarn.lock
@@ -532,10 +532,10 @@ axe-core@^4.9.1:
   resolved "https://registry.yarnpkg.com/axe-core/-/axe-core-4.10.0.tgz#d9e56ab0147278272739a000880196cdfe113b59"
   integrity sha512-Mr2ZakwQ7XUAjp7pAwQWRhhK8mQQ6JAaNWSjmjxil0R8BPioMtQsTLOolGYkji1rcL++3dCqZA3zWqpT+9Ew6g==
 
-axios@^1.7.3:
-  version "1.7.3"
-  resolved "https://registry.yarnpkg.com/axios/-/axios-1.7.3.tgz#a1125f2faf702bc8e8f2104ec3a76fab40257d85"
-  integrity sha512-Ar7ND9pU99eJ9GpoGQKhKf58GpUOgnzuaB7ueNQ5BMi0p+LZ5oaEnfF999fAArcTIBwXTCHAmGcHOZJaWPq9Nw==
+axios@^1.7.4:
+  version "1.7.4"
+  resolved "https://registry.yarnpkg.com/axios/-/axios-1.7.4.tgz#4c8ded1b43683c8dd362973c393f3ede24052aa2"
+  integrity sha512-DukmaFRnY6AzAALSH4J2M3k6PkaC+MfaAGdEERRWcC9q3/TWQwLpHR8ZRLKTdQ3aBDL64EdluRDjJqKw+BPZEw==
   dependencies:
     follow-redirects "^1.15.6"
     form-data "^4.0.0"

From 4f7f59ce327c92e335718f5063099e5c2a1d337e Mon Sep 17 00:00:00 2001
From: Dhruv Kotwani <96691139+druvkotwani@users.noreply.github.com>
Date: Sun, 8 Sep 2024 22:01:52 +0530
Subject: [PATCH 18/23] Update README.md

---
 README.md | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/README.md b/README.md
index 5782a6b..9e8e6f2 100644
--- a/README.md
+++ b/README.md
@@ -3,6 +3,8 @@
 A platform to create your LeetCode statistics and showcase your LeetCode profile globally.
 
 ![Screenshot 2023-11-23 154638](https://github.com/druvkotwani/Leetcode-Profiles/assets/96691139/9f6bfbb4-c389-4509-9e42-a0d394651180)
+![image](https://github.com/user-attachments/assets/25d9173e-7ab8-429d-baf7-a1b01ef635fa)
+
 
 
 

From 6a60690a9b552662c512ae7e56454145d546d68a Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Wed, 18 Sep 2024 05:09:32 +0000
Subject: [PATCH 19/23] Bump next from 14.2.5 to 14.2.10 in /client

Bumps [next](https://github.com/vercel/next.js) from 14.2.5 to 14.2.10.
- [Release notes](https://github.com/vercel/next.js/releases)
- [Changelog](https://github.com/vercel/next.js/blob/canary/release.js)
- [Commits](https://github.com/vercel/next.js/compare/v14.2.5...v14.2.10)

---
updated-dependencies:
- dependency-name: next
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
---
 client/package.json |   2 +-
 client/yarn.lock    | 124 ++++++++++++++++++++++----------------------
 2 files changed, 63 insertions(+), 63 deletions(-)

diff --git a/client/package.json b/client/package.json
index 0bca9cf..b9e81b6 100644
--- a/client/package.json
+++ b/client/package.json
@@ -15,7 +15,7 @@
     "axios": "^1.7.3",
     "html2canvas": "^1.4.1",
     "mongoose": "^8.5.2",
-    "next": "14.2.5",
+    "next": "14.2.10",
     "react": "^18",
     "react-calendar-heatmap": "^1.9.0",
     "react-dom": "^18",
diff --git a/client/yarn.lock b/client/yarn.lock
index 9f75c2c..ad3f431 100644
--- a/client/yarn.lock
+++ b/client/yarn.lock
@@ -129,10 +129,10 @@
   dependencies:
     sparse-bitfield "^3.0.3"
 
-"@next/env@14.2.5":
-  version "14.2.5"
-  resolved "https://registry.yarnpkg.com/@next/env/-/env-14.2.5.tgz#1d9328ab828711d3517d0a1d505acb55e5ef7ad0"
-  integrity sha512-/zZGkrTOsraVfYjGP8uM0p6r0BDT6xWpkjdVbcz66PJVSpwXX3yNiRycxAuDfBKGWBrZBXRuK/YVlkNgxHGwmA==
+"@next/env@14.2.10":
+  version "14.2.10"
+  resolved "https://registry.yarnpkg.com/@next/env/-/env-14.2.10.tgz#1d3178340028ced2d679f84140877db4f420333c"
+  integrity sha512-dZIu93Bf5LUtluBXIv4woQw2cZVZ2DJTjax5/5DOs3lzEOeKLy7GxRSr4caK9/SCPdaW6bCgpye6+n4Dh9oJPw==
 
 "@next/eslint-plugin-next@14.2.5":
   version "14.2.5"
@@ -141,50 +141,50 @@
   dependencies:
     glob "10.3.10"
 
-"@next/swc-darwin-arm64@14.2.5":
-  version "14.2.5"
-  resolved "https://registry.yarnpkg.com/@next/swc-darwin-arm64/-/swc-darwin-arm64-14.2.5.tgz#d0a160cf78c18731c51cc0bff131c706b3e9bb05"
-  integrity sha512-/9zVxJ+K9lrzSGli1///ujyRfon/ZneeZ+v4ptpiPoOU+GKZnm8Wj8ELWU1Pm7GHltYRBklmXMTUqM/DqQ99FQ==
-
-"@next/swc-darwin-x64@14.2.5":
-  version "14.2.5"
-  resolved "https://registry.yarnpkg.com/@next/swc-darwin-x64/-/swc-darwin-x64-14.2.5.tgz#eb832a992407f6e6352eed05a073379f1ce0589c"
-  integrity sha512-vXHOPCwfDe9qLDuq7U1OYM2wUY+KQ4Ex6ozwsKxp26BlJ6XXbHleOUldenM67JRyBfVjv371oneEvYd3H2gNSA==
-
-"@next/swc-linux-arm64-gnu@14.2.5":
-  version "14.2.5"
-  resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-14.2.5.tgz#098fdab57a4664969bc905f5801ef5a89582c689"
-  integrity sha512-vlhB8wI+lj8q1ExFW8lbWutA4M2ZazQNvMWuEDqZcuJJc78iUnLdPPunBPX8rC4IgT6lIx/adB+Cwrl99MzNaA==
-
-"@next/swc-linux-arm64-musl@14.2.5":
-  version "14.2.5"
-  resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-14.2.5.tgz#243a1cc1087fb75481726dd289c7b219fa01f2b5"
-  integrity sha512-NpDB9NUR2t0hXzJJwQSGu1IAOYybsfeB+LxpGsXrRIb7QOrYmidJz3shzY8cM6+rO4Aojuef0N/PEaX18pi9OA==
-
-"@next/swc-linux-x64-gnu@14.2.5":
-  version "14.2.5"
-  resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-14.2.5.tgz#b8a2e436387ee4a52aa9719b718992e0330c4953"
-  integrity sha512-8XFikMSxWleYNryWIjiCX+gU201YS+erTUidKdyOVYi5qUQo/gRxv/3N1oZFCgqpesN6FPeqGM72Zve+nReVXQ==
-
-"@next/swc-linux-x64-musl@14.2.5":
-  version "14.2.5"
-  resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-14.2.5.tgz#cb8a9adad5fb8df86112cfbd363aab5c6d32757b"
-  integrity sha512-6QLwi7RaYiQDcRDSU/os40r5o06b5ue7Jsk5JgdRBGGp8l37RZEh9JsLSM8QF0YDsgcosSeHjglgqi25+m04IQ==
-
-"@next/swc-win32-arm64-msvc@14.2.5":
-  version "14.2.5"
-  resolved "https://registry.yarnpkg.com/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.2.5.tgz#81f996c1c38ea0900d4e7719cc8814be8a835da0"
-  integrity sha512-1GpG2VhbspO+aYoMOQPQiqc/tG3LzmsdBH0LhnDS3JrtDx2QmzXe0B6mSZZiN3Bq7IOMXxv1nlsjzoS1+9mzZw==
-
-"@next/swc-win32-ia32-msvc@14.2.5":
-  version "14.2.5"
-  resolved "https://registry.yarnpkg.com/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.2.5.tgz#f61c74ce823e10b2bc150e648fc192a7056422e0"
-  integrity sha512-Igh9ZlxwvCDsu6438FXlQTHlRno4gFpJzqPjSIBZooD22tKeI4fE/YMRoHVJHmrQ2P5YL1DoZ0qaOKkbeFWeMg==
-
-"@next/swc-win32-x64-msvc@14.2.5":
-  version "14.2.5"
-  resolved "https://registry.yarnpkg.com/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.2.5.tgz#ed199a920efb510cfe941cd75ed38a7be21e756f"
-  integrity sha512-tEQ7oinq1/CjSG9uSTerca3v4AZ+dFa+4Yu6ihaG8Ud8ddqLQgFGcnwYls13H5X5CPDPZJdYxyeMui6muOLd4g==
+"@next/swc-darwin-arm64@14.2.10":
+  version "14.2.10"
+  resolved "https://registry.yarnpkg.com/@next/swc-darwin-arm64/-/swc-darwin-arm64-14.2.10.tgz#49d10ca4086fbd59ee68e204f75d7136eda2aa80"
+  integrity sha512-V3z10NV+cvMAfxQUMhKgfQnPbjw+Ew3cnr64b0lr8MDiBJs3eLnM6RpGC46nhfMZsiXgQngCJKWGTC/yDcgrDQ==
+
+"@next/swc-darwin-x64@14.2.10":
+  version "14.2.10"
+  resolved "https://registry.yarnpkg.com/@next/swc-darwin-x64/-/swc-darwin-x64-14.2.10.tgz#0ebeae3afb8eac433882b79543295ab83624a1a8"
+  integrity sha512-Y0TC+FXbFUQ2MQgimJ/7Ina2mXIKhE7F+GUe1SgnzRmwFY3hX2z8nyVCxE82I2RicspdkZnSWMn4oTjIKz4uzA==
+
+"@next/swc-linux-arm64-gnu@14.2.10":
+  version "14.2.10"
+  resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-14.2.10.tgz#7e602916d2fb55a3c532f74bed926a0137c16f20"
+  integrity sha512-ZfQ7yOy5zyskSj9rFpa0Yd7gkrBnJTkYVSya95hX3zeBG9E55Z6OTNPn1j2BTFWvOVVj65C3T+qsjOyVI9DQpA==
+
+"@next/swc-linux-arm64-musl@14.2.10":
+  version "14.2.10"
+  resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-14.2.10.tgz#6b143f628ccee490b527562e934f8de578d4be47"
+  integrity sha512-n2i5o3y2jpBfXFRxDREr342BGIQCJbdAUi/K4q6Env3aSx8erM9VuKXHw5KNROK9ejFSPf0LhoSkU/ZiNdacpQ==
+
+"@next/swc-linux-x64-gnu@14.2.10":
+  version "14.2.10"
+  resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-14.2.10.tgz#086f2f16a0678890a1eb46518c4dda381b046082"
+  integrity sha512-GXvajAWh2woTT0GKEDlkVhFNxhJS/XdDmrVHrPOA83pLzlGPQnixqxD8u3bBB9oATBKB//5e4vpACnx5Vaxdqg==
+
+"@next/swc-linux-x64-musl@14.2.10":
+  version "14.2.10"
+  resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-14.2.10.tgz#1befef10ed8dbcc5047b5d637a25ae3c30a0bfc3"
+  integrity sha512-opFFN5B0SnO+HTz4Wq4HaylXGFV+iHrVxd3YvREUX9K+xfc4ePbRrxqOuPOFjtSuiVouwe6uLeDtabjEIbkmDA==
+
+"@next/swc-win32-arm64-msvc@14.2.10":
+  version "14.2.10"
+  resolved "https://registry.yarnpkg.com/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.2.10.tgz#731f52c3ae3c56a26cf21d474b11ae1529531209"
+  integrity sha512-9NUzZuR8WiXTvv+EiU/MXdcQ1XUvFixbLIMNQiVHuzs7ZIFrJDLJDaOF1KaqttoTujpcxljM/RNAOmw1GhPPQQ==
+
+"@next/swc-win32-ia32-msvc@14.2.10":
+  version "14.2.10"
+  resolved "https://registry.yarnpkg.com/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.2.10.tgz#32723ef7f04e25be12af357cc72ddfdd42fd1041"
+  integrity sha512-fr3aEbSd1GeW3YUMBkWAu4hcdjZ6g4NBl1uku4gAn661tcxd1bHs1THWYzdsbTRLcCKLjrDZlNp6j2HTfrw+Bg==
+
+"@next/swc-win32-x64-msvc@14.2.10":
+  version "14.2.10"
+  resolved "https://registry.yarnpkg.com/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.2.10.tgz#ee1d036cb5ec871816f96baee7991035bb242455"
+  integrity sha512-UjeVoRGKNL2zfbcQ6fscmgjBAS/inHBh63mjIlfPg/NG8Yn2ztqylXt5qilYb6hoHIwaU2ogHknHWWmahJjgZQ==
 
 "@nodelib/fs.scandir@2.1.5":
   version "2.1.5"
@@ -2035,12 +2035,12 @@ natural-compare@^1.4.0:
   resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7"
   integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==
 
-next@14.2.5:
-  version "14.2.5"
-  resolved "https://registry.yarnpkg.com/next/-/next-14.2.5.tgz#afe4022bb0b752962e2205836587a289270efbea"
-  integrity sha512-0f8aRfBVL+mpzfBjYfQuLWh2WyAwtJXCRfkPF4UJ5qd2YwrHczsrSzXU4tRMV0OAxR8ZJZWPFn6uhSC56UTsLA==
+next@14.2.10:
+  version "14.2.10"
+  resolved "https://registry.yarnpkg.com/next/-/next-14.2.10.tgz#331981a4fecb1ae8af1817d4db98fc9687ee1cb6"
+  integrity sha512-sDDExXnh33cY3RkS9JuFEKaS4HmlWmDKP1VJioucCG6z5KuA008DPsDZOzi8UfqEk3Ii+2NCQSJrfbEWtZZfww==
   dependencies:
-    "@next/env" "14.2.5"
+    "@next/env" "14.2.10"
     "@swc/helpers" "0.5.5"
     busboy "1.6.0"
     caniuse-lite "^1.0.30001579"
@@ -2048,15 +2048,15 @@ next@14.2.5:
     postcss "8.4.31"
     styled-jsx "5.1.1"
   optionalDependencies:
-    "@next/swc-darwin-arm64" "14.2.5"
-    "@next/swc-darwin-x64" "14.2.5"
-    "@next/swc-linux-arm64-gnu" "14.2.5"
-    "@next/swc-linux-arm64-musl" "14.2.5"
-    "@next/swc-linux-x64-gnu" "14.2.5"
-    "@next/swc-linux-x64-musl" "14.2.5"
-    "@next/swc-win32-arm64-msvc" "14.2.5"
-    "@next/swc-win32-ia32-msvc" "14.2.5"
-    "@next/swc-win32-x64-msvc" "14.2.5"
+    "@next/swc-darwin-arm64" "14.2.10"
+    "@next/swc-darwin-x64" "14.2.10"
+    "@next/swc-linux-arm64-gnu" "14.2.10"
+    "@next/swc-linux-arm64-musl" "14.2.10"
+    "@next/swc-linux-x64-gnu" "14.2.10"
+    "@next/swc-linux-x64-musl" "14.2.10"
+    "@next/swc-win32-arm64-msvc" "14.2.10"
+    "@next/swc-win32-ia32-msvc" "14.2.10"
+    "@next/swc-win32-x64-msvc" "14.2.10"
 
 normalize-path@^3.0.0, normalize-path@~3.0.0:
   version "3.0.0"

From b945faacb461ff341ecb30636a8a9114edb1dca3 Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Sat, 18 Jan 2025 11:09:46 +0000
Subject: [PATCH 20/23] Bump mongoose from 8.5.2 to 8.9.5 in /client

Bumps [mongoose](https://github.com/Automattic/mongoose) from 8.5.2 to 8.9.5.
- [Release notes](https://github.com/Automattic/mongoose/releases)
- [Changelog](https://github.com/Automattic/mongoose/blob/master/CHANGELOG.md)
- [Commits](https://github.com/Automattic/mongoose/compare/8.5.2...8.9.5)

---
updated-dependencies:
- dependency-name: mongoose
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
---
 client/package.json |  2 +-
 client/yarn.lock    | 40 ++++++++++++++++++++--------------------
 2 files changed, 21 insertions(+), 21 deletions(-)

diff --git a/client/package.json b/client/package.json
index 094b348..28def9a 100644
--- a/client/package.json
+++ b/client/package.json
@@ -14,7 +14,7 @@
     "@vercel/speed-insights": "^1.0.12",
     "axios": "^1.7.4",
     "html2canvas": "^1.4.1",
-    "mongoose": "^8.5.2",
+    "mongoose": "^8.9.5",
     "next": "14.2.10",
     "react": "^18",
     "react-calendar-heatmap": "^1.9.0",
diff --git a/client/yarn.lock b/client/yarn.lock
index 20ccf60..ffb3bf9 100644
--- a/client/yarn.lock
+++ b/client/yarn.lock
@@ -122,10 +122,10 @@
     "@jridgewell/resolve-uri" "^3.1.0"
     "@jridgewell/sourcemap-codec" "^1.4.14"
 
-"@mongodb-js/saslprep@^1.1.5":
-  version "1.1.8"
-  resolved "https://registry.yarnpkg.com/@mongodb-js/saslprep/-/saslprep-1.1.8.tgz#d39744540be8800d17749990b0da95b4271840d1"
-  integrity sha512-qKwC/M/nNNaKUBMQ0nuzm47b7ZYWQHN3pcXq4IIcoSBc2hOIrflAxJduIvvqmhoz3gR2TacTAs8vlsCVPkiEdQ==
+"@mongodb-js/saslprep@^1.1.9":
+  version "1.1.9"
+  resolved "https://registry.yarnpkg.com/@mongodb-js/saslprep/-/saslprep-1.1.9.tgz#e974bab8eca9faa88677d4ea4da8d09a52069004"
+  integrity sha512-tVkljjeEaAhCqTzajSdgbQ6gE6f3oneVwa3iXR6csiEwXXOFsiC6Uh9iAjAhXPtqa/XMDHWjjeNH/77m/Yq2dw==
   dependencies:
     sparse-bitfield "^3.0.3"
 
@@ -585,10 +585,10 @@ braces@^3.0.3, braces@~3.0.2:
   dependencies:
     fill-range "^7.1.1"
 
-bson@^6.7.0:
-  version "6.8.0"
-  resolved "https://registry.yarnpkg.com/bson/-/bson-6.8.0.tgz#5063c41ba2437c2b8ff851b50d9e36cb7aaa7525"
-  integrity sha512-iOJg8pr7wq2tg/zSlCCHMi3hMm5JTOxLTagf3zxhcenHsFp+c6uOs6K7W5UE7A4QIJGtqh/ZovFNMP4mOPJynQ==
+bson@^6.10.1:
+  version "6.10.1"
+  resolved "https://registry.yarnpkg.com/bson/-/bson-6.10.1.tgz#dcd04703178f5ecf5b25de04edd2a95ec79385d3"
+  integrity sha512-P92xmHDQjSKPLHqFxefqMxASNq/aWJMEZugpCjf+AF/pgcUpMMQCg7t7+ewko0/u8AapvF3luf/FoehddEK+sA==
 
 busboy@1.6.0:
   version "1.6.0"
@@ -1972,23 +1972,23 @@ mongodb-connection-string-url@^3.0.0:
     "@types/whatwg-url" "^11.0.2"
     whatwg-url "^13.0.0"
 
-mongodb@6.7.0:
-  version "6.7.0"
-  resolved "https://registry.yarnpkg.com/mongodb/-/mongodb-6.7.0.tgz#f86e51e6530e6a2ca4a99d7cfdf6f409223ac199"
-  integrity sha512-TMKyHdtMcO0fYBNORiYdmM25ijsHs+Njs963r4Tro4OQZzqYigAzYQouwWRg4OIaiLRUEGUh/1UAcH5lxdSLIA==
+mongodb@~6.12.0:
+  version "6.12.0"
+  resolved "https://registry.yarnpkg.com/mongodb/-/mongodb-6.12.0.tgz#8b0bda1b18cbb3f0aec8ab4119c5dc535a43c444"
+  integrity sha512-RM7AHlvYfS7jv7+BXund/kR64DryVI+cHbVAy9P61fnb1RcWZqOW1/Wj2YhqMCx+MuYhqTRGv7AwHBzmsCKBfA==
   dependencies:
-    "@mongodb-js/saslprep" "^1.1.5"
-    bson "^6.7.0"
+    "@mongodb-js/saslprep" "^1.1.9"
+    bson "^6.10.1"
     mongodb-connection-string-url "^3.0.0"
 
-mongoose@^8.5.2:
-  version "8.5.2"
-  resolved "https://registry.yarnpkg.com/mongoose/-/mongoose-8.5.2.tgz#73b40ce778f3fc66407aba3c3157795cdd278543"
-  integrity sha512-GZB4rHMdYfGatV+23IpCrqFbyCOjCNOHXgWbirr92KRwTEncBrtW3kgU9vmpKjsGf7nMmnAy06SwWUv1vhDkSg==
+mongoose@^8.9.5:
+  version "8.9.5"
+  resolved "https://registry.yarnpkg.com/mongoose/-/mongoose-8.9.5.tgz#90a2d70b48a66022a61d7a170ab4fad106b83cba"
+  integrity sha512-SPhOrgBm0nKV3b+IIHGqpUTOmgVL5Z3OO9AwkFEmvOZznXTvplbomstCnPOGAyungtRXE5pJTgKpKcZTdjeESg==
   dependencies:
-    bson "^6.7.0"
+    bson "^6.10.1"
     kareem "2.6.3"
-    mongodb "6.7.0"
+    mongodb "~6.12.0"
     mpath "0.9.0"
     mquery "5.0.0"
     ms "2.1.3"

From 574ccb2e078d7d11066fd85ffa742d8a3be112a0 Mon Sep 17 00:00:00 2001
From: druvkotwani <druvkotwani12@gmail.com>
Date: Sat, 8 Mar 2025 16:48:26 +0530
Subject: [PATCH 21/23] Implement pagination and enhanced search functionality
 for user data

---
 client/src/app/components/Navbar.tsx |  10 +-
 client/src/app/page.tsx              | 143 ++++++++++++++++++++++-----
 client/src/pages/api/fetchdata.ts    |  46 ++++++++-
 3 files changed, 168 insertions(+), 31 deletions(-)

diff --git a/client/src/app/components/Navbar.tsx b/client/src/app/components/Navbar.tsx
index 17c0eef..6be917a 100644
--- a/client/src/app/components/Navbar.tsx
+++ b/client/src/app/components/Navbar.tsx
@@ -35,21 +35,21 @@ const Navbar: React.FC<NavbarProps> = ({
 
       {/* Search */}
       {searchBarPresent && (
-        <form className="">
-          <div className="relative flex ">
+        <form className="" onSubmit={(e) => e.preventDefault()}>
+          <div className="relative flex items-center">
             <input
               value={search}
               onChange={(e) => setSearch && setSearch(e.target.value)}
               type="text"
-              placeholder="Search by username"
-              className="bg-[#1f1f1f] sm:w-[260px] w-[100px] font-sourcecodepro text-white rounded px-4 py-3  focus:outline-none pl-10"
+              placeholder="Search by name"
+              className="bg-[#1f1f1f] sm:w-[260px] w-[100px] font-sourcecodepro text-white rounded-l px-4 py-3 focus:outline-none pl-10"
             />
             <Image
               src="/assets/icons/search.svg"
               alt="Search Icon"
               width={20}
               height={20}
-              className="absolute left-2 -translate-y-1/2 top-1/2 "
+              className="absolute left-2 -translate-y-1/2 top-1/2"
             />
           </div>
         </form>
diff --git a/client/src/app/page.tsx b/client/src/app/page.tsx
index 6763ff9..2ed9302 100644
--- a/client/src/app/page.tsx
+++ b/client/src/app/page.tsx
@@ -5,7 +5,7 @@ import Navbar from "./components/Navbar";
 import Card from "./components/Card";
 import Footer from "./components/Footer";
 import GenerateStats from "./components/GenerateStats";
-import { useContext, useEffect, useState } from "react";
+import { useContext, useEffect, useState, useMemo } from "react";
 import PromotionCard from "./components/PromotionCard";
 import { DataContext } from "./context/DataContext";
 import { ToastContainer } from "react-toastify";
@@ -18,21 +18,62 @@ export default function Home() {
   const [loading, setLoading] = useState(true);
   const [showStats, setShowStats] = useState(false);
   const [sortBy, setSortBy] = useState("default");
+  const [pagination, setPagination] = useState({
+    currentPage: 1,
+    totalPages: 1,
+    totalItems: 0,
+    limit: 11,
+  });
+  const [searchTerm, setSearchTerm] = useState("");
+  const [debouncedSearch, setDebouncedSearch] = useState("");
 
-  const fetchData = async () => {
+  // Debounce search input to avoid too many requests
+  useEffect(() => {
+    const timer = setTimeout(() => {
+      setDebouncedSearch(search);
+    }, 500);
+
+    return () => clearTimeout(timer);
+  }, [search]);
+
+  // Reset pagination when search changes
+  useEffect(() => {
+    setPagination((prev) => ({ ...prev, currentPage: 1 }));
+  }, [debouncedSearch]);
+
+  const fetchData = async (page = 1) => {
     try {
-      const res = await fetch("/api/fetchdata");
-      const data = await res.json();
-      setDatas(data.data);
+      setLoading(true);
+      const queryParams = new URLSearchParams();
+
+      if (debouncedSearch) {
+        queryParams.append("search", debouncedSearch);
+      }
+
+      queryParams.append("page", page.toString());
+      queryParams.append("limit", pagination.limit.toString());
+      queryParams.append("sortBy", sortBy);
+
+      const res = await fetch(`/api/fetchdata?${queryParams.toString()}`);
+      const response = await res.json();
+
+      setDatas(response.data);
+      setPagination({
+        currentPage: response.pagination.page,
+        totalPages: response.pagination.totalPages,
+        totalItems: response.pagination.total,
+        limit: response.pagination.limit,
+      });
       setLoading(false);
     } catch (error) {
       console.error("Error fetching messages:", error);
+      setLoading(false);
     }
   };
 
   useEffect(() => {
-    fetchData();
-  }, [datas && datas.length]);
+    fetchData(pagination.currentPage);
+  }, [debouncedSearch, pagination.currentPage, pagination.limit, sortBy]);
 
   useEffect(() => {
     setTimeout(() => {
@@ -42,22 +83,13 @@ export default function Home() {
 
   const handleSortChange = (e: React.ChangeEvent<HTMLSelectElement>) => {
     setSortBy(e.target.value);
+    // Reset to first page when sorting changes
+    setPagination((prev) => ({ ...prev, currentPage: 1 }));
   };
 
-  const searchedData = datas?.filter((data: any) =>
-    data.profileData.fullName.toLowerCase().includes(search.toLowerCase())
-  );
-  const sorting = (data: any[]) => {
-    switch (sortBy) {
-      case "question-solved":
-        return data.slice().sort((a, b) => b.totalSolved - a.totalSolved);
-      case "default":
-      default:
-        return data.slice().sort((a, b) => {
-          return (
-            new Date(b.timeStamp).getTime() - new Date(a.timeStamp).getTime()
-          );
-        });
+  const handlePageChange = (newPage: number) => {
+    if (newPage > 0 && newPage <= pagination.totalPages) {
+      setPagination((prev) => ({ ...prev, currentPage: newPage }));
     }
   };
 
@@ -106,17 +138,80 @@ export default function Home() {
         <PromotionCard />
         {loading ? (
           <>
-            {Array.from({ length: 6 }, (_, i) => (
+            {Array.from({ length: 8 }, (_, i) => (
               <Skeleton key={i} />
             ))}
           </>
         ) : (
-          sorting(searchedData).map((userData: any, index: number) => (
-            <Card userData={userData} index={index} key={index} />
+          datas?.map((userData: any, index: number) => (
+            <Card
+              userData={userData}
+              index={index}
+              key={userData._id || index}
+            />
           ))
         )}
       </div>
 
+      {/* Pagination Controls */}
+      {!loading && pagination.totalPages > 1 && (
+        <div className="flex justify-center mt-12 mb-16 max-w-7xl mx-auto">
+          <div className="flex space-x-2 items-center font-sourcecodepro">
+            <button
+              onClick={() => handlePageChange(pagination.currentPage - 1)}
+              disabled={pagination.currentPage === 1}
+              className="px-4 py-2 rounded-md border border-gray-600 bg-[#0e0e0e] text-white disabled:opacity-50 disabled:cursor-not-allowed"
+            >
+              Previous
+            </button>
+
+            <div className="flex space-x-2">
+              {Array.from(
+                { length: Math.min(5, pagination.totalPages) },
+                (_, i) => {
+                  // Show 5 pages around current page
+                  let pageNum = 1;
+                  if (pagination.totalPages <= 5) {
+                    pageNum = i + 1;
+                  } else if (pagination.currentPage <= 3) {
+                    pageNum = i + 1;
+                  } else if (
+                    pagination.currentPage >=
+                    pagination.totalPages - 2
+                  ) {
+                    pageNum = pagination.totalPages - 4 + i;
+                  } else {
+                    pageNum = pagination.currentPage - 2 + i;
+                  }
+
+                  return (
+                    <button
+                      key={pageNum}
+                      onClick={() => handlePageChange(pageNum)}
+                      className={`w-10 h-10 rounded-md ${
+                        pagination.currentPage === pageNum
+                          ? "bg-gradient-to-r from-[#cb42b2] to-[#ecf576] text-black font-bold"
+                          : "border border-gray-600 bg-[#0e0e0e] text-white"
+                      }`}
+                    >
+                      {pageNum}
+                    </button>
+                  );
+                }
+              )}
+            </div>
+
+            <button
+              onClick={() => handlePageChange(pagination.currentPage + 1)}
+              disabled={pagination.currentPage === pagination.totalPages}
+              className="px-4 py-2 rounded-md border border-gray-600 bg-[#0e0e0e] text-white disabled:opacity-50 disabled:cursor-not-allowed"
+            >
+              Next
+            </button>
+          </div>
+        </div>
+      )}
+
       <Footer />
 
       <ToastContainer
diff --git a/client/src/pages/api/fetchdata.ts b/client/src/pages/api/fetchdata.ts
index 71e7717..29cd302 100644
--- a/client/src/pages/api/fetchdata.ts
+++ b/client/src/pages/api/fetchdata.ts
@@ -4,14 +4,56 @@ import UserData from "../../models/userdata";
 
 export default async function handler(req: any, res: any) {
   const { method } = req;
+  const { search, page = 1, limit = 11, sortBy = "default" } = req.query;
 
   await connectToDatabase();
 
   switch (method) {
     case "GET":
       try {
-        const messages = await UserData.find({});
-        res.status(200).json({ success: true, data: messages });
+        const pageNumber = parseInt(page as string);
+        const limitNumber = parseInt(limit as string);
+        const skip = (pageNumber - 1) * limitNumber;
+
+        // Build the query based on search parameter
+        let query = {};
+        if (search) {
+          query = {
+            "profileData.fullName": { $regex: search, $options: "i" },
+          };
+        }
+
+        // Determine sort options based on sortBy parameter
+        let sortOptions = {};
+        switch (sortBy) {
+          case "question-solved":
+            sortOptions = { totalSolved: -1 }; // -1 for descending order
+            break;
+          case "default":
+          default:
+            sortOptions = { timeStamp: -1 }; // Sort by timestamp descending (newest first)
+            break;
+        }
+
+        // Get total count for pagination
+        const totalItems = await UserData.countDocuments(query);
+
+        // Fetch data with pagination and sorting
+        const messages = await UserData.find(query)
+          .sort(sortOptions)
+          .skip(skip)
+          .limit(limitNumber);
+
+        res.status(200).json({
+          success: true,
+          data: messages,
+          pagination: {
+            total: totalItems,
+            page: pageNumber,
+            limit: limitNumber,
+            totalPages: Math.ceil(totalItems / limitNumber),
+          },
+        });
       } catch (error) {
         res.status(400).json({ success: false, error });
       }

From 79fc377350c7a2ea5bcca70871edb1d28bf7d9d4 Mon Sep 17 00:00:00 2001
From: druvkotwani <druvkotwani12@gmail.com>
Date: Sat, 8 Mar 2025 17:25:59 +0530
Subject: [PATCH 22/23] Add LeetCode profile sync functionality with admin UI
 and scheduled workflows

---
 .github/workflows/weekly-sync.yml       |  23 +++
 client/public/assets/icons/refresh.svg  |   1 +
 client/src/app/admin/sync/page.tsx      | 153 +++++++++++++++++
 client/src/app/api/cron/route.ts        |  49 ++++++
 client/src/app/page.tsx                 |  42 +++--
 client/src/pages/api/syncAllProfiles.ts | 211 ++++++++++++++++++++++++
 client/src/pages/api/syncProfile.ts     | 199 ++++++++++++++++++++++
 7 files changed, 665 insertions(+), 13 deletions(-)
 create mode 100644 .github/workflows/weekly-sync.yml
 create mode 100644 client/public/assets/icons/refresh.svg
 create mode 100644 client/src/app/admin/sync/page.tsx
 create mode 100644 client/src/app/api/cron/route.ts
 create mode 100644 client/src/pages/api/syncAllProfiles.ts
 create mode 100644 client/src/pages/api/syncProfile.ts

diff --git a/.github/workflows/weekly-sync.yml b/.github/workflows/weekly-sync.yml
new file mode 100644
index 0000000..2995f53
--- /dev/null
+++ b/.github/workflows/weekly-sync.yml
@@ -0,0 +1,23 @@
+name: Bi-Weekly LeetCode Profile Sync
+
+on:
+  schedule:
+    # Run every other Sunday at 00:00 UTC (every 2 weeks)
+    - cron: "0 0 */14 * *"
+
+  # Allow manual triggering
+  workflow_dispatch:
+
+jobs:
+  sync-profiles:
+    runs-on: ubuntu-latest
+
+    steps:
+      - name: Trigger Profile Sync
+        run: |
+          curl -X GET "${{ secrets.APP_URL }}/api/syncAllProfiles?secretKey=${{ secrets.SYNC_SECRET_KEY }}" \
+            -H "Content-Type: application/json" \
+            --fail
+        env:
+          APP_URL: ${{ secrets.APP_URL }}
+          SYNC_SECRET_KEY: ${{ secrets.SYNC_SECRET_KEY }}
diff --git a/client/public/assets/icons/refresh.svg b/client/public/assets/icons/refresh.svg
new file mode 100644
index 0000000..78c7f94
--- /dev/null
+++ b/client/public/assets/icons/refresh.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><g fill="none" stroke="#fff" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"><path stroke-dasharray="16" stroke-dashoffset="16" d="M12 3c4.97 0 9 4.03 9 9"><animate fill="freeze" attributeName="stroke-dashoffset" dur="0.3s" values="16;0"/><animateTransform attributeName="transform" dur="1.5s" repeatCount="indefinite" type="rotate" values="0 12 12;360 12 12"/></path><path stroke-dasharray="64" stroke-dashoffset="64" stroke-opacity="0.3" d="M12 3c4.97 0 9 4.03 9 9c0 4.97 -4.03 9 -9 9c-4.97 0 -9 -4.03 -9 -9c0 -4.97 4.03 -9 9 -9Z"><animate fill="freeze" attributeName="stroke-dashoffset" dur="1.2s" values="64;0"/></path></g></svg>
\ No newline at end of file
diff --git a/client/src/app/admin/sync/page.tsx b/client/src/app/admin/sync/page.tsx
new file mode 100644
index 0000000..6dcbb13
--- /dev/null
+++ b/client/src/app/admin/sync/page.tsx
@@ -0,0 +1,153 @@
+"use client";
+
+import React, { useState } from "react";
+import Link from "next/link";
+import Image from "next/image";
+import { useRouter } from "next/navigation";
+
+export default function AdminSync() {
+  const [isLoading, setIsLoading] = useState(false);
+  const [results, setResults] = useState<any>(null);
+  const [error, setError] = useState<string | null>(null);
+  const [secretKey, setSecretKey] = useState("");
+  const router = useRouter();
+
+  const handleSyncAll = async () => {
+    if (!secretKey) {
+      setError("Secret key is required");
+      return;
+    }
+
+    setIsLoading(true);
+    setError(null);
+
+    try {
+      const response = await fetch(
+        `/api/syncAllProfiles?secretKey=${secretKey}`
+      );
+      const data = await response.json();
+
+      if (!response.ok) {
+        throw new Error(data.message || "Failed to sync profiles");
+      }
+
+      setResults(data);
+    } catch (err: any) {
+      setError(err.message || "An error occurred while syncing profiles");
+    } finally {
+      setIsLoading(false);
+    }
+  };
+
+  return (
+    <section className="px-4 lg:px-24 py-24 min-h-screen bg-[#0e0e0e] text-white">
+      <div className="max-w-4xl mx-auto">
+        <div className="flex items-center mb-8">
+          <Link href="/" className="mr-4">
+            <Image
+              src="/assets/icons/leetcode.svg"
+              alt="Leetcode Logo"
+              width={36}
+              height={36}
+            />
+          </Link>
+          <h1 className="text-3xl font-bold font-sourcecodepro">
+            Admin: Profile Sync Tool
+          </h1>
+        </div>
+
+        <div className="bg-[#1a1a1a] p-6 rounded-lg border border-gray-700 mb-8">
+          <h2 className="text-xl font-bold mb-4 font-sourcecodepro">
+            Sync All LeetCode Profiles
+          </h2>
+          <p className="mb-6 text-gray-300">
+            This will update all profiles with the latest data from LeetCode.
+            This process may take several minutes depending on the number of
+            profiles.
+          </p>
+
+          <div className="mb-4">
+            <label className="block text-sm font-medium text-gray-300 mb-2">
+              Secret Key
+            </label>
+            <input
+              type="password"
+              value={secretKey}
+              onChange={(e) => setSecretKey(e.target.value)}
+              className="w-full p-2 bg-[#0e0e0e] border border-gray-700 rounded text-white"
+              placeholder="Enter secret key"
+            />
+            {error && <p className="mt-2 text-red-500">{error}</p>}
+          </div>
+
+          <button
+            onClick={handleSyncAll}
+            disabled={isLoading}
+            className={`px-4 py-2 rounded-md font-sourcecodepro font-bold ${
+              isLoading
+                ? "bg-gray-700 cursor-not-allowed"
+                : "bg-gradient-to-r from-[#cb42b2] to-[#ecf576] text-black hover:opacity-90"
+            } transition-all`}
+          >
+            {isLoading ? "Syncing..." : "Sync All Profiles"}
+          </button>
+        </div>
+
+        {results && (
+          <div className="bg-[#1a1a1a] p-6 rounded-lg border border-gray-700">
+            <h2 className="text-xl font-bold mb-4 font-sourcecodepro">
+              Sync Results
+            </h2>
+
+            <div className="flex mb-4 gap-4">
+              <div className="flex-1 p-4 bg-[#0e0e0e] rounded border border-gray-700">
+                <div className="text-4xl font-bold mb-2 text-center">
+                  {results.results.total}
+                </div>
+                <div className="text-center text-gray-300">Total Profiles</div>
+              </div>
+              <div className="flex-1 p-4 bg-[#0e0e0e] rounded border border-gray-700">
+                <div className="text-4xl font-bold mb-2 text-center text-green-500">
+                  {results.results.successful}
+                </div>
+                <div className="text-center text-gray-300">
+                  Successfully Updated
+                </div>
+              </div>
+              <div className="flex-1 p-4 bg-[#0e0e0e] rounded border border-gray-700">
+                <div className="text-4xl font-bold mb-2 text-center text-red-500">
+                  {results.results.failed}
+                </div>
+                <div className="text-center text-gray-300">Failed Updates</div>
+              </div>
+            </div>
+
+            {results.results.failures.length > 0 && (
+              <div>
+                <h3 className="text-lg font-bold mb-2 font-sourcecodepro">
+                  Failed Profiles:
+                </h3>
+                <ul className="list-disc pl-5 text-red-400">
+                  {results.results.failures.map(
+                    (username: string, idx: number) => (
+                      <li key={idx}>{username}</li>
+                    )
+                  )}
+                </ul>
+              </div>
+            )}
+
+            <div className="mt-6 flex justify-end">
+              <button
+                onClick={() => router.push("/")}
+                className="px-4 py-2 bg-[#0e0e0e] text-white rounded-md border border-gray-700 hover:bg-[#1f1f1f] transition-all"
+              >
+                Back to Home
+              </button>
+            </div>
+          </div>
+        )}
+      </div>
+    </section>
+  );
+}
diff --git a/client/src/app/api/cron/route.ts b/client/src/app/api/cron/route.ts
new file mode 100644
index 0000000..de9f736
--- /dev/null
+++ b/client/src/app/api/cron/route.ts
@@ -0,0 +1,49 @@
+import { NextRequest, NextResponse } from "next/server";
+
+export const config = {
+  runtime: "edge",
+  regions: ["iad1"], // specify a single region
+};
+
+// This defines a schedule for running once a week (Sunday at 00:00 UTC)
+export const dynamic = "force-dynamic";
+export const revalidate = 0;
+
+// Set the cron schedule to run monthly (1st day of each month at midnight)
+export const maxDuration = 300; // 5 minute maximum duration
+export const schedule = { cron: "0 0 1 * *" }; // Monthly at midnight on the 1st day
+
+export async function GET(request: NextRequest) {
+  try {
+    const secretKey = process.env.SYNC_SECRET_KEY || "your-default-secret-key";
+
+    // Call our sync API
+    const syncResponse = await fetch(
+      `${
+        process.env.NEXT_PUBLIC_BASE_URL || request.nextUrl.origin
+      }/api/syncAllProfiles?secretKey=${secretKey}`,
+      { method: "GET" }
+    );
+
+    const result = await syncResponse.json();
+
+    if (!result.success) {
+      console.error("Sync failed:", result);
+      return NextResponse.json(
+        { message: "Weekly sync failed", error: result },
+        { status: 500 }
+      );
+    }
+
+    return NextResponse.json({
+      message: "Weekly sync completed successfully",
+      result,
+    });
+  } catch (error) {
+    console.error("Error during scheduled sync:", error);
+    return NextResponse.json(
+      { message: "Error during weekly sync", error },
+      { status: 500 }
+    );
+  }
+}
diff --git a/client/src/app/page.tsx b/client/src/app/page.tsx
index 2ed9302..89234dd 100644
--- a/client/src/app/page.tsx
+++ b/client/src/app/page.tsx
@@ -112,26 +112,42 @@ export default function Home() {
       <GenerateStats showStats={showStats} setShowStats={setShowStats} />
 
       <div className="w-full max-w-7xl mx-auto flex flex-col lg:grid grid-cols-3 items-center justify-start gap-4 lg:gap-12 px-8 mt-28">
-        <Link
-          href="/worth"
-          className="flex w-fit  gap-2 rounded border-2 border-[#f7f7f7]  px-4 bg-gradient-to-r from-[#cb42b2] to-[#ecf576]  bg-clip-text text-transparent p-2 font-sourcecodepro font-bold"
-        >
-          <Image
-            src="/assets/icons/money.svg"
-            alt="Leetcode Logo"
-            width={24}
-            height={24}
-          />
-          LeetCode Worth
-        </Link>
+        <div className="flex flex-wrap gap-4">
+          <Link
+            href="/worth"
+            className="flex w-fit gap-2 rounded border-2 border-[#f7f7f7] px-4 bg-gradient-to-r from-[#cb42b2] to-[#ecf576] bg-clip-text text-transparent p-2 font-sourcecodepro font-bold"
+          >
+            <Image
+              src="/assets/icons/money.svg"
+              alt="Leetcode Logo"
+              width={24}
+              height={24}
+            />
+            LeetCode Worth
+          </Link>
+        </div>
         <select
           value={sortBy}
           onChange={handleSortChange}
-          className=" rounded border-2 border-[#f7f7f7]  w-64 bg-[#0e0e0e] text-white p-2 font-sourcecodepro"
+          className="rounded border-2 border-[#f7f7f7] w-64 bg-[#0e0e0e] text-white p-2 font-sourcecodepro"
         >
           <option value="default">Sort By Default</option>
           <option value="question-solved">Sort By Questions Solved</option>
         </select>
+        <div className="flex flex-wrap gap-4">
+          <Link
+            href="/admin/sync"
+            className="flex w-fit gap-2 rounded border-2 border-[#f7f7f7] px-4 bg-gradient-to-r from-[#3b82f6] to-[#22d3ee] bg-clip-text text-transparent p-2 font-sourcecodepro font-bold"
+          >
+            <Image
+              src="/assets/icons/refresh.svg"
+              alt="Sync Icon"
+              width={24}
+              height={24}
+            />
+            Sync Profiles
+          </Link>
+        </div>
       </div>
 
       <div className="mt-8  max-w-7xl mx-auto  place-items-center grid grid-cols-1 md:grid-cols-2 gap-y-8 xl:grid-cols-3 font-sourcecodepro gap-x-4">
diff --git a/client/src/pages/api/syncAllProfiles.ts b/client/src/pages/api/syncAllProfiles.ts
new file mode 100644
index 0000000..3412e03
--- /dev/null
+++ b/client/src/pages/api/syncAllProfiles.ts
@@ -0,0 +1,211 @@
+import connectToDatabase from "../../lib/mongodb";
+import UserData from "../../models/userdata";
+import axios from "axios";
+
+// Function to fetch updated data from LeetCode for a user (same as in syncProfile.ts)
+async function fetchLeetCodeData(username: string) {
+  try {
+    // LeetCode GraphQL API endpoint
+    const endpoint = "https://leetcode.com/graphql";
+
+    // GraphQL query to fetch user profile and stats
+    const query = `
+      query userPublicProfile($username: String!) {
+        matchedUser(username: $username) {
+          username
+          profile {
+            realName
+            userAvatar
+            ranking
+          }
+          submissionCalendar
+          submitStats {
+            acSubmissionNum {
+              difficulty
+              count
+              submissions
+            }
+            totalSubmissionNum {
+              difficulty
+              count
+              submissions
+            }
+          }
+          socialAccounts {
+            provider
+            profileUrl
+          }
+        }
+      }
+    `;
+
+    // Make the request to LeetCode API
+    const response = await axios.post(endpoint, {
+      query,
+      variables: { username },
+    });
+
+    const userData = response.data.data.matchedUser;
+
+    if (!userData) {
+      return null;
+    }
+
+    // Extract social accounts
+    const github = userData.socialAccounts.find(
+      (account: any) => account.provider === "GITHUB"
+    );
+    const twitter = userData.socialAccounts.find(
+      (account: any) => account.provider === "TWITTER"
+    );
+    const linkedin = userData.socialAccounts.find(
+      (account: any) => account.provider === "LINKEDIN"
+    );
+    const website = userData.socialAccounts.find(
+      (account: any) => account.provider === "WEBSITE"
+    );
+
+    // Extract submission stats
+    const totalSolved = userData.submitStats.acSubmissionNum.find(
+      (stat: any) => stat.difficulty === "All"
+    ).count;
+    const easySolved = userData.submitStats.acSubmissionNum.find(
+      (stat: any) => stat.difficulty === "Easy"
+    ).count;
+    const easyTotal = userData.submitStats.totalSubmissionNum.find(
+      (stat: any) => stat.difficulty === "Easy"
+    ).count;
+    const mediumSolved = userData.submitStats.acSubmissionNum.find(
+      (stat: any) => stat.difficulty === "Medium"
+    ).count;
+    const mediumTotal = userData.submitStats.totalSubmissionNum.find(
+      (stat: any) => stat.difficulty === "Medium"
+    ).count;
+    const hardSolved = userData.submitStats.acSubmissionNum.find(
+      (stat: any) => stat.difficulty === "Hard"
+    ).count;
+    const hardTotal = userData.submitStats.totalSubmissionNum.find(
+      (stat: any) => stat.difficulty === "Hard"
+    ).count;
+
+    // Format the data to match our schema
+    return {
+      profileData: {
+        image: userData.profile.userAvatar,
+        fullName: userData.profile.realName,
+        username: userData.username,
+        rank: userData.profile.ranking.toString(),
+      },
+      aboutData: {
+        github: {
+          link: github ? github.profileUrl : "",
+          text: github ? github.profileUrl.split("/").pop() : "",
+        },
+        twitter: {
+          link: twitter ? twitter.profileUrl : "",
+          text: twitter ? twitter.profileUrl.split("/").pop() : "",
+        },
+        linkedin: {
+          link: linkedin ? linkedin.profileUrl : "",
+          text: linkedin ? linkedin.profileUrl.split("/").pop() : "",
+        },
+        website: {
+          link: website ? website.profileUrl : "",
+          text: website ? website.profileUrl.split("/").pop() : "",
+        },
+      },
+      totalSolved,
+      easySolved,
+      easyTotal,
+      mediumSolved,
+      mediumTotal,
+      hardSolved,
+      hardTotal,
+      timeStamp: new Date(),
+    };
+  } catch (error) {
+    console.error(`Error fetching data for ${username}:`, error);
+    return null;
+  }
+}
+
+export default async function handler(req: any, res: any) {
+  const { method } = req;
+  const { secretKey } = req.query;
+
+  // Add a simple secret key check to prevent unauthorized access
+  const expectedSecretKey =
+    process.env.SYNC_SECRET_KEY || "your-default-secret-key";
+  if (secretKey !== expectedSecretKey) {
+    return res.status(401).json({ success: false, message: "Unauthorized" });
+  }
+
+  await connectToDatabase();
+
+  switch (method) {
+    case "GET":
+      try {
+        // Get all users from the database
+        const users = await UserData.find({});
+
+        if (!users || users.length === 0) {
+          return res
+            .status(404)
+            .json({ success: false, message: "No users found" });
+        }
+
+        const results = {
+          total: users.length,
+          successful: 0,
+          failed: 0,
+          failures: [] as string[],
+        };
+
+        // Process users with a delay between requests to avoid rate limiting
+        for (const user of users) {
+          try {
+            const username = user.profileData.username;
+            // Add a small delay to avoid overwhelming the LeetCode API
+            await new Promise((resolve) => setTimeout(resolve, 1000));
+
+            const updatedData = await fetchLeetCodeData(username);
+
+            if (!updatedData) {
+              results.failed++;
+              results.failures.push(username);
+              continue;
+            }
+
+            // Update the user data
+            await UserData.findOneAndUpdate(
+              { "profileData.username": username },
+              updatedData,
+              { new: true }
+            );
+
+            results.successful++;
+          } catch (error) {
+            console.error("Error updating user:", error);
+            results.failed++;
+            results.failures.push(user.profileData.username);
+          }
+        }
+
+        return res.status(200).json({
+          success: true,
+          message: `Sync completed. Total: ${results.total}, Successful: ${results.successful}, Failed: ${results.failed}`,
+          results,
+        });
+      } catch (error) {
+        console.error("Error syncing all profiles:", error);
+        return res
+          .status(500)
+          .json({ success: false, error: "Internal server error" });
+      }
+      break;
+
+    default:
+      res.status(405).json({ success: false, message: "Method not allowed" });
+      break;
+  }
+}
diff --git a/client/src/pages/api/syncProfile.ts b/client/src/pages/api/syncProfile.ts
new file mode 100644
index 0000000..80a29d0
--- /dev/null
+++ b/client/src/pages/api/syncProfile.ts
@@ -0,0 +1,199 @@
+import connectToDatabase from "../../lib/mongodb";
+import UserData from "../../models/userdata";
+import axios from "axios";
+
+// Function to fetch updated data from LeetCode for a user
+async function fetchLeetCodeData(username: string) {
+  try {
+    // LeetCode GraphQL API endpoint
+    const endpoint = "https://leetcode.com/graphql";
+
+    // GraphQL query to fetch user profile and stats
+    const query = `
+      query userPublicProfile($username: String!) {
+        matchedUser(username: $username) {
+          username
+          profile {
+            realName
+            userAvatar
+            ranking
+          }
+          submissionCalendar
+          submitStats {
+            acSubmissionNum {
+              difficulty
+              count
+              submissions
+            }
+            totalSubmissionNum {
+              difficulty
+              count
+              submissions
+            }
+          }
+          socialAccounts {
+            provider
+            profileUrl
+          }
+        }
+      }
+    `;
+
+    // Make the request to LeetCode API
+    const response = await axios.post(endpoint, {
+      query,
+      variables: { username },
+    });
+
+    const userData = response.data.data.matchedUser;
+
+    if (!userData) {
+      return null;
+    }
+
+    // Extract social accounts
+    const github = userData.socialAccounts.find(
+      (account: any) => account.provider === "GITHUB"
+    );
+    const twitter = userData.socialAccounts.find(
+      (account: any) => account.provider === "TWITTER"
+    );
+    const linkedin = userData.socialAccounts.find(
+      (account: any) => account.provider === "LINKEDIN"
+    );
+    const website = userData.socialAccounts.find(
+      (account: any) => account.provider === "WEBSITE"
+    );
+
+    // Extract submission stats
+    const totalSolved = userData.submitStats.acSubmissionNum.find(
+      (stat: any) => stat.difficulty === "All"
+    ).count;
+    const easySolved = userData.submitStats.acSubmissionNum.find(
+      (stat: any) => stat.difficulty === "Easy"
+    ).count;
+    const easyTotal = userData.submitStats.totalSubmissionNum.find(
+      (stat: any) => stat.difficulty === "Easy"
+    ).count;
+    const mediumSolved = userData.submitStats.acSubmissionNum.find(
+      (stat: any) => stat.difficulty === "Medium"
+    ).count;
+    const mediumTotal = userData.submitStats.totalSubmissionNum.find(
+      (stat: any) => stat.difficulty === "Medium"
+    ).count;
+    const hardSolved = userData.submitStats.acSubmissionNum.find(
+      (stat: any) => stat.difficulty === "Hard"
+    ).count;
+    const hardTotal = userData.submitStats.totalSubmissionNum.find(
+      (stat: any) => stat.difficulty === "Hard"
+    ).count;
+
+    // Format the data to match our schema
+    return {
+      profileData: {
+        image: userData.profile.userAvatar,
+        fullName: userData.profile.realName,
+        username: userData.username,
+        rank: userData.profile.ranking.toString(),
+      },
+      aboutData: {
+        github: {
+          link: github ? github.profileUrl : "",
+          text: github ? github.profileUrl.split("/").pop() : "",
+        },
+        twitter: {
+          link: twitter ? twitter.profileUrl : "",
+          text: twitter ? twitter.profileUrl.split("/").pop() : "",
+        },
+        linkedin: {
+          link: linkedin ? linkedin.profileUrl : "",
+          text: linkedin ? linkedin.profileUrl.split("/").pop() : "",
+        },
+        website: {
+          link: website ? website.profileUrl : "",
+          text: website ? website.profileUrl.split("/").pop() : "",
+        },
+      },
+      totalSolved,
+      easySolved,
+      easyTotal,
+      mediumSolved,
+      mediumTotal,
+      hardSolved,
+      hardTotal,
+      timeStamp: new Date(),
+    };
+  } catch (error) {
+    console.error(`Error fetching data for ${username}:`, error);
+    return null;
+  }
+}
+
+export default async function handler(req: any, res: any) {
+  const { method } = req;
+  const { username, secretKey } = req.query;
+
+  // Add a simple secret key check to prevent unauthorized access
+  const expectedSecretKey =
+    process.env.SYNC_SECRET_KEY || "your-default-secret-key";
+  if (secretKey !== expectedSecretKey) {
+    return res.status(401).json({ success: false, message: "Unauthorized" });
+  }
+
+  await connectToDatabase();
+
+  switch (method) {
+    case "GET":
+      try {
+        // If username is provided, sync only that user
+        if (username) {
+          const user = await UserData.findOne({
+            "profileData.username": username,
+          });
+
+          if (!user) {
+            return res
+              .status(404)
+              .json({ success: false, message: "User not found" });
+          }
+
+          const updatedData = await fetchLeetCodeData(username);
+
+          if (!updatedData) {
+            return res.status(400).json({
+              success: false,
+              message: "Failed to fetch updated data",
+            });
+          }
+
+          // Update the user data
+          await UserData.findOneAndUpdate(
+            { "profileData.username": username },
+            updatedData,
+            { new: true }
+          );
+
+          return res.status(200).json({
+            success: true,
+            message: `Successfully synced profile for ${username}`,
+          });
+        }
+        // If no username is provided, return error
+        else {
+          return res
+            .status(400)
+            .json({ success: false, message: "Username is required" });
+        }
+      } catch (error) {
+        console.error("Error syncing profile:", error);
+        return res
+          .status(500)
+          .json({ success: false, error: "Internal server error" });
+      }
+      break;
+
+    default:
+      res.status(405).json({ success: false, message: "Method not allowed" });
+      break;
+  }
+}

From 33b1639d7fa7e76e681b59dc55f10f2c424bf3e3 Mon Sep 17 00:00:00 2001
From: druvkotwani <druvkotwani12@gmail.com>
Date: Sat, 8 Mar 2025 17:32:47 +0530
Subject: [PATCH 23/23] Update cron route configuration for monthly sync and
 Next.js App Router

---
 client/src/app/api/cron/route.ts | 32 ++++++++++++--------------------
 vercel.json                      |  8 ++++++++
 2 files changed, 20 insertions(+), 20 deletions(-)
 create mode 100644 vercel.json

diff --git a/client/src/app/api/cron/route.ts b/client/src/app/api/cron/route.ts
index de9f736..6465c1a 100644
--- a/client/src/app/api/cron/route.ts
+++ b/client/src/app/api/cron/route.ts
@@ -1,26 +1,18 @@
-import { NextRequest, NextResponse } from "next/server";
-
-export const config = {
-  runtime: "edge",
-  regions: ["iad1"], // specify a single region
-};
-
-// This defines a schedule for running once a week (Sunday at 00:00 UTC)
-export const dynamic = "force-dynamic";
-export const revalidate = 0;
-
-// Set the cron schedule to run monthly (1st day of each month at midnight)
-export const maxDuration = 300; // 5 minute maximum duration
-export const schedule = { cron: "0 0 1 * *" }; // Monthly at midnight on the 1st day
-
-export async function GET(request: NextRequest) {
+import { NextResponse } from "next/server";
+
+/**
+ * This route is called by Vercel Cron Jobs
+ * Cron configuration is set in vercel.json at the project root
+ * Schedule: Monthly at midnight on the 1st day of each month
+ */
+export async function GET() {
   try {
     const secretKey = process.env.SYNC_SECRET_KEY || "your-default-secret-key";
 
     // Call our sync API
     const syncResponse = await fetch(
       `${
-        process.env.NEXT_PUBLIC_BASE_URL || request.nextUrl.origin
+        process.env.NEXT_PUBLIC_BASE_URL || "https://your-app-url.com"
       }/api/syncAllProfiles?secretKey=${secretKey}`,
       { method: "GET" }
     );
@@ -30,19 +22,19 @@ export async function GET(request: NextRequest) {
     if (!result.success) {
       console.error("Sync failed:", result);
       return NextResponse.json(
-        { message: "Weekly sync failed", error: result },
+        { message: "Monthly sync failed", error: result },
         { status: 500 }
       );
     }
 
     return NextResponse.json({
-      message: "Weekly sync completed successfully",
+      message: "Monthly sync completed successfully",
       result,
     });
   } catch (error) {
     console.error("Error during scheduled sync:", error);
     return NextResponse.json(
-      { message: "Error during weekly sync", error },
+      { message: "Error during monthly sync", error },
       { status: 500 }
     );
   }
diff --git a/vercel.json b/vercel.json
new file mode 100644
index 0000000..d50050d
--- /dev/null
+++ b/vercel.json
@@ -0,0 +1,8 @@
+{
+  "crons": [
+    {
+      "path": "/api/cron",
+      "schedule": "0 0 1 * *"
+    }
+  ]
+}