diff --git a/Team-1-Codeit b/Team-1-Codeit deleted file mode 160000 index 0097cf69..00000000 --- a/Team-1-Codeit +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 0097cf6918586adcc47641699c49fcbfea029ec0 diff --git a/package-lock.json b/package-lock.json index bbea71db..fc8a64f9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12420,6 +12420,126 @@ "optional": true } } + }, + "node_modules/@next/swc-darwin-arm64": { + "version": "14.2.18", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-14.2.18.tgz", + "integrity": "sha512-tOBlDHCjGdyLf0ube/rDUs6VtwNOajaWV+5FV/ajPgrvHeisllEdymY/oDgv2cx561+gJksfMUtqf8crug7sbA==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-darwin-x64": { + "version": "14.2.18", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-14.2.18.tgz", + "integrity": "sha512-uJCEjutt5VeJ30jjrHV1VIHCsbMYnEqytQgvREx+DjURd/fmKy15NaVK4aR/u98S1LGTnjq35lRTnRyygglxoA==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-arm64-gnu": { + "version": "14.2.18", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-14.2.18.tgz", + "integrity": "sha512-IL6rU8vnBB+BAm6YSWZewc+qvdL1EaA+VhLQ6tlUc0xp+kkdxQrVqAnh8Zek1ccKHlTDFRyAft0e60gteYmQ4A==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-arm64-musl": { + "version": "14.2.18", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-14.2.18.tgz", + "integrity": "sha512-RCaENbIZqKKqTlL8KNd+AZV/yAdCsovblOpYFp0OJ7ZxgLNbV5w23CUU1G5On+0fgafrsGcW+GdMKdFjaRwyYA==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-x64-gnu": { + "version": "14.2.18", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-14.2.18.tgz", + "integrity": "sha512-3kmv8DlyhPRCEBM1Vavn8NjyXtMeQ49ID0Olr/Sut7pgzaQTo4h01S7Z8YNE0VtbowyuAL26ibcz0ka6xCTH5g==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-x64-musl": { + "version": "14.2.18", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-14.2.18.tgz", + "integrity": "sha512-mliTfa8seVSpTbVEcKEXGjC18+TDII8ykW4a36au97spm9XMPqQTpdGPNBJ9RySSFw9/hLuaCMByluQIAnkzlw==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-arm64-msvc": { + "version": "14.2.18", + "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.2.18.tgz", + "integrity": "sha512-J5g0UFPbAjKYmqS3Cy7l2fetFmWMY9Oao32eUsBPYohts26BdrMUyfCJnZFQkX9npYaHNDOWqZ6uV9hSDPw9NA==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-ia32-msvc": { + "version": "14.2.18", + "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.2.18.tgz", + "integrity": "sha512-Ynxuk4ZgIpdcN7d16ivJdjsDG1+3hTvK24Pp8DiDmIa2+A4CfhJSEHHVndCHok6rnLUzAZD+/UOKESQgTsAZGg==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } } } } diff --git a/src/app/(auth)/login/_components/login-form.stories.tsx b/src/app/(auth)/login/_components/login-form.stories.tsx index 497156d1..e245f8f8 100644 --- a/src/app/(auth)/login/_components/login-form.stories.tsx +++ b/src/app/(auth)/login/_components/login-form.stories.tsx @@ -6,6 +6,16 @@ import LoginForm, { LoginFormValues } from './login-form'; const meta: Meta = { title: 'auth/login-form', component: LoginForm, + tags: ['autodocs'], + parameters: { + docs: { + subtitle: '로그인시 사용되는 폼', + description: { + component: + '포커스 이동 또는 입력 1초 이후에 이메일 형식, 비밀번호 8자이상 유효성 검사가 실행됩니다.', + }, + }, + }, }; export default meta; diff --git a/src/app/(auth)/signup/_components/signup-form.stories.tsx b/src/app/(auth)/signup/_components/signup-form.stories.tsx index 3ad935f8..3ce89904 100644 --- a/src/app/(auth)/signup/_components/signup-form.stories.tsx +++ b/src/app/(auth)/signup/_components/signup-form.stories.tsx @@ -6,6 +6,16 @@ import SignupForm, { SignupFormValues } from './signup-form'; const meta: Meta = { title: 'auth/signup-form', component: SignupForm, + tags: ['autodocs'], + parameters: { + docs: { + subtitle: '회원가입시 사용되는 폼', + description: { + component: + '포커스 이동 또는 입력 1초 이후에 이메일 형식, 비밀번호 8자이상, 비밀번호 확인 유효성 검사가 실행됩니다.', + }, + }, + }, }; export default meta; diff --git a/src/app/(crew)/_components/category/internal-category/internal-category.stories.tsx b/src/app/(crew)/_components/category/internal-category/internal-category.stories.tsx index 63f5c104..b27cbed5 100644 --- a/src/app/(crew)/_components/category/internal-category/internal-category.stories.tsx +++ b/src/app/(crew)/_components/category/internal-category/internal-category.stories.tsx @@ -7,16 +7,24 @@ const meta: Meta = { title: 'layout/category', component: InternalCategory, tags: ['autodocs'], + parameters: { + docs: { + subtitle: '운동 종목별 카테고리', + description: { + component: '크루찾기 페이지에서 운동 대종목 선택에 따라, 세부 카테고리를 보여줍니다.', + }, + }, + }, argTypes: { category: { - description: '세부 카테고리 이름 배열', + description: '카테고리 이름 배열', }, }, }; export default meta; -const Template: StoryFn = function InternalCategoryStory() { +const Template: StoryFn = function InternalCategoryStory() { const [subCategory, setSubCategory] = useState('running'); return ( @@ -28,12 +36,5 @@ const Template: StoryFn = function InternalCategoryStory( ); }; -export const Category1 = Template.bind({}); -Category1.args = { - category: categoryData[0].items, -}; - -export const Category2 = Template.bind({}); -Category2.args = { - category: categoryData[1].items, -}; +export const Default = Template.bind({}); +Default.args = {}; diff --git a/src/app/(crew)/_components/hero/hero-crew.tsx b/src/app/(crew)/_components/hero/hero-crew.tsx index dd7ac7fe..e41a5496 100644 --- a/src/app/(crew)/_components/hero/hero-crew.tsx +++ b/src/app/(crew)/_components/hero/hero-crew.tsx @@ -17,14 +17,14 @@ export default function HeroCrew() { 함께할 사람이 없나요? - + 지금 크루에 참여해보세요.

크루 만들기 diff --git a/src/app/(crew)/crew/create/_components/create-crew-form/create-crew-form.stories.tsx b/src/app/(crew)/crew/create/_components/create-crew-form/create-crew-form.stories.tsx index acc0aaaa..73e736c9 100644 --- a/src/app/(crew)/crew/create/_components/create-crew-form/create-crew-form.stories.tsx +++ b/src/app/(crew)/crew/create/_components/create-crew-form/create-crew-form.stories.tsx @@ -17,11 +17,27 @@ export default { title: 'crew/create-crew-form', component: CreateCrewForm, tags: ['autodocs'], + argTypes: { + type: { + control: 'radio', + options: ['create', 'edit'], + description: '폼 타입', + table: { type: { summary: 'create | edit' } }, + }, + data: { + control: 'object', + description: '폼 데이터', + table: { type: { summary: 'CreateCrewFormTypes' } }, + }, + isEdit: { control: 'boolean', description: '수정 여부' }, + onSubmit: { + action: 'submit', + table: { type: { summary: '(data: CreateCrewFormTypes) => void' } }, + }, + onEdit: { action: 'edit', table: { type: { summary: '(data: CreateCrewFormTypes) => void' } } }, + }, parameters: { layout: 'fullscreen', - nextjs: { - appDirectory: true, - }, docs: { description: { component: '크루 작성/수정에 사용되는 폼입니다.', diff --git a/src/app/(crew)/crew/create/_components/create-crew-form/index.tsx b/src/app/(crew)/crew/create/_components/create-crew-form/index.tsx index dc17810e..d5fb1a37 100644 --- a/src/app/(crew)/crew/create/_components/create-crew-form/index.tsx +++ b/src/app/(crew)/crew/create/_components/create-crew-form/index.tsx @@ -13,17 +13,26 @@ import DropDown from '@/src/components/common/input/drop-down'; import FileInputWrap from '@/src/components/common/input/file-input-wrap'; import TextInput from '@/src/components/common/input/text-input'; import Textarea from '@/src/components/common/input/textarea'; -import { CreateCrewFormTypes, EditCrewResponseTypes } from '@/src/types/create-crew'; +import { CreateCrewFormTypes } from '@/src/types/create-crew'; import ImgCrewSampleUrls from '@/public/assets/images/crew-sample'; export interface CreateCrewFormProps { type: 'create' | 'edit'; - data: CreateCrewFormTypes | EditCrewResponseTypes; + data: CreateCrewFormTypes; isEdit?: boolean; onEdit?: (data: CreateCrewFormTypes) => void; onSubmit?: (data: CreateCrewFormTypes) => void; } +/** + * 크루 생성/수정 폼 + * @param {'create' | 'edit'} type : form 타입 + * @param {boolean} isEdit : 수정 여부 + * @param {(data: CreateCrewFormTypes) => void} onEdit + * @param {(data: CreateCrewFormTypes) => void} onSubmit + * @param {CreateCrewFormTypes} data + */ + export default function CreateCrewForm({ type, isEdit, @@ -199,7 +208,7 @@ export default function CreateCrewForm({ field.onChange(value); handleMainCategoryChange(value); }} - error={errors.mainCategory?.message} + errorMsg={errors.mainCategory?.message} /> )} /> @@ -218,7 +227,7 @@ export default function CreateCrewForm({ placeholder={isEdit && field.value ? field.value : '세부 카테고리'} data={categoryData[categoryIndex]?.items || []} className="flex-1" - error={errors.subCategory?.message} + errorMsg={errors.subCategory?.message} /> )} /> @@ -277,7 +286,7 @@ export default function CreateCrewForm({ field.onChange(value); handleMainLocationChange(value); }} - error={errors.mainLocation?.message} + errorMsg={errors.mainLocation?.message} /> )} /> @@ -297,7 +306,7 @@ export default function CreateCrewForm({ placeholder={isEdit && field.value ? field.value : '시/군/구'} data={regionData[regionIndex]?.areas || []} className="flex-1" - error={errors.subLocation?.message} + errorMsg={errors.subLocation?.message} /> )} /> diff --git a/src/app/(crew)/crew/detail/[id]/_components/create-gathering/create-gathering-form/index.tsx b/src/app/(crew)/crew/detail/[id]/_components/create-gathering/create-gathering-form/index.tsx index bcdbdf52..a5a2f35e 100644 --- a/src/app/(crew)/crew/detail/[id]/_components/create-gathering/create-gathering-form/index.tsx +++ b/src/app/(crew)/crew/detail/[id]/_components/create-gathering/create-gathering-form/index.tsx @@ -20,6 +20,15 @@ export interface CreateGatheringFormProps { onClose: () => void; } +/** + * 약속 생성/수정 폼 + * @param {CreateGatheringFormTypes} data + * @param {boolean} isEdit + * @param {(data: CreateGatheringFormTypes) => void} onEdit + * @param {(data: CreateGatheringFormTypes) => void} onSubmit + * @param {() => void} onClose + */ + export default function CreateGatheringForm({ isEdit = false, onEdit = () => {}, diff --git a/src/app/(crew)/crew/detail/[id]/_components/crew-gathering-list.stories.tsx b/src/app/(crew)/crew/detail/[id]/_components/crew-gathering-list.stories.tsx index 750a5cfb..1a830602 100644 --- a/src/app/(crew)/crew/detail/[id]/_components/crew-gathering-list.stories.tsx +++ b/src/app/(crew)/crew/detail/[id]/_components/crew-gathering-list.stories.tsx @@ -6,7 +6,7 @@ import CrewGatheringList from './crew-gathering-list'; const mockGatheringData = [ { id: 1, - title: '가나다라마바사 요가 모임', + title: '요가 모임', dateTime: '2024-12-15T07:30', location: '서울, 한강공원', currentCount: 8, @@ -18,7 +18,7 @@ const mockGatheringData = [ { id: 2, title: '등산 모임', - dateTime: '2024-11-12T09:00', + dateTime: '2024-12-12T09:00', location: '서울 강남구 개포동 대모산', currentCount: 5, totalCount: 10, @@ -29,7 +29,7 @@ const mockGatheringData = [ { id: 3, title: '러닝 모임', - dateTime: '2024-11-15T09:00', + dateTime: '2024-12-15T09:00', location: '서울 영등포구 여의동로 330', currentCount: 10, totalCount: 20, @@ -40,7 +40,7 @@ const mockGatheringData = [ { id: 4, title: '러닝 모임', - dateTime: '2024-11-15T09:00', + dateTime: '2024-12-15T09:00', location: '서울 영등포구 여의동로 330', currentCount: 10, totalCount: 20, @@ -56,13 +56,17 @@ const meta: Meta = { title: 'crew/crew-gathering-list', component: CrewGatheringList, parameters: { - layout: 'fulled', // layout 변경 + docs: { + subtitle: '크루 디테일 페이지 에서 볼 수 있는 약속 카드 리스트입니다.', + description: { + component: ' 데스크탑에서는 캐러셀, 이하의 사이즈에서는 드래그로 이동 가능합니다.', + }, + }, }, tags: ['autodocs'], decorators: [ (Story) => ( - {/* 부모 컨테이너 추가 */}
@@ -76,10 +80,9 @@ const meta: Meta = { export default meta; type Story = StoryObj; -// 스토리북에서 gatheringData prop을 전달 export const Default: Story = { args: { gatheringData: mockGatheringData, - crewId: 1, // crewId를 기본값으로 설정 + crewId: 1, }, }; diff --git a/src/app/(crew)/crew/detail/[id]/_components/crew-review-list.stories.tsx b/src/app/(crew)/crew/detail/[id]/_components/crew-review-list.stories.tsx index 934b43ab..c2f6c0f3 100644 --- a/src/app/(crew)/crew/detail/[id]/_components/crew-review-list.stories.tsx +++ b/src/app/(crew)/crew/detail/[id]/_components/crew-review-list.stories.tsx @@ -2,16 +2,14 @@ import React, { useState } from 'react'; import type { Meta, StoryObj } from '@storybook/react'; import ClientProvider from '@/src/components/client-provider'; import { CrewReview } from '@/src/types/review'; -import { CrewReviewData } from '@/src/mock/review-data'; import CrewReviewList from './crew-review-list'; const meta: Meta = { title: 'crew/crew-review-list', component: CrewReviewList, parameters: { - layout: 'fulled', - nextjs: { - appDirectory: true, + docs: { + subtitle: '크루의 전체 리뷰를 확인할 수 있는 리스트 입니다.', }, }, tags: ['autodocs'], @@ -27,6 +25,95 @@ const meta: Meta = { export default meta; type Story = StoryObj; +const CrewReviewData: { data: CrewReview[] } = { + data: [ + { + crewId: 1, + id: 1, + rate: 5, + comment: '정말 좋은 모임이었어요! 많은 걸 배웠습니다.', + createdAt: '2024-10-30T14:00:00+09:00', + reviewer: { + id: 1, + nickname: '김철수', + profileImageUrl: 'https://i.pinimg.com/736x/25/64/5c/25645c1cbb29c5b8e8ebe995404b5ab6.jpg', + }, + }, + { + crewId: 1, + id: 2, + rate: 3, + comment: '괜찮았지만, 다음에는 조금 더 나아지면 좋겠어요.', + createdAt: '2024-10-31T09:30:00+09:00', + reviewer: { + id: 2, + nickname: '박영희', + profileImageUrl: 'https://i.pinimg.com/736x/ba/25/6f/ba256faae4c3608685067b2641507392.jpg', + }, + }, + { + crewId: 1, + id: 3, + rate: 1, + comment: '기대에 미치지 못했습니다. 개선이 필요해요.', + createdAt: '2024-11-01T11:15:00+09:00', + reviewer: { + id: 3, + nickname: '이영수', + profileImageUrl: '', + }, + }, + { + crewId: 1, + id: 4, + rate: 4, + comment: '전체적으로 만족스러웠습니다. 다음에도 참여하고 싶어요!', + createdAt: '2024-11-03T16:45:00+09:00', + reviewer: { + id: 4, + nickname: '최지훈', + profileImageUrl: '', + }, + }, + { + crewId: 1, + id: 5, + rate: 2, + comment: '조금 아쉬웠지만 새로운 경험이었습니다.', + createdAt: '2024-11-05T13:20:00+09:00', + reviewer: { + id: 5, + nickname: '강수진', + profileImageUrl: 'https://i.pinimg.com/736x/38/d2/9a/38d29a018ac0472d9c2916e9d46ca282.jpg', + }, + }, + { + crewId: 1, + id: 6, + rate: 2, + comment: '조금 아쉬웠지만 새로운 경험이었습니다.', + createdAt: '2024-11-05T13:20:00+09:00', + reviewer: { + id: 5, + nickname: '강수진', + profileImageUrl: '', + }, + }, + { + crewId: 1, + id: 7, + rate: 2, + comment: '아쉬워요', + createdAt: '2024-10-30T14:00:00+09:00', + reviewer: { + id: 1, + nickname: '김철수', + profileImageUrl: '', + }, + }, + ], +}; + function RenderReviewPagination() { const [currentPage, setCurrentPage] = useState(1); const itemsPerPage = 6; diff --git a/src/app/(crew)/crew/detail/[id]/_components/detail-crew-presenter.tsx b/src/app/(crew)/crew/detail/[id]/_components/detail-crew-presenter.tsx index 0410fb78..f148d4b2 100644 --- a/src/app/(crew)/crew/detail/[id]/_components/detail-crew-presenter.tsx +++ b/src/app/(crew)/crew/detail/[id]/_components/detail-crew-presenter.tsx @@ -188,8 +188,8 @@ export default function DetailCrewPresenter({
) : (
-

크루장 외에 아직 크루원이 없습니다.

-

크루에 참여해보세요!🙌

+

크루장 외에 아직 크루원이 없습니다

+

크루에 참여해보세요🙌

)}
diff --git a/src/app/(crew)/crew/detail/[id]/_components/detail-crew.stories.tsx b/src/app/(crew)/crew/detail/[id]/_components/detail-crew.stories.tsx index 831cce82..00dc08e2 100644 --- a/src/app/(crew)/crew/detail/[id]/_components/detail-crew.stories.tsx +++ b/src/app/(crew)/crew/detail/[id]/_components/detail-crew.stories.tsx @@ -5,7 +5,13 @@ const meta: Meta = { title: 'crew/crew-detail', component: DetailCrewPresenter, parameters: { - layout: 'fullscreen', + docs: { + subtitle: '크루 디테일 페이지에서 크루 정보를 나타냅니다.', + description: { + component: + '크루장인 경우, 크루원인 경우, 둘다 아닌 경우 세가지에 따라서 케밥이 다르게 보입니다.', + }, + }, }, tags: ['autodocs'], argTypes: { @@ -24,22 +30,21 @@ export const Default: Story = { args: { data: { id: 1, - title: '같이 물장구칠사람', + title: '스키 초보만 오세요', mainCategory: '기타', subCategory: '스키', mainLocation: '대전광역시', - introduce: - '크루 소개 크루 소개 크루 소개 크루 소개 크루 소개 크루 소개 크루 소개 크루 소개 크루 소개 크루 소개 크루 소개 크루 소개 크루 소개 크루 소개 크루 소개 크루 소개 크루 소개 크루 소개 크루 소개 크루 소개 크루 소개 크루 소개 크루 소개 크루 소개 크루 소개 크루 소개 크루 소개 크루 소개 크루 소개', + introduce: '스키 초보를 위한 모임입니다.', subLocation: '유성구', participantCount: 8, totalCount: 10, imageUrl: - 'https://crewcrew.s3.ap-northeast-2.amazonaws.com/crew/4d0c5851-e6e2-4919-897a-b8d4e88a4f72', + 'https://images.unsplash.com/photo-1504827274833-7db1774520e3?q=80&w=2670&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D', totalGatheringCount: 5, crewMembers: [ { id: 1, - nickname: 'John', + nickname: '스키조아', email: 'abc@asbc.com', profileImageUrl: 'https://i.pinimg.com/564x/e2/25/bb/e225bb492dc7a20a549f3c0abec28eb8.jpg', @@ -108,17 +113,17 @@ export const IsCaptain: Story = { args: { data: { id: 1, - title: '같이 물장구칠사람', + title: '스키 초보만 오세요', mainCategory: '기타', subCategory: '스키', mainLocation: '대전광역시', - introduce: '크루 소개', + introduce: '스키 초보를 위한 모임입니다.', subLocation: '유성구', - participantCount: 1, + participantCount: 8, totalCount: 10, imageUrl: - 'https://crewcrew.s3.ap-northeast-2.amazonaws.com/crew/4d0c5851-e6e2-4919-897a-b8d4e88a4f72', - totalGatheringCount: 1, + 'https://images.unsplash.com/photo-1504827274833-7db1774520e3?q=80&w=2670&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D', + totalGatheringCount: 5, crewMembers: [ { id: 1, @@ -139,17 +144,17 @@ export const IsMember: Story = { args: { data: { id: 1, - title: '같이 물장구칠사람', + title: '스키 초보만 오세요', mainCategory: '기타', subCategory: '스키', mainLocation: '대전광역시', - introduce: '', + introduce: '스키 초보를 위한 모임입니다.', subLocation: '유성구', - participantCount: 2, + participantCount: 8, totalCount: 10, imageUrl: - 'https://crewcrew.s3.ap-northeast-2.amazonaws.com/crew/4d0c5851-e6e2-4919-897a-b8d4e88a4f72', - totalGatheringCount: 1, + 'https://images.unsplash.com/photo-1504827274833-7db1774520e3?q=80&w=2670&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D', + totalGatheringCount: 5, crewMembers: [ { id: 1, diff --git a/src/app/(crew)/crew/detail/[id]/_components/gathering-list-section.tsx b/src/app/(crew)/crew/detail/[id]/_components/gathering-list-section.tsx index c9a04326..2378eb9f 100644 --- a/src/app/(crew)/crew/detail/[id]/_components/gathering-list-section.tsx +++ b/src/app/(crew)/crew/detail/[id]/_components/gathering-list-section.tsx @@ -71,9 +71,9 @@ export default function GatheringListSection({ id }: GatheringListSectionProps) if (!gatheringList || gatheringList.length === 0) return (
-
-

아직 등록된 약속이 없습니다!

-

새로운 약속을 만들어보세요! 🙌

+
+

아직 등록된 약속이 없어요

+

새로운 약속을 만들어보세요🙌

); diff --git a/src/app/(crew)/crew/detail/[id]/_components/rating-display.stories.tsx b/src/app/(crew)/crew/detail/[id]/_components/rating-display.stories.tsx index 7efc260c..c9479a0d 100644 --- a/src/app/(crew)/crew/detail/[id]/_components/rating-display.stories.tsx +++ b/src/app/(crew)/crew/detail/[id]/_components/rating-display.stories.tsx @@ -5,6 +5,11 @@ import RatingDisplay, { ReviewRateInfo } from './rating-display'; export default { title: 'crew/crew-rating-display', component: RatingDisplay, + parameters: { + docs: { + subtitle: '크루 디테일 페이지에서 크루의 리뷰 정보를 알 수 있는 컴포넌트 입니다.', + }, + }, tags: ['autodocs'], argTypes: { totalRate: { control: 'number', description: '총 평가 개수' }, diff --git a/src/app/(crew)/crew/detail/[id]/_components/review-section.tsx b/src/app/(crew)/crew/detail/[id]/_components/review-section.tsx index f7f5dd58..14237ba0 100644 --- a/src/app/(crew)/crew/detail/[id]/_components/review-section.tsx +++ b/src/app/(crew)/crew/detail/[id]/_components/review-section.tsx @@ -37,8 +37,8 @@ export default function CrewReviewSection({ crewId }: CrewReviewSectionProps) { if (data?.reviewList.content.length === 0) { return (
-

리뷰가 아직 없습니다

-

크루의 약속에 참여하고 리뷰를 남겨보세요!

+

리뷰가 아직 없어요

+

크루의 약속에 참여하고 리뷰를 남겨보세요🙌

); } diff --git a/src/app/(crew)/crew/detail/[id]/page.tsx b/src/app/(crew)/crew/detail/[id]/page.tsx index 8df25bda..2234d921 100644 --- a/src/app/(crew)/crew/detail/[id]/page.tsx +++ b/src/app/(crew)/crew/detail/[id]/page.tsx @@ -37,7 +37,7 @@ export default async function CrewDetailPage({ params }: CrewDetailPageProps) { {/* Crew Review Section */} -
+

크루 리뷰

diff --git a/src/app/(crew)/favicon.ico b/src/app/(crew)/favicon.ico deleted file mode 100644 index 718d6fea..00000000 Binary files a/src/app/(crew)/favicon.ico and /dev/null differ diff --git a/src/app/(crew)/my-favorite/_components/gathering-list/gathering-list.stories.tsx b/src/app/(crew)/my-favorite/_components/gathering-list/gathering-list.stories.tsx index ed59c89e..c182910b 100644 --- a/src/app/(crew)/my-favorite/_components/gathering-list/gathering-list.stories.tsx +++ b/src/app/(crew)/my-favorite/_components/gathering-list/gathering-list.stories.tsx @@ -10,7 +10,12 @@ const meta: Meta = { title: 'gathering/liked-gathering-card', component: LikedListPresenter, parameters: { - layout: 'fullscreen', + docs: { + subtitle: '찜한 약속을 확인하는 컴포넌트 입니다.', + description: { + component: '페이지네이션을 사용해 한 페이지에 6개씩 확인할 수 있습니다.', + }, + }, }, tags: ['autodocs'], decorators: [ @@ -34,13 +39,12 @@ const dataWithOneItem: GatheringResponseType = { content: [ { id: 1, - title: '첫 번째 모임', + title: '서핑모임', dateTime: '2024-12-10T08:00:00.000', location: '서울 강남구 삼성동', currentCount: 1, totalCount: 5, - imageUrl: - 'https://crewcrew.s3.ap-northeast-2.amazonaws.com/gathering/73db4777-3d00-488c-a016-1e50eaa72b8f', + imageUrl: 'https://i.pinimg.com/736x/00/6d/4b/006d4bb521a737534e37a8af3203a7d3.jpg', }, ], pageNumber: 0, @@ -53,33 +57,30 @@ const dataWithThreeItems: GatheringResponseType = { content: [ { id: 1, - title: '첫 번째 모임', + title: '서핑모임', dateTime: '2024-12-10T08:00:00.000', location: '서울 강남구 삼성동', currentCount: 1, totalCount: 5, - imageUrl: - 'https://crewcrew.s3.ap-northeast-2.amazonaws.com/gathering/73db4777-3d00-488c-a016-1e50eaa72b8f', + imageUrl: 'https://i.pinimg.com/736x/00/6d/4b/006d4bb521a737534e37a8af3203a7d3.jpg', }, { id: 2, - title: '두 번째 모임', + title: '헬스', dateTime: '2024-12-15T09:00:00.000', location: '서울 종로구 광화문', currentCount: 3, totalCount: 5, - imageUrl: - 'https://crewcrew.s3.ap-northeast-2.amazonaws.com/gathering/73db4777-3d00-488c-a016-1e50eaa72b8f', + imageUrl: 'https://i.pinimg.com/736x/fb/53/e3/fb53e3a4225c01308c30882d92bee467.jpg', }, { id: 3, - title: '세 번째 모임', - dateTime: '2024-12-20T10:00:00.000', - location: '서울 서초구 양재천', - currentCount: 2, - totalCount: 4, - imageUrl: - 'https://crewcrew.s3.ap-northeast-2.amazonaws.com/gathering/73db4777-3d00-488c-a016-1e50eaa72b8f', + title: '서핑모임', + dateTime: '2024-12-10T08:00:00.000', + location: '서울 강남구 삼성동', + currentCount: 1, + totalCount: 5, + imageUrl: 'https://i.pinimg.com/736x/00/6d/4b/006d4bb521a737534e37a8af3203a7d3.jpg', }, ], pageNumber: 0, @@ -92,138 +93,54 @@ const dataWithFiveItems: GatheringResponseType = { content: [ { id: 1, - title: '첫 번째 모임', + title: '서핑모임', dateTime: '2024-12-10T08:00:00.000', location: '서울 강남구 삼성동', currentCount: 1, totalCount: 5, - imageUrl: - 'https://crewcrew.s3.ap-northeast-2.amazonaws.com/gathering/73db4777-3d00-488c-a016-1e50eaa72b8f', + imageUrl: 'https://i.pinimg.com/736x/00/6d/4b/006d4bb521a737534e37a8af3203a7d3.jpg', }, { id: 2, - title: '두 번째 모임', + title: '헬스', dateTime: '2024-12-15T09:00:00.000', location: '서울 종로구 광화문', currentCount: 3, totalCount: 5, - imageUrl: - 'https://crewcrew.s3.ap-northeast-2.amazonaws.com/gathering/73db4777-3d00-488c-a016-1e50eaa72b8f', + imageUrl: 'https://i.pinimg.com/736x/fb/53/e3/fb53e3a4225c01308c30882d92bee467.jpg', }, { id: 3, - title: '세 번째 모임', - dateTime: '2024-12-20T10:00:00.000', - location: '서울 서초구 양재천', - currentCount: 2, - totalCount: 4, - imageUrl: - 'https://crewcrew.s3.ap-northeast-2.amazonaws.com/gathering/73db4777-3d00-488c-a016-1e50eaa72b8f', - }, - { - id: 4, - title: '네 번째 모임', - dateTime: '2024-12-25T14:00:00.000', - location: '서울 용산구 한남동', - currentCount: 5, - totalCount: 6, - imageUrl: - 'https://crewcrew.s3.ap-northeast-2.amazonaws.com/gathering/73db4777-3d00-488c-a016-1e50eaa72b8f', - }, - { - id: 5, - title: '다섯 번째 모임', - dateTime: '2024-12-30T16:00:00.000', - location: '서울 송파구 잠실', - currentCount: 3, - totalCount: 5, - imageUrl: - 'https://crewcrew.s3.ap-northeast-2.amazonaws.com/gathering/73db4777-3d00-488c-a016-1e50eaa72b8f', - }, - ], - pageNumber: 0, - pageSize: 6, - totalElements: 5, - totalPages: 1, -}; - -const dataWithSevenItems: GatheringResponseType = { - content: [ - { - id: 1, - title: '첫 번째 모임', + title: '서핑모임', dateTime: '2024-12-10T08:00:00.000', location: '서울 강남구 삼성동', currentCount: 1, totalCount: 5, - imageUrl: - 'https://crewcrew.s3.ap-northeast-2.amazonaws.com/gathering/73db4777-3d00-488c-a016-1e50eaa72b8f', - }, - { - id: 2, - title: '두 번째 모임', - dateTime: '2024-12-15T09:00:00.000', - location: '서울 종로구 광화문', - currentCount: 3, - totalCount: 5, - imageUrl: - 'https://crewcrew.s3.ap-northeast-2.amazonaws.com/gathering/73db4777-3d00-488c-a016-1e50eaa72b8f', - }, - { - id: 3, - title: '세 번째 모임', - dateTime: '2024-12-20T10:00:00.000', - location: '서울 서초구 양재천', - currentCount: 2, - totalCount: 4, - imageUrl: - 'https://crewcrew.s3.ap-northeast-2.amazonaws.com/gathering/73db4777-3d00-488c-a016-1e50eaa72b8f', + imageUrl: 'https://i.pinimg.com/736x/00/6d/4b/006d4bb521a737534e37a8af3203a7d3.jpg', }, { id: 4, - title: '네 번째 모임', + title: '러닝 같이 해요', dateTime: '2024-12-25T14:00:00.000', location: '서울 용산구 한남동', currentCount: 5, totalCount: 6, - imageUrl: - 'https://crewcrew.s3.ap-northeast-2.amazonaws.com/gathering/73db4777-3d00-488c-a016-1e50eaa72b8f', + imageUrl: 'https://i.pinimg.com/736x/72/8e/94/728e94219c8d4570d0901e7df5567282.jpg', }, { id: 5, - title: '다섯 번째 모임', + title: '같이 풋살해요', dateTime: '2024-12-30T16:00:00.000', location: '서울 송파구 잠실', currentCount: 3, totalCount: 5, - imageUrl: - 'https://crewcrew.s3.ap-northeast-2.amazonaws.com/gathering/73db4777-3d00-488c-a016-1e50eaa72b8f', - }, - { - id: 6, - title: '여섯 번째 모임', - dateTime: '2025-01-05T18:00:00.000', - location: '서울 은평구 불광동', - currentCount: 4, - totalCount: 4, - imageUrl: - 'https://crewcrew.s3.ap-northeast-2.amazonaws.com/gathering/73db4777-3d00-488c-a016-1e50eaa72b8f', - }, - { - id: 7, - title: '일곱 번째 모임', - dateTime: '2025-01-10T20:00:00.000', - location: '서울 노원구 상계동', - currentCount: 2, - totalCount: 3, - imageUrl: - 'https://crewcrew.s3.ap-northeast-2.amazonaws.com/gathering/73db4777-3d00-488c-a016-1e50eaa72b8f', + imageUrl: 'https://i.pinimg.com/736x/25/64/5c/25645c1cbb29c5b8e8ebe995404b5ab6.jpg', }, ], pageNumber: 0, pageSize: 6, - totalElements: 7, - totalPages: 2, + totalElements: 5, + totalPages: 1, }; export const OneItem: Story = { @@ -255,13 +172,3 @@ export const FiveItems: Story = { page: 1, }, }; - -export const SevenItems: Story = { - args: { - gatheringData: dataWithSevenItems, - onPageChange, - onLike, - onUnlike, - page: 1, - }, -}; diff --git a/src/app/(crew)/my-favorite/_components/gathering-list/liked-list-container.tsx b/src/app/(crew)/my-favorite/_components/gathering-list/liked-list-container.tsx index d537a08b..d35751c7 100644 --- a/src/app/(crew)/my-favorite/_components/gathering-list/liked-list-container.tsx +++ b/src/app/(crew)/my-favorite/_components/gathering-list/liked-list-container.tsx @@ -53,7 +53,12 @@ export default function LikedList() { // 빈 배열 처리(좋아요 목록이 없는 경우) if (gatheringData.content.length === 0) { - return
좋아요 누른 목록이 없습니다
; + return ( +
+

찜한 약속이 없습니다

+

약속을 찜해보세요🙌

+
+ ); } return ( diff --git a/src/app/(crew)/my-gathering/hosted/page.tsx b/src/app/(crew)/my-gathering/hosted/page.tsx index b3472b3a..1af910e7 100644 --- a/src/app/(crew)/my-gathering/hosted/page.tsx +++ b/src/app/(crew)/my-gathering/hosted/page.tsx @@ -25,6 +25,15 @@ export default function MyGatheringHostedPage() { refetch(); }, [selectedDate]); + if (hostedGatheringList?.length === 0) { + return ( +
+

내가 만든 약속이 아직 없어요

+

크루에서 약속을 만들어보세요 🙌

+
+ ); + } + return (
diff --git a/src/app/(crew)/my-gathering/joined/page.tsx b/src/app/(crew)/my-gathering/joined/page.tsx index 7c949f1e..b9ace55f 100644 --- a/src/app/(crew)/my-gathering/joined/page.tsx +++ b/src/app/(crew)/my-gathering/joined/page.tsx @@ -25,6 +25,15 @@ export default function MyGatheringJoinedPage() { refetch(); }, [selectedDate]); + if (joinedGatheringList?.length === 0) { + return ( +
+

내가 참여한 약속이 아직 없어요

+

크루에서 약속에 참여해 보세요 🙌

+
+ ); + } + return (
diff --git a/src/app/(crew)/my-page/_components/profile-card/container.tsx b/src/app/(crew)/my-page/_components/profile-card/container.tsx index 4f01f6ee..7ceb06ad 100644 --- a/src/app/(crew)/my-page/_components/profile-card/container.tsx +++ b/src/app/(crew)/my-page/_components/profile-card/container.tsx @@ -12,9 +12,7 @@ export default function ProfileCard() { // 로딩 중일 때 스켈레톤 표시 if (userLoading) return ; - - // 사용자 데이터가 없는 경우 null 반환 - if (!user) return null; + if (!user) return ; const handleEdit = () => { const input = document.createElement('input'); diff --git a/src/app/(crew)/my-page/_components/reviewable-gatherings/reviewable-gathering-card-list.tsx b/src/app/(crew)/my-page/_components/reviewable-gatherings/reviewable-gathering-card-list.tsx index 4f043515..6d027c71 100644 --- a/src/app/(crew)/my-page/_components/reviewable-gatherings/reviewable-gathering-card-list.tsx +++ b/src/app/(crew)/my-page/_components/reviewable-gatherings/reviewable-gathering-card-list.tsx @@ -19,14 +19,21 @@ export default function ReviewableGatheringCardList() { // 로딩 중일 때 스켈레톤 표시 if (isLoading) { - return ; + return ( +
+ +
+ ); } return ( -
    +
      {/* 데이터가 비었을 때 메시지 */} {isDataEmpty ? ( -
      아직 모임이 없습니다.
      +
      +

      리뷰 가능한 약속이 없어요

      +

      크루의 약속에 참여해보세요🙌

      +
      ) : ( // 카드 컴포넌트 배열 렌더링 data.pages.map((page, pageIndex) => ( diff --git a/src/app/(crew)/my-page/_components/reviewable-gatherings/reviewable-gathering-card.stories.tsx b/src/app/(crew)/my-page/_components/reviewable-gatherings/reviewable-gathering-card.stories.tsx index 6e0e3d5d..158dbaca 100644 --- a/src/app/(crew)/my-page/_components/reviewable-gatherings/reviewable-gathering-card.stories.tsx +++ b/src/app/(crew)/my-page/_components/reviewable-gatherings/reviewable-gathering-card.stories.tsx @@ -7,7 +7,13 @@ const meta: Meta = { component: ReviewableGatheringCard, tags: ['autodocs'], parameters: { - layout: 'fullscreen', + docs: { + subtitle: '리뷰 가능한 약속 카드입니다.', + description: { + component: + '약속이름, 약속장소, 인원수, 시간 등을 알려주고 리뷰 작성 버튼을 통해 리뷰를 남길 수 있습니다.', + }, + }, }, decorators: [ (Story) => ( @@ -32,16 +38,20 @@ type Story = StoryObj; export const Default: Story = { args: { id: 1, - gatheringName: '모임모임모임모임모임모밈미밈미미미미미미', - location: '모임모임모임모임모임모밈미밈미미미미미미', + gatheringName: '서핑모임', + location: '양양', dateTime: '2024-11-21T18:30:00.000Z', currentCount: 8, totalCount: 12, - imageUrl: 'https://i.pinimg.com/736x/5d/83/ce/5d83cec545201e5ca8f2477070e2eac9.jpg', + imageUrl: 'https://i.pinimg.com/736x/00/6d/4b/006d4bb521a737534e37a8af3203a7d3.jpg', participants: [ { id: 1, nickname: '유저1', profileImageUrl: '' }, { id: 2, nickname: '유저2', profileImageUrl: '' }, - { id: 3, nickname: '유저3', profileImageUrl: '' }, + { + id: 3, + nickname: '유저3', + profileImageUrl: 'https://i.pinimg.com/736x/97/5a/3c/975a3c645d344216e8ea346c084fba04.jpg', + }, ], }, }; diff --git a/src/app/(crew)/page.tsx b/src/app/(crew)/page.tsx index b921927c..a384f5dc 100644 --- a/src/app/(crew)/page.tsx +++ b/src/app/(crew)/page.tsx @@ -91,13 +91,13 @@ export default function HomePage() { classNames={{ root: 'w-full', input: - 'h-11 w-full rounded-xl border-0 pl-10 font-pretendard text-base font-medium text-gray-800 placeholder:text-gray-500', + 'h-10 md:h-11 w-full rounded-xl border-0 pl-10 font-pretendard text-base font-medium text-gray-800 placeholder:text-gray-500', }} /> diff --git a/src/app/favicon.ico b/src/app/favicon.ico deleted file mode 100644 index 7ffab4bf..00000000 Binary files a/src/app/favicon.ico and /dev/null differ diff --git a/src/app/not-found.tsx b/src/app/not-found.tsx index 4af1b939..8fde6269 100644 --- a/src/app/not-found.tsx +++ b/src/app/not-found.tsx @@ -35,7 +35,7 @@ export default function NotFound() { xmlnsXlink="http://www.w3.org/1999/xlink" viewBox="0 24 150 28" preserveAspectRatio="none" - shape-rendering="auto" + shapeRendering="auto" > = { title: 'common/button/like-button', component: LikeBtn, tags: ['autodocs'], - argTypes: { - isLiked: { control: 'boolean' }, - id: { control: 'number' }, - onLikeToggle: { action: 'liked toggled' }, // 클릭 이벤트 발생 시 로그 확인 + parameters: { + layout: 'fullscreen', + nextjs: { + appDirectory: true, + }, + docs: { + subtitle: '찜하기 버튼은 약속 카드에서 약속을 찜할 때 사용됩니다.', + description: { + component: '클릭해 찜한 상태 / 찜하지 않은 상태를 나타냅니다.', + }, + }, }, } satisfies Meta; export default meta; type Story = StoryObj; +// 기본적으로 찜하지 않은 상태 export const Default: Story = { args: { id: 1, - isLiked: false, // 기본적으로 찜하지 않은 상태 + isLiked: false, }, }; +// 찜한 상태로 시작, 사이즈 작음 export const Liked: Story = { args: { id: 2, - isLiked: true, // 찜한 상태로 시작 + isLiked: true, size: 32, }, }; diff --git a/src/components/common/crew-list/crew-card-list.tsx b/src/components/common/crew-list/crew-card-list.tsx index 50594e7b..e9bce663 100644 --- a/src/components/common/crew-list/crew-card-list.tsx +++ b/src/components/common/crew-list/crew-card-list.tsx @@ -27,9 +27,10 @@ export default function CrewCardList({ data, inWhere }: CrewCardListProps) { if (!crewDataList.length) return ( -
      -

      데이터가 없습니다.

      -
      +
      +

      크루가 아직 없어요

      +

      크루를 만들어서 함께 운동할 사람을 모집해보세요! 🙌

      +
      ); return ( diff --git a/src/components/common/gathering-card/gathering-card.stories.tsx b/src/components/common/gathering-card/gathering-card.stories.tsx index a860a9d1..5c557620 100644 --- a/src/components/common/gathering-card/gathering-card.stories.tsx +++ b/src/components/common/gathering-card/gathering-card.stories.tsx @@ -8,23 +8,19 @@ const meta: Meta = { title: 'gathering/gathering-card', component: GatheringCard, parameters: { - layout: 'fullscreen', + docs: { + subtitle: '약속을 확인할 수 있는 카드입니다.', + description: { + component: + '약속에 대한 간단한 정보를 알 수 있습니다. 크루 디테일 페이지와 찜한 약속에서 사용합니다.', + }, + }, backgrounds: { default: 'light-gray', values: [{ name: 'light-gray', value: '#F9FAFB' }], }, }, tags: ['autodocs'], - argTypes: { - title: { control: 'text' }, - dateTime: { control: 'date' }, - location: { control: 'text' }, - currentCount: { control: 'number' }, - totalCount: { control: 'number' }, - imageUrl: { control: 'text' }, - liked: { control: 'boolean' }, - className: { control: false }, - }, decorators: [ (Story) => ( @@ -39,27 +35,12 @@ type Story = StoryObj; export const Default: Story = { args: { - title: '가나다라마가나다라마가나다라마가', - dateTime: '2024-11-30T00:30', - location: '서울, 한강공원', - currentCount: 8, - totalCount: 12, - imageUrl: - 'https://images.unsplash.com/photo-1601758260892-a62c486ace97?q=80&w=1470&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D', - liked: true, - }, -}; - -// 좋아요가 눌리지 않은 모임 카드 -export const NotLiked: Story = { - args: { - title: '등산 모임', - dateTime: '2024-12-12T09:00', - location: '서울, 한강공원', - currentCount: 5, - totalCount: 10, - imageUrl: - 'https://images.unsplash.com/photo-1517849845537-4d257902454a?q=80&w=1470&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D', + title: '서핑모임', + dateTime: '2024-12-10T08:00:00.000', + location: '서울 강남구 삼성동', + currentCount: 1, + totalCount: 5, + imageUrl: 'https://i.pinimg.com/736x/00/6d/4b/006d4bb521a737534e37a8af3203a7d3.jpg', liked: false, }, }; @@ -67,13 +48,12 @@ export const NotLiked: Story = { // 마감된 모임 카드 export const PastEvent: Story = { args: { - title: '마감된 모임입니다', - dateTime: '2024-10-15T07:30', - location: '서울, 한강공원', - currentCount: 12, - totalCount: 12, - imageUrl: - 'https://images.unsplash.com/photo-1517849845537-4d257902454a?q=80&w=1470&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D', + title: '서핑모임', + dateTime: '2024-02-10T08:00:00.000', + location: '서울 강남구 삼성동', + currentCount: 1, + totalCount: 5, + imageUrl: 'https://i.pinimg.com/736x/00/6d/4b/006d4bb521a737534e37a8af3203a7d3.jpg', liked: false, }, }; @@ -81,13 +61,12 @@ export const PastEvent: Story = { // 찜한 모임 카드 export const LikedEvent: Story = { args: { - title: '조깅 모임', - dateTime: '2024-12-15T07:30', - location: '서울, 한강공원', - currentCount: 8, - totalCount: 12, - imageUrl: - 'https://images.unsplash.com/photo-1601758260892-a62c486ace97?q=80&w=1470&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D', + title: '서핑모임', + dateTime: '2024-12-10T08:00:00.000', + location: '서울 강남구 삼성동', + currentCount: 1, + totalCount: 5, + imageUrl: 'https://i.pinimg.com/736x/00/6d/4b/006d4bb521a737534e37a8af3203a7d3.jpg', liked: true, }, }; diff --git a/src/components/common/header/header.stories.tsx b/src/components/common/header/header.stories.tsx index c91643fb..171548bd 100644 --- a/src/components/common/header/header.stories.tsx +++ b/src/components/common/header/header.stories.tsx @@ -7,8 +7,12 @@ const meta: Meta = { component: Header, tags: ['autodocs'], parameters: { - nextjs: { - appDirectory: true, + docs: { + subtitle: '화면 최상단에 위치한 헤더', + description: { + component: + "'로고, 크루찾기, 나의크루, 나의약속, 로그인/마이페이지/로그아웃'으로 구성되어 있으며 해당페이지로 연결됩니다.", + }, }, }, }; @@ -33,7 +37,7 @@ Home.parameters = { }, docs: { description: { - story: '사용자가 로그아웃 상태이며 기본 경로(/)에 있는 경우', + story: '사용자가 기본 경로(/)에 있는 경우', }, }, }; @@ -49,7 +53,7 @@ MyCrew.parameters = { }, docs: { description: { - story: '사용자가 로그인 상태일 때 "나의 크루" 경로로 이동(+테스트용 버튼 클릭)', + story: '사용자가 "나의 크루" 경로에 있는 경우', }, }, }; @@ -65,7 +69,23 @@ MyGathering.parameters = { }, docs: { description: { - story: '사용자가 로그인 상태일 때 "나의 모임" 경로로 이동(+테스트용 버튼 클릭)', + story: '사용자가 "나의 약속" 경로에 있는 경우', + }, + }, +}; + +// 3. 로그인 상태에서 나의 모임 (/my-favorite) 경로 +export const MyFavorite: StoryFn = Template.bind({}); +MyFavorite.parameters = { + nextjs: { + navigation: { + pathname: '/my-favorite', + query: {}, + }, + }, + docs: { + description: { + story: '사용자가 "찜한 약속" 경로에 있는 경우', }, }, }; diff --git a/src/components/common/input/calendar-filter/calendar-filter.stories.tsx b/src/components/common/input/calendar-filter/calendar-filter.stories.tsx index 68f644d7..6656d034 100644 --- a/src/components/common/input/calendar-filter/calendar-filter.stories.tsx +++ b/src/components/common/input/calendar-filter/calendar-filter.stories.tsx @@ -4,12 +4,7 @@ import type { Meta, StoryFn } from '@storybook/react'; import { userEvent, within } from '@storybook/test'; import CalendarFilter, { CalendarFilterProps } from '.'; -const mockData = [ - new Date('2024-10-01'), - new Date('2024-10-05'), - new Date('2024-10-12'), - new Date('2024-10-15'), -]; +const mockData = [new Date()]; const meta: Meta = { title: 'common/calendar/calendar-filter', @@ -20,7 +15,14 @@ const meta: Meta = { type: { name: 'string' }, description: '선택된 날짜', }, - toDoDates: mockData, + toDoDates: { + description: '일정이 있는 날짜', + table: { + type: { + summary: 'Date[] | null', + }, + }, + }, onChange: action('onChange'), }, parameters: { diff --git a/src/components/common/input/calendar-filter/index.tsx b/src/components/common/input/calendar-filter/index.tsx index 26ad4047..874c8a5f 100644 --- a/src/components/common/input/calendar-filter/index.tsx +++ b/src/components/common/input/calendar-filter/index.tsx @@ -12,6 +12,13 @@ export interface CalendarFilterProps { onChange: (date: Date) => void; } +/** + * 달력에서 날짜를 선택하면 값을 변경할 수 있는 컴포넌트 + * @param {Date} value - 선택된 날짜 + * @param {Date[] | null} toDoDates - 일정이 있는 날짜 + * @param {(date: Date) => void} onChange - 값이 변경될 때 실행하는 함수 + */ + export default function CalendarFilter({ value, toDoDates, diff --git a/src/components/common/input/date-time-picker/index.tsx b/src/components/common/input/date-time-picker/index.tsx index e959f59d..990f1a6e 100644 --- a/src/components/common/input/date-time-picker/index.tsx +++ b/src/components/common/input/date-time-picker/index.tsx @@ -12,6 +12,12 @@ export interface DateTimePickerProps { onChange: (date: string) => void; } +/** + * 달력에서 날짜를 선택하고, 드롭다운으로 시간을 선택하면 날짜/시간 값을 변경할 수 있는 컴포넌트 + * @param {Date} fullDate - 선택된 날짜 + * @param {(date: string) => void} onChange - 값이 변경될 때 실행하는 함수 + */ + export default function DateTimePicker({ fullDate, onChange }: DateTimePickerProps) { const [selected, setSelected] = useState(fullDate || new Date()); const [hour, setHour] = useState('시'); diff --git a/src/components/common/input/drop-down/drop-down.stories.tsx b/src/components/common/input/drop-down/drop-down.stories.tsx index e29e98e8..838f0d48 100644 --- a/src/components/common/input/drop-down/drop-down.stories.tsx +++ b/src/components/common/input/drop-down/drop-down.stories.tsx @@ -13,22 +13,57 @@ const meta: Meta = { }, value: { description: '선택된 값', + table: { + type: { + summary: 'string | null', + }, + }, }, data: { description: '옵션 데이터 배열', }, variant: { - description: '`default` | `sort`', + description: '컴포넌트 타입', control: { type: 'radio', option: ['default', 'sort'], }, + table: { + type: { + summary: 'default | sort', + }, + }, }, placeholder: { description: '선택된 값이 없을 때 표시하는 문자열', }, - onChange: { - description: '값이 변경될 때 실행하는 함수', + onChange: action('onChange'), + errorMsg: { + description: '에러 메시지', + table: { + type: { + summary: 'string | null', + }, + }, + }, + inWhere: { + description: '컴포넌트 사용 위치', + control: { + type: 'radio', + option: ['default', 'form'], + }, + table: { + type: { + summary: 'default | form', + }, + }, + }, + }, + parameters: { + docs: { + description: { + component: '필터/정렬에 사용되는 드롭다운입니다.', + }, }, }, }; diff --git a/src/components/common/input/drop-down/index.tsx b/src/components/common/input/drop-down/index.tsx index fcde5af0..113e6bae 100644 --- a/src/components/common/input/drop-down/index.tsx +++ b/src/components/common/input/drop-down/index.tsx @@ -1,4 +1,4 @@ -import { LegacyRef, useEffect, useMemo, useRef, useState } from 'react'; +import { useEffect, useMemo, useRef, useState } from 'react'; import { ComboboxData, Select } from '@mantine/core'; import IconArrow from '@/public/assets/icons/ic-arrow'; @@ -11,11 +11,24 @@ export interface DropDownProps { value: string | null; onChange: (newValue: string | null) => void; className?: string; - inWhere?: string; - error?: string | null; - ref?: LegacyRef; + inWhere?: 'default' | 'form'; + errorMsg?: string | null; } +/** + * 드롭다운 컴포넌트 : 필터, 정렬 등에 사용 + * @param {string} id - 컴포넌트 id + * @param {'default' | 'sort'} variant - 컴포넌트 타입 + * @param {ComboboxData} data - 옵션 데이터 배열 + * @param {string} name - 컴포넌트 name + * @param {string} placeholder - 선택된 값이 없을 때 표시하는 문자열 + * @param {string | null} value - 선택된 값 + * @param {(newValue: string | null) => void} onChange - 값이 변경될 때 실행하는 함수 + * @param {string} className - 컴포넌트 wrapper에 추가하는 클래스명 + * @param {'default' | 'form'} inWhere - 컴포넌트 위치 + * @param {string | null} errorMsg - 에러 메시지 + */ + export default function DropDown({ id, inWhere = 'default', @@ -26,7 +39,7 @@ export default function DropDown({ onChange, placeholder, className, - error, + errorMsg, ...rest }: DropDownProps) { const [currentValue, setCurrentValue] = useState(value); @@ -76,7 +89,7 @@ export default function DropDown({ return (