Skip to content

Commit

Permalink
feat : 알림페이지 api 연동 및 알림 타입 변경 (#359)
Browse files Browse the repository at this point in the history
  • Loading branch information
kangminguu authored Dec 8, 2024
1 parent a7fd03a commit 353bc7c
Show file tree
Hide file tree
Showing 8 changed files with 98 additions and 73 deletions.
8 changes: 5 additions & 3 deletions src/components/NotificationPage/NotificationContainer.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { NotificationProps } from '@/types/notification';
import { NotificationItemItemProps } from '@/types/notification';
import { NotificationItem } from './NotificationItem';

type NotificationContainerProps = {
notifications: Array<NotificationProps>;
notifications: Array<NotificationItemItemProps>;
};

export const NotificationContainer = ({
Expand All @@ -11,7 +11,8 @@ export const NotificationContainer = ({
return (
<div>
{notifications.map((notification, index) => {
const { type, createdAt, letterId, isRead } = notification;
const { type, createdAt, letterId, isRead, label } =
notification;

return (
<div key={index} className="mb-4">
Expand All @@ -20,6 +21,7 @@ export const NotificationContainer = ({
createdAt={createdAt}
letterId={letterId}
isRead={isRead}
label={label}
/>
</div>
);
Expand Down
30 changes: 18 additions & 12 deletions src/components/NotificationPage/NotificationItem.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,20 @@
import { NotificationProps } from '@/types/notification';
import { match } from 'ts-pattern';
import { Margin } from '../Common/Margin/Margin';
import { NotificationItemItemProps } from '@/types/notification';

export const NotificationItem = ({
type,
createdAt,
letterId,
isRead
}: NotificationProps) => {
isRead,
label
}: NotificationItemItemProps) => {
// 메인 메시지
const notificatioMessage = match(type)
.with('NEW_LETTER', () => '새로운 편지가 도착했어요')
.with('TARGET_LETTER', () => '지도 편지가 도착했어요')
.with('REPLY_LETTER', () => '답장이 도착했어요')
.with('NEW_LETTER', () => '새로운 익명의 편지가 도착했어요')
.with('TARGET_LETTER', () => '나에게 편지가 도착했어요')
.with('KEYWORD_REPLY', () => '내가 쓴 편지에 답장이 도착했어요')
.with('MAP_REPLY', () => '내가 쓴 편지에 답장이 도착했어요')
.with('WARNING', () => '규정에 맞는 편지를 작성해주세요')
.with('BAN', () => '정지된 계정입니다')
.run();
Expand Down Expand Up @@ -41,8 +43,9 @@ export const NotificationItem = ({
}
};

// todo : 라벨 이미지 및 상세보기 라우팅 경로 지정
// 아직 사용하지 않아서 콘솔처리, 추후에 수정하겠습니다.
const letterLink = `/detail/${letterId}`;
console.log(letterLink);

// 읽음 여부에 따라 스타일 : 투명도 조절
const isReadStyle = `flex gap-3 items-center ${
Expand All @@ -51,11 +54,14 @@ export const NotificationItem = ({

return (
<div className={isReadStyle}>
<img
className="size-[44px] bg-slate-400 rounded-full"
src=""
alt=""
/>
{type !== 'WARNING' && type !== 'BAN' ? (
<img
className="size-[44px] bg-slate-400 rounded-full"
src={label}
alt=""
/>
) : null}

<div className="w-full">
<div className="flex items-center justify-between">
<p className="text-[16px] overflow-hidden">
Expand Down
9 changes: 9 additions & 0 deletions src/hooks/useGetNotifications.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { useQuery } from '@tanstack/react-query';
import { getNotifications } from '@/service/notification/getNotifiations';

export const useGetNotifications = () => {
return useQuery({
queryKey: ['notifications'],
queryFn: getNotifications
});
};
8 changes: 8 additions & 0 deletions src/hooks/useUpdateNotifications.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { useMutation } from '@tanstack/react-query';
import { updateNotificationStatus } from '@/service/notification/updateNotificationStatus';

export const useUpdateNotificationStatus = () => {
return useMutation({
mutationFn: updateNotificationStatus
});
};
75 changes: 19 additions & 56 deletions src/pages/Notification/NotificationPage.tsx
Original file line number Diff line number Diff line change
@@ -1,78 +1,41 @@
import { Margin } from '@/components/Common/Margin/Margin';
import { TitleClosedTopBar } from '@/components/Common/TitleClosedTopBar/TitleClosedTopBar';
import { NotificationContainer } from '@/components/NotificationPage/NotificationContainer';
import { useGetNotifications } from '@/hooks/useGetNotifications';
import { useUpdateNotificationStatus } from '@/hooks/useUpdateNotifications';
import { NotificationType } from '@/types/notification';

export const NotificationPage = () => {
const dummy = [
{
id: 'ba017e82-022e-4a82-94db-f0c5d22ef318',
type: 'NEW_LETTER',
receiver: 99,
createdAt: '2024-12-03T18:20:38.6242079',
letterId: 1,
isRead: false
},
{
id: 'ba017e82-022e-4a82-94db-f0c5d22ef318',
type: 'TARGET_LETTER',
receiver: 99,
createdAt: '2024-12-03T11:20:38.6242079',
letterId: 1,
isRead: false
},
{
id: '8f6f7748-dfd7-46b2-8e1f-4dff4abc8ab9',
type: 'WARNING',
receiver: 99,
createdAt: '2024-12-02T11:17:16.7813547',
letterId: null,
isRead: true
},
{
id: 'ba017e82-022e-4a82-94db-f0c5d22ef318',
type: 'NEW_LETTER',
receiver: 99,
createdAt: '2024-12-02T11:20:38.6242079',
letterId: 1,
isRead: true
},
{
id: 'ba017e82-022e-4a82-94db-f0c5d22ef318',
type: 'REPLY_LETTER',
receiver: 99,
createdAt: '2024-12-01T19:20:38.6242079',
letterId: 1,
isRead: true
},
{
id: 'ba017e82-022e-4a82-94db-f0c5d22ef318',
type: 'NEW_LETTER',
receiver: 99,
createdAt: '2024-12-01T11:20:38.6242079',
letterId: 1,
isRead: true
}
];
const { data, isLoading, isError } = useGetNotifications();

// 상태 업데이트
useUpdateNotificationStatus();

if (isLoading) return <p>알림 로딩 중...</p>;
if (isError) return <p>알림 로딩 실패!</p>;

const dummy = data?.result || [];

// 읽지 않은 알림 : isRead = false
const unReadNotifications = [...dummy]
.filter((notification) => !notification.isRead)
.map(({ type, createdAt, letterId, isRead }) => ({
.map(({ type, createdAt, letterId, isRead, label }) => ({
type: type as NotificationType,
createdAt,
letterId: letterId ?? 0, // null일 경우 0
isRead
letterId,
isRead,
label
}));

// 읽은 알림 : isRead = true
const readNotifications = [...dummy]
.filter((notification) => notification.isRead)
.map(({ type, createdAt, letterId, isRead }) => ({
.map(({ type, createdAt, letterId, isRead, label }) => ({
type: type as NotificationType,
createdAt,
letterId: letterId ?? 0, // null일 경우 0
isRead
letterId,
isRead,
label
}));

return (
Expand Down
9 changes: 9 additions & 0 deletions src/service/notification/getNotifiations.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { defaultApi } from '@/service/api';
import { NotificationResponseType } from '@/types/notification';

export const getNotifications = async (): Promise<NotificationResponseType> => {
const api = defaultApi();

const response = await api.patch('/notification');
return response.data;
};
11 changes: 11 additions & 0 deletions src/service/notification/updateNotificationStatus.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { defaultApi } from '@/service/api';
import { NotificationResponseType } from '@/types/notification';

export const updateNotificationStatus = async (
isRead: boolean
): Promise<NotificationResponseType> => {
const api = defaultApi();

const response = await api.patch('/notification', { isRead });
return response.data;
};
21 changes: 19 additions & 2 deletions src/types/notification.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,30 @@
export type NotificationType =
| 'NEW_LETTER'
| 'TARGET_LETTER'
| 'REPLY_LETTER'
| 'KEYWORD_REPLY'
| 'MAP_REPLY'
| 'WARNING'
| 'BAN';

export type NotificationProps = {
export type NotificationItemItemProps = {
type: NotificationType;
createdAt: string;
letterId: number;
isRead: boolean;
label: string;
};

export type NotificationResponseType = {
isSuccess: boolean;
code: string;
message: string;
result: {
id: string;
type: NotificationType;
receiver: number;
createdAt: string;
letterId: number;
isRead: boolean;
label: string;
}[];
};

0 comments on commit 353bc7c

Please sign in to comment.