Skip to content

Commit

Permalink
♻️ Refactor : S3 이미지, 토큰, 채팅 개선
Browse files Browse the repository at this point in the history
♻️ Refactor : S3 이미지, 토큰, 채팅 개선
  • Loading branch information
eunjju2 authored Jan 16, 2025
2 parents e8178c2 + c0d69d3 commit 0ee7a50
Show file tree
Hide file tree
Showing 7 changed files with 104 additions and 22 deletions.
6 changes: 5 additions & 1 deletion src/apis/chat.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,12 @@ import { authInstance } from '.';
// 메시지 기록 조회
export const getMessage = async (
roomId: number,
cursor?: string,
): Promise<ChatMessageResponse[]> => {
const response = await authInstance.get(`/api/v1/chat/room/${roomId}`);
const now = new Date(Date.now() + 9 * 60 * 60 * 1000);
const response = await authInstance.get(`/api/v1/chat/room/${roomId}`, {
params: { cursor: cursor || now },
});
return response.data;
};

Expand Down
10 changes: 10 additions & 0 deletions src/apis/workplace.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,16 @@ export const deleteStudyRoom = async (studyRoomId: string): Promise<void> => {
return authInstance.delete(`/api/v1/studyroom/${studyRoomId}`);
};

// 스터디룸 이미지 삭제
export const deleteStudyRoomImage = async (
fileName: string,
fileLocation: string,
): Promise<void> => {
await authInstance.delete(`/api/delete-object`, {
params: { fileName, fileLocation },
});
};

// 사업장의 스터디룸 찾기
export const getWorkplaceStudyRoom = async (
workplaceId: number,
Expand Down
46 changes: 39 additions & 7 deletions src/pages/ChatPage/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,21 @@ const ChatPage = () => {
};

// 채팅 내용 불러오기
const loadMessage = async () => {
const messageList = await getMessage(Number(roomId));
setMessages(messageList);
const loadMessage = async (cursor?: string) => {
try {
const messageList = await getMessage(Number(roomId), cursor);
setMessages((prevMessages) => [...messageList, ...prevMessages]);
} catch (error) {
toast.error('메시지를 불러오는 중 오류가 발생했습니다.');
}
};

// 채팅 무한 스크롤
const loadMoreMessages = () => {
if (messages.length > 0) {
const lastMessageTimestamp = messages[0].timestamp; // 첫 번째 메시지의 타임스탬프 사용
loadMessage(lastMessageTimestamp);
}
};

// 소켓 연결
Expand All @@ -54,6 +66,11 @@ const ChatPage = () => {
brokerURL: WS_URL,
webSocketFactory: () => new SockJS(WS_URL),
reconnectDelay: 5000, // 자동 재연결
connectHeaders: {
nickName: user,
senderType: role === 'ROLE_USER' ? 'MEMBER' : 'BUSINESS',
chatRoomId: roomId as string,
},
});

// 구독
Expand Down Expand Up @@ -96,25 +113,40 @@ const ChatPage = () => {
stompClient.publish({
destination: '/pub/sendMessage',
body: JSON.stringify(chatMessage),
headers: {
nickName: user,
senderType: role === 'ROLE_USER' ? 'MEMBER' : 'BUSINESS',
chatRoomId: roomId as string,
},
});
}
};

useEffect(() => {
getUserNickName();
loadMessage();
connect();
if (user !== '') {
loadMessage();
connect();
}

return () => disConnect();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
}, [user]);

return (
<>
<MainLayout>
<HeaderOnlyTitle title={chatTitle} />
<div className='fixed left-1/2 top-[93px] flex h-[calc(100vh-93px-94px)] w-custom -translate-x-1/2 overflow-hidden'>
<div className='overflow-y-auto'>
<div
className='overflow-y-auto'
onScroll={(e) => {
const target = e.target as HTMLDivElement;
if (target.scrollTop === 0) {
loadMoreMessages();
}
}}
>
<MessageContainer
messages={messages}
user={user}
Expand Down
21 changes: 19 additions & 2 deletions src/pages/MainPage/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,12 @@ import BottomNavigation from '@layouts/BottomNavigation';
import usePositionStore from '@store/positionStore';
import useAuthStore from '@store/authStore';
import { useEffect, useState } from 'react';
import { getRole } from '@utils/auth';
import {
getRole,
getTokenExpiration,
removeAuthToken,
removeRole,
} from '@utils/auth';
import MainList from './components/MainList';
import KakaoMap from './components/KakaoMap';
import {
Expand All @@ -28,9 +33,21 @@ const MainPage = () => {
);

// 비로그인 / 사업자 / 사용자 확인
const { isLogin } = useAuthStore();
const { isLogin, storeLogout } = useAuthStore();
const [isUser, setIsUser] = useState<boolean>(false);

// 토큰 만료 확인
useEffect(() => {
const isExpiration = getTokenExpiration();
if (isExpiration && isExpiration < new Date().getTime()) {
removeAuthToken();
removeRole();
storeLogout();
}

// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);

useEffect(() => {
if (isLogin) {
const role = getRole();
Expand Down
7 changes: 6 additions & 1 deletion src/pages/ModifySpace/components/RoomModify.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import CountPeople from '@components/CountPeople';
import { ERROR_MESSAGE } from '@constants/constants';
import { validate } from 'uuid';
import { useParams } from 'react-router-dom';
import { getS3URL } from '@apis/workplace';
import { deleteStudyRoomImage, getS3URL } from '@apis/workplace';
import axios from 'axios';
import useGetRoomListInfo from '../hooks/useGetRoomListInfo';
import usePostRoom from '../hooks/usePostRoom';
Expand Down Expand Up @@ -155,6 +155,11 @@ const RoomModify = ({ room, updateRoomData, completeAdd }: RoomModifyProps) => {
// 삭제된 이미지가 있을 경우
if (deletedImage) {
// 룸 사진 삭제
deletedImage.forEach((img) => {
const fileName = img;
const fileLocation = `workplace-${workplaceId}/studyroom-${room.id}`;
deleteStudyRoomImage(fileName, fileLocation);
});
}
}

Expand Down
18 changes: 10 additions & 8 deletions src/pages/PaymentPage/components/PaymentButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -163,14 +163,16 @@ const PaymentButton = (props: PaymentButtonProps) => {
};

return (
<div className='fixed bottom-0 z-10 flex h-[94px] w-[375px] items-center justify-between border-t-[1px] border-t-subfont bg-white px-[30px] pb-[30px] pt-[18px]'>
<button
type='button'
onClick={handlePaymentButton}
className='btn-primary'
>
{totalAmount.toLocaleString('ko-KR')}원 결제하기
</button>
<div className='fixed bottom-0 z-10 flex h-[94px] w-[375px] items-center justify-center border-t-[1px] border-t-subfont bg-white pb-[16px]'>
<div className='flex items-center gap-2'>
<button
type='button'
onClick={handlePaymentButton}
className='btn-primary w-custom px-1'
>
{totalAmount.toLocaleString('ko-KR')}원 결제하기
</button>
</div>
</div>
);
};
Expand Down
18 changes: 15 additions & 3 deletions src/utils/auth.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,21 @@
const setAuthToken = (accessToken: string) => {
localStorage.setItem('accessToken', accessToken);
const expiration = new Date().getTime() + 5 * 60 * 1000; // 만료시간 5분
localStorage.setItem(
'accessToken',
JSON.stringify({ accessToken, expiration }),
);
};

const getAuthToken = () => {
const token = localStorage.getItem('accessToken');
return token;
const tokenData = localStorage.getItem('accessToken');
const accessToken = tokenData ? JSON.parse(tokenData).accessToken : '';
return accessToken;
};

const getTokenExpiration = () => {
const tokenData = localStorage.getItem('accessToken');
const expiration = tokenData ? JSON.parse(tokenData).expiration : '';
return expiration;
};

const removeAuthToken = () => {
Expand All @@ -29,6 +40,7 @@ const removeRole = () => {
export {
setAuthToken,
getAuthToken,
getTokenExpiration,
removeAuthToken,
setRole,
getRole,
Expand Down

0 comments on commit 0ee7a50

Please sign in to comment.