API مسیرهای تصویر را نسبی برمیگرداند (/uploads/...) که next/image روی دامنه localhost میجست و 404 میداد. helper جدید imageUrl مسیرهای نسبی uploads را با NEXT_PUBLIC_API_URL کامل میکند (absolute و asset محلی دستنخورده). اعمال روی لیست/جزئیات پزشک، نوبت، گالری کلینیک، آواتارها. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
173 lines
5.3 KiB
JavaScript
173 lines
5.3 KiB
JavaScript
import Image from "next/image";
|
|
import { imageUrl } from "@/helper";
|
|
import { Button, CircularProgress } from "@mui/material";
|
|
|
|
// Icons
|
|
import BoldDisLikeComment from "@/components/icons/BoldDisLikeComment";
|
|
import BoldLikeComment from "@/components/icons/BoldLikeComment";
|
|
import DisLikeComment from "@/components/icons/DisLikeComment";
|
|
import LikeComment from "@/components/icons/LikeComment";
|
|
import Replies from "./Replies";
|
|
import AnswerField from "./AnswerField";
|
|
import SendAnswer from "./SendAnswer";
|
|
import { alert, isUserLoggedIn, timeAgo } from "@/helper";
|
|
import { request } from "@/services/response";
|
|
import { useState } from "react";
|
|
|
|
function ItemUser({ update, setUpdate, data }) {
|
|
const [loadingLike, setLoadingLike] = useState(false);
|
|
const [loadingDislike, setLoadingDislike] = useState(false);
|
|
|
|
const SendReq = async (type) => {
|
|
if (type === "like") setLoadingLike(true);
|
|
else setLoadingDislike(true);
|
|
|
|
const body = {
|
|
comment_id: data.id,
|
|
like: type === "like" ? 1 : 0,
|
|
};
|
|
|
|
try {
|
|
const res = await request.postCommentsLike(body);
|
|
} catch (err) {
|
|
// err
|
|
} finally {
|
|
if (type === "like") setLoadingLike(false);
|
|
else setLoadingDislike(false);
|
|
}
|
|
};
|
|
|
|
const handleLike = (data, type) => {
|
|
SendReq(type);
|
|
|
|
const { current_user_like } = data.like_status;
|
|
|
|
if (type === "like") {
|
|
if (current_user_like.like) {
|
|
data.like_status.like_count -= 1;
|
|
current_user_like.like = false;
|
|
} else {
|
|
data.like_status.like_count += 1;
|
|
current_user_like.like = true;
|
|
if (current_user_like.dislike) {
|
|
data.like_status.dislike_count -= 1;
|
|
current_user_like.dislike = false;
|
|
}
|
|
}
|
|
} else {
|
|
if (current_user_like.dislike) {
|
|
data.like_status.dislike_count -= 1;
|
|
current_user_like.dislike = false;
|
|
} else {
|
|
data.like_status.dislike_count += 1;
|
|
current_user_like.dislike = true;
|
|
if (current_user_like.like) {
|
|
data.like_status.like_count -= 1;
|
|
current_user_like.like = false;
|
|
}
|
|
}
|
|
}
|
|
|
|
setUpdate(!update);
|
|
};
|
|
|
|
return (
|
|
<li className="w-full">
|
|
<div className="flex items-center justify-start gap-2">
|
|
<Image
|
|
className="!w-[32px] !h-[32px]"
|
|
src={imageUrl(data.author?.picture?.[0]?.url)}
|
|
width={40}
|
|
height={40}
|
|
alt="profile"
|
|
/>
|
|
<div className="flex flex-col items-start justify-center gap-[8px]">
|
|
<p className="text-[#343A40] text-[14px] md:text-[16px] font-medium">
|
|
{data.author.real_name}
|
|
</p>
|
|
<p className="text-[#7E7E7E] text-[12px] md:text-[14px] font-medium">
|
|
{timeAgo(data.created)}
|
|
</p>
|
|
</div>
|
|
</div>
|
|
<div className="mt-2">
|
|
<p className="text-[#495057] text-[12px] md:text-[14px]">
|
|
{data.comment}
|
|
</p>
|
|
|
|
<div className="flex items-center justify-start mt-2 gap-[28px]">
|
|
{/* لایک */}
|
|
<div className="flex items-center justify-start gap-1">
|
|
<div
|
|
className="cursor-pointer"
|
|
onClick={() => handleLike(data, "like")}
|
|
>
|
|
{loadingLike ? (
|
|
<CircularProgress
|
|
className="!w-[24px] !h-[24px]"
|
|
sx={{ color: "#7E7E7E" }}
|
|
/>
|
|
) : data.like_status.current_user_like.like ? (
|
|
<BoldLikeComment />
|
|
) : (
|
|
<LikeComment />
|
|
)}
|
|
</div>
|
|
<p className="text-[#6C757D] text-[12px] select-none">
|
|
{data.like_status.like_count || ""}
|
|
</p>
|
|
</div>
|
|
|
|
{/* دیسلایک */}
|
|
<div className="flex items-center justify-start gap-1">
|
|
<div
|
|
className="cursor-pointer"
|
|
onClick={() => handleLike(data, "dislike")}
|
|
>
|
|
{loadingDislike ? (
|
|
<CircularProgress
|
|
className="!w-[24px] !h-[24px]"
|
|
sx={{ color: "#7E7E7E" }}
|
|
/>
|
|
) : data.like_status.current_user_like.dislike ? (
|
|
<BoldDisLikeComment />
|
|
) : (
|
|
<DisLikeComment />
|
|
)}
|
|
</div>
|
|
<p className="text-[#6C757D] text-[12px] select-none">
|
|
{data.like_status.dislike_count || ""}
|
|
</p>
|
|
</div>
|
|
|
|
<Button
|
|
className="!text-[#495057] !text-[12px] !font-medium"
|
|
onClick={() => {
|
|
if (isUserLoggedIn()) {
|
|
data.is_open_answer = !data.is_open_answer;
|
|
setUpdate(!update);
|
|
} else {
|
|
alert(
|
|
"warning",
|
|
"برای ارسال کامنت باید ابتدا وارد حساب کاربری شوید."
|
|
);
|
|
}
|
|
}}
|
|
variant="text"
|
|
>
|
|
پاسخ
|
|
</Button>
|
|
</div>
|
|
|
|
<SendAnswer data={data} />
|
|
{!!data.replies.length && (
|
|
<AnswerField data={data} update={update} setUpdate={setUpdate} />
|
|
)}
|
|
<Replies data={data} update={update} setUpdate={setUpdate} />
|
|
</div>
|
|
</li>
|
|
);
|
|
}
|
|
|
|
export default ItemUser;
|