-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathNotificationModal.vue
More file actions
128 lines (116 loc) · 3.84 KB
/
NotificationModal.vue
File metadata and controls
128 lines (116 loc) · 3.84 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
<template>
<div
v-if="isOpen"
@click.stop
class="absolute right-6 top-[calc(100%+16px)] h-[400px] w-[400px] bg-white rounded-lg shadow-custom overflow-hidden flex flex-col">
<div class="flex justify-between items-center px-4 pt-3 pb-2 border-b border-border-2">
<p class="text-body font-semibold text-xs">알림</p>
<div class="flex items-center gap-2">
<button
type="button"
@click="readAllNotifi"
class="flex items-center gap-1 p-1 rounded hover:bg-background-2">
<CommonIcons :name="smallCheckIcon" />
<p class="font-semibold text-primary1 text-xs">모두 읽음</p>
</button>
<button
type="button"
class="hover:bg-background-2 rounded"
@click="closeModal">
<CommonIcons :name="closeIcon" />
</button>
</div>
</div>
<div class="grow h-full flex flex-col overflow-y-auto scrollbar-hide">
<template v-if="notifications">
<NotificationMessage
v-for="notification in notifications"
:key="notification.notificationId"
@click="readNotifi(notification.notificationId, notification.taskId)"
:type="notification.notificationType"
:title="notification.taskTitle"
:message="notification.message"
:is-read="notification.isRead"
:createdAt="notification.createdAt">
</NotificationMessage>
</template>
<template v-else>
<NoContent title="전달 받은 알림이 없습니다" />
</template>
<InfiniteLoading
@infinite="loadMoreNotifications"
class="flex items-center justify-center">
<template v-slot:complete>
<span class="flex py-4 items-center justify-center text-xs text-primary1">
알림을 전부 확인했습니다
</span>
</template>
<template v-slot:error>
<span class="flex py-4 items-center justify-center text-xs text-primary1">
데이터를 불러오는 중 오류가 발생했습니다. 다시 시도해 주세요.
</span>
</template>
</InfiniteLoading>
</div>
</div>
</template>
<script setup lang="ts">
import { getNotification, patchNotificationRead } from '@/api/common'
import { closeIcon, smallCheckIcon } from '@/constants/iconPath'
import type { NotificationContent } from '@/types/common'
import { axiosInstance } from '@/utils/axios'
import InfiniteLoading from 'v3-infinite-loading'
import 'v3-infinite-loading/lib/style.css'
import { ref } from 'vue'
import CommonIcons from '../common/CommonIcons.vue'
import NotificationMessage from './NotificationMessage.vue'
import { useRouter } from 'vue-router'
import NoContent from '../lists/NoContent.vue'
const { isOpen } = defineProps<{
isOpen: boolean
}>()
const router = useRouter()
const notifications = ref<NotificationContent[]>([])
const page = ref(0)
const pageSize = 5
const hasNext = ref(true)
interface InfiniteLoadingState {
loaded: () => void
complete: () => void
error: () => void
}
const loadMoreNotifications = async ($state: InfiniteLoadingState) => {
try {
const response = await getNotification(page.value, pageSize)
if (response.isFirst) {
notifications.value = response.content
} else {
notifications.value.push(...response.content)
}
hasNext.value = response.hasNext
if (hasNext.value) {
page.value++
$state.loaded()
} else {
$state.complete()
}
} catch {
$state.error()
}
}
const readNotifi = async (id: number, taskId: number) => {
await patchNotificationRead(id)
emit('close')
router.replace({ query: { taskId } })
}
const emit = defineEmits<{
(e: 'close'): void
}>()
const closeModal = () => {
emit('close')
}
const readAllNotifi = async () => {
await axiosInstance.patch('/api/notifications')
emit('close')
}
</script>