그룹채팅 - Part6 방장의 권한(2) - 강퇴
ㆍProject Diary/Next.js + Prisma + MariaDB (KiloFlow)
방장이 특정 사용자를 강제로 퇴장시키는 기능에 대해서 설명하겠습니다.
프론트엔드
1. 참여 사용자 목록 가져오기
특정 채팅방의 사용자 목록을 가져오는 API를 호출하여 참여 사용자 목록을 상태에 저장합니다.
const fetchParticipatingUsers = async () => {
const res = await fetch(`/api/community/current-chatroom-info?roomId=${roomId}&action=users`);
const data = await res.json();
setParticipatingUsers(data); // 참여 사용자 목록을 상태에 저장
};
2. 방장 여부 확인
현재 사용자가 방장인지 확인하기 위해 채팅방 정보를 가져오는 API를 호출합니다.
const checkIfOwner = async () => {
const res = await fetch(`/api/community/current-chatroom-info?roomId=${roomId}&action=info`);
const data = await res.json();
if (currentUser && data.owner_id === currentUser.user_id) {
setIsOwner(true); // 현재 사용자가 방장인 경우 isOwner 상태를 true로 설정
}
setChatroomInfo(data); // 채팅방 정보를 상태에 저장
};
3. 사용자 강퇴 기능 구현
강퇴 요청이 성공하면 최신 사용자 목록을 가져옵니다.
const kickUser = async (userId: number, userNickname: string) => {
if (confirm(`${userNickname}님을 강제로 퇴장시키겠습니까?`)) {
const res = await fetch(`/api/community/join`, {
method: "DELETE",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
chatroom_id: roomId,
user_id: userId,
action: "kick",
}),
});
if (res.ok) {
fetchParticipatingUsers(); // 강퇴 후 최신 사용자 목록을 가져옴
socket.emit("kick_room", {
roomId,
user: { userId: userId, nickname: userNickname },
}); // 다른 사용자들에게 강퇴 메시지를 전송
router.push("/community/list"); // 강퇴 후 채팅방 목록으로 이동
} else {
alert("사용자 강퇴에 실패했습니다."); // 강퇴 요청이 실패한 경우
}
}
};
- kickUser
- 강퇴 확인 후 API 요청을 보내고, 성공 시 최신 사용자 목록을 가져옵니다.
- 다른 사용자들에게 강퇴 메시지를 전송하고, 채팅방 목록으로 이동합니다.
4. 사용자 목록 렌더링 및 강퇴 버튼 추가
참여 중인 사용자 목록을 렌더링하고, 방장인 경우 강퇴 버튼을 표시합니다.
{participatingUsers.map((user) => (
<div className="user__item" key={user.user_id}>
<Image
src={user.profile_image}
alt="유저프로필"
width={50}
height={50}
/> {/* 사용자 프로필 이미지를 보여줌 */}
<span>{user.nickname}</span> {/* 사용자 닉네임을 보여줌 */}
{user.user_id === chatroomInfo?.owner_id && <span>(방장)</span>} {/* 방장을 표시 */}
{isOwner && user.user_id !== chatroomInfo?.owner_id && (
<button
className="kick"
onClick={() => kickUser(user.user_id, user.nickname)}
>
강퇴
</button> {/* 방장일 경우, 다른 사용자에게 강퇴 버튼을 보여줌 */}
)}
</div>
))}
백엔드
1. 사용자 강퇴 API 엔드포인트
// pages/api/community/join.ts
import { NextApiRequest, NextApiResponse } from "next";
import prisma from "../../../lib/prisma";
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
if (req.method === "DELETE") {
const { chatroom_id, user_id, action } = req.body;
if (action === "kick") {
try {
// 사용자를 채팅방에서 강퇴
await prisma.chatroom_members.deleteMany({
where: {
chatroom_id: Number(chatroom_id),
user_id: Number(user_id),
},
});
res.status(200).json({ message: "User kicked successfully" }); // 강퇴 성공 시 응답
} catch (error) {
res.status(500).json({ error: "Error kicking user" }); // 오류 발생 시 응답
}
} else {
res.status(400).json({ message: "Invalid action" }); // 유효하지 않은 action
}
} else {
res.setHeader("Allow", ["DELETE"]); // 허용되지 않는 메서드에 대한 응답 설정
res.status(405).end(`Method ${req.method} Not Allowed`); // 405 상태 코드 응답
}
}