-
Notifications
You must be signed in to change notification settings - Fork 4
feat: 밸런스게임 모바일 페이지 수정, 삭제 기능 연결 #306
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
…ntend into feat/295-game-edit
Walkthrough이 풀 리퀘스트는 BalanceGame 관련 컴포넌트와 후크 전반에 걸쳐 여러 기능 개선을 포함합니다. App.tsx에서는 모바일 환경에서 BalanceGameEditPage 렌더링을 제한하며, ToastModal 스타일에 미디어 쿼리를 추가해 반응형 디자인을 지원합니다. 또한, GameTagModal에 태그 검증 로직이 도입되었고, 생성/수정 페이지에서는 기존 게임 데이터를 prop으로 전달합니다. 게스트 판별 로직이 localStorage에서 중앙 상태 관리 방식으로 전환되었으며, 삭제 모달, 유틸리티 함수 추가 등 다양한 기능 및 검증 로직이 강화되었습니다. Changes
Possibly related PRs
Suggested labels
Suggested reviewers
Poem
✨ Finishing Touches
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🔭 Outside diff range comments (3)
src/components/molecules/BalanceGameEndingBox/BalanceGameEndingBox.tsx (1)
1-1: 🛠️ Refactor suggestionconsole.log 문을 제거해주세요.
프로덕션 코드에서는 디버깅용 console.log 문을 제거하는 것이 좋습니다. eslint-disable 주석도 함께 제거할 수 있습니다.
-/* eslint-disable no-console */ import React, { useState } from 'react'; // ... .writeText(link) .then(() => { - console.log('게임 링크 복사 완료!'); }) .catch((err) => { - console.log(err); });Also applies to: 45-45, 48-48
src/App.tsx (1)
157-159:⚠️ Potential issue논리 연산자 사용 오류 수정 필요
널 병합 연산자(??)가 잘못 사용되었습니다. 현재 구현은
isMobile이 null 또는 undefined일 때만 NotificationPage를 렌더링합니다.다음과 같이 수정을 제안합니다:
- {isMobile ?? ( // TODO: 404페이지 생성시 조건부로 수정 + {isMobile && ( // TODO: 404페이지 생성시 조건부로 수정 <Route path={PATH.NOTIFICATION} element={<NotificationPage />} /> )}src/components/mobile/molecules/GameTagModal/GameTagModal.tsx (1)
34-45: 🛠️ Refactor suggestion유효성 검사 실패 시 사용자 피드백이 필요합니다.
유효성 검사가 실패할 경우 사용자에게 어떤 문제가 있는지 알려주는 피드백이 없습니다. 오류 메시지를 표시하여 사용자 경험을 개선하는 것이 좋겠습니다.
const handleTagSubmit = () => { if (currentMainTag) { const gameValidation = validateGameTag(form); if (!gameValidation.isValid) { + // 유효성 검사 실패 메시지를 표시 + setError(gameValidation.message); return; } submitGame(); onClose?.(); } };
🧹 Nitpick comments (14)
src/components/molecules/BalanceGameEndingBox/BalanceGameEndingBox.tsx (1)
41-50: 에러 처리를 개선해주세요.클립보드 API 호출 실패 시 사용자에게 적절한 피드백을 제공하는 것이 좋습니다.
const copyGameLink = (link: string) => { navigator.clipboard .writeText(link) .then(() => { - console.log('게임 링크 복사 완료!'); + // Success is handled by showToastModal in handleCopyButton }) .catch((err) => { - console.log(err); + showToastModal('클립보드 복사에 실패했습니다. 다시 시도해주세요.'); }); };src/App.tsx (2)
151-151: 모바일에서 편집 페이지 렌더링 로직 검토모바일 환경에서 BalanceGameEditPage를 숨기고 BalanceGameCreationPage를 통해 편집 기능을 처리하는 접근 방식이 적용되었습니다. 이는 코드 재사용성 측면에서 긍정적이지만, 몇 가지 고려사항이 있습니다.
다음 사항들을 확인해 주시기 바랍니다:
- 모바일 사용자가 직접 URL을 통해 편집 페이지에 접근하려 할 때의 처리
- SEO 및 웹 크롤러에 대한 영향
제안사항:
- 모바일 사용자를 위한 리다이렉션 로직 추가
- 적절한 메타 태그 설정으로 SEO 최적화
163-190: 주석 처리된 코드 정리 필요주석 처리된 대규모 코드 블록이 파일의 가독성과 유지보수성을 저하시킵니다. 특히 App.tsx와 같은 핵심 라우팅 파일에서는 더욱 중요합니다.
제안사항:
- 사용하지 않는 코드는 과감히 삭제
- 향후 사용 예정인 코드는 별도 브랜치로 관리
- TODO 주석에는 관련 이슈 번호 추가
src/hooks/game/usePostBalanceGameForm.ts (2)
56-71: 수정/생성 로직 분기 검토
existingGame && gameSetId조건에 따라 수정 혹은 생성 여부를 분기하는 것은 합리적입니다. 다만,editBalanceGame과createBalanceGame에 대한 에러 상황(네트워크 에러 등) 처리 로직도 추가로 고려해 보시면 완성도가 높아질 것 같습니다.
124-130: 이미지 삭제 분기 로직 주의사항
기존 게임 또는 임시 게임로드 상태(existingBalanceGame혹은isTempGameLoaded)일 때에는deleteFiles를 생략하는 로직이 인상적입니다. 다만, 파일 삭제가 제대로 이뤄지지 않는 경우를 대비한 에러 처리가 필요할 수 있으니 검토해 보세요.src/utils/array.ts (1)
13-15: 콜론(,) 기준으로 배열을 생성하는 함수 추가
createArrayFromCommaString함수는 구현 의도가 명확하고 간단하여 활용도가 높습니다. 다만, 공백 처리를 위해trim()등을 추가로 고려할 수도 있습니다. 예를 들어 "tag1, tag2 " 형태의 문자열도 있을 수 있으니, 필요하면 공백 제거 로직을 포함하는 것이 좋겠습니다.src/hooks/game/validateBalanceGameForm.ts (1)
33-38: 서브 태그 유효성 검사 로직을 개선할 수 있습니다.현재 구현은 기능적으로는 문제가 없으나, 사용자에게 더 명확한 피드백을 제공할 수 있습니다.
다음과 같이 구체적인 오류 메시지를 반환하도록 개선을 제안합니다:
if (subTagList.length > 3) { - return { isValid: false }; + return { isValid: false, message: '서브 태그는 최대 3개까지만 입력 가능합니다.' }; } if (!isAllLessThan(subTagList, 10)) { - return { isValid: false }; + return { isValid: false, message: '각 서브 태그는 10자 이하여야 합니다.' }; }src/components/mobile/molecules/GameTagModal/GameTagModal.tsx (1)
76-82: 입력 필드에 시각적 제약이 필요합니다.maxLength 속성이 제거되어 사용자가 입력 제한을 알 수 없습니다. 입력 길이 제한을 시각적으로 표시하거나 실시간으로 유효성을 검사하는 것이 좋겠습니다.
<input name="subTag" css={S.inputStyling} placeholder="ex. 너무어려운밸런스게임, 선택장애, 이상형" value={form.subTag} onChange={setSubTagValue} + maxLength={50} // 적절한 최대 길이 설정 />src/utils/balanceGameUtils.ts (1)
113-132: 함수 문서화 및 타입 안전성 개선이 필요합니다.새로 추가된 함수의 문서화와 타입 안전성을 개선하면 코드의 유지보수성이 향상될 것 같습니다.
+/** + * GameSet 데이터를 BalanceGame 형식으로 변환하는 함수 + * @param gameSet - 변환할 GameSet 객체 + * @returns BalanceGame 형식으로 변환된 객체 + * @throws {Error} gameSet이 null 또는 undefined인 경우 + */ export const transformGameSetToBalanceGameSet = ( gameSet: GameSet, ): BalanceGame => { + if (!gameSet) { + throw new Error('GameSet must not be null or undefined'); + } + return { title: gameSet.title, mainTag: gameSet.mainTag, subTag: gameSet.subTag, games: gameSet.gameDetailResponses.map((gameDetail) => ({ - description: gameDetail.description ?? '', + description: gameDetail.description || '', gameOptions: gameDetail.gameOptions.map((option) => ({ id: option.id, name: option.name, - imgUrl: option.imgUrl ?? '', + imgUrl: option.imgUrl || '', description: option.description, optionType: option.optionType, - fileId: option.fileId ?? null, + fileId: option.fileId || null, })), })), }; };src/components/mobile/organisms/BalanceGameCreateSection/BalanceGameCreateSection.tsx (2)
16-19: Props 유효성 검사가 필요합니다.existingGame이 제공될 때 gameSetId도 필수적으로 제공되어야 하는지 명확하게 하면 좋겠습니다.
interface BalanceGameCreateSectionProps { existingGame?: GameSet; - gameSetId?: number; + gameSetId: existingGame extends GameSet ? number : undefined; }
96-102: 이미지 삭제 핸들러의 타입 안전성 개선이 필요합니다.fileId가 null이나 undefined일 때의 처리를 더 명확하게 하면 좋겠습니다.
- handleDeleteImg( - form.games[gameStage].gameOptions[selectedOptionId].fileId ?? - null, - selectedOptionId, - ); + const fileId = form.games[gameStage].gameOptions[selectedOptionId].fileId; + handleDeleteImg(fileId || null, selectedOptionId);src/components/mobile/organisms/BalanceGameSection/BalanceGameSection.tsx (3)
102-114: 게임 삭제 중 로딩 상태 처리가 필요합니다.삭제 기능이 잘 구현되어 있으나, 다음 개선사항을 고려해보세요:
- 삭제 진행 중 로딩 상태 표시
- 삭제 중 버튼 비활성화로 중복 클릭 방지
+ const [isDeleting, setIsDeleting] = useState(false); const handleGameDeleteButton = () => { + setIsDeleting(true); deleteBalanceGame( { gameSetId }, { onSuccess: () => { navigate('/'); }, onError: () => { showToastModal(ERROR.DELETEGAME.FAIL); + setIsDeleting(false); }, }, ); };
126-140: 네비게이션 state에 타입 정의가 필요합니다.navigate 함수에 전달되는 state 객체에 타입을 정의하면 타입 안정성이 향상됩니다.
interface GameNavigationState { game: GameSet; gameSetId: number; } // 사용 예시: navigate<GameNavigationState>(`/${PATH.CREATE.GAME}`, { state: { game, gameSetId } });
155-160: 삭제 진행 중 모달의 확인 버튼 비활성화가 필요합니다.TextModal 컴포넌트에 isLoading prop을 추가하여 삭제 진행 중에는 확인 버튼을 비활성화하는 것이 좋습니다.
<TextModal text="해당 게임을 삭제하시겠습니까?" isOpen={deleteModalOpen} + isLoading={isDeleting} onConfirm={handleGameDeleteButton} onClose={() => setDeleteModalOpen(false)} />
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (16)
src/App.tsx(1 hunks)src/components/atoms/ToastModal/ToastModal.style.ts(2 hunks)src/components/mobile/molecules/GameTagModal/GameTagModal.tsx(2 hunks)src/components/mobile/organisms/BalanceGameCreateSection/BalanceGameCreateSection.tsx(4 hunks)src/components/mobile/organisms/BalanceGameEndingSection/BalanceGameEndingSection.tsx(2 hunks)src/components/mobile/organisms/BalanceGameSection/BalanceGameSection.style.ts(1 hunks)src/components/mobile/organisms/BalanceGameSection/BalanceGameSection.tsx(8 hunks)src/components/molecules/BalanceGameEndingBox/BalanceGameEndingBox.tsx(2 hunks)src/hooks/api/game/useCreateGameMutation.ts(1 hunks)src/hooks/game/usePostBalanceGameForm.ts(6 hunks)src/hooks/game/validateBalanceGameForm.ts(2 hunks)src/pages/mobile/BalanceGameCreationMobilePage/BalanceGameCreationMobilePage.tsx(1 hunks)src/pages/mobile/BalanceGameMobilePage/BalanceGameMobilePage.tsx(1 hunks)src/utils/array.ts(1 hunks)src/utils/balanceGameUtils.ts(1 hunks)src/utils/validator.ts(1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (2)
- GitHub Check: storybook
- GitHub Check: build
🔇 Additional comments (19)
src/pages/mobile/BalanceGameMobilePage/BalanceGameMobilePage.tsx (1)
10-11: 멤버 데이터 조회 로직이 개선되었습니다!토큰 파싱 로직을 제거하고
useMemberQuery훅을 직접 사용하도록 변경하여 코드가 더 간단하고 명확해졌습니다.src/components/mobile/organisms/BalanceGameEndingSection/BalanceGameEndingSection.tsx (1)
10-11: 게스트 상태 관리가 Redux로 전환되었습니다!localStorage 대신 Redux를 사용하여 상태 관리를 중앙화했습니다. 이는 애플리케이션의 상태 관리를 더 예측 가능하고 유지보수하기 쉽게 만듭니다.
Also applies to: 34-34
src/components/molecules/BalanceGameEndingBox/BalanceGameEndingBox.tsx (1)
12-13: 게스트 상태 관리가 Redux로 통합되었습니다!localStorage에서 Redux로의 전환이 일관되게 적용되어 상태 관리가 개선되었습니다.
Also applies to: 30-30
src/hooks/game/usePostBalanceGameForm.ts (6)
1-5: 임포트 구조가 명확하고 사용 의도가 잘 드러납니다.
추가된 임포트들은 모두 필요한 의존성을 알기 쉽게 보여주고 있어 가독성을 높여줍니다.Also applies to: 9-9
20-21: 추가된validateBalanceGameForm와useEditGamesMutation임포트 확인
밸런스 게임 폼 검증 유틸, 게임 수정 API 호출 훅을 명확하게 분리하여 관리 중이니 유지보수성에 도움이 됩니다.
28-28: gameSetId 매개변수 추가
기존 게임 수정 로직에서 식별용 ID를 명확하게 받을 수 있도록 구성한 점이 인상적입니다. 필요한 경우가 아니면 undefined로 처리되는 옵셔널 파라미터로 설계된 점도 좋은 패턴입니다.
30-33:existingBalanceGame를 생성하는 로직 검토
existingGame이 존재할 때만 변환해주는 것으로, null 처리나 변환 실패 시의 에러 처리가 필요한 상황이 있는지 확인해 보세요. 현재 로직으로는 안전해 보이지만,transformGameSetToBalanceGameSet의 예외 케이스가 있을 경우를 대비해 에러 핸들링을 고려해볼 수도 있습니다.
35-35: 기본 폼 상태 설정
existingBalanceGame ?? { ... }패턴은 재활용 가능성이 높고, 기존 데이터를 우선적으로 사용하는 구조가 직관적입니다. 가독성과 유지보수에 문제 없습니다.
46-46: 게임 수정 훅 초기화
useEditGamesMutation을 통해 수정 API를 명료하게 분리했네요. API 호출 로직을 훅으로 추상화해 재사용성도는 유지하기에 적절해 보입니다.src/utils/validator.ts (1)
21-25: 문자열 배열 전체 길이 검사 함수 추가
isAllLessThan(arr, num)함수로 배열 내 모든 문자열 길이가num이하인지 단순 명료하게 확인할 수 있습니다. 유효성 검사의 반복 패턴을 효과적으로 추상화했으며, 빈 배열이나 null 처리를 고려해야 할 상황이 있다면 추가 방어 로직을 고려해 볼 수도 있습니다.src/pages/mobile/BalanceGameCreationMobilePage/BalanceGameCreationMobilePage.tsx (3)
7-10: State 인터페이스가 적절하게 정의되었습니다.게임 데이터의 타입 안전성을 보장하기 위한 인터페이스가 잘 구현되었습니다.
13-17: 상태 접근 시 타입 안전성과 null 처리가 잘 구현되었습니다.location.state의 타입 캐스팅과 옵셔널 체이닝을 통한 안전한 상태 접근이 잘 구현되었습니다.
21-24: 게임 수정 기능이 적절하게 구현되었습니다.기존 게임 데이터와 ID를 props로 전달하여 생성/수정 기능을 통합적으로 처리할 수 있도록 구현되었습니다.
src/components/atoms/ToastModal/ToastModal.style.ts (2)
23-25: 타이포그래피 스프레드 연산자 사용이 적절합니다.타이포그래피 스타일을 스프레드 연산자로 적용하여 코드의 재사용성과 유지보수성이 향상되었습니다.
34-37: 모바일 반응형 디자인이 적절하게 구현되었습니다.430px 이하의 화면에서 모바일에 최적화된 타이포그래피와 패딩이 적용되도록 구현되었습니다.
src/hooks/api/game/useCreateGameMutation.ts (1)
24-24: 성공 메시지 상수가 올바르게 업데이트되었습니다.SUCCESS.CREATEGAME.CREATE에서 SUCCESS.GAME.CREATE로 변경되어 메시지 상수의 일관성이 개선되었습니다.
src/hooks/game/validateBalanceGameForm.ts (1)
28-29: 서브 태그 파싱 로직이 적절하게 구현되었습니다.createArrayFromCommaString 유틸리티 함수를 사용하여 서브 태그 문자열을 배열로 변환하는 로직이 잘 구현되었습니다.
src/components/mobile/organisms/BalanceGameSection/BalanceGameSection.style.ts (1)
83-83: 서브 태그 간격 조정이 적절합니다!Flex 컨테이너 내의 요소들 간 간격을 8px로 설정한 것이 다른 간격들과 일관성 있게 잘 어울립니다.
src/components/mobile/organisms/BalanceGameSection/BalanceGameSection.tsx (1)
4-5: 상태 관리 개선이 잘 이루어졌습니다!localStorage에서 Redux store로 게스트 상태 체크 로직을 이동한 것이 좋은 개선입니다. 이는 상태 관리를 중앙화하고 타입 안정성을 향상시킵니다.
Also applies to: 60-60
| </div> | ||
| <div css={S.subTagWrapper}> | ||
| {game.subTag && <GameTagChip tag={game.subTag} />} | ||
| {game.subTag && subTagList.map((tag) => <GameTagChip tag={tag} />)} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
map 함수 사용 시 key prop이 필요합니다.
React 요소 배열을 렌더링할 때 각 요소에 고유한 key prop을 지정해야 합니다.
- {game.subTag && subTagList.map((tag) => <GameTagChip tag={tag} />)}
+ {game.subTag && subTagList.map((tag, index) => (
+ <GameTagChip key={`${tag}-${index}`} tag={tag} />
+ ))}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| {game.subTag && subTagList.map((tag) => <GameTagChip tag={tag} />)} | |
| {game.subTag && subTagList.map((tag, index) => ( | |
| <GameTagChip key={`${tag}-${index}`} tag={tag} /> | |
| ))} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🧹 Nitpick comments (3)
src/components/mobile/organisms/BalanceGameSection/BalanceGameSection.tsx (3)
76-79: 게임 삭제 기능의 사용자 경험 개선이 필요합니다.삭제 중 로딩 상태 표시와 구체적인 에러 메시지 처리가 필요합니다.
다음과 같은 개선을 제안합니다:
+ const [isDeleting, setIsDeleting] = useState<boolean>(false); const handleGameDeleteButton = () => { + setIsDeleting(true); deleteBalanceGame( { gameSetId }, { onSuccess: () => { + setIsDeleting(false); navigate('/'); }, onError: (error) => { + setIsDeleting(false); - showToastModal(ERROR.DELETEGAME.FAIL); + showToastModal(error.message || ERROR.DELETEGAME.FAIL); }, }, ); };Also applies to: 102-114
126-161: 메뉴 아이템과 모달의 일관성 개선이 필요합니다.삭제 중 메뉴 아이템 비활성화와 모달 네이밍의 일관성이 필요합니다.
다음과 같은 개선을 제안합니다:
const myGameItem: MenuItem[] = [ { label: '수정', onClick: () => { navigate(`/${PATH.CREATE.GAME}`, { state: { game, gameSetId } }); }, + disabled: isDeleting, }, { label: '삭제', onClick: () => { setDeleteModalOpen(true); }, + disabled: isDeleting, }, ];그리고 모달 컴포넌트의 네이밍을 일관되게 변경하는 것을 추천드립니다:
ShareModal->TextModal로 통일하거나TextModal->ConfirmModal로 변경
210-211: 빈 태그 필터링이 필요합니다.빈 문자열이나 공백만 있는 태그는 렌더링하지 않도록 처리가 필요합니다.
다음과 같이 수정을 제안합니다:
{game.subTag && - subTagList.map((tag) => <GameTagChip key={tag} tag={tag} />)} + subTagList + .filter((tag) => tag.trim()) + .map((tag) => <GameTagChip key={tag} tag={tag.trim()} />)}
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
src/components/mobile/organisms/BalanceGameSection/BalanceGameSection.tsx(8 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (2)
- GitHub Check: build
- GitHub Check: storybook
🔇 Additional comments (1)
src/components/mobile/organisms/BalanceGameSection/BalanceGameSection.tsx (1)
4-7: 상태 관리 및 유틸리티 개선이 잘 이루어졌습니다!Redux를 통한 중앙 상태 관리로의 전환과 타입 안전성이 향상된 유틸리티 함수의 도입이 적절합니다.
Also applies to: 22-24
| const gameStages: GameDetail[] = | ||
| game?.gameDetailResponses ?? gameDefaultDetail; | ||
| const isGuest = !localStorage.getItem('accessToken'); | ||
| const isGuest = !useNewSelector(selectAccessToken); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
옵셔널 체이닝을 통한 안전한 접근이 필요합니다.
game 객체가 undefined일 때 subTag 접근이 안전하도록 처리가 필요합니다.
다음과 같이 수정을 제안합니다:
- const subTagList = createArrayFromCommaString(game?.subTag ?? '');
+ const subTagList = game ? createArrayFromCommaString(game.subTag ?? '') : [];Also applies to: 65-65
WonJuneKim
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
모바일 페이지 관련 코멘트 남겼습니다~ 논의 했던 내용들이 잘 담겨 있네요! 고생하셨어요!
| <Route | ||
| path={PATH.BALANCEGAME.EDIT()} | ||
| element={<BalanceGameEditPage />} | ||
| element={!isMobile && <BalanceGameEditPage />} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
이런 표현 좋네요~
| }: BalanceGameEndingSectionProps) => { | ||
| const navigate = useNavigate(); | ||
| const isGuest = !localStorage.getItem('accessToken'); | ||
| const isGuest = !useNewSelector(selectAccessToken); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
리덕스로 일원화 한 점 아주 좋습니다~
| existingGame?: GameSet; | ||
| gameSetId?: number; | ||
| } | ||
|
|
||
| const BalanceGameCreateSection = ({ | ||
| existingGame, | ||
| gameSetId, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
이 organisms의 props는 전부 옵셔널인데, default 설정이 없으면 어떻게 처리되고 있는지 궁금합니다!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
게임이 존재할 때는 게임 수정, 존재하지 않을 때는 게임 생성이 수행됩니다!
| }; | ||
|
|
||
| export { isEmptyString, isLongerThan, isAllTrue, isTimeLimit }; | ||
| const isAllLessThan = (arr: string[], num: number) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| const isAllLessThan = (arr: string[], num: number) => { | |
| const validateElementsLength = (arr: string[], num: number) => { |
또는
| const isAllLessThan = (arr: string[], num: number) => { | |
| const checkMaxLength = (arr: string[], num: number) => { |
요런 네이밍은 어떠신가요??
++) ts doc 로 간단한 사용법(+매개변수에 대한 설명)까지 주어진다면 더 가독성이 좋을 거 같아요!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
check나 validate의 이름은 배열의 모든 요소들의 길이가 인자로 받은 수보다 같거나 작은지에 대한 역할을 정확히 보여주지 않다고 생각되어 isAllLessThan을 사용했습니다..!! 해당 파일 내의 함수 이름에 통일성을 주기 위함도 있구요 ㅎㅎ
| }; | ||
|
|
||
| export const createArrayFromCommaString = (str: string): string[] => { | ||
| return str.split(','); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
이 부분이 서브 태그와 관련이 있군요!
|
|
||
| const BalanceGameCreationMobilePage = () => { | ||
| const location = useLocation(); | ||
| const state = location.state as State; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
혹시 타입 단언을 사용하게 된 계기가 있을까요?!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
as State 처럼 타입 지정을 해주지 않으면 오류가 나서 해둔건데 질문 주셔서 서치해보니 기본적으로 state는 unknown으로 정의되기 때문에 타입 단언이 필요하다고 하네요!! 🙌
alwubin
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
늦은 답변 죄송합니다🙇♀️ 원준님 리뷰에서 제기되었던 수정 사항들이 잘 반영되었네용ㅎㅎ 전반적으로 코드가 가독성 좋고 유지보수하기 편리하도록 작성된 것 같아요! 고생 많으셨습니다👏
WonJuneKim
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
수정사항 확인했습니다~ 고생하셨습니다!!
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🧹 Nitpick comments (1)
src/components/mobile/organisms/BalanceGameSection/BalanceGameSection.tsx (1)
235-236: 서브태그 렌더링이 개선되었으나 키 처리에 주의가 필요합니다.서브태그를 배열로 변환하여 렌더링하는 방식은 좋습니다. 현재 키로 태그 값 자체를 사용하고 있는데, 동일한 태그가 있을 경우 중복 키가 발생할 수 있습니다. 태그와 인덱스를 조합하여 키를 생성하는 것이 더 안전합니다.
- {game.subTag && subTagList.map((tag) => <GameTagChip key={tag} tag={tag} />)} + {game.subTag && subTagList.map((tag, index) => <GameTagChip key={`${tag}-${index}`} tag={tag} />)}
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
src/components/mobile/organisms/BalanceGameSection/BalanceGameSection.tsx(8 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (1)
- GitHub Check: build
🔇 Additional comments (10)
src/components/mobile/organisms/BalanceGameSection/BalanceGameSection.tsx (10)
4-5: localStorage에서 Redux로의 전환이 잘 이루어졌습니다.게스트 상태 확인을 위해 localStorage 대신 Redux를 사용하는 방식으로 개선되었습니다. 이는 상태 관리를 중앙화하고 일관성을 유지하는 좋은 접근법입니다.
7-7: 유틸리티 함수 활용으로 코드 재사용성이 향상되었습니다.쉼표로 구분된 문자열을 배열로 변환하는 유틸리티 함수를 사용함으로써 코드가 더 깔끔해지고 재사용 가능해졌습니다.
61-61: Redux 선택자를 통한 게스트 상태 확인 방식이 개선되었습니다.localStorage 대신 Redux 상태를 사용하여 게스트 상태를 확인하는 방식으로 변경되었습니다. 이는 상태 관리의 일관성을 높이고 유지보수를 용이하게 합니다.
66-66: subTag 처리 방식 개선이 필요합니다.
game객체가 undefined일 경우 안전하게 처리할 수 있도록 옵셔널 체이닝을 적용한 것은 좋습니다. 그러나 이전 리뷰 코멘트에서 언급된 것처럼 추가적인 안전장치가 필요합니다.
77-78: 게임 삭제 기능이 적절하게 추가되었습니다.게임 삭제를 위한 mutation hook이 추가되어 기능이 완성되었습니다.
79-85: 모달 상태 관리가 효율적으로 구현되었습니다.여러 유형의 모달을 하나의 상태 변수로 관리하는 방식이 깔끔하고 유지보수하기 좋습니다.
109-121: 게임 삭제 핸들러가 적절하게 구현되었습니다.성공 시 홈으로 리다이렉트하고 실패 시 오류 메시지를 표시하는 방식으로 사용자 경험을 고려한 구현이 잘 되었습니다.
133-146: 내 게임 메뉴 항목이 기능적으로 잘 구현되었습니다.수정 및 삭제 기능에 대한 메뉴 항목이 적절하게 구현되었으며, 수정 시 필요한 상태 데이터를 함께 전달하는 방식도 좋습니다.
147-154: 다른 사용자의 게임에 대한 메뉴 항목이 적절하게 구현되었습니다.신고 기능을 위한 메뉴 항목이 잘 구현되었습니다.
169-180: TextModal 컴포넌트 구현이 명확합니다.게임 삭제와 신고에 대한 확인 모달이 각각의 목적에 맞게 적절하게 구성되었습니다.
| <ReportModal | ||
| isOpen={activeModal === 'reportGame'} | ||
| onConfirm={() => {}} | ||
| onClose={() => setShareModalOpen(false)} | ||
| onClose={onCloseModal} | ||
| /> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
ReportModal 컴포넌트에 대한 확인 핸들러 구현이 필요합니다.
ReportModal의 onConfirm 핸들러가 빈 함수로 설정되어 있습니다. 실제 신고 기능을 구현하거나 해당 기능이 아직 준비되지 않았다면 TODO 주석을 추가하는 것이 좋습니다.
- onConfirm={() => {}}
+ onConfirm={() => {
+ // TODO: 신고 API 연동 구현 필요
+ }}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| <ReportModal | |
| isOpen={activeModal === 'reportGame'} | |
| onConfirm={() => {}} | |
| onClose={() => setShareModalOpen(false)} | |
| onClose={onCloseModal} | |
| /> | |
| <ReportModal | |
| isOpen={activeModal === 'reportGame'} | |
| onConfirm={() => { | |
| // TODO: 신고 API 연동 구현 필요 | |
| }} | |
| onClose={onCloseModal} | |
| /> |



💡 작업 내용
💡 자세한 설명
✅ validateBalanceGameForm
utils폴더 내에 쉼표를 기준으로 배열을 리턴하는 함수와 배열 내 모든 요소의 길이가 10글자 이하인지 확인하는 함수를 선언해두었습니다!✅ GameTagModal
handleTagSubmit함수 내에서 실행하도록 하였습니다.✅ 밸런스 게임 수정 관련
-.Clipchamp.6.mp4
📗 참고 자료 (선택)
📢 리뷰 요구 사항 (선택)
🚩 후속 작업 (선택)
서브 태그 관련으로 게임 태그 모달 ui가 수정되면 이슈 파서 진행하겠습니다!!😃
✅ 셀프 체크리스트
closes #295
Summary by CodeRabbit
새로운 기능
리팩토링
스타일