From a894d66641119f922e44572618c2d180a6868482 Mon Sep 17 00:00:00 2001 From: aquaman122 Date: Mon, 16 Dec 2024 15:51:16 +0900 Subject: [PATCH 1/3] =?UTF-8?q?refactoring:=20profileEdit=20=ED=8E=98?= =?UTF-8?q?=EC=9D=B4=EC=A7=80=20=EC=BD=94=EB=93=9C=20hooks=EB=A1=9C=20?= =?UTF-8?q?=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../user/hooks/useNicknameValidate.ts | 66 +++++++++++++++++++ src/pages/user/ui/UserProfileEdit.tsx | 56 ++-------------- src/shared/utils/updateProfileEditState.ts | 22 +++++++ 3 files changed, 93 insertions(+), 51 deletions(-) create mode 100644 src/features/user/hooks/useNicknameValidate.ts create mode 100644 src/shared/utils/updateProfileEditState.ts diff --git a/src/features/user/hooks/useNicknameValidate.ts b/src/features/user/hooks/useNicknameValidate.ts new file mode 100644 index 00000000..246e3c54 --- /dev/null +++ b/src/features/user/hooks/useNicknameValidate.ts @@ -0,0 +1,66 @@ +import { useDispatch } from 'react-redux'; +import { useEffect } from 'react'; +import { + setNicknameError, + setIsNicknameChecked, + setIsSubmitEnabled, + setIsNicknameCheckDisabled +} from '@/entities/user/model/profileEditSlice'; +import { useCheckNickname } from '@/features/profile/model'; + +interface UseNicknameProps { + nickname: string; + originalNickname: string; +} + +export const useNicknameValidate = ({ nickname, originalNickname }: UseNicknameProps) => { + const dispatch = useDispatch(); + const { checkNickname } = useCheckNickname({ nickname }); + + const handleNicknameValidation = (isAvailable: boolean) => { + if (!nickname || nickname === '') { + dispatch(setNicknameError('닉네임을 입력해주세요.')); + dispatch(setIsNicknameChecked(false)); + dispatch(setIsSubmitEnabled(false)); + } else if (isAvailable) { + dispatch(setNicknameError('사용 가능한 닉네임입니다.')); + dispatch(setIsNicknameChecked(true)); + dispatch(setIsSubmitEnabled(true)); + } else { + dispatch(setNicknameError('이미 사용중인 닉네임입니다. 다른 닉네임을 입력해주세요.')); + dispatch(setIsNicknameChecked(false)); + dispatch(setIsSubmitEnabled(false)); + } + }; + + const checkNicknameAvailability = async () => { + if (nickname === originalNickname) { + dispatch(setNicknameError('기존 닉네임입니다. 사용가능합니다.')); + dispatch(setIsNicknameChecked(true)); + dispatch(setIsSubmitEnabled(true)); + return; + } + + const { data } = await checkNickname(); + handleNicknameValidation(data.isAvailable); + }; + + useEffect(() => { + if (nickname.length > 15) { + dispatch(setNicknameError('닉네임은 15자 미만으로 입력해주세요.')); + dispatch(setIsSubmitEnabled(false)); + dispatch(setIsNicknameChecked(false)); + dispatch(setIsNicknameCheckDisabled(true)); + } else { + dispatch(setNicknameError('')); + dispatch(setIsNicknameCheckDisabled(false)); + if (nickname === originalNickname) { + dispatch(setIsSubmitEnabled(true)); + } else { + dispatch(setIsSubmitEnabled(false)); + } + } + }, [nickname, originalNickname, dispatch]); + + return { checkNicknameAvailability }; +}; \ No newline at end of file diff --git a/src/pages/user/ui/UserProfileEdit.tsx b/src/pages/user/ui/UserProfileEdit.tsx index e397ecf6..b36a03b0 100644 --- a/src/pages/user/ui/UserProfileEdit.tsx +++ b/src/pages/user/ui/UserProfileEdit.tsx @@ -1,4 +1,4 @@ -import { setIsNicknameCheckDisabled, setIsNicknameChecked, setIsSubmitEnabled, setNicknameError } from '@/entities/user/model/profileEditSlice'; +import { setNicknameError } from '@/entities/user/model/profileEditSlice'; import { Button, FormField } from '@/shared'; import { useEffect, useRef, useState } from 'react'; import { useDispatch, useSelector } from 'react-redux'; @@ -12,8 +12,9 @@ import NoticeBlue from '@/shared/assets/icons/blue_notice.svg'; import NoticeRed from '@/shared/assets/icons/notice_red.svg'; import { Input } from '@/shared/ui/input'; import { Textarea } from '@/shared/ui/textarea'; -import { uploadProfileImageToS3, useCheckNickname } from '@/features/profile/model'; +import { uploadProfileImageToS3 } from '@/features/profile/model'; import { getProfileImageURL } from '@/features/profile/api'; +import { useNicknameValidate } from '@/features/user/hooks/useNicknameValidate'; export const UserProfileEdit = () => { const formRef = useRef(null); @@ -26,35 +27,7 @@ export const UserProfileEdit = () => { const { nicknameError, isNicknameChecked, isSubmitEnabled, isNicknameCheckDisabled } = useSelector((state: RootState) => state.profileEdit); const nickname = watch('nickname')?.trim(); - const { checkNickname } = useCheckNickname({ nickname }); - - const handleNicknameValidation = (nickname: string, isAvailable: boolean) => { - if (!nickname || nickname === '') { - dispatch(setNicknameError('닉네임을 입력해주세요.')); - dispatch(setIsNicknameChecked(false)); - dispatch(setIsSubmitEnabled(false)); - } else if (isAvailable) { - dispatch(setNicknameError('사용 가능한 닉네임입니다.')); - dispatch(setIsNicknameChecked(true)); - dispatch(setIsSubmitEnabled(true)); - } else { - dispatch(setNicknameError('이미 사용중인 닉네임입니다. 다른 닉네임을 입력해주세요.')); - dispatch(setIsNicknameChecked(false)); - dispatch(setIsSubmitEnabled(false)); - } - }; - - const onNicknameCheck = async () => { - if (nickname === originalNickname) { - dispatch(setNicknameError('기존 닉네임입니다. 사용가능합니다.')); - dispatch(setIsNicknameChecked(true)); - dispatch(setIsSubmitEnabled(true)); - return; - } - - const { data } = await checkNickname(); - handleNicknameValidation(nickname, data.isAvailable); - }; + const { checkNicknameAvailability } = useNicknameValidate({ nickname, originalNickname }); const onSubmit = async (data: IUserProfile) => { const { nickname, bio } = data; @@ -86,8 +59,6 @@ export const UserProfileEdit = () => { handleEditProfile(formData); } else { dispatch(setNicknameError('닉네임 중복 확인을 해주세요.')); - dispatch(setIsNicknameChecked(false)); - dispatch(setIsSubmitEnabled(false)); } }; @@ -97,23 +68,6 @@ export const UserProfileEdit = () => { } }, [userProfileImageUrl]); - useEffect(() => { - if (nickname.length > 15) { - dispatch(setNicknameError('닉네임 15자 미만으로 입력해주세요.')); - dispatch(setIsSubmitEnabled(false)); - dispatch(setIsNicknameChecked(false)); - dispatch(setIsNicknameCheckDisabled(true)); - } else { - dispatch(setNicknameError('')); - dispatch(setIsNicknameCheckDisabled(false)); - if (nickname === originalNickname) { - dispatch(setIsSubmitEnabled(true)); - } else { - dispatch(setIsSubmitEnabled(false)); - } - } - }, [nickname]); - return ( @@ -148,7 +102,7 @@ export const UserProfileEdit = () => { />
- +
{nicknameError && ( diff --git a/src/shared/utils/updateProfileEditState.ts b/src/shared/utils/updateProfileEditState.ts new file mode 100644 index 00000000..3dca651e --- /dev/null +++ b/src/shared/utils/updateProfileEditState.ts @@ -0,0 +1,22 @@ +import { AppDispatch } from '@/app/store'; +import { + setNicknameError, + setIsNicknameChecked, + setIsSubmitEnabled, + setIsNicknameCheckDisabled, +} from '@/entities/user/model/profileEditSlice'; + +export const updateProfileEditState = ( + dispatch: AppDispatch, + updates: Partial<{ + nicknameError: string; + isNicknameChecked: boolean; + isSubmitEnabled: boolean; + isNicknameCheckDisabled: boolean; + }> +) => { + if ('nicknameError' in updates) dispatch(setNicknameError(updates.nicknameError || '')); + if ('isNicknameChecked' in updates) dispatch(setIsNicknameChecked(updates.isNicknameChecked || false)); + if ('isSubmitEnabled' in updates) dispatch(setIsSubmitEnabled(updates.isSubmitEnabled || false)); + if ('isNicknameCheckDisabled' in updates) dispatch(setIsNicknameCheckDisabled(updates.isNicknameCheckDisabled || false)); +}; \ No newline at end of file From a0a871d279a672274b98e2130c46269973f8afcc Mon Sep 17 00:00:00 2001 From: aquaman122 Date: Mon, 16 Dec 2024 16:50:23 +0900 Subject: [PATCH 2/3] =?UTF-8?q?refactoring:=20signup=ED=8E=98=EC=9D=B4?= =?UTF-8?q?=EC=A7=80=20hooks=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../hooks/useProfileNicknameValidate.ts} | 2 +- .../hooks/useSignupNicknameValidate.ts | 54 +++++++++++++++++++ src/features/sign-up/model/signupSlice.ts | 7 ++- src/pages/sign-up/ui/Signup.tsx | 52 +++--------------- src/pages/user/ui/UserProfileEdit.tsx | 4 +- 5 files changed, 71 insertions(+), 48 deletions(-) rename src/features/{user/hooks/useNicknameValidate.ts => profile/hooks/useProfileNicknameValidate.ts} (95%) create mode 100644 src/features/sign-up/hooks/useSignupNicknameValidate.ts diff --git a/src/features/user/hooks/useNicknameValidate.ts b/src/features/profile/hooks/useProfileNicknameValidate.ts similarity index 95% rename from src/features/user/hooks/useNicknameValidate.ts rename to src/features/profile/hooks/useProfileNicknameValidate.ts index 246e3c54..686d52ce 100644 --- a/src/features/user/hooks/useNicknameValidate.ts +++ b/src/features/profile/hooks/useProfileNicknameValidate.ts @@ -13,7 +13,7 @@ interface UseNicknameProps { originalNickname: string; } -export const useNicknameValidate = ({ nickname, originalNickname }: UseNicknameProps) => { +export const useProfileNicknameValidate = ({ nickname, originalNickname }: UseNicknameProps) => { const dispatch = useDispatch(); const { checkNickname } = useCheckNickname({ nickname }); diff --git a/src/features/sign-up/hooks/useSignupNicknameValidate.ts b/src/features/sign-up/hooks/useSignupNicknameValidate.ts new file mode 100644 index 00000000..c1c47993 --- /dev/null +++ b/src/features/sign-up/hooks/useSignupNicknameValidate.ts @@ -0,0 +1,54 @@ +import { useDispatch } from 'react-redux'; +import { useEffect } from 'react'; +import { setIsNameValid, setIsNicknameCheckDisabled, setIsNicknameChecked, setIsSubmitEnabled, setNicknameError } from '../model/signupSlice'; +import { useCheckNickname } from '@/features/profile/model'; + +interface UseNicknameProps { + nickname: string; +} + +export const useSignupNicknameValidate = ({ nickname }: UseNicknameProps) => { + const dispatch = useDispatch(); + const { checkNickname } = useCheckNickname({ nickname }); + + const handleNicknameValidation = (isAvailable: boolean) => { + if (!nickname || nickname === '') { + dispatch(setNicknameError('닉네임을 입력해주세요.')); + dispatch(setIsNicknameChecked(false)); + dispatch(setIsSubmitEnabled(false)); + dispatch(setIsNameValid(false)); + } else if (isAvailable) { + dispatch(setNicknameError('사용 가능한 닉네임입니다.')); + dispatch(setIsNicknameChecked(true)); + dispatch(setIsSubmitEnabled(true)); + dispatch(setIsNameValid(true)); + } else { + dispatch(setNicknameError('이미 사용중인 닉네임입니다. 다른 닉네임을 입력해주세요.')); + dispatch(setIsNicknameChecked(false)); + dispatch(setIsSubmitEnabled(false)); + dispatch(setIsNameValid(false)); + } + }; + + const checkNicknameAvailability = async () => { + const { data } = await checkNickname(); + handleNicknameValidation(data.isAvailable); + }; + + useEffect(() => { + if (nickname.length > 15) { + dispatch(setNicknameError('닉네임은 15자 미만으로 입력해주세요.')); + dispatch(setIsSubmitEnabled(false)); + dispatch(setIsNicknameChecked(false)); + dispatch(setIsNicknameCheckDisabled(true)); + dispatch(setIsNameValid(false)); + } else { + dispatch(setNicknameError('')); + dispatch(setIsNicknameCheckDisabled(false)); + dispatch(setIsSubmitEnabled(false)); + dispatch(setIsNameValid(false)); + } + }, [nickname, dispatch]); + + return { checkNicknameAvailability }; +}; \ No newline at end of file diff --git a/src/features/sign-up/model/signupSlice.ts b/src/features/sign-up/model/signupSlice.ts index 8110b22a..1556a9be 100644 --- a/src/features/sign-up/model/signupSlice.ts +++ b/src/features/sign-up/model/signupSlice.ts @@ -5,6 +5,7 @@ export interface SignupState { isNameValid: boolean; isNicknameChecked: boolean; isSubmitEnabled: boolean; + isNicknameCheckDisabled: boolean; } const initialState: SignupState = { @@ -12,6 +13,7 @@ const initialState: SignupState = { isNameValid: false, isNicknameChecked: false, isSubmitEnabled: false, + isNicknameCheckDisabled: false, }; export const signupSlice = createSlice({ @@ -30,8 +32,11 @@ export const signupSlice = createSlice({ setIsSubmitEnabled: (state, action: PayloadAction) => { state.isSubmitEnabled = action.payload; }, + setIsNicknameCheckDisabled: (state, action: PayloadAction) => { + state.isNicknameCheckDisabled = action.payload; + } }, }); -export const { setNicknameError, setIsNameValid, setIsNicknameChecked, setIsSubmitEnabled } = signupSlice.actions; +export const { setNicknameError, setIsNameValid, setIsNicknameChecked, setIsSubmitEnabled, setIsNicknameCheckDisabled } = signupSlice.actions; export default signupSlice.reducer; \ No newline at end of file diff --git a/src/pages/sign-up/ui/Signup.tsx b/src/pages/sign-up/ui/Signup.tsx index 8fb31ab3..4a82e79b 100644 --- a/src/pages/sign-up/ui/Signup.tsx +++ b/src/pages/sign-up/ui/Signup.tsx @@ -1,6 +1,6 @@ -import { setIsNameValid, setIsNicknameChecked, setIsSubmitEnabled, setNicknameError } from '@/features/sign-up/model/signupSlice'; +import { setNicknameError } from '@/features/sign-up/model/signupSlice'; import { Button, FormField } from '@/shared'; -import { KeyboardEvent, useEffect, useRef } from 'react'; +import { KeyboardEvent, useRef } from 'react'; import { useDispatch, useSelector } from 'react-redux'; import { Layout } from '@/app/layout/index'; @@ -12,17 +12,14 @@ import NoticeRed from '@/shared/assets/icons/notice_red.svg'; import { Input } from '@/shared/ui/input'; import { Textarea } from '@/shared/ui/textarea'; import { useNavigate } from 'react-router-dom'; -import { useCheckNickname } from '@/features/profile/model'; +import { useSignupNicknameValidate } from '@/features/sign-up/hooks/useSignupNicknameValidate'; export const Signup = () => { const dispatch = useDispatch(); const navigate = useNavigate(); const formRef = useRef(null); - const nicknameError = useSelector((state: RootState) => state.signup.nicknameError); - const isNameValid = useSelector((state: RootState) => state.signup.isNameValid); - const isNicknameChecked = useSelector((state: RootState) => state.signup.isNicknameChecked); - const isSubmitEnabled = useSelector((state: RootState) => state.signup.isSubmitEnabled); + const { nicknameError, isNameValid, isNicknameChecked, isSubmitEnabled, isNicknameCheckDisabled } = useSelector((state: RootState) => state.signup); const { control, @@ -33,41 +30,9 @@ export const Signup = () => { } = useSignup(); const formValues = watch(); const nickname = formValues.nickname?.trim() || ''; - const { checkNickname } = useCheckNickname({ nickname }); - - const validateNickname = () => { - if (nickname.length > 15) { - dispatch(setNicknameError('닉네임 15자 미만으로 입력해주세요.')); - dispatch(setIsNameValid(false)); - dispatch(setIsSubmitEnabled(false)); - return false; - } - dispatch(setNicknameError(null)); - dispatch(setIsNameValid(false)); - dispatch(setIsSubmitEnabled(false)); - return true; - }; - - useEffect(() => { - validateNickname(); - }, [nickname]); - - const onNicknameCheck = async () => { - if (!validateNickname()) return; - - if (!nickname) { - dispatch(setNicknameError('닉네임을 입력해주세요.')); - return; - } - - const { data } = await checkNickname(); - const { isAvailable } = data; - - dispatch(setNicknameError(isAvailable ? '사용 가능한 닉네임입니다.' : '이미 사용중인 닉네임입니다. 다른 닉네임을 입력해주세요.')); - dispatch(setIsNameValid(isAvailable)); - dispatch(setIsSubmitEnabled(isAvailable)); - dispatch(setIsNicknameChecked(isAvailable)); - }; + const { checkNicknameAvailability } = useSignupNicknameValidate({ + nickname, + }); const onSubmit = (data: IUser) => { if (!isNicknameChecked) { @@ -84,7 +49,6 @@ export const Signup = () => { } }; - return ( navigate('/')} /> @@ -115,7 +79,7 @@ export const Signup = () => { />
- +
{nicknameError && ( diff --git a/src/pages/user/ui/UserProfileEdit.tsx b/src/pages/user/ui/UserProfileEdit.tsx index b36a03b0..5f89686b 100644 --- a/src/pages/user/ui/UserProfileEdit.tsx +++ b/src/pages/user/ui/UserProfileEdit.tsx @@ -14,7 +14,7 @@ import { Input } from '@/shared/ui/input'; import { Textarea } from '@/shared/ui/textarea'; import { uploadProfileImageToS3 } from '@/features/profile/model'; import { getProfileImageURL } from '@/features/profile/api'; -import { useNicknameValidate } from '@/features/user/hooks/useNicknameValidate'; +import { useProfileNicknameValidate } from '@/features/profile/hooks/useProfileNicknameValidate'; export const UserProfileEdit = () => { const formRef = useRef(null); @@ -27,7 +27,7 @@ export const UserProfileEdit = () => { const { nicknameError, isNicknameChecked, isSubmitEnabled, isNicknameCheckDisabled } = useSelector((state: RootState) => state.profileEdit); const nickname = watch('nickname')?.trim(); - const { checkNicknameAvailability } = useNicknameValidate({ nickname, originalNickname }); + const { checkNicknameAvailability } = useProfileNicknameValidate({ nickname, originalNickname }); const onSubmit = async (data: IUserProfile) => { const { nickname, bio } = data; From 4191d76fac06bb9b64ad5a2657af8261e86a797f Mon Sep 17 00:00:00 2001 From: aquaman122 Date: Tue, 17 Dec 2024 15:34:45 +0900 Subject: [PATCH 3/3] =?UTF-8?q?feat:=20stories=20=EA=B3=B5=ED=86=B5=20?= =?UTF-8?q?=EC=BB=B4=ED=8F=AC=EB=84=8C=ED=8A=B8=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../auction/AuctionItem.stories.tsx | 94 +++++++++++++++++++ .../components/button/Button.stoires.tsx | 84 +++++++++++++++++ .../components/price/Price.stories.tsx | 23 +++++ .../components/product}/ProductItem.mdx | 0 .../product}/ProductItem.stories.tsx | 2 +- .../components/product}/ProductItem.test.tsx | 0 src/stories/components/product/index.ts | 0 7 files changed, 202 insertions(+), 1 deletion(-) create mode 100644 src/stories/components/auction/AuctionItem.stories.tsx create mode 100644 src/stories/components/button/Button.stoires.tsx create mode 100644 src/stories/components/price/Price.stories.tsx rename src/{shared/ui/product/story => stories/components/product}/ProductItem.mdx (100%) rename src/{shared/ui/product/story => stories/components/product}/ProductItem.stories.tsx (98%) rename src/{shared/ui/product/test => stories/components/product}/ProductItem.test.tsx (100%) create mode 100644 src/stories/components/product/index.ts diff --git a/src/stories/components/auction/AuctionItem.stories.tsx b/src/stories/components/auction/AuctionItem.stories.tsx new file mode 100644 index 00000000..a35ec4e2 --- /dev/null +++ b/src/stories/components/auction/AuctionItem.stories.tsx @@ -0,0 +1,94 @@ +import { AuctionItem, Button } from '@/shared'; +import type { Meta, StoryObj } from '@storybook/react'; + +const meta: Meta = { + title: 'Components/AuctionItem', + component: AuctionItem, + tags: ['autodocs'], + argTypes: { + label: { control: 'text', description: 'ARIA label for accessibility' }, + axis: { + control: { type: 'radio' }, + options: ['row', 'column'], + description: 'Layout direction (row or column)', + }, + }, +}; + +export default meta; +type Story = StoryObj; + +export const Default: Story = { + args: { + label: 'Auction Item Default', + axis: 'row', + children: ( + <> + + + + + + + ), + }, +}; + +export const ColumnLayout: Story = { + args: { + label: 'Auction Item Column', + axis: 'column', + children: ( + <> + + + + + + + ), + }, +}; + +export const NoTimeImage: Story = { + args: { + label: 'Auction Item without Time', + axis: 'row', + children: ( + <> + + + + + + + ), + }, +}; \ No newline at end of file diff --git a/src/stories/components/button/Button.stoires.tsx b/src/stories/components/button/Button.stoires.tsx new file mode 100644 index 00000000..def194dd --- /dev/null +++ b/src/stories/components/button/Button.stoires.tsx @@ -0,0 +1,84 @@ +import { Button } from "@/shared"; +import { Meta, StoryObj } from "@storybook/react"; + +const meta: Meta = { + title: 'components/Button', + component: Button, + tags: ['autodocs'], + argTypes: { + children: { control: 'text', description: '버튼 내부 텍스트나 요소'}, + size: { + control: 'select', + options: ['xsmall', 'small', 'medium', 'large'], + description: '버튼 크기', + }, + color: { + control: 'select', + options: ['black', 'white', 'gray', 'gray2', 'gray3', 'cheeseYellow', 'grayWhite', 'disabled'], + description: '버튼 색상', + }, + hoverColor: { + control: 'select', + options: ['black', 'white'], + description: '호버 시 버튼 색상', + }, + disabled: { control: 'boolean', description: '버튼 비활성화 여부' }, + loading: { control: 'boolean', description: '로딩 상태 표시 여부'}, + type: { + control: 'select', + options: ['button', 'submit', 'reset'], + description: '버튼 타입', + }, + ariaLabel: { control: 'text', description: '접근성 라벨' }, + onClick: { action: 'clicked', description: '버튼 클릭 이벤트' }, + }, +}; + +export default meta; + +type Story = StoryObj; + +export const Default: Story = { + args: { + children: '버튼', + size: 'medium', + color: 'black', + hoverColor: 'black', + disabled: false, + loading: false, + type: 'button', + ariaLabel: '기본 버튼', + }, +}; + +export const Loading: Story = { + args: { + ...Default.args, + loading: true, + children: '로딩 중...', + }, +}; + +export const Disabled: Story = { + args: { + ...Default.args, + disabled: true, + children: '비활성화됨', + }, +}; + +export const Large: Story = { + args: { + ...Default.args, + size: 'large', + children: 'Large 버튼', + }, +}; + +export const CheeseYellow: Story = { + args: { + ...Default.args, + color: 'cheeseYellow', + children: 'Cheese Yellow 버튼', + }, +}; \ No newline at end of file diff --git a/src/stories/components/price/Price.stories.tsx b/src/stories/components/price/Price.stories.tsx new file mode 100644 index 00000000..113494b2 --- /dev/null +++ b/src/stories/components/price/Price.stories.tsx @@ -0,0 +1,23 @@ +import { Price } from "@/shared"; +import { Meta, StoryObj } from "@storybook/react"; + +const meta: Meta = { + title: 'components/Price', + component: Price, + tags: ['autodocs'], + argTypes: { + title: { control: 'text', description: '가격 제목' }, + price: { control: 'number', description: '가격 값 (숫자)' }, + }, +}; + +export default meta; + +type Story = StoryObj; + +export const Default: Story = { + args: { + title: '판매가', + price: 10000, + }, +}; \ No newline at end of file diff --git a/src/shared/ui/product/story/ProductItem.mdx b/src/stories/components/product/ProductItem.mdx similarity index 100% rename from src/shared/ui/product/story/ProductItem.mdx rename to src/stories/components/product/ProductItem.mdx diff --git a/src/shared/ui/product/story/ProductItem.stories.tsx b/src/stories/components/product/ProductItem.stories.tsx similarity index 98% rename from src/shared/ui/product/story/ProductItem.stories.tsx rename to src/stories/components/product/ProductItem.stories.tsx index 9324906e..af6207a4 100644 --- a/src/shared/ui/product/story/ProductItem.stories.tsx +++ b/src/stories/components/product/ProductItem.stories.tsx @@ -2,7 +2,7 @@ import { LikeCount, Price, ProductItem } from '@/shared/ui'; import { Meta, StoryObj } from '@storybook/react'; const meta: Meta = { - title: 'Components/ProductItem', + title: 'components/ProductItem', component: ProductItem, // tags: ["autodocs"], // 자동으로 Docs 파일 생성 Docs파일 커스터마이징 원할 시 아래의 argTypes에 각 Prop에 대한 설명 추가 및 Default Value를 테이블 속성에 정의 가능 argTypes: { diff --git a/src/shared/ui/product/test/ProductItem.test.tsx b/src/stories/components/product/ProductItem.test.tsx similarity index 100% rename from src/shared/ui/product/test/ProductItem.test.tsx rename to src/stories/components/product/ProductItem.test.tsx diff --git a/src/stories/components/product/index.ts b/src/stories/components/product/index.ts new file mode 100644 index 00000000..e69de29b