-
Notifications
You must be signed in to change notification settings - Fork 3
Feat/CR-63/ReviewingModal #68
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
|
๐storybook: https://67206cc6ff9d7a05a3528ff8-orqemtpjli.chromatic.com/ |
ca771d0 to
df0f555
Compare
|
๐storybook: https://67206cc6ff9d7a05a3528ff8-euuqppzhtg.chromatic.com/ |
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.
import Button from '@/src/components/common/input/button';
์ผ๋ก ๊ณ ์น๋ฉด ๋ ๊ฒ๊ฐ์์ฌ
Walkthrough์ด๋ฒ ๋ณ๊ฒฝ ์ฌํญ์์๋ ์๋ก์ด React ์ปดํฌ๋ํธ์ธ Changes
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 (
|
|
๐storybook: https://67206cc6ff9d7a05a3528ff8-caundczvat.chromatic.com/ |
|
๐storybook: https://67206cc6ff9d7a05a3528ff8-igigyzujwa.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: 4
๐งน Outside diff range and nitpick comments (9)
src/components/my-page/reviewing-modal/reviewing-modal.tsx (2)
7-10: ์ธํฐํ์ด์ค์ JSDoc ๋ฌธ์๋ฅผ ์ถ๊ฐํ๋ฉด ์ข์ ๊ฒ ๊ฐ์ต๋๋ค.props์ ๋ชฉ์ ๊ณผ ์ฌ์ฉ๋ฒ์ ๋ ๋ช ํํ๊ฒ ์ดํดํ ์ ์๋๋ก JSDoc ๋ฌธ์๋ฅผ ์ถ๊ฐํ๋ ๊ฒ์ ์ ์๋๋ฆฝ๋๋ค.
๋ค์๊ณผ ๊ฐ์ด ๋ฌธ์๋ฅผ ์ถ๊ฐํด๋ณด์ธ์:
+/** + * ๋ฆฌ๋ทฐ ์์ฑ ๋ชจ๋ฌ ์ปดํฌ๋ํธ์ props ์ธํฐํ์ด์ค + */ export interface ReviewingModalProps { + /** ๋ชจ๋ฌ์ ํ์ ์ฌ๋ถ๋ฅผ ์ ์ดํ๋ ์ํ ๊ฐ */ opened: boolean; + /** ๋ชจ๋ฌ์ ๋ซ๋ ํธ๋ค๋ฌ ํจ์ */ close: () => void; }
12-36: ์ฝ๋ ํ์ง ๊ฐ์ ์ ์ํ ์ ์์ฌํญ์ด ์์ต๋๋ค.
- ํ๋์ฝ๋ฉ๋ ๋ฌธ์์ด๊ณผ ์คํ์ผ ๊ฐ๋ค์ ์์๋ก ๋ถ๋ฆฌํ๋ฉด ์ ์ง๋ณด์๊ฐ ๋ ์ฉ์ดํด์ง ๊ฒ ๊ฐ์ต๋๋ค.
- close ํจ์ ํธ์ถ ์ ์๋ฌ ์ฒ๋ฆฌ๋ฅผ ์ถ๊ฐํ๋ฉด ์ข์ ๊ฒ ๊ฐ์ต๋๋ค.
๋ค์๊ณผ ๊ฐ์ด ๊ฐ์ ํด๋ณด์ธ์:
+const MODAL_CONSTANTS = { + TITLE: '๋ฆฌ๋ทฐ ์ฐ๊ธฐ', + PADDING: 24, + RADIUS: 12, + OVERLAY_OPACITY: 0.5, + TITLE_FONT_SIZE: '1.125rem', +} as const; export default function ReviewingModal({ opened, close }: ReviewingModalProps) { + const handleClose = () => { + try { + close(); + } catch (error) { + console.error('๋ชจ๋ฌ ๋ซ๊ธฐ ์ค ์ค๋ฅ ๋ฐ์:', error); + } + }; + return ( <Modal opened={opened} centered - title="๋ฆฌ๋ทฐ ์ฐ๊ธฐ" - onClose={close} + title={MODAL_CONSTANTS.TITLE} + onClose={handleClose} size="auto" - padding={24} - radius={12} - overlayProps={{ backgroundOpacity: 0.5 }} + padding={MODAL_CONSTANTS.PADDING} + radius={MODAL_CONSTANTS.RADIUS} + overlayProps={{ backgroundOpacity: MODAL_CONSTANTS.OVERLAY_OPACITY }} styles={{ title: { fontWeight: 600, - fontSize: '1.125rem', + fontSize: MODAL_CONSTANTS.TITLE_FONT_SIZE, }, body: { fontFamily: 'var(--font-pretendard)', }, }} > - <ReviewForm onCancel={close} /> + <ReviewForm onCancel={handleClose} /> </Modal> ); }src/components/my-page/reviewing-modal/reviewing-modal.stories.tsx (3)
7-13: ์คํ ๋ฆฌ๋ถ ๋ฉํ๋ฐ์ดํฐ ๊ฐ์ ์ ์ํ์ฌ ๊ตฌ์ฑ์ ์ข์ง๋ง, ๋ค์๊ณผ ๊ฐ์ ๊ฐ์ ์ฌํญ์ ๊ณ ๋ คํด๋ณด์ธ์:
const meta: Meta<typeof ReviewingModal> = { title: 'Modal/ReviewingModal', component: ReviewingModal, - argTypes: { opened: { control: 'boolean' } }, + argTypes: { + opened: { control: 'boolean', description: '๋ชจ๋ฌ์ ํ์ ์ฌ๋ถ๋ฅผ ์ ์ดํฉ๋๋ค' }, + close: { description: '๋ชจ๋ฌ ๋ซ๊ธฐ ํธ๋ค๋ฌ ํจ์' } + }, + parameters: { + docs: { + description: { + component: '์ฌ์ฉ์ ๋ฆฌ๋ทฐ๋ฅผ ์ ๋ ฅ๋ฐ๊ธฐ ์ํ ๋ชจ๋ฌ ์ปดํฌ๋ํธ์ ๋๋ค.' + } + } + } };
14-39: ํ ํ๋ฆฟ ์ปดํฌ๋ํธ ๊ฐ์ ์ ์ํ์ฌ ๊ตฌํ์ ์ ๋์ด ์์ง๋ง, ๋ค์๊ณผ ๊ฐ์ ๊ฐ์ ์ฌํญ์ ๊ณ ๋ คํด๋ณด์ธ์:
const Template: StoryFn<ReviewingModalProps> = function GatheringDetailModalStory({ opened, }: ReviewingModalProps) { const [isOpened, setIsOpened] = useState(opened); + const [isLoading, setIsLoading] = useState(false); const handleOpen = () => { action('Modal Opened')(); setIsOpened(true); }; const handleClose = () => { action('Modal Closed')(); setIsOpened(false); }; useEffect(() => { setIsOpened(opened); }, [opened]); return ( - <> + <ErrorBoundary fallback={<div>์๋ฌ๊ฐ ๋ฐ์ํ์ต๋๋ค</div>}> <Button onClick={handleOpen}>Open Modal</Button> - <ReviewingModal opened={isOpened} close={handleClose} /> - </> + <ReviewingModal + opened={isOpened} + close={handleClose} + isLoading={isLoading} + /> + </ErrorBoundary> ); };
41-41: ๊ธฐ๋ณธ ์คํ ๋ฆฌ์ ์ด๊ธฐ๊ฐ ์ถ๊ฐ ์ ์์คํ ๋ฆฌ์ ์ด๊ธฐ ์ํ๋ฅผ ๋ ๋ช ํํ๊ฒ ๋ณด์ฌ์ฃผ๊ธฐ ์ํด args๋ฅผ ์ถ๊ฐํ๋ ๊ฒ์ด ์ข์ต๋๋ค.
export const Default = Template.bind({}); +Default.args = { + opened: false +};src/components/my-page/reviewing-modal/button-hearts.tsx (2)
6-8: ์ธํฐํ์ด์ค ๋ฌธ์ํ ๋ฐ ํ์ ์ ํ ๊ฐ์ ํ์Props ์ธํฐํ์ด์ค์ ๋ค์๊ณผ ๊ฐ์ ๊ฐ์ ์ฌํญ์ ์ ์ํฉ๋๋ค:
- JSDoc ์ฃผ์์ ์ถ๊ฐํ์ฌ ์ปดํฌ๋ํธ์ ์ฉ๋์ ์ฌ์ฉ๋ฒ์ ๋ช ํํ ์ค๋ช
- score ํ์ ์ 1-5 ๋ฒ์๋ก ์ ํํ์ฌ ํ์ ์์ ์ฑ ๊ฐํ
+/** + * ํํธ ๋ฒํผ์ ํตํด 1-5์ ์ฌ์ด์ ์ ์๋ฅผ ์ ํํ ์ ์๋ ์ปดํฌ๋ํธ์ ๋๋ค. + */ interface ButtonHeartsProps { + /** ์ ํ๋ ์ ์(1-5)๋ฅผ ์ฒ๋ฆฌํ๋ ์ฝ๋ฐฑ ํจ์ */ - onChange: (score: number) => void; + onChange: (score: 1 | 2 | 3 | 4 | 5) => void; }
10-11: ์ํ ๊ด๋ฆฌ ๊ฐ๋ ์ฑ ๊ฐ์ ์ ์์ํ ๊ด๋ฆฌ์ ๊ฐ๋ ์ฑ์ ๋์ด๊ธฐ ์ํ ๊ฐ์ ์ฌํญ์ ์ ์ํฉ๋๋ค:
- ์ํ ๋ณ์๋ช ์ ๋ ๋ช ํํ๊ฒ ๋ณ๊ฒฝ (์:
selectedHearts)- ์ด๊ธฐ ์ํ๋ฅผ ์์๋ก ๋ถ๋ฆฌ
+const INITIAL_HEARTS_STATE = Array(5).fill(false); + export default function ButtonHearts({ onChange }: ButtonHeartsProps) { - const [clickedArray, setClickedArray] = useState<boolean[]>(Array(5).fill(false)); + const [selectedHearts, setSelectedHearts] = useState<boolean[]>(INITIAL_HEARTS_STATE);src/components/my-page/reviewing-modal/review-form.tsx (2)
7-14: ํ์ ์ ์์ ์ ํจ์ฑ ๊ฒ์ฌ ์ ์ฝ ์กฐ๊ฑด ์ถ๊ฐ ํ์FormValues ํ์ ์ ๋ค์๊ณผ ๊ฐ์ ์ ์ฝ ์กฐ๊ฑด์ ์ถ๊ฐํ๋ฉด ์ข์ ๊ฒ ๊ฐ์ต๋๋ค:
- reviewText์ ์ต์/์ต๋ ๊ธธ์ด
- score์ ์ ํจํ ๋ฒ์ (์: 1-5)
type FormValues = { - reviewText: string; - score: number; + reviewText: string & { minLength: 10; maxLength: 500 }; + score: number & { min: 1; max: 5 }; };
21-30: API ์ฐ๋ ๊ตฌํ ํ์TODO ์ฃผ์์ ์ธ๊ธ๋ API ์ฐ๋์ด ๊ตฌํ๋์ด ์์ง ์์ต๋๋ค. Swagger ๋ฌธ์๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ๋ค์ ์์ ์ด ํ์ํฉ๋๋ค:
- API ํธ์ถ ํจ์ ๊ตฌํ
- ์๋ฌ ์ฒ๋ฆฌ
- ๋ก๋ฉ ์ํ ๊ด๋ฆฌ
API ์ฐ๋ ๊ตฌํ์ ๋์์ด ํ์ํ์๋ค๋ฉด ์ ๊ฐ ๋์๋๋ฆด ์ ์์ต๋๋ค. GitHub ์ด์๋ฅผ ์์ฑํด๋๋ฆด๊น์?
๐ Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
๐ Files selected for processing (4)
src/components/my-page/reviewing-modal/button-hearts.tsx(1 hunks)src/components/my-page/reviewing-modal/review-form.tsx(1 hunks)src/components/my-page/reviewing-modal/reviewing-modal.stories.tsx(1 hunks)src/components/my-page/reviewing-modal/reviewing-modal.tsx(1 hunks)
๐ Additional comments (2)
src/components/my-page/reviewing-modal/reviewing-modal.tsx (1)
1-6: ์ฝ๋๊ฐ ๊น๋ํ๊ณ ํ์ํ import๋ค์ด ์ ๊ตฌ์ฑ๋์ด ์์ต๋๋ค!
ํด๋ผ์ด์ธํธ ์ฌ์ด๋ ๋ ๋๋ง์ ์ํ 'use client' ์ง์๋ฌธ๊ณผ ํ์ํ ์์กด์ฑ๋ค์ด ์ ์ ํ๊ฒ import ๋์ด ์์ต๋๋ค.
src/components/my-page/reviewing-modal/reviewing-modal.stories.tsx (1)
1-6: ์ํฌํธ ๊ตฌ๋ฌธ์ด ์ ๊ตฌ์ฑ๋์ด ์์ต๋๋ค!
ํ์ํ ๋ชจ๋ ์์กด์ฑ์ด ๋ ผ๋ฆฌ์ ์ธ ์์๋ก ์ ์ํฌํธ๋์ด ์์ต๋๋ค.
| const handleClick = (index: number) => { | ||
| setClickedArray((prev) => prev.map((_, i) => i <= index)); | ||
| onChange(index + 1); | ||
| }; |
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
์ด๋ฒคํธ ํธ๋ค๋ฌ ๊ฐ์ ํ์
์ด๋ฒคํธ ํธ๋ค๋ฌ์ ์์ ์ฑ๊ณผ ๊ฐ๋ ์ฑ์ ๋์ด๊ธฐ ์ํ ๊ฐ์ ์ฌํญ์ ์ ์ํฉ๋๋ค:
- ์ ์ ๊ณ์ฐ ๋ก์ง์ ๋ช ํํ๊ฒ ๋ถ๋ฆฌ
- ํ์ ์์ ์ฑ ๊ฐํ
+const calculateScore = (index: number): 1 | 2 | 3 | 4 | 5 => {
+ return (index + 1) as 1 | 2 | 3 | 4 | 5;
+};
+
- const handleClick = (index: number) => {
+ const handleClick = (index: 0 | 1 | 2 | 3 | 4) => {
setClickedArray((prev) => prev.map((_, i) => i <= index));
- onChange(index + 1);
+ onChange(calculateScore(index));
};๐ 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 handleClick = (index: number) => { | |
| setClickedArray((prev) => prev.map((_, i) => i <= index)); | |
| onChange(index + 1); | |
| }; | |
| const calculateScore = (index: number): 1 | 2 | 3 | 4 | 5 => { | |
| return (index + 1) as 1 | 2 | 3 | 4 | 5; | |
| }; | |
| const handleClick = (index: 0 | 1 | 2 | 3 | 4) => { | |
| setClickedArray((prev) => prev.map((_, i) => i <= index)); | |
| onChange(calculateScore(index)); | |
| }; |
| return ( | ||
| <div className="flex w-full flex-col items-start justify-between gap-[12px]"> | ||
| <p className="font-base font-semibold">๋ง์กฑ์ค๋ฌ์ด ๊ฒฝํ์ด์๋์?</p> | ||
| <div> | ||
| {Array.from({ length: 5 }).map((_, index) => ( | ||
| <button type="button" onClick={() => handleClick(index)} key={`btn ${index + 1}`}> | ||
| <Image | ||
| src={clickedArray[index] ? activeHeart : defaultHeart} | ||
| width={24} | ||
| height={24} | ||
| alt="heartbtn" | ||
| /> | ||
| </button> | ||
| ))} | ||
| </div> | ||
| </div> | ||
| ); |
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
์ ๊ทผ์ฑ ๊ฐ์ ํ์
์น ์ ๊ทผ์ฑ ํฅ์์ ์ํ ๊ฐ์ ์ฌํญ์ ์ ์ํฉ๋๋ค:
- aria-label ์ถ๊ฐ
- ๋ ๋ช ํํ ์ด๋ฏธ์ง ๋์ฒด ํ ์คํธ
- ํ์ฌ ์ ํ๋ ์ ์ ์ํ ์์ฑ ์๋ด
<div className="flex w-full flex-col items-start justify-between gap-[12px]">
- <p className="font-base font-semibold">๋ง์กฑ์ค๋ฌ์ด ๊ฒฝํ์ด์๋์?</p>
+ <p className="font-base font-semibold" id="rating-description">๋ง์กฑ์ค๋ฌ์ด ๊ฒฝํ์ด์๋์?</p>
<div>
{Array.from({ length: 5 }).map((_, index) => (
<button
type="button"
onClick={() => handleClick(index)}
key={`btn ${index + 1}`}
+ aria-label={`${index + 1}์ ์ ํ`}
+ aria-pressed={clickedArray[index]}
+ aria-describedby="rating-description"
>
<Image
src={clickedArray[index] ? activeHeart : defaultHeart}
width={24}
height={24}
- alt="heartbtn"
+ alt={clickedArray[index] ? '์ฑ์์ง ํํธ' : '๋น ํํธ'}
/>
</button>
))}
</div>
</div>๐ 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.
| return ( | |
| <div className="flex w-full flex-col items-start justify-between gap-[12px]"> | |
| <p className="font-base font-semibold">๋ง์กฑ์ค๋ฌ์ด ๊ฒฝํ์ด์๋์?</p> | |
| <div> | |
| {Array.from({ length: 5 }).map((_, index) => ( | |
| <button type="button" onClick={() => handleClick(index)} key={`btn ${index + 1}`}> | |
| <Image | |
| src={clickedArray[index] ? activeHeart : defaultHeart} | |
| width={24} | |
| height={24} | |
| alt="heartbtn" | |
| /> | |
| </button> | |
| ))} | |
| </div> | |
| </div> | |
| ); | |
| return ( | |
| <div className="flex w-full flex-col items-start justify-between gap-[12px]"> | |
| <p className="font-base font-semibold" id="rating-description">๋ง์กฑ์ค๋ฌ์ด ๊ฒฝํ์ด์๋์?</p> | |
| <div> | |
| {Array.from({ length: 5 }).map((_, index) => ( | |
| <button | |
| type="button" | |
| onClick={() => handleClick(index)} | |
| key={`btn ${index + 1}`} | |
| aria-label={`${index + 1}์ ์ ํ`} | |
| aria-pressed={clickedArray[index]} | |
| aria-describedby="rating-description" | |
| > | |
| <Image | |
| src={clickedArray[index] ? activeHeart : defaultHeart} | |
| width={24} | |
| height={24} | |
| alt={clickedArray[index] ? '์ฑ์์ง ํํธ' : '๋น ํํธ'} | |
| /> | |
| </button> | |
| ))} | |
| </div> | |
| </div> | |
| ); |
| export default function ReviewForm({ onCancel }: ReviewProps) { | ||
| const { register, handleSubmit } = useForm<FormValues>(); | ||
| const [textReview, setTextReview] = useState<string>(''); | ||
| const [point, setPoint] = useState<number>(0); | ||
|
|
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
ํผ ์ด๊ธฐํ ๋ฐ ์ ํจ์ฑ ๊ฒ์ฌ ์ค์ ๊ฐ์ ํ์
useForm ํ ์ ๊ธฐ๋ณธ ์ต์ ์ด ์ค์ ๋์ด ์์ง ์์ต๋๋ค. ๋ค์ ์ฌํญ๋ค์ ์ถ๊ฐํ๋ฉด ์ข์ ๊ฒ ๊ฐ์ต๋๋ค:
- defaultValues ์ค์
- mode ์ค์ (์: onChange)
- ํ์ ํ๋ ์ ํจ์ฑ ๊ฒ์ฌ
- const { register, handleSubmit } = useForm<FormValues>();
+ const { register, handleSubmit } = useForm<FormValues>({
+ defaultValues: {
+ reviewText: '',
+ score: 0
+ },
+ mode: 'onChange'
+ });Committable suggestion skipped: line range outside the PR's diff.
| return ( | ||
| <form className="flex h-[308px] w-[472px] flex-col justify-between gap-[24px]"> | ||
| <ButtonHearts onChange={handleScoreChange} /> | ||
| <Textarea | ||
| placeholder="๋จ๊ฒจ์ฃผ์ ๋ฆฌ๋ทฐ๋ ํ๋ก๊ทธ๋จ ์ด์ ๋ฐ ๋ค๋ฅธ ํ์ ๋ถ๋ค๊ป ํฐ ๋์์ด ๋ฉ๋๋ค." | ||
| inputClassNames="w-[471px] h-[120px] bg-gray-50 text-gray-400" | ||
| value={textReview} | ||
| onChange={handleTextChange} | ||
| register={register('reviewText')} | ||
| label="๊ฒฝํ์ ๋ํด ๋จ๊ฒจ์ฃผ์ธ์" | ||
| styles={{ | ||
| input: { | ||
| '::placeholder': { | ||
| color: 'gray - 400', | ||
| fontWeight: 500, | ||
| fontSize: '1rem', | ||
| }, | ||
| }, | ||
| label: { | ||
| fontWeight: 600, | ||
| fontSize: '1rem', | ||
| }, | ||
| }} | ||
| /> | ||
| <input type="hidden" value={point} {...register('score')} /> | ||
| <div className="font-base flex justify-between gap-[16px] font-semibold"> | ||
| <Button | ||
| onClick={onCancel} | ||
| className="h-[44px] w-[228px] border border-blue-500 bg-white text-blue-500" | ||
| > | ||
| ์ทจ์ | ||
| </Button> | ||
| <Button type="submit" className="h-[44px] w-[228px] border-none bg-blue-500 text-white"> | ||
| ๋ฆฌ๋ทฐ ๋ฑ๋ก | ||
| </Button> | ||
| </div> | ||
| </form> | ||
| ); |
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
์ ๊ทผ์ฑ ๋ฐ ์คํ์ผ๋ง ๊ฐ์ ํ์
๋ค์ ์ฌํญ๋ค์ ๊ฐ์ ํ๋ฉด ์ข์ ๊ฒ ๊ฐ์ต๋๋ค:
- ์ ๊ทผ์ฑ:
- form์ aria-label ์ถ๊ฐ
- ๋ฒํผ์ aria-label ์ถ๊ฐ
- ์๋ฌ ๋ฉ์์ง ํ์ ์์ญ ์ถ๊ฐ
- ์คํ์ผ๋ง:
- gray - 400์ ์๋ ๋ถํ์ํ ๊ณต๋ฐฑ ์ ๊ฑฐ
- ๋งค์ง ๋๋ฒ(ํฌ๊ธฐ๊ฐ) ์์๋ก ๋ถ๋ฆฌ
- <form className="flex h-[308px] w-[472px] flex-col justify-between gap-[24px]">
+ <form
+ className="flex h-[308px] w-[472px] flex-col justify-between gap-[24px]"
+ aria-label="๋ฆฌ๋ทฐ ์์ฑ ํผ"
+ >- color: 'gray - 400',
+ color: 'gray-400',Committable suggestion skipped: line range outside the PR's diff.
๐ Issue Ticket
Ticket
โ๏ธ Description
๋ฆฌ๋ทฐ ์์ฑ ๋ชจ๋ฌ์์ ํผ ์ปดํฌ๋ํธ์ api ๊ด๋ จ ํจ์๋ swagger ๋ฐ๊ณ ์ด์ฐจํผ ๋ค์ ํด์ผํ ๊ฒ ๊ฐ์ ์ฃผ์ ์ฒ๋ฆฌํด๋ ๊ฒ๋ ์ญ์ ํด๋์ต๋๋ค
โ Checklist
PR
Test
Summary by CodeRabbit
์๋ก์ด ๊ธฐ๋ฅ
ReviewForm์ปดํฌ๋ํธ ์ถ๊ฐ.ButtonHearts์ปดํฌ๋ํธ ์ถ๊ฐ.ReviewingModal์ปดํฌ๋ํธ ์ถ๊ฐ.๋ฌธ์ํ
ReviewingModal์ปดํฌ๋ํธ์ ๋ํ Storybook ์คํ ๋ฆฌ ์ถ๊ฐ.