굿즈 스토어 프로젝트 10 - 스토어 마이 페이지.

이유승·2023년 7월 23일
0

상품을 결제하는 기능을 구현할 때, 결제 내역과 포인트 사용 내역을 저장하는 기능도 같이 구현하였다.

스토어 마이페이지에서는 이렇게 저장된 결제 내역과, 포인트 사용 내역을 조회하는 기능을 구현하였다. 스토어 마이 페이지를 중심으로 상황에 맞게 결제내역 조회 컴포넌트와 포인트 내역 조회 컴포넌트가 렌더링 되도록 UI를 구현하였다. 컴포넌트 출력 방식은 회원가입 페이지의 방식과 동일하다.



1. 결제 내역 조회.

결제 내역이 저장될 때, DB에 사용자의 이메일 주소도 저장되어 해당 기록이 누구의 기록인지 구분하는데 사용된다.

이를 기준으로 DB에서 데이터를 조회하여 화면에 출력한다.

검색 기능과 페이지네이션.

자신이 어느 물건을 언제 구매했는지 검색하는 기능이 필요하다. 상품의 이름을 정확하게 입력하면 그 결과만 출력되도록 구현해야 한다. 검색 기능은 스토어 상단 바를 통해 상품 목록 페이지 기능을 구현할 때 이미 만들어두었다. 이를 그대로 가져오면 된다.

페이지네이션도 마찬가지. 앞서 기능을 구현해두었으니 그대로 사용하면 된다.

  • 검색 기능과 페이지네이션을 같이 구현할 경우, 페이지네이션을 다시 계산해주어야 한다. 실제 화면에 출력되는 요소의 수가 한 페이지 당 화면에 출력하기로 지정된 요소의 갯수보다 작을 경우에는 분명 결과값은 하나만 나와야 하는데 다음 페이지로 넘어갈 수 있다던지, 화면에는 1번부터 5번까지 밖에 보이지않는데 다음 페이지로 넘어갔더니 11번부터 출력된다던가 하는 문제가 발생할 수 있기 때문이다. 나는 페이지네이션 기능을 구현했을 때, 한 페이지 기준 데이터의 양 끝점도 페이지네이션 계산 기준으로 사용하여 이 문제 발생을 예방하였다.

내역 삭제 기능.

결제 내역이 화면에 출력된 시점에서 DB에 저장되어 있는 데이터가 이미 모두 받아져있는 상황이다. 따라서 결제 내역을 삭제하는 기능은 프론트단까지 반환된 데이터를 이용하여 DB에 해당 내역을 삭제하라고 요청하는 방식으로 구현하였다.

우측에 X 버튼을 클릭하면..

const deleteHistory = (purchaseNumber) => {
    const confirmChoice = window.confirm('구매내역을 삭제하시겠습니까?');

    if (!confirmChoice) {
        return;
    }
    else {
        dispatch(DeletePurchaseRecord(purchaseNumber));
    };
};

사용자에게 정말 삭제할 것이냐고 한 번 확인을 받고, 삭제 기능을 호출한다.

  • DB에서 데이터를 삭제할때는..
    이전 포스트 참조. 삭제 기능은 실제로 DB에서 데이터를 지우는게 아니라 isDelete 필드를 추가하여 화면상에서만 출력되지 않도록 구현하였다.



2. 포인트 사용 내역 조회.

기본 구조는 결제 내역 조회 기능과 동일하다. 다만 세세한 점에서 일부 차이가 있다. 포인트 사용 내역은 포인트를 충전하는 것과 사용하는 것 두 가지 분류에 속한다. 기능을 구현 하던 때, 나는 이를 시각적으로 명확하게 표현하고 싶었고, 충전 혹은 사용 이후 잔액이 화면에 출력되도록 UI를 구성하길 원했다.

따라서 포인트 DB 구조를 다음과 같이 설정하였다.

해당 내역이 포인트를 충전한 것인지, 사용한 것인지를 recordType 필드로 구분하고 충전 혹은 사용 이후의 포인트 잔액이 leftoverPoint 필드에 저장되도록 하였다. 원래 포인트 잔액은 회원 DB에서 관리하는 필드인데, 이 기능 때문에 회원 DB에서 데이터를 호출하는 것은 자원 낭비라고 판단하여 포인트 내역 DB에서도 관리하도록 하였다.

<PointInfo>
	<p>{item.recordDesc}</p>
	<Point type={item.recordType === '+' ? 'income' : 'outcome'}> {item.recordType === '+' ? '+' : '-'} {item.pointChangeNumber}p</Point>
	<p>잔액 {item.leftoverPoint}p</p>
</PointInfo>

(...)

const Point = styled.div`
    font-size: 18px;
    margin-top: 3px;

    ${(props) => props.type === 'income' && css`
        color: #F77154;
    `};

    ${(props) => props.type === 'outcome' &&
        css`
        color: #1F70B4;
    `};
`;

프론트에서는 이 필드 데이터를 조건부 렌더링을 통해 상황에 맞는 부호와 폰트 색깔이 적용되도록 하였다.



3. 포인트 충전.

이 스토어에서 포인트를 충전하는 방법은 2가지 이다. 마이 페이지의 포인트 충전하기 버튼을 클릭하는 것과 결제 시 포인트가 부족했을 때.

마이 페이지에서 포인트를 충전했을 때도 포인트 충전 모달을 통해 기능을 수행한다. 모달창을 출력하는 방식은 한 페이지에서 여러 컴포넌트를 출력하는 방법과 동일하다.

기능은 단순한데, 충전하고 싶은 수치를 입력하고 하단에 입력한 수치를 한 번 더 입력한 다음 완료 버튼을 클릭하면 유저 DB에 포인트 수치가 갱신되고, 포인트 사용 내역 DB에 새로운 기록이 저장되는 것이다.

원래는 가상 결제 시스템을 도입하면서 보안에 신경쓰기 위해서 이것저것 추가할 예정이었으나 가장 결제를 사용하지 않게 되면서 그냥 DB에 데이터를 수정하고 추가하는 기본적인 기능이 되어버렸다. 다음 프로젝트에서 제대로 만들어 볼 생각이다.

코드 평가.

평가 방법, 개인적인 코드 리뷰 및 Chat GPT 사용.

-> 보안성 낮음. 결제 정보같은 민감한 정보가 아무 암호화 절차 없이 무방비하게 사용되고 있음. 사실 해당 프로젝트에서 웹 보안쪽은 염두해두지 않고 있다보니 프로젝트 전체적으로 보안에 대해서 신경을 쓰지 않고 있음. 차기 프로젝트 에서는 웹 보안에 대한 쪽도 공부해서 이 문제를 보완할 필요가 있음.

profile
프론트엔드 개발자를 준비하고 있습니다.

1개의 댓글

comment-user-thumbnail
2023년 7월 23일

공감하며 읽었습니다. 좋은 글 감사드립니다.

답글 달기