forked from Transparency/kgroad-frontend2
made filters in rating section
This commit is contained in:
parent
a12aaa1213
commit
d4c49a1061
@ -12,14 +12,22 @@
|
|||||||
background-color: rgb(255, 255, 255);
|
background-color: rgb(255, 255, 255);
|
||||||
}
|
}
|
||||||
|
|
||||||
&__prev {
|
&__prev,
|
||||||
|
&__prev-disabled {
|
||||||
border-radius: 8px 0px 0px 8px;
|
border-radius: 8px 0px 0px 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
&__next {
|
&__next,
|
||||||
|
&__next-disabled {
|
||||||
border-radius: 0px 8px 8px 0px;
|
border-radius: 0px 8px 8px 0px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&__next-disabled,
|
||||||
|
&__prev-disabled {
|
||||||
|
cursor: auto;
|
||||||
|
opacity: 0.7;
|
||||||
|
}
|
||||||
|
|
||||||
&__page,
|
&__page,
|
||||||
&__page_active {
|
&__page_active {
|
||||||
font-size: 14px;
|
font-size: 14px;
|
@ -121,7 +121,9 @@ const Pagination: React.FC<IPaginationProps> = ({
|
|||||||
<button
|
<button
|
||||||
onClick={prevPage}
|
onClick={prevPage}
|
||||||
disabled={prev === null}
|
disabled={prev === null}
|
||||||
className="pagination__prev"
|
className={`pagination__prev${
|
||||||
|
prev === null ? "-disabled" : ""
|
||||||
|
}`}
|
||||||
>
|
>
|
||||||
<Image src={arrow_left} alt="" />
|
<Image src={arrow_left} alt="" />
|
||||||
</button>
|
</button>
|
||||||
@ -129,7 +131,9 @@ const Pagination: React.FC<IPaginationProps> = ({
|
|||||||
<button
|
<button
|
||||||
onClick={nextPage}
|
onClick={nextPage}
|
||||||
disabled={next === null}
|
disabled={next === null}
|
||||||
className="pagination__next"
|
className={`pagination__next${
|
||||||
|
next === null ? "-disabled" : ""
|
||||||
|
}`}
|
||||||
>
|
>
|
||||||
<Image src={arrow_right} alt="" />
|
<Image src={arrow_right} alt="" />
|
||||||
</button>
|
</button>
|
Before Width: | Height: | Size: 417 B After Width: | Height: | Size: 417 B |
Before Width: | Height: | Size: 416 B After Width: | Height: | Size: 416 B |
@ -4,8 +4,6 @@ import Image from "next/image";
|
|||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import { useRouter } from "next/navigation";
|
import { useRouter } from "next/navigation";
|
||||||
import SearchForm from "@/features/SearchForm/SearchForm";
|
import SearchForm from "@/features/SearchForm/SearchForm";
|
||||||
import arrow_down_icon from "./icons/arrow-down.svg";
|
|
||||||
import arrow_up_icon from "./icons/arrow-up.svg";
|
|
||||||
import like_icon from "./icons/like.svg";
|
import like_icon from "./icons/like.svg";
|
||||||
import message_icon from "./icons/message.svg";
|
import message_icon from "./icons/message.svg";
|
||||||
import { useRatingStore } from "./ratingSectionStore";
|
import { useRatingStore } from "./ratingSectionStore";
|
||||||
@ -19,7 +17,12 @@ import RoadType from "@/entities/RoadType/RoadType";
|
|||||||
import Typography from "@/shared/ui/components/Typography/Typography";
|
import Typography from "@/shared/ui/components/Typography/Typography";
|
||||||
import Paragraph from "@/shared/ui/components/Paragraph/Paragraph";
|
import Paragraph from "@/shared/ui/components/Paragraph/Paragraph";
|
||||||
import arrows from "../../shared/icons/arrows.svg";
|
import arrows from "../../shared/icons/arrows.svg";
|
||||||
import Pagination from "@/entities/Pagination/Pagination";
|
import Pagination from "@/features/Pagination/Pagination";
|
||||||
|
import {
|
||||||
|
sliceDate,
|
||||||
|
sliceDescription,
|
||||||
|
sliceLocation,
|
||||||
|
} from "./helpers";
|
||||||
|
|
||||||
interface IRatingSectionProps {
|
interface IRatingSectionProps {
|
||||||
[key: string]: string;
|
[key: string]: string;
|
||||||
@ -35,6 +38,10 @@ const RatingSection: React.FC<IRatingSectionProps> = ({
|
|||||||
queryRating || ""
|
queryRating || ""
|
||||||
);
|
);
|
||||||
const [activePage, setActivePage] = useState<number>(+page);
|
const [activePage, setActivePage] = useState<number>(+page);
|
||||||
|
const [filter, setFilter] = useState({
|
||||||
|
option: "date",
|
||||||
|
toggle: false,
|
||||||
|
});
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
||||||
const reports = useRatingStore(useShallow((state) => state.data));
|
const reports = useRatingStore(useShallow((state) => state.data));
|
||||||
@ -43,7 +50,7 @@ const RatingSection: React.FC<IRatingSectionProps> = ({
|
|||||||
);
|
);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
getReports(ratingSearch, +page);
|
getReports(ratingSearch, +page, filter);
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const handleSubmit: React.FormEventHandler<
|
const handleSubmit: React.FormEventHandler<
|
||||||
@ -64,7 +71,7 @@ const RatingSection: React.FC<IRatingSectionProps> = ({
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
getReports(ratingSearch, activePage);
|
getReports(ratingSearch, activePage, filter);
|
||||||
|
|
||||||
if (reports.results.length < 8 && page !== "1") {
|
if (reports.results.length < 8 && page !== "1") {
|
||||||
setActivePage(1);
|
setActivePage(1);
|
||||||
@ -83,36 +90,22 @@ const RatingSection: React.FC<IRatingSectionProps> = ({
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
getReports(ratingSearch, activePage);
|
getReports(ratingSearch, activePage, filter);
|
||||||
}, [activePage]);
|
}, [activePage]);
|
||||||
|
|
||||||
const sliceDate = (date: string) => {
|
|
||||||
return `${date.slice(8, 10)}.${date.slice(5, 7)}.${date.slice(
|
|
||||||
0,
|
|
||||||
4
|
|
||||||
)}`;
|
|
||||||
};
|
|
||||||
|
|
||||||
const sliceLocation = (location: string) => {
|
|
||||||
if (location.length > 15) return `${location.slice(0, 15)}...`;
|
|
||||||
|
|
||||||
return location;
|
|
||||||
};
|
|
||||||
|
|
||||||
const sliceDescription = (description: string) => {
|
|
||||||
if (description.length > 49) {
|
|
||||||
return `${description.slice(0, 50)}...`;
|
|
||||||
}
|
|
||||||
|
|
||||||
return description;
|
|
||||||
};
|
|
||||||
|
|
||||||
const params = [
|
const params = [
|
||||||
{
|
{
|
||||||
id: 1,
|
id: 1,
|
||||||
name: "Дата",
|
name: "Дата",
|
||||||
handleClick() {
|
handleClick() {
|
||||||
console.log(this.name);
|
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: 2, name: "Адрес" },
|
||||||
@ -122,14 +115,28 @@ const RatingSection: React.FC<IRatingSectionProps> = ({
|
|||||||
id: 5,
|
id: 5,
|
||||||
name: "Комментарии",
|
name: "Комментарии",
|
||||||
handleClick() {
|
handleClick() {
|
||||||
console.log(this.name);
|
if (filter.option !== "reviews") {
|
||||||
|
return setFilter({ option: "reviews", toggle: false });
|
||||||
|
}
|
||||||
|
|
||||||
|
setFilter((prev) => {
|
||||||
|
return { option: "reviews", toggle: !prev.toggle };
|
||||||
|
});
|
||||||
|
getReports(ratingSearch, activePage, filter);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 6,
|
id: 6,
|
||||||
name: "Рейтинг",
|
name: "Рейтинг",
|
||||||
handleClick() {
|
handleClick() {
|
||||||
console.log(this.name);
|
if (filter.option !== "rating") {
|
||||||
|
return setFilter({ option: "rating", toggle: false });
|
||||||
|
}
|
||||||
|
|
||||||
|
setFilter((prev) => {
|
||||||
|
return { option: "rating", toggle: !prev.toggle };
|
||||||
|
});
|
||||||
|
getReports(ratingSearch, activePage, filter);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
20
src/widgets/RatingSection/helpers.ts
Normal file
20
src/widgets/RatingSection/helpers.ts
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
export const sliceDate = (date: string) => {
|
||||||
|
return `${date.slice(8, 10)}.${date.slice(5, 7)}.${date.slice(
|
||||||
|
0,
|
||||||
|
4
|
||||||
|
)}`;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const sliceLocation = (location: string) => {
|
||||||
|
if (location.length > 15) return `${location.slice(0, 15)}...`;
|
||||||
|
|
||||||
|
return location;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const sliceDescription = (description: string) => {
|
||||||
|
if (description.length > 49) {
|
||||||
|
return `${description.slice(0, 50)}...`;
|
||||||
|
}
|
||||||
|
|
||||||
|
return description;
|
||||||
|
};
|
@ -2,7 +2,6 @@ import { apiInstance } from "@/shared/config/apiConfig";
|
|||||||
import { IFetch } from "@/shared/types/fetch-type";
|
import { IFetch } from "@/shared/types/fetch-type";
|
||||||
import { IList } from "@/shared/types/list-type";
|
import { IList } from "@/shared/types/list-type";
|
||||||
import { IReport } from "@/shared/types/report-type";
|
import { IReport } from "@/shared/types/report-type";
|
||||||
import axios from "axios";
|
|
||||||
import { create } from "zustand";
|
import { create } from "zustand";
|
||||||
|
|
||||||
interface IFetchReports extends IList {
|
interface IFetchReports extends IList {
|
||||||
@ -11,7 +10,11 @@ interface IFetchReports extends IList {
|
|||||||
|
|
||||||
interface IRatingStore extends IFetch {
|
interface IRatingStore extends IFetch {
|
||||||
data: IFetchReports;
|
data: IFetchReports;
|
||||||
getReports: (categories: string, page: number) => Promise<void>;
|
getReports: (
|
||||||
|
categories: string,
|
||||||
|
page: number,
|
||||||
|
filter: { option: string; toggle: boolean }
|
||||||
|
) => Promise<void>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const useRatingStore = create<IRatingStore>((set) => ({
|
export const useRatingStore = create<IRatingStore>((set) => ({
|
||||||
@ -23,7 +26,11 @@ export const useRatingStore = create<IRatingStore>((set) => ({
|
|||||||
},
|
},
|
||||||
isLoading: false,
|
isLoading: false,
|
||||||
error: "",
|
error: "",
|
||||||
getReports: async (query: string = "", page: number = 1) => {
|
getReports: async (
|
||||||
|
query: string = "",
|
||||||
|
page: number = 1,
|
||||||
|
filter: { option: string; toggle: boolean }
|
||||||
|
) => {
|
||||||
try {
|
try {
|
||||||
set({ isLoading: true });
|
set({ isLoading: true });
|
||||||
|
|
||||||
@ -41,6 +48,46 @@ export const useRatingStore = create<IRatingStore>((set) => ({
|
|||||||
|
|
||||||
data.results = [...searched];
|
data.results = [...searched];
|
||||||
|
|
||||||
|
if (filter.option === "date" && filter.toggle === false) {
|
||||||
|
data.results = data.results.sort((a, b) => {
|
||||||
|
const dateA = new Date(a.created_at) as unknown as number;
|
||||||
|
const dateB = new Date(b.created_at) as unknown as number;
|
||||||
|
return dateA - dateB;
|
||||||
|
});
|
||||||
|
} else if (filter.option === "date" && filter.toggle === true) {
|
||||||
|
data.results = data.results.sort((a, b) => {
|
||||||
|
const dateA = new Date(a.created_at) as unknown as number;
|
||||||
|
const dateB = new Date(b.created_at) as unknown as number;
|
||||||
|
return dateB - dateA;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (filter.option === "reviews" && filter.toggle === false) {
|
||||||
|
data.results = data.results.sort(
|
||||||
|
(a, b) => a.count_reviews - b.count_reviews
|
||||||
|
);
|
||||||
|
} else if (
|
||||||
|
filter.option === "reviews" &&
|
||||||
|
filter.toggle === true
|
||||||
|
) {
|
||||||
|
data.results = data.results.sort(
|
||||||
|
(a, b) => b.count_reviews - a.count_reviews
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (filter.option === "rating" && filter.toggle === false) {
|
||||||
|
data.results = data.results.sort(
|
||||||
|
(a, b) => a.total_likes - b.total_likes
|
||||||
|
);
|
||||||
|
} else if (
|
||||||
|
filter.option === "rating" &&
|
||||||
|
filter.toggle === true
|
||||||
|
) {
|
||||||
|
data.results = data.results.sort(
|
||||||
|
(a, b) => b.total_likes - a.total_likes
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
set({ data: data });
|
set({ data: data });
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
set({ error: error.message });
|
set({ error: error.message });
|
||||||
|
@ -1,28 +1,30 @@
|
|||||||
import { ROAD_TYPES_STATS } from "@/shared/variables/road-types";
|
import { ROAD_TYPES_STATS } from "@/shared/variables/road-types";
|
||||||
import "./StatisticsSection.scss";
|
import "./StatisticsSection.scss";
|
||||||
import { statiscsSectionStore } from "./statisticsSection.store";
|
import { apiInstance } from "@/shared/config/apiConfig";
|
||||||
|
|
||||||
|
interface ICategoryStatistics {
|
||||||
|
category: number;
|
||||||
|
total: number;
|
||||||
|
}
|
||||||
|
|
||||||
const StatisticsSection = async () => {
|
const StatisticsSection = async () => {
|
||||||
// const { getStatsCount, getErrorMessage } = statiscsSectionStore();
|
const getCategoryStatistics = async () => {
|
||||||
// const statistics = await getStatsCount();
|
const res = await apiInstance.get<ICategoryStatistics[]>(
|
||||||
// const error = getErrorMessage();
|
"/report/category_count/"
|
||||||
|
);
|
||||||
|
|
||||||
const mockArray = [
|
return res.data;
|
||||||
{ category: 1, count: 132 },
|
};
|
||||||
{ category: 2, count: 12 },
|
|
||||||
{ category: 3, count: 1432 },
|
const statistics = await getCategoryStatistics();
|
||||||
{ category: 4, count: 18 },
|
|
||||||
{ category: 5, count: 95 },
|
|
||||||
{ category: 6, count: 54 },
|
|
||||||
];
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<section className="statistics-section">
|
<section className="statistics-section">
|
||||||
<ul className="statistics-section__list">
|
<ul className="statistics-section__list">
|
||||||
{mockArray.map((cat) => (
|
{statistics.map((cat) => (
|
||||||
<li key={cat.category}>
|
<li key={cat.category}>
|
||||||
<p>{ROAD_TYPES_STATS[cat.category]}</p>
|
<p>{ROAD_TYPES_STATS[cat.category]}</p>
|
||||||
<span>{cat.count}</span>
|
<span>{cat.total}</span>
|
||||||
</li>
|
</li>
|
||||||
))}
|
))}
|
||||||
</ul>
|
</ul>
|
||||||
|
@ -1,35 +0,0 @@
|
|||||||
import { apiInstance } from "@/shared/config/apiConfig";
|
|
||||||
import { AxiosError } from "axios";
|
|
||||||
|
|
||||||
interface IStatsCount {
|
|
||||||
category: number;
|
|
||||||
count: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const statiscsSectionStore = () => {
|
|
||||||
let errorMessage = "";
|
|
||||||
async function getStatsCount() {
|
|
||||||
try {
|
|
||||||
const response = await apiInstance.get<IStatsCount[]>(
|
|
||||||
"/report/category_count/"
|
|
||||||
);
|
|
||||||
|
|
||||||
return response.data;
|
|
||||||
} catch (error: unknown) {
|
|
||||||
if (error instanceof AxiosError) {
|
|
||||||
errorMessage = error.message;
|
|
||||||
} else {
|
|
||||||
errorMessage = "An error ocured";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function getErrorMessage() {
|
|
||||||
return errorMessage;
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
getStatsCount,
|
|
||||||
getErrorMessage,
|
|
||||||
};
|
|
||||||
};
|
|
Loading…
Reference in New Issue
Block a user