코딩블로그
고스락 티켓 예매 프로젝트-(2)관리자 페이지_티켓 페이지 본문
시작하기 전에 대략 티켓 페이지의 기능을 설명해보자면:
공연 날짜별로(YB,OB)별로 구분할 수 있도록 ant-design에서 segmented를 이용하였다.
티켓 페이지네이션도 ant-design에서 table 부분에서 가져왔다.
단체 협업이다 보니 swagger을 이용하여 api키값을 가져와서 정보를 불러왔다.
Action 부분에서는 상태를 변경할때마다 값들의 상태, 즉 티켓 상태를 변경할 수 있도록 만들어주었다.
1.티켓 페이지에서 페이지네이션 구현하기
페이지네이션을 구현하기 전에, 가장 중요한, data값을 불러오는 부분부터 설명을 해보겠어요.
여기서 actions-creators에서 ticketPagi와 ticketPagination, changeState를 import해 온것을 볼 수 있다.
react-redux의 useSelector를 사용하여 리덕스의 상태(state)를 조회 하였고
react-redux의 useDispatch를 사용하여 action생성한 것을 발생시켰다.
제일 핵심이 되는 'data'를 dispatch를 사용하여 actions-creators에 있는 ticketPagi를 호출하였다. 이때 호출할때 기본값이 null인지 아니면
현재 value의 state인지 구분하여 dispatch하였다. onPageChange함수와 useEffect안에 기본값이 다른 이유는 말그대로onPageChange함수는
페이지네이션에서 다른 페이지로 넘어갈때마다 해당 페이지 data를 호출해야 되기 때문에 'page:e'라 하였고 useEffect는 초기화면일때 보여지는
것들이므로 'page:1'로 첫번째 페이지를 호출해야한다.
//src/state/action-types/ticketPagination.js
export const TICKET_PAGINATION_PENDING = 'TICKET_PAGINATION_PENDING';
export const TICKET_PAGINATION_SUCCESS = 'TICKET_PAGINATION_SUCCESS';
export const TICKET_PAGINATION_ERROR = 'TICKET_PAGINATION_ERROR';
export const STATE_CHANGE = 'state_change';
export const STATE_CHANGE_ERROR = 'state_change_error';
//src/state/actions-creators/ticketPagination.js
import axios from 'axios';
import {
TICKET_PAGINATION_PENDING,
TICKET_PAGINATION_SUCCESS,
TICKET_PAGINATION_ERROR,
STATE_CHANGE,
STATE_CHANGE_ERROR
} from '../action-types';
export const ticketPagination =
({ requestPage }, callback) =>
async dispatch => {
try {
dispatch({ type: TICKET_PAGINATION_PENDING });
const response = await axios.get(
`https://api.gosrock.band/v1/tickets/find?&order=DESC&page=${requestPage}&take=10`
);
const data = {
total: response.data.data.meta.itemCount,
currentPage: requestPage,
ticketList: response.data.data.data
};
dispatch({ type: TICKET_PAGINATION_SUCCESS, payload: data });
// 자동으로 피쳐로 넘어가게끔
// callback();
} catch (e) {
//400 ~
dispatch({ type: TICKET_PAGINATION_ERROR, payload: '조회 실패' });
}
};
export const changeState =
({ id, e }, message) =>
async dispatch => {
try {
message.config({ maxCount: 1 });
message.loading(`${id} 상태 ${e}으로 처리중`);
const response = await axios.patch(
`https://api.gosrock.band/v1/tickets/status`,
{ ticketId: id, status: e }
);
// message.destory();
message.success(`${id}티켓 상태 ${e}으로 변경 성공`);
dispatch({ type: STATE_CHANGE, payload: response.data.data });
} catch (e) {
dispatch({
type: STATE_CHANGE_ERROR,
payload: e.response.data
});
}
};
export const ticketPagi =
({ requestVal }, { page }, callback) =>
async dispatch => {
try {
dispatch({ type: TICKET_PAGINATION_PENDING });
const response = await axios.get(
`https://api.gosrock.band/v1/tickets/find`,
{
params: {
date: requestVal,
order: 'DESC',
page: page,
take: 10
}
}
);
const data = {
total: response.data.data.meta.itemCount,
currentPage: page,
ticketList: response.data.data.data
};
dispatch({ type: TICKET_PAGINATION_SUCCESS, payload: data });
// 자동으로 피쳐로 넘어가게끔
// callback();
} catch (e) {
//400 ~
dispatch({ type: TICKET_PAGINATION_ERROR, payload: '조회 실패' });
}
};
axios를 이용하여 결국에 swagger에 있는 api를 가져왔다. 이 부분에서 많은 것을 얻어간 것 같다. 개념으로만 들으면 음 뭐 그래 알겠네 하고 넘어갔었는데
직접 작성하려고 해보니까 매우매우 힘들었다. 그 과정에서 총괄 선배님이 정말 많이 고생하신^^.. 그분께 너무너무감사할 따름이네요..
어쨌든, import axios해서 actions-creators/ticketPagination.js에 총 3가지 함수가 있는데 사실 ticketPagination함수는 사용을 하지 않는데 안지우고 냅뒀다. 괜히
건들였다가 모든게 오류뜰까봐 망상하는 초짜라서^^..ㅎㅎ
그래서 결국 사용한게 ticketPagi와 changeState이다. 먼저 ticketPagi에서는 페이지 정보, requestVal이라고 공연 날짜 정보를 받아오게 설정해놓았다. 이 것은
antdesign에서 segmented를 이용하여 yb,ob 다른 날짜를 기준으로 표를 정렬하게 할 때 사용한 함수이다.
changeState함수를 보면 id,e를 호출한것을 볼 수 있는데,
action에서 상태 변경할때 필요한 값들이다. 현재 입금확인, 입장완료 이렇게 바꿔줄 수 있는데 바꿀때마다 서버에 알려 서버가 값을 갱신할 수 있을 수 있게까지 만들었다.
이 부분은 dispatch({type:STATE_CHANGE, payload:data})부분에서 볼 수 있다. 이 dispatch로 인하여 reducer파일에 있는 부분으로 넘어갈 수 있게 된다 .
비동기를 위해 promise함수에서 async await문법을 처음 사용했는데 정말 편한 문법을 배워간 것 같다.
//src/state/reducers/ticketPagination.js
import {
TICKET_PAGINATION_PENDING,
TICKET_PAGINATION_SUCCESS,
TICKET_PAGINATION_ERROR,
STATE_CHANGE,
STATE_CHANGE_ERROR
} from '../action-types';
case TICKET_PAGINATION_PENDING:
return { ...state, data: action.payload, error: null, pending: true };
case TICKET_PAGINATION_SUCCESS:
return { ...state, data: action.payload, error: null, pending: false };
case TICKET_PAGINATION_ERROR:
return { ...state, data: [], error: action.payload, pending: false };
case STATE_CHANGE:
const newTicketList = state.data.ticketList.map(element => {
if (element.id === action.payload.id) {
return action.payload;
}
return element;
});
return {
...state,
data: {
total: state.data.total,
//totalResultCount: state.ticketInfo.totalResultCount,
ticketList: newTicketList,
currentPage: state.currentPage
},
errorMessage: null
};
case STATE_CHANGE_ERROR:
return {
...state,
errorMessage: action.payload.message
};
default:
return state;
}
}
이 코드를 보면 TICKET_으로 시작하는것과 STATE_로 시작하는 부분이 다른것을 볼 수 있다. TICKET부분에서는 단순히 서버에서 값을 갖고오는 부분으로 처리를 하였다. 그래서
아까 actions-creators함수에서 ticketPagi는 값을 바꾸는 것이 아니라 그냥 값만 받아와서 적용하면 됬기 때문에 TICKET_PAGINATION_SUCCESS를 이용했던 것을 볼 수 있었지만
STATE_부분은 action에서 상태 변경할때 호출되는 것이기 때문에, 해당 아이디(id)를 가지고 상태를 찾아 사용자가 변경한 상태로 변경해주어야 한다.
ERROR부분은 둘다 다른점은 없고 통신 부분에서 오류가 있다는 것을 보여주는 부분이다.
이제 본격적으로 antd의 table과 segmented, select에 data를 어떻게 적용했는지 설명해 보겠습니다!
먼저, ant-design을 적용하기 전에 몇 분 정도 공부를 해보았어요.
노션에도 정리를 해두었지만 다시 정리를 해보자면,
Ant-design이라는 것은 간단하게 ui를 편하게 도와주는 둘
:a design system for entrprise-level products. create an efficient and enjoyable work experience
먼저 ant를 설치, npm install antd
사용법
- npx create-react-app antd-demo: antd-demo 폴더에 cra 생성
- yarn add antd: antd 설치
- 필요한 부분 import하여 사용하기
css적용을 위해 공통 컴포넌트에 import ‘antd/dist/antd.css’;
import, export 리액트에서 하는 것처럼 하면 될듯??
본격 사용법
필요한 컴포넌트 import
import{Menu}from ‘antd’;
컴포넌트 사용
import React from ‘react’;
import {Menu} from ‘antd’;
const AppLayout = ()⇒{
}
export default AppLayout;
이 간단한 적용 방법을 기반으로 ant-design에서 Table 소스를 가져와서 적용하였다.
https://ant.design/components/table/
table안에 속성 값넣어 주는데 코드 짜면서 주의했던 부분이 바로 삼항 연산자 적용 부분이었다. 131줄이나 145줄을 보면 삼항 연산자 사용을 볼 수있는데, 이 줄을 연산자처리를 하지 않는다면 오류가 뜬다. data가 null인경우도 생각해줘야 하기 때문이다. 이제 table에 column도 적용을 하였는데 column에서 주의할 점은 render함수 였던 것 같다. 149줄 쪽을 보면 dataIndex는 user인데 render함수로 user의 name을 가져왔어야 했다. 처음에 할때 바로 user.name을 했는데 오류가 뜨길래 애를 많이 썼었다.
그리고 하나 더 기억에 남는것은 moment함수이다. moment는 이미 내장되어 있는 문법이였기 때문에 쉽게 적용을 하였는데 시간이 계속 +9로 찍히는 것이였다. 몇시간을 해매다가 결국 선배한테 질문을 했는데 utc에(false)를 붙여주면 됬었다. 너무 간단해서 허무했지만 일단 해결해서 기뻣던 기억이 난다.(ㅋㅋㅋㅋ)
action column에서는 selected를 또 antd에서 가져왔는데 너무 간단하다. 그냥 Selected안에 Option또 선언해줘서 필요한 목록들을 각각 만들어주었다. 저 disabled는 선택목록에는 있지만 선택을 하지 못하게 하는 function이다.
2.Segmented 구현하기
이 부분도 table 구현하는 것과 동일하다.
https://ant.design/components/segmented/
Segmented의 options안에 있는 ALL,YB,OB를 value값들의 후보들로 설정해주었다. 코드 초반에 useState를 사용하여 value의 초기값을 ALL로 설정해두었다. 그래서 onChange(ALL에서 YB나 OB로 바뀔때) handlefilt함수를 호출해주었다. 그 함수 안에서 actions-creators에 있는 ticketPagi를 또 dispatch해주어 data를 가져와주어 segmented디자인에 서버에서 가져온 data를 적용 시켜주었다.
마지막으로 Tag icon은 바로 이 부분이다.
이것도 디자인을antd에서 가져와주고 간단하게 data를 이미 useSelector을 통해서 가져와져 있는 상태여서 바로 data와 삼항연산자를 이용해서 구현하였다.
다음글은 랜딩페이지 구현에 대해서 써보겠습니당
'고스락 티켓 프로젝트_관리자' 카테고리의 다른 글
고스락 티켓 예매 프로젝트-(4)관리자 페이지_댓글 추첨 페이지 (0) | 2022.08.19 |
---|---|
고스락 티켓 예매 프로젝트-(3)관리자 페이지_랜딩 페이지 (0) | 2022.08.19 |
고스락 티켓 예매 프로젝트-(1)관리자 페이지_시작 (0) | 2022.08.19 |