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

107 lines
3.5 KiB
TypeScript
Raw 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.

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="group flex w-full min-w-[200px] grow basis-0 flex-col gap-3"
onMouseEnter={() => onHover(true)}
onMouseLeave={() => onHover(false)}
>
{/* 角色图片 */}
<div
className="relative overflow-hidden rounded-lg bg-cover bg-center bg-no-repeat pb-[133%]"
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="bg-surface-element-dark-normal absolute top-2 right-2 z-[1] flex h-6 w-6 items-center justify-center rounded-xs backdrop-blur-xs">
<i
className={cn('iconfont !text-[12px]', {
'icon-eye-off': isPrivate,
'icon-eye-on': !isPrivate,
})}
/>
</div>
{/* 底部遮罩层 */}
<div
className={cn(
'absolute right-0 bottom-0 left-0 flex flex-col justify-end bg-gradient-to-b from-transparent to-black px-3 pb-3',
{
'pt-6': !isHovered,
'h-full pt-12': isHovered,
}
)}
>
{/* 描述文字 - hover时显示带过渡动效 */}
<div
className={cn(
'txt-body-m mb-2 line-clamp-6 transform overflow-hidden text-white transition-all duration-300 ease-in-out',
{
'max-h-0 opacity-0': !isHovered,
'h-full max-h-max opacity-100': isHovered,
}
)}
>
{character.introduction || ''}
</div>
{/* 点赞数 - 暂时用固定值实际应该从API获取 */}
<div className="flex h-6 items-center gap-1 px-1 py-0.5">
{/* <img src={likeIcon} alt="点赞" className="w-3 h-3" /> */}
<i className="iconfont icon-Like-fill" />
<span className="text-xs font-medium text-white">
{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