diff --git a/checkers-app/src/components/common/BackButton.tsx b/checkers-app/src/components/common/BackButton.tsx
index cac81b07..faea16f5 100644
--- a/checkers-app/src/components/common/BackButton.tsx
+++ b/checkers-app/src/components/common/BackButton.tsx
@@ -7,7 +7,7 @@ export function BackButton() {
const regex = /^\/messages\/[^/]+\/voteRequests\/[^/]+\/?$/;
function onClick() {
if (regex.test(location.pathname)) {
- navigate("/votes");
+ navigate("/votes", { state: location.state }); //for resumption of old position
} else {
navigate(-1);
}
diff --git a/checkers-app/src/components/common/Layout.tsx b/checkers-app/src/components/common/Layout.tsx
index b272df60..f425d6ff 100644
--- a/checkers-app/src/components/common/Layout.tsx
+++ b/checkers-app/src/components/common/Layout.tsx
@@ -14,7 +14,7 @@ export default function Layout({
showMenu = false,
}: LayoutProps) {
return (
-
+
{/*
*/}
-
{children}
+
{children}
);
diff --git a/checkers-app/src/components/myvotes/MessageCard.tsx b/checkers-app/src/components/myvotes/MessageCard.tsx
index 67be1bbb..f706e5d9 100644
--- a/checkers-app/src/components/myvotes/MessageCard.tsx
+++ b/checkers-app/src/components/myvotes/MessageCard.tsx
@@ -6,6 +6,7 @@ import "./MessageCard.css";
interface MessageCardProps {
voteSummary: VoteSummary;
status: string;
+ scrollPosition: number;
}
type ColourMap = {
@@ -71,13 +72,14 @@ export default function MessageCard(props: MessageCardProps) {
firestorePath,
} = props.voteSummary;
const status = props.status;
+ const scrollPosition = props.scrollPosition;
// const colour: string = colours[category];
const navigate = useNavigate();
const dateString = dateToDateString(new Date(createdTimestamp));
// If the message is PENDING, clicking the button should go to the voting page
- const viewVote = (firestorePath: string) => {
- navigate(`/${firestorePath}`);
+ const viewVote = (firestorePath: string, status: string, scrollPosition: number) => {
+ navigate(`/${firestorePath}`, {state: {status: status, scrollPosition: scrollPosition}});
};
const textStyle = "font-normal"; //add bold in future
@@ -128,7 +130,7 @@ export default function MessageCard(props: MessageCardProps) {
return (
viewVote(firestorePath)}
+ onClick={() => viewVote(firestorePath, status, scrollPosition)}
>
{/* Coloured dot if needs review*/}
diff --git a/checkers-app/src/components/myvotes/MessagesDisplay.tsx b/checkers-app/src/components/myvotes/MessagesDisplay.tsx
index 93d28145..1be8f91d 100644
--- a/checkers-app/src/components/myvotes/MessagesDisplay.tsx
+++ b/checkers-app/src/components/myvotes/MessagesDisplay.tsx
@@ -16,100 +16,148 @@ Idea:
- Have a nested component for each button
*/
-import { useState, useEffect, FC } from "react";
+interface MessagesDisplayProps {
+ status: "pending" | "voted";
+ scrollPosition: number;
+}
+
+import { useState, useEffect, FC, useCallback, useRef } from "react";
import { useUser } from "../../providers/UserContext";
-import Loading from "../common/Loading";
import MessageCard from "./MessageCard";
import { Typography } from "@material-tailwind/react";
import { getCheckerVotes } from "../../services/api";
import { VoteSummary, VoteSummaryApiResponse } from "../../types";
-import Pagination from "./Pagination"; // Make sure to create this component
-const MessagesDisplay: FC = () => {
+const MessagesDisplay: FC
= ({
+ status,
+ scrollPosition,
+}) => {
const { checkerDetails } = useUser();
const [isLoading, setIsLoading] = useState(false);
const [votes, setVotes] = useState([]);
const [lastPath, setLastPath] = useState(null);
- const [activeTab, setActiveTab] = useState<"pending" | "voted">("pending");
- const [currentPage, setCurrentPage] = useState(1);
+ const [activeTab, setActiveTab] = useState<"pending" | "voted">(status);
const [totalPages, setTotalPages] = useState(1);
const [error, setError] = useState("");
+ const [page, setPage] = useState(1);
+ const [scrollY, setScrollY] = useState(0);
+
+ const scrollRef = useRef(null);
+
+ // Scroll Functions
+ const handleScroll = () => {
+ const scrollY = window.scrollY;
+ setScrollY(scrollY);
+ };
useEffect(() => {
- const fetchMessages = async () => {
- setIsLoading(true);
- try {
- if (!checkerDetails.checkerId) {
- throw new Error("Checker Id missing.");
- }
- const response: VoteSummaryApiResponse = await getCheckerVotes(
- checkerDetails.checkerId,
- activeTab.toLowerCase(),
- 5,
- lastPath
- );
- // Assuming your API correctly maps to the ApiResponse interface
- if (response.votes) {
- setVotes(response.votes);
- }
- setTotalPages(response.totalPages);
- setLastPath(response.lastPath);
- setIsLoading(false);
- } catch (err) {
- setError("Failed to fetch messages");
- setIsLoading(false);
- }
+ window.addEventListener("scroll", handleScroll);
+ return () => {
+ window.removeEventListener("scroll", handleScroll);
};
+ }, []);
+
+ useEffect(() => {
+ if (scrollY >= scrollPosition) {
+ return;
+ } else if (scrollPosition !== 0) {
+ setTimeout(() => {
+ window.scrollTo({
+ top: scrollPosition,
+ behavior: "smooth",
+ });
+ }, 200);
+ }
+ }, [votes]);
+
+ const fetchMessages = async () => {
+ setIsLoading(true);
+ try {
+ if (!checkerDetails.checkerId) {
+ throw new Error("Checker Id missing.");
+ }
+ const response: VoteSummaryApiResponse = await getCheckerVotes(
+ checkerDetails.checkerId,
+ activeTab.toLowerCase(),
+ 10,
+ lastPath
+ );
+ if (response.votes) {
+ setVotes((prevVotes) => [...prevVotes, ...response.votes]);
+ }
+ setTotalPages(response.totalPages);
+ setLastPath(response.lastPath);
+ setIsLoading(false);
+ } catch (err) {
+ setError("Failed to fetch messages");
+ setIsLoading(false);
+ }
+ };
+
+ useEffect(() => {
if (checkerDetails.checkerId) {
fetchMessages();
}
- }, [checkerDetails.checkerId, activeTab, currentPage]);
+ }, [checkerDetails.checkerId, activeTab, page]);
const handleTabChange = (tab: "pending" | "voted") => {
+ setVotes([]);
setActiveTab(tab);
handlePageChange(1); // Reset to the first page whenever the tab changes
};
+ const observer = useRef(null);
+ // Function to use the Intersection Observer API
+ const lastMessageElementRef = useCallback(
+ (node: any) => {
+ if (isLoading) return;
+ if (observer.current) observer.current.disconnect();
+
+ observer.current = new IntersectionObserver((entries) => {
+ if (entries[0].isIntersecting && page !== totalPages) {
+ setPage((prevPage) => prevPage + 1);
+ }
+ });
+ if (node) observer.current.observe(node);
+ },
+ [isLoading]
+ );
+
// Function to handle page change from the Pagination component
const handlePageChange = (page: number) => {
- setCurrentPage(page);
+ setPage(page);
if (page === 1) {
setLastPath(null);
}
};
- if (isLoading) {
- return ;
- }
-
return (
-
-
-
+
+
+
+
+
-
+
{error &&
{error}
}
{!error && votes.length === 0 && (
@@ -118,18 +166,18 @@ const MessagesDisplay: FC = () => {
)}
{!error &&
votes.map((voteSummary, index) => (
-
- {!error && votes.length > 0 && (
-
- )}
);
};
diff --git a/checkers-app/src/components/myvotes/Pagination.tsx b/checkers-app/src/components/myvotes/Pagination.tsx
deleted file mode 100644
index 0a128be0..00000000
--- a/checkers-app/src/components/myvotes/Pagination.tsx
+++ /dev/null
@@ -1,73 +0,0 @@
-import { FC } from "react";
-
-interface PaginationProps {
- currentPage: number;
- totalPages: number;
- onPageChange: (page: number) => void;
-}
-
-const Pagination: FC
= ({
- currentPage,
- totalPages,
- onPageChange,
-}) => {
- const pageNumbers: number[] = [];
-
- // Determine page numbers to display
- for (let i = 1; i <= totalPages; i++) {
- pageNumbers.push(i);
- }
-
- // Handle page change
- const handlePageChange = (pageNumber: number) => {
- onPageChange(pageNumber);
- };
-
- if (totalPages <= 1) return null; // Don't display pagination for single page
-
- return (
-
-
- {/*
- {pageNumbers.map((number) => (
-
- ))} */}
-
- {/* */}
-
- );
-};
-
-export default Pagination;
diff --git a/checkers-app/src/components/myvotes/index.tsx b/checkers-app/src/components/myvotes/index.tsx
index 1f11e0a0..f8ea06b0 100644
--- a/checkers-app/src/components/myvotes/index.tsx
+++ b/checkers-app/src/components/myvotes/index.tsx
@@ -1,10 +1,26 @@
import MessagesDisplay from "./MessagesDisplay";
+// import MessagesDisplayTest from "./MessagesDisplayTest";
+import { useState, useEffect } from "react";
+import { useLocation } from "react-router-dom";
export default function MyVotes() {
+ const [activeTab, setActiveTab] = useState<"pending" | "voted">("pending");
+ const location = useLocation();
+
+ useEffect(() => {
+ console.log(location)
+ if (location.state) {
+ if (location.state.status) {
+ setActiveTab(location.state.status)
+ }
+ }
+ }, [location, activeTab])
+
return (
);
diff --git a/functions/src/definitions/api/handlers/getCheckerVotes.ts b/functions/src/definitions/api/handlers/getCheckerVotes.ts
index 29eb1ab3..055f04d6 100644
--- a/functions/src/definitions/api/handlers/getCheckerVotes.ts
+++ b/functions/src/definitions/api/handlers/getCheckerVotes.ts
@@ -151,6 +151,7 @@ const getCheckerVotesHandler = async (req: Request, res: Response) => {
lastPath: lastVotePath,
totalPages,
}
+
return res.status(200).send(response)
} catch (error) {
logger.error("Error fetching documents: ", error)