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);
|
||||
}
|
||||
|
||||
&__prev {
|
||||
&__prev,
|
||||
&__prev-disabled {
|
||||
border-radius: 8px 0px 0px 8px;
|
||||
}
|
||||
|
||||
&__next {
|
||||
&__next,
|
||||
&__next-disabled {
|
||||
border-radius: 0px 8px 8px 0px;
|
||||
}
|
||||
|
||||
&__next-disabled,
|
||||
&__prev-disabled {
|
||||
cursor: auto;
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
&__page,
|
||||
&__page_active {
|
||||
font-size: 14px;
|
@ -121,7 +121,9 @@ const Pagination: React.FC<IPaginationProps> = ({
|
||||
<button
|
||||
onClick={prevPage}
|
||||
disabled={prev === null}
|
||||
className="pagination__prev"
|
||||
className={`pagination__prev${
|
||||
prev === null ? "-disabled" : ""
|
||||
}`}
|
||||
>
|
||||
<Image src={arrow_left} alt="" />
|
||||
</button>
|
||||
@ -129,7 +131,9 @@ const Pagination: React.FC<IPaginationProps> = ({
|
||||
<button
|
||||
onClick={nextPage}
|
||||
disabled={next === null}
|
||||
className="pagination__next"
|
||||
className={`pagination__next${
|
||||
next === null ? "-disabled" : ""
|
||||
}`}
|
||||
>
|
||||
<Image src={arrow_right} alt="" />
|
||||
</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 { useRouter } from "next/navigation";
|
||||
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 message_icon from "./icons/message.svg";
|
||||
import { useRatingStore } from "./ratingSectionStore";
|
||||
@ -19,7 +17,12 @@ 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";
|
||||
import Pagination from "@/features/Pagination/Pagination";
|
||||
import {
|
||||
sliceDate,
|
||||
sliceDescription,
|
||||
sliceLocation,
|
||||
} from "./helpers";
|
||||
|
||||
interface IRatingSectionProps {
|
||||
[key: string]: string;
|
||||
@ -35,6 +38,10 @@ const RatingSection: React.FC<IRatingSectionProps> = ({
|
||||
queryRating || ""
|
||||
);
|
||||
const [activePage, setActivePage] = useState<number>(+page);
|
||||
const [filter, setFilter] = useState({
|
||||
option: "date",
|
||||
toggle: false,
|
||||
});
|
||||
const router = useRouter();
|
||||
|
||||
const reports = useRatingStore(useShallow((state) => state.data));
|
||||
@ -43,7 +50,7 @@ const RatingSection: React.FC<IRatingSectionProps> = ({
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
getReports(ratingSearch, +page);
|
||||
getReports(ratingSearch, +page, filter);
|
||||
}, []);
|
||||
|
||||
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") {
|
||||
setActivePage(1);
|
||||
@ -83,36 +90,22 @@ const RatingSection: React.FC<IRatingSectionProps> = ({
|
||||
}
|
||||
);
|
||||
|
||||
getReports(ratingSearch, activePage);
|
||||
getReports(ratingSearch, activePage, filter);
|
||||
}, [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 = [
|
||||
{
|
||||
id: 1,
|
||||
name: "Дата",
|
||||
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: "Адрес" },
|
||||
@ -122,14 +115,28 @@ const RatingSection: React.FC<IRatingSectionProps> = ({
|
||||
id: 5,
|
||||
name: "Комментарии",
|
||||
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,
|
||||
name: "Рейтинг",
|
||||
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 { IList } from "@/shared/types/list-type";
|
||||
import { IReport } from "@/shared/types/report-type";
|
||||
import axios from "axios";
|
||||
import { create } from "zustand";
|
||||
|
||||
interface IFetchReports extends IList {
|
||||
@ -11,7 +10,11 @@ interface IFetchReports extends IList {
|
||||
|
||||
interface IRatingStore extends IFetch {
|
||||
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) => ({
|
||||
@ -23,7 +26,11 @@ export const useRatingStore = create<IRatingStore>((set) => ({
|
||||
},
|
||||
isLoading: false,
|
||||
error: "",
|
||||
getReports: async (query: string = "", page: number = 1) => {
|
||||
getReports: async (
|
||||
query: string = "",
|
||||
page: number = 1,
|
||||
filter: { option: string; toggle: boolean }
|
||||
) => {
|
||||
try {
|
||||
set({ isLoading: true });
|
||||
|
||||
@ -41,6 +48,46 @@ export const useRatingStore = create<IRatingStore>((set) => ({
|
||||
|
||||
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 });
|
||||
} catch (error: any) {
|
||||
set({ error: error.message });
|
||||
|
@ -1,28 +1,30 @@
|
||||
import { ROAD_TYPES_STATS } from "@/shared/variables/road-types";
|
||||
import "./StatisticsSection.scss";
|
||||
import { statiscsSectionStore } from "./statisticsSection.store";
|
||||
import { apiInstance } from "@/shared/config/apiConfig";
|
||||
|
||||
interface ICategoryStatistics {
|
||||
category: number;
|
||||
total: number;
|
||||
}
|
||||
|
||||
const StatisticsSection = async () => {
|
||||
// const { getStatsCount, getErrorMessage } = statiscsSectionStore();
|
||||
// const statistics = await getStatsCount();
|
||||
// const error = getErrorMessage();
|
||||
const getCategoryStatistics = async () => {
|
||||
const res = await apiInstance.get<ICategoryStatistics[]>(
|
||||
"/report/category_count/"
|
||||
);
|
||||
|
||||
const mockArray = [
|
||||
{ category: 1, count: 132 },
|
||||
{ category: 2, count: 12 },
|
||||
{ category: 3, count: 1432 },
|
||||
{ category: 4, count: 18 },
|
||||
{ category: 5, count: 95 },
|
||||
{ category: 6, count: 54 },
|
||||
];
|
||||
return res.data;
|
||||
};
|
||||
|
||||
const statistics = await getCategoryStatistics();
|
||||
|
||||
return (
|
||||
<section className="statistics-section">
|
||||
<ul className="statistics-section__list">
|
||||
{mockArray.map((cat) => (
|
||||
{statistics.map((cat) => (
|
||||
<li key={cat.category}>
|
||||
<p>{ROAD_TYPES_STATS[cat.category]}</p>
|
||||
<span>{cat.count}</span>
|
||||
<span>{cat.total}</span>
|
||||
</li>
|
||||
))}
|
||||
</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