팀 프로젝트 - 포메이션 팝업 선수리스트

BooKi·2022년 4월 17일
0
post-thumbnail

팀 프로젝트 - 포메이션 팝업 선수리스트

지난번 정리

전에는 각 원의 위치에 따라 포지션 명을 바꿔주도록 하였다
이번에는 선수 리스트를 받아서 원을 우클릭하면 선수의 리스트를 띄워주도록 해보자
이후 이름을 선택하면 이름이 원에 뜨고 리스트에서는 사라지게 구현하자

구현

우선 같이 프론트 개발을 하고있는 팀원은 TS로 개발을 하고있는데 우클릭을 해서 선수 리스트를 뜨게하는것까지 구현을 해주었다

목데이터 (Mock Data)

type Players = {
    id: number;
    //등번호
    name: string;
    already?: boolean;
    //들어가있는지 유무

    //주장 유무랑 포지션 추가 예정
}

export const playersList: Players[] = [
    {
        id: 1,
        name: "1번",
        already: true
    },
    {
        id: 2,
        name: "2번",
        already: true
    },
    {
        id: 3,
        name: "3번",
        already: true
    },
    {
        id: 4,
        name: "4번",
        already: true
    },
    {
        id: 5,
        name: "5번",
        already: true
    },
    {
        id: 6,
        name: "6번",
        already: true
    },
    {
        id: 7,
        name: "7번",
        already: true
    },
    {
        id: 8,
        name: "8번",
        already: true
    },
    {
        id: 9,
        name: "9번",
        already: true
    },
    {
        id: 10,
        name: "10번",
        already: true
    },
    {
        id: 11,
        name: "11번",
        already: true
    },
    {
        id: 12,
        name: "12번",
        already: false
    },
    {
        id: 13,
        name: "13번",
        already: false
    },
    {
        id: 14,
        name: "14번",
        already: false
    },
];
-----------------------------------------------------
CSS

.move {
  background-color:skyblue;
  width:80px;
  height:80px;
  border-radius:75px;
  text-align:center;
  margin:0 auto;
  font-size:30px;
  vertical-align:middle;
  line-height:50px;
  cursor: grab;
  position: absolute;
}
.move:hover {
  background-color: pink;
}
.formation {
  width: 600px;
  height: 950px;
  background-image: url(https://velog.velcdn.com/images%2Fqnrl3442%2Fpost%2F733d5e03-5531-4e99-98e6-6f9a05c26c15%2Fformation.png);
}
.GK {
  background-color:skyblue;
  width:80px;
  height:80px;
  border-radius:75px;
  text-align:center;
  margin:0 auto;
  font-size:30px;
  vertical-align:middle;
  line-height:50px;
  cursor: not-allowed;
  position: absolute;
}
.button {
  border-radius:50%;
  text-align:center;
  font-size:30px;
  vertical-align:middle;
  line-height:50px;
}
-------------------------------------------------------------------
import React, { useState } from 'react';
import "./Formation.css";
import Draggable, { DraggableData } from 'react-draggable';
import axios from 'axios';
import Menu from '@mui/material/Menu';
import MenuItem from '@mui/material/MenuItem';
import { Button } from '@mui/material';

import { playersList } from './data';
//s 조심
function Formation() {

  type PlayerType = {
    id: number;
    name: string;
    already: boolean;
  };
  const [playerList, setPlayerList] = useState(playersList);
  //s 조심
  const [Status, SetStatus] = useState(true)
  const [anchorEl, setAnchorEl] = React.useState<null | HTMLElement>(null);
  const open = Boolean(anchorEl);
  const handleClick = (event: React.MouseEvent<HTMLButtonElement>) => {
    setAnchorEl(event.currentTarget);
    event.preventDefault();
    //event.preventDefault() 브라우저 우클릭을 막아준다.
  };
  const handleClose = () => {
    setAnchorEl(null);
  };

  const onStatusHandler = () => {
    SetStatus(!Status)
  }

  const readDB = () => {
    if (Status) {
      console.log("read")
      axios.get('/api/readUser') // res = axios 이런식으로 해서 res를 가지고 있어야됨 방법 찾아보자
        .then(res => {
          console.log(res.data)
          // const name = res.data.UserName
          // const x = res.data.x
          // const y = res.data.y
          // console.log(name,x,y)
        })
      console.log("포메이션 원에 위에서 받은 선수 데이터 넣어주기")
    } else {
      console.log("send")
      const body = {
        Status: Status,
        first_Position: Content1 //첫번째 요소 포지션 
      }
      axios.post('/api/sendUser', body)
        .then(res => {
          console.log(res.data)
        })
    }
  }
  // 포지션 위치 값 보내는 방법
  // const [Position1, SetPosition1] = useState({ x: 0, y: 0 });

  // const trackPos = (data) => {
  //   SetPosition1({ x: data.x, y: data.y }); 
  // };

  // let body = {
  //   first: Position1
  // }

  // axios.post('/api/position', body)
  // .then(res => {
  //     console.log(res.data)
  // })

  const [Content1, SetContent1] = useState("ST");
  ------------------------ Content2~9------------
  const [Content10, SetContent10] = useState("RB");

  const onContentHandler1 = (props: string) => {
    SetContent1(props)
  }
  const onDragHandler1 = (data: DraggableData) => {
    if (data.x > 80 && data.y < 120 && data.x < 450) {
      onContentHandler1("ST")
    } else if (data.x < 80 && data.y < 200) {
      onContentHandler1("LW")
    } else if (data.x > 450 && data.y < 200) {
      onContentHandler1("RW")
    } else if (data.x > 80 && data.y > 120 && data.y < 185 && data.x < 450) {
      onContentHandler1("CF")
    } else if (data.x > 80 && data.y > 185 && data.y < 275 && data.x < 450) {
      onContentHandler1("CAM")
    } else if (data.x < 80 && data.y > 200 && data.y < 440) {
      onContentHandler1("LM")
    } else if (data.x > 450 && data.y > 200 && data.y < 440) {
      onContentHandler1("RM")
    } else if (data.x > 80 && data.y > 275 && data.y < 460 && data.x < 450) {
      onContentHandler1("CM")
    } else if (data.x < 80 && data.y > 440) {
      onContentHandler1("LB")
    } else if (data.x > 450 && data.y > 440) {
      onContentHandler1("RB")
    } else if (data.x > 80 && data.y > 460 && data.y < 560 && data.x < 450) {
      onContentHandler1("CDM")
    } else if (data.x > 80 && data.y > 560 && data.x < 450) {
      onContentHandler1("CB")
    }
  }

  --------------------------- onDragHandler2~9--------------------------------

  const onContentHandler10 = (props: string) => {
    SetContent10(props)
  }
  const onDragHandler10 = (data: DraggableData) => {
    if (data.x > 80 && data.y < 120 && data.x < 450) {
      onContentHandler10("ST")
    } else if (data.x < 80 && data.y < 200) {
      onContentHandler10("LW")
    } else if (data.x > 450 && data.y < 200) {
      onContentHandler10("RW")
    } else if (data.x > 80 && data.y > 120 && data.y < 185 && data.x < 450) {
      onContentHandler10("CF")
    } else if (data.x > 80 && data.y > 185 && data.y < 275 && data.x < 450) {
      onContentHandler10("CAM")
    } else if (data.x < 80 && data.y > 200 && data.y < 440) {
      onContentHandler10("LM")
    } else if (data.x > 450 && data.y > 200 && data.y < 440) {
      onContentHandler10("RM")
    } else if (data.x > 80 && data.y > 275 && data.y < 460 && data.x < 450) {
      onContentHandler10("CM")
    } else if (data.x < 80 && data.y > 440) {
      onContentHandler10("LB")
    } else if (data.x > 450 && data.y > 440) {
      onContentHandler10("RB")
    } else if (data.x > 80 && data.y > 460 && data.y < 560 && data.x < 450) {
      onContentHandler10("CDM")
    } else if (data.x > 80 && data.y > 560 && data.x < 450) {
      onContentHandler10("CB")
    }
  }

  return (
    <div className="formation">

      <button onClick={() => {
        onStatusHandler()
        readDB()
      }}>
        {Status ? "편집" : "편집 완료"}
      </button>

      <Draggable
        disabled={Status}
        defaultPosition={{ x: 145, y: 80 }}
        onDrag={(e, data) => onDragHandler1(data)}
        bounds={{ top: 0, left: 0, right: 520, bottom: 740 }}
      // onStop={(e, data) => trackPos(data)}
      // 포지션 위치 값 보내는 방법
      >
        <div className="move">
          <Button className="button"
            disabled={Status}
            id="basic-button"
            aria-controls={open ? 'basic-menu' : undefined}
            aria-haspopup="true"
            aria-expanded={open ? 'true' : undefined}
            onContextMenu={handleClick}
          ><div>{Content1}</div>
          </Button>
        </div>
      </Draggable >

      <Menu
        id="basic-menu"
        anchorEl={anchorEl}
        open={open}
        onClose={handleClose}
        MenuListProps={{
          'aria-labelledby': 'basic-button',
        }}
        PaperProps={{
          style: {
            maxHeight: "200px",
            width: '20ch',
          },
        }}
      //스크롤 만드는것
      >
        {playerList.map((player): JSX.Element => {
          return (
            // player.already === false &&
            <MenuItem onClick={handleClose}>{player.name}</MenuItem>
          );
        })}
      </Menu>

      {/* <MenuItem onClick={handleClose}>My account</MenuItem>
      <MenuItem onClick={handleClose}>Logout</MenuItem> */}


      <Draggable
        disabled={Status}
        defaultPosition={{ x: 380, y: 80 }}
        onDrag={(e, data) => onDragHandler2(data)}
        bounds={{ top: 0, left: 0, right: 520, bottom: 740 }}
      >
        <div className="move">
          <div>{Content2}</div>
        </div>
      </Draggable>

--------- 3~10번 Draggable------------------

      <Draggable
        disabled={true}
        defaultPosition={{ x: 260, y: 790 }}
      >
        <div className="GK">
          <div>GK</div>
        </div>
      </Draggable>
    </div >
  )
}


export default Formation

겹치는 코드는 --------- 여기서는 이걸로 조금 짧게 표현했다

코드를 해석해보면 목데이터를 불러온다

그리고 playlist에 기본 값으로 넣어주고 anchorEl, open 을 만들었다

Menu라는 것을 만들어 draggable안의 button 에서 menu를 불러오도록 만든것 같다

내가 작성한 코드가 아니라서 제대로된 알지못한다 ㅠ

일단 리스트가 뜨는것까지만 구현했다고 하여서 이후는 내가 구현하기로했다

목데이터를 보면 already라는 불린값이 있는데 이 already가 false일때만 리스트에 나오게 코드를 만들어야 된다고 들었다

그래서 menu에서 menuitem을 만들 때 if로 한번 걸러주었다

        {playerList.map((player, idx) => {
          if(player.already === false){
            return (
              <MenuItem 
                onClick={() => {handleClose()}}
                key={idx}
              >
                {player.name}
              </MenuItem>
            )
          }
        })}

그리고 idx값을 주어 각 리스트에 키값을 넣어주었다

이후 목데이터를 수정한후에 테스트해보았다

제대로 리스트가 떳다

이후 선택되면 already 값을 바꿔주려고 생각을 해보았다

지금 보면 Menuitem에 handleClose()가 걸려있다

그래서 저걸 사용해서 해보려고 handleClose에 player를 props로 넣어주었다

그러면 선택될 때 그 선택되는 선수가 담겨서 들어갈것이다

  const handleClose = ({id, name, already}) => {
    setAnchorEl();

    setPlayerList(playerList.map((player) =>
      player.id === id ? { ...player, already: !already} : player)
    )
  }

프롭스를 바로 구조분해를 하고 setPlayerList를 이용해서 지금 받아온 id와 비교를 해서

같은 id가 있으면 already를 바꿔주고 같지않으면 그냥 냅두게 삼항연산자로 작성을 하였다

이렇게 하니까 변경이 되고 선택된 값은 리스트에서 사라졌다

그런데 1번을 고른 후 2번을 고르면 다시 1번의 already를 false로 바꿔줘야하는데 그걸 어떻게 구현해야할지

아무리 머리를 싸매고 생각을 해도 방법이 나오지않았다

처음에는 똑같이 삼항연산자를써서 true를 모두 false로 바꾼 뒤에 선택된 값만 다시 true로 바꿔주면 되지않을까 싶었는데

되지않고 한번 사라지면 계속 뜨지않았다

그래서 일단 이건 나중에 구현하기로 하고 선택되는 선수의 이름을 원에 띄워주기를 먼저 하려고 했다

그래서 const [Name1, SetName1] = useState("")를 먼저 만들어주고 Name핸들러를 만들어서

메뉴 onClick에 걸어주고 props로 똑같이 해당 선수를 받았다

그리고 Name을 Draggable에 넣어주니까 선택되는 선수로 이름이 변경 되었다

비교를 위해 두번째 원도 똑같이 해주고 Name핸들러 2를 만들어서 2를 걸어주었다

그런데 1번에서 고른 값이 2번 원에 나오는 것이다

혼자는 어려워서 팀원과 같이 디스코드를 하면서 진행하였지만 둘다 원인을 찾지 못하였고 다음에 하기로 하였다

다음 포스트에서 이어서 작성하겠다

profile
성장을 보여주는 기록

0개의 댓글