Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"trailingComma": "es5",
"tabWidth": 2,
"semi": true,
"singleQuote": true
}
333 changes: 134 additions & 199 deletions package-lock.json

Large diffs are not rendered by default.

6 changes: 5 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
{
"name": "vote",
"name": "chat",
"version": "0.1.0",
"private": true,
"dependencies": {
"@testing-library/jest-dom": "^5.11.5",
"@testing-library/react": "^11.1.1",
"@testing-library/user-event": "^12.2.0",
"react": "^17.0.1",
"react-bootstrap-icons": "^1.4.0",
"react-dom": "^17.0.1",
"react-router": "^5.2.0",
"react-router-dom": "^5.2.0",
"react-scripts": "4.0.0",
"styled-components": "^5.2.1",
"typescript": "^4.2.4",
"web-vitals": "^0.2.4"
},
"scripts": {
Expand Down
Binary file added public/babodog.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion public/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
work correctly both with client-side routing and a non-root public URL.
Learn how to configure a non-root public URL by running `npm run build`.
-->
<title>12기 프론트 투표</title>
<title>React Chat</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
Expand Down
Binary file added public/myphoto.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
241 changes: 238 additions & 3 deletions src/App.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,245 @@
import React from 'react';
import React, { useState } from 'react';
import styled from 'styled-components';

import ProfileContainer from './ProfileContainer';
import ChatList from './ChatList';
import ChatInput from './ChatInput';

import { BrowserRouter, Route, Switch, Redirect, Link } from 'react-router-dom';
import FriendList from './FriendList';
import RoomList from './RoomList';
import Settings from './Settings';

const initialChatData = [
{
chatId: 1,
chatText: '미션 다햇니',
userId: 0,
profileImgSrc: process.env.PUBLIC_URL + '/babodog.jpg',
roomId: 1,
},
{
chatId: 2,
chatText: '아니ㅎㅎ',
userId: 1,
profileImgSrc: process.env.PUBLIC_URL + '/babodog.jpg',
roomId: 1,
},
{
chatId: 1,
chatText: '미션 다햇니',
userId: 0,
profileImgSrc: process.env.PUBLIC_URL + '/babodog.jpg',
roomId: 2,
},
{
chatId: 2,
chatText: '아니ㅎㅎ',
userId: 2,
profileImgSrc: process.env.PUBLIC_URL + '/babodog.jpg',
roomId: 2,
},
{
chatId: 1,
chatText: '미션 다햇니',
userId: 0,
profileImgSrc: process.env.PUBLIC_URL + '/babodog.jpg',
roomId: 3,
},
{
chatId: 2,
chatText: '아니ㅎㅎ',
userId: 3,
profileImgSrc: process.env.PUBLIC_URL + '/babodog.jpg',
roomId: 3,
},
{
chatId: 1,
chatText: '미션 다햇니',
userId: 0,
profileImgSrc: process.env.PUBLIC_URL + '/babodog.jpg',
roomId: 4,
},
{
chatId: 2,
chatText: '아니ㅎㅎ',
userId: 4,
profileImgSrc: process.env.PUBLIC_URL + '/babodog.jpg',
roomId: 4,
},
{
chatId: 1,
chatText: '미션 다햇니',
userId: 0,
profileImgSrc: process.env.PUBLIC_URL + '/babodog.jpg',
roomId: 5,
},
{
chatId: 2,
chatText: '아니ㅎㅎ',
userId: 5,
profileImgSrc: process.env.PUBLIC_URL + '/babodog.jpg',
roomId: 5,
},
{
chatId: 1,
chatText: '미션 다햇니',
userId: 6,
profileImgSrc: process.env.PUBLIC_URL + '/babodog.jpg',
roomId: 6,
},
{
chatId: 2,
chatText: '아니ㅎㅎ',
userId: 0,
profileImgSrc: process.env.PUBLIC_URL + '/babodog.jpg',
roomId: 6,
},
{
chatId: 1,
chatText: '미션 다햇니',
userId: 7,
profileImgSrc: process.env.PUBLIC_URL + '/babodog.jpg',
roomId: 7,
},
{
chatId: 2,
chatText: '아니ㅎㅎ',
userId: 0,
profileImgSrc: process.env.PUBLIC_URL + '/babodog.jpg',
roomId: 7,
},
];

const initialusers = [
{
id: 0,
name: '정윤선',
profileImgSrc: process.env.PUBLIC_URL + '/myphoto.jpg',
},
{
id: 1,
name: '김선종',
profileImgSrc: process.env.PUBLIC_URL + '/babodog.jpg',
},
{
id: 2,
name: '김영우',
profileImgSrc: process.env.PUBLIC_URL + '/babodog.jpg',
},
{
id: 3,
name: '박예진',
profileImgSrc: process.env.PUBLIC_URL + '/babodog.jpg',
},
{
id: 4,
name: '안건희',
profileImgSrc: process.env.PUBLIC_URL + '/babodog.jpg',
},
{
id: 5,
name: '이소정',
profileImgSrc: process.env.PUBLIC_URL + '/babodog.jpg',
},
{
id: 6,
name: '이승범',
profileImgSrc: process.env.PUBLIC_URL + '/babodog.jpg',
},
{
id: 7,
name: '이호연',
profileImgSrc: process.env.PUBLIC_URL + '/babodog.jpg',
},
];

function App() {
const [messages, setMessages] = useState(initialChatData);
const [rooms, setRooms] = useState([]);
const [currentUser, setCurrentUser] = useState(initialusers[0]);

function toggleCurrentUser(roomId) {
if (currentUser === initialusers[0]) {
setCurrentUser(initialusers[roomId]);
} else {
setCurrentUser(initialusers[0]);
}
}

function addChatData(message, roomId) {
setMessages(
messages.concat([
{
chatId: messages.length,
chatText: message,
userId: currentUser.id,
profileImgSrc: currentUser.profileImgSrc,
roomId: roomId,
},
])
);
}

// function createRoom(friendId) {
// setRooms((prevRooms) => {
// let newRooms = prevRooms;
// newRooms.push({
// roomId: rooms.length,
// participants: [friendId, currentUser.id],
// });
// return newRooms;
// });
// }

return (
<div > 12기 프론트엔드 개발팀장 투표 ^.^
</div>
<BrowserRouter>
<Container>
<Switch>
<Route path="/friends">
<FriendList FriendListData={initialusers} />
</Route>{' '}
{/* 이부분은 사용자에게 보이는 주소창에 들어가는 부분! */}
<Route path="/rooms">
<RoomList initialusers={initialusers} messages={messages} />
</Route>
<Route path="/room/:roomId">
{' '}
{/* :id 는 유저가 주소창에 입력한 값을 불러오는 곳이다
(줌 방 번호같은 느낌)
만약 여러개의 parameter 를 만들고 싶으면
/:id/:melon/:peach 이런식으루 쓰면 된다!} */}

<ProfileContainer
currentUser={currentUser}
toggleCurrentUser={toggleCurrentUser}
/>
<ChatList messages={messages} />
<ChatInput addChatData={addChatData} />
</Route>
<Route path="/settings">
<Settings />
</Route>
<Route path="/">
{/* 만약 이걸 제일 처음에 넣고 싶으면
exact path="/" 라고 넣어주면 된다! */}
{/* Switch가 없으면 루트에 일치하는 모든 것들을
불러오지만 Switch를 넣으면 일치하는 첫번째 루트만
불러온다. 따라서 Switch가 없으면 /를 마지막에 넣어도
소용이 없다. */}
<Redirect to="/friends" />
</Route>
</Switch>
</Container>
</BrowserRouter>
);
}

const Container = styled.div`
width: 100vw;
height: 100vh;
display: flex;
flex-direction: column;
`;

export default App;
59 changes: 59 additions & 0 deletions src/ChatInput.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import { useState } from 'react';
import { useParams } from 'react-router-dom';
import styled from 'styled-components';

const Container = styled.div`
display: flex;
flex-direction: row;

height: 60px;
`;

const ChatSendInput = styled.input`
flex-grow: 5;
`;

const SubmitButton = styled.button`
flex-grow: 1;
`;

function ChatInput(props) {
const [inputValue, setInputValue] = useState('');

const { addChatData } = props;

const { roomId } = useParams(); // App.js에서 Route path="/room/:id에서 불러온 parameters 중에 id!"

function handleChange(e) {
setInputValue(e.target.value); // inputValue를 e.target.value로 업데이트
}

function handleClick() {
if (inputValue !== '') {
addChatData(inputValue, roomId);
setInputValue('');
}
}

function handleKeyPress(e) {
if (e.code === 'Enter' && !e.isComposing) {
handleClick();
}
}

return (
<Container>
<ChatSendInput
value={inputValue}
onChange={handleChange}
onKeyPress={handleKeyPress}
/>
<SubmitButton onClick={handleClick}>전송</SubmitButton>
</Container>
);
}
// value는 원래 html에서 Input이라는 element에 있는 attribute이다.
// 여기서 value는 원래 props인데 styled.component의 기능 중 같은 이름이면 attribute로 처리되는 기능때문에 attribute로 처리된다.
// styledComponent로 HTML attribute와 같은 이름을 가진 props를 넘겨주면, 그걸 자동으로 html attribute로 넘겨준다.

export default ChatInput;
49 changes: 49 additions & 0 deletions src/ChatItem.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import styled from 'styled-components';

const ChatBox = styled.div`
display: flex;
flex-direction: row;
margin-bottom: 15px;
`;
// const name = "정윤선"
// const Text = `저의 이름은 ${name}입니다.`

const Photo = styled.img`
width: 50px;
height: 50px;
border-radius: 50%;
`;

const ChatText = styled.div`
border: 1px solid black;
border-radius: 10px;
padding: 10px;
display: flex;
flex-direction: row;
justify-content: flex-start;
align-items: flex-start;
margin: 0 10px;
`;

export default function ChatItem(props) {
// props = { item: item }

// props.item = {
// chatId: 1,
// chatText: '안녕!!',
// userId: 1,
// profileImg: process.env.PUBLIC_URL + '/logo512.png',
// }

const { chatText, profileImgSrc, userId } = props.item;
// const {messages} = props;
// const messages = props.messages 둘이 같은거!
// 결론은 const userId = props.item.userId
console.log(props.item.userId===0)
return (
<ChatBox userId={userId} style={{flexDirection: (props.item.userId===0 ? 'row' : 'row-reverse')}}>
<Photo src={profileImgSrc} />
<ChatText>{chatText}</ChatText>
</ChatBox>
);
}
Loading