Commit 228362f2 authored by JeongYeonwoo's avatar JeongYeonwoo
Browse files

Merge remote-tracking branch 'origin/young' into yeonwoo

parents 8b3af68d 918ba292
node_modules node_modules
package-lock.json package-lock.json
package.json
uploads/ uploads
\ No newline at end of file \ No newline at end of file
...@@ -25,5 +25,4 @@ yarn-error.log* ...@@ -25,5 +25,4 @@ yarn-error.log*
.env .env
.eslintcache .eslintcache
.package-lock.json .package-lock.json
.package.json
debug.log debug.log
...@@ -9,13 +9,13 @@ ...@@ -9,13 +9,13 @@
"@testing-library/user-event": "^12.6.0", "@testing-library/user-event": "^12.6.0",
"axios": "^0.21.1", "axios": "^0.21.1",
"bootstrap": "^4.5.3", "bootstrap": "^4.5.3",
"nanoid": "^3.1.20",
"react": "^17.0.1", "react": "^17.0.1",
"react-bootstrap": "^1.4.0", "react-bootstrap": "^1.4.0",
"react-dom": "^17.0.1", "react-dom": "^17.0.1",
"react-router-dom": "^5.2.0", "react-router-dom": "^5.2.0",
"react-scripts": "4.0.1", "react-scripts": "4.0.1",
"socket.io-client": "^3.0.5", "socket.io-client": "^3.0.5",
"styled-components": "^5.2.1",
"web-vitals": "^0.2.4" "web-vitals": "^0.2.4"
}, },
"scripts": { "scripts": {
......
...@@ -6,9 +6,13 @@ import catchErrors from '../utils/catchErrors'; ...@@ -6,9 +6,13 @@ import catchErrors from '../utils/catchErrors';
function Chat(props) { function Chat(props) {
const [user, setUser] = useState('') // let defaultname = sessionStorage.getItem('name');
const [error, setError] = useState('')
const [inner, setInner] = useState([''])
const [chat, setChat] = useState([]) //object로 key는 보낸사람 value는 메세지
const [disabled, setDisabled] = useState(true) const [disabled, setDisabled] = useState(true)
const [user, setUser] = useState('')
const [error, setError] = useState('');
const userId = isAuthenticated() const userId = isAuthenticated()
async function getProfile(userId) { async function getProfile(userId) {
...@@ -20,15 +24,6 @@ function Chat(props) { ...@@ -20,15 +24,6 @@ function Chat(props) {
} }
} }
// let defaultname=''
let defaultname = sessionStorage.getItem('name');
const [inner, setInner] = useState([''])
const [chat, setChat] = useState([inner]) //object로 key는 보낸사람 value는 메세지
function handleChange(e) { function handleChange(e) {
e.preventDefault() e.preventDefault()
setInner(e.target.value) setInner(e.target.value)
...@@ -61,39 +56,51 @@ function Chat(props) { ...@@ -61,39 +56,51 @@ function Chat(props) {
const time = new Date().toLocaleTimeString() const time = new Date().toLocaleTimeString()
return ( return (
<div className="chat" id="chat" style={{ border: "2px solid", height: "300%", margin: "1%", borderColor: "#BDBDBD", background: '' }}> <div className="chat" id="chat" style={{ border: "2px solid", height: "300%", margin: "1%", borderColor: "#BDBDBD", background: '' }}>
<h2>현재 {props.roomName} 입니다.{chat.length}</h2> <h2>해당 방에 대한 참여코드는 {props.roomCode} 입니다.</h2>
{/* 상대방이 보낸 메세지 띄우기 + 같은유저면 프로필 이미지는 생략(chat을 object로 보낸사람과 함께 보내서 구분하자) */} {/* 상대방이 보낸 메세지 띄우기 + 같은유저면 프로필 이미지는 생략(chat을 object로 보낸사람과 함께 보내서 구분하자) */}
{ chat.map((value, index) => ( {chat.map((value, index) => {
<Row key={index} className='m-1 ml-3' > if (!(value == '')) {
<Col xs={2}> return (
{user.profileimg ? <Image src={user.profileimg && `/images/${user.profileimg}`} style={{ width: "50px", height: "50px" }} roundedCircle /> : <Image src='https://www.flaticon.com/svg/vstatic/svg/149/149071.svg?token=exp=1610922596~hmac=f4b972b9db509d4e3cc2eb40543b0b0f' style={{ width: "50px", height: "50px" }} roundedCircle />} <Row key={index} className='m-1 ml-3' >
</Col> <Col xs={2}>
<Col xs={8} className='justify-content-flex-start'> {user.profileimg ? <Image src={user.profileimg && `/images/${user.profileimg}`} style={{ width: "50px", height: "50px" }} roundedCircle /> : <Image src='https://www.flaticon.com/svg/vstatic/svg/149/149071.svg?token=exp=1610922596~hmac=f4b972b9db509d4e3cc2eb40543b0b0f' style={{ width: "50px", height: "50px" }} roundedCircle />}
<Row>{user.nickname}</Row> </Col>
<Row className='d-flex flex-wrap-nowrap'> <Col xs={8}>
<Row className='border border-dark' style={{ width: 'max-content', maxWidth: '300px', height: 'auto', paddingLeft: '15px', paddingRight: '15px', background: 'white', borderRadius: '5px', fontSize: 'x-large' }}>{value}</Row> <Row><strong>{user.nickname} {index}</strong></Row>
<Col xs={5} className='ml-1'>{new Date().toLocaleTimeString()}</Col> <Row className='d-flex flex-wrap-nowrap'>
<Col className='border border-dark' style={{ width: 'max-content', maxWidth: '300px', height: 'auto', paddingLeft: '15px', paddingRight: '15px', background: 'white', borderRadius: '5px', fontSize: 'x-large' }}>{value}</Col>
<Col className='ml-4'>{new Date().toLocaleTimeString()}</Col>
</Row>
</Col>
</Row> </Row>
</Col> )
</Row> } else {
)) return null
}
})
} }
{/* 내가 보낸 메세지 띄우기 */} {/* 내가 보낸 메세지 띄우기 */}
{ chat.map((value, index) => ( {chat.map((value, index) => {
<Row key={index} className='m-1 mr-5 justify-content-end'> if (!(value == '')) {
<Row className='d-flex flex-wrap-nowrap' > return (
<Col className='mr-1'>{time}</Col> <Row key={index} className='m-1 mr-4 justify-content-end'>
<Row style={{ width: 'max-content', maxWidth: '300px', height: 'auto', paddingLeft: '15px', paddingRight: '15px', background: 'yellow', borderRadius: '3px', fontSize: 'x-large' }}>{value}</Row> <div className='d-flex flex-wrap-nowrap' >
</Row> <Row className='mr-4'>{time}</Row>
</Row> <Row style={{ width: 'max-content', maxWidth: '300px', height: 'auto', paddingLeft: '15px', paddingRight: '15px', background: 'yellow', borderRadius: '3px', fontSize: 'x-large' }}>{value}</Row>
</div>
)) </Row>
)
} else {
return null
}
})
} }
<Button variant="light" onClick={props.handleChatc} >{`<`}</Button> <Button variant="light" onClick={props.handleChatc} >{`<`}</Button>
<Form onSubmit={sendMsgCH}> <Form onSubmit={sendMsgCH}>
<Form.Group className='d-flex flex-wrap-nowrap justify-content-center ml-2 mr-2'> <Form.Group className='d-flex flex-wrap-nowrap justify-content-center ml-2 mr-2'>
...@@ -110,4 +117,5 @@ function Chat(props) { ...@@ -110,4 +117,5 @@ function Chat(props) {
); );
} }
export default Chat; export default Chat;
import React, { useState } from 'react';
import { Form, Row, Col, Button } from 'react-bootstrap'
function ChatForm(props) {
const INIT_SAYING = ''
const [saying, setSaying] = useState(INIT_SAYING);
function handleChange(event) {
const { name, value } = event.target
setSaying(value)
console.log(saying)
}
function handleSubmit(event) {
event.preventDefault()
// const response = await axios.post('chat/makeChat', chatR)
props.setSingleChat()
setSaying(INIT_SAYING)
}
return (
<Form onSubmit={handleSubmit}>
<Row>
<Col>
<Form.Group>
<Form.Control name='chat' type='text' onChange={handleChange}>chat</Form.Control>
</Form.Group>
</Col>
<Col>
<Form.Group>
<Button type="submit">send</Button>
</Form.Group>
</Col>
</Row>
</Form>
)
}
export default ChatForm
\ No newline at end of file
import React, { useState } from 'react' import React, { useState, useEffect } from 'react'
import { ListGroup, Row, Col } from 'react-bootstrap'; import { ListGroup } from 'react-bootstrap';
import axios from 'axios'
function ClosedList(props) { function ClosedList(props) {
const [list, setList] = useState([
{ room: '테스트 방1', memnum: 5, admin: '가영' }, const [list, setList] = useState([]);
{ room: '테스트 방2', memnum: 4, admin: '수현' }]
); useEffect(() => {
getClosedList();
function enterChatroomCH(e) { }, []);
console.log(e.target.name)
console.log(e.target) async function getClosedList() {
const roomName = e.target.name const userid = sessionStorage.getItem('userId')
props.enterChatroom(roomName) // 각각의 room으로 들어가도록 설정해야 함 let res = await axios.get('/room/closedlist', { params: { '_id': userid } })
props.setRoomName(roomName) setList(res.data)
// props.clearChat() }
function enterChatRoomCH(e) {
const roomCode = e.target.name
props.enterChatRoom(roomCode)
props.setRoomCode(roomCode)
} }
return ( return (
<div> <div>
{list.map((item, index) => {list.map((item, index) =>
<ListGroup key={index}> <ListGroup key={index}>
<ListGroup.Item action onClick={enterChatroomCH} name={item.room}> <ListGroup.Item action onClick={enterChatRoomCH} name={item.roomId}>
{item.room} {item.roomName}
</ListGroup.Item> </ListGroup.Item>
</ListGroup> </ListGroup>
)} )}
......
import React, { useState } from 'react'
import axios from 'axios';
import { Row, Col, Modal, Button, Form } from 'react-bootstrap';
import catchErrors from '../utils/catchErrors'
function EnterRoom(props) {
const [enterCode, setEnterCode] = useState('');
const [error, setError] = useState('');
function handleChange(event) {
const { name, value } = event.target
setEnterCode(value)
console.log(enterCode)
}
async function handleSubmit(event) {
event.preventDefault()
try {
setError('')
let res = await axios.post('/room/enterRoom', { enterCode })
props.setRoomName(res.data)
props.enterChatRoom(enterCode)
props.handleCloseEnter()
props.handleChato()
setEnterCode('')
} catch (error){
catchErrors(error, setError)
}
}
return (
<>
<Modal show={props.showEnter} onHide={props.handleCloseEnter}>
<Modal.Header closeButton>
<Modal.Title>참여 코드로 채팅 참가</Modal.Title>
</Modal.Header>
<Modal.Body>
<Form onSubmit={handleSubmit}>
<Form.Group as={Row} controlId="formCodeE">
<Form.Label column sm={4}>참여 코드</Form.Label>
<Col>
<Form.Control name='roomCode' type='text' value={enterCode} onChange={handleChange} />
</Col>
</Form.Group>
<Form.Group as={Row}>
<Col sm={{ span: 5, offset: 4 }}>
<Button type="submit">참가</Button>
</Col>
</Form.Group>
</Form>
</Modal.Body>
</Modal>
</>
)
}
export default EnterRoom
import React, { useState, useEffect } from 'react' import React from 'react'
import { Navbar, Nav, Button } from 'react-bootstrap'; import { Navbar, Nav, Button } from 'react-bootstrap';
import { Link } from 'react-router-dom';
import { handleLogout } from '../utils/auth'; import { handleLogout } from '../utils/auth';
import axios from 'axios'
function Menu() { function Menu() {
...@@ -12,14 +10,18 @@ function Menu() { ...@@ -12,14 +10,18 @@ function Menu() {
return ( return (
<Navbar bg="dark" variant="dark"> <Navbar bg="dark" variant="dark">
<Navbar.Brand href="/home">YDK Messenger</Navbar.Brand> <Navbar.Brand href="/home">YDK Messenger</Navbar.Brand>
<div className='ml-1 mr-2' style={{ color: 'white' }}>{name} 환영합니다</div> {name ?
<Nav className="mr-auto"> <>
<Nav.Link href="/home">Home</Nav.Link> <div className='ml-1 mr-2' style={{ color: 'white' }}>{name} 환영합니다</div>
<Nav.Link href="/profile">Profile</Nav.Link> <Nav className="mr-auto">
</Nav> <Nav.Link href="/profile">Profile</Nav.Link>
<Link to="./login"> </Nav>
<Button onClick={() => handleLogout()} variant="light" className="ml-3">Logout</Button> <Button className="ml-auto" onClick={() => handleLogout()} variant="light" className="ml-3">Logout</Button>
</Link> </>
: <Nav className="ml-auto">
<Nav.Link href='/login'>로그인</Nav.Link>
<Nav.Link href='/signup'>회원가입</Nav.Link>
</Nav>}
</Navbar> </Navbar>
) )
} }
......
import React, { useState } from 'react' import React, { useState, useEffect } from 'react'
import { ListGroup } from 'react-bootstrap'; import { ListGroup } from 'react-bootstrap';
import axios from 'axios'
function OpenList(props) { function OpenList(props) {
const [list, setList] = useState([ const [openlist, setOpenlist] = useState([]);
{ room: '테스트 방3', memnum: 7, admin: '가영2' },
{ room: '테스트 방4', memnum: 2, admin: '수현2' }]
);
function enterChatroomCH(e) { useEffect(() => {
const roomName = e.target.name getOpenList();
props.enterChatroom(roomName) // 각각의 room으로 들어가도록 설정해야 함 }, []);
props.setRoomName(roomName)
async function getOpenList() {
let res = await axios.get('/room/openlist')
setOpenlist(res.data)
}
function enterChatRoomCH(e) {
const roomCode = e.target.name
props.enterChatRoom(roomCode) // 각각의 room으로 들어가도록 설정해야 함
props.setRoomCode(roomCode)
// props.clearChat() // props.clearChat()
} }
return ( return (
<div> <div>
{list.map((list, index) => {openlist.map((item, index) =>
<ListGroup key={index}> <ListGroup key={index}>
<ListGroup.Item action onClick={enterChatroomCH} name={list.room}> <ListGroup.Item action onClick={enterChatRoomCH} name={item.roomId}>
<h2>{list.room}</h2> {item.roomName}
</ListGroup.Item> </ListGroup.Item>
</ListGroup> </ListGroup>
)} )}
......
...@@ -2,19 +2,18 @@ import React from 'react' ...@@ -2,19 +2,18 @@ import React from 'react'
import { Redirect, Route } from 'react-router-dom' import { Redirect, Route } from 'react-router-dom'
import { isAuthenticated } from '../utils/auth' import { isAuthenticated } from '../utils/auth'
function PrivateRoute({ path, children }) { function PrivateRoute({path, children}) {
if (isAuthenticated()) { if (isAuthenticated()) {
return ( return (
<Route path={path}> <Route path={path}>
{children} {children}
</Route> </Route>
) )
} else { } else {
return ( return (
<Redirect to='/login'/> <Redirect to='./login' />
) )
} }
} }
export default PrivateRoute export default PrivateRoute
\ No newline at end of file
import React, { useState, useEffect } from 'react'
import axios from 'axios';
import { Row, Col, Modal, Button, Form, Alert } from 'react-bootstrap';
import catchErrors from '../utils/catchErrors';
const INIT_ROOM = {
roomName: '',
interest: '',
isOpen: false
}
function RoomMake(props) {
const [room, setRoom] = useState(INIT_ROOM);
const [disabled, setDisabled] = useState(true);
const [error, setError] = useState('');
useEffect(() => {
const isRoom = Object.values(room).every(el => Boolean(el))
isRoom ? setDisabled(false) : setDisabled(true)
}, [room])
const member = sessionStorage.getItem('userId');
function handleChange(event) {
const { name, value } = event.target
setRoom({ ...room, [name]: value , member})
console.log(room)
}
async function handleSubmit(event) {
event.preventDefault()
try {
setError('')
let res = await axios.post('/room/makeRoom', room)
const Id = res.data.roomId
alert(`방암호는 ${Id}입니다`)
props.handleCloseModal()
setRoom(INIT_ROOM)
} catch (error){
catchErrors(error, setError)
}
}
return (
<Modal show={props.showModal} onHide={props.handleCloseModal}>
<Modal.Header closeButton>
<Modal.Title> 생성</Modal.Title>
</Modal.Header>
{error && <Alert variant='danger'>
{error}
</Alert>}
<Modal.Body>
<Form onSubmit={handleSubmit}>
<Form.Group as={Row} controlId="chatName">
<Form.Label column sm={4}> 이름</Form.Label>
<Col>
<Form.Control name='roomName' type='text' value={room.roomName} onChange={handleChange} />
</Col>
</Form.Group>
<Form.Group as={Row} controlId="chatInterest">
<Form.Label column sm={4}>관심 분야</Form.Label>
<Col>
<Form.Control as="select" defaultValue="Choose..." name='interest' type='text' value={room.interest} onChange={handleChange}>
<option>Choose...</option>
<option>과학</option>
<option>수학</option>
<option>예술</option>
<option>언어</option>
<option>취미</option>
</Form.Control>
{/* <Form.Control type="text" /> */}
</Col>
</Form.Group>
<Form.Group as={Row} controlId="chatIsOpen">
<Form.Label column sm={4}>공개방</Form.Label>
<Col>
<Form.Check
type="checkbox"
checked={room.isOpen}
name='isOpen'
onChange={() => setRoom({ ...room, isOpen: !room.isOpen })} />
</Col>
</Form.Group>
{
(room.isOpen)
? (<p><b>공개방</b>으로 개설되어 공개방 목록에 공개되며, 코드를 공유하여 참가할 수도 있습니다.</p>)
: (<p><b>비밀방</b>으로 개설되며, 참여자들에게 코드를 공유해야합니다.</p>)
}
<Form.Group as={Row}>
<Col sm={{ span: 5, offset: 4 }}>
<Button type="submit" > 생성</Button>
</Col>
</Form.Group>
</Form>
</Modal.Body>
</Modal>
)
}
export default RoomMake
import React, { useState, useEffect } from 'react'; import React, { useState, useEffect } from 'react';
import axios from 'axios'; import { Row, Col, Button } from 'react-bootstrap';
import { Row, Col, Modal, Button, Form, Alert } from 'react-bootstrap';
import Tabs from 'react-bootstrap/Tabs'; import Tabs from 'react-bootstrap/Tabs';
import Tab from 'react-bootstrap/Tab'; import Tab from 'react-bootstrap/Tab';
import ClosedList from '../Components/ClosedList'; import ClosedList from '../Components/ClosedList';
import OpenList from '../Components/OpenList'; import OpenList from '../Components/OpenList';
import Menu from '../Components/Menu'; import Menu from '../Components/Menu';
import catchErrors from '../utils/catchErrors';
import { io } from "socket.io-client"; //모듈 가져오기 import { io } from "socket.io-client"; //모듈 가져오기
import Chat from "../Components/Chat"; import Chat from "../Components/Chat";
import RoomMake from "../Components/RoomMake"
import EnterRoom from "../Components/EnterRoom"
const socket = io(); const socket = io();
const INIT_ROOM = {
roomName: '',
interest: '',
isOpen: false
}
function Home() { function Home() {
// const [namelist, setNamelist] = useState([]) const [showModal, setShowModal] = useState(false);
const [showEnter, setEnter] = useState(false);
const [show, setShow] = useState(false); const [chat, setChat] = useState(false);
const [show2, setShow2] = useState(false);
const [chat, setChat] = useState(false); //소켓
const [room, setRoom] = useState(INIT_ROOM); const [singleChat, setSingleChat] = useState('')
const [disabled, setDisabled] = useState(true); const [recievedMsg, setRecievedMsg] = useState('')
const [error, setError] = useState(''); const [roomCode, setRoomCode] = useState('')
const [singleChat, setSingleChat] = useState('') //방참가
const [roomName, setRoomName] = useState('')
const [recievedMsg, setRecievedMsg] = useState('') const [roomName, setRoomName] = useState('')
const handleClose = () => setShow(false); const handleCloseModal = () => setShowModal(false);
const handleShow = () => setShow(true); const handleShowModal = () => setShowModal(true);
const handleChato = () => setChat(true); const handleCloseEnter = () => setEnter(false);
const handleChatc = () => setChat(false); const handleShowEnter = () => setEnter(true);
const handleClose2 = () => setShow2(false); const handleChato = () => setChat(true);
const handleShow2 = () => setShow2(true); const handleChatc = () => setChat(false);
useEffect(() => {
const isRoom = Object.values(room).every(el => Boolean(el))
isRoom ? setDisabled(false) : setDisabled(true) //SOCKET 관련 시작
}, [room]) function enterChatRoom(rName) { //방 입장하기
socket.emit('joinRoom', rName)
function handleChange(event) { console.log(`joinRoom : ${rName} 입장`)
const { name, value } = event.target }
setRoom({ ...room, [name]: value })
console.log(room) const sendMsg = (e) => {
} e.preventDefault()
async function handleSubmit(event) {
event.preventDefault()
try {
setError('')
await axios.post('/room/makeRoom', room)
setRoom(INIT_ROOM)
} catch (error) {
catchErrors(error, setError)
} }
}
useEffect(() => {
//SOCKET 관련 시작 if (!(singleChat == '')) {
socket.emit("chat", {
function enterChatroom(rName) { //방 입장하기 roomInfo: roomCode,
socket.emit('joinRoom', rName) msg: singleChat
console.log(`joinRoom : ${rName} 입장`) })
} setSingleChat([''])
}
const sendMsg = (e) => { }, [singleChat])
e.preventDefault()
// socket.emit("chat", {
// roomName: roomName, useEffect(() => {
// msg: inner, socket.on("sendedMSG", (msg) => {
// }); console.log(msg)
} setRecievedMsg(msg)
})
useEffect(() => { }, [])
socket.emit("chat", {
roomName: roomName, return (
msg: singleChat <>
}) <Menu />
}, [singleChat]) <Row className="mr-0">
<Col className="list" md={5}>
useEffect(() => { <Tabs defaultActiveKey="closed" id="uncontrolled-tab-example">
socket.on("sendedMSG", (msg) => { <Tab eventKey="closed" title="내 채팅" onClick={handleChato} >
console.log('sendedMsg = ', msg) <ClosedList enterChatRoom={enterChatRoom} setRoomCode={setRoomCode} />
setRecievedMsg(msg) </Tab>
}) <Tab eventKey="open" title="공개방" onClick={handleChato}>
}, []) <OpenList enterChatRoom={enterChatRoom} setRoomCode={setRoomCode} />
socket.on('broadcast', (msg) => { </Tab>
console.log(msg) </Tabs>
setSingleChat(msg) </Col>
}) <Col style={{ padding: "0" }}>
{chat ? <Chat handleChatc={handleChatc} sendMsg={sendMsg} singleChat={singleChat} recievedMsg={recievedMsg} setSingleChat={setSingleChat} roomCode={roomCode} /> : null}
return (
<> <div style={{ position: "fixed", bottom: "20px", right: "30px" }}>
<Menu /> <Button variant="primary" onClick={handleShowModal} size="lg" block>
<Row className="mr-0"> 생성
<Col className="list" md={5}>
<Tabs defaultActiveKey="closed" id="uncontrolled-tab-example">
<Tab eventKey="closed" title="내 채팅" onClick={handleChato} >
<ClosedList enterChatroom={enterChatroom} setRoomName={setRoomName} />
</Tab>
<Tab eventKey="open" title="공개방" >
<OpenList enterChatroom={enterChatroom} setRoomName={setRoomName} />
</Tab>
</Tabs>
</Col>
<Col style={{ padding: "0" }}>
{chat ? <Chat handleChatc={handleChatc} sendMsg={sendMsg} singleChat={singleChat} setSingleChat={setSingleChat} roomName={roomName} recievedMsg={recievedMsg} /> : null}
<div style={{ position: "fixed", bottom: "20px", right: "30px" }}>
<Button variant="primary" onClick={handleShow} size="lg" block>
생성
</Button> </Button>
<Button variant="secondary" onClick={handleShow2} size="lg" block> <Button variant="secondary" onClick={handleShowEnter} size="lg" block>
참가 참가
</Button> </Button>
</div> </div>
</Col>
<Modal show={show} onHide={handleClose}> </Row>
<Modal.Header closeButton> <RoomMake showModal={showModal} handleCloseModal={handleCloseModal} />
<Modal.Title> 생성</Modal.Title> <EnterRoom showEnter={showEnter} enterChatRoom={enterChatRoom} handleCloseEnter={handleCloseEnter} handleChato={handleChato} setRoomName={setRoomName}/>
</Modal.Header> </>
{error && <Alert variant='danger'> );
{error}
</Alert>}
<Modal.Body>
<Form onSubmit={handleSubmit}>
<Form.Group as={Row} controlId="chatName">
<Form.Label column sm={4}> 이름</Form.Label>
<Col>
<Form.Control name='roomName' type='text' value={room.roomName} onChange={handleChange} />
</Col>
</Form.Group>
<Form.Group as={Row} controlId="chatInterest">
<Form.Label column sm={4}>관심 분야</Form.Label>
<Col>
<Form.Control as="select" defaultValue="Choose..." name='interest' type='text' value={room.interest} onChange={handleChange}>
<option>Choose...</option>
<option>과학</option>
<option>수학</option>
<option>예술</option>
<option>언어</option>
<option>취미</option>
</Form.Control>
{/* <Form.Control type="text" /> */}
</Col>
</Form.Group>
<Form.Group as={Row} controlId="chatIsOpen">
<Form.Label column sm={4}>공개방</Form.Label>
<Col>
<Form.Check
type="checkbox"
checked={room.isOpen}
name='isOpen'
onChange={() => setRoom({ ...room, isOpen: !room.isOpen })} />
</Col>
</Form.Group>
{
(room.isOpen)
? (<p><b>공개방</b>으로 개설되어 공개방 목록에 공개되며, 코드를 공유하여 참가할 수도 있습니다.</p>)
: (<p><b>비밀방</b>으로 개설되며, 참여자들에게 코드를 공유해야합니다.</p>)
}
<Form.Group as={Row}>
<Col sm={{ span: 5, offset: 4 }}>
<Button type="submit" > 생성</Button>
</Col>
</Form.Group>
</Form>
</Modal.Body>
</Modal>
<Modal show={show2} onHide={handleClose2}>
<Modal.Header closeButton>
<Modal.Title>참여 코드로 채팅 참가</Modal.Title>
</Modal.Header>
<Modal.Body>
<Form onSubmit={() => { console.log('제출') }}>
<Form.Group as={Row} controlId="formCodeE">
<Form.Label column sm={4}>참여 코드</Form.Label>
<Col>
<Form.Control type="text" />
</Col>
</Form.Group>
<Form.Group as={Row}>
<Col sm={{ span: 5, offset: 4 }}>
<Button type="submit">참가</Button>
</Col>
</Form.Group>
</Form>
</Modal.Body>
</Modal>
</Col>
</Row>
</>
);
} }
export default Home; export default Home;
...@@ -4,6 +4,7 @@ import { Button, Form, Container, Navbar, Spinner, Alert } from 'react-bootstrap ...@@ -4,6 +4,7 @@ import { Button, Form, Container, Navbar, Spinner, Alert } from 'react-bootstrap
import catchErrors from '../utils/catchErrors' import catchErrors from '../utils/catchErrors'
import { Link, Redirect } from 'react-router-dom' import { Link, Redirect } from 'react-router-dom'
import { handleLogin } from '../utils/auth' import { handleLogin } from '../utils/auth'
import Menu from '../Components/Menu';
const INIT_USER = { const INIT_USER = {
email: '', email: '',
...@@ -48,14 +49,13 @@ function LogIn() { ...@@ -48,14 +49,13 @@ function LogIn() {
//success시 링크이동 //success시 링크이동
if (success) { if (success) {
console.log('success', success) console.log('success', success)
alert('로그인 되었습니다!')
return <Redirect to='/' /> return <Redirect to='/' />
} }
return ( return (
<> <>
<Navbar bg="dark" variant="dark"> <Menu />
<Navbar.Brand>YDK Messenger</Navbar.Brand>
</Navbar>
<Form onSubmit={handleSubmit} className='vh-100 flex-column align-items-center justify-content-center mt-2'> <Form onSubmit={handleSubmit} className='vh-100 flex-column align-items-center justify-content-center mt-2'>
<Container className="d-flex justify-content-center"> <Container className="d-flex justify-content-center">
<div className="mt-5 p-5 shadow w-75"> <div className="mt-5 p-5 shadow w-75">
...@@ -97,10 +97,6 @@ function LogIn() { ...@@ -97,10 +97,6 @@ function LogIn() {
block> block>
{loading && <Spinner as='span' animation='border' size='sm' role='status' aria-hidden='true' />} {' '} 로그인 {loading && <Spinner as='span' animation='border' size='sm' role='status' aria-hidden='true' />} {' '} 로그인
</Button> </Button>
<Link to="./signup">
<h6 type="button" className="text-right mt-2" style={{ cursor: 'pointer' }}>회원가입</h6>
</Link>
{error && <Alert variant='danger'> {error && <Alert variant='danger'>
{error} {error}
</Alert>} </Alert>}
......
import React, { useState, useEffect } from 'react' import React, { useState, useEffect } from 'react'
import Menu from '../Components/Menu'; import Menu from '../Components/Menu';
import { Image, Button, Container, Form, Row, Col, Dropdown } from 'react-bootstrap'; import { Image, Button, Container, Form, Row, Col } from 'react-bootstrap';
import { BrowserRouter as Link } from 'react-router-dom'; import { BrowserRouter as Link } from 'react-router-dom';
import axios from 'axios' import axios from 'axios'
import catchErrors from '../utils/catchErrors' import catchErrors from '../utils/catchErrors'
......
...@@ -3,6 +3,7 @@ import axios from 'axios' ...@@ -3,6 +3,7 @@ import axios from 'axios'
import { Button, Form, Container, Alert, Navbar } from 'react-bootstrap'; import { Button, Form, Container, Alert, Navbar } from 'react-bootstrap';
import catchErrors from '../utils/catchErrors'; import catchErrors from '../utils/catchErrors';
import { Redirect } from 'react-router-dom'; import { Redirect } from 'react-router-dom';
import Menu from '../Components/Menu';
const INIT_USER = { const INIT_USER = {
username: '', username: '',
...@@ -12,11 +13,11 @@ const INIT_USER = { ...@@ -12,11 +13,11 @@ const INIT_USER = {
} }
function SingUp() { function SingUp() {
const [validated, setValidated] = useState(false); //const [validated, setValidated] = useState(false);
const [user, setUser] = useState(INIT_USER) const [user, setUser] = useState(INIT_USER)
const [error, setError] = useState('') const [error, setError] = useState('')
const [disabled, setDisabled] = useState(true) const [disabled, setDisabled] = useState(true)
const [success, setSucces] = useState(false) const [success, setSuccess] = useState(false)
useEffect(() => { useEffect(() => {
const isUser = Object.values(user).every(el => Boolean(el)) const isUser = Object.values(user).every(el => Boolean(el))
...@@ -32,19 +33,19 @@ function SingUp() { ...@@ -32,19 +33,19 @@ function SingUp() {
event.preventDefault(); event.preventDefault();
//빈문자열 입력 시 오류 문자 출력 //빈문자열 입력 시 오류 문자 출력
const form = event.currentTarget; //const form = event.currentTarget;
if (form.checkValidity() === false) { //if (form.checkValidity() === false) {
event.preventDefault(); // event.preventDefault();
event.stopPropagation(); // event.stopPropagation();
} // //event.stopPropagation() : 이벤트 캡쳐링과 버블링에 있어 현재 이벤트 이후의 전파를 막습니다.
setValidated(true); //}
//setValidated(true);
// console.log(user) // console.log(user)
try { try {
setError('') setError('')
await axios.post('/users/signup', user) await axios.post('/users/signup', user)
alert("회원가입이 완료되었습니다!") setSuccess(true)
setSucces(true)
} catch (error) { } catch (error) {
catchErrors(error, setError) catchErrors(error, setError)
} }
...@@ -52,17 +53,16 @@ function SingUp() { ...@@ -52,17 +53,16 @@ function SingUp() {
if (success) { if (success) {
console.log('success', success) console.log('success', success)
alert('회원가입이 완료되었습니다!')
return <Redirect to='/login' /> return <Redirect to='/login' />
} }
return ( return (
<> <>
<Navbar bg="dark" variant="dark"> <Menu />
<Navbar.Brand>YDK Messenger</Navbar.Brand>
</Navbar>
<Form noValidate validated={validated} onSubmit={handleSubmit} className='vh-100 flex-column align-items-center justify-content-center mt-2'> <Form onSubmit={handleSubmit} className='vh-100 flex-column align-items-center justify-content-center mt-2'>
<Container className="d-flex justify-content-center"> <Container className="d-flex justify-content-center">
<div className="mt-5 p-5 shadow w-75"> <div className="mt-5 p-5 shadow w-75">
......
...@@ -2,9 +2,8 @@ import React from 'react'; ...@@ -2,9 +2,8 @@ import React from 'react';
import ReactDOM from 'react-dom'; import ReactDOM from 'react-dom';
import 'bootstrap/dist/css/bootstrap.min.css'; import 'bootstrap/dist/css/bootstrap.min.css';
import './index.css'; import './index.css';
import { BrowserRouter as Router, Route, Redirect, Switch } from 'react-router-dom'; import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
import reportWebVitals from './reportWebVitals'; import reportWebVitals from './reportWebVitals';
import SignUpPage from './Pages/SignUpPage'; import SignUpPage from './Pages/SignUpPage';
import ProfilePage from './Pages/ProfilePage'; import ProfilePage from './Pages/ProfilePage';
import 'bootstrap/dist/css/bootstrap.min.css'; import 'bootstrap/dist/css/bootstrap.min.css';
...@@ -12,7 +11,6 @@ import LogInPage from './Pages/LogInPage'; ...@@ -12,7 +11,6 @@ import LogInPage from './Pages/LogInPage';
import HomePage from './Pages/HomePage' import HomePage from './Pages/HomePage'
import PrivateRoute from './Components/PrivateRoute'; import PrivateRoute from './Components/PrivateRoute';
ReactDOM.render( ReactDOM.render(
<Router> <Router>
<Switch> <Switch>
......
...@@ -6,10 +6,11 @@ export function handleLogin(data) { ...@@ -6,10 +6,11 @@ export function handleLogin(data) {
sessionStorage.setItem('name', data.user.username) sessionStorage.setItem('name', data.user.username)
} }
export async function handleLogout() { export async function handleLogout() {
sessionStorage.clear(); sessionStorage.clear();
await axios.get('/auth/logout') await axios.get('/auth/logout')
//login페이지로 이동
window.location.href='/login'
} }
export function isAuthenticated() { export function isAuthenticated() {
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
"main": "index.js", "main": "index.js",
"type": "module", "type": "module",
"scripts": { "scripts": {
"dev": "nodemon server/server.js", "dev": "nodemon --ignore client server/server.js",
"test": "echo \"Error: no test specified\" && exit 1" "test": "echo \"Error: no test specified\" && exit 1"
}, },
"repository": { "repository": {
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
"bcrypt": "^5.0.0", "bcrypt": "^5.0.0",
"bcryptjs": "^2.4.3", "bcryptjs": "^2.4.3",
"body-parser": "^1.19.0", "body-parser": "^1.19.0",
"cors": "^2.8.5",
"express": "^4.17.1", "express": "^4.17.1",
"jsonwebtoken": "^8.5.1", "jsonwebtoken": "^8.5.1",
"mongoose": "^5.11.9", "mongoose": "^5.11.9",
......
...@@ -16,7 +16,7 @@ const login = async (req, res) => { ...@@ -16,7 +16,7 @@ const login = async (req, res) => {
const passwordMatch = await bcrypt.compare(password, user.password) const passwordMatch = await bcrypt.compare(password, user.password)
if (passwordMatch) { if (passwordMatch) {
//토큰 생성 //토큰 생성
const token = jwt.sign({ userId: user._id }, config.jwtSecret, {expiresIn: '7d'}) const token = jwt.sign({ userId: user._id}, config.jwtSecret, {expiresIn: '7d'})
//jwtSecret : 노출되면 안됨. 문자열 //jwtSecret : 노출되면 안됨. 문자열
//expiresIn: '7d' -> 만기날짜 : 만든 7일후 만기 //expiresIn: '7d' -> 만기날짜 : 만든 7일후 만기
......
...@@ -6,8 +6,8 @@ const nanoid = customAlphabet('1234567890abcdef', 10) ...@@ -6,8 +6,8 @@ const nanoid = customAlphabet('1234567890abcdef', 10)
const makeRoom = async (req, res) => { const makeRoom = async (req, res) => {
console.log(req.body) console.log(req.body)
const { roomName, interest, isOpen } = req.body; const { roomName, interest, isOpen, member } = req.body;
console.log(roomName, interest, isOpen) console.log('콘솔확인',roomName, interest, isOpen, member)
const roomId = nanoid() const roomId = nanoid()
const room = await Room.findOne({ roomId }) const room = await Room.findOne({ roomId })
...@@ -19,14 +19,15 @@ const makeRoom = async (req, res) => { ...@@ -19,14 +19,15 @@ const makeRoom = async (req, res) => {
try { try {
if (!isLength(roomName, { min: 3, max: 20 })) { if (!isLength(roomName, { min: 3, max: 20 })) {
return res.status(422).send('채팅방의 이름은 3-20자여야 합니다.') return res.status(422).send('채팅방의 이름은 3-20자여야 합니다.')
} else if (interest=='Choose...' || interest==''){ } else if (interest == 'Choose...' || interest == '') {
return res.status(422).send('분야를 반드시 선택하여야 합니다.') return res.status(422).send('분야를 반드시 선택하여야 합니다.')
} }
const newRoom = await new Room({ const newRoom = await new Room({
roomId, roomId,
roomName, roomName,
interest, interest,
isOpen isOpen,
member,
}).save() }).save()
console.log(newRoom) console.log(newRoom)
res.json(newRoom) res.json(newRoom)
...@@ -36,4 +37,25 @@ const makeRoom = async (req, res) => { ...@@ -36,4 +37,25 @@ const makeRoom = async (req, res) => {
} }
} }
export default { makeRoom } const getClosedList = async (req, res) => {
\ No newline at end of file try {
console.log('req확인',req.query._id)
let list = await Room.find({ member: [req.query._id] })
console.log('c_list가져오기', list)
return res.json(list)
} catch (error) {
res.status(500).send('리스트 불러오기를 실패하였습니다!')
}
}
const getOpenList = async (req, res) => {
try {
let list = await Room.find({ isOpen: true })
console.log('o_list가져오기', list)
return res.json(list)
} catch (error) {
res.status(500).send('리스트 불러오기를 실패하였습니다!')
}
}
export default { makeRoom, getClosedList, getOpenList }
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment