[탐나예] 어드민 개별 인재 관리 페이지

AnSuebin·2022년 10월 7일
0

[탐나예]프로젝트

목록 보기
4/4
post-thumbnail

탐나예 어드민 개별 인재 관리 페이지 기능 및 코드 소개
1. 어드민 개별 인재 관리 페이지 간단 기능 소개
2. 코드 소개

00. 들어가기전에

  • 어드민 개별 인재 관리 페이지는 메인과 예약 페이지를 만들며, CORS의 GET만 사용한 부분이 아쉬워 담당한 파트입니다.
  • 데이터를 받아올 뿐만 아니라, 지우고, 수정, 추가까지 모두 할 수 있었습니다.

01. 어드민 개별 인재 관리 페이지 간단 기능 소개

  • 교육생을 개별적으로 추가, 수정, 삭제할 수 있습니다.

02. 코드 소개

2-1. 교육생 데이터 받아오기
2-1-1) 부트스트랩의 드롭다운을 사용하여 기수 데이터 목록을 보여주고, 클릭시 관련 데이터 받아 아래에 보여주도록 구현
1) classList fetch를 통해 데이터 받아오기

const [classList, setClassList] = useState([]);

  // 드롭다운에 사용될 class들 가져오기//
  const url = `http://${myUrl}/admin/view/class-list`;
  useEffect(() => {
    fetchGet(url, navigate).then((data) => {
      setClassList(data?.ClassList);
    });
  }, [url, myUrl, navigate]);

2) 기수 목록 드롭다운으로 가져오기

<DropdownButton
   style={{
       marginTop: '10px',
       fontSize: '12px',
       textAalign: 'center',
   }}
   id="dropdown-item-button"
   title={classPickState}
>
   {classList.map((classes) => (
        <Dropdown.Item
              style={{
                   marginLeft: '3px',
                   marginRight: '3px',
                   fontSize: '13px',
                    textAalign: 'center',
              }}
              as="button"
              key={classes}
              value={classes}
              onClick={(event) => {
                   onClickClass(event);
              }}
         >
             {classes === 0 ? '매니저' : `${classes}기`}
         </Dropdown.Item>
    ))}
</DropdownButton>

3) 드롭다운 버튼 클릭 시 관련 데이터 가져오는 함수 설정

  // 선택된 기수 state //
  const [classPickState, setClassPickState] = useState('기수 선택');
  const [classPickNumber, setClassPickNumber] = useState('');

  // 드롭 다운 선택 시 클릭 이름으로 변경 및 관련 데이터 가져오기
  const onClickClass = (event) => {
    setClassPickState(event.target.innerText);
    setClassPickNumber(event.target.value);
    // 선택된 기수 관련 데이터 받아오는 함수에 props 전달
    selectedClassData(event.target.value);
  };

  // 선택된 기수 관련 데이터 가져오는 함수
  const selectedClassData = (pickedClass) => {
    fetchGet(
      `http://${myUrl}/admin/view/user?classes=${pickedClass}`,
      navigate
    ).then((data) => {
      setEachClassUsers(data?.AllUserData);
    });
  };

2-2. 교육생 추가하기

  • 기수, 인재번호, 이름, 권한, 층수를 선택, 입력하고 이를 교육생 리스트에 추가하는 기능을 추가하였습니다.
    2-2-1) 부트스트랩을 통한 인풋 폼 구현
{/* 1. 추가하기 */}
<tr>
    <th></th>
    {/* 1-1. 기수선택 */}
    <th style={{ backgrondColor: 'rgb(93, 168, 226)' }}>
    <Form.Group className="mb-1">
        <Form.Select
        value={addUserClass}
        onChange={(e) => onAddUserClass(e)}
        >
        {classList.map((classes, idx) => (
            <option key={idx} style={{ textAlign: 'center' }}>
            {classes === 0 ? '매니저' : `${classes}기`}
            </option>
        ))}
        </Form.Select>
    </Form.Group>
    </th>
    {/* 1-2. 인재번호 작성 */}
    <th>
    <Form.Group className="mb-1">
        <Form.Control
        style={{ textAlign: 'center' }}
        placeholder="인재 번호"
        value={addUserId}
        onChange={(e) => onAddUserId(e)}
        required
        />
    </Form.Group>
    </th>
    {/* 1-3. 이름 작성 */}
    <th>
    <Form.Group className="mb-1">
        <Form.Control
        style={{ textAlign: 'center' }}
        placeholder="이름"
        value={addUserName}
        onChange={(e) => onAddUserName(e)}
        required
        />
    </Form.Group>
    </th>
    {/* 1-4. 권한 선택 */}
    <th>
    <Form.Group className="mb-1">
        <Form.Select
        style={{ textAlign: 'center' }}
        value={addUserRole}
        onChange={(e) => onAddUserRole(e)}
        required
        >
        <option>USER</option>
        <option>MANAGER</option>
        <option>ADMIN</option>
        </Form.Select>
    </Form.Group>
    </th>
    {/* 1-5. 사용 층수 선택 */}
    <th>
    <Form.Group className="mb-1">
        <Form.Select
        style={{ textAlign: 'center' }}
        value={addUserFloor}
        onChange={(e) => onAddUserFloor(e)}
        required
        >
        <option>2</option>
        <option>3</option>
        <option>ALL</option>
        </Form.Select>
    </Form.Group>
    </th>
    {/* 1-6. 추가 하기 버튼 */}
    <th>
    <Button
        style={{
        width: '10rem',
        marginLeft: '3px',
        marginRight: '3px',
        fontSize: '13px',
        }}
        variant="primary"
        onClick={onAddListConfirm}
    >
        추가하기
    </Button>
    </th>
</tr>

2-2-2) 추가 관련 state 설정하기

  const [addUserClass, setAddUserClass] = useState('6기');
  const [addUserClassNumber, setAddUserClassNumber] = useState('6');
  const [addUserId, setAddUserId] = useState(null);
  const [addUserName, setAddUserName] = useState(null);
  const [addUserRole, setAddUserRole] = useState('USER');
  const [addUserFloor, setAddUserFloor] = useState('2');
  const [addUserFloorNumber, setAddUserFloorNumber] = useState('2');

2-2-3) 추가를 원하는 user 정보를 인풋에 쓴 value에서 가져오기

  const onAddUserClass = (e) => {
    setAddUserClass(e.target.value);
    setAddUserClassNumber([
      e.target.value === '매니저' ? 0 : Number(e.target.value.slice(0, 1)),
    ]);
  };

  const onAddUserId = (e) => {
    setAddUserId(e.target.value);
  };
  const onAddUserName = (e) => {
    setAddUserName(e.target.value);
  };
  const onAddUserRole = (e) => {
    setAddUserRole(e.target.value);
  };
  const onAddUserFloor = (e) => {
    setAddUserFloor(e.target.value);
    setAddUserFloorNumber([e.target.value === 'ALL' ? 0 : e.target.value]);
  };

2-2-4) 추가 원하는 데이터 백 데이터에 post하기

  • 데이터를 받아온 후, 새로 고쳐 데이터를 다시 받아오고, input 창 비워 두도록 지정하였습니다.
  const onAddListConfirm = () => {
    // console.log(addUserClassNumber[0]);
    // console.log(addUserId);
    // console.log(addUserName);
    // console.log(addUserRole);
    // console.log(addUserFloorNumber[0]);

    const postUrl = `http://${myUrl}/admin/insertion/user`;
    const object = {
      classes: addUserClassNumber[0],
      floor: addUserFloorNumber[0],
      roles: addUserRole,
      userId: addUserId,
      userName: addUserName,
    };
    fetchPostJson(postUrl, object, navigate).then((data) => {
      //console.log(data.message);
      alert(data.message);
      window.location.reload(); //alert 버튼 클릭 시, 새로고침해서 데이터 다시 받아옴
      selectedClassData(addUserClassNumber[0]);
      setAddUserId(' ');
      setAddUserName(' ');
    });
  };

2-3. 교육생 수정하기

  • 리스트 옆에 수정하기를 클릭하면, 팝업창을 통해 수정할 수 있도록 구현하였습니다.

2-3-1) 관련 데이터 불러와 표에 넣어주기

  • 기수와 인재번호는 고정값으로 가져가고, 그 외의 것은 수정하도록 하였습니다.
{/* 기수 정보 리스트 */}
{EachClassUsers.map((data) => (
  <tr key={data.userId}>
    {/* 삭제 버튼 */}
    <th>
      <input
        type="checkbox"
        onChange={() => onDeleteChecked({ data })}
        // checked={isChecked}
      />
    </th>
    {/* 유저 정보 */}
    <th>
      {data.classes === 0 ? '매니저' : `${data.classes}기`}
    </th>
    <th>{data.userId}</th>
    <th>{data.userName}</th>
    <th>{data.roles}</th>
    <th>{data.floor === 0 ? 'ALL' : data.floor}</th>
    <th>
      {/* 모달창 관련 */}
      <>
        {/* 모달창으로 들어가는 버튼 */}
        <Button
          style={{
            width: '10rem',
            marginLeft: '3px',
            marginRight: '3px',
            backgroundColor: '#2090ff',
            fontSize: '13px',
          }}
          variant="primary"
          onClick={() => handleShow({ data })}
        >
          수정하기
        </Button>

2-3-2) 버튼 클릭 시, 모달 창 오픈 및 클로즈 state 설정 및 함수 구현

// 모달창 show state
const [show, setShow] = useState(false);
  • 오픈 시 선택 된 아이디도 함께 가져오기
 const handleClose = () => {
    setShow(false);
    setChangedUserName('');
    // changedUserName.current = '';
  };

  const handleShow = (data) => {
    setShow(true);
    setPickedUserId(data.data.userId);
    // console.log(data.data);
    // console.log(data.data.userId);
    // console.log(pickedUserId);
  };

2-3-3) 수정할 모달창 부트스트랩으로 구현

  • onChange와 같은 이벤트 함수에서 e 값은 알아서 받아오기 때문에 onChange={(e) => onChangeName(e)} 가 아닌 onChange={onChangeName} 사용가능
{/* 모달창 */}
<Modal
  show={show}
  onHide={handleClose}
  backdrop="static"
  keyboard={false}
>
  {/* 모달 창 헤더 */}
  <Modal.Header closeButton>
    <Modal.Title>{pickedUserId}</Modal.Title>
  </Modal.Header>
  {/* 모달창 내 수정사항 */}
  <Form.Group className="mb-1">
    <Modal.Body>
      <Form.Label>이름</Form.Label>
      <Form.Control
        id="inputName"
        // placeholder="변경할 이름을 기입해주세요"
        // onChange={(e) => onChangeName(e)}
        onChange={onChangeName}
        value={changedUserName}
        required
        // ref={c}
      />
      <Form.Label>권한</Form.Label>
      <Form.Select
        id="role"
        onChange={(e) => onChangeRole(e)}
        value={changedUserRole}
        required
      >
        <option>USER</option>
        <option>MANAGER</option>
        <option>ADMIN</option>
      </Form.Select>
      <Form.Label>사용가능 층수</Form.Label>
      <Form.Select
        id="floor"
        onChange={(e) => onChangeFloor(e)}
        value={changedUserFloor}
        required
      >
        <option>2</option>
        <option>3</option>
        <option>ALL</option>
      </Form.Select>
    </Modal.Body>
    {/* 모달 창 아래 닫기 및 수정하기 버튼 */}
    <Modal.Footer>
      <Button variant="secondary" onClick={handleClose}>
        닫기
      </Button>
      <Button
        variant="primary"
        onClick={() => onClickToChange()}
      >
        수정하기
      </Button>
    </Modal.Footer>
  </Form.Group>
</Modal>

2-3-4) 모달창에 쓴 내용 state로 받기

  • 특이점 : 모달창이 글 쓸 때마다 깜빡였음 => 매번 새로 고침이 되기 때문
  • 솔루션 : e.preventDefault() 기입
 // 수정에서 변경될 내용 데이터
  const [changedUserName, setChangedUserName] = useState('');
  const [changedUserRole, setChangedUserRole] = useState('USER');
  const [changedUserFloor, setChangedUserFloor] = useState('2');
  const [changedUserFloorNumber, setChangedUserFloorNumber] = useState('2');
  const onChangeName = (e) => {
    e.preventDefault();
    // changedUserName.current = e.target.value;
    setChangedUserName(e.target.value);
    console.log(e.target.value);
  };

  const onChangeRole = (e) => {
    setChangedUserRole(e.target.value);
  };

  const onChangeFloor = (e) => {
    setChangedUserFloor(e.target.value);
    setChangedUserFloorNumber([e.target.value === 'ALL' ? 0 : e.target.value]);
  };

2-3-5) 모달창에 쓴 내용 받아 기수 리스트을 수정하기

  • 수정 버튼 클릭시, fetch 후 닫아주기
const onClickToChange = () => {
    // console.log(classPickNumber);
    // console.log(changedUserFloorNumber[0]);
    // console.log(changedUserRole);
    // console.log(pickedUserId);
    // console.log(changedUserName);

    const postUrl = `http://${myUrl}/admin/update/user`;
    const object = {
      classes: classPickNumber,
      floor: changedUserFloorNumber[0],
      roles: changedUserRole,
      userId: pickedUserId,
      userName: changedUserName,
    };

    fetchPostJson(postUrl, object, navigate).then((data) => {
      //console.log(data.message);
      alert(data.message);

      selectedClassData(classPickNumber);
      handleClose();
    });
  };

2-4. 교육생 삭제하기

  • 교육생 여럿을 체크 버튼을 클릭하여, 삭제 버튼 클릭 시 여럿을 삭제할 수 있도록 구현하였습니다.
    2-4-1) 삭제 체크 버튼 교육생 리스트 앞에 구현
{EachClassUsers.map((data) => (
    <tr key={data.userId}>
      {/* 삭제 버튼 */}
      <th>
        <input
          type="checkbox"
          onChange={() => onDeleteChecked({ data })}
          // checked={isChecked}
        />
      </th>

2-4-2) 삭제 리스트를 state 설정하기

const [deletecheckedList, setDeletecheckedList] = useState([]);

2-4-3) 삭제를 원하는 리스트 가져오는 함수 구현하기

  • 특이점 : 데이터가 하나도 없을 때를 먼저 설정해줘야 하였습
 const onDeleteChecked = (data) => {
    console.log('deletecheckedList.length : ', deletecheckedList.length);
    // setIsChecked(!isChecked);
    // console.log(checkedArr);
    if (deletecheckedList.length === 0) {
      setDeletecheckedList((deletecheckedList) => [
        ...deletecheckedList,
        data.data.userId,
      ]);
    } else {
      if (!deletecheckedList.includes(data.data.userId)) {
        setDeletecheckedList((deletecheckedList) => [
          ...deletecheckedList,
          data.data.userId,
        ]);
      } else {
        setDeletecheckedList(
          deletecheckedList.filter((checked) => checked !== data.data.userId)
        );
      }
    }
    // 변경된 state로 불러오는지 확인
    // selectedClassData(data.data.classes);
    console.log('deletecheckedList 1 ', deletecheckedList);
  };
  console.log('deletecheckedList 1 ', deletecheckedList);
profile
고객에게 명료한 의미를 전달하고, 명료한 코드를 통해 생산성 향상에 기여하고자 노력합니다.

0개의 댓글