|
1 |
| -import { |
2 |
| - useCreateTag, |
3 |
| - useTagQuery, |
4 |
| -} from '../../../../../features/product/tag/api/useTagQuery'; |
5 |
| -import {useEffect, useState} from 'react'; |
6 |
| -import { |
7 |
| - addTagFromServerData, |
8 |
| - addTagFromUserInputIfDuplicate, |
9 |
| - createTagAndAddToList, |
10 |
| -} from '@/features/product/tag/config/utils'; |
11 |
| -import {useDebounce} from '@/shared/hook'; |
| 1 | +import {useTagManagement} from '../../hooks/useTagManagement'; |
12 | 2 | import {InputWithSearchIcon} from '@/shared/ui/input/InputWithSearchIcon';
|
13 | 3 | import {Tags} from '@/shared/ui/tag/Tags';
|
14 | 4 | import {TAG_LIMIT} from '@/shared/util';
|
15 | 5 | import {Label} from '@wraffle/ui';
|
16 | 6 |
|
17 |
| -interface TagList { |
18 |
| - id: number; |
19 |
| - name: string; |
20 |
| -} |
21 |
| - |
22 | 7 | interface TagSectionProps {
|
23 | 8 | tagIds: number[];
|
24 | 9 | onTagChange: (newTags: number[]) => void;
|
25 | 10 | }
|
26 | 11 |
|
27 | 12 | export const TagSection = ({tagIds, onTagChange}: TagSectionProps) => {
|
28 |
| - const [inputValue, setInputValue] = useState(''); // 입력하는 값 |
29 |
| - const debouncedInputValue = useDebounce(inputValue); |
30 |
| - |
31 |
| - const [autocompleteTags, setAutocompleteTags] = useState<TagList[]>([]); // 서버에서 받아오는 태그 리스트 |
32 |
| - |
33 |
| - const [isNew, setIsNew] = useState<boolean>(true); // 새로 생성할지 말지 |
34 |
| - |
35 |
| - const [selectedTagNames, setSelectedTagNames] = useState<string[]>([]); // 화면에 보여지는 태그 리스트 |
36 |
| - |
37 |
| - const {mutateAsync: createTag} = useCreateTag(); |
38 |
| - const {isPending: isQueryPending, data} = useTagQuery({ |
39 |
| - itemsPerPage: 100, // |
40 |
| - uuid: '', |
41 |
| - prefix: debouncedInputValue.toLocaleLowerCase(), |
42 |
| - }); |
43 |
| - const serverTags = data?.items; |
44 |
| - |
45 |
| - useEffect(() => { |
46 |
| - if (!serverTags) return; |
47 |
| - |
48 |
| - setIsNew(true); |
49 |
| - |
50 |
| - const isExistingTag = serverTags.some(tag => tag.name === inputValue); |
51 |
| - |
52 |
| - if (isExistingTag) { |
53 |
| - const suggestions = serverTags.filter(tag => tag.name !== inputValue); |
54 |
| - setAutocompleteTags(suggestions); |
55 |
| - setIsNew(false); |
56 |
| - } else { |
57 |
| - setAutocompleteTags(serverTags); |
58 |
| - } |
59 |
| - }, [data, inputValue, serverTags]); |
60 |
| - |
61 |
| - const handleAddTag = async (tag: string, id: number) => { |
62 |
| - if (selectedTagNames.length >= 5 || selectedTagNames.includes(tag)) { |
63 |
| - setInputValue(''); |
64 |
| - return; |
65 |
| - } |
66 |
| - |
67 |
| - if (isNew && id === 0) { |
68 |
| - createTagAndAddToList({tag, createTag, tagIds, onTagChange}); |
69 |
| - } else if (!isNew && id === 0) { |
70 |
| - addTagFromUserInputIfDuplicate({tag, serverTags, tagIds, onTagChange}); |
71 |
| - } else { |
72 |
| - addTagFromServerData({id, tagIds, onTagChange}); |
73 |
| - } |
74 |
| - |
75 |
| - setSelectedTagNames(prev => [...prev, tag]); |
76 |
| - setInputValue(''); |
77 |
| - }; |
| 13 | + const { |
| 14 | + inputValue, |
| 15 | + setInputValue, |
| 16 | + selectedTagNames, |
| 17 | + setSelectedTagNames, |
| 18 | + autocompleteTags, |
| 19 | + isQueryPending, |
| 20 | + handleAddTag, |
| 21 | + } = useTagManagement({tagIds, onTagChange}); |
78 | 22 |
|
79 | 23 | return (
|
80 | 24 | <div className='relative'>
|
|
0 commit comments