-
Notifications
You must be signed in to change notification settings - Fork 3
Feat/127/update detail page #130
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
Walkthrough์ด PR์์๋ ์ฌ์ฉ์ API์ ์น๋ฌด์ ๊ด๋ฆฌ API์ ๊ธฐ๋ฅ์ ํ์ฅํ๋ ์ฌ๋ฌ ๋ณ๊ฒฝ ์ฌํญ์ด ํฌํจ๋์ด ์์ต๋๋ค. Changes
Possibly related PRs
Suggested labels
Suggested reviewers
Poem
Warning There were issues while running some tools. Please review the errors and either fix the toolโs configuration or disable the tool if itโs a critical failure. ๐ง eslint
src/app/(crew)/crew/detail/[id]/page.tsxOops! Something went wrong! :( ESLint: 8.57.1 ESLint couldn't determine the plugin "react-hooks" uniquely.
Please remove the "plugins" setting from either config or remove either plugin installation. If you still can't figure out the problem, please stop by https://eslint.org/chat/help to chat with the team. ๐ Recent review detailsConfiguration used: CodeRabbit UI ๐ Files selected for processing (2)
๐ง Files skipped from review as they are similar to previous changes (2)
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 (
|
|
๐storybook: https://67206cc6ff9d7a05a3528ff8-otzqwvpnqi.chromatic.com/ |
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: 7
๐งน Outside diff range and nitpick comments (14)
src/_apis/crew/crew-detail-apis.ts (1)
Line range hint
4-15: ์ ๋ ฅ๊ฐ ์ ํจ์ฑ ๊ฒ์ฌ ์ถ๊ฐ ํ์ํฌ๋ฃจ ID๊ฐ ์ ํจํ ์์์ธ์ง ํ์ธํ๋ ๊ฒ์ฆ ๋ก์ง์ ์ถ๊ฐํ๋ ๊ฒ์ด ์ข์ต๋๋ค.
๋ค์๊ณผ ๊ฐ์ด ์์ ํ๋ ๊ฒ์ ์ ์ํฉ๋๋ค:
export async function getCrewDetail(id: number): Promise<CrewDetail> { + if (!Number.isInteger(id) || id <= 0) { + throw new Error('ํฌ๋ฃจ ID๋ ์์ ์ ์์ฌ์ผ ํฉ๋๋ค.'); + } const url = `/api/crews/${id}`;src/app/(crew)/crew/detail/[id]/page.tsx (1)
Line range hint
33-39: ๋ฆฌ๋ทฐ ์น์ ๊ตฌํ ์ถ์ ์ด ํ์ํฉ๋๋ค๋ฆฌ๋ทฐ ์น์ ๊ตฌํ์ด ๋ณด๋ฅ๋ ์ํ์ ๋๋ค. ์ด์ ํธ๋ํน ์์คํ ์์ ๊ด๋ฆฌ๋๊ณ ์๋์ง ํ์ธ์ด ํ์ํฉ๋๋ค.
๋ฆฌ๋ทฐ ์น์ ๊ตฌํ์ ์ํ ์ด์๋ฅผ ์์ฑํด๋๋ฆด๊น์?
src/types/crew-card.d.ts (1)
41-46: ๋ฏผ๊ฐํ ์ ๋ณด ์ฒ๋ฆฌ์ ๋ํ ๋ณด์ ๊ฒํ ํ์
CrewDetailMember์ธํฐํ์ด์ค์ ์ด๋ฉ์ผ๊ณผ ๊ฐ์ ๋ฏผ๊ฐํ ๊ฐ์ธ์ ๋ณด๊ฐ ํฌํจ๋์ด ์์ต๋๋ค. ๋ค์ ์ฌํญ๋ค์ ๊ณ ๋ คํด์ฃผ์ธ์:
- ์ด๋ฉ์ผ ์ ๋ณด๊ฐ UI์ ํ์๋ ๋ ์ ์ ํ ๋ง์คํน ์ฒ๋ฆฌ
- ํ์ํ ๊ฒฝ์ฐ์๋ง ์ด๋ฉ์ผ ์ ๋ณด๋ฅผ ๋ก๋ํ๋๋ก ๊ตฌํ
src/app/(crew)/crew/detail/[id]/_components/rating-display.stories.tsx (1)
Line range hint
1-67: ํ์ ์์ ์ฑ ๊ฐ์ ์ ์ํ ์ ์์ ๋ฐ์ ์ธ ๊ตฌ์กฐ๊ฐ ์ ์กํ์์ง๋ง, ํ์ ๋ฐ์ดํฐ์ ์ผ๊ด์ฑ์ ์ํด ๋ค์๊ณผ ๊ฐ์ ๊ฐ์ ์ ์ ์๋๋ฆฝ๋๋ค:
+ const DEFAULT_RATING_SCORES = [5, 4, 3, 2, 1] as const; + type RatingScore = typeof DEFAULT_RATING_SCORES[number]; + + interface RatingData { + score: RatingScore; + count: number; + } - interface RatingDisplayStoryProps { + interface RatingDisplayStoryProps { totalReviewCount: number; averageRate: number; - ratingsData: { score: number; count: number }[]; + ratingsData: RatingData[]; }์ด๋ ๊ฒ ํ๋ฉด:
- ํ์ ์ ์๊ฐ ํญ์ 1-5 ์ฌ์ด์ ๊ฐ๋ง ๊ฐ์ง ์ ์์ต๋๋ค
- ๋ฐ์ดํฐ ๊ตฌ์กฐ์ ์ฌ์ฌ์ฉ์ฑ์ด ๋์์ง๋๋ค
- ํ์ ์์ ์ฑ์ด ๋์ฑ ๊ฐํ๋ฉ๋๋ค
src/components/common/profile/index.tsx (3)
16-16: ์ธํฐํ์ด์ค ๋ฌธ์ํ ๋ฐ ํ์ ์ ์ ๊ฐ์ ํ์์๋ก์ด
isCaptainprop์ด ์ถ๊ฐ๋์์ง๋ง, JSDoc ์ฃผ์๊ณผ ์ธํฐํ์ด์ค์์ ์ผ๊ด์ฑ ์๊ฒ ์ฒ๋ฆฌ๋์์ต๋๋ค. ๋ค๋ง, ๊ฐ size ์ต์ ('small' | 'header' | 'large' | 'full')์ ๋ํ ์์ธํ ์ค๋ช ์ด JSDoc์ ๋๋ฝ๋์ด ์์ต๋๋ค.๋ค์๊ณผ ๊ฐ์ด JSDoc์ ๋ณด์ํ๋ ๊ฒ์ ์ ์ํฉ๋๋ค:
* @param {Object} props - Profile ์ปดํฌ๋ํธ์ props -* @param {'small' | 'medium' | 'large'} [props.size='large'] - ํ๋กํ์ ํฌ๊ธฐ๋ฅผ ๊ฒฐ์ ๊ธฐ๋ณธ๊ฐ์ 'large' +* @param {'small' | 'header' | 'large' | 'full'} [props.size='full'] - ํ๋กํ์ ํฌ๊ธฐ๋ฅผ ๊ฒฐ์ +* - small: ์์ ํฌ๊ธฐ (24x24) +* - header: ํค๋์ฉ ํฌ๊ธฐ (๋ฐ์ํ: 28x28 ~ 40x40) +* - large: ํฐ ํฌ๊ธฐ (56x56) +* - full: ์ปจํ ์ด๋ ํฌ๊ธฐ์ ๋ง์ถคAlso applies to: 25-25
38-46: ์ฌ์ด์ฆ ๊ณ์ฐ ๋ก์ง ๋ฐ ํด๋์ค ๊ตฌ์กฐ ๊ฒํ์ฌ์ด์ฆ ๊ณ์ฐ ๋ก์ง์ด ๊ฐ์ ๋์์ผ๋, ๋ช ๊ฐ์ง ๊ณ ๋ ค์ฌํญ์ด ์์ต๋๋ค:
finalSize๊ฐ 'captain' ํ์ ์ ๊ณ ๋ คํ์ง ์์ ํ์ ์์ ์ฑ์ด ๋ถ์กฑํฉ๋๋ค.- captain ์ฌ์ด์ฆ(80x80)๊ฐ ํ๋์ฝ๋ฉ๋์ด ์์ด ์ ์ง๋ณด์์ฑ์ด ๋จ์ด์ง๋๋ค.
๋ค์๊ณผ ๊ฐ์ ๊ฐ์ ์ ์ ์ํฉ๋๋ค:
-const finalSize = editable || isCaptain ? 'large' : size; +const finalSize = isCaptain ? 'captain' : (editable ? 'large' : size); +// ํฌ๊ธฐ ์์ ์ ์ +const PROFILE_SIZES = { + SMALL: 24, + HEADER: { SM: 28, MD: 40, LG: 40 }, + LARGE: 56, + CAPTAIN: 80, +} as const; const sizeClasses = { small: 'w-6 h-6', header: 'sm:w-7 sm:h-7 md:w-[40px] md:h-[40px] lg:w-[40px] lg:h-[40px]', large: 'w-14 h-14', full: 'w-full h-full', - captain: 'w-20 h-20', + captain: 'w-[80px] h-[80px]', };
87-91: ์บกํด ๋ฐฐ์ง UI ๊ตฌํ ๊ฒํ์บกํด ๋ฐฐ์ง UI๊ฐ ์ ์ ํ๊ฒ ๊ตฌํ๋์์ต๋๋ค. ํ์ง๋ง ์ ๊ทผ์ฑ๊ณผ ๋ฐ์ํ ๋์์ธ ์ธก๋ฉด์์ ๊ฐ์ ์ด ํ์ํฉ๋๋ค.
๋ค์๊ณผ ๊ฐ์ ๊ฐ์ ์ ์ ์ํฉ๋๋ค:
{isCaptain && ( <div className="absolute bottom-0 right-0 z-20"> <Image src={captainCheck} alt="์บกํด ๋ฐฐ์ง" - width={24} - height={24} + width={28} + height={28} + className="sm:w-6 sm:h-6 md:w-7 md:h-7" /> </div> )}src/app/(crew)/crew/detail/[id]/_components/detail-crew.stories.tsx (2)
22-105: ํ ์คํธ ๋ฐ์ดํฐ ๊ฐ์ ์ด ํ์ํฉ๋๋ค.๋ค์ ์ฌํญ๋ค์ ๊ณ ๋ คํด ์ฃผ์ธ์:
- ํ๋กํ ์ด๋ฏธ์ง๊ฐ ์๋ ๊ฒฝ์ฐ์ ์๋ ๊ฒฝ์ฐ๊ฐ ํผ์ฌ๋์ด ์์ด ์ข์ผ๋, ๋งค์ฐ ๊ธด ๋๋ค์์ด๋ ํน์๋ฌธ์๊ฐ ํฌํจ๋ ์ผ์ด์ค๋ ์ถ๊ฐํ๋ฉด ์ข์ ๊ฒ ๊ฐ์ต๋๋ค.
introduceํ ์คํธ๊ฐ ๋ฐ๋ณต๋๋ ๋ฌธ์์ด๋ณด๋ค๋ ์ค์ ์ ์ ์ฌํ ์๊ฐ๊ธ๋ก ๋์ฒดํ๋ฉด ์ข์ ๊ฒ ๊ฐ์ต๋๋ค.
107-138: ์บกํด ์๋๋ฆฌ์ค์ ๋ํ ํ ์คํธ ์ผ์ด์ค ๋ณด์์ด ํ์ํฉ๋๋ค.๋ค์๊ณผ ๊ฐ์ ์ฃ์ง ์ผ์ด์ค๋ค์ ์ถ๊ฐํ๋ฉด ์ข์ ๊ฒ ๊ฐ์ต๋๋ค:
totalCount๊ฐparticipantCount๋ณด๋ค ์์ ๊ฒฝ์ฐconfirmed๊ฐfalse์ธ ๊ฒฝ์ฐtotalGatheringCount๊ฐ 0์ธ ๊ฒฝ์ฐsrc/app/(crew)/crew/detail/[id]/_components/detail-crew-presenter.tsx (3)
61-78: ์ด๋ฏธ์ง ์ต์ ํ ๊ด๋ จ ๊ฐ์ ์ด ํ์ํฉ๋๋ค.ํฐ ์ด๋ฏธ์ง๋ฅผ ๋ก๋ํ ๋ ์ฑ๋ฅ ์ต์ ํ๋ฅผ ์ํด Next.js Image ์ปดํฌ๋ํธ์ ์ถ๊ฐ ์์ฑ๋ค์ ํ์ฉํ ์ ์์ต๋๋ค.
๋ค์๊ณผ ๊ฐ์ด ์์ ํ๋ ๊ฒ์ ์ ์ํฉ๋๋ค:
-<Image src={imageUrl} alt={title} layout="fill" objectFit="cover" className="rounded-lg" /> +<Image + src={imageUrl} + alt={title} + layout="fill" + objectFit="cover" + className="rounded-lg" + priority + sizes="(max-width: 1200px) 100vw, 1200px" + quality={85} +/>
137-137: ๋ถํ์ํ non-null ๋จ์ธ ์ฐ์ฐ์๊ฐ ์ฌ์ฉ๋์์ต๋๋ค.
captain!.email์์ ์ฌ์ฉ๋ non-null ๋จ์ธ ์ฐ์ฐ์๋ ๋ถํ์ํฉ๋๋ค. captain ๊ฐ์ฒด๋ ์ด๋ฏธ ํ์ ๋์ด ์์ต๋๋ค.๋ค์๊ณผ ๊ฐ์ด ์์ ํ๋ ๊ฒ์ ์ ์ํฉ๋๋ค:
-<p className="text-sm font-normal text-gray-500">{captain!.email}</p> +<p className="text-sm font-normal text-gray-500">{captain.email}</p>
168-186: ๋ฉค๋ฒ ๋ชฉ๋ก์ ์ ๊ทผ์ฑ ๊ฐ์ ์ด ํ์ํฉ๋๋ค.๋ฉค๋ฒ ๋ชฉ๋ก ์น์ ์ ARIA ๋ ์ด๋ธ๊ณผ ์ญํ ์ด ๋๋ฝ๋์ด ์์ต๋๋ค.
๋ค์๊ณผ ๊ฐ์ด ์์ ํ๋ ๊ฒ์ ์ ์ํฉ๋๋ค:
-<div className="mt-4 h-40 space-y-6 overflow-y-auto"> +<div + className="mt-4 h-40 space-y-6 overflow-y-auto" + role="list" + aria-label="ํฌ๋ฃจ ๋ฉค๋ฒ ๋ชฉ๋ก" +> {members.length > 0 ? ( <div className="grid grid-cols-2 gap-4"> {members.map((member) => ( - <div key={member.id} className="flex items-center space-x-2"> + <div + key={member.id} + className="flex items-center space-x-2" + role="listitem" + >src/app/(crew)/crew/detail/[id]/_components/detail-crew-container.tsx (2)
29-31: 'user' ๊ฐ์ฒด์ ํ์ ์ผ๊ด์ฑ ์ ์ง๋ก ์ฝ๋ ๊ฐ์ํํ์ฌ
isDataWrappedUserํ์ ๊ฐ๋ ํจ์๋ฅผ ์ฌ์ฉํ์ฌuser๊ฐ์ฒด์ ๊ตฌ์กฐ๋ฅผ ํ๋ณํ๊ณ ์์ต๋๋ค. ์ด๋user๊ฐ์ฒด์ ํ์ ์ด ์ผ๊ด๋์ง ์์์ ์๋ฏธํฉ๋๋ค.useAuthStore์์ ๋ฐํ๋๋user๊ฐ์ฒด์ ๊ตฌ์กฐ๋ฅผ ํต์ผํ์ฌ ํ์ ๊ฐ๋ ํจ์ ์์ด ์ฝ๋๋ฅผ ๊ฐ๊ฒฐํ๊ฒ ์ ์งํ๋ ๊ฒ์ ์ถ์ฒ๋๋ฆฝ๋๋ค.
127-129: ์ค๋ณต๋ ๋ฐ์ดํฐ ํ์ธ ๋ก์ง ์ ๊ฑฐ ๊ณ ๋ ค์ด๋ฏธ
isLoading๊ณผfetchError์ ๋ํ ์ฒ๋ฆฌ๊ฐ ์ด๋ฃจ์ด์ง๊ณ ์์ผ๋ฏ๋ก,if (!data)์กฐ๊ฑด๋ฌธ์ ๋ถํ์ํ ์ ์์ต๋๋ค(127๋ฒ ๋ผ์ธ). ์ฝ๋์ ๊ฐ๊ฒฐ์ฑ๊ณผ ๊ฐ๋ ์ฑ์ ์ํด ํด๋น ์กฐ๊ฑด๋ฌธ์ ์ฌ๊ฒํ ํ๋ ๊ฒ์ ์ ์๋๋ฆฝ๋๋ค.
๐ Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
โ Files ignored due to path filters (3)
public/assets/icons/ic-captain-check.svgis excluded by!**/*.svgpublic/assets/icons/ic-email.svgis excluded by!**/*.svgpublic/assets/icons/ic-share.svgis excluded by!**/*.svg
๐ Files selected for processing (14)
src/_apis/auth/user-apis.ts(1 hunks)src/_apis/crew/crew-detail-apis.ts(2 hunks)src/app/(crew)/crew/detail/[id]/_components/create-gathering.tsx(1 hunks)src/app/(crew)/crew/detail/[id]/_components/crew-review-list.stories.tsx(1 hunks)src/app/(crew)/crew/detail/[id]/_components/detail-crew-container.tsx(1 hunks)src/app/(crew)/crew/detail/[id]/_components/detail-crew-presenter.tsx(1 hunks)src/app/(crew)/crew/detail/[id]/_components/detail-crew-section.tsx(0 hunks)src/app/(crew)/crew/detail/[id]/_components/detail-crew.stories.tsx(1 hunks)src/app/(crew)/crew/detail/[id]/_components/rating-display.stories.tsx(1 hunks)src/app/(crew)/crew/detail/[id]/page.tsx(2 hunks)src/components/common/crew-list/detail-crew-card.stories.tsx(0 hunks)src/components/common/crew-list/detail-crew-card.tsx(0 hunks)src/components/common/profile/index.tsx(5 hunks)src/types/crew-card.d.ts(1 hunks)
๐ค Files with no reviewable changes (3)
- src/app/(crew)/crew/detail/[id]/_components/detail-crew-section.tsx
- src/components/common/crew-list/detail-crew-card.stories.tsx
- src/components/common/crew-list/detail-crew-card.tsx
โ Files skipped from review due to trivial changes (1)
- src/app/(crew)/crew/detail/[id]/_components/create-gathering.tsx
๐ Additional comments (13)
src/_apis/auth/user-apis.ts (1)
4-10: ์๋ต ํ์
๋จ์ํ๊ฐ ์ ์ด๋ฃจ์ด์ก์ต๋๋ค!
์๋ต ํ์
์ Promise<{ data: User }>์์ Promise`๋ก ๋จ์ํํ ๊ฒ์ด ์ข์ ๋ณ๊ฒฝ์ฌํญ์
๋๋ค. ์ด๋ ์ฝ๋๋ฅผ ๋ ๊น๋ํ๊ฒ ๋ง๋ค๊ณ ์ฌ์ฉํ๊ธฐ ์ฝ๊ฒ ๋ง๋ญ๋๋ค.
์ด ๋ณ๊ฒฝ์ผ๋ก ์ธํ ์ํฅ์ ํ์ธํ๊ธฐ ์ํด ๋ค์ ์คํฌ๋ฆฝํธ๋ฅผ ์คํํ์ธ์:
โ Verification successful
Let me gather more information to verify the impact of this change.
Let me do one final check to ensure we haven't missed any usages.
์๋ต ํ์ ๋ณ๊ฒฝ์ด ์์ ํ๊ฒ ์ ์ฉ๋์์ต๋๋ค
๊ฒ์ฆ ๊ฒฐ๊ณผ, getUser ํจ์์ ์๋ต ํ์
์ Promise<{ data: User }>์์ Promise<User>๋ก ๋ณ๊ฒฝํ ๊ฒ์ด ์์ ํ๊ฒ ์ด๋ฃจ์ด์ก์์ ํ์ธํ์ต๋๋ค. ๋ค์๊ณผ ๊ฐ์ ์ด์ ๋ก ์ด ๋ณ๊ฒฝ์ด ๋ฌธ์ ์์์ ํ์ธํ์ต๋๋ค:
getUserํจ์๋ ๋ด๋ถ์ ์ผ๋กresponse.data๋ฅผ ์ถ์ถํ์ฌ ๋ฐํํ๋ฏ๋ก ํธ์ถํ๋ ์ชฝ์์๋ ์ด๋ฏธ unwrap๋ User ๊ฐ์ฒด๋ฅผ ๋ฐ๊ฒ ๋ฉ๋๋ค- ์ฝ๋๋ฒ ์ด์ค ๊ฒ์ ๊ฒฐ๊ณผ, ์ด ํจ์๋ฅผ ์ฌ์ฉํ๋ ๋ชจ๋ ๊ณณ์์
.dataํ๋กํผํฐ์ ์ง์ ์ ๊ทผํ์ง ์๊ณ ์์ต๋๋ค - React Query๋ฅผ ์ฌ์ฉํ๋
getUserQuery์์๋ ์ฌ๋ฐ๋ฅด๊ฒ ํ์ ์ด ์ ํ๋๊ณ ์์ต๋๋ค
๐ Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: getUser ํจ์๋ฅผ ์ฌ์ฉํ๋ ๋ชจ๋ ์์น ํ์ธ
# getUser ํจ์ ํธ์ถ ๊ฒ์
rg -l "getUser\(\)" | xargs rg -l "\.data"
# ๋ฐํ๋ User ํ์
์ฌ์ฉ ๊ฒ์
ast-grep --pattern 'const $_ = await getUser()'
Length of output: 122
Script:
#!/bin/bash
# Search for all usages of getUser function with context
rg "getUser\(\)" -A 3 -B 3
# Search for any potential destructuring of data property
ast-grep --pattern 'const { data } = await getUser()'
Length of output: 494
Script:
#!/bin/bash
# Search for any usage of getUser in tsx/ts files
rg "getUser" -t ts -t tsx -A 5
# Check if there are any test files using getUser
fd -e test.ts -e test.tsx -e spec.ts -e spec.tsx | xargs rg "getUser"
Length of output: 606
src/_apis/crew/crew-detail-apis.ts (1)
29-39: ํฌ๋ฃจ ํํด ์ ๋ฉค๋ฒ์ญ ํ์ธ ๋ก์ง ํ์
์ฌ์ฉ์๊ฐ ์ค์ ๋ก ํฌ๋ฃจ์ ๋ฉค๋ฒ์ธ์ง ํ์ธํ๋ ๋ก์ง์ด ํ์ํ๋ฉฐ, ๋์์ฑ ๋ฌธ์ ๋ฅผ ๊ณ ๋ คํด์ผ ํฉ๋๋ค.
๋ฉค๋ฒ์ญ ํ์ธ์ ์ํ ๋ณ๋์ ํจ์๋ฅผ ๊ตฌํํ๊ณ , ํํด ์ ์ ์ด๋ฅผ ํธ์ถํ๋ ๊ฒ์ ๊ถ์ฅํฉ๋๋ค.
src/app/(crew)/crew/detail/[id]/_components/crew-review-list.stories.tsx (1)
9-9: ์คํ ๋ฆฌ๋ถ ์ปดํฌ๋ํธ ๊ตฌ์กฐ ๊ฐ์ ์ด ํ์ธ๋์์ต๋๋ค.
์ปดํฌ๋ํธ ๊ณ์ธต ๊ตฌ์กฐ๊ฐ 'Components/Detail' ํ์๋ก ์ด๋๋ ๊ฒ์ด ํ์ธ๋์์ต๋๋ค. ์ด๋ ๋ํ ์ผ ํ์ด์ง ๊ด๋ จ ์ปดํฌ๋ํธ๋ค์ ๊ตฌ์กฐํ๋ ๊ด๋ฆฌ๋ฅผ ์ํ ์ ์ ํ ๋ณ๊ฒฝ์ผ๋ก ๋ณด์ ๋๋ค.
๋ค๋ฅธ ๋ํ ์ผ ํ์ด์ง ๊ด๋ จ ์คํ ๋ฆฌ๋ค์ ์ผ๊ด์ฑ์ ํ์ธํ๊ธฐ ์ํด ๋ค์ ์คํฌ๋ฆฝํธ๋ฅผ ์คํํฉ๋๋ค:
โ Verification successful
์คํ ๋ฆฌ๋ถ ์ปดํฌ๋ํธ ๊ตฌ์กฐ๊ฐ ์ผ๊ด๋๊ฒ ์ ์ฉ๋์ด ์์ต๋๋ค.
๋ํ ์ผ ํ์ด์ง ๊ด๋ จ ๋ชจ๋ ์คํ ๋ฆฌ ํ์ผ๋ค('CrewReviewList', 'RatingDisplay', 'DetailCrewPresenter')์ด 'Components/Detail' ํ์์ ์ผ๊ด๋๊ฒ ๊ตฌ์ฑ๋์ด ์์์ ํ์ธํ์ต๋๋ค.
๐ Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: ๋ํ
์ผ ํ์ด์ง ๊ด๋ จ ์คํ ๋ฆฌ ํ์ผ๋ค์ title ์ผ๊ด์ฑ ํ์ธ
# ์คํ ๋ฆฌ ํ์ผ๋ค์์ title ์ค์ ์ ๊ฒ์
rg "title: ['|\"]Components/Detail" -g "*.stories.tsx"
Length of output: 409
src/app/(crew)/crew/detail/[id]/page.tsx (3)
19-19: props ํ์
๊ฒ์ฆ์ด ํ์ํฉ๋๋ค
DetailCrew ์ปดํฌ๋ํธ์ ์ ๋ฌ๋๋ id prop์ ํ์
์ด ์ ์ ํ์ง ํ์ธ์ด ํ์ํฉ๋๋ค.
#!/bin/bash
# Description: DetailCrew ์ปดํฌ๋ํธ์ props ํ์
ํ์ธ
# props ํ์
์ ์ ๊ฒ์
ast-grep --pattern 'interface $Props {
$$$
id: $_
$$$
}'26-26: CreateGathering ์ปดํฌ๋ํธ์ ์์กด์ฑ ํ์ธ์ด ํ์ํฉ๋๋ค
CreateGathering ์ปดํฌ๋ํธ๊ฐ crew id์ ๊ฐ์ ์ปจํ
์คํธ ์ ๋ณด์ ์ ๊ทผํ ์ ์๋์ง ํ์ธ์ด ํ์ํฉ๋๋ค.
#!/bin/bash
# Description: CreateGathering ์ปดํฌ๋ํธ์ ์์กด์ฑ ํ์ธ
# ์ปดํฌ๋ํธ ๊ตฌํ ํ์ธ
rg -A 10 "export.*CreateGathering" "src/app/(crew)/crew/detail"
# Context ์ฌ์ฉ ํ์ธ
rg "useContext|Provider" "src/app/(crew)/crew/detail"3-3: ์ปดํฌ๋ํธ ๊ตฌ์กฐ ๊ฒ์ฆ์ด ํ์ํฉ๋๋ค
DetailCrewSection์์ DetailCrew๋ก์ ์ด๋ฆ ๋ณ๊ฒฝ์ด ์ปจํ
์ด๋ ํจํด ๋์
์ ์๋ฏธํ๋ ๊ฒ์ผ๋ก ๋ณด์
๋๋ค. ๊ด๋ จ ์ปดํฌ๋ํธ๋ค์ ๊ตฌ์กฐ๋ฅผ ํ์ธํด์ฃผ์ธ์.
โ Verification successful
Let me gather more specific information about the DetailCrew component structure.
์ปจํ ์ด๋ ํจํด์ด ์ฌ๋ฐ๋ฅด๊ฒ ๊ตฌํ๋์ด ์์ต๋๋ค
DetailCrew ์ปดํฌ๋ํธ๊ฐ Container-Presenter ํจํด์ ๋ฐ๋ผ ์ ์ ํ ๊ตฌ์กฐํ๋์ด ์์ต๋๋ค:
detail-crew-container.tsx: ๋น์ฆ๋์ค ๋ก์ง ์ฒ๋ฆฌdetail-crew-presenter.tsx: UI ํํ ๋ด๋นdetail-crew.stories.tsx: ์ปดํฌ๋ํธ ๋ฌธ์ํ
์ด๋ฆ ๋ณ๊ฒฝ์ ์ํคํ ์ฒ ๊ฐ์ ์ ์ํ ์ ์ ํ ๋ฆฌํฉํ ๋ง์ผ๋ก ํ์ธ๋ฉ๋๋ค.
๐ Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: ์ปดํฌ๋ํธ ๊ตฌ์กฐ ํ์ธ
# DetailCrew ๊ด๋ จ ์ปดํฌ๋ํธ ํ์ผ ๊ฒ์
fd -e tsx -e ts "detail-crew" "src/app/(crew)/crew/detail"
# ์ปจํ
์ด๋ ํจํด ๊ตฌํ ํ์ธ
rg -A 5 "DetailCrew" "src/app/(crew)/crew/detail"
Length of output: 1503
Script:
#!/bin/bash
# DetailCrew ์ปดํฌ๋ํธ ํ์ผ ์ฐพ๊ธฐ
fd "detail-crew" "src/app/(crew)/crew/detail"
# DetailCrew ์ปดํฌ๋ํธ ๊ตฌํ ํ์ธ
rg -A 10 "DetailCrew" "src/app/(crew)/crew/detail"
# ์ด์ DetailCrewSection ๊ด๋ จ ์ฝ๋ ์ฐพ๊ธฐ
rg -A 10 "DetailCrewSection" "src/app/(crew)/crew/detail"
Length of output: 9168
src/types/crew-card.d.ts (1)
52-54: ํ์
๋ณ๊ฒฝ์ ๋ฐ๋ฅธ ์ปดํฌ๋ํธ ์
๋ฐ์ดํธ ํ์ธ
CrewDetail ์ธํฐํ์ด์ค์ ๋ค์๊ณผ ๊ฐ์ ์ค์ํ ๋ณ๊ฒฝ์ฌํญ์ด ์์ต๋๋ค:
- ์๊ฐ(
introduce)์ ์นดํ ๊ณ ๋ฆฌ ์ ๋ณด๊ฐ ์ถ๊ฐ๋จ crewMembers์ ํ์ ์ดCrewDetailMember[]๋ก ๋ณ๊ฒฝ๋จ
์ด๋ฌํ ๋ณ๊ฒฝ์ฌํญ์ด ๊ด๋ จ ์ปดํฌ๋ํธ์ ์ฌ๋ฐ๋ฅด๊ฒ ๋ฐ์๋์๋์ง ํ์ธ์ด ํ์ํฉ๋๋ค.
Also applies to: 61-61
โ Verification successful
ํ์ ๋ณ๊ฒฝ์ด ์ปดํฌ๋ํธ์ ์ฌ๋ฐ๋ฅด๊ฒ ๋ฐ์๋์ด ์์์ ํ์ธํ์ต๋๋ค
CrewDetail ์ธํฐํ์ด์ค์ ๋ณ๊ฒฝ์ฌํญ์ด ๋ค์ ํ์ผ๋ค์์ ์ ์ ํ๊ฒ ์ฌ์ฉ๋๊ณ ์์ต๋๋ค:
src/app/(crew)/crew/detail/[id]/_components/detail-crew-presenter.tsx: ์๋ก์ด ํ๋๋ค(introduce,mainCategory,subCategory)์ ์ฌ๋ฐ๋ฅด๊ฒ ์ฌ์ฉsrc/app/(crew)/crew/detail/[id]/edit/page.tsx: ์์ ํผ์์ ์๋ก์ด ํ๋๋ค์ ํฌํจํ์ฌ ์ฒ๋ฆฌsrc/_apis/crew/crew-detail-apis.ts: API ์๋ต ํ์ ์ผ๋ก ์ฌ๋ฐ๋ฅด๊ฒ ์ ์ฉ
๐ Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: CrewDetail ํ์
์ ์ฌ์ฉํ๋ ์ปดํฌ๋ํธ ๊ฒ์
# CrewDetail ํ์
์ฌ์ฉ ๊ฒ์
rg "CrewDetail" -t typescript -A 3
Length of output: 69
Script:
#!/bin/bash
# Search for CrewDetail type usage across all files
rg "CrewDetail" --type-add 'ts:*.{ts,tsx}' --type ts -A 3
# Also search for files that might use these new fields
rg "introduce|mainCategory|subCategory" --type-add 'ts:*.{ts,tsx}' --type ts -A 3
# Find all TypeScript/TSX files that might be related to crew details
fd "\.(ts|tsx)$" | grep -i "crew"
Length of output: 34246
src/app/(crew)/crew/detail/[id]/_components/rating-display.stories.tsx (1)
6-6: ์คํ ๋ฆฌ๋ถ ๊ตฌ์กฐ ๊ฐ์ ์ด ์ ๋์์ต๋๋ค!
์ปดํฌ๋ํธ๋ฅผ 'Detail' ์นดํ ๊ณ ๋ฆฌ๋ก ์ด๋์ํจ ๊ฒ์ด ์ ์ฒด์ ์ธ ๊ตฌ์กฐ ๊ฐ์ ์ ๋์์ด ๋ฉ๋๋ค. ์ด๋ ๋ค๋ฅธ detail ๊ด๋ จ ์ปดํฌ๋ํธ๋ค๊ณผ์ ์ผ๊ด์ฑ์ ์ ์งํ๋๋ฐ ๋์์ด ๋ฉ๋๋ค.
src/components/common/profile/index.tsx (1)
4-4: ์๋ก์ด ์ ํธ๋ฆฌํฐ์ ์์ด์ฝ import ์ถ๊ฐ ๊ฒํ
์๋ก์ด import๋ฌธ๋ค์ด ์ ์ ํ๊ฒ ์ถ๊ฐ๋์์ต๋๋ค. cn ์ ํธ๋ฆฌํฐ๋ ์กฐ๊ฑด๋ถ ํด๋์ค ๋ค์ ์ฒ๋ฆฌ์ ์ ์ฉํ๋ฉฐ, ์บกํด ์์ด์ฝ์ ์๋ก์ด ๊ธฐ๋ฅ ๊ตฌํ์ ํ์ํฉ๋๋ค.
Also applies to: 6-6
src/app/(crew)/crew/detail/[id]/_components/detail-crew.stories.tsx (2)
1-20: ๋ฉํ๋ฐ์ดํฐ ๊ตฌ์ฑ์ด ์ ๋์ด์์ต๋๋ค!
์คํ ๋ฆฌ๋ถ ๋ฉํ๋ฐ์ดํฐ๊ฐ ์ฒด๊ณ์ ์ผ๋ก ๊ตฌ์ฑ๋์ด ์์ผ๋ฉฐ, ์ฌ์ฉ์ ์ํธ์์ฉ์ ์ํ ์ก์ ํธ๋ค๋ฌ๊ฐ ์ ์ ํ ์ ์๋์ด ์์ต๋๋ค.
140-178: ๋น ์๊ฐ๊ธ ์ฒ๋ฆฌ ๊ฒ์ฆ์ด ํ์ํฉ๋๋ค.
introduce๊ฐ ๋น ๋ฌธ์์ด์ธ ๊ฒฝ์ฐ์ ๋ํ UI ์ฒ๋ฆฌ๊ฐ ์ฌ๋ฐ๋ฅด๊ฒ ๋์ด์๋์ง ํ์ธํด ์ฃผ์ธ์. ๋น ๋ฌธ์์ด ๋์ ๊ธฐ๋ณธ๊ฐ์ ํ์ํ๊ฑฐ๋, "์๊ฐ๊ธ์ด ์์ต๋๋ค"์ ๊ฐ์ ๋ฉ์์ง๋ฅผ ๋ณด์ฌ์ฃผ๋ ๊ฒ์ด ์ข์ ๊ฒ ๊ฐ์ต๋๋ค.
src/app/(crew)/crew/detail/[id]/_components/detail-crew-presenter.tsx (2)
14-23: ์ธํฐํ์ด์ค ์ ์๊ฐ ๋ช
ํํ๊ณ ์ ๊ตฌ์ฑ๋์ด ์์ต๋๋ค.
props ์ธํฐํ์ด์ค๊ฐ ์ ์ ์๋์ด ์์ผ๋ฉฐ, ํ์ํ ๋ชจ๋ ํธ๋ค๋ฌ ํจ์๋ค์ด ํฌํจ๋์ด ์์ต๋๋ค.
150-167: ์ฐธ์ฌ ์ธ์ ํ์ UI์ ๋ฐ์ํ ์ฒ๋ฆฌ ๊ฒํ ๊ฐ ํ์ํฉ๋๋ค.
๋ชจ๋ฐ์ผ ํ๋ฉด์์ ์ฐธ์ฌ ์ธ์ ์์ ํ๋ก๊ทธ๋ ์ค ๋ฐ๊ฐ ์ ํ์๋๋์ง ํ์ธ์ด ํ์ํฉ๋๋ค.
๋ค์ ์คํฌ๋ฆฝํธ๋ก ๊ด๋ จ ์ปดํฌ๋ํธ์ ๋ฐ์ํ ์ฒ๋ฆฌ๋ฅผ ํ์ธํด์ฃผ์ธ์:
| // ์ฃผ์ต์ ํฌ๋ฃจ ์ทจ์ | ||
| export async function cancelCrew(crewId: number): Promise<void> { | ||
| const url = `/api/crews/${crewId}`; | ||
|
|
||
| await fetchApi<void>(url, { | ||
| method: 'DELETE', | ||
| headers: { | ||
| 'Content-Type': 'application/json', | ||
| }, | ||
| }); | ||
| } |
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 async function cancelCrew(crewId: number): Promise<void> {
+export async function cancelCrew(
+ crewId: number,
+ organizerId: number,
+ confirmation: boolean
+): Promise<void> {
+ if (!confirmation) {
+ throw new Error('ํฌ๋ฃจ ์ทจ์ ์์
์ ํ์ธ์ด ํ์ํฉ๋๋ค.');
+ }
+
+ // ์ฃผ์ต์ ๊ถํ ํ์ธ
+ const crewDetail = await getCrewDetail(crewId);
+ if (crewDetail.organizerId !== organizerId) {
+ throw new Error('ํฌ๋ฃจ ์ทจ์๋ ์ฃผ์ต์๋ง ๊ฐ๋ฅํฉ๋๋ค.');
+ }
const url = `/api/crews/${crewId}`;Committable suggestion skipped: line range outside the PR's diff.
| // ํฌ๋ฃจ ์ฐธ์ฌ | ||
| export async function joinCrew(crewId: number): Promise<void> { | ||
| const url = `/api/crews/${crewId}/join`; | ||
|
|
||
| await fetchApi<void>(url, { | ||
| method: 'POST', | ||
| headers: { | ||
| 'Content-Type': 'application/json', | ||
| }, | ||
| }); | ||
| } |
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
์๋ฌ ์ฒ๋ฆฌ ๋ฐ ์๋ต ํ์ ๋ช ์ ํ์
API ํธ์ถ ์คํจ ์์ ์๋ฌ ์ฒ๋ฆฌ์ ์๋ต ํ์ ์ ๋ํ ๋ช ํํ ์ ์๊ฐ ํ์ํฉ๋๋ค.
๋ค์๊ณผ ๊ฐ์ด ์์ ํ๋ ๊ฒ์ ์ ์ํฉ๋๋ค:
+interface JoinCrewResponse {
+ success: boolean;
+ message?: string;
+}
-export async function joinCrew(crewId: number): Promise<void> {
+export async function joinCrew(crewId: number): Promise<JoinCrewResponse> {
const url = `/api/crews/${crewId}/join`;
- await fetchApi<void>(url, {
+ const response = await fetchApi<JoinCrewResponse>(url, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
});
+ return response;
}๐ 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.
| // ํฌ๋ฃจ ์ฐธ์ฌ | |
| export async function joinCrew(crewId: number): Promise<void> { | |
| const url = `/api/crews/${crewId}/join`; | |
| await fetchApi<void>(url, { | |
| method: 'POST', | |
| headers: { | |
| 'Content-Type': 'application/json', | |
| }, | |
| }); | |
| } | |
| interface JoinCrewResponse { | |
| success: boolean; | |
| message?: string; | |
| } | |
| export async function joinCrew(crewId: number): Promise<JoinCrewResponse> { | |
| const url = `/api/crews/${crewId}/join`; | |
| const response = await fetchApi<JoinCrewResponse>(url, { | |
| method: 'POST', | |
| headers: { | |
| 'Content-Type': 'application/json', | |
| }, | |
| }); | |
| return response; | |
| } |
| nickname: string; | ||
| profileImageUrl?: string; | ||
| captain?: boolean; | ||
| } |
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.
๐ก Codebase verification
captain ์์ฑ ์ ๊ฑฐ๋ ์์ ํ์ง ์์ต๋๋ค
captain ์์ฑ์ด ์ฌ๋ฌ ์ปดํฌ๋ํธ์์ ํ๋ฐํ ์ฌ์ฉ๋๊ณ ์์์ด ํ์ธ๋์์ต๋๋ค:
src/app/(crew)/crew/detail/[id]/_components/detail-crew-presenter.tsx์์ ํฌ๋ฃจ์ฅ ํ์ ๋ก์ง์ ์ฌ์ฉsrc/app/(crew)/crew/detail/[id]/_components/detail-crew-container.tsx์์ ํ์ฌ ์ฌ์ฉ์๊ฐ ํฌ๋ฃจ์ฅ์ธ์ง ํ์ธํ๋๋ฐ ์ฌ์ฉsrc/components/common/profile/index.tsx์์ ํฌ๋ฃจ์ฅ ๋ฐฐ์ง ํ์์ ์ฌ์ฉ- Storybook ํ์ผ์์๋ ์ฌ๋ฌ ํ ์คํธ ์ผ์ด์ค์ ์ฌ์ฉ
์ด ์์ฑ์ ์ ๊ฑฐํ๋ฉด ๊ธฐ์กด ๊ธฐ๋ฅ์ด ์์๋ ์ ์์ผ๋ฏ๋ก, ์ ์งํ๊ฑฐ๋ ์์ ํ ๋ง์ด๊ทธ๋ ์ด์ ๊ณํ์ด ํ์ํฉ๋๋ค.
๐ Analysis chain
captain ์์ฑ ์ ๊ฑฐ์ ๋ฐ๋ฅธ ์ํฅ ํ์ธ ํ์
CrewMember ์ธํฐํ์ด์ค์์ captain ์์ฑ์ด ์ ๊ฑฐ๋์์ต๋๋ค. ์ด ๋ณ๊ฒฝ์ด ๊ธฐ์กด ์ฝ๋์ ๋ฏธ์น๋ ์ํฅ์ ํ์ธํด์ผ ํฉ๋๋ค.
๐ Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: captain ์์ฑ์ ์ฌ์ฉํ๋ ์ฝ๋ ๊ฒ์
# CrewMember ํ์
์ captain ์์ฑ ์ฌ์ฉ ๊ฒ์
rg "captain.*CrewMember" -t typescript
Length of output: 75
Script:
#!/bin/bash
# Search for 'captain' usage in all potential TypeScript files
rg "captain" --type-add 'ts:*.{ts,tsx,d.ts}' -t ts
# Also search for CrewMember usage to understand the context
rg "CrewMember" --type-add 'ts:*.{ts,tsx,d.ts}' -t ts
Length of output: 3205
| <div | ||
| className={cn( | ||
| 'relative inline-block', | ||
| isCaptain ? sizeClasses.captain : sizeClasses[finalSize], | ||
| )} | ||
| > | ||
| <button | ||
| type="button" | ||
| className={`relative ${sizeClasses[finalSize]} overflow-hidden rounded-full`} | ||
| className={cn( | ||
| 'relative overflow-hidden rounded-full', | ||
| isCaptain ? sizeClasses.captain : sizeClasses[finalSize], | ||
| !editable && 'pointer-events-none', | ||
| )} |
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
์กฐ๊ฑด๋ถ ํด๋์ค ์ฒ๋ฆฌ ๋ฐ ์ ๊ทผ์ฑ ๊ฐ์ ํ์
cn ์ ํธ๋ฆฌํฐ๋ฅผ ์ฌ์ฉํ ํด๋์ค ์กฐํฉ์ด ์ ๊ตฌํ๋์์ต๋๋ค. ํ์ง๋ง ์ ๊ทผ์ฑ ์ธก๋ฉด์์ ๊ฐ์ ์ด ํ์ํฉ๋๋ค.
๋ค์๊ณผ ๊ฐ์ ๊ฐ์ ์ ์ ์ํฉ๋๋ค:
<div
className={cn(
'relative inline-block',
isCaptain ? sizeClasses.captain : sizeClasses[finalSize],
)}
>
<button
type="button"
+ aria-label={isCaptain ? "์บกํด ํ๋กํ" : "ํ๋กํ"}
className={cn(
'relative overflow-hidden rounded-full',
isCaptain ? sizeClasses.captain : sizeClasses[finalSize],
!editable && 'pointer-events-none',
)}๐ 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.
| <div | |
| className={cn( | |
| 'relative inline-block', | |
| isCaptain ? sizeClasses.captain : sizeClasses[finalSize], | |
| )} | |
| > | |
| <button | |
| type="button" | |
| className={`relative ${sizeClasses[finalSize]} overflow-hidden rounded-full`} | |
| className={cn( | |
| 'relative overflow-hidden rounded-full', | |
| isCaptain ? sizeClasses.captain : sizeClasses[finalSize], | |
| !editable && 'pointer-events-none', | |
| )} | |
| <div | |
| className={cn( | |
| 'relative inline-block', | |
| isCaptain ? sizeClasses.captain : sizeClasses[finalSize], | |
| )} | |
| > | |
| <button | |
| type="button" | |
| aria-label={isCaptain ? "์บกํด ํ๋กํ" : "ํ๋กํ"} | |
| className={cn( | |
| 'relative overflow-hidden rounded-full', | |
| isCaptain ? sizeClasses.captain : sizeClasses[finalSize], | |
| !editable && 'pointer-events-none', | |
| )} |
| // captain๊ณผ members ๋ถ๋ฆฌ | ||
| const captain = crewMembers.find((member) => member.captain) as CrewDetailMember; | ||
| const members = crewMembers.filter((member) => !member.captain); |
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.
captain ๋ณ์์ ํ์ ๋จ์ธ ์ฌ์ฉ์ ๋ํ ์์ ์ฑ ๊ฒํ ๊ฐ ํ์ํฉ๋๋ค.
as CrewDetailMember ํ์
๋จ์ธ์ ์ํํ ์ ์์ต๋๋ค. captain์ด ์กด์ฌํ์ง ์์ ๊ฒฝ์ฐ๋ฅผ ๋๋นํด์ผ ํฉ๋๋ค.
๋ค์๊ณผ ๊ฐ์ด ์์ ํ๋ ๊ฒ์ ์ ์ํฉ๋๋ค:
-const captain = crewMembers.find((member) => member.captain) as CrewDetailMember;
+const captain = crewMembers.find((member) => member.captain);
+if (!captain) {
+ throw new Error('ํฌ๋ฃจ์ฅ์ด ์กด์ฌํ์ง ์์ต๋๋ค.');
+}๐ 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.
| // captain๊ณผ members ๋ถ๋ฆฌ | |
| const captain = crewMembers.find((member) => member.captain) as CrewDetailMember; | |
| const members = crewMembers.filter((member) => !member.captain); | |
| // captain๊ณผ members ๋ถ๋ฆฌ | |
| const captain = crewMembers.find((member) => member.captain); | |
| if (!captain) { | |
| throw new Error('ํฌ๋ฃจ์ฅ์ด ์กด์ฌํ์ง ์์ต๋๋ค.'); | |
| } | |
| const members = crewMembers.filter((member) => !member.captain); |
| if (fetchError) { | ||
| if (fetchError instanceof ApiError) { | ||
| try { | ||
| const errorData = JSON.parse(fetchError.message); | ||
|
|
||
| if (errorData.status === 'NOT_FOUND') { | ||
| return <p>ํฌ๋ฃจ ์ ๋ณด๋ฅผ ์ฐพ์ ์ ์์ต๋๋ค</p>; | ||
| } | ||
| } catch (parseError) { | ||
| return <p>{`Error ${fetchError.status}: ${fetchError.message}`}</p>; | ||
| } | ||
| } | ||
| return <p>๋ฐ์ดํฐ ํต์ ์ ์คํจํ์ต๋๋ค.</p>; | ||
| } |
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
์๋ฌ ์ฒ๋ฆฌ ๋ก์ง ๊ฐ์ ์ผ๋ก ์์ ์ฑ ํฅ์
fetchError.message๋ฅผ JSON์ผ๋ก ํ์ฑํ์ฌ ์๋ฌ๋ฅผ ์ฒ๋ฆฌํ๊ณ ์์ต๋๋ค(115๋ฒ ๋ผ์ธ). ๊ทธ๋ฌ๋ message ์์ฑ์ด ํญ์ JSON ํ์์ ๋ณด์ฅํ์ง ์์ผ๋ฏ๋ก, ์๋ฌ ์ฒ๋ฆฌ ๋ก์ง์ ๊ฐ์ ํ ํ์๊ฐ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด, fetchError ๊ฐ์ฒด์ ์๋ต ๋ฐ์ดํฐ๊ฐ ํฌํจ๋์ด ์๋ค๋ฉด ํด๋น ๋ฐ์ดํฐ๋ฅผ ์ง์ ์ฌ์ฉํ๊ฑฐ๋, ์๋ฒ ์ธก์์ ์ผ๊ด๋ ์๋ฌ ์๋ต ๊ตฌ์กฐ๋ฅผ ์ ๊ณตํ๋๋ก ์์ฒญํ๋ ๊ฒ์ด ์ข์ต๋๋ค.
| const handleLeaveCrew = async () => { | ||
| try { | ||
| await leaveCrew(id); | ||
| toast.success('ํฌ๋ฃจ๋ฅผ ํํดํ์์ต๋๋ค๐'); | ||
| await refetch(); | ||
| } catch (leaveError) { | ||
| if (leaveError instanceof ApiError) { | ||
| toast.error(leaveError.message); | ||
| } else { | ||
| toast.error('๐ซ ํฌ๋ฃจ ํํด ์ค ์๋ฌ๊ฐ ๋ฐ์ํ์ต๋๋ค.'); | ||
| } | ||
| } | ||
| }; |
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.
ํฌ๋ฃจ ํํด ํ isMember ์ํ ์
๋ฐ์ดํธ ํ์
handleLeaveCrew ํจ์์์ ํฌ๋ฃจ๋ฅผ ํํดํ ํ์๋ isMember ์ํ๊ฐ ๋ณ๊ฒฝ๋์ง ์์ ์ฌ์ฉ์ ์ธํฐํ์ด์ค์ ์ผ๊ด๋์ง ์์ ์ ๋ณด๊ฐ ํ์๋ ์ ์์ต๋๋ค. ์ฑ๊ณต์ ์ผ๋ก ํํดํ ๊ฒฝ์ฐ setIsMember(false)๋ฅผ ํธ์ถํ์ฌ ์ํ๋ฅผ ์ ํํ๊ฒ ๋ฐ์ํด์ฃผ์ธ์.
์์ ์ฌํญ:
await leaveCrew(id);
toast.success('ํฌ๋ฃจ๋ฅผ ํํดํ์์ต๋๋ค๐');
+ setIsMember(false);
await refetch();๐ 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.
| const handleLeaveCrew = async () => { | |
| try { | |
| await leaveCrew(id); | |
| toast.success('ํฌ๋ฃจ๋ฅผ ํํดํ์์ต๋๋ค๐'); | |
| await refetch(); | |
| } catch (leaveError) { | |
| if (leaveError instanceof ApiError) { | |
| toast.error(leaveError.message); | |
| } else { | |
| toast.error('๐ซ ํฌ๋ฃจ ํํด ์ค ์๋ฌ๊ฐ ๋ฐ์ํ์ต๋๋ค.'); | |
| } | |
| } | |
| }; | |
| const handleLeaveCrew = async () => { | |
| try { | |
| await leaveCrew(id); | |
| toast.success('ํฌ๋ฃจ๋ฅผ ํํดํ์์ต๋๋ค๐'); | |
| setIsMember(false); | |
| await refetch(); | |
| } catch (leaveError) { | |
| if (leaveError instanceof ApiError) { | |
| toast.error(leaveError.message); | |
| } else { | |
| toast.error('๐ซ ํฌ๋ฃจ ํํด ์ค ์๋ฌ๊ฐ ๋ฐ์ํ์ต๋๋ค.'); | |
| } | |
| } | |
| }; |
yulrang
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.
๋์์ธ์ด ์์ฒญ ๋ฐ๋์์ด์!!~
์๊ณ ๋ง์ผ์
จ์ต๋๋ค~~~
minkyung5x5
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.
์๊ณ ํ์ จ์ต๋๋ค!!!! ๐
|
๐storybook: https://67206cc6ff9d7a05a3528ff8-epayxibmzm.chromatic.com/ |
|
๐storybook: https://67206cc6ff9d7a05a3528ff8-dinmagodbe.chromatic.com/ |
๐ Issue Ticket
#127
โ๏ธ Description
โ Checklist
PR
Test
Summary by CodeRabbit
New Features
Bug Fixes
Documentation
Chores