forked from Transparency/kgroad-frontend2
237 lines
7.0 KiB
TypeScript
237 lines
7.0 KiB
TypeScript
"use client";
|
||
import "./RatingSection.scss";
|
||
import Image from "next/image";
|
||
import { useEffect, useState } from "react";
|
||
import { useRouter } from "next/navigation";
|
||
import SearchForm from "@/features/SearchForm/SearchForm";
|
||
import like_icon from "./icons/like.svg";
|
||
import message_icon from "./icons/message.svg";
|
||
import { useRatingStore } from "./ratingSectionStore";
|
||
import { useShallow } from "zustand/react/shallow";
|
||
import Link from "next/link";
|
||
import {
|
||
ROAD_TYPES,
|
||
ROAD_TYPES_COLORS,
|
||
} from "@/shared/variables/road-types";
|
||
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 "@/features/Pagination/Pagination";
|
||
import {
|
||
sliceDate,
|
||
sliceDescription,
|
||
sliceLocation,
|
||
} from "./helpers";
|
||
|
||
interface IRatingSectionProps {
|
||
searchParams: {
|
||
["тип-дороги"]: string;
|
||
["поиск-на-карте"]: string;
|
||
["поиск-рейтинг"]: string;
|
||
["страница-рейтинга"]: string;
|
||
};
|
||
}
|
||
|
||
const RatingSection: React.FC<IRatingSectionProps> = ({
|
||
searchParams,
|
||
}: IRatingSectionProps) => {
|
||
const [ratingSearch, setRatingSearch] = useState<string>(
|
||
searchParams["поиск-рейтинг"] || ""
|
||
);
|
||
const [activePage, setActivePage] = useState<number>(
|
||
+searchParams["страница-рейтинга"] || 1
|
||
);
|
||
const [filter, setFilter] = useState({
|
||
option: "date",
|
||
toggle: false,
|
||
});
|
||
const router = useRouter();
|
||
|
||
const reports = useRatingStore(useShallow((state) => state.data));
|
||
const getReports = useRatingStore(
|
||
useShallow((state) => state.getReports)
|
||
);
|
||
|
||
useEffect(() => {
|
||
getReports(ratingSearch, activePage, filter);
|
||
}, []);
|
||
|
||
const handleSubmit: React.FormEventHandler<
|
||
HTMLFormElement
|
||
> = async (e) => {
|
||
e.preventDefault();
|
||
const formData = new FormData(e.currentTarget);
|
||
setRatingSearch(formData.get("rating-search") as string);
|
||
|
||
router.push(
|
||
`/?тип-дороги=${searchParams["тип-дороги"] || "1,2,3,4,5,6"}${
|
||
searchParams["поиск-на-карте"]
|
||
? `&поиск-на-карте=${searchParams["поиск-на-карте"] || ""}`
|
||
: ""
|
||
}${
|
||
ratingSearch ? `&поиск-рейтинг=${ratingSearch || ""}` : ""
|
||
}&страница-рейтинга=${searchParams["страница-рейтинга"]}`,
|
||
{
|
||
scroll: false,
|
||
}
|
||
);
|
||
|
||
getReports(ratingSearch, activePage, filter);
|
||
|
||
if (
|
||
reports.results.length < 8 &&
|
||
searchParams["страница-рейтинга"] !== "1"
|
||
) {
|
||
setActivePage(1);
|
||
}
|
||
};
|
||
|
||
useEffect(() => {
|
||
router.push(
|
||
`/?тип-дороги=${searchParams["тип-дороги"] || "1,2,3,4,5,6"}${
|
||
searchParams["поиск-на-карте"]
|
||
? `&поиск-на-карте=${searchParams["поиск-на-карте"] || ""}`
|
||
: ""
|
||
}${ratingSearch ? `&поиск-рейтинг=${ratingSearch || ""}` : ""}${
|
||
activePage === 1 ? "" : `&страница-рейтинг=${activePage}`
|
||
}`,
|
||
{
|
||
scroll: false,
|
||
}
|
||
);
|
||
|
||
getReports(ratingSearch, activePage, filter);
|
||
}, [activePage]);
|
||
|
||
const params = [
|
||
{
|
||
id: 1,
|
||
name: "Дата",
|
||
handleClick() {
|
||
if (filter.option !== "date") {
|
||
return setFilter({ option: "date", toggle: false });
|
||
}
|
||
|
||
setFilter((prev) => {
|
||
return { option: "date", toggle: !prev.toggle };
|
||
});
|
||
getReports(ratingSearch, activePage, filter);
|
||
},
|
||
},
|
||
{ id: 2, name: "Адрес" },
|
||
{ id: 3, name: "Статус" },
|
||
{ id: 4, name: "Описание" },
|
||
{
|
||
id: 5,
|
||
name: "Комментарии",
|
||
handleClick() {
|
||
if (filter.option !== "reviews") {
|
||
return setFilter({ option: "reviews", toggle: false });
|
||
}
|
||
|
||
setFilter((prev) => {
|
||
return { option: "reviews", toggle: !prev.toggle };
|
||
});
|
||
getReports(ratingSearch, activePage, filter);
|
||
},
|
||
},
|
||
{
|
||
id: 6,
|
||
name: "Рейтинг",
|
||
handleClick() {
|
||
if (filter.option !== "rating") {
|
||
return setFilter({ option: "rating", toggle: false });
|
||
}
|
||
|
||
setFilter((prev) => {
|
||
return { option: "rating", toggle: !prev.toggle };
|
||
});
|
||
getReports(ratingSearch, activePage, filter);
|
||
},
|
||
},
|
||
];
|
||
|
||
return (
|
||
<section className="rating-section">
|
||
<div className="rating-section__header">
|
||
<Typography element="h3">Рейтинг</Typography>
|
||
<Paragraph>
|
||
Обсуждаем дороги: рейтинг, опыт, комфорт в пути!
|
||
</Paragraph>
|
||
</div>
|
||
<SearchForm
|
||
onChange={(e) => setRatingSearch(e.target.value)}
|
||
name="rating-search"
|
||
placeholder="Введите адрес"
|
||
value={ratingSearch}
|
||
handleSubmit={handleSubmit}
|
||
/>
|
||
<div className="rating-section__table">
|
||
<table>
|
||
<thead>
|
||
<tr>
|
||
{params.map((p) => (
|
||
<td key={p.id}>
|
||
{p.handleClick ? (
|
||
<button onClick={p.handleClick}>
|
||
{p.name}
|
||
<Image src={arrows} alt="Up and Down Arrows" />
|
||
</button>
|
||
) : (
|
||
p.name
|
||
)}
|
||
</td>
|
||
))}
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
{reports.results.map((report) => (
|
||
<tr key={report.id}>
|
||
<td id="rating-section-date">
|
||
{sliceDate(report.created_at)}
|
||
</td>
|
||
<td id="rating-section-link">
|
||
<Link href={`/report/${report.id}`}>
|
||
{sliceLocation(report.location[0].address)}
|
||
</Link>
|
||
</td>
|
||
<td>
|
||
<RoadType
|
||
color={ROAD_TYPES_COLORS[report.category]}
|
||
>
|
||
{ROAD_TYPES[report.category]}
|
||
</RoadType>
|
||
</td>
|
||
<td id="rating-section-description">
|
||
{sliceDescription(report.description)}
|
||
</td>
|
||
<td id="rating-section-reviews">
|
||
<Image src={message_icon} alt="Message Icon" />
|
||
{report.count_reviews}
|
||
</td>
|
||
<td id="rating-section-likes">
|
||
<Image src={like_icon} alt="Like Icon" />
|
||
{report.total_likes}
|
||
</td>
|
||
</tr>
|
||
))}
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
|
||
<Pagination
|
||
setActivePage={setActivePage}
|
||
activePage={activePage}
|
||
count={reports.count as number}
|
||
next={reports.next}
|
||
prev={reports.previous}
|
||
current_count={reports.results.length}
|
||
limit={8}
|
||
/>
|
||
</section>
|
||
);
|
||
};
|
||
|
||
export default RatingSection;
|