- 新增 Follow 表和 User.bio 字段 (Prisma schema)
- 创建 follow 模块 (action-service-repository)
- 新增 FollowButton/FollowStats/UserList 组件
- 用户页面显示 bio、粉丝/关注数、关注按钮
- 新增 /users/[username]/followers 和 following 页面
- 添加 en-US/zh-CN i18n 翻译
⚠️ 需要运行: prisma migrate dev --name add_follow_and_bio
48 lines
1.4 KiB
TypeScript
48 lines
1.4 KiB
TypeScript
"use client";
|
|
|
|
import { useState, useTransition } from "react";
|
|
import { PrimaryButton, LightButton } from "@/design-system/base/button";
|
|
import { actionToggleFollow } from "@/modules/follow/follow-action";
|
|
import { toast } from "sonner";
|
|
|
|
interface FollowButtonProps {
|
|
targetUserId: string;
|
|
initialIsFollowing: boolean;
|
|
onFollowChange?: (isFollowing: boolean, followersCount: number) => void;
|
|
}
|
|
|
|
export function FollowButton({
|
|
targetUserId,
|
|
initialIsFollowing,
|
|
onFollowChange,
|
|
}: FollowButtonProps) {
|
|
const [isFollowing, setIsFollowing] = useState(initialIsFollowing);
|
|
const [isPending, startTransition] = useTransition();
|
|
|
|
const handleToggleFollow = () => {
|
|
startTransition(async () => {
|
|
const result = await actionToggleFollow({ targetUserId });
|
|
if (result.success && result.data) {
|
|
setIsFollowing(result.data.isFollowing);
|
|
onFollowChange?.(result.data.isFollowing, result.data.followersCount);
|
|
} else {
|
|
toast.error(result.message || "Failed to update follow status");
|
|
}
|
|
});
|
|
};
|
|
|
|
if (isFollowing) {
|
|
return (
|
|
<LightButton onClick={handleToggleFollow} disabled={isPending}>
|
|
{isPending ? "..." : "Following"}
|
|
</LightButton>
|
|
);
|
|
}
|
|
|
|
return (
|
|
<PrimaryButton onClick={handleToggleFollow} disabled={isPending}>
|
|
{isPending ? "..." : "Follow"}
|
|
</PrimaryButton>
|
|
);
|
|
}
|