forked from Transparency/kgroad-frontend2
217 lines
6.5 KiB
TypeScript
217 lines
6.5 KiB
TypeScript
"use client";
|
|
|
|
import "./RatingSection.scss";
|
|
import Image from "next/image";
|
|
import { useEffect, useState } from "react";
|
|
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 { 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 { sliceDescription, sliceLocation } from "./helpers";
|
|
import { Link, useRouter } from "@/shared/config/navigation";
|
|
import { useTranslations } from "next-intl";
|
|
|
|
interface IRatingSectionProps {
|
|
searchParams: {
|
|
["тип-дороги"]: string;
|
|
["поиск-на-карте"]: string;
|
|
["поиск-рейтинг"]: string;
|
|
["страница-рейтинга"]: string;
|
|
};
|
|
}
|
|
|
|
const RatingSection: React.FC<IRatingSectionProps> = ({
|
|
searchParams,
|
|
}: IRatingSectionProps) => {
|
|
const tHome = useTranslations("home");
|
|
const tGeneral = useTranslations("general");
|
|
|
|
const [ratingSearch, setRatingSearch] = useState<string>(
|
|
searchParams["поиск-рейтинг"] || ""
|
|
);
|
|
const [activePage, setActivePage] = useState<number>(
|
|
+searchParams["страница-рейтинга"] || 1
|
|
);
|
|
const [sort, setSort] = useState<string>("");
|
|
const router = useRouter();
|
|
|
|
const reports = useRatingStore(useShallow((state) => state.data));
|
|
const getReports = useRatingStore(
|
|
useShallow((state) => state.getReports)
|
|
);
|
|
|
|
useEffect(() => {
|
|
getReports(ratingSearch, activePage, sort);
|
|
}, [sort]);
|
|
|
|
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, sort);
|
|
|
|
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, sort);
|
|
}, [activePage]);
|
|
|
|
const params = [
|
|
{
|
|
id: 1,
|
|
name: tGeneral("date"),
|
|
handleClick() {
|
|
setSort("");
|
|
},
|
|
},
|
|
{ id: 2, name: tGeneral("address") },
|
|
{ id: 3, name: tGeneral("status") },
|
|
{ id: 4, name: tGeneral("description") },
|
|
{
|
|
id: 5,
|
|
name: tGeneral("reviews"),
|
|
handleClick() {
|
|
setSort("reviews");
|
|
},
|
|
},
|
|
{
|
|
id: 6,
|
|
name: tGeneral("rating"),
|
|
handleClick() {
|
|
setSort("likes");
|
|
},
|
|
},
|
|
];
|
|
|
|
const ROAD_TYPES: Record<number, string> = {
|
|
1: tHome("broken_roads"),
|
|
2: tHome("accident_hotspots"),
|
|
3: tHome("local_defects"),
|
|
4: tHome("repair_plans"),
|
|
5: tHome("repaired"),
|
|
6: tHome("fixed_local_defects"),
|
|
};
|
|
|
|
return (
|
|
<section className="rating-section">
|
|
<div className="rating-section__header">
|
|
<Typography element="h3">{tHome("rating")}</Typography>
|
|
<Paragraph>{tHome("road_discussions")}</Paragraph>
|
|
</div>
|
|
<SearchForm
|
|
onChange={(e) => setRatingSearch(e.target.value)}
|
|
name="rating-search"
|
|
placeholder={tHome("enter_address")}
|
|
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">
|
|
{new Date(report.created_at).toLocaleDateString()}
|
|
</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;
|