Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5,175 changes: 2,097 additions & 3,078 deletions package-lock.json

Large diffs are not rendered by default.

Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
11 changes: 11 additions & 0 deletions public/assets/images/crew-sample/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import ImgCrewSample01 from './crew-sample-1.jpg';
import ImgCrewSample02 from './crew-sample-2.jpg';
import ImgCrewSample03 from './crew-sample-3.jpg';

const ImgCrewSamples = [
ImgCrewSample01,
ImgCrewSample02,
ImgCrewSample03,
];

export default ImgCrewSamples;
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
11 changes: 11 additions & 0 deletions public/assets/images/gathering-sample/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import ImgGatheringSample01 from './gathering-sample-1.jpg';
import ImgGatheringSample02 from './gathering-sample-2.jpg';
import ImgGatheringSample03 from './gathering-sample-3.jpg';

const ImgGatheringSamples = [
ImgGatheringSample01,
ImgGatheringSample02,
ImgGatheringSample03,
];

export default ImgGatheringSamples;
25 changes: 25 additions & 0 deletions src/_apis/crew/get-crew-list.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { fetchApi } from '@/src/utils/api';
import { CrewCardInform, CrewCardInformResponse } from '@/src/types/crew-card';

export async function getCrewList(page: number, limit: number): Promise<CrewCardInformResponse> {
try {
const response = await fetchApi<CrewCardInformResponse>(
`/crews?_page=${page + 1}&_limit=${limit}`,
{
method: 'GET',
headers: {
'Content-Type': 'application/json',
},
},
);
if (!Array.isArray(response)) {
throw new Error('서버 응답이 올바른 형식이 아닙니다.');
}
const data = response as CrewCardInform[];
const hasNextPage = data.length === limit;

return { data, hasNextPage };
} catch (error) {
throw new Error('크루 리스트를 불러오는데 실패했습니다.');
}
}
4 changes: 2 additions & 2 deletions src/_queries/crew-queries.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { getCrewData } from '@/src/app/api/mock-api/crew';
import { CrewCardInform } from '@/src/types/crew-card';
import { getCrewList } from '../_apis/crew/get-crew-list';

// Crew data 변환 로직을 간소화한 helper 함수
const mapCrewData = (crew: CrewCardInform) => ({
Expand Down Expand Up @@ -31,7 +31,7 @@ export function useGetCrewQuery() {

return {
queryKey: ['crew'],
queryFn: ({ pageParam = 0 }: QueryParams) => getCrewData(pageParam, 3),
queryFn: ({ pageParam = 0 }: QueryParams) => getCrewList(pageParam, 3),
getNextPageParam: (lastPage: Page, allPages: Page[]) =>
lastPage.hasNextPage ? allPages.length + 1 : undefined,
select: (data: CrewCardInform[]) => data.map(mapCrewData),
Expand Down
19 changes: 12 additions & 7 deletions src/app/(crew)/crew/_components/create-crew-form/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ 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 { CreateCrewRequestTypes } from '@/src/types/create-crew';
import ImgCrewSamples from '@/public/assets/images/crew-sample';

export interface CreateCrewFormTypes {
data: CreateCrewRequestTypes;
Expand All @@ -37,7 +38,8 @@ export default function CreateCrewForm({
mode: 'onBlur',
});

const isFormValid = Object.keys(errors).length === 0;
const isFormValid = Object.keys(errors).length === 0 && Object.values(data).every(Boolean);

const [categoryIndex, setCategoryIndex] = useState(0);
const [regionIndex, setRegionIndex] = useState(0);

Expand All @@ -46,17 +48,16 @@ export default function CreateCrewForm({
const mainLocation = useWatch({ control, name: 'mainLocation' });

const handleMainCategoryChange = (newValue: string | null) => {
setValue('mainCategory', newValue);
setValue('subCategory', null);
setValue('mainCategory' as const, newValue as CreateCrewRequestTypes['mainCategory']);
setValue('subCategory' as const, null as CreateCrewRequestTypes['subCategory']);
clearErrors('subCategory');
};

const handleMainLocationChange = (newValue: string | null) => {
setValue('mainLocation', newValue);
setValue('subLocation', null);
setValue('mainLocation' as const, newValue as CreateCrewRequestTypes['mainLocation']);
setValue('subLocation' as const, null as CreateCrewRequestTypes['subLocation']);
clearErrors('subLocation');
};

useEffect(() => {
setCategoryIndex(categoryData.findIndex((category) => category.title.value === mainCategory));
setRegionIndex(regionData.findIndex((region) => region.main.value === mainLocation));
Expand Down Expand Up @@ -154,7 +155,11 @@ export default function CreateCrewForm({
control={control}
rules={{ required: '이미지를 선택해주세요.' }}
render={({ field }) => (
<FileInputWrap {...field} onChange={(newValue) => field.onChange(newValue)} />
<FileInputWrap
{...field}
sample={ImgCrewSamples}
onChange={(newValue) => field.onChange(newValue)}
/>
)}
/>
{errors.imageUrl && <p className="text-red-500">{errors.imageUrl.message}</p>}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ 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 { CreateGatheringRequestType } from '@/src/types/gathering-data';
import ImgGatheringSamples from '@/public/assets/images/gathering-sample';

export interface CreateGatheringFormTypes {
data: CreateGatheringRequestType;
Expand Down Expand Up @@ -89,6 +90,7 @@ export default function CreateGatheringForm({
</label>
<div className="flex">
<FileInputWrap
sample={ImgGatheringSamples}
value={values.imageUrl}
onChange={(newValue) =>
setValues((prevValues) => ({ ...prevValues, imageUrl: newValue }))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,18 @@ export default function CreateGatheringModalPresenter({
title="약속 잡기"
styles={{
root: { '--modal-size': '520px' },
content: { boxShadow: '0 25px 50px -12px rgba(0,0,0,0.1)', borderRadius: '12px' },
content: {
boxShadow: '0 25px 50px -12px rgba(0,0,0,0.1)',
borderRadius: '12px',
},
}}
classNames={{
body: 'p-0',
title: 'text-xl font-semibold text-gray-900',
}}
>
<div>
<ScrollArea h={640}>
<ScrollArea h={760}>
<div className="flex flex-col gap-8 p-6">
<CreateGatheringForm
data={data}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ export default function GatheringDetailModalPresenter({
}}
>
<div>
<ScrollArea h={640}>
<ScrollArea h={760}>
<figure className="relative aspect-video w-full overflow-hidden">
<Image
src={data?.imageUrl}
Expand Down
6 changes: 3 additions & 3 deletions src/app/(crew)/crew/create/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@ export default function CreateCrewPage() {
const initialValue: CreateCrewRequestTypes = {
title: '',
mainCategory: '',
subCategory: '',
subCategory: null,
imageUrl: null,
mainLocation: '',
subLocation: '',
totalCount: 0,
subLocation: null,
totalCount: 4,
};

const handleSubmit = () => {
Expand Down
13 changes: 4 additions & 9 deletions src/app/(crew)/my-crew/page.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
'use client';

import { useState } from 'react';
import { useGetCrewQuery } from '@/src/_queries/crew-queries';
import { useInfiniteScroll } from '@/src/hooks/useInfiniteScroll';
import { fetchCrewData } from '@/src/app/api/mock-api/crew';
import CrewCardList from '@/src/components/common/crew-list/crew-card-list';
import Tabs from '@/src/components/common/tab';
import { CrewCardInformResponse } from '@/src/types/crew-card';
Expand All @@ -15,14 +15,9 @@ export default function MyCrewPage() {
const [currentTab, setCurrentTab] = useState(myPageTabs[0].id);

// TODO: fetchCrewData 함수를 사용하여 데이터를 불러오기 : 파라미터 수정 필요
const { data, ref, isFetchingNextPage } = useInfiniteScroll<CrewCardInformResponse>({
queryKey: ['crew'],
queryFn: ({ pageParam = 0 }) => {
return fetchCrewData(pageParam, 3);
},
getNextPageParam: (lastPage, allPages) =>
lastPage.hasNextPage ? allPages.length + 1 : undefined,
});
const { data, ref, isFetchingNextPage } =
useInfiniteScroll<CrewCardInformResponse>(useGetCrewQuery());

return (
<div className="py-8 md:py-12.5">
<div className="px-3 md:px-8 lg:px-11.5">
Expand Down
42 changes: 0 additions & 42 deletions src/app/api/mock-api/crew.ts

This file was deleted.

14 changes: 4 additions & 10 deletions src/components/common/crew-list/crew-card-list.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import type { Meta, StoryObj } from '@storybook/react';
import { useGetCrewQuery } from '@/src/_queries/crew-queries';
import { useInfiniteScroll } from '@/src/hooks/useInfiniteScroll';
import { fetchCrewData } from '@/src/app/api/mock-api/crew';
import ClientProvider from '@/src/components/client-provider';
import { CrewCardInformResponse } from '@/src/types/crew-card';
import ClientProvider from '../../client-provider';
import CrewCardList from './crew-card-list';

const meta: Meta = {
Expand All @@ -28,14 +28,8 @@ export default meta;
type Story = StoryObj<typeof meta>;

function RenderCrewCardList() {
const { data, ref, isFetchingNextPage } = useInfiniteScroll<CrewCardInformResponse>({
queryKey: ['crew'],
queryFn: ({ pageParam = 0 }) => {
return fetchCrewData(pageParam, 3);
},
getNextPageParam: (lastPage, allPages) =>
lastPage.hasNextPage ? allPages.length + 1 : undefined,
});
const { data, ref, isFetchingNextPage } =
useInfiniteScroll<CrewCardInformResponse>(useGetCrewQuery());

return <CrewCardList data={data} ref={ref} isFetchingNextPage={isFetchingNextPage} />;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { useState } from 'react';
import { StaticImageData } from 'next/image';
import { action } from '@storybook/addon-actions';
import { Meta, StoryFn } from '@storybook/react';
import FileInput, { FileInputProps } from '.';
Expand All @@ -25,7 +26,7 @@ const meta: Meta = {
export default meta;

const Template: StoryFn<FileInputProps> = function FileInputStory() {
const [fileValue, setFileValue] = useState<File | null>(null);
const [fileValue, setFileValue] = useState<File | StaticImageData | null>(null);
const [isBlur, setIsBlur] = useState(false);

return (
Expand Down Expand Up @@ -54,7 +55,7 @@ export const FileInput01 = Template.bind({});
FileInput01.args = {
value: null,
isBlur: false,
onChange: (newValue: File | null) => {
onChange: (newValue: File | StaticImageData | null) => {
action('onChange')({ image: newValue });
},
Comment on lines +58 to 60
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

onChange 핸들러의 타입 정의와 구현에 대한 개선이 필요합니다.

현재 구현에서 몇 가지 개선할 점이 있습니다:

  1. 타입 안전성: action 호출 시 객체 래핑이 불필요할 수 있습니다
  2. 일관성: 다른 곳에서는 직접 값을 전달하는데 여기서만 객체로 감싸고 있습니다

다음과 같이 수정하는 것을 제안드립니다:

-  onChange: (newValue: File | StaticImageData | null) => {
-    action('onChange')({ image: newValue });
-  },
+  onChange: (newValue: File | StaticImageData | null) => {
+    action('onChange')(newValue);
+  },
📝 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.

Suggested change
onChange: (newValue: File | StaticImageData | null) => {
action('onChange')({ image: newValue });
},
onChange: (newValue: File | StaticImageData | null) => {
action('onChange')(newValue);
},

};
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { ChangeEvent, useEffect, useRef, useState } from 'react';
import Image from 'next/image';
import Image, { StaticImageData } from 'next/image';
import IcoPlus from '@/public/assets/icons/ic-plus.svg';
import IcoX from '@/public/assets/icons/ic-x.svg';

export interface FileInputProps {
value: File | null;
onChange: (value: File | null) => void;
value: File | StaticImageData | null;
onChange: (value: File | StaticImageData | null) => void;
isBlur: boolean;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
import { useState } from 'react';
import { StaticImageData } from 'next/image';
import { action } from '@storybook/addon-actions';
import { Meta, StoryFn } from '@storybook/react';
import ImgCrewSamples from '@/public/assets/images/crew-sample';
import FileSample, { FileSampleProps } from '.';

const meta: Meta = {
title: 'Components/input/file-sample',
component: FileSample,
argTypes: {
imgUrl: {
image: {
control: 'text',
description: '샘플 이미지 URL',
},
Expand All @@ -24,13 +26,11 @@ const meta: Meta = {

export default meta;

const Template: StoryFn<FileSampleProps> = function FileInputStory(
args: FileSampleProps = { isBlur: false, imgUrl: '', onChange: () => {} },
) {
const [selectedFile, setSelectedFile] = useState<File | null>(null);
const Template: StoryFn<FileSampleProps> = function FileInputStory(args: FileSampleProps) {
const [selectedFile, setSelectedFile] = useState<File | StaticImageData | null>(null);
const [isBlur, setIsBlur] = useState(false);

const handleFileChange = (file: File | null) => {
const handleFileChange = (file: File | StaticImageData | null) => {
setSelectedFile(file);
setIsBlur(false); // 파일 선택 시 블러 해제
};
Expand All @@ -47,14 +47,12 @@ const Template: StoryFn<FileSampleProps> = function FileInputStory(
>
블러 토글
</button>
{!isBlur && <p>{selectedFile?.name}</p>}
</div>
);
};
export const FileSample01 = Template.bind({});
FileSample01.args = {
imgUrl:
'https://images.stockcake.com/public/a/7/6/a768d87b-1f99-4b50-9286-f1583af33522_large/team-huddle-celebration-stockcake.jpg',
image: ImgCrewSamples[0],
isBlur: false,
onChange: () => {
action('onChange');
Expand Down
Loading