Skip to content

Commit

Permalink
Feat/issue-29 (#38)
Browse files Browse the repository at this point in the history
* Feat:FE디렉토리 구조

* Feat:FE 디렉토리 구조 추가 수정

* Chore : 더미 파일 명 수정

* Feat: 라우터 경로 설정

* Test: 임시 컴포넌트 테스트 페이지 생성

* Test: 임시 테스트 페이지 라우터 설정

* Feat : 채팅 상태관리 및 스켈레톤 코드 구현

* Feat: 채팅 입력시 날짜 표현

* Remove : 필요없는 상태 코드 삭제

* Test: 최근 데이터 불러오기 코드 작성 및 날짜 체크

* Feat: 더미데이터 시간 중복 표시 구현

* Rename: RecentChat -> ChatRecent 파일명 변경

* Feat: 시간 중복일때 마지막 메시지만 시간 표시

* Chore: Chat 파일명 분리

---------

Co-authored-by: eastfilmm <[email protected]>
  • Loading branch information
KimKyuHoi and eastfilmm authored Jan 24, 2024
1 parent fbcec00 commit 3000ee4
Show file tree
Hide file tree
Showing 25 changed files with 379 additions and 27 deletions.
9 changes: 9 additions & 0 deletions .idea/TadakTadak.iml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions .idea/modules.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions .idea/vcs.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

47 changes: 47 additions & 0 deletions .idea/workspace.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

55 changes: 28 additions & 27 deletions frontend/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,35 +1,36 @@
import { useState } from 'react';
import reactLogo from './assets/react.svg';
import viteLogo from "/vite.svg";
import { createBrowserRouter, RouterProvider } from 'react-router-dom';
import RootPage from './pages/RootPage';
import WelcomePage from './pages/WelcomePage';
import ErrorPage from './pages/ErrorPage';
import ChattingListPage from './pages/ChattingListPage';
import SignupPage from './pages/SignupPage';
import SigninPage from './pages/SigninPage';
import ChattingRoomPage from './pages/ChattingRoomPage';
import TestPage from './test/TestPage';

const router = createBrowserRouter([
{
path: '/',
element: <RootPage />,
id: 'root',
errorElement: <ErrorPage />,
children: [
{ index: true, element: <WelcomePage /> },
{ path: 'signin', element: <SigninPage /> },
{ path: 'signup', element: <SignupPage /> },
{ path: 'chattinglist', element: <ChattingListPage /> },
{ path: 'chatroom/:chatroom_id', element: <ChattingRoomPage /> },
{ path: 'test', element: <TestPage /> },
],
},
]);

function App() {
const [count, setCount] = useState(0);

const App = () => {
return (
<>
<div>
<a href="https://vitejs.dev" target="_blank">
<img src={viteLogo} className="logo" alt="Vite logo" />
</a>
<a href="https://react.dev" target="_blank">
<img src={reactLogo} className="logo react" alt="React logo" />
</a>
</div>
<h1>Vite + React</h1>
<div className="card">
<button onClick={() => setCount((count) => count + 1)}>
count is {count}
</button>
<p>
Edit <code>src/App.tsx</code> and save to test HMR
</p>
</div>
<p className="read-the-docs">
Click on the Vite and React logos to learn more
</p>
<RouterProvider router={router} />
</>
);
}
};

export default App;
Empty file.
55 changes: 55 additions & 0 deletions frontend/src/components/chat/Chat.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import useChatStore from '../../stores/useChatStore';
import { useEffect } from 'react';

const formatTime = (createdAt: Date) => {
return createdAt.toLocaleTimeString('ko-KR', {
hour: '2-digit',
minute: '2-digit',
hour12: true,
});
};

const formatDate = (createdAt: Date) => {
return createdAt.toLocaleDateString('ko-KR', {
year: 'numeric',
month: 'long',
day: 'numeric',
});
};

const Chat: React.FC = () => {
const { messages } = useChatStore();

useEffect(() => {
console.log(messages);
}, [messages]);

return (
<>
<section>
{messages.map((message, index, array) => {
const isLastMessageForWriter =
index === array.length - 1 ||
array[index + 1].writer !== message.writer ||
formatTime(array[index + 1].createdAt) !==
formatTime(message.createdAt);

const shouldDisplayYear =
index === 0 ||
formatDate(message.createdAt) !==
formatDate(array[index - 1].createdAt);

return (
<div key={message.id}>
{shouldDisplayYear && <div>{formatDate(message.createdAt)}</div>}
<strong>{message.writer}: </strong> {message.message}{' '}
{isLastMessageForWriter && formatTime(message.createdAt)}
</div>
);
})}
</section>
</>
);
};

export default Chat;
31 changes: 31 additions & 0 deletions frontend/src/components/chat/ChatForm.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import useChatStore from '../../stores/useChatStore';
import Chat from './Chat';
import ChatRecent from './ChatRecent';

const ChatForm: React.FC = () => {
const { inputMessage, setInputMessage, handleSendMessage } = useChatStore();

return (
<>
<ChatRecent />
<Chat />
<div>
<input
type="text"
value={inputMessage}
onChange={(e: React.ChangeEvent<HTMLInputElement>) =>
setInputMessage(e.target.value)
}
onKeyDown={(e: React.KeyboardEvent<HTMLInputElement>) => {
if (e.key === 'Enter') {
handleSendMessage();
}
}}
placeholder="채팅을 입력해주세요"
/>
</div>
</>
);
};

export default ChatForm;
81 changes: 81 additions & 0 deletions frontend/src/components/chat/ChatRecent.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
interface ChatMessage {
writer: string;
message: string;
createdAt: Date | string;
}

const DUMMY_DATA: ChatMessage[] = [
{
writer: '감자',
message: '헬로',
createdAt: '2023-12-31T23:57:59',
},
{
writer: '감자',
message: '점메추',
createdAt: '2023-12-31T23:57:59',
},
{
writer: '감자',
message: '점메추123',
createdAt: '2023-12-31T23:59:59',
},
{
writer: '고구마',
message: '헬로',
createdAt: '2023-12-31T23:59:59',
},
{
writer: '고구마',
message: '점메추',
createdAt: '2024-01-01T00:05:59',
},
{
writer: '고구마',
message: '점메추',
createdAt: '2024-01-01T00:07:59',
},
];

const RecentChat: React.FC = () => {
let currentFormattedDate = '';
return (
<>
{DUMMY_DATA.map((item, index, array) => {
const date = new Date(item.createdAt);

const formattedDate = date.toLocaleDateString('ko-KR', {
year: 'numeric',
month: 'long',
day: 'numeric',
});

const formattedTime = date.toLocaleTimeString('ko-KR', {
hour: '2-digit',
minute: '2-digit',
hour12: true,
});

const isLastMessageForWriter =
index === array.length - 1 ||
array[index + 1].writer !== item.writer ||
array[index + 1].createdAt !== item.createdAt;

const shouldDisplayYear = formattedDate !== currentFormattedDate;

currentFormattedDate = formattedDate;

return (
<div key={index}>
{shouldDisplayYear && <div>{formattedDate}</div>}
<strong>{item.writer}: </strong> {item.message}{' '}
{isLastMessageForWriter && formattedTime}
</div>
);
})}
<div>---- 이전 채팅 기록입니다. ----</div>
</>
);
};

export default RecentChat;
12 changes: 12 additions & 0 deletions frontend/src/components/chat/ChatRoom.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import ChatForm from './ChatForm';

const ChatRoom: React.FC = () => {
return (
<div>
<header>채팅방</header>
<ChatForm />
</div>
);
};

export default ChatRoom;
Empty file.
Empty file.
Empty file.
Empty file added frontend/src/hooks/Hook.ts
Empty file.
5 changes: 5 additions & 0 deletions frontend/src/pages/ChattingListPage.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
const ChattingListPage = () => {
return <>It's ChattingListPage!</>;
};

export default ChattingListPage;
5 changes: 5 additions & 0 deletions frontend/src/pages/ChattingRoomPage.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
const ChattingRoomPage = () => {
return <>It's Chatting RoomPage!</>;
};

export default ChattingRoomPage;
7 changes: 7 additions & 0 deletions frontend/src/pages/ErrorPage.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
const ErrorPage = () => {
return(
<>It's ErrorPage!</>
)
};

export default ErrorPage;
12 changes: 12 additions & 0 deletions frontend/src/pages/RootPage.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { Outlet } from 'react-router-dom';

const RootPage = () => {
return <>

<main>
<Outlet/>
</main>
</>
};

export default RootPage;
7 changes: 7 additions & 0 deletions frontend/src/pages/SigninPage.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
const SigninPage = () => {
return(
<>It's SigninPage!</>
)
};

export default SigninPage;
5 changes: 5 additions & 0 deletions frontend/src/pages/SignupPage.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
const SignupPage = () => {
return <div>It's SignupPage!</div>;
};

export default SignupPage;
7 changes: 7 additions & 0 deletions frontend/src/pages/WelcomePage.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
const WelcomePage = () => {
return(
<>It's Home!</>
)
};

export default WelcomePage;
Empty file added frontend/src/stores/Store.ts
Empty file.
Loading

0 comments on commit 3000ee4

Please sign in to comment.