Add pagination for tenders
This commit is contained in:
parent
6335c23129
commit
69edf925fb
@ -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>
|
||||||
|
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 { 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>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user