Skip to content

[WRFE-70](feat): 래플, 이벤트 생성과정에 필요한 API 연동 #84

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

Open
wants to merge 14 commits into
base: dev
Choose a base branch
from

Conversation

eric-hjh
Copy link
Contributor

@eric-hjh eric-hjh commented Feb 24, 2025

📖 개요

💻 작업사항

래플 / 이벤트 API

  • 생성 API 연동

태그 API

  • 태그 조회
  • 태그 생성

카테고리 API

  • 카테고리 조회

이미지 API

  • 이미지 업로드

💡 작성한 이슈 외에 작업한 사항

API 연동 외에 추가한 사항

  • 생성 단계중 날짜 선택하는 단계에서 날짜 + 시간으로 변경
    -> 변경 전 : 시간은 자동으로 24:00으로 들어감
    변경 후 : 시간을 설정함으로 원하는 시간에 당첨 및 마감 가능

✔️ check list

  • 작성한 이슈의 내용을 전부 적용했나요?
  • 리뷰어를 등록했나요?

@eric-hjh eric-hjh marked this pull request as draft February 24, 2025 21:35
@eric-hjh eric-hjh changed the title [WRFE-70](feat): 래플, 이벤트 생성과정에 필요한 API 연 [WRFE-70](feat): 래플, 이벤트 생성과정에 필요한 API 연동 Feb 24, 2025
Comment on lines 26 to 30
export const useTagQuery = ({itemsPerPage, uuid, prefix}: TagQueryParams) =>
useQuery({
queryKey: ['tags', itemsPerPage, uuid, prefix],
queryFn: () => fetchTags({itemsPerPage, uuid, prefix}),
});
Copy link
Member

Choose a reason for hiding this comment

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

tag 목록 조회 API가 Pagination API인 것 같은데 useQuery를 사용하신 이유가 있나요??
useInfiniteQuery 또는 useSuspenseInifniteQuery를 사용해서 구현할 수 있을 것 같아서요!

Copy link
Contributor Author

@eric-hjh eric-hjh Apr 27, 2025

Choose a reason for hiding this comment

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

4cfd2d8
페이지 네이션 적용 수정 커밋입니다

Comment on lines 28 to 77
const [inputValue, setInputValue] = useState(''); // 입력하는 값
const debouncedInputValue = useDebounce(inputValue);

const [autocompleteTags, setAutocompleteTags] = useState<TagList[]>([]); // 서버에서 받아오는 태그 리스트

const [isNew, setIsNew] = useState<boolean>(true); // 새로 생성할지 말지

const [selectedTagNames, setSelectedTagNames] = useState<string[]>([]); // 화면에 보여지는 태그 리스트

const {mutateAsync: createTag} = useCreateTag();
const {isPending: isQueryPending, data} = useTagQuery({
itemsPerPage: 100, //
uuid: '',
prefix: debouncedInputValue.toLocaleLowerCase(),
});
const serverTags = data?.items;

useEffect(() => {
if (!serverTags) return;

setIsNew(true);

const isExistingTag = serverTags.some(tag => tag.name === inputValue);

if (isExistingTag) {
const suggestions = serverTags.filter(tag => tag.name !== inputValue);
setAutocompleteTags(suggestions);
setIsNew(false);
} else {
setAutocompleteTags(serverTags);
}
}, [data, inputValue, serverTags]);

const handleAddTag = async (tag: string, id: number) => {
if (selectedTagNames.length >= 5 || selectedTagNames.includes(tag)) {
setInputValue('');
return;
}

if (isNew && id === 0) {
createTagAndAddToList({tag, createTag, tagIds, onTagChange});
} else if (!isNew && id === 0) {
addTagFromUserInputIfDuplicate({tag, serverTags, tagIds, onTagChange});
} else {
addTagFromServerData({id, tagIds, onTagChange});
}

setSelectedTagNames(prev => [...prev, tag]);
setInputValue('');
};
Copy link
Member

Choose a reason for hiding this comment

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

비지니스 로직을 hook으로 추상화 시키는건 어떨까요?!
특히 features 레이어에서 util에서 만든 유틸 함수들이 굳이 분리될 필요 없이 hook 내부에서 정의하고 사용해도 괜찮을 것 같다는 생각이 듭니다!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

0a397fa
수정 커밋입니다!

Comment on lines 10 to 48
export const createTagAndAddToList = async ({
tag,
createTag,
tagIds,
onTagChange,
}: CreateTagAndAddToList) => {
try {
const response = await createTag(tag);
onTagChange([...tagIds, response.id]);
} catch (error) {
console.error('error:', error);
}
};

/**
* id를 서버에서 받아온 태그 추가하는 곳
* but 서버에서 받아온 리스트중 사용자 입력값과 중복된 값은 리스트에서 제거하고 맨 위로 올리기 때문에
* id를 찾아서 제출태그 리스트에 넣어줌
*/
export const addTagFromUserInputIfDuplicate = ({
tag,
serverTags,
tagIds,
onTagChange,
}: AddTagFromUserInputIfDuplicate) => {
const foundid = serverTags?.find(item => item.name === tag)?.id ?? 0;
onTagChange([...tagIds, foundid]);
};

/**
* id를 서버에서 받아온 태그 추가하는 곳
*/
export const addTagFromServerData = ({
id,
tagIds,
onTagChange,
}: AddTagFromServerData) => {
onTagChange([...tagIds, id]);
};
Copy link
Member

Choose a reason for hiding this comment

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

유틸 함수들을 features 레이어에서 분리하기 보다 사용하는 widgets 레이어에서 커스텀훅으로 포함시키는게 어떨까요??
widgets 레이어 안에 UI 안에서 비지니스 로직으로 드러내기 보다 내부적으로 hook으로 추상화시킨다면 해당 파일에 정의할 필요는 없을 것 같아요!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

위 리뷰 커밋과 동일합니다!

const categoryItems = [
{
value: '1',
name: '생활',
},
{
value: '2',
name: '가전-디지탈',
},
{
value: '3',
name: '행사',
},
{
value: '4',
name: '당일마감',
},
];
const {data: categoryItems} = useCategoryQuery();

const tags = ['tag1', 'tag2'];
if (!categoryItems) {
return <div>loading...</div>;
}
Copy link
Member

Choose a reason for hiding this comment

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

꼭 필요하진 않지만 Suspense를 사용해서 로딩을 선언적으로 처리하는 것도 깔끔할 것 같아요!
그러기 위해서는 useCategoryQuery 내부에서 useQuery 대신 useSuspenseQuery를 사용할 수 있습니다 🙂

Copy link
Contributor Author

Choose a reason for hiding this comment

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

funnel 사용 시 ReferenceError: window is not defined로 인해 500 에러가 발생하는걸 해결하기 위해 ssr: false 옵션을 적용하여 해결하였는데 
이 과정에서, 클라이언트 컴포넌트에서 서버 액션을 호출해야 하는 구조가 생기면서 고려사항이 생겼는데, 이 부분을 우선은 논이슈로 두고, 현재는 useQuery를 사용하는 방식으로 유지하다가 추후에 useSuspenseQuery로 리팩토링해보면 좋을 것 같은데 어떻게 생각하시나요?

@eric-hjh eric-hjh marked this pull request as ready for review April 27, 2025 11:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants