diff --git a/src/app/[locale]/report/[id]/page.tsx b/src/app/[locale]/report/[id]/page.tsx
index ca97f3b..bc18787 100644
--- a/src/app/[locale]/report/[id]/page.tsx
+++ b/src/app/[locale]/report/[id]/page.tsx
@@ -33,7 +33,7 @@ const ReportDetails = async ({
return res.json();
};
- const report: IReport = await getReportDetails();
+ const report: IReport = (await getReportDetails()) || {};
return (
diff --git a/src/shared/types/list-type.ts b/src/shared/types/list-type.ts
index 5676a34..b425a68 100644
--- a/src/shared/types/list-type.ts
+++ b/src/shared/types/list-type.ts
@@ -1,5 +1,5 @@
export interface IList {
- count: number | null;
+ count: number;
previous: string | null;
next: string | null;
}
diff --git a/src/shared/ui/components/Loader/Loader.tsx b/src/shared/ui/components/Loader/Loader.tsx
index 6842803..e75796f 100644
--- a/src/shared/ui/components/Loader/Loader.tsx
+++ b/src/shared/ui/components/Loader/Loader.tsx
@@ -1,7 +1,16 @@
import "./Loader.scss";
-const Loader = () => {
- return
;
+interface ILoader {
+ color?: string;
+}
+
+const Loader: React.FC
= ({ color }: ILoader) => {
+ return (
+
+ );
};
export default Loader;
diff --git a/src/widgets/ReviewSection/ReviewSection.scss b/src/widgets/ReviewSection/ReviewSection.scss
index 17cb30b..9d5a673 100644
--- a/src/widgets/ReviewSection/ReviewSection.scss
+++ b/src/widgets/ReviewSection/ReviewSection.scss
@@ -46,6 +46,11 @@
}
}
+ &__loader {
+ display: flex;
+ justify-content: center;
+ }
+
form {
margin-bottom: 70px;
display: flex;
diff --git a/src/widgets/ReviewSection/ReviewSection.tsx b/src/widgets/ReviewSection/ReviewSection.tsx
index 3bbeffb..868879c 100644
--- a/src/widgets/ReviewSection/ReviewSection.tsx
+++ b/src/widgets/ReviewSection/ReviewSection.tsx
@@ -4,7 +4,7 @@ import "./ReviewSection.scss";
import { apiInstance } from "@/shared/config/apiConfig";
import { IReviewList } from "@/shared/types/review-type";
import { signIn, useSession } from "next-auth/react";
-import { useEffect, useState } from "react";
+import { useEffect, useRef, useState } from "react";
import calendar from "./icons/calendar.svg";
import Image from "next/image";
import {
@@ -12,6 +12,7 @@ import {
usePathname,
useRouter,
} from "@/shared/config/navigation";
+import Loader from "@/shared/ui/components/Loader/Loader";
interface IReviewsSectionProps {
endpoint: string;
@@ -22,7 +23,30 @@ const ReviewSection: React.FC = ({
endpoint,
id,
}: IReviewsSectionProps) => {
- const [reviews, setReviews] = useState();
+ const lastElement = useRef(null);
+ const observer = useRef(null);
+ const [reviews, setReviews] = useState({
+ count: 0,
+ next: null,
+ previous: null,
+ results: [
+ {
+ id: 0,
+ author: {
+ image: "",
+ id: 0,
+ first_name: "",
+ last_name: "",
+ govern_status: null,
+ },
+ review: "",
+ created_at: "",
+ },
+ ],
+ });
+ const [pageSize, setPageSize] = useState(8);
+ const [reviewCount, setReviewCount] = useState(0);
+ const [loader, setLoader] = useState(false);
const pathname = usePathname();
const session = useSession();
const handleSubmit: React.MouseEventHandler<
@@ -55,6 +79,7 @@ const ReviewSection: React.FC = ({
formData,
config
);
+
getReviews();
} catch (error) {
console.log(error);
@@ -62,15 +87,45 @@ const ReviewSection: React.FC = ({
};
const getReviews = async () => {
+ setLoader(true);
const response = await apiInstance.get(
- `/${endpoint}/${id}/reviews/?page_size=8`
+ `/${endpoint}/${id}/reviews/?page_size=${pageSize}`
);
+
+ setReviewCount(response.data.count);
+ setLoader(false);
+ setReviews({
+ count: response.data.count,
+ next: response.data.next,
+ previous: response.data.previous,
+ results: [...reviews?.results, ...response.data.results],
+ });
setReviews(response?.data);
};
+ useEffect(() => {
+ if (loader) return;
+ if (observer.current) observer.current.disconnect();
+ const callback = function (entries: any) {
+ console.log(reviewCount, pageSize);
+ if (
+ entries[0].isIntersecting &&
+ (reviews?.results.length as number) <= reviewCount
+ ) {
+ if (pageSize < reviewCount) {
+ setPageSize((prev) => prev + 8);
+ } else {
+ setPageSize(reviewCount);
+ }
+ }
+ };
+ observer.current = new IntersectionObserver(callback);
+ observer.current.observe(lastElement.current as HTMLDivElement);
+ }, [loader]);
+
useEffect(() => {
getReviews();
- }, []);
+ }, [pageSize]);
const months: Record = {
"01": "Январь",
@@ -86,6 +141,7 @@ const ReviewSection: React.FC = ({
"11": "Ноябрь",
"12": "Декабрь",
};
+
return (
@@ -116,7 +172,7 @@ const ReviewSection: React.FC = ({
{reviews?.results.length !== 0 ? (
-
+
{reviews?.results.map((review) => (
-
@@ -152,6 +208,15 @@ const ReviewSection: React.FC
= ({
Оставьте комментарий первым :)
)}
+ {loader ? (
+
+
+
+ ) : null}
+
);