Commit 289b3608 authored by JeongYeonwoo's avatar JeongYeonwoo
Browse files

parent 99a6f465
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
"@testing-library/jest-dom": "^5.11.4", "@testing-library/jest-dom": "^5.11.4",
"@testing-library/react": "^11.1.0", "@testing-library/react": "^11.1.0",
"@testing-library/user-event": "^12.1.10", "@testing-library/user-event": "^12.1.10",
"axios": "^0.21.1",
"bootstrap": "^4.5.3", "bootstrap": "^4.5.3",
"react": "^17.0.1", "react": "^17.0.1",
"react-bootstrap": "^1.4.0", "react-bootstrap": "^1.4.0",
......
...@@ -3,53 +3,95 @@ import ReactDOM from 'react-dom'; ...@@ -3,53 +3,95 @@ import ReactDOM from 'react-dom';
import Menu from '../Components/Menu'; import Menu from '../Components/Menu';
import { Image, Button, Container, Form, FormControl, Navbar, Nav } from 'react-bootstrap'; import { Image, Button, Container, Form, FormControl, Navbar, Nav } from 'react-bootstrap';
import { BrowserRouter as Router, Route, Redirect, Switch, Link } from 'react-router-dom'; import { BrowserRouter as Router, Route, Redirect, Switch, Link } from 'react-router-dom';
import axios from 'axios'
import userdefault from './KakaoTalk_20201230_153151693.png' import userdefault from './KakaoTalk_20201230_153151693.png'
//localStorage에 아이디? 가있는걸로 db에서 그 사람꺼 찾은(findOne 이런걸로) 다음에 닉네임도 불러오고 여기서 수정할 수 있는 기능을 만들자!
////////////////////////////////////////////////////////////////////////////////
// async function sending() {
// const info = await fetch(`/api/users/signup`, {
// method: "POST",
// headers: {
// "Content-type": 'application/json'
// },
// body: JSON.stringify({
// name: userName,
// email: userEmail,
// password: "123123123",
// nickname: userNickname
// })
// })
// const data = await info.json()
// console.log(data)
// }
////////////////////////////////////////////////////////////////////////////////
const INIT_USER = {
name: '',
email: '',
nickname: ''
}
const userName = "정연우"; function ProfilePage() {
const userEmail = "dusdn8455@korea.ac.kr"; const [user, setUser] = useState(INIT_USER)
let userNickname = "가나다라마바사";
const [defaultImg, setDefaultImg] = useState(true)
const [hidden, setHidden] = useState(true)
function setlocal() {
localStorage.setItem('_id', '5ff77d56da609732c001b392')
}
async function loginedinfo() {
const userid = localStorage.getItem('_id')
const response = await axios.post(`/api/users/${userid}`, user)
setUser(response.data[1])
console.log(user)
}
function editNickname1() { //수정버튼 누르면 재입력하게 함
const html = (
<Form>
<div className="d-flex justify-content-center">
별명 : <Form.Control className="" id="editBlock" style={{ width: "40%" }} size="sm" type="id" defaultValue={userNickname} />
<Button className="ml-3" variant="outline-primary" size="sm" onClick={editNickname2}>수정</Button>
</div>
{/*
<div>
<Image src={pic} width="300px" roundedCircle />
</div> */} async function getInfo() { //db에서 로그인 정보 가져옴
</Form> const response = await axios.get('/api/users')
) console.log(response.data)
ReactDOM.render(html, document.getElementById("nickname")) setUser(response.data[1])
} console.log(user)
function editNickname2() { //수정버튼 누르면 다시 원래대로 돌아가게 함 }
changeNickname() async function makeLogin() { //로그인 상태로 만들어줌
const html = ( const info = await axios.get('/api/users')
<div> console.log('info', info.data)
별명 : {userNickname} setUser(info.data[1])
<Button className="ml-3" variant="outline-primary" size="sm" onClick={editNickname1}>수정</Button>
</div> await axios.post(`/api/users/`, user)
) localStorage.setItem('loginStatus', 'true')
ReactDOM.render(html, document.getElementById("nickname")) localStorage.setItem('_id', user._id)
} console.log(user)
function changeNickname() { //수정버튼 누르면 닉네임 변경해줌 }
let editedNickname = document.getElementById("editBlock")
userNickname = editedNickname.value
}
function ProfilePage() { async function authinfo() { //id로 db에서 찾아오기
const [tohome, setTohome] = useState(false) const userid = { '_id': localStorage.getItem('_id') }
const [defaultImg, setDefaultImg] = useState(true) const response = await axios.post(`/api/users/${userid._id}`, userid)
console.log(response.data)
setUser(response.data)
}
//@@그다음에 찾아온걸로 다시 띄우기
//@@닉네임 수정하기
function handleEditnick() {
if (hidden) {
setHidden(false)
} else {
setUser({ ...user, 'nickname': document.getElementById("inputNick").value })
setHidden(true)
}
}
async function handleNicksave(){
const userid = { '_id': localStorage.getItem('_id') }
await axios.put(`/api/users/${userid._id}`, user)
function goHome() {
return (setTohome(true))
} }
function setThumbnail(event) { //불러온 사진 <div id='image_container'>에 띄우기 function setThumbnail(event) { //불러온 사진 <div id='image_container'>에 띄우기
...@@ -59,43 +101,49 @@ function ProfilePage() { ...@@ -59,43 +101,49 @@ function ProfilePage() {
let img = document.createElement("img"); let img = document.createElement("img");
img.setAttribute("src", event.target.result); img.setAttribute("src", event.target.result);
img.setAttribute("id", "profileImg") img.setAttribute("id", "profileImg")
img.setAttribute("style",'height:300px; width:300px') img.setAttribute("style", 'height:300px; width:300px')
img.setAttribute("class","mb-3") img.setAttribute("class", "mb-3")
// img.setAttribute("class","d-flex justify-content-center mb-3") // img.setAttribute("class","d-flex justify-content-center mb-3")
document.querySelector("div#image_container").appendChild(img); document.querySelector("div#image_container").appendChild(img);
}; };
reader.readAsDataURL(event.target.files[0]); reader.readAsDataURL(event.target.files[0]);
if (defaultImg) { //첫 이미지 업로드(default이미지 지우고 유저가 올린걸로 업로드) if (defaultImg) { //첫 이미지 업로드(default이미지 지우고 유저가 올린걸로 업로드)
let del = document.getElementById("defaultImg") let del = document.getElementById("defaultImg")
del.remove() del.remove()
setDefaultImg(false) setDefaultImg(false)
} }
else { //기존에 올렸던 사진 지우고 재선택한 사진 업로드 else { //기존에 올렸던 사진 지우고 재선택한 사진 업로드
let del2= document.getElementById('profileImg') let del2 = document.getElementById('profileImg')
del2.remove() del2.remove()
reader.onload = function (event) { reader.onload = function (event) {
let img = document.createElement("img"); let img = document.createElement("img");
img.setAttribute("src", event.target.result); img.setAttribute("src", event.target.result);
img.setAttribute("id", "profileImg") img.setAttribute("id", "profileImg")
img.setAttribute("style",'height:300px; width:300px') img.setAttribute("style", 'height:300px; width:300px')
document.querySelector("div#image_container").appendChild(img); document.querySelector("div#image_container").appendChild(img);
}; };
} }
} }
return ( return (
<div> <div>
<Menu /> <Menu />
<Button onClick={setlocal}>로컬에 추가</Button>
<Button onClick={loginedinfo}>로그인된 정보 불러오기</Button>
<Button onClick={getInfo}>불러오기</Button>
<Button onClick={makeLogin}>로그인 상태로 만들기</Button>
<Button onClick={authinfo}>로그인 유저 불러오기</Button>
{/* <Button onClick={sending}>보내기</Button> */}
{tohome ? <Redirect to='/homepage' /> : ''}
<Container className="d-flex justify-content-center"> <Container className="d-flex justify-content-center">
<div className="mt-5 shadow w-75"> <div className="mt-5 shadow w-75">
<h1 className="text-center mt-4 ml-5 mr-5 mb-3">Profile Page</h1> <h1 className="text-center mt-4 ml-5 mr-5 mb-3">Profile Page</h1>
<h4 className="text-center mb-5">{userName} 환영합니다 !</h4> <h4 className="text-center mb-5">{user.name} 환영합니다 !</h4>
<div className="d-flex justify-content-center mb-3" id="defaultImg"> <div className="d-flex justify-content-center mb-3" id="defaultImg">
<Image src={userdefault} width="300px" roundedCircle /> <Image src={userdefault} width="300px" roundedCircle />
...@@ -110,16 +158,26 @@ function ProfilePage() { ...@@ -110,16 +158,26 @@ function ProfilePage() {
</div> </div>
<div className="text-center"> <div className="text-center">
<div className="m-3">이름 : {userName}</div> <div className="m-3" style={{ fontWeight: "bold", fontSize: "x-large" }}>이름 : {user.name}</div>
<div className="m-3" id="nickname">별명 : {userNickname} <div className="m-3" id="nickname">
<Button className="ml-3" variant="outline-primary" size="sm" onClick={editNickname1}>수정</Button> <Form className="d-flex justify-content-center" style={{ fontWeight: "bold", fontSize: "x-large" }}>
별명 :
<div id="mainNick" hidden={!hidden}>
{user.nickname}
</div>
<Form.Control id="inputNick" type="name" defaultValue={user.nickname} style={{ width: "40%" }} size="sm" hidden={hidden} />
<Button className="ml-3" variant="outline-primary" size="sm" onClick={handleEditnick}>수정</Button>
</Form>
</div> </div>
<div className="m-3">이메일 : {userEmail}</div> <div className="m-3" style={{ fontWeight: "bold", fontSize: "x-large" }}>이메일 : {user.email}</div>
</div> </div>
<div className="text-center m-5"> <div className="text-center m-5">
<span> <span>
<Button variant="outline-success" size="sm" className="mr-4">저장</Button> <Button variant="outline-success" size="sm" className="mr-4" onClick={handleNicksave}>저장</Button>
<Button variant="outline-success" size="sm" className="ml-4" onClick={goHome}> 화면으로</Button> <Link to='/'>
<Button variant="outline-success" size="sm" className="ml-4" > 화면으로</Button>
</Link>
</span> </span>
</div> </div>
</div> </div>
......
...@@ -5,7 +5,9 @@ ...@@ -5,7 +5,9 @@
"main": "index.js", "main": "index.js",
"type": "module", "type": "module",
"dependencies": { "dependencies": {
"bcryptjs": "^2.4.3",
"express": "^4.17.1", "express": "^4.17.1",
"jsonwebtoken": "^8.5.1",
"mongoose": "^5.11.9", "mongoose": "^5.11.9",
"nodemon": "^2.0.6", "nodemon": "^2.0.6",
"validator": "^13.5.2" "validator": "^13.5.2"
...@@ -13,7 +15,7 @@ ...@@ -13,7 +15,7 @@
"devDependencies": {}, "devDependencies": {},
"scripts": { "scripts": {
"test": "echo \"Error: no test specified\" && exit 1", "test": "echo \"Error: no test specified\" && exit 1",
"dev":"nodemon server/server.js" "dev": "nodemon server/server.js"
}, },
"repository": { "repository": {
"type": "git", "type": "git",
......
...@@ -2,7 +2,8 @@ const config = { ...@@ -2,7 +2,8 @@ const config = {
env: process.env.NODE_ENV || 'development', env: process.env.NODE_ENV || 'development',
port: process.env.PORT || 3030, port: process.env.PORT || 3030,
jwtSecret: process.env.JWT_SECRET || 'My_Secret_Key', jwtSecret: process.env.JWT_SECRET || 'My_Secret_Key',
mongoDbUri: process.env.MONGODB_URI || 'mongodb://localhost/messenger' mongoDbUri: process.env.MONGODB_URI || 'mongodb://localhost/messenger',
cookieMaxAge: 60 * 60 * 24 * 7 * 1000,
} }
export default config export default config
\ No newline at end of file
import User from "../models/user.js"
import bcrypt from "bcryptjs";
import jwt from 'jsonwebtoken'
import config from "../config.js"
const mklogin = async (req, res) => {
const { email } = req.body
console.log(email)
try {
const user = await User.findOne({ email }).select('+name')
console.log(user.name, user.nickname, user.email)
const token = jwt.sign({ userId: user._id }, config.jwtSecret, {
expiresIn: '7d'
})
res.cookie('token', token, {
maxAge: config.cookieMaxAge,
httpOnly: true,
secure: config.env === 'production'
})
res.send('login successful')
}
catch (error){
console.log(error)
res.send(500).send('로그인에러')
}
}
const getinfo = (req, res) => {
// 1) 로그인 된 사용자 정보를 가져오기
// 일단 1명으로 해놓고 설정
// let users = await User.find().select('name nickname email password').exec()
// return res.json(users)
res.send('여기가 프로필이다.')
//try catch로 오류잡는거 추가해야함
}
export default { mklogin , getinfo }
\ No newline at end of file
import User from "../models/User.js" import User from "../models/User.js"
import isLength from 'validator/lib/isLength.js' import isLength from 'validator/lib/isLength.js'
import isEmail from 'validator/lib/isEmail.js' import isEmail from 'validator/lib/isEmail.js'
import bcrypt from "bcryptjs";
import jwt from 'jsonwebtoken'
import config from "../config.js"
//꼭 js붙여주기!! //꼭 js붙여주기!!
//isEmail //isEmail
//sign validation해야됨 //sign validation해야됨
const signup = async (req, res) => { const signup = async (req, res) => {
const { name, nickname, email, password } = req.body // const { name, nickname, email, password } = req.body
//req.body를 구조분해하여 각각 보이게함 -> 모든정보들이 한줄에 보임 // //req.body를 구조분해하여 각각 보이게함 -> 모든정보들이 한줄에 보임
console.log(name, nickname, email, password) // console.log(name, nickname, email, password)
// try {
// // if (!isLength(name, { min: 3, max: 10 })) {
// // //이범위를 벗어나면 error발생
// // return res.status(422).send('Name must be 3-10 characters')
// // //422 : 형식이 잘못되었다는 error발생
// // }
// // else if (!isLength(nickname, { min: 3, max: 10 })) {
// // return res.status(422).send('Nickname must be 3-10 characters')
// // }
// // else if (!isEmail(email, {
// // allow_display_name: true,
// // require_display_name: true,
// // allow_utf8_local_part: false,
// // })) {
// // return res.status(422).send('Email does not fit the format')
// // }
// // else if (!isLength(password, { min: 6, max: 25 })) {
// // return res.status(422).send('Nickname must be 6-25 characters')
// // }
// const hash = await bcrypt.hash(password, 10)
// const newUser = await new User({
// name,
// nickname,
// email,
// password : hash,
// //required를 하였기 때문에 이중 하나라도 없으면 에러 발생
// }).save()
// //save시 user schema형식에 맞는지 확인후 틀리면 error발생 맞으면 mongooDb로 들어감
// //save(promise)붙일 시 fuction 앞에 await 붙여주기 + async 함수 앞에 붙여주기
// console.log(newUser)
// res.json(newUser)
// } catch (error) {
// //알수없는 모든 에러발생시 처리
// console.log(error)
// res.status(500).send('User signup error')
// }
// //newUSer (객체)를 json형식으로 바꿔서 객체열로 보냄
// //res : 응답하는 객체
// //응답안할 시 browser에서 빙빙돌다 에러 발생 -> 꼭 붙여줘야됨!
// //res는 한번만 실행. 두번하면 에러 발생
const { email } = req.body
console.log(email, 'ddd')
try { try {
const user = await User.findOne({ email }).select('+name')
console.log(user.name, user.nickname, user.email)
if (!isLength(name, { min: 3, max: 10 })) { const token = jwt.sign({ userId: user._id }, config.jwtSecret, {
//이범위를 벗어나면 error발생 expiresIn: '7d'
return res.status(422).send('Name must be 3-10 characters') })
//422 : 형식이 잘못되었다는 error발생 res.cookie('token', token, {
} else if (!isLength(nickname, { min: 3, max: 10 })) { maxAge: config.cookieMaxAge,
return res.status(422).send('Nickname must be 3-10 characters') httpOnly: true,
} else if (!isEmail(email, { secure: config.env === 'production'
allow_display_name: true, })
require_display_name: true, res.send('login successful')
allow_utf8_local_part: false,
})) {
return res.status(422).send('Email does not fit the format')
} else if (!isLength(password, { min: 6, max: 25 })) {
return res.status(422).send('Nickname must be 6-25 characters')
} }
catch (error) {
const newUser = await new User({
name,
nickname,
email,
password,
//required를 하였기 때문에 이중 하나라도 없으면 에러 발생
}).save()
//save시 user schema형식에 맞는지 확인후 틀리면 error발생 맞으면 mongooDb로 들어감
//save(promise)붙일 시 fuction 앞에 await 붙여주기 + async 함수 앞에 붙여주기
console.log(newUser)
res.json(newUser)
} catch (error) {
//알수없는 모든 에러발생시 처리
console.log(error) console.log(error)
res.status(500).send('User signup error') res.send(500).send('로그인에러')
} }
//newUSer (객체)를 json형식으로 바꿔서 객체열로 보냄
//res : 응답하는 객체
//응답안할 시 browser에서 빙빙돌다 에러 발생 -> 꼭 붙여줘야됨!
//res는 한번만 실행. 두번하면 에러 발생
} }
const hello = (req, res) => { // const list=async(req, res)=>{
res.send('Hello from users controller') // let users = await User.find().select('name nickname email password').exec()
// return res.json(users)
// }
const hello = async (req, res) => {
let users = await User.find().select('name nickname email _id').exec()
return res.json(users)
}
const authuser = async (req, res) => {
let user = await User.findOne( req.body ).select('name email nickname').exec()
console.log(user)
return res.json(user)
} }
export default { signup, hello } const chnick = async (req, res) =>{
let user = {"dusdn":"ddd"}
console.log("변경~")
return res.json(user)
}
export default { signup, hello, authuser, chnick }
// {} : 객체로 return함 // {} : 객체로 return함
\ No newline at end of file
import express from 'express'
import profileCtrl from "../controllers/profile.controller.js";
const router = express.Router()
router.route('/api/profile')
.post(profileCtrl.mklogin)
.get(profileCtrl.getinfo)
export default router
\ No newline at end of file
...@@ -4,10 +4,21 @@ import userCtrl from '../controllers/user.controller.js' ...@@ -4,10 +4,21 @@ import userCtrl from '../controllers/user.controller.js'
const router = express.Router() const router = express.Router()
//router의 역할 : './주소'부분을 처리하는 역할함. //router의 역할 : './주소'부분을 처리하는 역할함.
router.route('/api/users/signup') router.route('/api/users/')
.post(userCtrl.signup) .post(userCtrl.signup)
.get(userCtrl.hello) .get(userCtrl.hello)
router.route(`/api/users/:userId`)
.post(userCtrl.authuser)
.put(userCtrl.chnick)
// router.route('/api/users/signup/:userId') //로그인한 사람의 정보만 가져오도록
// .get
// /api/users/signup로 들어오는 것을 post (method) 를 통해 useCtrl.signup 이것이 처리함 // /api/users/signup로 들어오는 것을 post (method) 를 통해 useCtrl.signup 이것이 처리함
//browser에서 주소창에 치고 들어가면 get (method) 을 타고 들어간것임 //browser에서 주소창에 치고 들어가면 get (method) 을 타고 들어간것임
//post를 띄우고 싶으면 앱에서 ARC실행해서 post를 실행하게 만들면됨. //post를 띄우고 싶으면 앱에서 ARC실행해서 post를 실행하게 만들면됨.
......
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