|
1 | 1 | <template> |
2 | 2 | <div class="w-full flex flex-col gap-y-6"> |
3 | | - <RequestTaskDropdown |
| 3 | + <CategoryDropDown |
4 | 4 | v-model="category1" |
5 | | - :options="DUMMY_REQUEST_TASK_CATEGORIES" |
| 5 | + :options="mainCategoryArr" |
6 | 6 | :label-name="'1차 카테고리'" |
7 | | - :placeholderText="'1차 카테고리를 선택해주세요'" /> |
8 | | - <RequestTaskDropdown |
| 7 | + :isInvalidate="isInvalidate" |
| 8 | + :isDisabled="false" /> |
| 9 | + <CategoryDropDown |
9 | 10 | v-model="category2" |
10 | | - :options="DUMMY_REQUEST_TASK_CATEGORIES" |
| 11 | + :options="afterSubCategoryArr" |
11 | 12 | :label-name="'2차 카테고리'" |
12 | | - :placeholderText="'2차 카테고리를 선택해주세요'" /> |
| 13 | + :is-invalidate="isInvalidate" |
| 14 | + :isDisabled="!category1" /> |
13 | 15 | <RequestTaskInput |
14 | 16 | v-model="title" |
15 | | - :placeholderText="TITLE_PLACEHOLDER" |
16 | | - :label-name="'제목'" /> |
| 17 | + :placeholderText="'제목을 입력해주세요'" |
| 18 | + :label-name="'제목'" |
| 19 | + :is-invalidate="isInvalidate" /> |
17 | 20 | <RequestTaskTextArea |
18 | 21 | v-model="description" |
19 | | - :placeholderText="EXPLANATION_PLACEHOLDER" /> |
| 22 | + :placeholderText="'부가 정보를 입력해주세요'" /> |
20 | 23 | <RequestTaskFileInput v-model="file" /> |
21 | 24 | <FormButtonContainer |
22 | 25 | :handleCancel="handleCancel" |
23 | 26 | :handleSubmit="handleSubmit" |
24 | 27 | cancelText="취소" |
25 | 28 | submitText="요청" /> |
| 29 | + <ModalView |
| 30 | + :isOpen="isModalVisible" |
| 31 | + :type="'successType'" |
| 32 | + @close="handleCancel"> |
| 33 | + <template #header>작업이 요청되었습니다</template> |
| 34 | + </ModalView> |
26 | 35 | </div> |
27 | 36 | </template> |
28 | 37 |
|
29 | 38 | <script lang="ts" setup> |
30 | | -import { EXPLANATION_PLACEHOLDER, TITLE_PLACEHOLDER } from '@/constants/user' |
31 | | -import { DUMMY_REQUEST_TASK_CATEGORIES } from '@/datas/taskdetail' |
32 | | -import { ref } from 'vue' |
| 39 | +import { getMainCategory, getSubCategory } from '@/api/common' |
| 40 | +import { postTaskRequest } from '@/api/user' |
| 41 | +import type { MainCategoryTypes, SubCategoryTypes } from '@/types/common' |
| 42 | +import { onMounted, ref, watch } from 'vue' |
| 43 | +import { useRouter } from 'vue-router' |
33 | 44 | import FormButtonContainer from '../common/FormButtonContainer.vue' |
34 | | -import RequestTaskDropdown from './RequestTaskDropdown.vue' |
| 45 | +import ModalView from '../ModalView.vue' |
| 46 | +import CategoryDropDown from './CategoryDropDown.vue' |
35 | 47 | import RequestTaskFileInput from './RequestTaskFileInput.vue' |
36 | 48 | import RequestTaskInput from './RequestTaskInput.vue' |
37 | 49 | import RequestTaskTextArea from './RequestTaskTextArea.vue' |
38 | | -import { useRouter } from 'vue-router' |
39 | 50 |
|
40 | | -const category1 = ref('1차 카테고리를 선택해주세요') |
41 | | -const category2 = ref('2차 카테고리를 선택해주세요') |
| 51 | +const category1 = ref<MainCategoryTypes | null>(null) |
| 52 | +const category2 = ref<MainCategoryTypes | null>(null) |
| 53 | +
|
42 | 54 | const title = ref('') |
43 | 55 | const description = ref('') |
44 | 56 | const file = ref(null as File[] | null) |
| 57 | +const isInvalidate = ref('') |
| 58 | +const isModalVisible = ref(false) |
| 59 | +
|
| 60 | +const mainCategoryArr = ref<MainCategoryTypes[]>([]) |
| 61 | +const subCategoryArr = ref<SubCategoryTypes[]>([]) |
| 62 | +const afterSubCategoryArr = ref<SubCategoryTypes[]>([]) |
| 63 | +
|
| 64 | +onMounted(async () => { |
| 65 | + mainCategoryArr.value = await getMainCategory() |
| 66 | + subCategoryArr.value = await getSubCategory() |
| 67 | + afterSubCategoryArr.value = await getSubCategory() |
| 68 | +}) |
| 69 | +
|
| 70 | +watch(category1, async newValue => { |
| 71 | + category2.value = null |
| 72 | + afterSubCategoryArr.value = subCategoryArr.value.filter( |
| 73 | + subCategory => subCategory.mainCategoryId === newValue?.id |
| 74 | + ) |
| 75 | +}) |
45 | 76 |
|
46 | 77 | const router = useRouter() |
| 78 | +
|
47 | 79 | const handleCancel = () => { |
48 | | - category1.value = '' |
49 | | - category2.value = '' |
| 80 | + category1.value = null |
| 81 | + category2.value = null |
50 | 82 | title.value = '' |
51 | 83 | description.value = '' |
52 | | - file.value = null |
| 84 | + file.value = [] |
53 | 85 | router.back() |
54 | 86 | } |
55 | 87 |
|
56 | | -const handleSubmit = () => { |
| 88 | +const handleSubmit = async () => { |
| 89 | + if (!category1.value || !category2.value) { |
| 90 | + isInvalidate.value = 'category' |
| 91 | + console.log(isInvalidate.value, '변경됨') |
| 92 | + return |
| 93 | + } else if (!title.value) { |
| 94 | + isInvalidate.value = 'input' |
| 95 | + return |
| 96 | + } |
57 | 97 | const formData = new FormData() |
58 | | - formData.append('category1', category1.value) |
59 | | - formData.append('category2', category2.value) |
60 | | - formData.append('title', title.value) |
61 | | - formData.append('description', description.value) |
62 | | - if (file.value) { |
63 | | - file.value.forEach(f => { |
64 | | - formData.append('file', f) |
65 | | - }) |
| 98 | + const taskInfo = { |
| 99 | + categoryId: category2.value.id, |
| 100 | + title: title.value, |
| 101 | + description: description.value |
| 102 | + } |
| 103 | +
|
| 104 | + const jsonTaskInfo = JSON.stringify(taskInfo) |
| 105 | + const newBlob = new Blob([jsonTaskInfo], { type: 'application/json' }) |
| 106 | +
|
| 107 | + formData.append('taskInfo', newBlob) |
| 108 | +
|
| 109 | + if (file.value && file.value.length > 0) { |
| 110 | + file.value.forEach(f => formData.append('attachment', f)) |
| 111 | + } |
| 112 | + try { |
| 113 | + const res = await postTaskRequest(formData) |
| 114 | + isModalVisible.value = true |
| 115 | + console.error('요청 성공:', res) |
| 116 | + } catch (error) { |
| 117 | + console.error('요청 실패:', error) |
66 | 118 | } |
67 | | - console.log(Object.fromEntries(formData)) |
68 | 119 | } |
69 | 120 | </script> |
0 commit comments