diff --git a/backend/src/note/note.controller.ts b/backend/src/note/note.controller.ts
index 1a1a19e44a7c6b7a7d38090aeab3fa5bceed8976..a2f225b7f4b3e1e5763da0c13b7f08619f18800c 100644
--- a/backend/src/note/note.controller.ts
+++ b/backend/src/note/note.controller.ts
@@ -10,7 +10,7 @@ export class NoteController {
     private voterService: VoterService,
   ) {}
   @Get('/all')
-  async getAllNotes(@Query('stakeKeys') stakeKeys?: any, @Query('beforeNoteCursor') beforeNote?: number, @Query('afterNoteCursor') afterNote?: number) {
+  async getAllNotes(@Query('stakeKeys') stakeKeys?: any, @Query('currentNoteCursor') currentNote?: number, @Query('request') request?: string) {
     const { stakeKey, stakeKeyBech32 } = stakeKeys || {};
 
     let delegation = null;
@@ -20,7 +20,7 @@ export class NoteController {
         await this.voterService.getAdaHolderCurrentDelegation(stakeKey);
     }
 
-    return this.noteService.getAllNotes(stakeKeyBech32, delegation,beforeNote, afterNote);
+    return this.noteService.getAllNotes(stakeKeyBech32, delegation,currentNote, request);
   }
   @Get('/:id/single')
   getSingleNote(@Param('id') noteId: string) {
diff --git a/backend/src/note/note.service.ts b/backend/src/note/note.service.ts
index 959b39aabe53d99ca471463fd27f8355d74c80b9..67b94c4aedd86c37ee3eb159ed6f35854c7315c5 100644
--- a/backend/src/note/note.service.ts
+++ b/backend/src/note/note.service.ts
@@ -17,12 +17,17 @@ export class NoteService {
     private reactionsService: ReactionsService,
     private commentsService: CommentsService,
   ) {}
-  async getAllNotes(stakeKeyBech32?: string, delegation?: Delegation,beforeNote?: number, afterNote?: number) {
+  async getAllNotes(
+    stakeKeyBech32?: string,
+    delegation?: Delegation,
+    currentNote?: number,
+    request?: string,
+  ) {
     let allNotes = await this.getNotesWithVisibility(
       delegation,
       stakeKeyBech32,
-      beforeNote,
-      afterNote
+      currentNote,
+      request,
     );
 
     // Used Promise.all to ensure all asynchronous operations complete
@@ -41,8 +46,8 @@ export class NoteService {
         return { ...note, reactions: reactions, comments: comments };
       }),
     );
-    
-    return allNotes
+
+    return allNotes;
   }
 
   async getSingleNote(noteId: string) {
@@ -92,7 +97,12 @@ export class NoteService {
     }
   }
 
-  private async getNotesWithVisibility(delegation?, stakeKeyBech32?: string, beforeNote?: number, afterNote?: number) {
+  private async getNotesWithVisibility(
+    delegation?,
+    stakeKeyBech32?: string,
+    currentNote?: number,
+    request?: string,
+  ) {
     const queryBuilder = this.voltaireService
       .getRepository('Note')
       .createQueryBuilder('note')
@@ -104,13 +114,17 @@ export class NoteService {
     queryBuilder.where('note.note_visibility = :everyone', {
       everyone: 'everyone',
     });
-    if (beforeNote) {
-     queryBuilder.where('note.id > :beforeNote', { beforeNote });
-    }
-    if (afterNote) {
-     queryBuilder.where('note.id < :afterNote', { afterNote });
+    if (currentNote) {
+      console.log(request);
+      if (request === 'before') {
+        queryBuilder.where('note.id <= :currentNote', { currentNote: Number(currentNote) });
+      } else if (request === 'after') {
+        queryBuilder.where('note.id <= :currentNote', {
+          currentNote: Number(currentNote) + 20,
+        });
+      }
     }
-    
+
     // 'delegators' visibility
     if (delegation) {
       queryBuilder.orWhere(
diff --git a/frontend/package.json b/frontend/package.json
index f2f9734bda2fb3b1420d254cd256fbdea75122ca..ef09ad57172e81e2ed354a842488eb3782c74f1a 100644
--- a/frontend/package.json
+++ b/frontend/package.json
@@ -59,8 +59,8 @@
     "react": "^18",
     "react-copy-to-clipboard": "^5.1.0",
     "react-dom": "^18",
+    "react-easy-infinite-scroll-hook": "^2.1.4",
     "react-hook-form": "^7.51.3",
-    "react-infinite-scroll-component": "^6.1.0",
     "react-query": "^3.39.3",
     "use-debounce": "^10.0.1",
     "zod": "^3.23.4"
diff --git a/frontend/src/app/[locale]/dreps/[drepid]/delegators/page.tsx b/frontend/src/app/[locale]/dreps/[drepid]/delegators/page.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..d6b481724ba132e33aa10a7e3bc7fd8aade30e9b
--- /dev/null
+++ b/frontend/src/app/[locale]/dreps/[drepid]/delegators/page.tsx
@@ -0,0 +1,13 @@
+'use client';
+import DrepProfileMetrics from '@/components/molecules/DrepProfileMetrics';
+import { useGetSingleDRepQuery } from '@/hooks/useGetSingleDRepQuery';
+import { useParams } from 'next/navigation';
+
+const DelegatorsPage = () => {
+  const { drepid } = useParams();
+  const { dRep } = useGetSingleDRepQuery(drepid);
+
+  return <DrepProfileMetrics drepMetrics={dRep} />;
+};
+
+export default DelegatorsPage;
\ No newline at end of file
diff --git a/frontend/src/app/[locale]/dreps/[drepid]/layout.tsx b/frontend/src/app/[locale]/dreps/[drepid]/layout.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..695e8bde4d7897244ce575da37b8130c19c4cfd4
--- /dev/null
+++ b/frontend/src/app/[locale]/dreps/[drepid]/layout.tsx
@@ -0,0 +1,51 @@
+'use client';
+import DRepProfileBar from '@/components/atoms/DrepProfileBar';
+import DrepTabGroup from '@/components/atoms/DrepTabGroup';
+import { useState } from 'react';
+import { IconButton } from '@mui/material';
+import { useCardano } from '@/context/walletContext';
+import { useGetSingleDRepQuery } from '@/hooks/useGetSingleDRepQuery';
+import { useParams } from 'next/navigation';
+
+export default function Layout({ children }: { children: React.ReactNode }) {
+  const { dRepIDBech32 } = useCardano();
+  const [isOpen, setIsOpen] = useState(false);
+  const { drepid } = useParams();
+  const { dRep, isDRepLoading } = useGetSingleDRepQuery(drepid);
+
+  return (
+    <div className="flex">
+      {/* If current user is a drep, the drawer will be available for use */}
+      {dRep?.drep_id && dRep?.cexplorerDetails?.view == dRepIDBech32 && (
+        <DRepProfileBar isOpen={isOpen} setIsOpen={setIsOpen} />
+      )}
+      <div className="base_container w-full">
+        <div className="flex h-full w-full flex-col">
+          <div className="flex items-center justify-start">
+            <div className="w-[30%]">
+              {dRep?.drep_id &&
+                dRep?.cexplorerDetails?.view == dRepIDBech32 && (
+                  <IconButton
+                    data-testid="close-drawer-button"
+                    onClick={() => {
+                      setIsOpen(!isOpen);
+                    }}
+                  >
+                    <img
+                      width={'50%'}
+                      className="shrink-0"
+                      src={'/svgs/menu.svg'}
+                    />
+                  </IconButton>
+                )}
+            </div>
+            <div className="w-[70%]">
+              <DrepTabGroup drepId={drepid as string}/>
+            </div>
+          </div>
+          {children}
+        </div>
+      </div>
+    </div>
+  );
+}
\ No newline at end of file
diff --git a/frontend/src/app/[locale]/dreps/[drepid]/page.tsx b/frontend/src/app/[locale]/dreps/[drepid]/page.tsx
index 3fcf5a205495231ad20d5a9ed9eed60b6c184b50..5b7dd8b4b1cfc885b001e15254cc4500d747713a 100644
--- a/frontend/src/app/[locale]/dreps/[drepid]/page.tsx
+++ b/frontend/src/app/[locale]/dreps/[drepid]/page.tsx
@@ -1,80 +1,38 @@
 'use client';
-import DRepProfileBar from '@/components/atoms/DrepProfileBar';
 import DrepProfileCard from '@/components/atoms/DrepProfileCard';
-import DrepTabGroup from '@/components/atoms/DrepTabGroup';
-import { Suspense, useState } from 'react';
-import { IconButton } from '@mui/material';
+import { Suspense } from 'react';
 import DrepTimeline from '@/components/molecules/DrepTimeline';
-import DrepProfileMetrics from '@/components/molecules/DrepProfileMetrics';
-import { useParams } from 'next/navigation';
-import DrepClaimProfileCard from '@/components/atoms/DrepClaimProfileCard';
 import { useCardano } from '@/context/walletContext';
 import { useGetSingleDRepQuery } from '@/hooks/useGetSingleDRepQuery';
+import { useParams } from 'next/navigation';
+import DrepClaimProfileCard from '@/components/atoms/DrepClaimProfileCard';
 
 const page = () => {
-  const [currentTab, setCurrentTab] = useState('profile');
-  const { latestEpoch, dRepIDBech32 } = useCardano();
-  const [isOpen, setIsOpen] = useState(false);
+  const { latestEpoch } = useCardano();
   const { drepid } = useParams();
   const { dRep, isDRepLoading } = useGetSingleDRepQuery(drepid);
 
   return (
-    <div className="flex">
-      {/* If current user is a drep, the drawer will be available for use */}
-      {dRep?.drep_id && dRep?.cexplorerDetails?.view == dRepIDBech32 && (
-        <DRepProfileBar isOpen={isOpen} setIsOpen={setIsOpen} />
-      )}
-      <div className="base_container w-full">
-        <div className="flex h-full w-full flex-col">
-          <div className="flex items-center justify-start">
-            <div className="w-[30%]">
-              {dRep?.drep_id &&
-                dRep?.cexplorerDetails?.view == dRepIDBech32 && (
-                  <IconButton
-                    data-testid="close-drawer-button"
-                    onClick={() => {
-                      setIsOpen(!isOpen);
-                    }}
-                  >
-                    <img
-                      width={'50%'}
-                      className="shrink-0"
-                      src={'/svgs/menu.svg'}
-                    />
-                  </IconButton>
-                )}
-            </div>
-            <div className="w-[70%]">
-              <DrepTabGroup setActiveTab={setCurrentTab} />
-            </div>
-          </div>
-          {currentTab === 'profile' ? (
-            <div className="flex flex-col lg:flex-row">
-              <div className="lg:w-[30%]">
-                {dRep?.drep_id ? (
-                  <DrepProfileCard drep={dRep} state={isDRepLoading} />
-                ) : (
-                  <DrepClaimProfileCard drep={dRep} state={isDRepLoading} />
-                )}
-              </div>
-              <div className="lg:w-[70%]">
-                <Suspense>
-                <DrepTimeline
-                  drepId={dRep?.drep_id || dRep?.cexplorerDetails?.view}
-                  latestEpoch={latestEpoch}
-                  cexplorerDetails={dRep?.cexplorerDetails}
-                  activity={dRep?.activity}
-                />
-                </Suspense>
-              </div>
-            </div>
-          ) : (
-            <DrepProfileMetrics drepMetrics={dRep} />
-          )}
-        </div>
+    <div className="flex flex-col lg:flex-row">
+      <div className="lg:w-[30%]">
+        {dRep?.drep_id ? (
+          <DrepProfileCard drep={dRep} state={isDRepLoading} />
+        ) : (
+          <DrepClaimProfileCard drep={dRep} state={isDRepLoading} />
+        )}
+      </div>
+      <div className="lg:w-[70%]">
+        <Suspense>
+          <DrepTimeline
+            drepId={dRep?.drep_id || dRep?.cexplorerDetails?.view}
+            latestEpoch={latestEpoch}
+            cexplorerDetails={dRep?.cexplorerDetails}
+            activity={dRep?.activity}
+          />
+        </Suspense>
       </div>
     </div>
   );
 };
 
-export default page;
+export default page;
\ No newline at end of file
diff --git a/frontend/src/components/atoms/DrepTabGroup.tsx b/frontend/src/components/atoms/DrepTabGroup.tsx
index ca89b03a8e9eedf068d2ef24d2b2979007e686e7..b8b2e5928c82529b8a4acbf92c249070788b6416 100644
--- a/frontend/src/components/atoms/DrepTabGroup.tsx
+++ b/frontend/src/components/atoms/DrepTabGroup.tsx
@@ -1,15 +1,28 @@
-import React, { useState } from 'react';
+import { usePathname, useRouter } from 'next/navigation';
+import React, { useEffect, useState } from 'react';
 
-const DrepTabGroup = ({setActiveTab}:{setActiveTab:Function}) => {
+const DrepTabGroup = ({ drepId }: { drepId: string }) => {
   const [active, setActive] = useState('profile');
+  const router = useRouter();
+  const pathname = usePathname();
   const activeClasses =
     'bg-white border-b-2 border-b-blue-800 rounded-t-lg text-blue-800 ';
-  const inactiveClasses = 'bg-white bg-opacity-40 rounded-t-lg text-gray-400 hover:text-gray-800 cursor-pointer';
+  const inactiveClasses =
+    'bg-white bg-opacity-40 rounded-t-lg text-gray-400 hover:text-gray-800 cursor-pointer';
 
   const handleClick = (id) => {
-    setActive(id);
-    setActiveTab(id);
+    if (id === 'profile') {
+      router.push(`/dreps/${drepId}`);
+    }
+    if (id === 'delegators') {
+      router.push(`/dreps/${drepId}/delegators`);
+    }
   };
+  useEffect(() => {
+    if (pathname.includes(`/dreps/${drepId}/delegators`)) {
+      setActive('delegators');
+    } else setActive('profile');
+  }, [pathname]);
   return (
     <div className="flex items-center gap-1 overflow-x-auto">
       <div
@@ -20,11 +33,11 @@ const DrepTabGroup = ({setActiveTab}:{setActiveTab:Function}) => {
         <p>Profile</p>
       </div>
       <div
-        id="metrics"
-        className={`px-16 py-4 ${active === 'metrics' ? activeClasses : inactiveClasses}`}
-        onClick={() => handleClick('metrics')}
+        id="delegators"
+        className={`px-16 py-4 ${active === 'delegators' ? activeClasses : inactiveClasses}`}
+        onClick={() => handleClick('delegators')}
       >
-        <p>Metrics</p>
+        <p>Delegators</p>
       </div>
     </div>
   );
diff --git a/frontend/src/components/dreps/notes/NotesPage.tsx b/frontend/src/components/dreps/notes/NotesPage.tsx
index 82a20dadecc34547baf1ec8ff8189aeddcad8db8..6dcc4ec54d088b1a8e3efe0069eb66e6796f766d 100644
--- a/frontend/src/components/dreps/notes/NotesPage.tsx
+++ b/frontend/src/components/dreps/notes/NotesPage.tsx
@@ -3,12 +3,11 @@ import { useEffect, useState, useRef, useCallback } from 'react';
 import { useRouter, useSearchParams } from 'next/navigation';
 import SingleNote from './SingleNote';
 import NotesPageHeader from './NotesPageHeader';
-import { Skeleton } from '@mui/material';
+import { CircularProgress, List, Skeleton } from '@mui/material';
 import { useCardano } from '@/context/walletContext';
 import { useDRepContext } from '@/context/drepContext';
 import { useGetNotesQuery } from '@/hooks/useGetNotesQuery';
-import InfiniteScroll from 'react-infinite-scroll-component';
-
+import useInfiniteScroll from 'react-easy-infinite-scroll-hook';
 const LoaderComponent = () => {
   return Array.from({ length: 4 }).map((_, index) => (
     <div
@@ -28,18 +27,33 @@ function NotesPage() {
   const searchParams = useSearchParams();
   const { stakeKeyBech32, isEnabled } = useCardano();
   const { isLoggedIn } = useDRepContext();
-  const [lastNoteID, setLastNoteID] = useState<number | undefined>(undefined);
   const [dominantNoteId, setDominantNoteId] = useState<number | undefined>(
     undefined,
   );
+  const [currentNoteId, setCurrentNoteId] = useState<number | undefined>(
+    undefined,
+  );
+  const [request, setRequest] = useState<'before' | 'after'>('before');
+  const [prevScrollTop, setPrevScrollTop] = useState(0);
+  const [scrollDirection, setScrollDirection] = useState(null);
   const [allNotes, setAllNotes] = useState<any[]>([]);
-  const [hasMore, setHasMore] = useState(true);
   const noteRefs = useRef<{ [key: number]: HTMLDivElement | null }>({});
-
+  const [hasMoreBelow, setHasMoreBelow] = useState(true);
+  const [hasMoreAbove, setHasMoreAbove] = useState(true);
   const { Notes, isNotesLoading, isNotesFetching, isPreviousData } =
     useGetNotesQuery({
-      afterNote:lastNoteID,
+      currentNote: currentNoteId,
+      request: request,
     });
+  useEffect(() => {
+    if (allNotes && allNotes.length > 0) {
+      const topMostNote = allNotes[0];
+      if (!dominantNoteId) {
+        setDominantNoteId(topMostNote.note_id);
+        updateURL(topMostNote.note_id.toString());
+      }
+    }
+  }, [allNotes, dominantNoteId]);
 
   useEffect(() => {
     if (Notes && !isPreviousData) {
@@ -51,21 +65,32 @@ function NotesPage() {
 
         // Convert the Map values back to an array
         const uniqueNotes = Array.from(uniqueNotesMap.values());
-
+        uniqueNotes.sort((a, b) => b.note_id - a.note_id);
         // Sort notes by note_id in descending order (assuming higher IDs are more recent)
         return uniqueNotes;
       });
-      setHasMore(Notes.length > 0);
+      if (scrollDirection === 'down') {
+        setHasMoreBelow(Notes.length > 1);
+      } else if (scrollDirection === 'up') {
+        setHasMoreAbove(Notes.length > 1);
+      }
     }
   }, [Notes, isPreviousData]);
-
+  const ref = useInfiniteScroll({
+    next: async (scrollDirection) => fetchMoreData(),
+    rowCount: allNotes.length,
+    hasMore: { down: hasMoreBelow, up: hasMoreAbove },
+    onScroll: (event) => {
+      handleScroll(event);
+      updateDominantNote();
+    },
+  });
   useEffect(() => {
     const urlNote = searchParams.get('note');
     if (urlNote) {
-      setLastNoteID(Number(urlNote));
+      setCurrentNoteId(Number(urlNote));
     }
   }, []);
-
   const updateDominantNote = useCallback(() => {
     if (allNotes && allNotes.length > 0) {
       const windowHeight = window.innerHeight;
@@ -91,65 +116,71 @@ function NotesPage() {
       }
     }
   }, [allNotes, dominantNoteId]);
-
-  useEffect(() => {
-    if (allNotes && allNotes.length > 0) {
-      const topMostNote = allNotes[0];
-      if (!dominantNoteId) {
-        setDominantNoteId(topMostNote.note_id);
-        updateURL(topMostNote.note_id.toString());
-      }
-    }
-  }, [allNotes, dominantNoteId]);
+  const handleScroll = useCallback(
+    (event) => {
+      const currentScrollTop = event.scrollTop;
+      const isScrollingDown = currentScrollTop > prevScrollTop;
+      setScrollDirection(isScrollingDown ? 'down' : 'up');
+      setPrevScrollTop(currentScrollTop);
+    },
+    [prevScrollTop],
+  );
 
   const updateURL = (noteId?: string) => {
     const params = new URLSearchParams(searchParams);
     if (noteId) params.set('note', noteId);
     router.replace(`?${params.toString()}`, { scroll: false });
   };
+  const fetchMoreDataDown = useCallback(() => {
+    if (!isNotesFetching && !isPreviousData && allNotes.length > 0) {
+      setCurrentNoteId(allNotes[allNotes.length - 1].note_id);
+      setRequest('before');
+    }
+  }, [isNotesFetching, allNotes]);
 
+  const fetchMoreDataUp = useCallback(() => {
+    if (!isNotesFetching && !isPreviousData) {
+      setCurrentNoteId(allNotes[0].note_id);
+      setRequest('after');
+    }
+  }, [isNotesFetching, allNotes]);
   const fetchMoreData = useCallback(() => {
-    if (!isNotesFetching && !isPreviousData && hasMore) {
-      if (allNotes && allNotes.length > 0) {
-        const lastNote = allNotes[allNotes.length - 1];
-        if (lastNote.note_id !== lastNoteID) {
-          setLastNoteID(lastNote.note_id);
-        }
-      }
+    if (scrollDirection === 'down') {
+      fetchMoreDataDown();
+    } else if (scrollDirection === 'up') {
+      fetchMoreDataUp();
     }
-  }, [isNotesFetching, isPreviousData, hasMore, allNotes, lastNoteID]);
-  if (isNotesLoading) {
-    // first render
-    return (
-      <div className="flex min-h-screen flex-col gap-5 bg-white bg-opacity-50 px-5 py-10">
-        <NotesPageHeader />
-        <LoaderComponent />
-      </div>
-    );
-  }
-
+  }, [scrollDirection]);
   return (
-    <div className="flex min-h-screen flex-col gap-5 bg-white bg-opacity-50 px-5 py-10">
+    <div className="flex h-screen flex-col gap-5 bg-white bg-opacity-50 px-5 py-10">
       <NotesPageHeader />
-      <InfiniteScroll
-        onScroll={updateDominantNote}
-        dataLength={allNotes.length}
-
-        next={fetchMoreData}
-        hasMore={hasMore}
-        loader={<LoaderComponent />}
-        endMessage={<p className="text-center">You've caught up!</p>}
-        scrollThreshold="200px"
-        className="flex flex-col gap-5 pt-5"
+      <List
+        id="scrollableDiv"
+        ref={ref as any}
+        style={{
+          height: 1000,
+          overflow: 'auto',
+          display: 'flex',
+          flexDirection: 'column',
+          gap: '2rem',
+        }}
       >
-        {Array.from(new Set(allNotes.map((note) => note.note_id))).map(
-          (noteId) => {
-            const note = allNotes.find((n) => n.note_id === noteId);
+        {isNotesFetching && scrollDirection === 'up' && (
+          <div className="flex items-center justify-center">
+            <CircularProgress size={40} />
+          </div>
+        )}
+        {isNotesLoading ? (
+          <LoaderComponent />
+        ) : (
+          allNotes &&
+          allNotes.length > 0 &&
+          allNotes.map((note) => {
             return (
               <div
-                key={noteId}
+                key={note.note_id}
                 className="w-full"
-                ref={(el: any) => (noteRefs.current[noteId] = el)}
+                ref={(el: any) => (noteRefs.current[note.note_id] = el)}
               >
                 <SingleNote
                   note={note}
@@ -159,10 +190,11 @@ function NotesPage() {
                 />
               </div>
             );
-          },
+          })
         )}
+        {isNotesFetching && scrollDirection === 'down' && <LoaderComponent />}
         {allNotes.length === 0 && !isNotesLoading && <p>No notes</p>}
-      </InfiniteScroll>
+      </List>
     </div>
   );
 }
diff --git a/frontend/src/components/dreps/notes/SingleNote.tsx b/frontend/src/components/dreps/notes/SingleNote.tsx
index 2a701b3b2269862338865b619da39349b75544f5..f84ac736579b403482fa9ead9d7f7cc89948ed70 100644
--- a/frontend/src/components/dreps/notes/SingleNote.tsx
+++ b/frontend/src/components/dreps/notes/SingleNote.tsx
@@ -279,7 +279,6 @@ const SingleNote = ({
         </div>
         <div className="flex gap-5">
           {Object.keys(reactionIcons).map((type) => {
-            console.log(currentReactions)
             return (
               <div
                 key={type}
diff --git a/frontend/src/components/molecules/DrepTimeline.tsx b/frontend/src/components/molecules/DrepTimeline.tsx
index 311bf383bb243f5081e38a5aea2d5d618abfee02..94b52494a4c212ee39a2313d2810f739bb6d9d38 100644
--- a/frontend/src/components/molecules/DrepTimeline.tsx
+++ b/frontend/src/components/molecules/DrepTimeline.tsx
@@ -2,13 +2,14 @@
 import React, { useCallback, useEffect, useState } from 'react';
 import DrepTimelineWaterfall from './DrepTimelineWaterfall';
 import Link from 'next/link';
-import InfiniteScroll from 'react-infinite-scroll-component';
+import useInfiniteScroll from 'react-easy-infinite-scroll-hook';
 
 import Button from '../atoms/Button';
 import { useCardano } from '@/context/walletContext';
 import { useRouter, useSearchParams } from 'next/navigation';
 import { getSingleDRep } from '@/services/requests/getSingleDrep';
 import { getSingleDRepViaVoterId } from '@/services/requests/getSingleDrepViaVoterId';
+import { CircularProgress } from '@mui/material';
 const ProfileClaimedChip = ({ claimedAddress }) => {
   return (
     <div className="flex flex-col gap-1 rounded-xl bg-yellow-500 px-3 py-2 ">
@@ -38,12 +39,16 @@ const DrepTimeline = ({
 }) => {
   const [searchText, setSearchText] = useState('');
   const [allActivities, setAllActivities] = useState(activity || []);
-  const [hasMore, setHasMore] = useState(true);
+  const [hasMoreBelow, setHasMoreBelow] = useState(true);
+  const [hasMoreAbove, setHasMoreAbove] = useState(true);
+  const [prevScrollTop, setPrevScrollTop] = useState(0);
+  const [scrollDirection, setScrollDirection] = useState(null);
   const router = useRouter();
+  const [isLoadingMore, setIsLoadingMore] = useState(false);
   const [endTime, setEndTime] = useState(() => Date.now());
   const [startTime, setStartTime] = useState(
     () => endTime - 30 * 24 * 60 * 60 * 1000,
-  );// 30 days for now
+  ); // 30 days for now
   const searchParams = useSearchParams();
   const { dRepIDBech32 } = useCardano();
   const updateURL = (startTime?: number, endTime?: number) => {
@@ -56,34 +61,94 @@ const DrepTimeline = ({
     }
     router.replace(`?${params.toString()}`, { scroll: false });
   };
+  const ref = useInfiniteScroll({
+    next: (scrollDirection) => fetchMoreData(),
+    rowCount: allActivities.length,
+    hasMore: { down: hasMoreBelow, up: hasMoreAbove },
+    onScroll: (event) => {
+      handleScroll(event);
+      updateDominantActivity();
+    },
+  });
   useEffect(() => {
-    if (activity) {
-      setAllActivities((prevActivities) => {
-        const uniqueActivitiesMap = new Map(
-          [...prevActivities, ...activity].map((activity) => [
-            activity.timestamp,
-            activity,
-          ]),
-        );
-        return Array.from(uniqueActivitiesMap.values()).sort(
-          (a, b) => b.timestamp - a.timestamp,
-        );
-      });
-      setHasMore(activity.length > 0);
+    let startTime, endTime;
+    if (searchParams) {
+      const params = new URLSearchParams(searchParams);
+      if (params.get('startTime')) {
+        setStartTime(Number(params.get('startTime')));
+        startTime = Number(params.get('startTime'));
+      }
+      if (params.get('endTime')) {
+        setEndTime(Number(params.get('endTime')));
+        endTime = Number(params.get('endTime'));
+      }
     }
-  }, [activity]);
+    const initialFetch = async (startTime, endTime) => {
+      let newStartTime = startTime;
+      let newEndTime = endTime;
+      let drep;
+      String(drepId).includes('drep')
+        ? (drep = await getSingleDRepViaVoterId(
+            drepId as string,
+            null,
+            newEndTime,
+            newStartTime,
+          ))
+        : (drep = await getSingleDRep(
+            Number(drepId),
+            null,
+            newEndTime,
+            newStartTime,
+          ));
 
+      if (drep.activity && drep.activity.length > 0) {
+        setAllActivities((prevActivities) => {
+          const uniqueActivitiesMap = new Map(
+            [...drep.activity].map((activity) => [
+              activity.timestamp,
+              activity,
+            ]),
+          );
+          return Array.from(uniqueActivitiesMap.values()).sort(
+            (a, b) =>
+              new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime(),
+          );
+        });
+        setHasMoreBelow(drep.activity.length > 0);
+        // Update time states
+        setEndTime(newEndTime);
+        setStartTime(newStartTime);
+      }
+    };
+    if (drepId) initialFetch(startTime, endTime);
+  }, [drepId]);
   const updateDominantActivity = () => {
     updateURL(startTime, endTime);
   };
-
+  const handleScroll = (event) => {
+    const currentScrollTop = event.scrollTop;
+    const isScrollingDown = currentScrollTop > prevScrollTop;
+    setScrollDirection(isScrollingDown ? 'down' : 'up');
+    setPrevScrollTop(currentScrollTop);
+  };
   const fetchMoreData = useCallback(async () => {
     if (allActivities && allActivities.length > 0) {
-      const oldestActivityTimestamp = Math.min(
-        ...allActivities.map((a) => new Date(a.timestamp).getTime()),
-      );
-      const newEndTime = oldestActivityTimestamp;
-      const newStartTime = newEndTime - 30 * 24 * 60 * 60 * 1000; // Fetch 30 more days
+      setIsLoadingMore(true);
+      let newStartTime, newEndTime;
+      if (scrollDirection === 'up') {
+        const oldestActivityTimestamp = Math.max(
+          ...allActivities.map((a) => new Date(a.timestamp).getTime()),
+        );
+        newStartTime = oldestActivityTimestamp;
+        newEndTime = newStartTime + 30 * 24 * 60 * 60 * 1000; // 30 days earlier
+      } else {
+        const oldestActivityTimestamp = Math.min(
+          ...allActivities.map((a) => new Date(a.timestamp).getTime()),
+        );
+        newEndTime = oldestActivityTimestamp;
+        newStartTime = newEndTime - 30 * 24 * 60 * 60 * 1000; // Fetch 30 more days
+      }
+
       let drep;
       drepId.includes('drep')
         ? (drep = await getSingleDRepViaVoterId(
@@ -111,15 +176,24 @@ const DrepTimeline = ({
               new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime(),
           );
         });
-        setHasMore(drep.activity.length > 0);
+        if (scrollDirection === 'up') {
+          setHasMoreAbove(drep.activity.length > 1);
+        }
+        if (scrollDirection === 'down') {
+          setHasMoreBelow(drep.activity.length > 1);
+        }
         // Update time states
         setEndTime(newEndTime);
         setStartTime(newStartTime);
+        setIsLoadingMore(false);
       } else {
-        setHasMore(false);
+        setHasMoreBelow(false);
+        setIsLoadingMore(false);
+        setHasMoreAbove(false);
       }
     }
-  }, [drepId, allActivities]);
+  }, [drepId, allActivities, scrollDirection]);
+
   return (
     <div className="flex h-full w-full flex-col gap-5 bg-white px-5 py-3">
       <div className="flex flex-col items-center gap-2 sm:flex-row sm:justify-between">
@@ -138,22 +212,35 @@ const DrepTimeline = ({
           <Link href={`/dreps/workflow/notes/new`}>Add a note</Link>
         </Button>
       )}
-
-      {drepId && !drepId.includes('drep') && <ProfileClaimedChip claimedAddress={drepId} />}
-      {allActivities && allActivities.length > 0 && (
-        <InfiniteScroll
-          onScroll={updateDominantActivity}
-          dataLength={allActivities.length}
-          next={fetchMoreData}
-          hasMore={hasMore}
-          loader={<p>Loading...</p>}
-          endMessage={<p className="text-center">You've caught up!</p>}
-          scrollThreshold="200px"
-          className="flex flex-col gap-5 pt-5"
-        >
-          <DrepTimelineWaterfall activity={allActivities} />
-        </InfiniteScroll>
+      {drepId && (drepId).includes('drep') && (
+        <ProfileClaimedChip claimedAddress={drepId} />
       )}
+      <div
+        id="drep-timeline"
+        ref={ref as any}
+        style={{
+          height: 1000,
+          overflow: 'auto',
+          display: 'flex',
+          flexDirection: 'column',
+        }}
+      >
+        {isLoadingMore && scrollDirection === 'up' && (
+          <div className="flex items-center justify-center">
+            <CircularProgress size={40} />
+          </div>
+        )}
+        {allActivities && allActivities.length > 0 && (
+          <div className="flex flex-col gap-5 pt-5">
+            <DrepTimelineWaterfall activity={allActivities} />
+          </div>
+        )}
+        {isLoadingMore && scrollDirection === 'down' && (
+          <div className="flex items-center justify-center">
+            <CircularProgress size={40} />
+          </div>
+        )}
+      </div>
     </div>
   );
 };
diff --git a/frontend/src/components/molecules/DrepTimelineWaterfall.tsx b/frontend/src/components/molecules/DrepTimelineWaterfall.tsx
index a13d9a22a79b61b8213534985396946e889758a1..ebc039be5ad2501a411d546401de35d8be39f3fb 100644
--- a/frontend/src/components/molecules/DrepTimelineWaterfall.tsx
+++ b/frontend/src/components/molecules/DrepTimelineWaterfall.tsx
@@ -36,11 +36,10 @@ export default function DrepTimelineWaterfall({
       {activity &&
         activity.length > 0 &&
         activity.map((item, epochIndex) => (
-          <>
+          <div key={epochIndex}>
             {item.type === 'note' && (
               <div
                 className="flex w-full flex-col items-center space-y-2"
-                key={epochIndex}
               >
                 <TimelineSeparator>
                   <TimelineDot />
@@ -62,7 +61,6 @@ export default function DrepTimelineWaterfall({
             {item.type === 'epoch' && (
               <div
                 className="flex w-full flex-col items-center space-y-2"
-                key={epochIndex}
               >
                 <TimelineSeparator>
                   <TimelineDot />
@@ -90,7 +88,7 @@ export default function DrepTimelineWaterfall({
               </div>
             )}
             {item.type === 'voting_activity' && (
-              <TimelineItem key={epochIndex}>
+              <TimelineItem>
                 <TimelineSeparator>
                   <TimelineDot />
                   <TimelineConnector
@@ -103,7 +101,7 @@ export default function DrepTimelineWaterfall({
                 </TimelineContent>
               </TimelineItem>
             )}
-          </>
+          </div>
         ))}
     </Timeline>
   );
diff --git a/frontend/src/hooks/useGetNotesQuery.ts b/frontend/src/hooks/useGetNotesQuery.ts
index 495cb262907bb6ed87adb16e01e17a444a4a6df9..8ee411a877b413343a69ae12bd3abcea6cd4b1a2 100644
--- a/frontend/src/hooks/useGetNotesQuery.ts
+++ b/frontend/src/hooks/useGetNotesQuery.ts
@@ -5,15 +5,15 @@ import { useQuery } from 'react-query';
 import { StakeKeys } from '../../types/commonTypes';
 
 type GetNotesProps = {
-  beforeNote?: number;
-  afterNote?: number;
+  currentNote?: number;
+  request?: string;
 }
-export const useGetNotesQuery = ({ beforeNote, afterNote }: GetNotesProps = {}) => {
+export const useGetNotesQuery = ({ currentNote, request }: GetNotesProps = {}) => {
   const { stakeKey, stakeKeyBech32 } = useCardano();
   const stakeKeys: StakeKeys = { stakeKey, stakeKeyBech32 };
   const { data, isLoading, refetch, isFetching, isPreviousData } = useQuery({
-    queryKey: [QUERY_KEYS.getNotesKey, stakeKeys, beforeNote, afterNote],
-    queryFn: async () => await getNotes(stakeKeys, beforeNote, afterNote),
+    queryKey: [QUERY_KEYS.getNotesKey, stakeKeys, currentNote,request],
+    queryFn: async () => await getNotes(stakeKeys, currentNote,request),
     refetchOnWindowFocus: false,
     enabled: true,
     keepPreviousData: true,
diff --git a/frontend/src/services/requests/getNotes.ts b/frontend/src/services/requests/getNotes.ts
index bbf9ebfc1450d6bd08332152224f783e909e092c..85acb693cdf88cd71ca9dd547a3291106d45cb17 100644
--- a/frontend/src/services/requests/getNotes.ts
+++ b/frontend/src/services/requests/getNotes.ts
@@ -1,12 +1,16 @@
 import { StakeKeys } from '../../../types/commonTypes';
 import axiosInstance from '../axiosInstance';
 
-export const getNotes = async (stakeKeys?: StakeKeys, beforeNote?: number, afterNote?: number) => {
+export const getNotes = async (
+  stakeKeys?: StakeKeys,
+  currentNote?: number,
+  request?: string,
+) => {
   const response = await axiosInstance.get(`/api/notes/all`, {
     params: {
       stakeKeys: stakeKeys,
-      beforeNoteCursor: beforeNote,
-      afterNoteCursor: afterNote
+      currentNoteCursor: currentNote,
+      request: request,
     },
   });
   return response.data;
diff --git a/frontend/yarn.lock b/frontend/yarn.lock
index 84461a3a821476707c531fcdc5eb0c3b4c98080f..89d8cb08000f72ace029b98488acfc3a5a722b37 100644
--- a/frontend/yarn.lock
+++ b/frontend/yarn.lock
@@ -8659,6 +8659,11 @@ react-dom@^18.2.0:
     loose-envify "^1.1.0"
     scheduler "^0.23.2"
 
+react-easy-infinite-scroll-hook@^2.1.4:
+  version "2.1.4"
+  resolved "https://registry.yarnpkg.com/react-easy-infinite-scroll-hook/-/react-easy-infinite-scroll-hook-2.1.4.tgz#6b61ba1d9dbf17a28d5b99e7513e281b4b61159f"
+  integrity sha512-sRbQGWh4BjSvCHTUGQwqf6PtMsOJWYl+RQ7h7BagmNpoWRi+Q/X8qwMZJ5WyzZS6U5vi3OrSGAfjLFPKp73jrg==
+
 react-error-boundary@^3.1.4:
   version "3.1.4"
   resolved "https://registry.yarnpkg.com/react-error-boundary/-/react-error-boundary-3.1.4.tgz#255db92b23197108757a888b01e5b729919abde0"
@@ -8676,13 +8681,6 @@ react-hook-form@^7.51.3:
   resolved "https://registry.yarnpkg.com/react-hook-form/-/react-hook-form-7.51.3.tgz#7486dd2d52280b6b28048c099a98d2545931cab3"
   integrity sha512-cvJ/wbHdhYx8aviSWh28w9ImjmVsb5Y05n1+FW786vEZQJV5STNM0pW6ujS+oiBecb0ARBxJFyAnXj9+GHXACQ==
 
-react-infinite-scroll-component@^6.1.0:
-  version "6.1.0"
-  resolved "https://registry.yarnpkg.com/react-infinite-scroll-component/-/react-infinite-scroll-component-6.1.0.tgz#7e511e7aa0f728ac3e51f64a38a6079ac522407f"
-  integrity sha512-SQu5nCqy8DxQWpnUVLx7V7b7LcA37aM7tvoWjTLZp1dk6EJibM5/4EJKzOnl07/BsM1Y40sKLuqjCwwH/xV0TQ==
-  dependencies:
-    throttle-debounce "^2.1.0"
-
 react-is@^16.13.1, react-is@^16.7.0:
   version "16.13.1"
   resolved "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz"
@@ -9469,11 +9467,6 @@ thenify-all@^1.0.0:
   dependencies:
     any-promise "^1.0.0"
 
-throttle-debounce@^2.1.0:
-  version "2.3.0"
-  resolved "https://registry.yarnpkg.com/throttle-debounce/-/throttle-debounce-2.3.0.tgz#fd31865e66502071e411817e241465b3e9c372e2"
-  integrity sha512-H7oLPV0P7+jgvrk+6mwwwBDmxTaxnu9HMXmloNLXwnNO0ZxZ31Orah2n8lU1eMPvsaowP2CX+USCgyovXfdOFQ==
-
 throttleit@^1.0.0:
   version "1.0.1"
   resolved "https://registry.npmjs.org/throttleit/-/throttleit-1.0.1.tgz"