Skip to content

Commit

Permalink
✨ Feat : 실시간 알림 연결 #104
Browse files Browse the repository at this point in the history
  • Loading branch information
JOEIH committed Dec 6, 2024
1 parent c3048ad commit 48336d6
Show file tree
Hide file tree
Showing 6 changed files with 100 additions and 46 deletions.
46 changes: 6 additions & 40 deletions src/components/LogoAndNotification.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,16 @@
import Logo from '@assets/images/roomit_logo.png';
import { BASE_URL } from '@constants/constants';
import useAuthStore from '@store/authStore';
import { getAuthToken, getRole } from '@utils/auth';
import { NativeEventSource, EventSourcePolyfill } from 'event-source-polyfill';
import { useEffect, useState } from 'react';
import { getRole } from '@utils/auth';
import { RiNotification3Line } from 'react-icons/ri';
import { Link, useNavigate } from 'react-router-dom';
import { SseAlarm } from '@typings/types';
import NotiContainer from './notiContainer';

const LogoAndNotification = () => {
interface HeaderProps {
isLogin: boolean;
}

const LogoAndNotification = ({ isLogin }: HeaderProps) => {
const navigate = useNavigate();
const { isLogin } = useAuthStore();
const role = getRole();

const [message, setMessage] = useState<SseAlarm>();

const handleMoveToNotiPageClick = () => {
if (role === 'ROLE_USER') {
navigate('/user-noti');
Expand All @@ -24,34 +19,6 @@ const LogoAndNotification = () => {
}
};

useEffect(() => {
console.log('useEffect');
const EventSource = EventSourcePolyfill || NativeEventSource;
const token = getAuthToken() || '';
console.log(token);
const eventSource = new EventSource(`${BASE_URL}/api/subscribe`, {
headers: {
Authorization: token,
},
withCredentials: true,
});

console.log('EventSource initialized:', eventSource);

eventSource.onmessage = (event) => {
const newMessage = event.data;
setMessage(newMessage);
};

eventSource.onerror = (error) => {
console.log(error);
};

return () => {
eventSource.close();
};
}, []);

return (
<>
<Link to='/'>
Expand All @@ -67,7 +34,6 @@ const LogoAndNotification = () => {
onClick={handleMoveToNotiPageClick}
/>
)}
{isLogin && message && <NotiContainer message={message} />}
</>
);
};
Expand Down
8 changes: 7 additions & 1 deletion src/components/NotiContainer.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
import { SseAlarm } from '@typings/types';
import { AiFillNotification } from 'react-icons/ai';

const NotiContainer = ({ message }: { message: SseAlarm }) => {
return <div className='h-[50px] w-custom bg-primary'>{message.content}</div>;
return (
<div className='fixed top-8 z-[2000] flex h-[70px] w-custom items-center justify-start gap-3 rounded-lg bg-white px-4 py-2 text-base text-black shadow-custom'>
<AiFillNotification className='size-5 text-primary' />
{message.content}
</div>
);
};

export default NotiContainer;
8 changes: 7 additions & 1 deletion src/components/notiContainer.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
import { SseAlarm } from '@typings/types';
import { AiFillNotification } from 'react-icons/ai';

const NotiContainer = ({ message }: { message: SseAlarm }) => {
return <div className='h-[50px] w-custom bg-primary'>{message.content}</div>;
return (
<div className='fixed top-8 z-[2000] flex h-[70px] w-custom items-center justify-start gap-3 rounded-lg bg-white px-4 py-2 text-base text-black shadow-custom'>
<AiFillNotification className='size-5 text-primary' />
{message.content}
</div>
);
};

export default NotiContainer;
36 changes: 35 additions & 1 deletion src/layouts/HeaderNoTitle.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,44 @@
import LogoAndNotification from '@components/LogoAndNotification';
import { getAuthToken } from '@utils/auth';
import { useEffect, useState } from 'react';
import { EventSourcePolyfill, NativeEventSource } from 'event-source-polyfill';
import { BASE_URL } from '@constants/constants';
import useAuthStore from '@store/authStore';

const HeaderNoTitle = () => {
const { isLogin } = useAuthStore();
const [message, setMessage] = useState<string>();
console.log(message);

useEffect(() => {
if (!isLogin) return;

setMessage('');
const EventSource = EventSourcePolyfill || NativeEventSource;
const token = getAuthToken() || '';
const eventSource = new EventSource(`${BASE_URL}/api/subscribe`, {
headers: {
Authorization: `Bearer ${token}`,
},
withCredentials: true,
});

eventSource.onmessage = (event) => {
const newMessage = JSON.parse(event.data);
setMessage(newMessage);
};

// eslint 에러 제거 주석
// eslint-disable-next-line consistent-return
return () => {
eventSource.close();
};
}, [isLogin]);

return (
<div className='fixed top-0 z-[1000] flex h-[93px] w-[375px] flex-col items-center bg-white'>
<div className='fixed top-[46px] flex h-[37px] w-[330px] items-center justify-between'>
<LogoAndNotification />
<LogoAndNotification isLogin={isLogin} />
</div>
</div>
);
Expand Down
46 changes: 45 additions & 1 deletion src/layouts/HeaderWithTitle.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,59 @@
import LogoAndNotification from '@components/LogoAndNotification';
import { BASE_URL } from '@constants/constants';
import useAuthStore from '@store/authStore';
import { SseAlarm } from '@typings/types';
import { getAuthToken } from '@utils/auth';
import { EventSourcePolyfill, NativeEventSource } from 'event-source-polyfill';
import { useEffect, useState } from 'react';
import { toast } from 'react-toastify';

export interface TitleProps {
title: string;
}

const HeaderWithTitle = ({ title }: TitleProps) => {
const { isLogin } = useAuthStore();
const [message, setMessage] = useState<string>('');
console.log(message);

useEffect(() => {
if (!isLogin) return;

setMessage('');
const EventSource = EventSourcePolyfill || NativeEventSource;
const token = getAuthToken() || '';
const eventSource = new EventSource(`${BASE_URL}/api/subscribe`, {
headers: {
Authorization: `Bearer ${token}`,
},
withCredentials: true,
});

eventSource.onmessage = (event) => {
const newMessage: SseAlarm = JSON.parse(event.data);
setMessage(newMessage.content);

if (newMessage.content !== 'connected!') {
toast.info(newMessage.content);
}
};

eventSource.onerror = (error) => {
console.error('SSE Error:', error);
};

// eslint 에러 제거 주석
// eslint-disable-next-line consistent-return
return () => {
eventSource.close();
};
}, [isLogin]);

return (
<div className='fixed top-0 z-[1000] flex h-[132px] w-[375px] flex-col items-center bg-white'>
<div className='fixed top-[46px] w-[330px] flex-col'>
<div className='flex h-[37px] w-[100%] items-center justify-between'>
<LogoAndNotification />
<LogoAndNotification isLogin={isLogin} />
</div>
<p className='flex h-[42px] w-[100%] items-center justify-center text-[18px] font-normal'>
{title}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,6 @@ const ManagementPlaceCard = ({ item }: ManagementPlaceCardProps) => {
navigate(`/modify-Space/${pageId}`);
};

console.log(workplaceId);

return (
<>
<div className='mx-auto flex w-custom flex-col gap-4 border-b border-solid border-b-black px-[13px] py-[26px]'>
Expand Down

0 comments on commit 48336d6

Please sign in to comment.