2025-01-24 00:19:02 +08:00
|
|
|
import { PostDto, VisitType } from "@nice/common";
|
|
|
|
import { motion } from "framer-motion";
|
|
|
|
import dayjs from "dayjs";
|
2025-01-24 17:39:41 +08:00
|
|
|
|
2025-01-24 11:39:51 +08:00
|
|
|
import { Avatar } from "antd";
|
2025-01-24 00:19:02 +08:00
|
|
|
import { useVisitor } from "@nice/client";
|
2025-01-24 17:39:41 +08:00
|
|
|
import { useContext, useState } from "react";
|
2025-01-24 00:19:02 +08:00
|
|
|
import { PostDetailContext } from "./context/PostDetailContext";
|
2025-01-24 17:39:41 +08:00
|
|
|
import { LikeFilled, LikeOutlined } from "@ant-design/icons";
|
2025-01-24 00:19:02 +08:00
|
|
|
|
|
|
|
export default function PostCommentCard({
|
|
|
|
post,
|
|
|
|
index,
|
2025-01-24 17:39:41 +08:00
|
|
|
isReceiverComment,
|
2025-01-24 00:19:02 +08:00
|
|
|
}: {
|
|
|
|
post: PostDto;
|
|
|
|
index: number;
|
2025-01-24 15:06:57 +08:00
|
|
|
isReceiverComment: boolean;
|
2025-01-24 00:19:02 +08:00
|
|
|
}) {
|
|
|
|
const { user } = useContext(PostDetailContext);
|
2025-01-24 17:39:41 +08:00
|
|
|
const { like, unLike } = useVisitor();
|
|
|
|
const [liked, setLiked] = useState(post?.liked || false);
|
|
|
|
const [likeCount, setLikeCount] = useState(post?.likes || 0);
|
2025-01-24 00:19:02 +08:00
|
|
|
|
|
|
|
async function likeThisPost() {
|
2025-01-24 17:39:41 +08:00
|
|
|
if (!liked) {
|
2025-01-24 00:19:02 +08:00
|
|
|
try {
|
2025-01-24 17:39:41 +08:00
|
|
|
setLikeCount((prev) => prev + 1);
|
|
|
|
setLiked(true);
|
|
|
|
like.mutateAsync({
|
2025-01-24 00:19:02 +08:00
|
|
|
data: {
|
|
|
|
visitorId: user?.id || null,
|
|
|
|
postId: post.id,
|
|
|
|
type: VisitType.LIKE,
|
|
|
|
},
|
|
|
|
});
|
|
|
|
} catch (error) {
|
2025-01-24 11:39:51 +08:00
|
|
|
console.error("Failed to like post:", error);
|
2025-01-24 17:39:41 +08:00
|
|
|
setLikeCount((prev) => prev - 1);
|
|
|
|
setLiked(false);
|
2025-01-24 00:19:02 +08:00
|
|
|
}
|
2025-01-24 17:39:41 +08:00
|
|
|
} else {
|
|
|
|
setLikeCount((prev) => prev - 1);
|
|
|
|
setLiked(false);
|
|
|
|
unLike.mutateAsync({
|
|
|
|
where: {
|
|
|
|
visitorId: user?.id || null,
|
|
|
|
postId: post.id,
|
|
|
|
type: VisitType.LIKE,
|
|
|
|
},
|
|
|
|
});
|
2025-01-24 00:19:02 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return (
|
|
|
|
<motion.div
|
|
|
|
className="bg-white rounded-lg shadow-sm border border-slate-200 p-4"
|
|
|
|
layout>
|
|
|
|
<div className="flex items-start space-x-3">
|
|
|
|
<div className="flex-shrink-0">
|
|
|
|
<Avatar
|
2025-01-24 17:39:41 +08:00
|
|
|
className="ring-2 ring-white hover:ring-[#00538E]/90
|
|
|
|
transition-all duration-200 ease-in-out shadow-md
|
|
|
|
hover:shadow-lg"
|
2025-01-24 00:19:02 +08:00
|
|
|
src={post.author?.avatar}
|
2025-01-24 17:39:41 +08:00
|
|
|
size={40}>
|
|
|
|
{!post.author?.avatar &&
|
|
|
|
(post.author?.showname || "匿名用户")}
|
2025-01-24 11:39:51 +08:00
|
|
|
</Avatar>
|
2025-01-24 00:19:02 +08:00
|
|
|
</div>
|
|
|
|
<div className="flex-1 min-w-0">
|
|
|
|
<div
|
|
|
|
className="flex items-center space-x-2"
|
|
|
|
style={{ height: 40 }}>
|
|
|
|
<span className="font-medium text-slate-900">
|
|
|
|
{post.author?.showname || "匿名用户"}
|
|
|
|
</span>
|
|
|
|
<span className="text-sm text-slate-500">
|
|
|
|
{dayjs(post?.createdAt).format("YYYY-MM-DD HH:mm")}
|
|
|
|
</span>
|
2025-01-24 17:39:41 +08:00
|
|
|
{isReceiverComment && (
|
|
|
|
<span className="inline-flex items-center px-2 py-1 text-xs font-medium rounded-full bg-blue-100 text-blue-800">
|
|
|
|
官方回答
|
|
|
|
</span>
|
|
|
|
)}
|
2025-01-24 00:19:02 +08:00
|
|
|
</div>
|
|
|
|
<div
|
|
|
|
className="ql-editor text-slate-800"
|
|
|
|
style={{
|
|
|
|
padding: 0,
|
|
|
|
}}
|
|
|
|
dangerouslySetInnerHTML={{ __html: post.content || "" }}
|
|
|
|
/>
|
|
|
|
|
|
|
|
{/* 添加有帮助按钮 */}
|
|
|
|
<div className="mt-3 flex items-center">
|
|
|
|
<motion.button
|
|
|
|
onClick={likeThisPost}
|
|
|
|
whileHover={{ scale: 1.05 }}
|
|
|
|
whileTap={{ scale: 0.95 }}
|
|
|
|
className={`inline-flex items-center space-x-1.5 px-3 py-1.5 rounded-full text-sm
|
2025-01-24 17:39:41 +08:00
|
|
|
${
|
|
|
|
liked
|
|
|
|
? "bg-blue-50 text-blue-600"
|
|
|
|
: "hover:bg-slate-50 text-slate-600"
|
|
|
|
} transition-colors duration-200`}>
|
|
|
|
{liked ? <LikeFilled /> : <LikeOutlined />}
|
|
|
|
<span>{likeCount} 有帮助</span>
|
2025-01-24 00:19:02 +08:00
|
|
|
</motion.button>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</motion.div>
|
|
|
|
);
|
|
|
|
}
|