kgroad-frontend2/src/widgets/ReviewSection/ReviewSection.tsx
2024-04-13 18:57:36 +00:00

227 lines
6.2 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"use client";
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, useRef, useState } from "react";
import calendar from "./icons/calendar.svg";
import Image from "next/image";
import {
Link,
usePathname,
useRouter,
} from "@/shared/config/navigation";
import Loader from "@/shared/ui/components/Loader/Loader";
interface IReviewsSectionProps {
endpoint: string;
id: number;
}
const ReviewSection: React.FC<IReviewsSectionProps> = ({
endpoint,
id,
}: IReviewsSectionProps) => {
const lastElement = useRef<HTMLDivElement | null>(null);
const observer = useRef<IntersectionObserver | null>(null);
const [reviews, setReviews] = useState<IReviewList>({
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<number>(8);
const [reviewCount, setReviewCount] = useState<number>(0);
const [loader, setLoader] = useState<boolean>(false);
const pathname = usePathname();
const session = useSession();
const handleSubmit: React.MouseEventHandler<
HTMLFormElement
> = async (e) => {
e.preventDefault();
const Authorization = `Bearer ${session.data?.access_token}`;
const formData = new FormData(e.currentTarget);
const config = {
headers: {
Authorization,
},
};
if (session.status === "unauthenticated") {
signIn(undefined, { callbackUrl: pathname });
}
if (!formData.get("review")) {
return;
}
formData.append("news", id.toString());
try {
const res = await apiInstance.post(
`/${endpoint}/${id}/reviews/`,
formData,
config
);
getReviews();
} catch (error) {
console.log(error);
}
};
const getReviews = async () => {
setLoader(true);
const response = await apiInstance.get<IReviewList>(
`/${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) {
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<string, string> = {
"01": "Январь",
"02": "Февраль",
"03": "Март",
"04": "Апрель",
"05": "Май",
"06": "Июнь",
"07": "Июль",
"08": "Август",
"09": "Сентябрь",
"10": "Октябрь",
"11": "Ноябрь",
"12": "Декабрь",
};
const def = process.env.NEXT_PUBLIC_PROFILE_AVATAR_URL as string;
return (
<section className="review-section">
<h3>
<span id="blue-point" /> Написать комментарий
</h3>
{session.status === "authenticated" ? (
<form onSubmit={handleSubmit}>
<textarea name="review" />
<button type="submit">Отправить</button>
</form>
) : (
<p className="review-section__auth-warning">
Перед тем как оставить комментарий, пожалуйста
<button
onClick={() =>
signIn(undefined, { callbackUrl: pathname })
}
>
войдите в аккаунт
</button>
</p>
)}
<div className="review-section__list">
<h3>
<span id="blue-point" /> Комментарии
</h3>
{reviews?.results.length !== 0 ? (
<ul key="unuqie key">
{reviews?.results.map((review) => (
<li key={review.id} className="review">
<div className="review__author">
<img
id="author-img"
src={review.author.image ? review.author.image : def}
alt="Author Imagex2"
/>
<div className="review__header">
<h5 className="review__author-name">
{review.author.first_name}{" "}
{review.author.last_name}
</h5>
<div className="review__date">
<Image src={calendar} alt="Calendar Icon" />
<p>
{months[review.created_at.slice(5, 7)]}{" "}
{review.created_at.slice(5, 7).slice(0, 1) ===
"0"
? review.created_at.slice(6, 7)
: review.created_at.slice(5, 7)}
, {review.created_at.slice(0, 4)}
</p>
</div>
</div>
</div>
<p className="review__description">{review.review}</p>
</li>
))}
</ul>
) : (
<p className="review-section__warning">
Оставьте комментарий первым
</p>
)}
{loader ? (
<div className="review-section__loader">
<Loader color="#000" />
</div>
) : null}
<div
ref={lastElement}
className="review-section__list_bottom"
></div>
</div>
</section>
);
};
export default ReviewSection;