Add pagination for tenders
This commit is contained in:
parent
6335c23129
commit
69edf925fb
@ -25,19 +25,17 @@ const TenderCard: React.FC<Props> = ({
|
||||
}: Props) => {
|
||||
return (
|
||||
<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
|
||||
text={`№ ${id_of_card}`}
|
||||
className="font-bold text-[24px] mb-[48px]"
|
||||
/>
|
||||
<Title
|
||||
text={name_of_buy}
|
||||
className="text-[18px] font-semibold leading-6 text-[#489FE1] mb-6"
|
||||
/>
|
||||
<Title
|
||||
text={name_of_organization}
|
||||
className="text-[18px] leading-6 font-normal"
|
||||
/>
|
||||
<h2 className="mb-6 text-[18px] font-semibold leading-6 text-blue">
|
||||
{name_of_buy}
|
||||
</h2>
|
||||
<h2 className="text-[18px] leading-6 font-normal ">
|
||||
{name_of_organization}
|
||||
</h2>
|
||||
</div>
|
||||
<div className="w-[285px]"></div>
|
||||
</div>
|
||||
|
48
src/features/Pagination/Pagination.scss
Normal file
48
src/features/Pagination/Pagination.scss
Normal 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);
|
||||
}
|
||||
}
|
138
src/features/Pagination/Pagination.tsx
Normal file
138
src/features/Pagination/Pagination.tsx
Normal 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;
|
7
src/features/Pagination/icons/arrow-left.svg
Normal file
7
src/features/Pagination/icons/arrow-left.svg
Normal 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 |
7
src/features/Pagination/icons/arrow-right.svg
Normal file
7
src/features/Pagination/icons/arrow-right.svg
Normal 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 |
@ -3,9 +3,11 @@ import React, { useEffect, useState } from "react";
|
||||
import { useTendersStore } from "./tendersStore";
|
||||
import { data } from "autoprefixer";
|
||||
import TenderCard from "@/entities/TenderCard";
|
||||
import Pagination from "@/features/Pagination/Pagination";
|
||||
|
||||
interface Props {}
|
||||
const TendersList = () => {
|
||||
const [activePage, setActivePage] = useState<number>(1);
|
||||
const [ordering, setOrdering] = useState<number>(1);
|
||||
const { data: tenders, getTenders, isLoading, error } = useTendersStore();
|
||||
|
||||
@ -14,23 +16,30 @@ const TendersList = () => {
|
||||
}, []);
|
||||
console.log(tenders);
|
||||
return (
|
||||
<div className="bg-#E4F1FB">
|
||||
<div className="flex flex-col gap-2">
|
||||
{tenders?.results?.map((tender) => (
|
||||
<TenderCard
|
||||
key={tender.id}
|
||||
id={tender.id}
|
||||
id_of_card={tender.id_of_card}
|
||||
data_rk={tender.data_rk}
|
||||
name_of_organization={tender.name_of_organization}
|
||||
type_of_buy={tender.type_of_buy}
|
||||
name_of_buy={tender.name_of_buy}
|
||||
date_of_publication_datetime={tender.date_of_publication_datetime}
|
||||
date_of_offer_datetime={tender.date_of_offer_datetime}
|
||||
current_timestamp={tender.current_timestamp}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
<div className="flex flex-col gap-2 pb-[96px] items-center">
|
||||
{tenders?.results?.map((tender) => (
|
||||
<TenderCard
|
||||
key={tender.id}
|
||||
id={tender.id}
|
||||
id_of_card={tender.id_of_card}
|
||||
data_rk={tender.data_rk}
|
||||
name_of_organization={tender.name_of_organization}
|
||||
type_of_buy={tender.type_of_buy}
|
||||
name_of_buy={tender.name_of_buy}
|
||||
date_of_publication_datetime={tender.date_of_publication_datetime}
|
||||
date_of_offer_datetime={tender.date_of_offer_datetime}
|
||||
current_timestamp={tender.current_timestamp}
|
||||
/>
|
||||
))}
|
||||
<Pagination
|
||||
activePage={activePage}
|
||||
setActivePage={setActivePage}
|
||||
prev={tenders.previous}
|
||||
next={tenders.next}
|
||||
count={tenders.count as number}
|
||||
current_count={tenders.results.length}
|
||||
limit={20}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user