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
11 changes: 11 additions & 0 deletions src/api/common.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { axiosInstance } from '../utils/axios'

export const getMainCategory = async () => {
const response = await axiosInstance.get('/api/main-category')
return response.data
}

export const getSubCategory = async () => {
const response = await axiosInstance.get('/api/sub-category')
return response.data
}
2 changes: 1 addition & 1 deletion src/api/test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import axiosInstance from '../utils/axios'
import { axiosInstance } from '../utils/axios'

export const getNotifications = async () => {
const response = await axiosInstance.get('/api/notifications?page=0&size=5')
Expand Down
6 changes: 6 additions & 0 deletions src/api/user.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { formDataAxiosInstance } from '@/utils/axios'

export const postTaskRequest = async (formdata: FormData) => {
const response = await formDataAxiosInstance.post('/api/tasks', formdata)
return response.data
}
12 changes: 6 additions & 6 deletions src/components/my-request/MyRequestFilterBar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -33,15 +33,15 @@
</template>

<script setup lang="ts">
import FilterDropdown from '../filters/FilterDropdown.vue'
import { PAGE_SIZE_LIST, TASK_STATUS_LIST, TERM_LIST } from '@/constants/common'
import { useRequestParamsStore } from '@/stores/params'
import { axiosInstance } from '@/utils/axios'
import { useQuery } from '@tanstack/vue-query'
import FilterCategory from '../filters/FilterCategory.vue'
import FilterInput from '../filters/FilterInput.vue'
import FilterDropdown from '../filters/FilterDropdown.vue'
import FilterDropdownMulti from '../filters/FilterDropdownMulti.vue'
import { useRequestParamsStore } from '@/stores/params'
import { PAGE_SIZE_LIST, TASK_STATUS_LIST, TERM_LIST } from '@/constants/common'
import FilterInput from '../filters/FilterInput.vue'
import { useRequestParamsChange } from '../hooks/useRequestParamsChange'
import axiosInstance from '@/utils/axios'
import { useQuery } from '@tanstack/vue-query'

const store = useRequestParamsStore()
store.$reset()
Expand Down
14 changes: 7 additions & 7 deletions src/components/my-request/MyRequestList.vue
Original file line number Diff line number Diff line change
Expand Up @@ -22,17 +22,17 @@
</template>

<script setup lang="ts">
import MyRequestListBar from './MyRequestListBar.vue'
import MyRequestListCard from './MyRequestListCard.vue'
import ListPagination from '../lists/ListPagination.vue'
import ListContainer from '../lists/ListContainer.vue'
import { useRequestParamsStore } from '@/stores/params'
import axiosInstance from '@/utils/axios'
import { useQuery } from '@tanstack/vue-query'
import { useParseParams } from '../hooks/useParseParams'
import type { MyRequestResponse } from '@/types/user'
import { axiosInstance } from '@/utils/axios'
import { useQuery } from '@tanstack/vue-query'
import { ref, watch } from 'vue'
import { useParseParams } from '../hooks/useParseParams'
import ListContainer from '../lists/ListContainer.vue'
import ListPagination from '../lists/ListPagination.vue'
import NoContent from '../lists/NoContent.vue'
import MyRequestListBar from './MyRequestListBar.vue'
import MyRequestListCard from './MyRequestListCard.vue'

const { params } = useRequestParamsStore()
const onPageChange = (value: number) => {
Expand Down
2 changes: 1 addition & 1 deletion src/components/my-task/MyTaskFilterBar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ import { useRequestParamsStore } from '@/stores/params'
import { PAGE_SIZE_LIST, TASK_STATUS_LIST, TERM_LIST } from '@/constants/common'
import { useRequestParamsChange } from '../hooks/useRequestParamsChange'
import { useQuery } from '@tanstack/vue-query'
import axiosInstance from '@/utils/axios'
import {axiosInstance} from '@/utils/axios'

const store = useRequestParamsStore()
store.$reset()
Expand Down
12 changes: 6 additions & 6 deletions src/components/request-history/RequestHistoryFilterBar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -33,15 +33,15 @@
</template>

<script setup lang="ts">
import FilterDropdown from '../filters/FilterDropdown.vue'
import FilterCategory from '../filters/FilterCategory.vue'
import FilterInput from '../filters/FilterInput.vue'
import { PAGE_SIZE_LIST, TASK_STATUS_LIST, TERM_LIST } from '@/constants/common'
import FilterDropdownMulti from '../filters/FilterDropdownMulti.vue'
import { useRequestParamsStore } from '@/stores/params'
import { useRequestParamsChange } from '../hooks/useRequestParamsChange'
import { axiosInstance } from '@/utils/axios'
import { useQuery } from '@tanstack/vue-query'
import axiosInstance from '@/utils/axios'
import FilterCategory from '../filters/FilterCategory.vue'
import FilterDropdown from '../filters/FilterDropdown.vue'
import FilterDropdownMulti from '../filters/FilterDropdownMulti.vue'
import FilterInput from '../filters/FilterInput.vue'
import { useRequestParamsChange } from '../hooks/useRequestParamsChange'

const store = useRequestParamsStore()
store.$reset()
Expand Down
65 changes: 65 additions & 0 deletions src/components/request-task/CategoryDropDown.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
<template>
<div>
<div class="flex text-xs gap-x-1 mb-2">
<p class="text-body font-bold">{{ labelName }}</p>
<p
v-if="!isLabel"
class="text-red-1">
*
</p>
<p
v-if="isInvalidateState === 'category'"
class="text-red-1">
카테고리를 선택해주세요
</p>
</div>
<div class="relative flex text-base">
<div
class="flex w-full h-11 items-center rounded p-4 bg-white border border-border-1 cursor-pointer text-black"
@click="toggleDropdown">
<p :class="{ 'text-disabled': !modelValue?.name }">
{{ modelValue?.name ?? labelName + '를 선택해주세요' }}
</p>
<CommonIcons
:name="dropdownIcon"
:class="['ml-auto', { 'rotate-180': dropdownOpen }]" />
</div>
<div
v-if="dropdownOpen"
class="absolute w-full h-40 overflow-y-auto top-[52px] flex flex-col gap-2 p-2 bg-white rounded z-10 shadow border-t border-t-border-2 text-black">
<div
v-for="option in options"
:key="option.id"
class="w-full flex items-center h-11 p-2 rounded hover:bg-background-2 cursor-pointer"
@click="selectOption(option)">
{{ option.name }}
</div>
</div>
</div>
</div>
</template>

<script lang="ts" setup>
import { dropdownIcon } from '@/constants/iconPath'
import type { CategoryDropdownProps, MainCategoryTypes, SubCategoryTypes } from '@/types/common'
import { computed, ref } from 'vue'
import CommonIcons from '../common/CommonIcons.vue'

const { options, labelName, modelValue, isLabel, isDisabled, isInvalidate } =
defineProps<CategoryDropdownProps>()

const isInvalidateState = computed(() => isInvalidate)

const emit = defineEmits(['update:modelValue'])
const dropdownOpen = ref(false)

const toggleDropdown = () => {
if (isDisabled) return
dropdownOpen.value = !dropdownOpen.value
}

const selectOption = (option: MainCategoryTypes | SubCategoryTypes) => {
emit('update:modelValue', option)
dropdownOpen.value = false
}
</script>
109 changes: 80 additions & 29 deletions src/components/request-task/RequestTask.vue
Original file line number Diff line number Diff line change
@@ -1,69 +1,120 @@
<template>
<div class="w-full flex flex-col gap-y-6">
<RequestTaskDropdown
<CategoryDropDown
v-model="category1"
:options="DUMMY_REQUEST_TASK_CATEGORIES"
Copy link
Contributor

Choose a reason for hiding this comment

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

더미 데이터는 삭제하고 있으신 걸까요?
사용되지 않을 더미 데이터는 확인 후 삭제 부탁드립니다!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

아직 1,2차 카테고리를 사용하는 페이지들에 전부 반영하지 않아서 (요청 승인) 해당 파트를 진행하며 마지막으로 지우려합니다!

:options="mainCategoryArr"
:label-name="'1차 카테고리'"
:placeholderText="'1차 카테고리를 선택해주세요'" />
<RequestTaskDropdown
:isInvalidate="isInvalidate"
:isDisabled="false" />
<CategoryDropDown
v-model="category2"
:options="DUMMY_REQUEST_TASK_CATEGORIES"
:options="afterSubCategoryArr"
:label-name="'2차 카테고리'"
:placeholderText="'2차 카테고리를 선택해주세요'" />
:is-invalidate="isInvalidate"
:isDisabled="!category1" />
<RequestTaskInput
v-model="title"
:placeholderText="TITLE_PLACEHOLDER"
:label-name="'제목'" />
:placeholderText="'제목을 입력해주세요'"
:label-name="'제목'"
:is-invalidate="isInvalidate" />
<RequestTaskTextArea
v-model="description"
:placeholderText="EXPLANATION_PLACEHOLDER" />
:placeholderText="'부가 정보를 입력해주세요'" />
<RequestTaskFileInput v-model="file" />
<FormButtonContainer
:handleCancel="handleCancel"
:handleSubmit="handleSubmit"
cancelText="취소"
submitText="요청" />
<ModalView
:isOpen="isModalVisible"
:type="'successType'"
@close="handleCancel">
<template #header>작업이 요청되었습니다</template>
</ModalView>
</div>
</template>

<script lang="ts" setup>
import { EXPLANATION_PLACEHOLDER, TITLE_PLACEHOLDER } from '@/constants/user'
import { DUMMY_REQUEST_TASK_CATEGORIES } from '@/datas/taskdetail'
import { ref } from 'vue'
import { getMainCategory, getSubCategory } from '@/api/common'
import { postTaskRequest } from '@/api/user'
import type { MainCategoryTypes, SubCategoryTypes } from '@/types/common'
import { onMounted, ref, watch } from 'vue'
import { useRouter } from 'vue-router'
import FormButtonContainer from '../common/FormButtonContainer.vue'
import RequestTaskDropdown from './RequestTaskDropdown.vue'
import ModalView from '../ModalView.vue'
import CategoryDropDown from './CategoryDropDown.vue'
import RequestTaskFileInput from './RequestTaskFileInput.vue'
import RequestTaskInput from './RequestTaskInput.vue'
import RequestTaskTextArea from './RequestTaskTextArea.vue'
import { useRouter } from 'vue-router'

const category1 = ref('1차 카테고리를 선택해주세요')
const category2 = ref('2차 카테고리를 선택해주세요')
const category1 = ref<MainCategoryTypes | null>(null)
const category2 = ref<MainCategoryTypes | null>(null)

const title = ref('')
const description = ref('')
const file = ref(null as File[] | null)
const isInvalidate = ref('')
const isModalVisible = ref(false)

const mainCategoryArr = ref<MainCategoryTypes[]>([])
const subCategoryArr = ref<SubCategoryTypes[]>([])
const afterSubCategoryArr = ref<SubCategoryTypes[]>([])

onMounted(async () => {
mainCategoryArr.value = await getMainCategory()
subCategoryArr.value = await getSubCategory()
afterSubCategoryArr.value = await getSubCategory()
})

watch(category1, async newValue => {
category2.value = null
afterSubCategoryArr.value = subCategoryArr.value.filter(
subCategory => subCategory.mainCategoryId === newValue?.id
)
})

const router = useRouter()

const handleCancel = () => {
category1.value = ''
category2.value = ''
category1.value = null
category2.value = null
title.value = ''
description.value = ''
file.value = null
file.value = []
router.back()
}

const handleSubmit = () => {
const handleSubmit = async () => {
if (!category1.value || !category2.value) {
isInvalidate.value = 'category'
console.log(isInvalidate.value, '변경됨')
return
} else if (!title.value) {
isInvalidate.value = 'input'
return
}
const formData = new FormData()
formData.append('category1', category1.value)
formData.append('category2', category2.value)
formData.append('title', title.value)
formData.append('description', description.value)
if (file.value) {
file.value.forEach(f => {
formData.append('file', f)
})
const taskInfo = {
categoryId: category2.value.id,
title: title.value,
description: description.value
}

const jsonTaskInfo = JSON.stringify(taskInfo)
const newBlob = new Blob([jsonTaskInfo], { type: 'application/json' })

formData.append('taskInfo', newBlob)

if (file.value && file.value.length > 0) {
file.value.forEach(f => formData.append('attachment', f))
}
try {
const res = await postTaskRequest(formData)
isModalVisible.value = true
console.error('요청 성공:', res)
} catch (error) {
console.error('요청 실패:', error)
}
console.log(Object.fromEntries(formData))
}
</script>
12 changes: 6 additions & 6 deletions src/components/request-task/RequestTaskFileInput.vue
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
@change="handleFileUpload" />
<RequestTaskFileInputAfter
v-if="hasFiles"
:files="props.modelValue"
:files="modelValue"
:removeFile="removeFile" />
<div
v-else
Expand All @@ -31,25 +31,25 @@ import { uploadIcon } from '@/constants/iconPath'
import { computed } from 'vue'
import RequestTaskFileInputAfter from './RequestTaskFileInputAfter.vue'

const props = defineProps<{
const { modelValue } = defineProps<{
modelValue: File[] | null
}>()
const emit = defineEmits(['update:modelValue'])

const hasFiles = computed(() => props.modelValue && props.modelValue.length > 0)
const hasFiles = computed(() => modelValue && modelValue.length > 0)

const handleFileUpload = (event: Event) => {
const target = event.target as HTMLInputElement
if (target.files && target.files.length > 0) {
const newFiles = Array.from(target.files)
const updatedFiles = props.modelValue ? [...props.modelValue, ...newFiles] : newFiles
const updatedFiles = modelValue ? [...modelValue, ...newFiles] : newFiles
emit('update:modelValue', updatedFiles)
}
}

const removeFile = (index: number) => {
if (props.modelValue) {
const updatedFiles = [...props.modelValue]
if (modelValue) {
const updatedFiles = [...modelValue]
updatedFiles.splice(index, 1)
emit('update:modelValue', updatedFiles)
}
Expand Down
12 changes: 10 additions & 2 deletions src/components/request-task/RequestTaskInput.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@
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"
Expand All @@ -19,9 +24,12 @@

<script lang="ts" setup>
import type { RequestTaskInputProps } from '@/types/user'

const { modelValue, placeholderText, labelName, isNotRequired, isEdit } =
import { computed } from 'vue'
const { modelValue, placeholderText, labelName, isNotRequired, isEdit, isInvalidate } =
defineProps<RequestTaskInputProps>()

const isInvalidateState = computed(() => isInvalidate)

const emit = defineEmits(['update:modelValue'])

const updateValue = (value: string) => {
Expand Down
2 changes: 1 addition & 1 deletion src/components/requested/RequestedFilterBar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ import { PAGE_SIZE_LIST, TERM_LIST } from '@/constants/common'
import { useRequestParamsStore } from '@/stores/params'
import { useRequestParamsChange } from '../hooks/useRequestParamsChange'
import { useQuery } from '@tanstack/vue-query'
import axiosInstance from '@/utils/axios'
import {axiosInstance} from '@/utils/axios'

const store = useRequestParamsStore()
store.$reset()
Expand Down
Loading
Loading