crush-level-web/src/app/(main)/profile/components/CharacterCard.tsx

99 lines
3.4 KiB
TypeScript
Raw Normal View History

2025-11-13 08:38:25 +00:00
import { Tag } from "@/components/ui/tag";
import { cn, formatNumberToKMB } from "@/lib/utils";
import { AIPermission, AiUserBaseListOutput } from "@/services/create";
import Image from "next/image";
import Link from "next/link";
const CharacterCard = ({
character,
isHovered,
onHover
}: {
character: AiUserBaseListOutput;
isHovered: boolean;
onHover: (hovered: boolean) => void;
}) => {
// 根据权限判断是否私密
const isPrivate = character.permission === AIPermission.Private;
return (
<Link href={`/@${character.aiId}`}>
<div
className="flex flex-col gap-3 min-w-[200px] w-full grow basis-0 group"
onMouseEnter={() => onHover(true)}
onMouseLeave={() => onHover(false)}
>
{/* 角色图片 */}
<div
className="pb-[133%] bg-center bg-cover bg-no-repeat rounded-lg relative overflow-hidden"
style={{
// backgroundImage: character.homeImageUrl ? `url('${character.homeImageUrl}')` : 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)'
}}
>
<Image
src={character.homeImageUrl ?? ''}
alt={character.nickname ?? ''}
fill
className="object-cover object-top"
sizes="100%"
/>
{/* 私密标识 */}
<div className="absolute top-2 right-2 z-[1] bg-surface-element-dark-normal rounded-xs backdrop-blur-xs w-6 h-6 flex items-center justify-center">
<i className={cn("!text-[12px] iconfont", {
'icon-eye-off': isPrivate,
'icon-eye-on': !isPrivate,
})} />
</div>
{/* 底部遮罩层 */}
<div className={cn("absolute bottom-0 left-0 right-0 bg-gradient-to-b from-transparent to-black pb-3 px-3 flex flex-col justify-end", {
'pt-6': !isHovered,
'pt-12 h-full': isHovered,
})}>
{/* 描述文字 - hover时显示带过渡动效 */}
<div
className={cn("text-white txt-body-m transition-all duration-300 ease-in-out transform line-clamp-6 overflow-hidden mb-2", {
'max-h-0 opacity-0': !isHovered,
'max-h-max h-full opacity-100': isHovered,
})}
>
{character.introduction || ''}
</div>
{/* 点赞数 - 暂时用固定值实际应该从API获取 */}
<div className="flex items-center gap-1 h-6 px-1 py-0.5">
{/* <img src={likeIcon} alt="点赞" className="w-3 h-3" /> */}
<i className="iconfont icon-Like-fill" />
<span className="text-white text-xs font-medium">{formatNumberToKMB(character.likedNum ?? 0)}</span>
</div>
</div>
</div>
{/* 角色信息 */}
<div className="flex flex-col gap-2">
{/* 角色名称 */}
<div className="txt-title-m truncate">
{character.nickname}
</div>
{/* 标签 */}
<div className="flex flex-wrap gap-1">
{/* 性格标签 */}
{character.characterName && (
<Tag size="small">{character.characterName}</Tag>
)}
{/* 标签 */}
{character.tagName && (
<Tag size="small">{character.tagName}</Tag>
)}
</div>
</div>
</div>
</Link>
);
};
export default CharacterCard;