1) (글 쓴 본인은 제외한) 사람들 팔로우, 언팔로우
2) 내 정보에서 언팔로우
3) 내 정보에서 맞팔로우
import { useDispatch, useSelector } from "react-redux";
const dispatch = useDispatch();
const { me } = useSelector((state) => state.user);
const { mainPosts } = useSelector((state) => state.post);
return (
{mainPosts.map((post, index) => {
return (
<PostCard key={post.id} post={post} index={index} me={me} />
//props로 post, me값 전달
);
})}
)
const PostCard = ({ post, index, me }) => {
const dispatch = useDispatch();
const id = useSelector((state) => state.user.me?.id);
const liked = post.Likers?.find((v) => v.id === id);
const isFollowing = me?.Followings.find((v) => v.id === post.User.id);
return (
{id === post.UserId ? null : (
<p className="text-sm">
{isFollowing ? "언팔로우" : "팔로우"}
</p>
)})
const dispatch = useDispatch();
const { me } = useSelector((state) => state.user);
const { mainPosts } = useSelector((state) => state.post);
const { wordLists } = useSelector((state) => state.word);
return (
<Profile me={me} postResult={postResult} wordResult={wordResult} />
)
const Profile = ({ me, postResult, wordResult }) => {
const dispatch = useDispatch();
const [followerModal, setFollowerModal] = useState(false);
const [followingModal, setFollowingModal] = useState(false);
//버튼 누르면 각각 setFollowerModal, setFollowingModal이 true가 되도록 함
return (
{followingModal ? (
<FollowingModal
setFollowingModal={setFollowingModal}
followingsInfo={me?.Followings}
/>
) : null}
{followerModal ? (
<FollowerModal
setFollowerModal={setFollowerModal}
followersInfo={me?.Followers}
followingsInfo={me?.Followings}
/>
) : null}
)
const FollowerModal = ({ setFollowerModal, followersInfo, followingsInfo }) => {
const onClickFollowUp = (id) => () => {
dispatch(followRequest(id));
};
return (
{followersInfo.map((follower) => {
return (
<div
key={follower.id}
className="mt-3 flex items-center space-x-4"
>
<div className="flex-shrink-0">
<img
className="ml-2 w-8 h-8 rounded-full"
src="/docs/images/people/profile-picture-1.jpg"
alt="Neil image"
/>
</div>
<div className="flex-1 min-w-0">
<p className="text-sm font-medium text-gray-900 truncate">
{follower.nickname}
</p>
<p className="text-sm text-gray-500 truncate dark:text-gray-400">
{follower.email}
</p>
</div>
{followingsInfo.find(
(following) =>
following.id === follower.id
) ? null : (
<button
onClick={onClickFollowUp(follower.id)}
className="bg-light-green text-white hover:bg-light-beige hover:text-red-500 rounded inline-flex items-center text-base font-semibold text-gray-900"
>
맞팔로우
</button>
)}
</div>
);
})}
)
}
const FollowingModal = ({ setFollowingModal, followingsInfo }) => {
const dispatch = useDispatch();
const onClickUnFollow = (id) => () => {
dispatch(unfollowRequest(id));
};
return (
<div className="mt-3 w-96 p-4 border rounded-lg shadow-md">
<div className="flex items-center justify-between mb-4">
<h5 className="text-xl font-bold leading-none text-gray-900">
팔로잉 수 : {followingsInfo.length}
</h5>
<a
href="#"
className="text-sm font-medium text-blue-600 hover:underline dark:text-blue-500"
>
View all
</a>
</div>
<div className="flow-root">
<ul
role="list"
className="divide-y divide-gray-200 dark:divide-gray-700"
>
<li className="py-3">
{followingsInfo.map((following) => {
return (
<div className="flex items-center space-x-4">
<div className="flex-shrink-0">
<img
className="ml-2 w-8 h-8 rounded-full"
src="/docs/images/people/profile-picture-1.jpg"
alt="Neil image"
/>
</div>
<div className="flex-1 min-w-0">
<p className="text-sm font-medium text-gray-900 truncate">
{following.nickname}
</p>
<p className="text-sm text-gray-500 truncate dark:text-gray-400">
{following.email}
</p>
</div>
<button
onClick={onClickUnFollow(following.id)}
className="bg-red-500 text-white hover:bg-light-beige hover:text-red-500 rounded inline-flex items-center text-base font-semibold text-gray-900"
>
언팔로우
</button>
</div>
);
})}
</li>
</ul>
</div>
</div>
)
function followAPI(data) {
return axios.patch(`/user/${data}/follow`);
}
function* follow(action) {
try {
const data = action.payload;
console.log("data", data);
const result = yield call(followAPI, data);
yield put(followSuccess(result.data));
} catch (error) {
yield put(followFailure(error));
console.log(error);
}
}
function unfollowAPI(data) {
return axios.delete(`/user/${data}/follow`);
}
function* unfollow(action) {
try {
const data = action.payload;
const result = yield call(unfollowAPI, data);
yield put(unfollowSuccess(result.data));
} catch (error) {
yield put(unfollowFailure(error));
console.log(error);
}
}
followSuccess: (state, action) => {
const data = action.payload;
state.followLoading = false;
state.followComplete = true;
state.me.Followings.push({ id: data.UserId });
},
unfollowSuccess: (state, action) => {
const data = action.payload;
state.unfollowLoading = false;
state.unfollowComplete = true;
state.me.Followings = state.me.Followings.filter(
(v) => v.id !== data.UserId
);
},
router.patch("/:userId/follow", isLoggedIn, async (req, res, next) => {
// PATCH /user/1/follow
try {
const user = await User.findOne({ where: { id: req.params.userId } });
if (!user) {
res.status(403).send("없는 사람을 팔로우하려고 하시네요?");
}
await user.addFollowers(req.user.id);
res.status(200).json({ UserId: parseInt(req.params.userId, 10) });
} catch (error) {
console.error(error);
next(error);
}
});
router.delete("/:userId/follow", isLoggedIn, async (req, res, next) => {
// DELETE /user/1/follow
try {
const user = await User.findOne({ where: { id: req.params.userId } });
if (!user) {
res.status(403).send("없는 사람을 언팔로우하려고 하시네요?");
}
await user.removeFollowers(req.user.id);
res.status(200).json({ UserId: parseInt(req.params.userId, 10) });
} catch (error) {
console.error(error);
next(error);
}
});