From fb575dcc38a912b27231fc917a2ddca79ff622c3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=C5=A0t=C4=9Bp=C3=A1n=20=C5=A0onovsk=C3=BD?=
 <stepan.sonovsky@inqool.cz>
Date: Mon, 12 Aug 2024 14:08:00 +0200
Subject: [PATCH] feat: added pagination

---
 src/app/components/CommitList.tsx  | 48 +++++++++++++++------
 src/app/csvDownload/CsvButtons.tsx | 68 ++++++++++++++++++------------
 src/app/hooks/useCommits.ts        | 33 ++++++++++++++-
 3 files changed, 106 insertions(+), 43 deletions(-)

diff --git a/src/app/components/CommitList.tsx b/src/app/components/CommitList.tsx
index 83f67c2..af79ad9 100644
--- a/src/app/components/CommitList.tsx
+++ b/src/app/components/CommitList.tsx
@@ -1,9 +1,10 @@
-import React from 'react';
-import useCommits from "@/app/hooks/useCommits";
+import React, { useState } from 'react';
+import {useCommitsPagination} from "@/app/hooks/useCommits";
 import CsvButtons from "@/app/csvDownload/CsvButtons";
 
 const CommitList = ({ projectId, token, host, onCommitClick }) => {
-    const { commits, loading, error } = useCommits(projectId, token, host);
+    const [page, setPage] = useState(1);
+    const { commits, loading, error, totalPages } = useCommitsPagination(projectId, token, host, page);
 
     if (loading) return <p>Loading...</p>;
     if (error) return <p>Error: {error.message}</p>;
@@ -11,21 +12,40 @@ const CommitList = ({ projectId, token, host, onCommitClick }) => {
     return (
         <div className="bg-white shadow-md rounded-lg p-4">
             {commits ? (
-                <ul className="bg-white shadow-md rounded-lg p-4">
-                    {commits.map(commit => (
-                        <li
-                            key={commit.id}
-                            className="cursor-pointer py-2 px-4 hover:bg-gray-100"
-                            onClick={() => onCommitClick(commit.id)}
+                <>
+                    <ul className="bg-white shadow-md rounded-lg p-4">
+                        {commits.map(commit => (
+                            <li
+                                key={commit.id}
+                                className="cursor-pointer py-2 px-4 hover:bg-gray-100"
+                                onClick={() => onCommitClick(commit.id)}
+                            >
+                                {commit.title}
+                            </li>
+                        ))}
+                    </ul>
+                    <div className="flex justify-between mt-4">
+                        <button
+                            disabled={page <= 1}
+                            onClick={() => setPage(page - 1)}
+                            className="px-4 py-2 bg-blue-500 text-white rounded"
                         >
-                            {commit.title}
-                        </li>
-                    ))}
-                </ul>
+                            Previous
+                        </button>
+                        <span>Page {page} of {totalPages}</span>
+                        <button
+                            disabled={page >= totalPages}
+                            onClick={() => setPage(page + 1)}
+                            className="px-4 py-2 bg-blue-500 text-white rounded"
+                        >
+                            Next
+                        </button>
+                    </div>
+                    <CsvButtons projectId={projectId} token={token} host={host}/>
+                </>
             ) : (
                 <p>No commits found</p>
             )}
-            <CsvButtons commits={commits} projectId={projectId} token={token}/>
         </div>
     );
 };
diff --git a/src/app/csvDownload/CsvButtons.tsx b/src/app/csvDownload/CsvButtons.tsx
index 469236c..c40622c 100644
--- a/src/app/csvDownload/CsvButtons.tsx
+++ b/src/app/csvDownload/CsvButtons.tsx
@@ -1,40 +1,54 @@
-import React, { useState } from 'react';
+import React, { useState, useEffect } from 'react';
 import CsvDownloadPositivity from "@/app/csvDownload/CsvDownload";
 import CsvDownloadSize from "@/app/csvDownload/CsvDownloadSize";
+import { useCommitsAll } from "@/app/hooks/useCommits";
 
-const CsvButtons = ({ commits, projectId, token }) => {
+const CsvButtons = ({ projectId, token, host }) => {
     const [showCsvDownloadPositivity, setShowCsvDownloadPositivity] = useState(false);
     const [showCsvDownloadSize, setShowCsvDownloadSize] = useState(false);
+    const [fetchCommits, setFetchCommits] = useState(false);
+
+    const { commits, loading, error } = useCommitsAll(projectId, token, host, fetchCommits);
+
+    const handleFetchSize = () => {
+        setShowCsvDownloadSize(true);
+        setFetchCommits(true);
+    };
+
+    const handleFetchPositivity = () => {
+        setShowCsvDownloadPositivity(true);
+        setFetchCommits(true);
+    };
 
     return (
         <>
             {!showCsvDownloadSize ? (
-        <button
-            onClick={() => setShowCsvDownloadSize(prev => !prev)}
-    className="mt-4 bg-blue-500 text-white font-bold py-2 px-4 rounded hover:bg-blue-700 m-2"
-        >
-        Fetch CSV commits size
-    </button>
-) : (
-        <div className="mt-4">
-        <CsvDownloadSize commits={commits} projectId={projectId} token={token}/>
-    </div>
-)}
+                <button
+                    onClick={handleFetchSize}
+                    className="mt-4 bg-blue-500 text-white font-bold py-2 px-4 rounded hover:bg-blue-700 m-2"
+                >
+                    Fetch CSV commits size
+                </button>
+            ) : (
+                <div className="mt-4">
+                    <CsvDownloadSize commits={commits} projectId={projectId} token={token}/>
+                </div>
+            )}
 
-    {!showCsvDownloadPositivity ? (
-        <button
-            onClick={() => setShowCsvDownloadPositivity(true)}
-        className="mt-4 bg-blue-500 text-white font-bold py-2 px-4 rounded hover:bg-blue-700 m-2"
-            >
-            Fetch CSV commits positivity
-    </button>
-    ) : (
-        <div className="mt-4">
-        <CsvDownloadPositivity commits={commits} projectId={projectId} token={token}/>
-    </div>
-    )}
-    </>
-);
+            {!showCsvDownloadPositivity ? (
+                <button
+                    onClick={handleFetchPositivity}
+                    className="mt-4 bg-blue-500 text-white font-bold py-2 px-4 rounded hover:bg-blue-700 m-2"
+                >
+                    Fetch CSV commits positivity
+                </button>
+            ) : (
+                <div className="mt-4">
+                    <CsvDownloadPositivity commits={commits} projectId={projectId} token={token}/>
+                </div>
+            )}
+        </>
+    );
 };
 
 export default CsvButtons;
diff --git a/src/app/hooks/useCommits.ts b/src/app/hooks/useCommits.ts
index 1d09c5f..e61a716 100644
--- a/src/app/hooks/useCommits.ts
+++ b/src/app/hooks/useCommits.ts
@@ -1,7 +1,7 @@
 import { useState, useEffect } from 'react';
 import axios from 'axios';
 
-const useCommits = (projectId: string, token: string, host: string) => {
+export const useCommitsAll = (projectId: string, token: string, host: string) => {
     const [commits, setCommits] = useState([]);
     const [loading, setLoading] = useState(true);
     const [error, setError] = useState(null);
@@ -31,4 +31,33 @@ const useCommits = (projectId: string, token: string, host: string) => {
     return { commits, loading, error };
 };
 
-export default useCommits;
+
+export const useCommitsPagination = (projectId, token, host, page = 1, perPage = 10) => {
+    const [commits, setCommits] = useState([]);
+    const [loading, setLoading] = useState(true);
+    const [error, setError] = useState(null);
+    const [totalPages, setTotalPages] = useState(1);
+
+    useEffect(() => {
+        const fetchCommits = async () => {
+            setLoading(true);
+            try {
+                const response = await axios.get(`${host}/api/v4/projects/${projectId}/repository/commits`, {
+                    headers: { 'PRIVATE-TOKEN': token },
+                    params: { page, per_page: perPage }
+                });
+                setCommits(response.data);
+                setTotalPages(parseInt(response.headers['x-total-pages'], 10));
+            } catch (err) {
+                setError(err);
+            } finally {
+                setLoading(false);
+            }
+        };
+
+        fetchCommits();
+    }, [host, projectId, token, page, perPage]);
+
+    return { commits, loading, error, totalPages };
+};
+
-- 
GitLab