= ({
+ setActivePage,
+ activePage,
+ prev,
+ next,
+ count,
+ current_count,
+}: IPaginationProps) => {
+ const pages_count = count % 8;
+ const showPages = () => {
+ const btns = [];
+
+ for (let i = 1; i <= pages_count; i++) {
+ btns.push(
+
+ );
+ }
+
+ 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),
+ ,
+ ...btns.slice(
+ activePage -
+ (activePage + 2 === pages_count - 1 ? 2 : 1)
+ ),
+ ];
+
+ if (newBtns.length < 6) {
+ return [
+ ...btns.slice(0, 1),
+ ,
+ ...btns.slice(-4),
+ ];
+ }
+
+ return newBtns;
+ } else {
+ return [
+ ...btns.slice(0, 1),
+ ,
+
+ ...btns.slice(
+ activePage - (activePage === 3 ? 1 : 2),
+ activePage + 1
+ ),
+
+ ,
+ ...btns.slice(-2),
+ ];
+ }
+ } else {
+ return [
+ ...btns.slice(0, 3),
+ ,
+ ...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 (
+
+
+ {showPages().map((btn) => btn)}
+
+
+ );
+};
+
+export default Pagination;
diff --git a/src/entities/Pagination/icons/arrow-left.svg b/src/entities/Pagination/icons/arrow-left.svg
new file mode 100644
index 0000000..61eb8af
--- /dev/null
+++ b/src/entities/Pagination/icons/arrow-left.svg
@@ -0,0 +1,7 @@
+
diff --git a/src/entities/Pagination/icons/arrow-right.svg b/src/entities/Pagination/icons/arrow-right.svg
new file mode 100644
index 0000000..45b4244
--- /dev/null
+++ b/src/entities/Pagination/icons/arrow-right.svg
@@ -0,0 +1,7 @@
+
diff --git a/src/shared/types/location-type.ts b/src/shared/types/location-type.ts
index 0522ff3..cb12e66 100644
--- a/src/shared/types/location-type.ts
+++ b/src/shared/types/location-type.ts
@@ -1,6 +1,6 @@
export interface ILocation {
id: 4;
- latitude: number;
- longitude: number;
+ latitude: string;
+ longitude: string;
address: string;
}
diff --git a/src/widgets/MapSection/HomeMap/HomeMap.tsx b/src/widgets/MapSection/HomeMap/HomeMap.tsx
index 791632b..72988d3 100644
--- a/src/widgets/MapSection/HomeMap/HomeMap.tsx
+++ b/src/widgets/MapSection/HomeMap/HomeMap.tsx
@@ -5,6 +5,7 @@ import "leaflet/dist/leaflet.css";
import {
MapContainer,
Marker,
+ Polyline,
Popup,
TileLayer,
useMap,
@@ -15,10 +16,15 @@ import geo_pink_icon from "./icons/geo-pink.svg";
import geo_purple_icon from "./icons/geo-purple.svg";
import geo_red_icon from "./icons/geo-red.svg";
import geo_yellow_icon from "./icons/geo-yellow.svg";
-import { DivIcon, Icon, LatLngTuple } from "leaflet";
+import {
+ DivIcon,
+ Icon,
+ LatLngExpression,
+ LatLngTuple,
+} from "leaflet";
import { StaticImageData } from "next/image";
import Link from "next/link";
-import { useEffect, useState } from "react";
+import { Fragment, useEffect, useState } from "react";
import L from "leaflet";
import { ILocation } from "@/shared/types/location-type";
@@ -34,7 +40,7 @@ interface ILatLng {
}
interface IHomeMapProps {
- data: IData[] | undefined;
+ data: IData[];
latLng: ILatLng;
}
@@ -60,8 +66,17 @@ const HomeMap: React.FC = ({
2: createCustomIcon(geo_pink_icon),
3: createCustomIcon(geo_purple_icon),
4: createCustomIcon(geo_orange_icon),
- 5: createCustomIcon(geo_green_icon),
- 6: createCustomIcon(geo_yellow_icon),
+ 5: createCustomIcon(geo_yellow_icon),
+ 6: createCustomIcon(geo_green_icon),
+ };
+
+ const categoryToPolyline: Record = {
+ 1: { color: "rgba(230, 68, 82, 0.8)" },
+ 2: { color: "rgba(198, 152, 224, 0.8)" },
+ 3: { color: "rgba(135, 40, 157, 0.8)" },
+ 4: { color: "rgba(247, 181, 84, 0.8)" },
+ 5: { color: "rgba(254, 211, 99, 0.8)" },
+ 6: { color: "rgba(158, 221, 128, 0.8)" },
};
const LocationMark = () => {
@@ -76,6 +91,8 @@ const HomeMap: React.FC = ({
return null;
};
+ const defPos = [42.8746, 74.606];
+
return (
= ({
attribution='© OpenStreetMap contributors'
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
/>
- {data?.map((marker) => (
-
-
-
- {marker.location[0].address}
-
-
-
- ))}
+
+ {data.map((report) =>
+ report.location.length === 2 ? (
+
+ ) : null
+ )}
+
+ {data?.map((report) =>
+ report.location.map((marker) => (
+
+
+
+ {marker.address}
+
+
+
+ ))
+ )}
);
diff --git a/src/widgets/MapSection/MapSection.tsx b/src/widgets/MapSection/MapSection.tsx
index f43ccbf..ad667c4 100644
--- a/src/widgets/MapSection/MapSection.tsx
+++ b/src/widgets/MapSection/MapSection.tsx
@@ -29,6 +29,7 @@ const MapSection: React.FC = ({
categories = "1,2,3,4,5,6",
queryMap,
queryRating,
+ page = "1",
}: IMapSectionProps) => {
const [mapSearch, setMapSearch] = useState(queryMap || "");
const [latLng, setLatLng] = useState({
@@ -57,7 +58,9 @@ const MapSection: React.FC = ({
router.push(
`/?тип-дороги=${categories}${
mapSearch ? `&поиск-на-карте=${mapSearch}` : ""
- }${queryRating ? `&поиск-рейтинг=${queryRating}` : ""}`,
+ }${
+ queryRating ? `&поиск-рейтинг=${queryRating}` : ""
+ }&страница-рейтинга=${page}`,
{
scroll: false,
}
@@ -136,7 +139,7 @@ const MapSection: React.FC = ({
-
+
);
};
diff --git a/src/widgets/RatingSection/RatingSection.scss b/src/widgets/RatingSection/RatingSection.scss
index 75f7158..04007b1 100644
--- a/src/widgets/RatingSection/RatingSection.scss
+++ b/src/widgets/RatingSection/RatingSection.scss
@@ -35,7 +35,7 @@
height: 100%;
display: grid;
align-items: center;
- grid-template-columns: 120px 200px 210px 380px 165px 92px;
+ grid-template-columns: 120px 200px 230px 380px 165px 92px;
td {
button {
@@ -63,7 +63,7 @@
height: 90px;
padding: 10px 0;
display: grid;
- grid-template-columns: 120px 200px 210px 380px 165px 92px;
+ grid-template-columns: 120px 200px 230px 380px 165px 92px;
align-items: center;
td {
diff --git a/src/widgets/RatingSection/RatingSection.tsx b/src/widgets/RatingSection/RatingSection.tsx
index 460f977..836ca16 100644
--- a/src/widgets/RatingSection/RatingSection.tsx
+++ b/src/widgets/RatingSection/RatingSection.tsx
@@ -19,6 +19,7 @@ import RoadType from "@/entities/RoadType/RoadType";
import Typography from "@/shared/ui/components/Typography/Typography";
import Paragraph from "@/shared/ui/components/Paragraph/Paragraph";
import arrows from "../../shared/icons/arrows.svg";
+import Pagination from "@/entities/Pagination/Pagination";
interface IRatingSectionProps {
[key: string]: string;
@@ -28,10 +29,12 @@ const RatingSection: React.FC = ({
categories = "1,2,3,4,5,6",
queryMap,
queryRating,
+ page = "1",
}: IRatingSectionProps) => {
const [ratingSearch, setRatingSearch] = useState(
queryRating || ""
);
+ const [activePage, setActivePage] = useState(+page);
const router = useRouter();
const reports = useRatingStore(useShallow((state) => state.data));
@@ -40,7 +43,7 @@ const RatingSection: React.FC = ({
);
useEffect(() => {
- getReports(ratingSearch);
+ getReports(ratingSearch, +page);
}, []);
const handleSubmit: React.FormEventHandler<
@@ -53,15 +56,36 @@ const RatingSection: React.FC = ({
router.push(
`/?тип-дороги=${categories}${
queryMap ? `&поиск-на-карте=${queryMap}` : ""
- }${ratingSearch ? `&поиск-рейтинг=${ratingSearch}` : ""}`,
+ }${
+ ratingSearch ? `&поиск-рейтинг=${ratingSearch}` : ""
+ }&страница-рейтинга=${page}`,
{
scroll: false,
}
);
- getReports(ratingSearch);
+ getReports(ratingSearch, activePage);
+
+ if (reports.results.length < 8 && page !== "1") {
+ setActivePage(1);
+ }
};
+ useEffect(() => {
+ router.push(
+ `/?тип-дороги=${categories}${
+ queryMap ? `&поиск-на-карте=${queryMap}` : ""
+ }${ratingSearch ? `&поиск-рейтинг=${ratingSearch}` : ""}${
+ activePage === 1 ? "" : `&страница-рейтинг=${activePage}`
+ }`,
+ {
+ scroll: false,
+ }
+ );
+
+ getReports(ratingSearch, activePage);
+ }, [activePage]);
+
const sliceDate = (date: string) => {
return `${date.slice(8, 10)}.${date.slice(5, 7)}.${date.slice(
0,
@@ -177,6 +201,15 @@ const RatingSection: React.FC = ({
+
+
);
};
diff --git a/src/widgets/RatingSection/ratingSectionStore.ts b/src/widgets/RatingSection/ratingSectionStore.ts
index bad7864..8cc4619 100644
--- a/src/widgets/RatingSection/ratingSectionStore.ts
+++ b/src/widgets/RatingSection/ratingSectionStore.ts
@@ -11,7 +11,7 @@ interface IFetchReports extends IList {
interface IRatingStore extends IFetch {
data: IFetchReports;
- getReports: (categories: string) => Promise;
+ getReports: (categories: string, page: number) => Promise;
}
export const useRatingStore = create((set) => ({
@@ -23,12 +23,13 @@ export const useRatingStore = create((set) => ({
},
isLoading: false,
error: "",
- getReports: async (query: string = "") => {
+ getReports: async (query: string = "", page: number = 1) => {
try {
set({ isLoading: true });
- const data = (await apiInstance.get("/report/"))
- .data;
+ const data = (
+ await apiInstance.get(`/report/?page=${page}`)
+ ).data;
const searched = data.results.filter((rating) => {
return rating.location.some((location) => {