Skip to content

Commit 63b9c32

Browse files
authored
Merge pull request #48 from TaskFlow-CLAP/CLAP-179
Clap-179 요청 세부사항 담당자 UI
2 parents 244a51b + c1c9bd3 commit 63b9c32

17 files changed

+447
-119
lines changed

src/assets/styles.css

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,3 +132,13 @@ body {
132132
.category-management-line {
133133
@apply flex items-center px-4 w-full h-11 border-b border-b-border-1;
134134
}
135+
136+
.task-detail-dropdown {
137+
@apply flex w-full h-10 items-center text-sm rounded pl-4 pr-3 bg-white border border-border-1 cursor-pointer;
138+
}
139+
.task-detail-dropdown-option-list {
140+
@apply absolute w-full h-40 overflow-y-auto top-11 flex flex-col gap-2 p-2 bg-white rounded z-10 shadow border-t border-t-border-2;
141+
}
142+
.task-detail-dropdown-option {
143+
@apply w-full flex items-center h-10 p-2 rounded hover:bg-background-2 cursor-pointer;
144+
}
Lines changed: 13 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -1,81 +1,36 @@
11
<template>
2-
<div class="flex flex-col rounded-lg max-w-1200 bg-white">
3-
<div class="w-full flex justify-between items-center">
4-
<div class="flex gap-4 text-sm font-bold">
5-
<div
6-
v-if="!isManager"
7-
class="flex gap-1 items-center cursor-pointer">
8-
<CommonIcons :name="reRequestIcon" />
9-
<p class="text-body">재요청</p>
10-
</div>
11-
<div
12-
v-if="status.iconName && status.text"
13-
class="flex gap-1 items-center cursor-pointer">
14-
<CommonIcons :name="status.iconName" />
15-
<p class="text-primary1">{{ status.text }}</p>
16-
</div>
17-
<div
18-
v-if="isManager"
19-
class="flex gap-1 items-center cursor-pointer">
20-
<CommonIcons :name="cancelIcon" />
21-
<p class="text-red-1">요청취소</p>
22-
</div>
23-
</div>
24-
<CommonIcons
25-
:name="closeIcon"
26-
@click="closeTaskDetail"
27-
class="cursor-pointer" />
28-
</div>
2+
<div
3+
class="flex flex-col overflow-y-auto rounded-lg w-full max-w-[1200px] min-w-[1024px] bg-white p-6">
4+
<TaskDetailTopBar
5+
:is-manager="isManager"
6+
:is-approved="isApproved"
7+
:close-task-detail="closeTaskDetail" />
298
<div class="w-full flex gap-6">
30-
<div class="w-full flex flex-col gap-y-8 overflow-y-auto scrollbar-hide">
31-
<TaskDetailLeft :task-detail="DUMMY_TASK_DETAIL_LEFT" />
9+
<div class="w-full h-[718px] flex flex-col gap-y-8 overflow-y-auto scrollbar-hide">
10+
<TaskDetailLeft :task-detail="DUMMY_TASK_DETAIL" />
3211
<div class="w-full border-border-1 border"></div>
3312
<TaskDetailHistory
3413
:history="DUMMY_TASK_DETAIL_HISTORY"
3514
:is-approved="false"
3615
:is-manager="false" />
3716
</div>
3817
<div class="w-[1px] bg-border-1"></div>
39-
<TaskDetailRight :task-detail="DUMMY_TASK_DETAIL_RIGHT" />
18+
<TaskDetailRight
19+
:task-detail="DUMMY_TASK_DETAIL"
20+
:is-manager="true" />
4021
</div>
4122
</div>
4223
</template>
4324

4425
<script setup lang="ts">
45-
import {
46-
approveIcon,
47-
cancelIcon,
48-
closeIcon,
49-
modificationIcon,
50-
reRequestIcon
51-
} from '@/constants/iconPath'
5226
import * as taskDetailData from '@/datas/taskdetail'
5327
import type { TaskDetailProps } from '@/types/user'
54-
import CommonIcons from '../common/CommonIcons.vue'
5528
import TaskDetailHistory from './TaskDetailHistory.vue'
5629
import TaskDetailLeft from './TaskDetailLeft.vue'
5730
import TaskDetailRight from './TaskDetailRight.vue'
31+
import TaskDetailTopBar from './TaskDetailTopBar.vue'
5832
59-
const { DUMMY_TASK_DETAIL_HISTORY, DUMMY_TASK_DETAIL_LEFT, DUMMY_TASK_DETAIL_RIGHT } =
60-
taskDetailData
33+
const { DUMMY_TASK_DETAIL_HISTORY, DUMMY_TASK_DETAIL } = taskDetailData
6134
6235
const { isManager, isApproved, closeTaskDetail } = defineProps<TaskDetailProps>()
63-
64-
const getStatus = (isManager: boolean) => {
65-
if (!isManager && !isApproved) {
66-
return {
67-
iconName: modificationIcon,
68-
text: '요청 수정'
69-
}
70-
} else if (isManager && !isApproved) {
71-
return {
72-
iconName: approveIcon,
73-
text: '요청 승인'
74-
}
75-
} else {
76-
return {}
77-
}
78-
}
79-
80-
const status = getStatus(isManager)
8136
</script>
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
<template>
2+
<div>
3+
<div class="relative flex">
4+
<div
5+
class="task-detail-dropdown"
6+
@click="toggleDropdown">
7+
<div class="flex gap-2">
8+
<div class="w-6 h-6 rounded-full overflow-hidden">
9+
<img
10+
src="/images/mockProfile.jpg"
11+
alt="userProfile" />
12+
</div>
13+
<p class="text-black">
14+
{{ modelValue }}
15+
</p>
16+
</div>
17+
<CommonIcons
18+
:name="dropdownIcon"
19+
:class="['ml-auto', { 'rotate-180': dropdownOpen }]" />
20+
</div>
21+
<div
22+
v-if="dropdownOpen"
23+
class="task-detail-dropdown-option-list">
24+
<div
25+
v-for="option in options"
26+
:key="option"
27+
class="task-detail-dropdown-option justify-between"
28+
@click="selectOption(option)">
29+
<div class="flex gap-2 items-center">
30+
<div class="w-6 h-6 rounded-full overflow-hidden">
31+
<img
32+
:src="processor.profileUrl"
33+
alt="userProfile" />
34+
</div>
35+
<p class="text-sm">
36+
{{ option }}
37+
</p>
38+
</div>
39+
<p class="text-primary1 text-xs">잔여 작업 : {{ 3 }}</p>
40+
</div>
41+
</div>
42+
</div>
43+
</div>
44+
</template>
45+
46+
<script lang="ts" setup>
47+
import { dropdownIcon } from '@/constants/iconPath'
48+
import type { TaskDetailDropdownProps } from '@/types/user'
49+
import { ref } from 'vue'
50+
import CommonIcons from '../common/CommonIcons.vue'
51+
52+
const { options, modelValue, processor } = defineProps<TaskDetailDropdownProps>()
53+
const emit = defineEmits(['update:modelValue'])
54+
const dropdownOpen = ref(false)
55+
56+
const toggleDropdown = () => {
57+
dropdownOpen.value = !dropdownOpen.value
58+
}
59+
60+
const selectOption = (option: string) => {
61+
emit('update:modelValue', option)
62+
dropdownOpen.value = false
63+
}
64+
</script>

src/components/task-detail/TaskDetailHistory.vue

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,14 @@
44
<TaskDetailHistoryInput :history="history" />
55
<div class="flex flex-col w-full items-center gap-6 mt-8">
66
<div
7-
class="flex flex-col items-center gap-6"
7+
class="flex w-full flex-col items-center gap-6"
88
v-for="item in history"
99
:key="item.name">
1010
<div
11-
class="flex w-[150px] h-7 items-center justify-center bg-background-1 rounded-xl text-body text-xs font-bold">
11+
class="flex w-[150px] h-7 items-center justify-center bg-primary1 rounded-xl text-white text-xs font-bold">
1212
{{ formatDateWithDay(item.date) }}
1313
</div>
14-
<div class="flex gap-1 text-body text-sm">
14+
<div class="flex w-full gap-1 justify-center text-body text-sm">
1515
<p>{{ HistoryMessageBefore[item.TaskHistoryType] }}</p>
1616
<p
1717
v-if="item.TaskHistoryType === 'STATUS_SWITCHED'"
@@ -26,6 +26,7 @@
2626
class="text-primary1">
2727
{{ item.name }}
2828
</p>
29+
<TaskDetailHistoryChat v-else-if="item.TaskHistoryType === 'COMMENT'" />
2930
<p>{{ HistoryMessageAfter[item.TaskHistoryType] }}</p>
3031
</div>
3132
</div>
@@ -37,6 +38,7 @@
3738
import { HistoryMessageAfter, HistoryMessageBefore } from '@/constants/user'
3839
import type { TaskDetailHistoryProps } from '@/types/user'
3940
import { formatDateWithDay } from '@/utils/date'
41+
import TaskDetailHistoryChat from './TaskDetailHistoryChat.vue'
4042
import TaskDetailHistoryInput from './TaskDetailHistoryInput.vue'
4143
4244
const { history } = defineProps<{ history: TaskDetailHistoryProps[] }>()
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<template>
2+
<div class="flex w-full justify-start">
3+
<div class="w-10 h-10 rounded-full pt-1.5">
4+
<img
5+
src="/images/mockProfile.jpg"
6+
class="rounded-full" />
7+
</div>
8+
<div class="flex max-w-[400px] flex-wrap px-6 py-4 bg-background-2 ml-4 text-black rounded-lg">
9+
네네... 부탁드릴게요 가능하시다면 오늘 오후 6시까지 되었으면 좋겠습니다! 감사합니다.
10+
</div>
11+
<div class="flex h-full items-end text-xs font-bold text-body ml-2">오후 2:18</div>
12+
</div>
13+
</template>
14+
15+
<script setup lang="ts"></script>

src/components/task-detail/TaskDetailHistoryInput.vue

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
class="hidden"
1414
type="file"
1515
id="file"
16+
:disabled="!isPossible"
1617
multiple
1718
@change="handleFileUpload" />
1819
<label
@@ -34,7 +35,7 @@ import { ref } from 'vue'
3435
import CommonIcons from '../common/CommonIcons.vue'
3536
3637
const { history } = defineProps<{ history: TaskDetailHistoryProps[] }>()
37-
const isPossible = ref(history.length !== 0)
38+
const isPossible = ref(history.length === 0)
3839
const placeHolderText = ref(isPossible?.value ? '텍스트를 입력' : '요청 승인 후 작성할 수 있습니다')
3940
4041
const handleFileUpload = (event: Event) => {
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
<template>
2+
<div>
3+
<div class="relative flex">
4+
<div
5+
class="task-detail-dropdown"
6+
@click="toggleDropdown">
7+
<div class="flex gap-2">
8+
<div class="w-6 h-6 rounded-full border-red-1 border-2 bg-red-2"></div>
9+
<p class="text-black">
10+
{{ modelValue }}
11+
</p>
12+
</div>
13+
<CommonIcons
14+
:name="dropdownIcon"
15+
:class="['ml-auto', { 'rotate-180': dropdownOpen }]" />
16+
</div>
17+
<div
18+
v-if="dropdownOpen"
19+
class="task-detail-dropdown-option-list">
20+
<div
21+
v-for="option in options"
22+
:key="option.labelId"
23+
class="task-detail-dropdown-option justify-between"
24+
@click="selectOption(option.labelName)">
25+
<div class="flex gap-2 items-center">
26+
<div
27+
class="w-6 h-6 rounded-full overflow-hidden"
28+
:style="{ border: `2px solid ${option.labelColor}` }"></div>
29+
<p class="text-sm">
30+
{{ option.labelName }}
31+
</p>
32+
</div>
33+
</div>
34+
</div>
35+
</div>
36+
</div>
37+
</template>
38+
39+
<script lang="ts" setup>
40+
import { dropdownIcon } from '@/constants/iconPath'
41+
import type { TaskDetailLabelDropdownProps } from '@/types/user'
42+
import { ref } from 'vue'
43+
import CommonIcons from '../common/CommonIcons.vue'
44+
45+
const { options, modelValue } = defineProps<TaskDetailLabelDropdownProps>()
46+
const emit = defineEmits(['update:modelValue'])
47+
const dropdownOpen = ref(false)
48+
49+
const toggleDropdown = () => {
50+
dropdownOpen.value = !dropdownOpen.value
51+
}
52+
53+
const selectOption = (option: string) => {
54+
emit('update:modelValue', option)
55+
dropdownOpen.value = false
56+
}
57+
</script>

src/components/task-detail/TaskDetailLeft.vue

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<template>
2-
<div class="flex-grow flex flex-col gap-6 pt-6">
2+
<div class="flex-grow flex flex-col gap-6">
33
<div>
44
<p class="task-detail">1차 카테고리</p>
55
<p>{{ taskDetail.mainCategoryName }}</p>
@@ -24,9 +24,9 @@
2424
</template>
2525

2626
<script setup lang="ts">
27-
import type { TaskDetailLeftProps } from '@/types/user'
27+
import type { TaskDetailDatas } from '@/types/user'
2828
import TaskDetailFiles from './TaskDetailFiles.vue'
29-
const { taskDetail } = defineProps<{ taskDetail: TaskDetailLeftProps }>()
29+
const { taskDetail } = defineProps<{ taskDetail: TaskDetailDatas }>()
3030
</script>
3131

3232
<style scoped></style>

0 commit comments

Comments
 (0)