Skip to content

Commit

Permalink
Merge branch 'main' into GGFE-234-Gacha-Modal-API-Error
Browse files Browse the repository at this point in the history
  • Loading branch information
hyobb109 authored Sep 6, 2023
2 parents 072b5ac + 48a074f commit 35d6cf2
Show file tree
Hide file tree
Showing 7 changed files with 103 additions and 36 deletions.
48 changes: 36 additions & 12 deletions components/modal/store/inventory/EditMegaphoneModal.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { useEffect, useState } from 'react';
import { useRecoilValue, useResetRecoilState } from 'recoil';
import { useRecoilValue, useResetRecoilState, useSetRecoilState } from 'recoil';
import { UseItemRequest } from 'types/inventoryTypes';
import { mockInstance } from 'utils/mockAxios';
import { instance, isAxiosError } from 'utils/axios';
import { errorState } from 'utils/recoil/error';
import { userState } from 'utils/recoil/layout';
import { modalState } from 'utils/recoil/modal';
import { MegaphoneItem } from 'components/Layout/MegaPhone';
Expand All @@ -10,10 +11,11 @@ import {
ModalButton,
} from 'components/modal/ModalButton';
import { ItemCautionContainer } from 'components/modal/store/inventory/ItemCautionContainer';
import { useMockAxiosGet } from 'hooks/useAxiosGet';
import useAxiosGet from 'hooks/useAxiosGet';
import styles from 'styles/modal/store/InventoryModal.module.scss';

type EditMegaphoneProps = UseItemRequest;

type MegaphoneData = {
megaphoneId: number;
content: string;
Expand All @@ -26,15 +28,32 @@ const caution = [

const failMessage = '확성기 데이터를 불러오는데 실패했습니다.';

const errorCode = ['ME200', 'RC500', 'RC200'] as const;

type errorCodeType = (typeof errorCode)[number];

type errorPayload = {
status: number;
message: string;
code: errorCodeType;
};

const errorMessages: Record<errorCodeType, string> = {
ME200: '확성기를 찾을 수 없습니다.',
RC500: '삭제할 수 없는 확성기입니다.',
RC200: '삭제할 수 없는 확성기입니다.',
};

export default function EditMegaphoneModal({ receiptId }: EditMegaphoneProps) {
const resetModal = useResetRecoilState(modalState);
const user = useRecoilValue(userState);
const [megaphoneData, setMegaphoneData] = useState<MegaphoneData>({
megaphoneId: -1,
content: '',
});
const getMegaphoneData = useMockAxiosGet<MegaphoneData>({
url: `/megaphones/receipt/${receiptId}`,
const setError = useSetRecoilState(errorState);
const getMegaphoneData = useAxiosGet<MegaphoneData>({
url: `/pingpong/megaphones/receipt/${receiptId}`,
setState: setMegaphoneData,
err: 'JY05',
type: 'setError',
Expand All @@ -48,16 +67,21 @@ export default function EditMegaphoneModal({ receiptId }: EditMegaphoneProps) {
'확성기를 삭제하시겠습니까?\n삭제한 확성기는 다시 복구할 수 없습니다.'
);
if (!confirm) return;
mockInstance
.delete(`/megaphones/${megaphoneData.megaphoneId}`)
instance
.delete(`/pingpong/megaphones/${megaphoneData.megaphoneId}`)
.then(() => {
alert('확성기가 삭제되었습니다.');
resetModal();
// TODO : 삭제 이후에 item 목록에 삭제된 확성기가 보이지 않는지 확인 필요함.
})
.catch(() => {
// TODO : 에러 코드 정의 필요함.
alert('확성기 삭제에 실패했습니다.');
.catch((error: unknown) => {
if (isAxiosError<errorPayload>(error) && error.response) {
const { code } = error.response.data;
if (errorCode.includes(code) && code !== 'ME200')
alert(errorMessages[code]);
else setError('JY07');
} else setError('JY07');
})
.finally(() => {
resetModal();
});
}

Expand Down
46 changes: 37 additions & 9 deletions components/modal/store/inventory/NewMegaphoneModal.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { useState } from 'react';
import { useRecoilValue, useResetRecoilState } from 'recoil';
import { useRecoilValue, useResetRecoilState, useSetRecoilState } from 'recoil';
import { UseItemRequest, UseMegaphoneRequest } from 'types/inventoryTypes';
import { mockInstance } from 'utils/mockAxios';
import { instance, isAxiosError } from 'utils/axios';
import { errorState } from 'utils/recoil/error';
import { userState } from 'utils/recoil/layout';
import { modalState } from 'utils/recoil/modal';
import { MegaphoneItem } from 'components/Layout/MegaPhone';
Expand All @@ -24,10 +25,37 @@ const caution = [
'관리자의 판단에 따라 부적절한 내용의 확성기는 삭제될 수 있습니다.',
];

const errorCode = [
'ME200',
'RC100',
'RC500',
'IT200',
'RC200',
'CM007',
] as const;

type errorCodeType = (typeof errorCode)[number];

type errorPayload = {
status: number;
message: string;
code: errorCodeType;
};

const errorMessages: Record<errorCodeType, string> = {
ME200: '23:55-00:05 사이에는 확성기 사용이 불가능합니다.',
RC100: '아이템을 찾을 수 없습니다.',
RC500: '사용 불가능한 아이템입니다.',
IT200: '사용 불가능한 아이템입니다.',
RC200: '이미 등록한 확성기 아이템입니다.',
CM007: '확성기에 등록할 수 있는 글자수는 1 이상 30 이하입니다.',
};

export default function NewMegaphoneModal({ receiptId }: NewMegaphoneProps) {
const user = useRecoilValue(userState);
const [content, setContent] = useState('');
const resetModal = useResetRecoilState(modalState);
const setError = useSetRecoilState(errorState);
async function handleUseMegaphone() {
if (content.length === 0) {
alert('확성기 내용을 입력해주세요.');
Expand All @@ -38,15 +66,15 @@ export default function NewMegaphoneModal({ receiptId }: NewMegaphoneProps) {
content: content,
};
try {
// await mockInstance.post('/megaphones', data);
// NOTE : 테스트를 위해 응답 body를 console에 출력 <- 확성기 등록 결과 확인. 추후 삭제
const response = await mockInstance.post('/megaphones', data);
console.log(response.data.megaphoneList);
//
await instance.post('/pingpong/megaphones', data);
alert('확성기가 등록되었습니다.');
} catch (error: unknown) {
// TODO : error 정의 필요
console.log(error);
if (isAxiosError<errorPayload>(error) && error.response) {
const { code } = error.response.data;
if (errorCode.includes(code) && code !== 'RC100')
alert(errorMessages[code]);
else setError('JY06');
} else setError('JY06');
} finally {
resetModal();
}
Expand Down
16 changes: 10 additions & 6 deletions components/store/InventoryItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import Image from 'next/image';
import { useRecoilValue, useSetRecoilState } from 'recoil';
import { BsGiftFill, BsCircleFill } from 'react-icons/bs';
import { Tooltip } from '@mui/material';
import { InventoryItem } from 'types/inventoryTypes';
import { InventoryItem, InventoryItemStatus } from 'types/inventoryTypes';
import { userState } from 'utils/recoil/layout';
import { modalState } from 'utils/recoil/modal';
import styles from 'styles/store/Inventory.module.scss';
Expand All @@ -11,6 +11,12 @@ type inventoryItemProps = {
item: InventoryItem;
};

const badge: Record<InventoryItemStatus, string> = {
BEFORE: '사용 전',
USING: '사용 중',
WAITING: '대기 중',
};

export function InvetoryItem({ item }: inventoryItemProps) {
const user = useRecoilValue(userState);
const setModal = useSetRecoilState(modalState);
Expand Down Expand Up @@ -66,15 +72,13 @@ export function InvetoryItem({ item }: inventoryItemProps) {
</Tooltip>
)}
<div
className={`${styles.usingBadge} ${
styles[itemStatus === 'USING' ? 'using' : 'before']
}`}
className={`${styles.usingBadge} ${styles[itemStatus.toLowerCase()]}`}
>
<BsCircleFill /> {itemStatus === 'USING' ? '사용중' : '사용 전'}
<BsCircleFill /> {badge[itemStatus]}
</div>
</div>
<div className={styles.overlay}>
{itemStatus === 'USING' ? (
{itemStatus !== 'BEFORE' ? (
<button onClick={handleEditItem}>삭제하기</button>
) : (
<button onClick={handleUseItem}>사용하기</button>
Expand Down
4 changes: 2 additions & 2 deletions pages/api/pingpong/items/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ const item4: InventoryItem = {
itemName: 'ID 색깔 변경권',
imageUri: 'https://cdn.nookazon.com/nookazon/icons/leaf.png',
purchaserIntra: 'kim_takgu',
itemStatus: 'USED',
itemStatus: 'BEFORE',
itemType: 'TEXT_COLOR',
};

Expand Down Expand Up @@ -71,7 +71,7 @@ const item8: InventoryItem = {
itemName: '테스트8',
imageUri: 'https://cdn.nookazon.com/nookazon/icons/leaf.png',
purchaserIntra: 'kim_takgu',
itemStatus: 'USED',
itemStatus: 'BEFORE',
itemType: 'MEGAPHONE',
};

Expand Down
12 changes: 8 additions & 4 deletions styles/store/Inventory.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -107,18 +107,22 @@
grid-area: usingBadge;
justify-content: flex-end;
align-items: center;
&.using svg {

svg {
width: 0.75rem;
height: 0.75rem;
margin-right: 0.3rem;
}

&.using svg {
fill: #08f458;
}
&.before svg {
width: 0.75rem;
height: 0.75rem;
margin-right: 0.3rem;
fill: #d3d3d3;
}
&.waiting svg {
fill: #ff8e00;
}
}

.imgContainer {
Expand Down
3 changes: 2 additions & 1 deletion types/inventoryTypes.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export type InventoryItemStatus = 'BEFORE' | 'USING' | 'USED';
// USED, DELETED 는 응답으로 오지 않음.
export type InventoryItemStatus = 'BEFORE' | 'WAITING' | 'USING';

export type ItemType =
| 'MEGAPHONE'
Expand Down
10 changes: 8 additions & 2 deletions utils/axios.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import axios from 'axios';
import axios, { AxiosError } from 'axios';

const baseURL = `${process.env.NEXT_PUBLIC_SERVER_ENDPOINT}`;
const manageBaseURL = process.env.NEXT_PUBLIC_MANAGE_SERVER_ENDPOINT ?? '/';
Expand Down Expand Up @@ -34,4 +34,10 @@ instanceInManage.interceptors.request.use(
}
);

export { instance, instanceInManage };
function isAxiosError<ErrorPayload>(
error: unknown
): error is AxiosError<ErrorPayload> {
return axios.isAxiosError(error);
}

export { instance, instanceInManage, isAxiosError };

0 comments on commit 35d6cf2

Please sign in to comment.