doctor-mail/apps/web/src/components/models/post/LetterCard.tsx

128 lines
5.8 KiB
TypeScript
Raw Normal View History

2025-01-25 19:51:08 +08:00
import {
2025-01-25 21:22:20 +08:00
EyeOutlined,
LikeOutlined,
LikeFilled,
UserOutlined,
BankOutlined,
CalendarOutlined,
FileTextOutlined,
SendOutlined,
2025-01-25 19:51:08 +08:00
} from "@ant-design/icons";
import { Button, Typography, Space, Tooltip } from "antd";
2025-01-25 22:32:46 +08:00
import { PostDto, PostStateLabels } from "@nice/common";
2025-01-25 19:51:08 +08:00
import dayjs from "dayjs";
2025-01-25 21:22:20 +08:00
import PostLikeButton from "./detail/PostHeader/PostLikeButton";
2025-01-25 22:32:46 +08:00
import { LetterBadge } from "./LetterBadge";
2025-01-24 15:05:03 +08:00
const { Title, Paragraph, Text } = Typography;
2025-01-22 23:19:58 +08:00
interface LetterCardProps {
2025-01-25 21:22:20 +08:00
letter: PostDto;
2025-01-22 23:19:58 +08:00
}
export function LetterCard({ letter }: LetterCardProps) {
2025-01-25 21:22:20 +08:00
return (
2025-01-25 22:32:46 +08:00
<div onClick={() => {
window.open(`/${letter.id}/detail`)
}}
className=" cursor-pointer w-full p-6 bg-white rounded-xl group relative overflow-hidden duration-300 hover:-translate-y-1 transition-all ease-in-out "
>
<div className="flex flex-col gap-4">
2025-01-25 21:22:20 +08:00
<div className="flex justify-between items-start">
2025-01-25 22:32:46 +08:00
<Title level={4} className="!mb-0 flex-1 font-serif tracking-tight text-gray-800">
2025-01-25 21:22:20 +08:00
<a
href={`/${letter.id}/detail`}
2025-01-25 21:22:20 +08:00
target="_blank"
2025-01-25 22:32:46 +08:00
className="text-primary hover:text-primary-600 transition-colors duration-200 hover:underline">
2025-01-25 21:22:20 +08:00
{letter.title}
</a>
</Title>
</div>
{/* Meta Info */}
2025-01-25 22:32:46 +08:00
<div className="flex justify-between items-center text-sm text-gray-500">
<div className="flex items-center gap-6">
<div className="flex items-center gap-2">
<UserOutlined className="text-secondary-400 text-base" />
<Text className="text-gray-600 font-medium">
2025-01-25 21:22:20 +08:00
{letter.author?.showname || '匿名用户'}
</Text>
2025-01-25 22:32:46 +08:00
</div>
{letter.receivers.some(item => item.department?.name) && (
<div className="flex items-center gap-2">
<BankOutlined className="text-secondary-400 text-base" />
<Tooltip title={letter.receivers.map(item => item.department?.name).filter(Boolean).join(', ')}>
<Text className="text-gray-600">
{letter.receivers
.map(item => item.department?.name)
.filter(Boolean)
.slice(0, 2)
.join('、')}
{letter.receivers.filter(item => item.department?.name).length > 2 && ' 等'}
</Text>
</Tooltip>
</div>
)}
{letter.receivers.some(item => item.showname) && (
<div className="flex items-center gap-2">
<SendOutlined className="text-secondary-400 text-base" />
<Tooltip title={letter.receivers.map(item => item.showname).filter(Boolean).join(', ')}>
<Text className="text-gray-600">
{letter.receivers
.map(item => item.showname)
.filter(Boolean)
.slice(0, 2)
.join('、')}
{letter.receivers.filter(item => item.showname).length > 2 && ' 等'}
</Text>
</Tooltip>
</div>
)}
</div>
<div className="flex items-center gap-2">
<CalendarOutlined className="text-secondary-400 text-base" />
<Text className="text-gray-500">
2025-01-25 21:22:20 +08:00
{dayjs(letter.createdAt).format("YYYY-MM-DD")}
</Text>
2025-01-25 22:32:46 +08:00
</div>
2025-01-25 21:22:20 +08:00
</div>
2025-01-22 23:19:58 +08:00
2025-01-25 21:22:20 +08:00
{/* Content Preview */}
{letter.content && (
2025-01-25 22:32:46 +08:00
<Paragraph
ellipsis={{ rows: 2 }}
className="!mb-4 text-gray-600 flex-1 leading-relaxed text-sm font-sans">
{letter.content}
</Paragraph>
2025-01-25 21:22:20 +08:00
)}
2025-01-25 22:32:46 +08:00
<div className="flex flex-wrap gap-2">
<LetterBadge type="state" value={letter.state} />
{letter.meta.tags.map(tag => (
<LetterBadge key={tag} type="tag" value={tag} />
))}
</div>
2025-01-25 21:22:20 +08:00
{/* Badges & Interactions */}
2025-01-25 22:32:46 +08:00
<div className="flex justify-between items-center ">
<div className="flex flex-wrap gap-2">
{letter.terms.map(term => (
<LetterBadge key={term.name} type="category" value={term.name} />
))}
</div>
2025-01-24 15:05:03 +08:00
2025-01-25 21:22:20 +08:00
<div className="flex items-center gap-4">
2025-01-25 22:32:46 +08:00
<Button
type="default"
shape="round"
icon={<EyeOutlined />}
>
{letter.views}
</Button>
2025-01-25 21:22:20 +08:00
<PostLikeButton post={letter as any}></PostLikeButton>
</div>
</div>
</div>
</div>
);
2025-01-22 23:19:58 +08:00
}