Skip to content

Commit 9e43cd0

Browse files
authored
Merge pull request #66 from TaskFlow-CLAP/CLAP-218
CLAP-218 카테고리 추가 API 연결
2 parents 46a571e + 786292a commit 9e43cd0

File tree

4 files changed

+97
-56
lines changed

4 files changed

+97
-56
lines changed

src/components/request-task/RequestTaskInput.vue

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,29 @@
11
<template>
2-
<div>
2+
<div class="relative">
33
<div class="text-xs flex gap-x-1 mb-2">
44
<p class="text-body font-bold">{{ labelName }}</p>
55
<p
66
v-if="!isNotRequired"
77
class="text-red-1">
88
*
99
</p>
10-
<p
11-
v-if="isInvalidateState === 'input'"
12-
class="text-red-1">
13-
{{ labelName }}을 입력해주세요
14-
</p>
1510
</div>
1611
<input
1712
class="w-full h-11 border border-border-1 px-4 focus:outline-none text-black"
1813
:value="modelValue"
1914
:disabled="isEdit"
2015
@input="updateValue(($event.target as HTMLInputElement).value)"
2116
:placeholder="placeholderText" />
17+
<p
18+
v-if="isInvalidateState === 'input'"
19+
class="text-red-1 text-xs absolute top-[calc(100%+4px)]">
20+
{{ labelName }}을 입력해주세요
21+
</p>
22+
<p
23+
v-if="isInvalidateState === 'code'"
24+
class="text-red-1 text-xs absolute top-[calc(100%+4px)]">
25+
사용할 수 없는 고유코드입니다.
26+
</p>
2227
</div>
2328
</template>
2429

Lines changed: 79 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,69 +1,81 @@
11
<template>
22
<div class="w-full flex flex-col gap-y-6">
33
<ModalView
4-
:isOpen="isAddModalVisible"
5-
:type="'successType'"
4+
:is-open="isModalVisible.add"
5+
type="successType"
66
@close="handleAddModal">
77
<template #header>카테고리가 등록되었습니다</template>
88
</ModalView>
99
<ModalView
10-
:isOpen="isCancelModalVisible"
11-
:type="'warningType'"
10+
:is-open="isModalVisible.cancel"
11+
type="warningType"
1212
@close="handleCancelModal"
1313
@click="handleGoBack">
1414
<template #header>생성을 취소 하시겠습니까?</template>
1515
<template #body>작성하신 내용은 사라집니다</template>
1616
</ModalView>
17+
<ModalView
18+
:is-open="isModalVisible.fail"
19+
type="failType"
20+
@close="handleFailModal">
21+
<template #header>카테고리 정보를 확인해주세요</template>
22+
</ModalView>
1723
<!-- 카테고리 목록 API 필요, 임시로 역할로 설정 -->
1824
<RequestTaskDropdown
19-
v-model="categoryForm.firstCategory"
20-
:options="RoleKeys"
21-
:label-name="'1차 카테고리'"
22-
:placeholderText="'1차 카테고리를 선택해주세요'"
23-
v-if="props.categoryStep == '2'" />
25+
v-model="mainCategory"
26+
:options="categoryOptions.map(el => el.name)"
27+
label-name="1차 카테고리"
28+
placeholder-text="1차 카테고리를 선택해주세요"
29+
v-if="categoryStep == '2'" />
2430
<RequestTaskInput
2531
v-model="categoryForm.name"
26-
:placeholderText="'카테고리명을 입력해주세요'"
27-
:labelName="`${props.categoryStep}차 카테고리명`" />
32+
placeholder-text="카테고리명을 입력해주세요"
33+
:label-name="`${categoryStep}차 카테고리명`" />
2834
<RequestTaskInput
2935
v-model="categoryForm.code"
30-
:placeholderText="'카테고리의 고유코드를 입력해주세요'"
31-
:labelName="'고유코드 (대문자 영어 2글자까지)'" />
36+
placeholder-text="카테고리의 고유코드를 입력해주세요"
37+
label-name="고유코드 (대문자 영어 2글자까지)"
38+
:is-invalidate="isCodeInvalidate" />
3239

3340
<FormButtonContainer
34-
:handleCancel="handleCancel"
35-
:handleSubmit="handleSubmit"
36-
cancelText="취소"
37-
submitText="생성" />
41+
:handle-cancel="handleCancel"
42+
:handle-submit="handleSubmit"
43+
cancel-text="취소"
44+
submit-text="생성" />
3845
</div>
3946
</template>
4047

4148
<script lang="ts" setup>
42-
import { CATEGORY_FIRST_ADD, CATEGORY_SECOND_ADD, RoleKeys } from '@/constants/admin'
43-
import { ref } from 'vue'
49+
import { CATEGORY_FORM } from '@/constants/admin'
50+
import { computed, onMounted, ref, watch } from 'vue'
4451
import { useRouter } from 'vue-router'
4552
import FormButtonContainer from '../common/FormButtonContainer.vue'
4653
import ModalView from '../ModalView.vue'
4754
import RequestTaskDropdown from '../request-task/RequestTaskDropdown.vue'
4855
import RequestTaskInput from '../request-task/RequestTaskInput.vue'
56+
import { axiosInstance } from '@/utils/axios'
57+
import { getMainCategory } from '@/api/common'
58+
import type { Category, CategoryForm } from '@/types/common'
4959
5060
const router = useRouter()
5161
52-
const props = defineProps<{
62+
const { categoryStep } = defineProps<{
5363
categoryStep: string
5464
}>()
5565
56-
const isAddModalVisible = ref(false)
57-
const isCancelModalVisible = ref(false)
66+
const isModalVisible = ref({ add: false, cancel: false, fail: false })
5867
59-
const categoryForm = ref(props.categoryStep == '1' ? CATEGORY_FIRST_ADD : CATEGORY_SECOND_ADD)
68+
const categoryForm = ref<CategoryForm>(CATEGORY_FORM)
6069
6170
const handleAddModal = () => {
62-
isAddModalVisible.value = false
71+
isModalVisible.value.add = false
6372
handleGoBack()
6473
}
6574
const handleCancelModal = () => {
66-
isCancelModalVisible.value = !isCancelModalVisible.value
75+
isModalVisible.value.cancel = !isModalVisible.value.cancel
76+
}
77+
const handleFailModal = () => {
78+
isModalVisible.value.fail = !isModalVisible.value.fail
6779
}
6880
6981
const handleCancel = () => {
@@ -74,8 +86,47 @@ const handleGoBack = () => {
7486
router.push('/task-management')
7587
}
7688
77-
const handleSubmit = () => {
78-
console.log(categoryForm.value)
79-
isAddModalVisible.value = true
89+
const handleSubmit = async () => {
90+
if (
91+
isCodeInvalidate.value ||
92+
categoryForm.value.name.length === 0 ||
93+
categoryForm.value.code.length === 0 ||
94+
(categoryStep === '2' && categoryForm.value.mainCategoryId === undefined)
95+
) {
96+
handleFailModal()
97+
return
98+
}
99+
100+
try {
101+
const requestUrl =
102+
categoryStep === '1' ? '/api/managements/main-category' : '/api/managements/sub-category'
103+
await axiosInstance.post(requestUrl, categoryForm.value, {
104+
headers: { Authorization: `Bearer ${import.meta.env.VITE_ACCESS_TOKEN}` }
105+
})
106+
isModalVisible.value.add = true
107+
} catch {
108+
handleFailModal()
109+
}
80110
}
111+
112+
const isCodeInvalidate = computed(() => {
113+
const code = categoryForm.value.code
114+
if (code.length === 0) return ''
115+
116+
const isInvalidate = !/^[A-Z]{1,2}$/.test(code)
117+
return isInvalidate ? 'code' : ''
118+
})
119+
120+
const mainCategory = ref('')
121+
const categoryOptions = ref<Category[]>([])
122+
onMounted(async () => {
123+
categoryOptions.value = await getMainCategory()
124+
if (categoryStep === '2')
125+
categoryForm.value = { ...categoryForm.value, mainCategoryId: undefined }
126+
})
127+
watch(mainCategory, () => {
128+
categoryForm.value.mainCategoryId = categoryOptions.value.find(
129+
el => el.name === mainCategory.value
130+
)?.id
131+
})
81132
</script>

src/constants/admin.ts

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import type { ListBarTabProps, MainCategoryTypes, Option, SubCategoryTypes } from '@/types/common'
1+
import type { CategoryForm, ListBarTabProps, Option } from '@/types/common'
22

33
export const MEMBER_MANAGEMENT_LIST_BAR_TAB: ListBarTabProps[] = [
44
{ content: '이름', width: 60 },
@@ -36,17 +36,9 @@ export const LOGS_LIST_BAR_TAB: ListBarTabProps[] = [
3636

3737
import type { RoleTypes, RoleTypesEnum, UserRegistrationProps } from '@/types/admin'
3838

39-
export const CATEGORY_FIRST_ADD: MainCategoryTypes = {
39+
export const CATEGORY_FORM: CategoryForm = {
4040
name: '',
41-
code: '',
42-
id: 0
43-
}
44-
45-
export const CATEGORY_SECOND_ADD: SubCategoryTypes = {
46-
name: '',
47-
mainCategoryId: 0,
48-
code: '',
49-
id: 0
41+
code: ''
5042
}
5143

5244
export const INITIAL_USER_REGISTRATION: UserRegistrationProps = {

src/types/common.ts

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -79,23 +79,16 @@ export interface LabelDataTypes {
7979
labelColor: string
8080
}
8181

82-
export interface MainCategoryTypes {
83-
id: number
84-
name: string
85-
code: string
86-
}
87-
88-
export interface SubCategoryTypes {
89-
id: number
90-
mainCategoryId: number
82+
export interface CategoryForm {
9183
name: string
9284
code: string
85+
mainCategoryId?: number
9386
}
9487

9588
export interface CategoryDropdownProps {
96-
options: MainCategoryTypes[] | SubCategoryTypes[]
89+
options: CategoryForm
9790
labelName: string
98-
modelValue: MainCategoryTypes | SubCategoryTypes | null
91+
modelValue?: CategoryForm
9992
isLabel?: boolean
10093
isDisabled?: boolean
10194
isInvalidate?: string

0 commit comments

Comments
 (0)