All files / src/components/pages/chat/chat-user-list index.tsx

28% Statements 35/125
100% Branches 0/0
0% Functions 0/2
28% Lines 35/125

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 1261x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x                                                                       1x 1x                                                                                                                
'use client';
 
import { useState } from 'react';
 
import { Icon } from '@/components/icon';
import { ProfileImage } from '@/components/shared';
import { useModal } from '@/components/ui';
import { useGetParticipants } from '@/hooks/use-chat';
 
import { UserOutModal } from './UserOutModal';
 
interface UserProps {
  user: {
    userId: number;
    nickName: string;
    profileImage: string;
    profileMessage?: string;
    isOwner: boolean;
  };
  roomId: number;
  roomType: 'DM' | 'GROUP';
  isManaging: boolean;
  index: number;
}
 
interface UserListProps {
  onClose: () => void;
  roomId: number;
  roomType: 'DM' | 'GROUP';
  userId: number;
}
 
const User = ({ user, roomId, roomType, isManaging, index }: UserProps) => {
  const { open } = useModal();

  return (
    <div className='bg-mono-white flex h-22 items-center gap-4 p-5'>
      <div className='h-12 w-12 overflow-hidden rounded-full'>
        <ProfileImage size='md' src={user.profileImage} />
      </div>

      <div className='flex-1'>
        <div className='text-text-md-bold text-gray-800'>{user.nickName}</div>
        <div className='text-text-sm-medium line-clamp-1 text-gray-600'>
          {user.profileMessage || '상태 메시지가 없습니다.'}
        </div>
      </div>

      {roomType === 'GROUP' && user.isOwner && (
        <span className='bg-mint-100 text-mint-700 text-text-xs-medium rounded-full px-2.5 py-1'>
          방장
        </span>
      )}

      {isManaging && index !== 0 && (
        <button
          className='bg-error-500 flex h-5 w-5 items-center justify-center rounded-full'
          onClick={(e) => {
            e.stopPropagation();
            open(<UserOutModal nickName={user.nickName} roomId={roomId} userId={user.userId} />);
          }}
        >
          <div className='bg-mono-white h-0.5 w-2.5' />
        </button>
      )}
    </div>
  );
};
 
export const UserList = ({ onClose, roomId, roomType, userId }: UserListProps) => {
  const [isManaging, setIsManaging] = useState(false);
  const { data } = useGetParticipants(roomId);

  const isCurrentUserOwner = data?.participants.some(
    (participant) => participant.userId === userId && participant.isOwner,
  );
  const sortedParticipants = data?.participants
    ? [...data.participants].sort((a, b) => {
        if (a.isOwner === b.isOwner) return 0;
        return a.isOwner ? -1 : 1;
      })
    : [];

  return (
    <div className='bg-mono-white flex h-[calc(100vh-112px)] flex-col'>
      {/* 헤더 */}
      <div className='flex items-center justify-between border-b border-gray-200 px-5 py-3'>
        <Icon id='chevron-left-2' className='w-6 cursor-pointer text-gray-500' onClick={onClose} />
        <span className='text-text-md-bold flex items-center gap-1'>
          <span className='text-gray-800'>참여자</span>
          <span className='text-mint-500'>{data?.totalCount}</span>
        </span>
        {roomType === 'GROUP' && isCurrentUserOwner ? (
          <button
            className='text-text-sm-semibold cursor-pointer'
            onClick={() => setIsManaging(!isManaging)}
          >
            {isManaging ? (
              <span className='w-6 text-gray-600'>완료</span>
            ) : (
              <span className='text-mint-600 w-6'>관리</span>
            )}
          </button>
        ) : (
          <div className='w-6'></div>
        )}
      </div>

      {/* 유저 리스트 */}
      <div className='scrollbar-thin flex-1 overflow-y-auto'>
        {sortedParticipants.map((user, index) => (
          <div key={user.userId}>
            <User
              index={index}
              isManaging={isManaging}
              roomId={roomId}
              roomType={roomType}
              user={user}
            />
          </div>
        ))}
      </div>
    </div>
  );
};