From ac0d9f421f1304306d9b3a264a225966fa9d5677 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adri=C3=A1n=20Oliva?= Date: Mon, 29 May 2023 21:49:56 -0600 Subject: IT NOW HAS PAGING. --- src/App.jsx | 2 + src/ToDo-UI/Pagination.jsx | 239 +++++++++++++++++++++++++++++++++++++++++++++ src/api/axios_methods.js | 4 +- src/refreshToDos.js | 28 ++++-- 4 files changed, 262 insertions(+), 11 deletions(-) create mode 100644 src/ToDo-UI/Pagination.jsx diff --git a/src/App.jsx b/src/App.jsx index dd81431..ca2c07e 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -2,6 +2,7 @@ import React from "react"; import { Search } from "./ToDo-UI/Search"; import { NewToDo } from "./ToDo-UI/NewToDo"; import { ListToDos } from "./ToDo-UI/ListToDo"; +import { Pagination } from "./ToDo-UI/Pagination"; import { useDispatch, useSelector } from "react-redux"; import { @@ -25,6 +26,7 @@ function App() { + ); } diff --git a/src/ToDo-UI/Pagination.jsx b/src/ToDo-UI/Pagination.jsx new file mode 100644 index 0000000..61e41bf --- /dev/null +++ b/src/ToDo-UI/Pagination.jsx @@ -0,0 +1,239 @@ +import { useState } from "react"; +import { useDispatch, useSelector } from "react-redux"; + +import { + change_page, + select_current_filters, + select_current_sorting, + select_current_page, +} from "../features/todo/reducer"; + +import { refresh_todos } from "../refreshToDos"; +import { get_nu_pages_function } from "../api/axios_methods"; + +function range(start, end) { + return Array.from({ length: end - start + 1 }, (_, i) => i + start); +} + +function render_pagination(current_page, nu_pages, handle_on_click) { + const first_page = ( +
  • + handle_on_click(1)}> + « + +
  • + ); + const previous_page = ( +
  • + handle_on_click(current_page - 1)} + > + < + +
  • + ); + const next_page = ( +
  • + handle_on_click(current_page + 1)} + > + > + +
  • + ); + const last_page = ( +
  • + handle_on_click(nu_pages)}> + » + +
  • + ); + + let in_between = <>; + // If pages <= 5, render all of them. + if (nu_pages <= 5) { + in_between = ( + <> + {range(1, nu_pages).map((number) => ( +
  • + + handle_on_click(parseInt(e.target.innerText)) + } + > + {number} + +
  • + ))} + + ); + } else if (current_page <= 3) { + in_between = ( + <> + {range(1, 3).map((number) => ( +
  • + + handle_on_click(parseInt(e.target.innerText)) + } + > + {number} + +
  • + ))} +
  • + ... +
  • +
  • + + handle_on_click(parseInt(e.target.innerText)) + } + > + {nu_pages} + +
  • + + ); + } else if (current_page >= nu_pages - 2) { + in_between = ( + <> +
  • + handle_on_click(1)}> + 1 + +
  • +
  • + ... +
  • + {range(nu_pages - 2, nu_pages).map((number) => ( +
  • + + handle_on_click(parseInt(e.target.innerText)) + } + > + {number} + +
  • + ))} + + ); + } else { + in_between = ( + <> +
  • + handle_on_click(1)}> + 1 + +
  • +
  • + ... +
  • +
  • + {current_page} +
  • +
  • + ... +
  • +
  • + handle_on_click(nu_pages)} + > + {nu_pages} + +
  • + + ); + } + return ( + + ); +} + +export function Pagination() { + const [nu_pages, set_nu_pages] = useState(0); + + const nu_pages_api = get_nu_pages_function(); + nu_pages_api((response) => set_nu_pages(response)); + + const dispatch = useDispatch(); + + const my_filters = useSelector(select_current_filters); + const my_sorters = useSelector(select_current_sorting); + const my_curr_page = useSelector(select_current_page); + + function handle_on_click(target) { + if (my_curr_page == target) return; + + dispatch(change_page({ page: target })); + refresh_todos(my_filters, my_sorters, my_curr_page, dispatch); + } + + return ( +
    + {render_pagination(my_curr_page, nu_pages, handle_on_click)} +
    + ); +} diff --git a/src/api/axios_methods.js b/src/api/axios_methods.js index 822c334..bea8b79 100644 --- a/src/api/axios_methods.js +++ b/src/api/axios_methods.js @@ -126,10 +126,10 @@ export function get_todos_page_function() { export function get_nu_pages_function() { // Return the number of pages in total. // GET "/todos/filtSort/pages" - return async () => { + return async (handler) => { try { const response = await api.get("/todos/filtSort/pages"); - return response.data; + handler(response.data); } catch (err) { console.log(err); } diff --git a/src/refreshToDos.js b/src/refreshToDos.js index a6b1368..250b399 100644 --- a/src/refreshToDos.js +++ b/src/refreshToDos.js @@ -29,17 +29,27 @@ export function refresh_todos(my_filters, my_sorters, my_curr_page, dispatch) { }); // Get the total number of pages. Change the current page if necessary. - const get_nu_pages_api = get_nu_pages_function(); - const total_pages_api = get_nu_pages_api(); - - if (total_pages_api < my_curr_page) { - dispatch( - change_page({ - page: total_pages_api, - }) - ); + function handle_out_of_bounds(total_pages) { + if (total_pages == 0) { + dispatch( + change_page({ + page: 1, + }) + ); + } else if (total_pages < my_curr_page) { + dispatch( + change_page({ + page: total_pages, + }) + ); + } } + const get_nu_pages_api = get_nu_pages_function(); + const total_pages_api = get_nu_pages_api((nu_pages) => { + handle_out_of_bounds(nu_pages); + }); + // Delete all current to dos we have stored and retrieve new to dos from API. const get_todos_api = get_todos_page_function(); -- cgit v1.2.3