"use client" import { Avatar, AvatarImage, AvatarFallback } from "@/components/ui/avatar" import { Button } from "@/components/ui/button" import { TagBadge } from "@/components/ui/badge" import { InfiniteScrollList } from "@/components/ui/infinite-scroll-list" import RenderContactStatusText from "./components/RenderContactStatusText" import { useHeartbeatRelationListInfinite } from "@/hooks/useIm" import { HeartbeatRelationListOutput } from "@/services/im/types" import { useMemo } from "react" import { useRouter } from "next/navigation" import { Tag } from "@/components/ui/tag" import AIRelationTag from "@/components/features/AIRelationTag" import Link from "next/link" // 联系人数据类型现在使用API返回的数据结构 type ContactItem = HeartbeatRelationListOutput // 联系人卡片组件 const ContactCard = ({ contact }: { contact: ContactItem }) => { const router = useRouter(); // 计算年龄 const age = useMemo(() => { if (!contact.birthday) return null; const birthYear = new Date(contact.birthday).getFullYear(); const currentYear = new Date().getFullYear(); return currentYear - birthYear; }, [contact.birthday]); // 获取性别标识 const getGenderText = (sex?: number) => { switch (sex) { case 0: return "Male"; case 1: return "Female"; case 2: return "Custom"; default: return ""; } }; // 跳转到聊天页面 const handleChatClick = () => { if (contact.aiId) { router.push(`/chat/${contact.aiId}`); } }; return (
{/* 用户信息部分 */}
{/* 头像 */} {(contact.nickname || contact.roleName || 'A').charAt(0)} {/* 用户详细信息 */}
{/* 名字和标签 */}

{contact.nickname || contact.roleName}

{contact.heartbeatLevel && contact.isShow && }
{/* 心动值和用户信息 */}
{/* 心动值 */}
Heart {contact.heartbeatVal || 0}°
{/* 分隔线 */}
{/* 用户详细信息 */} {[ age && `${age}`, contact.characterName, contact.tagName ].filter(Boolean).join(" · ")}
{/* 聊天按钮 */}
) } const ContactsPage = () => { // 使用无限查询获取心动关系列表 const { data, fetchNextPage, hasNextPage, isLoading, isFetchingNextPage, error } = useHeartbeatRelationListInfinite(); // 扁平化所有页面的数据 const allContacts = useMemo(() => { return data?.pages.flatMap(page => page.datas || []) || []; }, [data]); // 加载状态骨架屏组件 const ContactSkeleton = () => (
); // 空状态组件 const EmptyState = () => (
Empty

No crushes found

Start chatting with AI characters to build your crushes

); return (
{/* 页面标题 */}

My Crushes

{/* 心动值统计信息栏 */} 0} /> {/* 联系人列表 */} items={allContacts} renderItem={(contact) => ( )} getItemKey={(contact) => contact.aiId?.toString() || 'unknown'} hasNextPage={!!hasNextPage} isLoading={isLoading || isFetchingNextPage} fetchNextPage={fetchNextPage} columns={1} gap={4} className="!grid-cols-1" // 强制单列布局 LoadingSkeleton={ContactSkeleton} EmptyComponent={EmptyState} hasError={!!error} onRetry={() => window.location.reload()} />
) } export default ContactsPage