-
Notifications
You must be signed in to change notification settings - Fork 2
[#101] ✨ shared 컴포넌트 Card 개발 #165
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
|
Warning Rate limit exceeded@KingNono1030 has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 18 minutes and 38 seconds before requesting another review. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. 📒 Files selected for processing (5)
Walkthrough이번 변경 사항은 여러 컴포넌트와 유틸리티 함수의 추가 및 수정으로 구성되어 있습니다. 새로운 Changes
Assessment against linked issues
Poem
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? 🪧 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: 6
🧹 Outside diff range and nitpick comments (14)
src/utils/convertArrayToHashString.ts (1)
1-3: 함수 구현이 깔끔하네요! 몇 가지 개선 사항을 제안드립니다.함수를 간결하게 작성하신 점이 인상적입니다. 다만 태그 간 구분자가 없어 가독성이 떨어질 수 있어요.
다음과 같이 개선해보는 건 어떨까요?
export const joinWithHash = (items: string[]): string => { - return items.map(item => `#${item}`).join('') + return items.map(item => `#${item}`).join(' ') }추가로 빈 배열이나 빈 문자열에 대한 처리도 고려해보시면 좋을 것 같아요:
export const joinWithHash = (items: string[]): string => { if (!items?.length) return '' return items .filter(item => item.trim()) .map(item => `#${item}`) .join(' ') }src/contants/stateToLabelMaps.ts (1)
1-24: 타입 안전성이 잘 확보되어 있네요! 🎉
Record타입을 활용해 타입 안전성을 확보하신 점이 훌륭합니다. 레이블 맵핑도 깔끔하게 정리되어 있어요.한 가지 작은 제안을 드리자면, 디렉토리 이름에 오타가 있네요:
src/contants->src/constants수정이 필요할 것 같습니다:
#!/bin/bash # 디렉토리 이름 변경 필요성 확인 find src -type d -name "contants"src/components/common/chip/Chip.tsx (1)
12-19: 색상 체계가 잘 정리되었네요. 몇 가지 제안을 드릴게요! 💡각 도메인별로 색상을 구분한 것이 인상적이에요. 다만, 더 나은 유지보수를 위해 몇 가지 개선사항을 제안드립니다:
- 상수로 분리하여 관리
- 시각적 계층 구조 문서화
다음과 같이 분리하는 것은 어떨까요?
+// src/constants/chipStyles.ts +export const CHIP_STYLES = { + RECRUITMENT: { + ACTIVE: 'bg-green-100 text-green-500', + COMPLETED: 'bg-gray-200 text-gray-600', + }, + CATEGORY: { + STUDY: 'bg-purple-100 text-purple-500', + PROJECT: 'bg-purple-100 text-purple-500', + MENTORING: 'bg-pink-100 text-pink-500', + TECH: 'bg-red-100 text-red-500', + CAREER: 'bg-yellow-100 text-yellow-500', + OTHER: 'bg-cyan-100 text-cyan-500', + }, +} as constsrc/stories/shared/card/PortfolioCard.stories.ts (2)
16-37: 태그 데이터를 더 의미있게 구성해보면 어떨까요? 📝현재 태그들이 단순 반복되어 있네요. 실제 포트폴리오에서 사용될 수 있는 의미있는 태그들로 구성하면 스토리북의 가치가 더욱 높아질 것 같아요.
예시를 제안드립니다:
- tags: [ - 'tag', - 'tag', - // ... repeated tags - ], + tags: [ + 'React', + 'TypeScript', + 'Next.js', + 'TailwindCSS', + 'Jest', + 'GitHub Actions', + ],
49-62: 스토리 구성이 깔끔하네요! 💫Default와 CareerCategory 두 가지 케이스를 통해 컴포넌트의 유연성을 잘 보여주고 있어요. 다만, 더 다양한 시나리오를 고려해보면 좋을 것 같아요:
- 긴 제목 케이스
- 이미지가 없는 케이스
- 태그가 없는 케이스
src/stories/shared/card/CommunityCard.stories.ts (1)
28-51: 스토리 구성이 체계적이에요! 더 풍성한 시나리오를 추가해보면 어떨까요? 🎨각 카테고리별 스토리가 잘 구성되어 있어요. 컴포넌트의 다양한 상태를 테스트하기 위해 추가 시나리오를 제안드립니다:
- 매우 긴 제목과 내용
- 답변/좋아요/조회수가 많은 케이스
- 작성자 정보가 없는 케이스
src/stories/shared/card/TeamRecruitmentCard.stories.ts (1)
61-72: 기술 스택 중복 항목을 제거하면 좋을 것 같아요.TooManyStack 스토리에서 'React', 'TypeScript', 'Tailwind'가 중복되어 있습니다. 실제 사용 사례를 더 잘 반영하기 위해 다른 기술 스택으로 대체하는 것이 좋겠습니다.
teamTechStack: [ 'React', 'TypeScript', 'Tailwind', 'Node.js', 'GraphQL', - 'React', - 'TypeScript', - 'Tailwind', + 'Next.js', + 'Jest', + 'Storybook', 'Node.js', 'GraphQL', ],src/components/portfolio/PortfolioCard.tsx (1)
35-35: 이미지 접근성을 개선하면 좋겠어요.현재 alt 텍스트가 일반적인 설명으로 되어있네요. 각 포트폴리오의 특성을 반영한 더 구체적인 설명으로 변경하면 좋겠습니다.
- <Image fill src={portImageUrl} alt='포트폴리오 썸네일' /> + <Image fill src={portImageUrl} alt={`${portTitle} 포트폴리오 이미지`} />src/components/community/CommunityCard.tsx (1)
12-12: 상수 값의 의미를 명확히 해주세요.
RESPONSE_NUM이 0으로 하드코딩되어 있네요. 이 값의 용도와 의미를 주석으로 설명하거나, 더 명확한 이름을 사용하면 좋겠습니다.-const RESPONSE_NUM = 0 +const INITIAL_RESPONSE_COUNT = 0 // 초기 답변자 수src/components/team/TeamRecruitmentCard.tsx (1)
33-33: 타입 안전성 향상을 위한 제안 💡
teamTechStack이 undefined일 수 있는 상황에 대해 잘 처리해주셨네요! 더 나아가 빈 배열을 기본값으로 제공하면 코드가 더 간결해질 것 같아요.- const teckStackLabel = joinWithHash(teamTechStack ?? []) + const teckStackLabel = joinWithHash(teamTechStack || [])src/components/shared/card/Card.tsx (2)
12-13: 상수 네이밍 컨벤션 개선 제안 ✨
baseCardContainerStyle은 상수이므로 대문자로 네이밍하면 좋겠습니다. 또한 매직 넘버인h-134는 의미있는 변수로 추출하면 좋겠어요.+ const CARD_HEIGHT = 'h-134' - const baseCardContainerStyle = - 'h-134 w-full border-b-1 border-solid border-gray-200' + const BASE_CARD_CONTAINER_STYLE = + `${CARD_HEIGHT} w-full border-b-1 border-solid border-gray-200`
77-90: 접근성 개선을 위한 제안 ♿️
CardCount컴포넌트에 aria-label을 추가하면 스크린 리더 사용자들의 경험이 개선될 것 같아요.<Text.Caption variant='caption1' color='gray400' + aria-label={`${type} 수: ${counts}`} className={twMergeEx('flex items-center gap-4', className)} >src/assets/IconList.ts (1)
1-1: 아이콘 관리 구조화 제안 🎨새로운 아이콘이 잘 추가되었네요! 추후 관리를 위해 아이콘들을 카테고리별로 그룹화하는 것은 어떨까요?
// 예시 구조 const INTERACTION_ICONS = { answer: IcAnswerBlue, comment: IcComment, heart: IcHeart, // ... } as const; const NAVIGATION_ICONS = { arrowRight: IcArrowRight, chevronLeft: IcChevronLeft, // ... } as const; export { INTERACTION_ICONS, NAVIGATION_ICONS };Also applies to: 84-84
src/components/common/text/Text.tsx (1)
109-109: TitleProps 인터페이스 유연성 개선에 대한 제안
as프로퍼티를 선택적으로 만든 것은 컴포넌트의 유연성을 높이는 좋은 시도입니다. 다만, 타입 안정성을 위해 다음과 같은 개선을 제안드립니다.- as?: 'h4' | 'h5' | 'div' | 'p' + as?: Extract<As, 'h4' | 'h5' | 'div' | 'p'>이렇게 하면
As타입과의 일관성을 유지하면서도 타입 안정성을 확보할 수 있습니다.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
⛔ Files ignored due to path filters (1)
src/assets/icons/ic-answer-blue.svgis excluded by!**/*.svg
📒 Files selected for processing (18)
src/assets/IconList.ts(2 hunks)src/components/common/chip/Chip.tsx(1 hunks)src/components/common/divider/Divider.tsx(1 hunks)src/components/common/divider/index.ts(1 hunks)src/components/common/text/Text.tsx(4 hunks)src/components/community/CommunityCard.tsx(1 hunks)src/components/portfolio/PortfolioCard.tsx(1 hunks)src/components/shared/card/Card.tsx(1 hunks)src/components/shared/card/index.ts(1 hunks)src/components/team/TeamRecruitmentCard.tsx(1 hunks)src/contants/stateToLabelMaps.ts(1 hunks)src/stories/shared/card/CommunityCard.stories.ts(1 hunks)src/stories/shared/card/PortfolioCard.stories.ts(1 hunks)src/stories/shared/card/TeamRecruitmentCard.stories.ts(1 hunks)src/types/api/Post.types.d.ts(1 hunks)src/utils/convertArrayToHashString.ts(1 hunks)src/utils/formatData.ts(1 hunks)tailwind.config.ts(1 hunks)
✅ Files skipped from review due to trivial changes (3)
- src/components/common/divider/index.ts
- src/components/common/divider/Divider.tsx
- src/components/shared/card/index.ts
🔇 Additional comments (10)
src/utils/formatData.ts (1)
1-9: 🛠️ Refactor suggestion
잘 작성된 날짜 포맷팅 함수네요! 몇 가지 개선사항을 제안드립니다.
날짜 형식을 일관성있게 유지하기 위해 padStart를 사용하신 점이 인상적입니다. 하지만 더 견고한 구현을 위해 다음 사항들을 고려해보시면 좋을 것 같아요:
입력값 검증과 에러 처리를 추가해보세요:
export const formatDate = (isoDate: string): string => {
+ if (!isoDate) {
+ throw new Error('날짜는 필수값입니다');
+ }
+
const date = new Date(isoDate);
+
+ if (isNaN(date.getTime())) {
+ throw new Error('유효하지 않은 날짜 형식입니다');
+ }
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, '0');
const day = String(date.getDate()).padStart(2, '0');
return `${year}.${month}.${day}`;
}타임존 관련 이슈가 있을 수 있는지 확인해보겠습니다:
타임존 처리가 필요하시다면 date-fns 라이브러리를 활용한 구현 예시를 제공해드릴 수 있습니다. 필요하신가요?
src/types/api/Post.types.d.ts (1)
9-9: 문서화가 잘 되어있고, 네이밍 변경이 적절해 보입니다! 👏
member에서 writer로의 변경은 의미상 더 명확해졌네요. 문서화도 매우 상세하게 잘 작성해주셨습니다.
다만, 이름 변경으로 인한 영향을 확인해보면 좋을 것 같습니다:
Also applies to: 14-18
✅ Verification successful
member에서 writer로의 변경이 안전하게 이루어졌네요! 👍
코드베이스를 검토해본 결과, Post 타입에서 member를 writer로 변경한 것이 다른 코드에 영향을 주지 않는 것으로 확인됩니다. 기존의 member 관련 코드들은 대부분 팀 멤버와 관련된 별도의 기능들이었고, Post 타입의 속성 변경은 독립적으로 잘 이루어졌습니다.
의미를 더 명확하게 만드는 이런 리팩토링 작업, 앞으로도 계속 해주시면 좋겠습니다! 😊
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# member -> writer 변경의 영향을 받을 수 있는 파일들 확인
rg -l "member\." src/
Length of output: 23
Script:
#!/bin/bash
# 더 넓은 범위로 검색하여 'member' 관련 코드 확인
rg "member" src/ -A 2
# Post 타입이 사용되는 곳 확인
rg "Post\." src/ -A 2
# writer 속성이 사용되는 곳 확인
rg "writer\." src/ -A 2
# .ts, .tsx 파일에서 Post 타입 import 확인
rg "import.*Post" src/ --type ts
Length of output: 3121
src/components/common/chip/Chip.tsx (2)
1-1: twMergeEx 도입으로 스타일 관리가 개선되었네요! 👏
clsx에서 twMergeEx로의 전환은 매우 좋은 판단이에요. Tailwind CSS의 클래스 충돌을 더 효과적으로 관리할 수 있게 되었습니다.
Also applies to: 24-24
9-9: w-max 추가로 레이아웃 안정성이 향상되었어요! ✨
w-max 클래스 추가는 칩 컴포넌트의 너비를 콘텐츠에 맞게 자동으로 조절하도록 해주는 훌륭한 개선이에요.
src/stories/shared/card/TeamRecruitmentCard.stories.ts (1)
11-29: 목 데이터의 구조가 잘 설계되어 있네요! 👏
실제 사용 사례를 잘 반영한 목 데이터를 만드셨습니다. 특히 필수 필드들을 모두 포함하고 있어 좋습니다.
src/components/community/CommunityCard.tsx (1)
38-40: 긴 콘텐츠에 대한 처리가 잘 되어있네요! 👏
overflow 처리와 ellipsis 적용이 잘 되어있습니다. 사용자 경험을 고려한 좋은 구현이에요.
src/components/common/text/Text.tsx (3)
17-17: Color 타입에 gray400 추가에 대한 긍정적인 평가
디자인 시스템의 일관성을 높이기 위해 gray400을 추가한 점이 인상적입니다. 색상 스펙트럼을 더욱 섬세하게 제어할 수 있게 되었네요! 👏
86-87: textStyle 로직 개선에 대한 칭찬
clsx 사용을 간소화하여 코드의 가독성을 높이신 점이 훌륭합니다. 불필요한 복잡성을 제거하고 핵심적인 스타일 결합에 집중하신 점이 돋보입니다. 👍
78-78: 기본 폰트 가중치 변경에 대한 검토 필요
기본 weight를 700에서 500으로 변경하신 것이 눈에 띄네요. 디자인 시스템의 일관성 측면에서 좋은 변화입니다만, 기존 사용 중인 컴포넌트들에 영향이 있을 수 있습니다.
기본값 변경이 미치는 영향을 최소화하기 위해, 다음과 같은 전략을 고려해보시는 건 어떨까요?
- 변경사항을 팀에 명확히 커뮤니케이션
- 점진적인 마이그레이션 계획 수립
✅ Verification successful
Let's analyze the actual weight usage patterns in the codebase to better understand the impact of this change.
기본 폰트 가중치 변경은 안전해 보입니다!
코드베이스를 분석해본 결과, Text 컴포넌트를 사용하는 대부분의 경우에서 weight 속성을 명시적으로 지정하고 있어서 기본값 변경이 미치는 영향이 제한적일 것으로 보입니다. 실제 사용 패턴을 보면:
- Card 컴포넌트에서는 이미 weight='500'과 weight='600'을 명시적으로 사용
- Footer에서도 weight='500'을 명시적으로 지정
- 테스트 코드에서도 weight 속성을 명시적으로 테스트
이런 패턴은 디자인 시스템의 일관성을 높이려는 좋은 시도였다고 생각합니다. 기본값을 500으로 변경하는 것이 현재 사용 패턴과도 잘 맞네요! 👍
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Text 컴포넌트의 기존 사용 패턴을 확인
rg "Text\." -A 2 "src/"
Length of output: 11320
Script:
#!/bin/bash
# Text 컴포넌트에서 weight prop이 명시적으로 설정된 사용 패턴을 확인
rg "weight=['\"]" -A 1 "src/components/"
# Text 컴포넌트의 실제 구현에서 weight 관련 코드를 확인
ast-grep --pattern 'weight = $_'
Length of output: 1262
tailwind.config.ts (1)
61-67: 새로운 cyan 컬러 팔레트 추가에 대한 평가
디자인 시스템에 cyan 컬러 팔레트를 추가하신 것이 인상적입니다. 특히 다음과 같은 점들이 돋보입니다:
- 기존 컬러 팔레트의 구조를 일관성 있게 따르고 있습니다.
- 색상 값들이 논리적인 단계로 잘 구성되어 있습니다.
혹시 이 새로운 컬러 팔레트에 대한 디자인 가이드라인 문서도 함께 업데이트하실 계획이 있으신가요? 팀원들의 원활한 사용을 위해 도움이 될 것 같습니다.
| communityCategory: 'SKILL', | ||
| communityTitle: '백엔드 5년차 이직 고민', |
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
카테고리 타입 안전성을 높여보면 어떨까요? 🛡️
communityCategory가 문자열로 정의되어 있네요. 타입 안전성을 높이기 위해 상수나 enum으로 관리하면 좋을 것 같아요.
+export const COMMUNITY_CATEGORIES = {
+ SKILL: 'SKILL',
+ CAREER: 'CAREER',
+ OTHER: 'OTHER',
+} as const;
+
+type CommunityCategory = typeof COMMUNITY_CATEGORIES[keyof typeof COMMUNITY_CATEGORIES];
- communityCategory: 'SKILL',
+ communityCategory: COMMUNITY_CATEGORIES.SKILL,Committable suggestion skipped: line range outside the PR's diff.
| </Card.Content> | ||
| </div> | ||
| <div className='flex items-center gap-8'> | ||
| <Card.Wrtier nickname={nickname} imageUrl={imageUrl} /> |
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.
오타를 수정해주세요.
'Wrtier'에 오타가 있네요. 'Writer'로 수정해주세요.
- <Card.Wrtier nickname={nickname} imageUrl={imageUrl} />
+ <Card.Writer nickname={nickname} imageUrl={imageUrl} />📝 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.
| <Card.Wrtier nickname={nickname} imageUrl={imageUrl} /> | |
| <Card.Writer nickname={nickname} imageUrl={imageUrl} /> |
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.
@yellowjang, 세심하게 코드를 확인하시는 모습이 정말 인상적입니다! 앞으로도 함께 좋은 코드 만들어 나가요.
| </Card.Content> | ||
| </div> | ||
| <div className='my-12 flex items-center gap-8'> | ||
| <Card.Wrtier nickname={nickname} imageUrl={imageUrl} /> |
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.
PortfolioCard와 동일한 오타가 있네요.
'Wrtier' 오타를 'Writer'로 수정해주세요.
- <Card.Wrtier nickname={nickname} imageUrl={imageUrl} />
+ <Card.Writer nickname={nickname} imageUrl={imageUrl} />📝 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.
| <Card.Wrtier nickname={nickname} imageUrl={imageUrl} /> | |
| <Card.Writer nickname={nickname} imageUrl={imageUrl} /> |
| <ItemWithDivider label={teckStackLabel} isLast /> | ||
| </div> | ||
| <div className='my-12 flex items-center gap-8'> | ||
| <Card.Wrtier nickname={nickname} imageUrl={imageUrl} /> |
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.
오타를 발견했어요! 🔍
Card.Wrtier에 오타가 있네요. Writer로 수정해주세요.
- <Card.Wrtier nickname={nickname} imageUrl={imageUrl} />
+ <Card.Writer nickname={nickname} imageUrl={imageUrl} />📝 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.
| <Card.Wrtier nickname={nickname} imageUrl={imageUrl} /> | |
| <Card.Writer nickname={nickname} imageUrl={imageUrl} /> |
| } = teamRecruitmentItem | ||
| const { nickname, imageUrl } = writer | ||
| const activeRecruitmentLabel = recruitmentStatusMap[`${teamIsActive}`] | ||
| const recruitmentNumLabel = `모집인원 : ${1}/${teamRecruitmentNum}` |
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.
모집 인원 표시 로직 개선이 필요합니다! 🎯
현재 모집인원이 하드코딩된 1값을 사용하고 있네요. 실제 현재 모집된 인원을 반영하도록 수정하면 좋겠습니다.
- const recruitmentNumLabel = `모집인원 : ${1}/${teamRecruitmentNum}`
+ const recruitmentNumLabel = `모집인원 : ${teamRecruitmentItem.currentRecruitmentNum}/${teamRecruitmentNum}`Committable suggestion skipped: line range outside the PR's diff.
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.
@yellowjang, 알겠습니다! 나중에 반영하실 예정이시군요. 전체적으로 훌륭한 코드 작성하셨습니다. 앞으로도 좋은 작업 기대하겠습니다!
| interface CardWriterProps extends BaseProps { | ||
| nickname: Nickname | ||
| imageUrl: ImageURL | ||
| } |
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.
타입 정의가 필요해 보입니다! 📝
Nickname과 ImageURL 타입이 정의되어 있지 않네요. 타입 안전성을 위해 명시적으로 정의해주시면 좋겠습니다.
type Nickname = string;
type ImageURL = string;
interface CardWriterProps extends BaseProps {
nickname: Nickname;
imageUrl: ImageURL;
}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 and nitpick comments (6)
src/components/team/TeamRecruitmentCard.tsx (2)
16-58: 컴포넌트 구조가 잘 설계되었어요! 👏컴포넌트의 책임 분리와 구조화가 잘 되어있습니다. 특히 다음 부분들이 인상적이에요:
- Props 타입 정의가 명확합니다
- 데이터 구조 분해가 깔끔합니다
- UI 레이아웃이 직관적으로 구성되어 있어요
한 가지 제안드리고 싶은 점은, 재사용성을 높이기 위해
activeRecruitmentLabel과 같은 레이블 생성 로직을 별도의 유틸리티 함수로 분리하는 것을 고려해보시면 어떨까요?
65-84: 접근성 개선을 위한 제안이 있어요! ♿
ItemWithDivider컴포넌트가 잘 구현되어 있습니다! 특히 overflow 처리가 깔끔해요.
접근성 향상을 위해 다음과 같은 개선을 제안드립니다:const ItemWithDivider = ({ label, isLast, -}: ItemWithDividerProps): JSX.Element => ( +}: ItemWithDividerProps): JSX.Element => { + const ariaLabel = `${label}${!isLast ? ', 구분선 있음' : ''}` + return ( <> <Text.Body variant='body1' color='gray700' + aria-label={ariaLabel} className={clsx( { 'shrink-0': !isLast }, { 'shrink overflow-x-hidden overflow-ellipsis': isLast, } )} > {label} </Text.Body> {!isLast && <Divider length='14' />} </> + ) }이렇게 하면 스크린 리더 사용자들에게도 더 나은 경험을 제공할 수 있어요! 👍
src/components/common/divider/Divider.tsx (2)
3-11: 잘 설계된 타입 정의입니다! 📝인터페이스와 타입 정의가 명확하고 타입 안전성이 잘 보장되어 있습니다. 특히 Length 타입을 문자열 리터럴로 제한한 것이 인상적이네요.
JSDoc 문서를 추가하면 더욱 좋을 것 같습니다:
+/** + * Divider 컴포넌트의 속성을 정의합니다. + * @property {boolean} [isVertical] - 구분선의 방향 (기본값: true) + * @property {Length} [thickness] - 구분선의 두께 + * @property {Length} [length] - 구분선의 길이 + * @property {string} [color] - 구분선의 색상 + * @property {string} [className] - 추가 스타일 클래스 + */ interface DividerProps {
24-40: 컴포넌트 구현이 깔끔합니다! ⭐기본값 설정과 클래스 조합 로직이 매우 명확하네요. twMerge를 활용한 클래스 병합도 훌륭합니다.
성능 최적화를 위해 dividerClass 계산을 메모이제이션하는 것을 고려해보세요:
export const Divider = ({ isVertical = true, thickness = '1', length = 'full', color = 'bg-gray-200', className = '', }: DividerProps): JSX.Element => { - const dividerClass = twMerge( + const dividerClass = useMemo(() => twMerge( 'min-h-0 min-w-0', color, isVertical ? heightMap[length] : heightMap[thickness], isVertical ? weightMap[thickness] : weightMap[length], className - ) + ), [isVertical, thickness, length, color, className]) return <div className={dividerClass} /> }src/components/shared/footer/Footer.tsx (2)
54-54: 반복되는 Divider 패턴을 최적화할 수 있습니다! 🔄여러 Text.Body 컴포넌트에서 동일한 Divider 설정이 반복되고 있네요.
컴포넌트를 만들어 재사용성을 높이는 것은 어떨까요?
const TextWithDivider = ({ children }: { children: React.ReactNode[] }) => ( <Text.Body variant='body3' color='gray600' weight='500' className='flex items-center gap-10' > {children.map((child, index) => ( <> {child} {index < children.length - 1 && <Divider length='14' />} </> ))} </Text.Body> );Also applies to: 66-66
71-72: 스타일 최적화가 가능해 보입니다! 🎨Divider 컴포넌트 다음의 추가 spacing div를 제거하고, margin을 Divider 컴포넌트에서 처리하는 것이 더 깔끔할 것 같습니다.
다음과 같이 변경해보세요:
- <Divider isVertical={false} /> - <div className='mb-30' /> + <Divider isVertical={false} className='mb-30' />
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
📒 Files selected for processing (3)
src/components/common/divider/Divider.tsx(1 hunks)src/components/shared/footer/Footer.tsx(4 hunks)src/components/team/TeamRecruitmentCard.tsx(1 hunks)
🔇 Additional comments (4)
src/components/team/TeamRecruitmentCard.tsx (2)
32-32: 모집 인원 하드코딩 이슈가 아직 해결되지 않았네요! 🎯
현재 모집 인원을 1로 하드코딩하신 부분이 있어요. 실제 데이터를 반영하도록 수정하면 좋겠습니다.
49-49: Writer 컴포넌트 이름에 오타가 있어요! ✍️
Card.Wrtier를 Card.Writer로 수정해주세요.
src/components/common/divider/Divider.tsx (1)
13-22: 매핑 객체 활용이 훌륭합니다! 💡
Record 타입과 매핑 객체를 활용하여 타입 안전성과 유지보수성을 모두 확보하셨네요. 특히 heightMap과 weightMap의 일관된 구조가 인상적입니다.
src/components/shared/footer/Footer.tsx (1)
3-3: Divider 컴포넌트 적용이 자연스럽습니다! 👍
기존 div 엘리먼트를 Divider 컴포넌트로 교체한 것이 코드의 가독성과 일관성을 높여주었습니다.
Also applies to: 42-42
| @@ -0,0 +1,84 @@ | |||
| import { recruitmentStatusMap } from '@/contants/stateToLabelMaps' | |||
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.
import 경로에 오타가 있어요! 🔍
@/contants/stateToLabelMaps에서 constants의 철자가 잘못되었네요. 이런 작은 실수가 런타임 에러를 일으킬 수 있어요.
-import { recruitmentStatusMap } from '@/contants/stateToLabelMaps'
+import { recruitmentStatusMap } from '@/constants/stateToLabelMaps'📝 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.
| import { recruitmentStatusMap } from '@/contants/stateToLabelMaps' | |
| import { recruitmentStatusMap } from '@/constants/stateToLabelMaps' |
yellowjang
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.
확인했습니다!!
📌 PR 템플릿
🏷️ PR 타입 (PR Type)
📝 요약 (Summary)
카드 컴포넌트를 만들고, 도메인 맥락이 추가된 팀 카드, 커뮤니티 카드, 포트폴리오 카드 컴포넌트 추가했습니다.
🔍 상세 내용 (Describe your changes)
🔗 관련 이슈 또는 링크 (Issue Number or Link)
✅ 체크리스트 (Checklist)
📸 스크린샷 (선택 사항)
2024-12-11.14.56.13.mov
📝 기타 사항
Summary by CodeRabbit
IcAnswerBlue아이콘 추가.Chip,CommunityCard,PortfolioCard,TeamRecruitmentCard,Card컴포넌트 추가.Divider,joinWithHash,formatDate함수 추가.cyan추가.TextBase컴포넌트의 기본 글꼴 두께 변경.CommunityCard,PortfolioCard,TeamRecruitmentCard스토리.Chip컴포넌트의 스타일 조정.Footer컴포넌트에서 시각적 구분을 위해Divider컴포넌트 사용.PostBaseBody인터페이스에서member속성을writer로 변경.