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
17 changes: 11 additions & 6 deletions src/components/request-task/RequestTaskInput.vue
Original file line number Diff line number Diff line change
@@ -1,24 +1,29 @@
<template>
<div>
<div class="relative">
<div class="text-xs flex gap-x-1 mb-2">
<p class="text-body font-bold">{{ labelName }}</p>
<p
v-if="!isNotRequired"
class="text-red-1">
*
</p>
<p
v-if="isInvalidateState === 'input'"
class="text-red-1">
{{ labelName }}을 입력해주세요
</p>
</div>
<input
class="w-full h-11 border border-border-1 px-4 focus:outline-none text-black"
:value="modelValue"
:disabled="isEdit"
@input="updateValue(($event.target as HTMLInputElement).value)"
:placeholder="placeholderText" />
<p
v-if="isInvalidateState === 'input'"
class="text-red-1 text-xs absolute top-[calc(100%+4px)]">
{{ labelName }}을 입력해주세요
</p>
<p
v-if="isInvalidateState === 'code'"
class="text-red-1 text-xs absolute top-[calc(100%+4px)]">
사용할 수 없는 고유코드입니다.
</p>
</div>
</template>

Expand Down
107 changes: 79 additions & 28 deletions src/components/task-management/CategoryAdd.vue
Original file line number Diff line number Diff line change
@@ -1,69 +1,81 @@
<template>
<div class="w-full flex flex-col gap-y-6">
<ModalView
:isOpen="isAddModalVisible"
:type="'successType'"
:is-open="isModalVisible.add"
type="successType"
@close="handleAddModal">
<template #header>카테고리가 등록되었습니다</template>
</ModalView>
<ModalView
:isOpen="isCancelModalVisible"
:type="'warningType'"
:is-open="isModalVisible.cancel"
type="warningType"
@close="handleCancelModal"
@click="handleGoBack">
<template #header>생성을 취소 하시겠습니까?</template>
<template #body>작성하신 내용은 사라집니다</template>
</ModalView>
<ModalView
:is-open="isModalVisible.fail"
type="failType"
@close="handleFailModal">
<template #header>카테고리 정보를 확인해주세요</template>
</ModalView>
<!-- 카테고리 목록 API 필요, 임시로 역할로 설정 -->
<RequestTaskDropdown
v-model="categoryForm.firstCategory"
:options="RoleKeys"
:label-name="'1차 카테고리'"
:placeholderText="'1차 카테고리를 선택해주세요'"
v-if="props.categoryStep == '2'" />
v-model="mainCategory"
:options="categoryOptions.map(el => el.name)"
label-name="1차 카테고리"
placeholder-text="1차 카테고리를 선택해주세요"
v-if="categoryStep == '2'" />
<RequestTaskInput
v-model="categoryForm.name"
:placeholderText="'카테고리명을 입력해주세요'"
:labelName="`${props.categoryStep}차 카테고리명`" />
placeholder-text="카테고리명을 입력해주세요"
:label-name="`${categoryStep}차 카테고리명`" />
<RequestTaskInput
v-model="categoryForm.code"
:placeholderText="'카테고리의 고유코드를 입력해주세요'"
:labelName="'고유코드 (대문자 영어 2글자까지)'" />
placeholder-text="카테고리의 고유코드를 입력해주세요"
label-name="고유코드 (대문자 영어 2글자까지)"
:is-invalidate="isCodeInvalidate" />

<FormButtonContainer
:handleCancel="handleCancel"
:handleSubmit="handleSubmit"
cancelText="취소"
submitText="생성" />
:handle-cancel="handleCancel"
:handle-submit="handleSubmit"
cancel-text="취소"
submit-text="생성" />
</div>
</template>

<script lang="ts" setup>
import { CATEGORY_FIRST_ADD, CATEGORY_SECOND_ADD, RoleKeys } from '@/constants/admin'
import { ref } from 'vue'
import { CATEGORY_FORM } from '@/constants/admin'
import { computed, onMounted, ref, watch } from 'vue'
import { useRouter } from 'vue-router'
import FormButtonContainer from '../common/FormButtonContainer.vue'
import ModalView from '../ModalView.vue'
import RequestTaskDropdown from '../request-task/RequestTaskDropdown.vue'
import RequestTaskInput from '../request-task/RequestTaskInput.vue'
import { axiosInstance } from '@/utils/axios'
import { getMainCategory } from '@/api/common'
import type { Category, CategoryForm } from '@/types/common'

const router = useRouter()

const props = defineProps<{
const { categoryStep } = defineProps<{
categoryStep: string
}>()

const isAddModalVisible = ref(false)
const isCancelModalVisible = ref(false)
const isModalVisible = ref({ add: false, cancel: false, fail: false })

const categoryForm = ref(props.categoryStep == '1' ? CATEGORY_FIRST_ADD : CATEGORY_SECOND_ADD)
const categoryForm = ref<CategoryForm>(CATEGORY_FORM)

const handleAddModal = () => {
isAddModalVisible.value = false
isModalVisible.value.add = false
handleGoBack()
}
const handleCancelModal = () => {
isCancelModalVisible.value = !isCancelModalVisible.value
isModalVisible.value.cancel = !isModalVisible.value.cancel
}
const handleFailModal = () => {
isModalVisible.value.fail = !isModalVisible.value.fail
}

const handleCancel = () => {
Expand All @@ -74,8 +86,47 @@ const handleGoBack = () => {
router.push('/task-management')
}

const handleSubmit = () => {
console.log(categoryForm.value)
isAddModalVisible.value = true
const handleSubmit = async () => {
if (
isCodeInvalidate.value ||
categoryForm.value.name.length === 0 ||
categoryForm.value.code.length === 0 ||
(categoryStep === '2' && categoryForm.value.mainCategoryId === undefined)
) {
handleFailModal()
return
}

try {
const requestUrl =
categoryStep === '1' ? '/api/managements/main-category' : '/api/managements/sub-category'
await axiosInstance.post(requestUrl, categoryForm.value, {
headers: { Authorization: `Bearer ${import.meta.env.VITE_ACCESS_TOKEN}` }
})
isModalVisible.value.add = true
} catch {
handleFailModal()
}
}

const isCodeInvalidate = computed(() => {
const code = categoryForm.value.code
if (code.length === 0) return ''

const isInvalidate = !/^[A-Z]{1,2}$/.test(code)
return isInvalidate ? 'code' : ''
})

const mainCategory = ref('')
const categoryOptions = ref<Category[]>([])
onMounted(async () => {
categoryOptions.value = await getMainCategory()
if (categoryStep === '2')
categoryForm.value = { ...categoryForm.value, mainCategoryId: undefined }
})
watch(mainCategory, () => {
categoryForm.value.mainCategoryId = categoryOptions.value.find(
el => el.name === mainCategory.value
)?.id
})
</script>
14 changes: 3 additions & 11 deletions src/constants/admin.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { ListBarTabProps, MainCategoryTypes, Option, SubCategoryTypes } from '@/types/common'
import type { CategoryForm, ListBarTabProps, Option } from '@/types/common'

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

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

export const CATEGORY_FIRST_ADD: MainCategoryTypes = {
export const CATEGORY_FORM: CategoryForm = {
name: '',
code: '',
id: 0
}

export const CATEGORY_SECOND_ADD: SubCategoryTypes = {
name: '',
mainCategoryId: 0,
code: '',
id: 0
code: ''
}

export const INITIAL_USER_REGISTRATION: UserRegistrationProps = {
Expand Down
15 changes: 4 additions & 11 deletions src/types/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,23 +79,16 @@ export interface LabelDataTypes {
labelColor: string
}

export interface MainCategoryTypes {
id: number
name: string
code: string
}

export interface SubCategoryTypes {
id: number
mainCategoryId: number
export interface CategoryForm {
name: string
code: string
mainCategoryId?: number
}

export interface CategoryDropdownProps {
options: MainCategoryTypes[] | SubCategoryTypes[]
options: CategoryForm
labelName: string
modelValue: MainCategoryTypes | SubCategoryTypes | null
modelValue?: CategoryForm
isLabel?: boolean
isDisabled?: boolean
isInvalidate?: string
Expand Down