-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* fix: fix cli notification page * fix: fix chat list * feat: add api for notifications * feat: add notification card * fix: fix err * fix: fix eslint err * chore: delete useles * fix: fix lint * feat: add mock data * fix: fix switch case * feat: add read path nofitication
- Loading branch information
Showing
18 changed files
with
508 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
import { ClientNotificationPage } from 'src/clientPages/notification' | ||
|
||
function NotificationPage() { | ||
return <ClientNotificationPage /> | ||
} | ||
|
||
export default NotificationPage |
37 changes: 37 additions & 0 deletions
37
packages/client/src/clientPages/notification/api/notification.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
import { APIApi, PageResponseNotificationResponse } from '@server-api/api' | ||
import { | ||
useMutation, | ||
useQuery, | ||
UseQueryOptions, | ||
UseQueryResult, | ||
} from '@tanstack/react-query' | ||
|
||
import { config } from '@shared/api' | ||
|
||
export const useFetchNotifications = ( | ||
dto: { | ||
type: '전체' | '답변' | '채택' | '채팅' | ||
page: number | ||
size: number | ||
}, | ||
options: Omit<UseQueryOptions<PageResponseNotificationResponse>, 'queryKey'>, // <PageResponseNotificationResponse>, | ||
): UseQueryResult => { | ||
return useQuery({ | ||
...options, | ||
queryKey: [`/notifications`, dto.type, dto.page, dto.size], | ||
queryFn: async () => | ||
( | ||
await new APIApi(config).getNotificationsByMember(dto.type, { | ||
page: dto.page, | ||
size: dto.size, | ||
}) | ||
).data, | ||
}) | ||
} | ||
|
||
export const usePatchNotification = () => { | ||
return useMutation({ | ||
mutationFn: async (dto: { notificationId: number }) => | ||
(await new APIApi(config).readNotification(dto)).data, | ||
}) | ||
} |
76 changes: 76 additions & 0 deletions
76
packages/client/src/clientPages/notification/hook/useInfiniteScrollNotifictaion.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
// TODO: useInfiniteScrollNotifictaion | ||
// 참고 https://oliveyoung.tech/blog/2023-10-04/useInfiniteQuery-scroll/ | ||
|
||
import { APIApi, NotificationResponse } from '@server-api/api' | ||
import { config } from '@shared/api' | ||
import { InfiniteData, useInfiniteQuery } from '@tanstack/react-query' | ||
import { useEffect } from 'react' | ||
|
||
interface InfinitNotification { | ||
content: Array<NotificationResponse> | ||
nextPage: number | ||
hasNext?: boolean | ||
} | ||
|
||
// API 호출 함수 | ||
|
||
export const useInfiniteScrollNotifictaion = ( | ||
countPerPage: number, | ||
): { | ||
data: InfiniteData<InfinitNotification> | ||
status: string | ||
isFetchingNextPage: boolean | ||
} => { | ||
const fetchNotifications = async ({ pageParam = 0 }) => { | ||
const response = await new APIApi(config).getNotificationsByMember( | ||
'전체', | ||
{ | ||
page: pageParam, | ||
size: countPerPage, | ||
}, | ||
) | ||
const { data } = response | ||
return { | ||
content: data.content, | ||
nextPage: pageParam + 1, | ||
hasNext: data.hasNext || false, | ||
} | ||
} | ||
|
||
const { data, fetchNextPage, hasNextPage, isFetchingNextPage, status } = | ||
useInfiniteQuery({ | ||
queryKey: ['notifications'], // 쿼리 키 | ||
queryFn: fetchNotifications, // API 호출 함수 | ||
getNextPageParam: (lastPage: InfinitNotification) => | ||
lastPage.hasNext ? lastPage.nextPage : undefined, // 다음 페이지 번호 반환 | ||
}) | ||
|
||
// 스크롤 이벤트 핸들러 | ||
const handleScroll = (e) => { | ||
if (!e.target.scrollingElement) { | ||
return | ||
} | ||
const { scrollHeight, scrollTop, clientHeight } = | ||
e.target.scrollingElement | ||
if ( | ||
scrollHeight - scrollTop <= clientHeight * 1.5 && | ||
hasNextPage && | ||
!isFetchingNextPage | ||
) { | ||
fetchNextPage() | ||
} | ||
} | ||
|
||
// 컴포넌트가 마운트될 때 스크롤 이벤트 리스너 추가 | ||
useEffect(() => { | ||
document.addEventListener('scroll', handleScroll) | ||
return () => { | ||
document.removeEventListener('scroll', handleScroll) | ||
} | ||
}, [hasNextPage, isFetchingNextPage]) | ||
return { | ||
data, | ||
status, | ||
isFetchingNextPage, | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export { ClientNotificationPage } from './ui/ClientNotificationPage' |
82 changes: 82 additions & 0 deletions
82
packages/client/src/clientPages/notification/ui/ClientNotificationPage.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
'use client' | ||
|
||
import { NotificationCard } from '@entities/notification' | ||
import { MainLoader } from '@shared/ui' | ||
import { NotificationResponse } from '@server-api/api' | ||
import { useInfiniteScrollNotifictaion } from '../hook/useInfiniteScrollNotifictaion' | ||
import * as styles from './style.css' | ||
import { usePatchNotification } from '../api/notification' | ||
|
||
export function ClientNotificationPage() { | ||
const { data, isFetchingNextPage, status } = | ||
useInfiniteScrollNotifictaion(10) | ||
|
||
const formatdNotification = ( | ||
notificationRes: NotificationResponse, | ||
): { message: string; date: string } => { | ||
const res = { | ||
date: notificationRes.createdAt | ||
? new Date(notificationRes.createdAt).toLocaleString() | ||
: '-', | ||
} | ||
|
||
switch (notificationRes.type) { | ||
case '답변': | ||
return { | ||
...res, | ||
message: `"${notificationRes.triggerMemberNickName}"님이 답변을 남겼습니다.`, | ||
} | ||
case '채택': | ||
return { | ||
...res, | ||
message: `"${notificationRes.triggerMemberNickName}"님이 답변을 채택했습니다. 크레딧이 적립됩니다.`, | ||
} | ||
case '채팅': | ||
return { | ||
...res, | ||
message: `"${notificationRes.triggerMemberNickName}"님에게 채팅이 도착했습니다.`, | ||
} | ||
default: | ||
return { ...res, message: `[ERROR] 잘못된 타입의 알림입니다.` } | ||
} | ||
} | ||
|
||
const { mutate: patchNotification } = usePatchNotification() | ||
|
||
return ( | ||
<div className={styles.container}> | ||
<MainLoader loading={isFetchingNextPage} /> | ||
{status === 'success' && | ||
data.pages.map((page, pageIndex) => ( | ||
<div key={pageIndex}> | ||
{page.content.map((notification) => { | ||
const foramtted = formatdNotification(notification) | ||
return ( | ||
<NotificationCard | ||
onClick={() => { | ||
if (notification.isRead) { | ||
return | ||
} | ||
patchNotification( | ||
{ | ||
notificationId: Number( | ||
notification.notificationId, | ||
), | ||
}, | ||
{ | ||
onError: (error) => alert(error.message), | ||
}, | ||
) | ||
}} | ||
key={notification.notificationId} | ||
notifyMessage={foramtted.message} | ||
date={foramtted.date} | ||
isRead={notification.isRead || false} | ||
/> | ||
) | ||
})} | ||
</div> | ||
))} | ||
</div> | ||
) | ||
} |
11 changes: 11 additions & 0 deletions
11
packages/client/src/clientPages/notification/ui/style.css.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
import { style } from '@vanilla-extract/css' | ||
|
||
export const container = style({ | ||
display: 'flex', | ||
flexDirection: 'column', | ||
alignItems: 'center', | ||
justifyContent: 'flex-start', | ||
|
||
width: '100%', | ||
gap: 8, | ||
}) |
Oops, something went wrong.