diff --git a/.idea/TadakTadak.iml b/.idea/TadakTadak.iml new file mode 100644 index 0000000..d6ebd48 --- /dev/null +++ b/.idea/TadakTadak.iml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..e9f2a87 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..35eb1dd --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/workspace.xml b/.idea/workspace.xml new file mode 100644 index 0000000..9196fa6 --- /dev/null +++ b/.idea/workspace.xml @@ -0,0 +1,47 @@ + + + + + + + + + + + + + + + + + + + 1705738328256 + + + + \ No newline at end of file diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index 9e051ef..323f45e 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -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: , + id: 'root', + errorElement: , + children: [ + { index: true, element: }, + { path: 'signin', element: }, + { path: 'signup', element: }, + { path: 'chattinglist', element: }, + { path: 'chatroom/:chatroom_id', element: }, + { path: 'test', element: }, + ], + }, +]); -function App() { - const [count, setCount] = useState(0); - +const App = () => { return ( <> - -

Vite + React

-
- -

- Edit src/App.tsx and save to test HMR -

-
-

- Click on the Vite and React logos to learn more -

+ ); -} +}; export default App; diff --git a/frontend/src/components/auth/auth.tsx b/frontend/src/components/auth/auth.tsx new file mode 100644 index 0000000..e69de29 diff --git a/frontend/src/components/chat/Chat.tsx b/frontend/src/components/chat/Chat.tsx new file mode 100644 index 0000000..801b867 --- /dev/null +++ b/frontend/src/components/chat/Chat.tsx @@ -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 ( + <> +
+ {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 ( +
+ {shouldDisplayYear &&
{formatDate(message.createdAt)}
} + {message.writer}: {message.message}{' '} + {isLastMessageForWriter && formatTime(message.createdAt)} +
+ ); + })} +
+ + ); +}; + +export default Chat; diff --git a/frontend/src/components/chat/ChatForm.tsx b/frontend/src/components/chat/ChatForm.tsx new file mode 100644 index 0000000..5a269da --- /dev/null +++ b/frontend/src/components/chat/ChatForm.tsx @@ -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 ( + <> + + +
+ ) => + setInputMessage(e.target.value) + } + onKeyDown={(e: React.KeyboardEvent) => { + if (e.key === 'Enter') { + handleSendMessage(); + } + }} + placeholder="채팅을 입력해주세요" + /> +
+ + ); +}; + +export default ChatForm; diff --git a/frontend/src/components/chat/ChatRecent.tsx b/frontend/src/components/chat/ChatRecent.tsx new file mode 100644 index 0000000..3b03cc3 --- /dev/null +++ b/frontend/src/components/chat/ChatRecent.tsx @@ -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 ( +
+ {shouldDisplayYear &&
{formattedDate}
} + {item.writer}: {item.message}{' '} + {isLastMessageForWriter && formattedTime} +
+ ); + })} +
---- 이전 채팅 기록입니다. ----
+ + ); +}; + +export default RecentChat; diff --git a/frontend/src/components/chat/ChatRoom.tsx b/frontend/src/components/chat/ChatRoom.tsx new file mode 100644 index 0000000..b692f65 --- /dev/null +++ b/frontend/src/components/chat/ChatRoom.tsx @@ -0,0 +1,12 @@ +import ChatForm from './ChatForm'; + +const ChatRoom: React.FC = () => { + return ( +
+
채팅방
+ +
+ ); +}; + +export default ChatRoom; diff --git a/frontend/src/components/chattingRoomList/ChattingRoomList.tsx b/frontend/src/components/chattingRoomList/ChattingRoomList.tsx new file mode 100644 index 0000000..e69de29 diff --git a/frontend/src/components/layout/Layout.tsx b/frontend/src/components/layout/Layout.tsx new file mode 100644 index 0000000..e69de29 diff --git a/frontend/src/components/video/Video.tsx b/frontend/src/components/video/Video.tsx new file mode 100644 index 0000000..e69de29 diff --git a/frontend/src/hooks/Hook.ts b/frontend/src/hooks/Hook.ts new file mode 100644 index 0000000..e69de29 diff --git a/frontend/src/pages/ChattingListPage.tsx b/frontend/src/pages/ChattingListPage.tsx new file mode 100644 index 0000000..cf5cdaa --- /dev/null +++ b/frontend/src/pages/ChattingListPage.tsx @@ -0,0 +1,5 @@ +const ChattingListPage = () => { + return <>It's ChattingListPage!; +}; + +export default ChattingListPage; diff --git a/frontend/src/pages/ChattingRoomPage.tsx b/frontend/src/pages/ChattingRoomPage.tsx new file mode 100644 index 0000000..0a9dd44 --- /dev/null +++ b/frontend/src/pages/ChattingRoomPage.tsx @@ -0,0 +1,5 @@ +const ChattingRoomPage = () => { + return <>It's Chatting RoomPage!; +}; + +export default ChattingRoomPage; diff --git a/frontend/src/pages/ErrorPage.tsx b/frontend/src/pages/ErrorPage.tsx new file mode 100644 index 0000000..7b01827 --- /dev/null +++ b/frontend/src/pages/ErrorPage.tsx @@ -0,0 +1,7 @@ +const ErrorPage = () => { + return( + <>It's ErrorPage! + ) +}; + +export default ErrorPage; \ No newline at end of file diff --git a/frontend/src/pages/RootPage.tsx b/frontend/src/pages/RootPage.tsx new file mode 100644 index 0000000..f39b6f1 --- /dev/null +++ b/frontend/src/pages/RootPage.tsx @@ -0,0 +1,12 @@ +import { Outlet } from 'react-router-dom'; + +const RootPage = () => { + return <> + +
+ +
+ +}; + +export default RootPage; \ No newline at end of file diff --git a/frontend/src/pages/SigninPage.tsx b/frontend/src/pages/SigninPage.tsx new file mode 100644 index 0000000..e1031c3 --- /dev/null +++ b/frontend/src/pages/SigninPage.tsx @@ -0,0 +1,7 @@ +const SigninPage = () => { + return( + <>It's SigninPage! + ) +}; + +export default SigninPage; diff --git a/frontend/src/pages/SignupPage.tsx b/frontend/src/pages/SignupPage.tsx new file mode 100644 index 0000000..ea4f828 --- /dev/null +++ b/frontend/src/pages/SignupPage.tsx @@ -0,0 +1,5 @@ +const SignupPage = () => { + return
It's SignupPage!
; +}; + +export default SignupPage; diff --git a/frontend/src/pages/WelcomePage.tsx b/frontend/src/pages/WelcomePage.tsx new file mode 100644 index 0000000..83658d4 --- /dev/null +++ b/frontend/src/pages/WelcomePage.tsx @@ -0,0 +1,7 @@ +const WelcomePage = () => { + return( + <>It's Home! + ) +}; + +export default WelcomePage; \ No newline at end of file diff --git a/frontend/src/stores/Store.ts b/frontend/src/stores/Store.ts new file mode 100644 index 0000000..e69de29 diff --git a/frontend/src/stores/useChatStore.ts b/frontend/src/stores/useChatStore.ts new file mode 100644 index 0000000..4ff348d --- /dev/null +++ b/frontend/src/stores/useChatStore.ts @@ -0,0 +1,43 @@ +import { create } from 'zustand'; + +interface ChatMessage { + id: number; + message: string; + writer: string; + createdAt: Date; +} + +interface ChatStore { + messages: ChatMessage[]; + inputMessage: string; + setInputMessage: (value: string) => void; + handleSendMessage: () => void; +} + +const useChatStore = create((set) => ({ + messages: [], + inputMessage: '', + setInputMessage: (value: string): void => set({ inputMessage: value }), + handleSendMessage: () => { + set((state) => { + if (state.inputMessage.trim() !== '') { + return { + ...state, + messages: [ + ...state.messages, + { + id: state.messages.length + 1, + message: state.inputMessage, + writer: 'User', + createdAt: new Date(), + }, + ], + inputMessage: '', + }; + } + return state; + }); + }, +})); + +export default useChatStore; diff --git a/frontend/src/styles/Style.tsx b/frontend/src/styles/Style.tsx new file mode 100644 index 0000000..e69de29 diff --git a/frontend/src/test/TestPage.tsx b/frontend/src/test/TestPage.tsx new file mode 100644 index 0000000..3ff73e5 --- /dev/null +++ b/frontend/src/test/TestPage.tsx @@ -0,0 +1,11 @@ +import ChatRoom from '../components/chat/ChatRoom'; + +const TestPage: React.FC = () => { + return ( + <> + + + ); +}; + +export default TestPage;