Commit 43ee14e5 authored by Choi Ga Young's avatar Choi Ga Young
Browse files

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

parents db5383e3 b1f271f9
......@@ -8,13 +8,13 @@
"@testing-library/user-event": "^12.6.0",
"axios": "^0.21.1",
"bootstrap": "^4.5.3",
"nanoid": "^3.1.20",
"react": "^17.0.1",
"react-bootstrap": "^1.4.0",
"react-dom": "^17.0.1",
"react-router-dom": "^5.2.0",
"react-scripts": "4.0.1",
"socket.io-client": "^3.0.5",
"styled-components": "^5.2.1",
"web-vitals": "^0.2.4"
},
"scripts": {
......
......@@ -24,6 +24,8 @@ function ClosedList(props) {
// props.clearChat()
}
//user.hasOwnProperty('이름');
return (
<div>
{list.map((item, index) =>
......
......@@ -12,15 +12,19 @@ function Menu() {
return (
<Navbar bg="dark" variant="dark">
<Navbar.Brand href="/home">YDK Messenger</Navbar.Brand>
<div className='ml-1 mr-2' style={{ color: 'white' }}>{name} 환영합니다</div>
<Nav className="mr-auto">
<Nav.Link href="/home">Home</Nav.Link>
<Nav.Link href="/profile">Profile</Nav.Link>
<Nav.Link href="/hello">Hello</Nav.Link>
</Nav>
<Link to="./login">
<Button onClick={() => handleLogout()} variant="light" className="ml-3">Logout</Button>
</Link>
{name ?
<>
<div className='ml-1 mr-2' style={{ color: 'white' }}>{name} 환영합니다</div>
<Nav className="mr-auto">
{/* <Nav.Link href="/home">Home</Nav.Link> */}
<Nav.Link href="/profile">Profile</Nav.Link>
</Nav>
<Button className="ml-auto" onClick={() => handleLogout()} variant="light" className="ml-3">Logout</Button>
</>
: <Nav className="ml-auto">
<Nav.Link href='/login'>로그인</Nav.Link>
<Nav.Link href='/signup'>회원가입</Nav.Link>
</Nav>}
</Navbar>
)
}
......
//로그인 한 사람만 route로 이동할 수 있도록 함
import React from 'react'
import { Redirect, Route } from 'react-router-dom'
import { isAuthenticated } from '../utils/auth'
function PrivateRoute({ path, children }) {
if (isAuthenticated()) {
return (
<Route path={path}>
{children}
</Route>
)
} else {
return (
<Redirect to='/login'/>
)
}
function PrivateRoute({path, children}) {
if (isAuthenticated()) {
//로그인이 됬을 시 정상적으로 작동
return (
<Route path={path}>
{children}
</Route>
)
} else {
//로그인이 되지 않았을 시 로그인페이지로 이동
return (
<Redirect to='./login' />
)
}
}
export default PrivateRoute
\ No newline at end of file
export default PrivateRoute
......@@ -9,13 +9,16 @@ import Menu from '../Components/Menu';
import catchErrors from '../utils/catchErrors';
import { io } from "socket.io-client"; //모듈 가져오기
import Chat from "../Components/Chat";
import { customAlphabet } from 'nanoid';
import { Redirect } from 'react-router-dom';
const socket = io();
const INIT_ROOM = {
roomName: '',
interest: '',
isOpen: false
isOpen: false,
moderator: '',
}
function Home() {
......@@ -28,6 +31,7 @@ function Home() {
const [singleChat, setSingleChat] = useState('')
const [roomName, setRoomName] = useState('')
const [success, setSuccess] = useState(false)
const handleClose = () => setShow(false);
const handleShow = () => setShow(true);
......@@ -36,6 +40,10 @@ function Home() {
const handleClose2 = () => setShow2(false);
const handleShow2 = () => setShow2(true);
const moderator = sessionStorage.getItem('userId');
const nanoid = customAlphabet('1234567890abcdef', 10)
const roomId = nanoid()
useEffect(() => {
const isRoom = Object.values(room).every(el => Boolean(el))
isRoom ? setDisabled(false) : setDisabled(true)
......@@ -43,23 +51,31 @@ function Home() {
function handleChange(event) {
const { name, value } = event.target
setRoom({ ...room, [name]: value })
console.log(room)
setRoom({ ...room, [name]: value, moderator, roomId })
//console.log(room)
}
console.log(room)
console.log(room.roomId)
async function handleSubmit(event) {
event.preventDefault()
try {
setError('')
await axios.post('/room/makeRoom', room)
setRoom(INIT_ROOM)
} catch (error){
// await axios.patch('/user/signup', { joinroom: `${room.roomId}`})
// await axios.post(`/user/${moderator}`, room.roomId)
setSuccess(true)
// setRoom(INIT_ROOM)
setShow(false)
} catch (error) {
catchErrors(error, setError)
}
}
//SOCKET 관련 시작
function enterChatroom(rName) { //방 입장하기
socket.emit('joinRoom', rName)
console.log(`joinRoom : ${rName} 입장`)
......@@ -80,7 +96,12 @@ function Home() {
})
}, [singleChat])
// console.log(room.roomId)
if (success) {
// console.log(room.roomId)
alert(`방암호는 ${room.roomId}입니다`)
// return <Redirect to='/home' />
}
return (
<>
......@@ -89,15 +110,15 @@ function Home() {
<Col className="list" md={5}>
<Tabs defaultActiveKey="closed" id="uncontrolled-tab-example">
<Tab eventKey="closed" title="내 채팅" onClick={handleChato} >
<ClosedList enterChatroom={enterChatroom} setRoomName={setRoomName}/>
<ClosedList enterChatroom={enterChatroom} setRoomName={setRoomName} />
</Tab>
<Tab eventKey="open" title="공개방" >
<OpenList enterChatroom={enterChatroom} setRoomName={setRoomName}/>
<OpenList enterChatroom={enterChatroom} setRoomName={setRoomName} />
</Tab>
</Tabs>
</Col>
<Col style={{ padding: "0" }}>
{chat ? <Chat handleChatc={handleChatc} sendMsg={sendMsg} singleChat={singleChat} setSingleChat={setSingleChat} roomName={roomName}/> : null}
{chat ? <Chat handleChatc={handleChatc} sendMsg={sendMsg} singleChat={singleChat} setSingleChat={setSingleChat} roomName={roomName} /> : null}
<div style={{ position: "fixed", bottom: "20px", right: "30px" }}>
<Button variant="primary" onClick={handleShow} size="lg" block>
......@@ -135,7 +156,6 @@ function Home() {
<option>언어</option>
<option>취미</option>
</Form.Control>
{/* <Form.Control type="text" /> */}
</Col>
</Form.Group>
<Form.Group as={Row} controlId="chatIsOpen">
......@@ -167,19 +187,19 @@ function Home() {
<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>
{/* <Form onSubmit={handleSubmit2}> */}
<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>
......@@ -189,3 +209,4 @@ function Home() {
}
export default Home;
......@@ -4,6 +4,7 @@ import { Button, Form, Container, Navbar, Spinner, Alert } from 'react-bootstrap
import catchErrors from '../utils/catchErrors'
import { Link, Redirect } from 'react-router-dom'
import { handleLogin } from '../utils/auth'
import Menu from '../Components/Menu';
const INIT_USER = {
email: '',
......@@ -48,14 +49,13 @@ function LogIn() {
//success시 링크이동
if (success) {
console.log('success', success)
alert('로그인 되었습니다!')
return <Redirect to='/' />
}
return (
<>
<Navbar bg="dark" variant="dark">
<Navbar.Brand>YDK Messenger</Navbar.Brand>
</Navbar>
<Menu />
<Form onSubmit={handleSubmit} className='vh-100 flex-column align-items-center justify-content-center mt-2'>
<Container className="d-flex justify-content-center">
<div className="mt-5 p-5 shadow w-75">
......@@ -97,10 +97,6 @@ function LogIn() {
block>
{loading && <Spinner as='span' animation='border' size='sm' role='status' aria-hidden='true' />} {' '} 로그인
</Button>
<Link to="./signup">
<h6 type="button" className="text-right mt-2" style={{ cursor: 'pointer' }}>회원가입</h6>
</Link>
{error && <Alert variant='danger'>
{error}
</Alert>}
......
......@@ -25,7 +25,7 @@ function ProfilePage() {
const [hidden, setHidden] = useState(true)
async function getLoginedUser() { //email로 db에서 찾아오기 ㅇㅇㅇㅇㅇ
async function getLoginedUser() {
const userid = sessionStorage.getItem('userId')
const response = await axios.post(`/users/${userid}`, { '_id': userid })
setUser(response.data)
......
......@@ -3,6 +3,7 @@ import axios from 'axios'
import { Button, Form, Container, Alert, Navbar } from 'react-bootstrap';
import catchErrors from '../utils/catchErrors';
import { Redirect } from 'react-router-dom';
import Menu from '../Components/Menu';
const INIT_USER = {
username: '',
......@@ -12,11 +13,11 @@ const INIT_USER = {
}
function SingUp() {
const [validated, setValidated] = useState(false);
//const [validated, setValidated] = useState(false);
const [user, setUser] = useState(INIT_USER)
const [error, setError] = useState('')
const [disabled, setDisabled] = useState(true)
const [success, setSucces] = useState(false)
const [success, setSuccess] = useState(false)
useEffect(() => {
const isUser = Object.values(user).every(el => Boolean(el))
......@@ -32,19 +33,19 @@ function SingUp() {
event.preventDefault();
//빈문자열 입력 시 오류 문자 출력
const form = event.currentTarget;
if (form.checkValidity() === false) {
event.preventDefault();
event.stopPropagation();
}
setValidated(true);
//const form = event.currentTarget;
//if (form.checkValidity() === false) {
// event.preventDefault();
// event.stopPropagation();
// //event.stopPropagation() : 이벤트 캡쳐링과 버블링에 있어 현재 이벤트 이후의 전파를 막습니다.
//}
//setValidated(true);
// console.log(user)
try {
setError('')
await axios.post('/users/signup', user)
alert("회원가입이 완료되었습니다!")
setSucces(true)
setSuccess(true)
} catch (error) {
catchErrors(error, setError)
}
......@@ -52,17 +53,16 @@ function SingUp() {
if (success) {
console.log('success', success)
alert('회원가입이 완료되었습니다!')
return <Redirect to='/login' />
}
return (
<>
<Navbar bg="dark" variant="dark">
<Navbar.Brand>YDK Messenger</Navbar.Brand>
</Navbar>
<Menu />
<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">
<div className="mt-5 p-5 shadow w-75">
......
......@@ -4,7 +4,6 @@ import 'bootstrap/dist/css/bootstrap.min.css';
import './index.css';
import { BrowserRouter as Router, Route, Redirect, Switch } from 'react-router-dom';
import reportWebVitals from './reportWebVitals';
import SignUpPage from './Pages/SignUpPage';
import ProfilePage from './Pages/ProfilePage';
import 'bootstrap/dist/css/bootstrap.min.css';
......@@ -12,7 +11,6 @@ import LogInPage from './Pages/LogInPage';
import HomePage from './Pages/HomePage'
import PrivateRoute from './Components/PrivateRoute';
ReactDOM.render(
<Router>
<Switch>
......
......@@ -6,10 +6,11 @@ export function handleLogin(data) {
sessionStorage.setItem('name', data.user.username)
}
export async function handleLogout() {
sessionStorage.clear();
await axios.get('/auth/logout')
//login페이지로 이동
window.location.href='/login'
}
export function isAuthenticated() {
......
......@@ -5,7 +5,7 @@
"main": "index.js",
"type": "module",
"scripts": {
"dev": "nodemon server/server.js",
"dev": "nodemon --ignore client server/server.js",
"test": "echo \"Error: no test specified\" && exit 1"
},
"repository": {
......@@ -20,6 +20,7 @@
"bcrypt": "^5.0.0",
"bcryptjs": "^2.4.3",
"body-parser": "^1.19.0",
"cors": "^2.8.5",
"express": "^4.17.1",
"jsonwebtoken": "^8.5.1",
"mongoose": "^5.11.9",
......
......@@ -16,7 +16,7 @@ const login = async (req, res) => {
const passwordMatch = await bcrypt.compare(password, user.password)
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 : 노출되면 안됨. 문자열
//expiresIn: '7d' -> 만기날짜 : 만든 7일후 만기
......
import Room from "../models/Room.js"
import { customAlphabet } from 'nanoid'
// import { customAlphabet } from 'nanoid'
import isLength from 'validator/lib/isLength.js'
const nanoid = customAlphabet('1234567890abcdef', 10)
// const nanoid = customAlphabet('1234567890abcdef', 10)
const makeRoom = async (req, res) => {
console.log(req.body)
const { roomName, interest, isOpen } = req.body;
console.log(roomName, interest, isOpen)
const { roomName, interest, isOpen, moderator, roomId } = req.body;
console.log(roomName, interest, isOpen, moderator, roomId)
const roomId = nanoid()
const room = await Room.findOne({ roomId })
while (room) {
roomId = nanoid()
room = await Room.findOne({ roomId })
}
// const roomId = nanoid()
// const room = await Room.findOne({ roomId })
// while (room) {
// roomId = nanoid()
// room = await Room.findOne({ roomId })
// }
try {
if (!isLength(roomName, { min: 3, max: 20 })) {
......@@ -23,10 +23,11 @@ const makeRoom = async (req, res) => {
return res.status(422).send('분야를 반드시 선택하여야 합니다.')
}
const newRoom = await new Room({
roomId,
roomName,
interest,
isOpen
isOpen,
moderator,
roomId,
}).save()
console.log(newRoom)
res.json(newRoom)
......@@ -46,4 +47,4 @@ const getClosedList = async (req, res) => {
}
}
export default { makeRoom, getClosedList }
\ No newline at end of file
export default { makeRoom, getClosedList }
......@@ -32,7 +32,7 @@ const signup = async (req, res) => {
email,
password: hash,
}).save()
console.log(newUser)
res.json(newUser)
......@@ -43,7 +43,6 @@ const signup = async (req, res) => {
}
}
const logineduser = async (req, res) => {
try {
let user = await User.findOne(req.body).select('username email nickname').exec()
......@@ -52,6 +51,7 @@ const logineduser = async (req, res) => {
alert('올바르지 못한 접근입니다.')
}
}
const changenick = async (req, res) => {
try {
const newnick = req.body.nickname
......@@ -61,6 +61,21 @@ const changenick = async (req, res) => {
}
}
const loginNavbar = async (req, res) => {
try {
let user = await User.findOne(req.body).select('username').exec()
return res.json(user)
} catch (error) {
alert('올바르지 못한 접근입니다.')
}
}
const saveroom = async (req, res) => {
const roomId = room.roomId
if (!isLength(roomId, { min: 11 })) {
return res.status(422).send('방아이디 저장에 오류가 발생하였습니다.')
}
}
export default { signup, logineduser, changenick }
// {} : 객체로 return함
\ No newline at end of file
export default { signup, logineduser, changenick, loginNavbar, saveroom }
// {} : 객체로 return 함
......@@ -18,4 +18,4 @@ const ChatSchema = new mongoose.Schema({
timestamps: true
})
export default mongoose.models.ChatSchema || mongoose.model('Chat', ChatSchema)
\ No newline at end of file
export default mongoose.models.Chat || mongoose.model('Chat', ChatSchema)
\ No newline at end of file
......@@ -3,11 +3,6 @@ import mongoose from 'mongoose'
const {String} = mongoose.Schema.Types
const RoomSchema = new mongoose.Schema({
roomId: {
type: String,
// default:() => nanoid(),
unique: true
},
roomName: {
type: String,
required: true,
......@@ -18,9 +13,20 @@ const RoomSchema = new mongoose.Schema({
select: false
},
isOpen: {
type: Boolean,
type: String,
required: true,
}
default: 'user',
enum: ['true', 'false']
},
moderator: {
type: String,
required: true,
},
roomId: {
type: String,
// default:() => nanoid(),
unique: true
},
}, {
timestamps: true
})
......
......@@ -3,6 +3,7 @@
import mongoose from 'mongoose'
const { String } = mongoose.Schema.Types
// const { Array } = mongoose.Schema.Types
//원래 java의 string이 아니라 mongoose의 string을 쓰기 위해 불러옴.
//object의 id를 쓸때에도 추가시켜줘야됨.
......
......@@ -10,6 +10,23 @@ router.route('/users/signup')
router.route(`/users/:userId`)
.post(userCtrl.logineduser)
.put(userCtrl.changenick)
.get(userCtrl.loginNavbar)
router.route(`users/:name`)
.post(userCtrl.saveroom)
// router.param('userId', userCtrl.userById)
// router.route('/api/users/signup/:userId') //로그인한 사람의 정보만 가져오도록
// .get
// /api/users/signup로 들어오는 것을 post (method) 를 통해 useCtrl.signup 이것이 처리함
//browser에서 주소창에 치고 들어가면 get (method) 을 타고 들어간것임
//post를 띄우고 싶으면 앱에서 ARC실행해서 post를 실행하게 만들면됨.
//객체에 접근할때는 .을 찍고 접근함/ ex) .hello
//express middleware : (req, res) => {}
//node(req(client의 정보), res)를 넘겨줌.
export default router
\ No newline at end of file
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