Add pagination for tenders

This commit is contained in:
ariari04 2024-08-30 13:46:23 +06:00
parent 6335c23129
commit 69edf925fb
6 changed files with 233 additions and 26 deletions

View File

@ -25,19 +25,17 @@ const TenderCard: React.FC<Props> = ({
}: Props) => { }: Props) => {
return ( return (
<div className="w-full min-h-[213px] bg-white shadow-sm rounded-sm flex gap-[82px] items-center p-6"> <div className="w-full min-h-[213px] bg-white shadow-sm rounded-sm flex gap-[82px] items-center p-6">
<div className="w-[840px]"> <div className="w-[840px] flex flex-col">
<Title <Title
text={`${id_of_card}`} text={`${id_of_card}`}
className="font-bold text-[24px] mb-[48px]" className="font-bold text-[24px] mb-[48px]"
/> />
<Title <h2 className="mb-6 text-[18px] font-semibold leading-6 text-blue">
text={name_of_buy} {name_of_buy}
className="text-[18px] font-semibold leading-6 text-[#489FE1] mb-6" </h2>
/> <h2 className="text-[18px] leading-6 font-normal ">
<Title {name_of_organization}
text={name_of_organization} </h2>
className="text-[18px] leading-6 font-normal"
/>
</div> </div>
<div className="w-[285px]"></div> <div className="w-[285px]"></div>
</div> </div>

View File

@ -0,0 +1,48 @@
.pagination {
margin-top: 40px;
display: flex;
button {
width: 40px;
height: 40px;
display: flex;
align-items: center;
justify-content: center;
border: 1px solid rgb(208, 213, 221);
background-color: rgb(255, 255, 255);
}
&__prev,
&__prev-disabled {
border-radius: 8px 0px 0px 8px;
}
&__next,
&__next-disabled {
border-radius: 0px 8px 8px 0px;
}
&__next-disabled,
&__prev-disabled {
cursor: auto;
opacity: 0.7;
}
&__page,
&__page_active {
font-size: 14px;
font-weight: 500;
line-height: 20px;
color: rgb(52, 64, 84);
}
&__page_active {
background-color: rgb(249, 250, 251) !important;
}
&__page:hover,
&__prev:hover,
&__next:hover {
background-color: rgb(249, 250, 251);
}
}

View File

@ -0,0 +1,138 @@
import "./Pagination.scss";
import arrow_right from "./icons/arrow-right.svg";
import arrow_left from "./icons/arrow-left.svg";
import Image from "next/image";
interface IPaginationProps {
setActivePage: (page: number | ((prev: number) => number)) => void;
activePage: number;
prev: string | null;
next: string | null;
count: number;
current_count: number;
limit: number;
}
const Pagination: React.FC<IPaginationProps> = ({
setActivePage,
activePage,
prev,
next,
count,
current_count,
limit,
}: IPaginationProps) => {
const pages_count = Math.ceil(count / limit);
const showPages = () => {
const btns = [];
for (let i = 1; i <= pages_count; i++) {
btns.push(
<button
onClick={() => setActivePage(i)}
key={i}
className={
activePage === i ? "pagination__page_active" : "pagination__page"
}
>
{i}
</button>
);
}
if (current_count < 8 && activePage === 1) {
return [...btns.slice(0, 1)];
}
if (pages_count > 5) {
if (activePage > 2) {
if (
activePage + 2 === pages_count - 1 ||
activePage + 1 === pages_count - 1 ||
activePage === pages_count - 1 ||
activePage === pages_count
) {
const newBtns = [
...btns.slice(0, 1),
<button key="..." disabled>
...
</button>,
...btns.slice(
activePage - (activePage + 2 === pages_count - 1 ? 2 : 1)
),
];
if (newBtns.length < 6) {
return [
...btns.slice(0, 1),
<button key="..." disabled>
...
</button>,
...btns.slice(-4),
];
}
return newBtns;
} else {
return [
...btns.slice(0, 1),
<button key="...1" disabled>
...
</button>,
...btns.slice(
activePage - (activePage === 3 ? 1 : 2),
activePage + 1
),
<button key="..." disabled>
...
</button>,
...btns.slice(-2),
];
}
} else {
return [
...btns.slice(0, 3),
<button key="..." disabled>
...
</button>,
...btns.slice(-2),
];
}
}
return btns;
};
const prevPage = () => {
if (activePage - 1 === 0) return;
setActivePage((prev) => prev - 1);
};
const nextPage = () => {
if (activePage + 1 > pages_count) return;
setActivePage((prev) => prev + 1);
};
return (
<div className="pagination">
<button
onClick={prevPage}
disabled={prev === null}
className={`pagination__prev${prev === null ? "-disabled" : ""}`}
>
<Image src={arrow_left} alt="" />
</button>
{showPages().map((btn) => btn)}
<button
onClick={nextPage}
disabled={next === null}
className={`pagination__next${next === null ? "-disabled" : ""}`}
>
<Image src={arrow_right} alt="" />
</button>
</div>
);
};
export default Pagination;

View File

@ -0,0 +1,7 @@
<svg width="13.336426" height="13.343750" viewBox="0 0 13.3364 13.3438" fill="none" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<desc>
Created with Pixso.
</desc>
<defs/>
<path id="Icon" d="M12.5015 6.67188L0.834961 6.67188M6.66846 12.5059L0.834961 6.67188L6.66846 0.838867" stroke="#344054" stroke-opacity="1.000000" stroke-width="1.670000" stroke-linejoin="round"/>
</svg>

After

Width:  |  Height:  |  Size: 417 B

View File

@ -0,0 +1,7 @@
<svg width="13.336426" height="13.343750" viewBox="0 0 13.3364 13.3438" fill="none" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<desc>
Created with Pixso.
</desc>
<defs/>
<path id="Icon" d="M0.834961 6.67188L12.5015 6.67188M6.66846 0.838867L12.5015 6.67188L6.66846 12.5059" stroke="#344054" stroke-opacity="1.000000" stroke-width="1.670000" stroke-linejoin="round"/>
</svg>

After

Width:  |  Height:  |  Size: 416 B

View File

@ -3,9 +3,11 @@ import React, { useEffect, useState } from "react";
import { useTendersStore } from "./tendersStore"; import { useTendersStore } from "./tendersStore";
import { data } from "autoprefixer"; import { data } from "autoprefixer";
import TenderCard from "@/entities/TenderCard"; import TenderCard from "@/entities/TenderCard";
import Pagination from "@/features/Pagination/Pagination";
interface Props {} interface Props {}
const TendersList = () => { const TendersList = () => {
const [activePage, setActivePage] = useState<number>(1);
const [ordering, setOrdering] = useState<number>(1); const [ordering, setOrdering] = useState<number>(1);
const { data: tenders, getTenders, isLoading, error } = useTendersStore(); const { data: tenders, getTenders, isLoading, error } = useTendersStore();
@ -14,8 +16,7 @@ const TendersList = () => {
}, []); }, []);
console.log(tenders); console.log(tenders);
return ( return (
<div className="bg-#E4F1FB"> <div className="flex flex-col gap-2 pb-[96px] items-center">
<div className="flex flex-col gap-2">
{tenders?.results?.map((tender) => ( {tenders?.results?.map((tender) => (
<TenderCard <TenderCard
key={tender.id} key={tender.id}
@ -30,7 +31,15 @@ const TendersList = () => {
current_timestamp={tender.current_timestamp} current_timestamp={tender.current_timestamp}
/> />
))} ))}
</div> <Pagination
activePage={activePage}
setActivePage={setActivePage}
prev={tenders.previous}
next={tenders.next}
count={tenders.count as number}
current_count={tenders.results.length}
limit={20}
/>
</div> </div>
); );
}; };