Skip to content
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

refactor: mypage layout 분리 #203

Merged
merged 17 commits into from
Oct 22, 2024
Merged

refactor: mypage layout 분리 #203

merged 17 commits into from
Oct 22, 2024

Conversation

sumi-0011
Copy link
Member

@sumi-0011 sumi-0011 commented Oct 2, 2024

💡 기능

  • 마이페이지 레이아웃 분리
  • 페이지에서 (~~~)와 같이 사용하면 경로로 인식하지 않으면서 폴더로 파일들을 묶을 수 있음.
  • github-custom/mypage 경로에서 접근 가능하게하고
  • my pet/mypage/my-pet 경로에서 접근 가능하도록 함,
  • 마이페이지 하위 두 페이지는 레이아웃이 비슷해, 변경되는 rightSection부분을 제외하고 layout으로 분리하여 공통적으로 사용

🔎 기타

  • my-pet 페이지 초안을 만들고, 이후에 이어서 작업할 예정이였으나 git에 잘못 올려버림,, 그렇지만 잘 동작하고 진입점이 없으므로 따로 삭제하지 않고 그냥 PR올리겠습니다

Summary by CodeRabbit

  • 새로운 기능

    • "Common" 섹션 추가로 애플리케이션의 공통 용어 정의
    • 사용자 프로필 페이지에 탭 인터페이스 추가
    • 반려동물 관리 UI 추가 및 선택된 반려동물 정보 표시 기능
    • MypageLayoutMypageMyPets 컴포넌트 추가
    • SelectPersonaList 컴포넌트의 확장 보기 기능 추가
  • 버그 수정

    • 컴포넌트 구조 개선으로 사용자 인터페이스 향상
  • 문서화

    • 여러 컴포넌트 및 레이아웃에 대한 설명 추가
  • 삭제

    • PointInfoRightSection 컴포넌트 제거
    • 이전 Mypage 컴포넌트 삭제

@sumi-0011 sumi-0011 self-assigned this Oct 2, 2024
@sumi-0011 sumi-0011 requested a review from hyesungoh as a code owner October 2, 2024 09:16
Copy link

coderabbitai bot commented Oct 2, 2024

Caution

Review failed

The pull request is closed.

Walkthrough

이 변경 사항은 apps/web/messages/en_US.json 파일에 "Common"이라는 새로운 섹션을 추가하여 애플리케이션 전반에서 사용되는 공통 용어를 정의합니다. 또한, 여러 컴포넌트에서 상태 변수를 추가하고, UI를 개선하기 위해 구조를 수정했습니다. 새로 추가된 Mypage 컴포넌트는 탭 인터페이스를 통해 다른 내용을 표시하며, MypageMyPets 컴포넌트는 사용자가 애완동물을 관리할 수 있는 인터페이스를 제공합니다. 일부 파일은 삭제되었습니다.

Changes

파일 경로 변경 요약
apps/web/messages/en_US.json "Common" 섹션 추가: "pet", "name", "grade", "level", "price", "date", "sell" 추가
apps/web/src/app/[locale]/mypage/(github-custom)/FarmType.tsx isExtend 상태 변수 추가, UI 개선을 위한 구조 수정, SelectPersonaListisExtend prop 추가
apps/web/src/app/[locale]/mypage/(github-custom)/OneType.tsx isExtend 상태 변수 추가, UI 개선을 위한 구조 수정, SelectPersonaListisExtend prop 추가
apps/web/src/app/[locale]/mypage/(github-custom)/page.tsx Mypage 컴포넌트 추가, 탭 인터페이스 구현, MYPAGE_TAB_INNER_MAP 정의
apps/web/src/app/[locale]/mypage/PersonaList.tsx isExtend prop 추가, 내부 상태 관리 제거, 구조 단순화
apps/web/src/app/[locale]/mypage/PointInfo.tsx PointInfo 컴포넌트 삭제
apps/web/src/app/[locale]/mypage/RightSection.tsx RightSection 컴포넌트 삭제
apps/web/src/app/[locale]/mypage/layout.tsx MypageLayout 컴포넌트 추가, 레이아웃 구성 및 스타일 정의
apps/web/src/app/[locale]/mypage/my-pet/page.tsx MypageMyPetsSelectedPetTable 컴포넌트 추가, 애완동물 관리 UI 구현
apps/web/src/app/[locale]/mypage/page.tsx 기존 Mypage 컴포넌트 삭제

Possibly related PRs

  • My Pet 페이지 추가 #211: 이 PR은 공통 용어 업데이트와 관련된 "Common" 섹션을 도입하여 "내 펫" 페이지에서 사용되는 용어의 일관성을 강화합니다.
  • refactor: mypage layout 분리 #203: 이 PR은 "마이 페이지" 레이아웃 리팩토링을 통해 "Mypage" 섹션에 새로운 로컬라이제이션 항목을 추가하여 주요 PR의 업데이트와 일치합니다.
  • 마이페이지 리뉴얼 #200: 이 PR은 "마이 페이지" 갱신을 통해 로컬라이제이션 파일을 업데이트하여 주요 PR의 "내 펫" 페이지와 관련된 용어의 일관성을 보장합니다.
  • refactor: persona schema type 정의 수정 및 queryFactory 추가 #202: 이 PR은 페르소나 스키마 타입 리팩토링 및 쿼리 팩토리 기능 도입을 통해 주요 PR과 관련된 애완동물 데이터 처리 개선을 다룹니다.

Suggested labels

diff: M, area: UI, area: Utils

Suggested reviewers

  • hyesungoh

Poem

🐰 변화의 바람이 불어와
공통의 언어가 피어나는구나
새로운 탭에서 애완동물 선택,
모두 함께 즐길 수 있는 공간!
UI가 환하게 빛나고,
우리 모두의 마음도 함께 뛰네! 🌼


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

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)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@sumi-0011
Copy link
Member Author

@coderabbitai review

Copy link

coderabbitai bot commented Oct 2, 2024

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 9

🧹 Outside diff range and nitpick comments (9)
apps/web/src/app/[locale]/mypage/(github-custom)/page.tsx (2)

1-9: import 문이 잘 구성되어 있습니다.

import 문들이 잘 구성되어 있고 필요한 모듈들을 적절히 가져오고 있습니다. 다만, 일관성을 위해 다음과 같은 작은 개선을 제안합니다:

  • OneType 컴포넌트를 default export로 변경하고, 다른 import 문과 일관되게 만들어보는 것은 어떨까요?

다음과 같이 변경할 수 있습니다:

-import { OneType } from './OneType';
+import OneType from './OneType';

이렇게 하면 FarmTypeOneType의 import 스타일이 일치하게 됩니다.


44-67: 스타일링이 잘 구성되어 있습니다.

tabListStyle의 정의가 포괄적이고 잘 구성되어 있습니다. 탭 아이템의 다양한 상태(기본, 호버, 선택됨)에 대한 스타일을 명확하게 정의하고 있습니다. 다만, 유지보수성을 높이기 위해 다음과 같은 작은 개선을 제안합니다:

반복되는 색상 값을 변수로 추출하는 것이 어떨까요? 예를 들면:

const colors = {
  white10: 'white.white_10',
  white25: 'white.white_25',
  white50: 'white.white_50',
  white75: 'white.white_75',
  white100: 'white.white_100',
};

const tabListStyle = flex({
  // ... 기존 코드
  color: colors.white25,
  backgroundColor: colors.white10,
  borderColor: colors.white10,
  '&.selected': {
    color: colors.white100,
    backgroundColor: colors.white25,
    borderColor: colors.white50,
  },
  // ... 나머지 코드
});

이렇게 하면 색상 값을 한 곳에서 관리할 수 있어 향후 변경이 필요할 때 더 쉽게 수정할 수 있습니다.

apps/web/src/app/[locale]/mypage/PersonaList.tsx (2)

17-17: 새로운 prop 추가 승인 및 문서화 제안

isExtend: boolean prop을 추가한 것은 PR의 목적에 부합하며, 컴포넌트의 확장 상태를 외부에서 제어할 수 있게 해줍니다. 이는 좋은 변경사항입니다.

이 새로운 prop에 대한 간단한 JSDoc 주석을 추가하는 것이 좋겠습니다. 예를 들어:

/**
 * 컴포넌트가 확장된 상태인지 여부를 나타냅니다.
 */
isExtend: boolean;

72-88: 컴포넌트 반환문 변경 승인 및 개선 제안

컴포넌트의 반환문을 크게 수정한 것은 PR의 목적에 부합하는 좋은 변경사항입니다. 외부 <section> 요소와 확장 보기를 위한 제목 및 토글 버튼을 제거하여 레이아웃을 단순화했습니다. isExtend prop을 사용하여 flex 래핑을 제어하는 것도 적절합니다.

성능 최적화를 위해 css 함수 호출을 useMemo로 감싸는 것을 고려해보세요. 예를 들어:

const listWrapStyle = useMemo(() => css({ flexWrap: isExtend ? 'wrap' : 'nowrap' }), [isExtend]);

// 사용시
<div className={cx(listStyle, listWrapStyle)}>

이렇게 하면 isExtend가 변경될 때만 스타일이 재계산됩니다.

apps/web/src/app/[locale]/mypage/(github-custom)/FarmType.tsx (4)

28-28: 새로운 상태 변수 추가가 적절합니다.

isExtend 상태 변수를 추가한 것은 컴포넌트의 확장 기능을 위한 좋은 접근입니다. 다만, 변수명을 더 명확하게 하는 것이 좋을 것 같습니다.

변수명을 isExtended로 변경하는 것이 어떨까요? 이렇게 하면 현재 상태를 더 정확하게 표현할 수 있습니다:

- const [isExtend, setIsExtend] = useState(false);
+ const [isExtended, setIsExtended] = useState(false);

78-91: 새로운 섹션 추가가 UI를 개선했습니다. 접근성과 국제화 관련 제안사항이 있습니다.

새로운 섹션 추가로 사용자 인터페이스가 개선되었습니다. 펫 목록을 확장하거나 축소할 수 있는 기능은 사용자 경험을 향상시킬 것 같습니다.

접근성과 국제화를 개선하기 위해 다음 사항들을 고려해보시는 것은 어떨까요?

  1. 버튼에 aria-expanded 속성을 추가하여 스크린 리더 사용자에게 현재 상태를 알려줍니다.
  2. 버튼에 aria-controls 속성을 추가하여 제어하는 요소를 명시합니다.
  3. 확장/축소 텍스트를 별도의 번역 키로 분리하여 국제화를 용이하게 합니다.

예시 코드:

<Button
  className="extend-button"
  onClick={() => setIsExtend((prev) => !prev)}
  aria-expanded={isExtend}
  aria-controls="persona-list"
>
  {t(isExtend ? 'shrink-button' : 'extend-button')}
</Button>
<SelectPersonaList
  id="persona-list"
  // ... 기존 props
  isExtend={isExtend}
/>

118-130: 새로운 CSS 스타일이 적절히 추가되었습니다. 반응형 디자인과 유지보수성 개선을 위한 제안이 있습니다.

새로운 섹션을 위한 CSS 스타일이 잘 구현되었습니다. 레이아웃과 디자인이 일관성 있게 적용되었습니다.

반응형 디자인과 유지보수성을 개선하기 위해 다음 사항들을 고려해보시는 것은 어떨까요?

  1. 미디어 쿼리를 사용하여 모바일 환경에서의 레이아웃을 조정합니다.
  2. 매직 넘버 대신 변수나 테마 시스템을 사용하여 일관성을 유지하고 유지보수를 용이하게 합니다.
  3. 버튼 위치 지정을 위해 absolute 포지셔닝 대신 flexbox나 grid를 사용하여 더 유연한 레이아웃을 구현합니다.

예시 코드:

const selectPetContainerStyle = css({
  display: 'flex',
  flexDirection: 'column',
  gap: 'var(--spacing-4)',
  position: 'relative',
  '& .heading': {
    textStyle: 'glyph18.bold',
    color: 'var(--color-white)',
    marginBottom: 'var(--spacing-4)',
  },
  '& .extend-button': {
    alignSelf: 'flex-end',
    marginTop: 'var(--spacing-negative-4)',
  },
  '@media (max-width: 768px)': {
    gap: 'var(--spacing-2)',
    '& .extend-button': {
      marginTop: 0,
    },
  },
});

Line range hint 1-130: 전반적인 변경사항이 사용자 경험을 개선했습니다. 몇 가지 추가 개선 사항을 제안합니다.

FarmType 컴포넌트에 대한 변경사항들이 전반적으로 사용자 인터페이스와 기능성을 향상시켰습니다. 펫 목록을 확장/축소할 수 있는 새로운 기능은 사용자에게 더 나은 제어 기능을 제공합니다.

다음 사항들을 고려하여 컴포넌트를 더욱 개선할 수 있을 것 같습니다:

  1. 접근성: aria-* 속성을 추가하여 스크린 리더 사용자를 위한 지원을 강화합니다.
  2. 국제화: 하드코딩된 문자열을 번역 키로 대체하여 다국어 지원을 개선합니다.
  3. 반응형 디자인: 다양한 화면 크기에 대응할 수 있도록 미디어 쿼리를 활용합니다.
  4. 상태 관리: 컴포넌트가 커짐에 따라 상태 관리 라이브러리 사용을 고려해볼 수 있습니다.

이러한 개선사항들을 통해 FarmType 컴포넌트의 품질과 유지보수성을 더욱 높일 수 있을 것입니다.

apps/web/src/app/[locale]/mypage/my-pet/page.tsx (1)

73-93: currentPersona가 null일 때 빈 행이 렌더링됨

currentPersonanull인 경우에도 빈 row div가 렌더링됩니다. 이는 불필요한 DOM 요소를 생성할 수 있으므로, currentPersona가 존재할 때만 해당 div를 렌더링하도록 수정하는 것이 좋습니다.

다음과 같이 수정할 수 있습니다:

- <div className={cx(rowStyle, 'row')}>
-   {currentPersona && (
-     <>
-       ... (content)
-     </>
-   )}
- </div>
+ {currentPersona && (
+   <div className={cx(rowStyle, 'row')}>
+     {/* ...content */}
+   </div>
+ )}
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between bde5209 and 9d2ba98.

📒 Files selected for processing (10)
  • apps/web/messages/en_US.json (1 hunks)
  • apps/web/src/app/[locale]/mypage/(github-custom)/FarmType.tsx (4 hunks)
  • apps/web/src/app/[locale]/mypage/(github-custom)/OneType.tsx (4 hunks)
  • apps/web/src/app/[locale]/mypage/(github-custom)/page.tsx (1 hunks)
  • apps/web/src/app/[locale]/mypage/PersonaList.tsx (4 hunks)
  • apps/web/src/app/[locale]/mypage/PointInfo.tsx (0 hunks)
  • apps/web/src/app/[locale]/mypage/RightSection.tsx (0 hunks)
  • apps/web/src/app/[locale]/mypage/layout.tsx (1 hunks)
  • apps/web/src/app/[locale]/mypage/my-pet/page.tsx (1 hunks)
  • apps/web/src/app/[locale]/mypage/page.tsx (0 hunks)
💤 Files with no reviewable changes (3)
  • apps/web/src/app/[locale]/mypage/PointInfo.tsx
  • apps/web/src/app/[locale]/mypage/RightSection.tsx
  • apps/web/src/app/[locale]/mypage/page.tsx
🔇 Additional comments (11)
apps/web/src/app/[locale]/mypage/(github-custom)/page.tsx (1)

11-11: TabType 정의가 명확합니다.

TabType의 정의가 간결하고 명확합니다. 컴포넌트에서 사용되는 두 가지 탭 유형을 정확하게 표현하고 있습니다.

apps/web/messages/en_US.json (2)

19-27: "Common" 섹션 추가에 대한 승인

"Common" 섹션을 추가한 것은 좋은 방법입니다. 이를 통해 자주 사용되는 용어들을 중앙 집중화하여 관리할 수 있게 되었습니다.


19-27: 공통 용어 사용 확인

새로 추가된 "Common" 섹션의 용어들이 애플리케이션 전체에서 일관되게 사용되고 있는지 확인이 필요합니다.

다음 스크립트를 실행하여 "Common" 섹션의 용어들이 어떻게 사용되고 있는지 확인해 주세요:

✅ Verification successful

공통 용어 사용 일관성 확인 완료

"Common" 섹션의 용어들이 애플리케이션 전체에서 일관되게 사용되고 있습니다.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the usage of common terms across the application

# Test: Search for the usage of common terms
for term in pet name grade level price date sell; do
  echo "Searching for usage of '$term':"
  rg --type-add 'web:*.{ts,tsx,js,jsx}' --type web -i "\b$term\b" apps/web
  echo "---"
done

Length of output: 15970

apps/web/src/app/[locale]/mypage/PersonaList.tsx (4)

3-3: 불필요한 import 제거 승인

사용하지 않는 useStateuseCallback import를 제거한 것은 좋은 변경사항입니다. 이는 코드를 더 깔끔하게 만들고 잠재적으로 성능을 향상시킬 수 있습니다.


34-38: Suspense fallback UI 개선 승인

Suspense의 fallback UI를 수정한 것은 좋은 변경사항입니다. 새로운 구조가 더 간단하고 집중되어 있으며, BannerSkeleton 컴포넌트 리스트를 직접 렌더링합니다. 이는 전체적인 컴포넌트 단순화 방향과 일치합니다.


42-49: 컴포넌트 props 업데이트 승인

컴포넌트의 매개변수에 isExtend를 추가한 것은 Props 인터페이스 업데이트와 일치하며, 적절한 변경사항입니다.


Line range hint 1-91: 전체적인 변경사항 승인 및 요약

이 PR의 변경사항들은 전반적으로 잘 이루어졌습니다. 주요 개선 사항은 다음과 같습니다:

  1. isExtend prop 추가로 컴포넌트의 유연성 향상
  2. 불필요한 레이아웃 요소 제거로 구조 단순화
  3. 컴포넌트의 재사용성 개선

이러한 변경사항들은 PR의 목적인 "마이페이지 레이아웃 분리"를 잘 달성하고 있습니다. 코드의 가독성과 유지보수성이 향상되었습니다.

제안된 작은 개선사항들(prop 문서화, 스타일 최적화)을 고려해보시면 좋겠습니다. 전반적으로 훌륭한 리팩토링입니다!

apps/web/src/app/[locale]/mypage/(github-custom)/FarmType.tsx (1)

18-18: import 문 변경이 적절해 보입니다.

SelectPersonaList 컴포넌트의 import 경로가 변경되었습니다. 이는 프로젝트 구조 개선의 일환으로 보이며, 적절한 변경으로 판단됩니다.

apps/web/src/app/[locale]/mypage/(github-custom)/OneType.tsx (3)

27-27: 새로운 상태 변수 추가가 적절합니다.

isExtend 상태 변수의 추가는 페르소나 선택 영역의 확장/축소 기능을 위한 것으로 보입니다. 이름이 명확하고 목적이 분명합니다.


Line range hint 1-150: PR 목표와 일치하는 변경 사항입니다. 전반적으로 잘 구현되었습니다.

이 PR의 주요 목표인 "My Page" 섹션의 레이아웃 분리가 잘 이루어졌습니다. 특히:

  1. 페르소나 선택 영역을 확장/축소할 수 있는 새로운 기능이 추가되었습니다.
  2. UI가 개선되어 사용자 경험이 향상되었습니다.
  3. 코드 구조가 명확하고 이해하기 쉽습니다.

이러한 변경 사항들은 PR의 목표와 잘 부합하며, "My Page" 섹션의 사용성을 크게 향상시킬 것으로 보입니다.


14-14: import 경로를 확인해주세요.

SelectPersonaList 컴포넌트를 부모 디렉토리에서 가져오고 있습니다. 이는 일반적이지 않은 구조입니다. 의도한 대로인지 확인해주시고, 가능하다면 같은 디렉토리 또는 하위 디렉토리에서 import하는 것이 좋습니다.

✅ Verification successful

Import 경로가 올바르게 설정되었습니다.

../PersonaList에서 SelectPersonaList를 성공적으로 가져올 수 있으며, 해당 파일이 프로젝트 내에서 유일함을 확인했습니다.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the existence and location of PersonaList.tsx file

# Test: Check if PersonaList.tsx exists in the parent directory
fd -p "../PersonaList.tsx" --exec echo "PersonaList.tsx found at: {}"

# Test: Check if there are any other files named PersonaList.tsx in the project
fd "PersonaList.tsx" --exec echo "Alternative PersonaList.tsx found at: {}"

Length of output: 311

Comment on lines +13 to +40
async function Mypage({
searchParams,
}: {
searchParams: {
type?: TabType;
};
}) {
const selectedType = searchParams?.type ?? '1-type';

const MYPAGE_TAB_INNER_MAP: Record<TabType, ReactNode> = {
'1-type': <OneType />,
'farm-type': <FarmType />,
};

return (
<div>
<div className={tabListStyle}>
<Link href={`/mypage?${updateUrlSearchParams(searchParams, 'type', '1-type')}`}>
<button className={cx('tab-item', selectedType === '1-type' && 'selected')}>1 Type</button>
</Link>
<Link href={`/mypage?${updateUrlSearchParams(searchParams, 'type', 'farm-type')}`}>
<button className={cx('tab-item', selectedType === 'farm-type' && 'selected')}>Farm Type</button>
</Link>
</div>
<div>{MYPAGE_TAB_INNER_MAP[selectedType]}</div>
</div>
);
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Mypage 컴포넌트 구조가 잘 구성되어 있습니다만, 몇 가지 개선 사항이 있습니다.

Mypage 컴포넌트의 전반적인 구조가 잘 구성되어 있고 React 모범 사례를 따르고 있습니다. 하지만 다음과 같은 개선 사항을 제안합니다:

  1. 컴포넌트가 비동기 작업을 수행하지 않는 것으로 보이는데 async 키워드를 사용하고 있습니다. 이는 불필요할 수 있습니다.
  2. 타입 안전성을 높이기 위해 MYPAGE_TAB_INNER_MAP의 타입을 더 구체적으로 지정할 수 있습니다.

다음과 같이 변경을 제안합니다:

  1. async 키워드 제거:
-async function Mypage({
+function Mypage({
  1. MYPAGE_TAB_INNER_MAP의 타입을 더 구체적으로 지정:
-const MYPAGE_TAB_INNER_MAP: Record<TabType, ReactNode> = {
+const MYPAGE_TAB_INNER_MAP: Record<TabType, JSX.Element> = {

이러한 변경으로 코드의 의도가 더 명확해지고 타입 안전성이 향상될 것입니다.

📝 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.

Suggested change
async function Mypage({
searchParams,
}: {
searchParams: {
type?: TabType;
};
}) {
const selectedType = searchParams?.type ?? '1-type';
const MYPAGE_TAB_INNER_MAP: Record<TabType, ReactNode> = {
'1-type': <OneType />,
'farm-type': <FarmType />,
};
return (
<div>
<div className={tabListStyle}>
<Link href={`/mypage?${updateUrlSearchParams(searchParams, 'type', '1-type')}`}>
<button className={cx('tab-item', selectedType === '1-type' && 'selected')}>1 Type</button>
</Link>
<Link href={`/mypage?${updateUrlSearchParams(searchParams, 'type', 'farm-type')}`}>
<button className={cx('tab-item', selectedType === 'farm-type' && 'selected')}>Farm Type</button>
</Link>
</div>
<div>{MYPAGE_TAB_INNER_MAP[selectedType]}</div>
</div>
);
}
function Mypage({
searchParams,
}: {
searchParams: {
type?: TabType;
};
}) {
const selectedType = searchParams?.type ?? '1-type';
const MYPAGE_TAB_INNER_MAP: Record<TabType, JSX.Element> = {
'1-type': <OneType />,
'farm-type': <FarmType />,
};
return (
<div>
<div className={tabListStyle}>
<Link href={`/mypage?${updateUrlSearchParams(searchParams, 'type', '1-type')}`}>
<button className={cx('tab-item', selectedType === '1-type' && 'selected')}>1 Type</button>
</Link>
<Link href={`/mypage?${updateUrlSearchParams(searchParams, 'type', 'farm-type')}`}>
<button className={cx('tab-item', selectedType === 'farm-type' && 'selected')}>Farm Type</button>
</Link>
</div>
<div>{MYPAGE_TAB_INNER_MAP[selectedType]}</div>
</div>
);
}

Comment on lines 19 to 27
"Common": {
"pet": "Pet",
"name": "Name",
"grade": "Grade",
"level": "Level",
"price": "Price",
"date": "Date",
"sell": "Sell"
},
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

"Shop" 섹션에서 중복 항목 제거 제안

"Common" 섹션과 "Shop" 섹션 사이에 중복되는 항목들이 있습니다. 일관성을 유지하고 유지보수를 용이하게 하기 위해 "Shop" 섹션에서 중복되는 항목들을 제거하고 "Common" 섹션의 항목들을 참조하는 것이 좋습니다.

다음과 같이 "Shop" 섹션을 수정하는 것을 제안합니다:

  "Shop": {
    "no-mobile-support": "Currently, mobile is not supported. Please connect to the desktop.",
    "buy-product-success": "Purchase complete!",
    "buy-product-fail": "Failed to purchase.",
    "buy": "buy",
-   "pet": "Pet",
-   "name": "Name",
-   "grade": "Grade",
-   "level": "Level",
-   "price": "Price",
-   "date": "Date",
-   "sell": "Sell",
    "price-you-want": "Price you want",
    "sell-product-success": "Sell complete!",
    "sell-product-fail": "Failed to sell.",
    "cancel": "Cancel",
    "delete": "Delete",
    "delete-product-success": "Cancellation complete!",
    "delete-product-fail": "Failed to cancellation.",
    "edit": "Edit"
  },

Also applies to: 39-46

Comment on lines 46 to 58
<section className={selectPetContainerStyle}>
<h2 className="heading">{t('change-pet')}</h2>
<Button className="extend-button" onClick={() => setIsExtend((prev) => !prev)}>
{isExtend ? t('shrink-button') : t('extend-button')}
</Button>

<SelectPersonaList
name={name}
selectPersona={selectPersona ? [selectPersona] : []}
onSelectPersona={(persona) => setSelectPersona(persona.id)}
isExtend={isExtend}
/>
</section>
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

페르소나 선택 섹션 추가가 잘 되었습니다. 작은 개선 사항이 있습니다.

새로운 페르소나 선택 섹션의 추가는 UI를 개선하고 사용자 경험을 향상시킵니다. 확장/축소 기능은 사용자에게 더 나은 제어 기능을 제공합니다.

다만, 접근성 향상을 위해 다음과 같은 작은 개선을 제안합니다:

버튼에 aria-expanded 속성을 추가하여 스크린 리더 사용자에게 현재 상태를 알려주는 것이 좋습니다. 다음과 같이 수정해 보세요:

-<Button className="extend-button" onClick={() => setIsExtend((prev) => !prev)}>
+<Button className="extend-button" onClick={() => setIsExtend((prev) => !prev)} aria-expanded={isExtend}>

이렇게 하면 스크린 리더 사용자들이 버튼의 현재 상태를 더 쉽게 이해할 수 있습니다.

📝 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.

Suggested change
<section className={selectPetContainerStyle}>
<h2 className="heading">{t('change-pet')}</h2>
<Button className="extend-button" onClick={() => setIsExtend((prev) => !prev)}>
{isExtend ? t('shrink-button') : t('extend-button')}
</Button>
<SelectPersonaList
name={name}
selectPersona={selectPersona ? [selectPersona] : []}
onSelectPersona={(persona) => setSelectPersona(persona.id)}
isExtend={isExtend}
/>
</section>
<section className={selectPetContainerStyle}>
<h2 className="heading">{t('change-pet')}</h2>
<Button className="extend-button" onClick={() => setIsExtend((prev) => !prev)} aria-expanded={isExtend}>
{isExtend ? t('shrink-button') : t('extend-button')}
</Button>
<SelectPersonaList
name={name}
selectPersona={selectPersona ? [selectPersona] : []}
onSelectPersona={(persona) => setSelectPersona(persona.id)}
isExtend={isExtend}
/>
</section>

Comment on lines +74 to +86
const selectPetContainerStyle = css({
position: 'relative',
'& .heading': {
textStyle: 'glyph18.bold',
color: 'white',
marginBottom: '16px',
},
'& .extend-button': {
position: 'absolute',
top: '-16px',
right: 0,
},
});
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

선택 영역 스타일 추가가 적절합니다. 유지보수성 개선을 위한 제안이 있습니다.

새로운 스타일 추가로 페르소나 선택 영역의 레이아웃과 외관이 개선되었습니다. 헤딩과 확장 버튼의 위치 지정이 잘 되어 있습니다.

유지보수성을 더욱 향상시키기 위해 다음과 같은 개선을 제안합니다:

매직 넘버 대신 변수를 사용하여 스타일을 정의하면 향후 변경이 필요할 때 더 쉽게 수정할 수 있습니다. 예를 들어:

+const SPACING = {
+  small: '16px',
+  medium: '24px',
+};

const selectPetContainerStyle = css({
  position: 'relative',
  '& .heading': {
    textStyle: 'glyph18.bold',
    color: 'white',
-   marginBottom: '16px',
+   marginBottom: SPACING.small,
  },
  '& .extend-button': {
    position: 'absolute',
    top: '-16px',
    right: 0,
  },
});

이렇게 하면 스타일 값을 한 곳에서 관리할 수 있어 일관성 유지와 변경이 더 쉬워집니다.

Committable suggestion was skipped due to low confidence.

Comment on lines 10 to 26
async function MypageLayout({ children }: { children: React.ReactNode }) {
const t = await getTranslations('Mypage');

return (
<>
<div className={cx(containerStyle, subStyle)}>
<GNB />
<Image src="/mypage/bg-cloud.webp" alt="bg" width={2400} height={1367} className={bgStyle} draggable={false} />
<main className={mainStyle}>
<ProfileSection />
<section className={rightSectionStyle}>{children}</section>
</main>
</div>
<div className={noticeStyle}>{t('no-mobile-support')}</div>
</>
);
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

컴포넌트의 props 타입을 별도의 인터페이스로 분리하세요.

현재 'MypageLayout' 컴포넌트의 props 타입이 인라인으로 정의되어 있습니다. 가독성과 유지 보수성을 향상시키기 위해 props 타입을 별도의 인터페이스로 정의하는 것을 권장합니다.

다음과 같이 수정할 수 있습니다:

interface MypageLayoutProps {
  children: React.ReactNode;
}

async function MypageLayout({ children }: MypageLayoutProps) {
  // ...
}

<>
<div className={cx(containerStyle, subStyle)}>
<GNB />
<Image src="/mypage/bg-cloud.webp" alt="bg" width={2400} height={1367} className={bgStyle} draggable={false} />
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

'next/image' 컴포넌트에서는 'draggable' 속성을 지원하지 않습니다.

'next/image' 컴포넌트는 'draggable' 속성을 직접 전달할 수 없습니다. 이미지를 드래그하지 못하도록 하려면 'onDragStart' 이벤트 핸들러를 사용하여 드래그 동작을 막을 수 있습니다.

해결 방법으로, 'onDragStart' 핸들러를 추가하세요:

 <Image
   src="/mypage/bg-cloud.webp"
   alt="bg"
   width={2400}
   height={1367}
   className={bgStyle}
-  draggable={false}
+  onDragStart={(e) => e.preventDefault()}
   />
📝 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.

Suggested change
<Image src="/mypage/bg-cloud.webp" alt="bg" width={2400} height={1367} className={bgStyle} draggable={false} />
<Image
src="/mypage/bg-cloud.webp"
alt="bg"
width={2400}
height={1367}
className={bgStyle}
onDragStart={(e) => e.preventDefault()}
/>

Comment on lines 54 to 56
const onSellClick = () => {
console.log('sell');
};
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

onSellClick 함수 구현 필요

현재 onSellClick 함수는 'sell'을 콘솔에 출력하고 있습니다. 실제 판매 기능을 구현해야 합니다.

판매 기능 구현에 도움이 필요하시면 말씀해주세요. 제가 해결책을 제안하거나 GitHub 이슈를 생성해드릴 수 있습니다.

Comment on lines +58 to +60
const onMergeClick = () => {
console.log('merge');
};
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

onMergeClick 함수 구현 필요

현재 onMergeClick 함수는 'merge'를 콘솔에 출력하고 있습니다. 실제 합성 기능을 구현해야 합니다.

합성 기능 구현에 도움이 필요하시면 말씀해주세요. 제가 해결책을 제안하거나 GitHub 이슈를 생성해드릴 수 있습니다.

@sumi-0011
Copy link
Member Author

@hyesungoh 이제 봤는데 저 코드래빗한데 엄청 까였네용.. 보고 수정할게요..,

@sumi-0011
Copy link
Member Author

Draft로 바꾸고 싶은데 어떻게 하는지 모르겠네욤..

Base automatically changed from refactor/persona-render to main October 21, 2024 12:27
# Conflicts:
#	apps/web/src/app/[locale]/mypage/PersonaList.tsx
Copy link

@coderabbitai coderabbitai bot left a 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 and nitpick comments (1)
apps/web/src/app/[locale]/mypage/my-pet/page.tsx (1)

23-38: 렌더링 로직이 잘 구현되어 있습니다. 가독성 개선을 위한 제안이 있습니다.

MypageMyPets 컴포넌트의 렌더링 로직이 잘 구현되어 있습니다. SelectedPetTable과 SelectPersonaList 컴포넌트를 적절히 사용하고 있습니다.

가독성 개선을 위해 다음과 같은 작은 변경을 제안합니다:

- selectPersona={selectPersona ? [selectPersona.id] : []}
+ selectPersona={selectPersona ? [selectPersona.id] : undefined}

빈 배열 대신 undefined를 사용하면 의도가 더 명확해질 수 있습니다.

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 9d2ba98 and 16b0bb5.

📒 Files selected for processing (3)
  • apps/web/messages/en_US.json (1 hunks)
  • apps/web/src/app/[locale]/mypage/PersonaList.tsx (4 hunks)
  • apps/web/src/app/[locale]/mypage/my-pet/page.tsx (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • apps/web/messages/en_US.json
  • apps/web/src/app/[locale]/mypage/PersonaList.tsx
🧰 Additional context used
🔇 Additional comments (4)
apps/web/src/app/[locale]/mypage/my-pet/page.tsx (4)

1-21: LGTM: 컴포넌트 선언과 임포트가 적절합니다.

컴포넌트 선언과 필요한 라이브러리 및 유틸리티 함수들의 임포트가 잘 되어 있습니다. useState를 사용한 상태 관리와 useTranslations를 통한 국제화 처리가 적절히 구현되어 있습니다.


54-60: onSellClick 및 onMergeClick 함수 구현 필요

onSellClick 및 onMergeClick 함수가 아직 구현되지 않았습니다. 이전 리뷰 코멘트에서 이미 지적된 사항이지만, 여전히 해결되지 않았습니다.

실제 기능을 구현하거나, 최소한 TODO 주석을 추가하여 향후 구현 계획을 명시하는 것이 좋겠습니다.

예시:

const onSellClick = () => {
  // TODO: Implement sell functionality
  console.log('sell');
};

const onMergeClick = () => {
  // TODO: Implement merge functionality
  console.log('merge');
};

42-49: CSS 스타일이 잘 정의되어 있습니다.

컴포넌트의 스타일링이 _panda/css의 css 함수를 사용하여 일관성 있게 잘 정의되어 있습니다. 테이블, 헤더, 행 등 각 요소에 대한 스타일이 명확하게 구분되어 있어 유지보수가 용이해 보입니다.

특히 다음과 같은 점이 좋습니다:

  • 반응형 디자인을 위한 그리드 레이아웃 사용
  • 색상 및 타이포그래피에 대한 일관된 스타일 적용
  • 오버플로우 처리를 통한 UI 안정성 확보

전반적으로 스타일 정의가 깔끔하고 효율적으로 되어 있습니다.

Also applies to: 98-154


1-154: 전반적으로 잘 구현되었습니다. 몇 가지 개선 사항이 있습니다.

MypageMyPets 컴포넌트와 관련 하위 컴포넌트들이 전체적으로 잘 구현되어 있습니다. 컴포넌트 구조, 상태 관리, 스타일링 등이 적절히 처리되어 있습니다.

주요 개선 사항:

  1. onSellClick 및 onMergeClick 함수의 실제 구현 또는 TODO 주석 추가
  2. dropRate 처리 로직의 안전성 개선
  3. SelectPersonaList에 전달되는 selectPersona prop의 가독성 개선

이러한 부분들을 개선하면 코드의 안정성과 유지보수성이 더욱 향상될 것입니다.

<Image src={getPersonaImage(currentPersona.type)} alt={currentPersona.type} width={60} height={67} />
</div>
<div>{snakeToTitleCase(currentPersona.type)}</div>
<div>{ANIMAL_TIER_TEXT_MAP[getAnimalTierInfo(Number(currentPersona.dropRate.replace('%', '')))]}</div>
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

dropRate 처리 로직 개선 필요

현재 dropRate 처리 로직에 잠재적인 문제가 있습니다. 이전 리뷰에서 지적된 대로, 예상치 못한 입력 형식에 대해 NaN이 발생할 수 있습니다.

다음과 같이 개선할 것을 제안합니다:

const dropRateValue = parseFloat(currentPersona.dropRate);
const animalTierInfo = isNaN(dropRateValue) ? 0 : getAnimalTierInfo(dropRateValue);
<div>{ANIMAL_TIER_TEXT_MAP[animalTierInfo]}</div>

이렇게 하면 잘못된 입력에 대해 더 안전하게 처리할 수 있습니다.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant