Skip to content

Commit

Permalink
Feat/noti (#109)
Browse files Browse the repository at this point in the history
* init: 환경설정

* feat: notification 제작중

* feat: notification 헤더 추가

* feat: notification API 연결 및 type 따른 처리

* feat: notification css 수정

* fix: notification 타입 및 id 필드 변경에 따른 방어코드로 수정

* fix: notification api 함수 변경

* fix: notification 오브젝트 속성 참조 오류 수정

* fix: notification 드롭다운 아이템 key값 수정

* fix: notification 쿼리 키 설정 및 적용

* fix: notification antd-style적용, suspense제거.

* fix: notification 알림 문구 변경, 아이콘 변경

---------

Co-authored-by: Jinho Choi <66049045+jinoov@users.noreply.github.com>
  • Loading branch information
Hys-Lee and jinoov committed Jul 17, 2024
1 parent 0da3ca1 commit 97e64dc
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 86 deletions.
5 changes: 1 addition & 4 deletions apps/web-client/src/components/header/Header.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -83,10 +83,7 @@ const Header = ({ member, onLogout }) => {
{isLogin && (
<div style={{ display: 'flex', flexDirection: 'row', justifyContent: 'center', alignItems: 'center', gap: '8px' }}>
{/** Noti */}
<Suspense fallback={<Spinner />}>
<Notification />
</Suspense>

<Notification />
{/** Profile */}
<Dropdown menu={{ items: dropDownItems }}>
<Button shape="circle" className={styles.avatarButton}>
Expand Down
139 changes: 57 additions & 82 deletions apps/web-client/src/components/header/Notification/Notification.tsx
Original file line number Diff line number Diff line change
@@ -1,89 +1,90 @@
import { MessageOutlined } from '@ant-design/icons';
import { BellOutlined } from '@ant-design/icons';
import { Avatar, Badge, Button, Dropdown, Space } from 'antd';
import { ReactNode } from 'react';
import { ReactNode, useCallback } from 'react';
import { Link } from 'react-router-dom';

// import { createStyles } from 'antd-style';
import { createStyles } from 'antd-style';
import { NotificationControllerService, NotificationResponse, queryKey, useAppQuery } from '~/lib/api-v2';

// CSS
// const useStyles = createStyles(({ css }) => ({
// dropdownItem: css`
// display: 'flex';
// flex-direction: 'row';
// gap: '4px';
// `,
// dropdownButton: css`
// padding: '0';
// margin: '0';
// border: '0';
// `,
// dropdownShape: css`
// display: 'flex';
// justify-content: 'center';
// align-items: 'center';
// `,
// dropdownAvatar: css`
// padding: '2px';
// display: 'flex';
// justify-content: 'center';
// align-items: 'center';
// background-color: '#19a47d28 !important';
// color: '#716e6e';
// `,
// }));
const useStyles = createStyles(() => ({
dropdownMenu: {
minHeight: '0px',
maxHeight: '250px',
overflowY: 'scroll',
},

dropdownItem: {
display: 'flex',
flexDirection: 'row',
gap: '4px',
},

dropdownButton: {
padding: '0',
margin: '0',
border: '0',
},
dropdownShape: { display: 'flex', justifyContent: 'center', alignItems: 'center' },

dropdownAvatar: {
padding: '2px',
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#19a47d28',
color: '#716e6e',
},
}));

// Helper function
const convertDate = (inputDate: Date | string) => {
if (!inputDate) return '';
const date = new Date(inputDate);
return `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}-${String(date.getDate()).padStart(2, '0')}`;
};
const Menu = (menu: ReactNode) => <div style={{ minHeight: '0px', maxHeight: '250px', overflowY: 'scroll' }}>{menu}</div>;

// Components
export default function Notification() {
// const { styles } = useStyles();
const { styles } = useStyles();
const { data }: { data?: NotificationResponse[] } = useAppQuery({
queryKey: queryKey.notification.unread,
queryFn: NotificationControllerService.getUnreadNotificationsUsingGet,
// queryFn: NotificationControllerService.getAllNotificationsUsingGet,

queryFn: () => NotificationControllerService.getUnreadNotificationsUsingGet(),
placeholderData: [],
});

const Menu = useCallback((menu: ReactNode) => <div className={styles.dropdownMenu}>{menu}</div>, [styles.dropdownMenu]);

const resultLinkAndDescription = (response: NotificationResponse) => {
switch (response.notificationType) {
case 'MESSAGE':
return {
link: response?.causedById ? `/message/${response?.causedById}` : `/message`,
description: (
<>
<h4>{response.senderName}</h4>
<p>님이 쪽지를 보냈습니다.</p>
</>
),
link: `/message/${response?.causedById}`,
description: <p>새로운 쪽지가 왔습니다.</p>,
};
case 'BADGE':
return { link: `/my-page/badge-list`, description: <p>새 뱃지를 받았습니다!</p> };
case 'POST':
return {
link: response?.causedById ? `/board/${response?.causedById}` : `/board/${response.postId}`,
link: `/board/${response?.causedById}`,
description: (
<>
<h4>{response.senderName}</h4>
<p>님이 댓글을 달았습니다.</p>
{/* <h4>{response.senderName}</h4> */}
<p>게시물에 댓글이 달렸습니다.</p>
</>
),
};
case 'RECOMMENT':
return {
link: response?.causedById ? `/board/${response?.causedById}` : `/board/${response.parentCommentId}`,
description: (
<>
<h4>{response.senderName}</h4>
<p>님이 대댓글을 달았습니다.</p>
</>
),
}; // 기능 안 나오긴 함.
// case 'RECOMMENT':
// return {
// link: response?.causedById ? `/board/${response?.causedById}` : `/board/${response.parentCommentId}`,
// description: (
// <>
// <h4>{response.senderName}</h4>
// <p>님이 대댓글을 달았습니다.</p>
// </>
// ),
// }; // 기능 안 나오긴 함.
default:
return { link: '/', description: <p>오류가 발생했습니다</p> };
}
Expand All @@ -94,12 +95,7 @@ export default function Notification() {
<Link to={resultLinkAndDescription(dataOne).link}>
<div>
<p>{convertDate(dataOne.createdAt ?? '')}</p>
<div
style={{ display: 'flex', flexDirection: 'row', gap: '4px' }}
// className={styles.dropdownItem}
>
{resultLinkAndDescription(dataOne).description}
</div>
<div className={styles.dropdownItem}>{resultLinkAndDescription(dataOne).description}</div>
</div>
</Link>
),
Expand All @@ -108,31 +104,10 @@ export default function Notification() {
return (
<div>
<Dropdown menu={{ items: dropDownItems }} dropdownRender={Menu}>
<Button
shape="circle"
style={{ padding: '0', margin: '0', border: '0' }}
// className={styles.dropdownButton}
>
<Space
size="large"
style={{ display: 'flex', justifyContent: 'center', alignItems: 'center' }}
// className={styles.dropdownShape}
>
<Button shape="circle" className={styles.dropdownButton}>
<Space size="large" className={styles.dropdownShape}>
<Badge count={data?.length}>
<Avatar
shape="circle"
size="default"
icon={<MessageOutlined />}
// className={styles.dropdownAvatar}
style={{
padding: '2px',
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#19a47d28',
color: '#716e6e',
}}
/>
<Avatar shape="circle" size="default" icon={<BellOutlined />} className={styles.dropdownAvatar} />
</Badge>
</Space>
</Button>
Expand Down

0 comments on commit 97e64dc

Please sign in to comment.