패스트 캠퍼스 프론트엔드 스쿨 최종 프로젝트 후기 - 2

백승일·2020년 11월 2일
1

어때시네마 후기

목록 보기
2/3
  • 지난이야기
    react-potal로 모달창도 띄웠고 이제 좌석 선택으로 넘어가야한다.


좌석 선택에서는 보이는 것 처럼 인원의 연령대에 맞게 사람 수를 선택하고 해당 인원수 만큼 좌석을 선택해야한다. 때문에 선택된 좌석의 수가 인원수와 같아지면 더이상 좌석 선택을 못하게 해야하고, 인원 수 만큼 선택하지 않은 채로 결제 페이지로 넘어가는 것을 막아야한다.

이 인원 정보를 가지고 결제를 해야하니 일단 예매정보를 담을 모듈을 만들고 이 컴포넌트에서 인원수 관리를 했다.

  const [ppc, setppc] = useState({
    adult: 0,
    junior: 0,
    senior: 0,
    handicaped: 0,
    all: 0,
  });

  const [clickedSeat, clickSeat] = useState([]);

  useEffect(() => {
    setppc(() => ({
      adult: 0,
      junior: 0,
      senior: 0,
      handicaped: 0,
      all: 0,
    }));
  }, [steps]);

peopleCount를 객체로 저장하고 페이지에 들어오면 초기화 시켜주도록 만들어준다. 이 state를 props로 좌석을 그리는 컴포넌트에 전달해줬다.

          <PayBookDataStageComponent
            stage={bookingData.stage}
            bookedSeat={bookingData.bookedSeat}
            clickedSeat={clickedSeat}
            peopleCnt={ppc.all}
            clickSeat={clickSeat}
            type="select"
          />

해당 컴포넌트에 예매 정보 검색 결과로 들어온 영화관 번호, 예매된 좌석를 주고 이전에 모달창과 다르게 select버전임을 알려주는 type을 준다. 선택된 좌석번호는 clickedSeat에 저장되어 ppc.all과 length를 비교하여 선택한 인원 수 만큼 좌석을 선택했는 지 비교하고 이후 db에 저장할 때 사용할 것이다.

좌석을 그리는 로직은 행렬을 이용했다.

const row = ['a', 'b', 'c', 'd', 'e', 'f'];
const col = ['1','2','3','4','5','6','7','8','9','10','11','12','13','14'];

{row.map((ro, roIdx) => (
          <ul key={roIdx}>
            <li>{ro.toUpperCase()}</li>
            {col.map((co, coIdx) => (
              <li key={coIdx} className={blockSeatCalc(roIdx, coIdx, ro, co)}>
                <a href="#" data-seat={`${ro}${co}`}>
                  {co}
                </a>
              </li>
            ))}
          </ul>
        ))}

이렇게 "A1"이런 식의 좌석 번호를 data-seat에 주어서 고유 data-seat을 가진 a태그를 만들었다.

좌석의 상태를 행렬의 좌표를 입력받아 db에서 가져온 좌석 데이터와 비교하는 함수를 만들어서 구분 되게 만들었다. 이때 실수한 부분이라면 코로나때문에 막힌 좌석을 DB에서 가져오는 게 아니라 클라이언트에 저장하게 했다는 점이다. 홀수, 짝수의 막힌 좌석을 blockA,blockB로 저장했다. 이를 현재 좌표와 비교하여 좌석의 상태를 변경해준다.

  function blockSeatCalc(roIdx, coIdx, ro, co) {
    // 훌수 줄에 블럭인 경우 || 짝수줄에 블럭인 경우
    if (
      ((roIdx + 1) % 2 && blockA.includes(coIdx + 1 + '')) ||
      (!((roIdx + 1) % 2) && blockB.includes(coIdx + 1 + ''))
    ) {
      return [styles.block, styles.seat].join(' ');
      // 예매 된 경우, 숫자만큼 클릭 된 경우
    } else if (clickedSeat.includes(`${ro}${co}`)) {
      return [styles.clicked, styles.seat].join(' ');
    } else if (
      bookedId.includes(`${ro}${co}`) ||
      (peopleCnt !== 0) === clickedSeat.length
    ) {
      return [styles.booked, styles.seat].join(' ');
      // 숫자만큼 클릭되지 않은 경우
    }
    // 일반 상태
    return styles.seat;
  }

선택한 좌석데이터는 컴포넌트에서 state로 가지고 있다가 결제 하기를 눌러 결제 화면으로 이동하면 store에 저장되도록 만들었다. 이렇게 좌석 선택하는 기능도 완성되었다. 팀원들과 합의 했을 때, 결제 시스템을 도입하는 것은 시간상 힘들다 생각하여 가상으로 결제 페이지와 결제 확인 페이지만을 만들었다.

그렇지만 서버로 예매 요청을 보내서 예매 테이블에 예매 정보가 저장되고 theater테이블의 해당 예매 정보에 예매된 좌석에 추가된다. 결제는 안되도 같은 자리는 예매할 수 없게 만들었다. 이렇게 순탄하게 진행될 줄 알았는데 사람 앞 일은 모르는 것이다. 쉽지 않은 일이 기다리고 있었다..

  • 다음에 계속
profile
뉴비 개발자

0개의 댓글