Commit ea3c348e authored by 한규민's avatar 한규민
Browse files

회원가입디버그

parent 01fc5d96
...@@ -31,11 +31,15 @@ const confirmMbnum = async (id,token) => { ...@@ -31,11 +31,15 @@ const confirmMbnum = async (id,token) => {
return data return data
} }
const getNickName = async(id) =>{ const getNickName = async (id) =>{
const url = `${baseUrl}/api/auth/${id}` const url = `${baseUrl}/api/auth/nickname/${id}`
console.log("url : ", url); const { data } = await axios.get(url)
const { nickName } = await axios.get(url) return data
return nickName }
const modifyUser = async (user) => {
const url = `${baseUrl}/api/auth/modify`
await axios.post(url, user)
} }
const authApi = { const authApi = {
...@@ -45,5 +49,6 @@ const authApi = { ...@@ -45,5 +49,6 @@ const authApi = {
compareId, compareId,
confirmMbnum, confirmMbnum,
getNickName, getNickName,
modifyUser,
}; };
export default authApi export default authApi
\ No newline at end of file
...@@ -2,34 +2,195 @@ import styles from "./my-info.module.scss"; ...@@ -2,34 +2,195 @@ import styles from "./my-info.module.scss";
import { useAuth } from "../../context/auth_context"; import { useAuth } from "../../context/auth_context";
import { useState, useEffect } from "react"; import { useState, useEffect } from "react";
import authApi from "../../apis/auth.api"; import authApi from "../../apis/auth.api";
import catchErrors from "../../utils/catchErrors.js";
const MyInfo = () => { const MyInfo = () => {
const { user } = useAuth(); const { user } = useAuth();
const [userNickName, setUserNickName] = useState(user.nickname); const [userNickName, setUserNickName] = useState(user.nickName);
const getNickName = async (id) => { const getNickName = async (id) => {
console.log(id); console.log(id);
const nickname = await authApi.getNickName(id); const nickname = await authApi.getNickName(id);
console.log(nickname); console.log(nickname);
return nickname setUserNickName(nickname);
} }
const [userRe, setUserRe] = useState({
userEmail: "",
userNickName: "",
userMbnum: "",
userPassword: "",
userRePassword: ""
})
const [loading, setLoading] = useState(false);
const [success, setSuccess] = useState(false);
//각 타입별 error 유무 state
const [error, setError] = useState("");
const [errorMsg, setErrorMsg] = useState({
errorEmail: false,
errorNickName: false,
errorMbnum: false,
errorPassword: false,
errorRePassword: false
})
useEffect(() => { useEffect(() => {
let name = getNickName(user.id); getNickName(user.id);
setUserNickName(name);
}, []) }, [])
return (
//입력할때마다 state에 저장
const handleUserOnChange = (e) => {
setUserRe({
...userRe,
[e.target.name]: e.target.value
})
if (e.target.name === "userMbnum") {
setUserRe({
...userRe,
[e.target.name]: String(e.target.value)
})
}
}
//비교하여 error메세지 반환
const vaildationData = (text, compareValue, error) => {
if (text !== compareValue) {
setErrorMsg(errorMsg => ({ ...errorMsg, [error]: true }));
} else {
setErrorMsg(errorMsg => ({ ...errorMsg, [error]: false }));
}
}
const vaildationIdPw = (text, minValue, error) => {
if ((text < minValue)) {
setErrorMsg(errorMsg => ({ ...errorMsg, [error]: true }));
} else {
setErrorMsg(errorMsg => ({ ...errorMsg, [error]: false }));
}
}
//유효성 검사
const validation = () => {
//별명 유효성 검사
vaildationData((userRe.userNickName.length === 0), false, "errorNickName");
// 휴대폰 유효성 검사
vaildationData(userRe.userMbnum.length, 11, "errorMbnum");
// 비밀번호 유효성 검사
vaildationIdPw(userRe.userPassword.length, 8, "errorPassword");
// 비밀번호 확인 유효성 검사
vaildationIdPw(userRe.userPassword.length, 8, "errorRePassword");
// 최종 유효성 검사
if ((Object.values(errorMsg).some((element) => (element)) === false)) {
} else {
throw new Error("유효하지 않은 데이터입니다.");
}
}
if (success) {
alert("회원정보 수정이 완료되었습니다.")
}
const handleOnSummit = async (e) => {
e.preventDefault();
try {
setError(() => (""));
//처리가 될때까지 버튼(가입하기)이 안눌리게 지정
setLoading(() => (true));
//유효성 검사
validation();
const userData = userRe;
console.log(userData);
//서버로 전송
await authApi.modifyUser(userData);
alert("회원정보 수정 완료");
setSuccess(true);
} catch (error) {
//에러전송
catchErrors(error, setError);
} finally {
setLoading(false);
}
}
return (<>
<div className="d-flex flex-column"> <div className="d-flex flex-column">
<span className={styles.title}>마이페이지</span> <span className={styles.title}>마이페이지</span>
<div className="d-flex flex mh-100"> <div className="d-flex flex mh-100">
<img src="/images/cat.jpg" className="img-thumbnail rounded-circle" /> <img src="/images/cat.jpg" className="img-thumbnail rounded-circle" />
<div> <div className="d-flex flex-column">
<span>{`${userNickName}`} 반갑습니다!</span> <span className={`${styles.userName}`}>{`${userNickName}`} 반갑습니다!</span>
<button>수정</button> <button type="button" class="btn btn-warning" data-bs-toggle="modal" data-bs-target="#exampleModal">회원정보 수정</button>
</div>
</div>
</div>
{/* 회원정보 수정 모달창 */}
<div className="modal fade" id="exampleModal" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div className="modal-dialog modal-dialog-scrollable">
<div className="modal-content">
<div class="modal-header">
<h5 className="modal-title" id="exampleModalLabel">회원정보 수정</h5>
<button type="button" className="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<form className={`d-flex col-md-6 col-12 justify-content-center d-flex flex-column`} onSubmit={handleOnSummit}>
<div className="modal-body">
<div className={`d-flex col-md-6 col-12 justify-content-center d-flex flex-column`}>
<div className="d-flex flex-column">
<div className={styles.inputContent}>
<label className={styles.signupLabel}>이메일</label>
<input className={`${styles.input} ${styles.inputSize}`} type="email" name="userEmail" placeholder="이메일을 입력해주세요" onChange={handleUserOnChange} maxlength="20" required />
</div>
{errorMsg.errorEmail && <p className={styles.passwordConfirmError}>이메일을 입력해주세요</p>}
</div>
<div className="d-flex flex-column">
<div className={styles.inputContent}>
<label className={styles.signupLabel}>별명</label>
<input className={`${styles.input} ${styles.inputSize}`} type="text" name="userNickName" placeholder="10자리 이내" onChange={handleUserOnChange} maxLength="10" required />
</div>
{errorMsg.errorNickName && <p className={styles.passwordConfirmError}>10 이내로 입력해주세요.</p>}
</div>
<div className="d-flex flex-column">
<div className={styles.inputContent}>
<label className={styles.signupLabel}>휴대폰 번호</label>
<div className="d-flex col-md-auto">
<input className={`${styles.input}`} type="number" name="userMbnum" placeholder="-없이 11자리 입력" onChange={handleUserOnChange} min="" max="99999999999" required />
</div>
</div>
{errorMsg.errorMbnum && <p className={styles.passwordConfirmError}>-없이 숫자 11자리를 입력해주세요.</p>}
</div>
<div className="d-flex flex-column">
<div className={`${styles.inputContent}`}>
<label className={styles.signupLabel}>기존 비밀번호</label>
<input className={`${styles.input} ${styles.inputSize}`} type="password" name="userPassword" placeholder="8~11자리 사이" onChange={handleUserOnChange} maxLength="11" required />
</div>
{errorMsg.errorPassword && <p className={styles.passwordConfirmError}>8~11자리 사이로 입력해주세요.</p>}
</div>
<div className="d-flex flex-column">
<div className={styles.inputContent}>
<label className={styles.signupLabel}>변경 비밀번호</label>
<input className={`${styles.input} ${styles.inputSize}`} type="password" name="userRePassword" placeholder="8~11자리 사이" onChange={handleUserOnChange} maxLength="11" required />
</div>
{errorMsg.errorRePassword && <p className={styles.passwordConfirmError}>비밀번호가 일치하지 않습니다.</p>}
</div>
</div>
<div className="modal-footer">
<button type="button" className="btn btn-secondary rounded my-3 py-2 fs-5" data-bs-dismiss="modal" disabled={loading}>닫기</button>
<button type="submit" className={`rounded my-3 py-2 fs-5 ${styles.butterYellowAndBtn} ${styles.btnHover}`} disabled={loading}>수정하기</button>
</div>
</div>
</form>
</div> </div>
</div> </div>
</div> </div>
</>
) )
} }
......
...@@ -5,3 +5,76 @@ ...@@ -5,3 +5,76 @@
font-size: 25px; font-size: 25px;
margin: 1rem 0; margin: 1rem 0;
} }
.userName{
color: white;
font-size: 1rem;
}
.contents{
display: flex;
width: 100%;
justify-content: spa;
align-items: center;
padding-top: 5px;
}
.signupLabel{
color: black;
padding-right: 8px;
text-align: left;
}
.inputContent{
display: flex;
justify-content: space-between;
align-items: center;
margin-top: 1rem;
}
.input {
margin: 0.5rem 0 0 0;
padding: 0.5rem 0 0.5rem 0;
border-radius: 3px;
text-align: center;
}
input[type=password]{
font-family: 'Courier New', Courier, monospace;
}
input::placeholder{
font-family: 'HangeulNuriB'
}
.inputSize{
width: 15.3rem;
}
input[type="number"]::-webkit-outer-spin-button,
input[type="number"]::-webkit-inner-spin-button {
-webkit-appearance: none;
}
.butterYellowAndBtn{
color: black;
background-color: #FEDC00;
border: 1px solid black;
text-align: center;
}
.btnHover:hover{
background-color: black;
color: #FEDC00;
transition: ease-out;
border: 1px solid #FEDC00 ;
text-align: center;
}
.passwordConfirmError{
margin-bottom: 0;
margin-top: 0.5rem;
text-align: end;
font-size: 13px;
color: #FEDC00;
}
\ No newline at end of file
...@@ -3,7 +3,6 @@ import { useState } from "react"; ...@@ -3,7 +3,6 @@ import { useState } from "react";
import authApi from "../../apis/auth.api.js"; import authApi from "../../apis/auth.api.js";
import { Redirect } from "react-router"; import { Redirect } from "react-router";
import catchErrors from "../../utils/catchErrors.js"; import catchErrors from "../../utils/catchErrors.js";
import Twilio from "twilio";
const Signup = () => { const Signup = () => {
const [user, setUser] = useState({ const [user, setUser] = useState({
......
import axios from "axios";
import { createContext, useCallback, useContext, useState } from "react"; import { createContext, useCallback, useContext, useState } from "react";
import authApi from "../apis/auth.api"; import authApi from "../apis/auth.api";
import { getLocalUser } from "../utils/auth"; import { getLocalUser } from "../utils/auth";
import {baseUrl} from "../utils/baseUrl";
import catchErrors from "../utils/catchErrors"; import catchErrors from "../utils/catchErrors";
import config from "../utils/clientConfig"; import config from "../utils/clientConfig";
const AuthContext = createContext({ const AuthContext = createContext({
error: "", error: "",
loading: false, loading: false,
user: {id:0, role:"user"}, user: {id:0, nickName:"비회원", role:"user"},
setUser: () => { }, setUser: () => { },
login: () => Promise.resolve(false), login: () => Promise.resolve(false),
logout: () => { }, logout: () => { },
...@@ -26,9 +24,9 @@ const AuthProvider = ({ children }) => { ...@@ -26,9 +24,9 @@ const AuthProvider = ({ children }) => {
setError(""); setError("");
setLoading(true); setLoading(true);
const user = await authApi.login(id, password); const user = await authApi.login(id, password);
console.log("user : ", user);
localStorage.setItem(config.loginUser, JSON.stringify(user)); localStorage.setItem(config.loginUser, JSON.stringify(user));
setUser(user); setUser(user);
return true; return true;
} catch (error) { } catch (error) {
catchErrors(error, setError); catchErrors(error, setError);
...@@ -45,7 +43,7 @@ const AuthProvider = ({ children }) => { ...@@ -45,7 +43,7 @@ const AuthProvider = ({ children }) => {
alert("로그아웃되었습니다."); alert("로그아웃되었습니다.");
localStorage.removeItem(config.loginUser); localStorage.removeItem(config.loginUser);
setLoading(true); setLoading(true);
await axios.get(`${baseUrl}/api/auth/logout`); await authApi.logout();
} catch (error) { } catch (error) {
catchErrors(error, setError); catchErrors(error, setError);
} finally { } finally {
......
import config from "./clientConfig"; import clientConfig from "./clientConfig";
export function handleLogin(user) { export function handleLogin(user) {
if (user) { if (user) {
localStorage.setItem(config.loginUser, JSON.stringify(user)); localStorage.setItem(clientConfig.loginUser, JSON.stringify(user));
} }
} }
export function getLocalUser() { export function getLocalUser() {
const userData = localStorage.getItem(config.loginUser); const userData = localStorage.getItem(clientConfig.loginUser);
console.log(userData);
let user = null; let user = null;
if (userData) { if (userData) {
user = JSON.parse(userData); user = JSON.parse(userData);
......
import jwt from "jsonwebtoken"; import jwt from "jsonwebtoken";
import config from "../config/app.config.js"; import config from "../config/app.config.js";
import { User, Role } from '../db/index.js'; import { User, Role } from '../db/index.js';
import Twilio from "twilio";
const login = async (req, res) => { const login = async (req, res) => {
try { try {
...@@ -57,7 +56,9 @@ const login = async (req, res) => { ...@@ -57,7 +56,9 @@ const login = async (req, res) => {
const logout = async (req, res) => { const logout = async (req, res) => {
try { try {
res.cookie(config.cookieName,"") console.log(req.cookies);
res.clearCookie(config.cookieName);
res.send('successfully cookie cleared.')
} catch (error) { } catch (error) {
console.error(error); console.error(error);
return res.status(500).send("로그인 에러"); return res.status(500).send("로그인 에러");
...@@ -78,18 +79,18 @@ const confirmMbnum = async (req, res) => { ...@@ -78,18 +79,18 @@ const confirmMbnum = async (req, res) => {
const id = req.params.id; const id = req.params.id;
const token = req.params.token; const token = req.params.token;
const client = Twilio(id, token); // const client = Twilio(id, token);
// console.log(client); // // console.log(client);
client.messages // client.messages
.create({ // .create({
to: '+8201086074580', // to: '+8201086074580',
from: '+14159428621', // from: '+14159428621',
body: '[ButterStudio] 인증번호[1234]를 입력해주세요', // body: '[ButterStudio] 인증번호[1234]를 입력해주세요',
}) // })
.then(message => console.log(message.sid)) // .then(message => console.log(message.sid))
.catch(e => console.log(error)); // .catch(e => console.log(error));
// console.log("id = ", id, "token = ", token); // console.log("id = ", id, "token = ", token);
return res.json(true); res.json(true);
} }
const signup = async (req, res) => { const signup = async (req, res) => {
...@@ -119,24 +120,55 @@ const signup = async (req, res) => { ...@@ -119,24 +120,55 @@ const signup = async (req, res) => {
}; };
const getNickName = async (req, res) => { const getNickName = async (req, res) => {
console.log("여기여기");
const id = req.params.id; const id = req.params.id;
console.log("id : ", id);
try { try {
const userNickName = await User.findOne({ where: { id: id }, attributes:["nickname"] }); const userNickName = await User.findOne({ where: { id: id }, attributes:["nickname"] });
console.log("userNickName: ", userNickName); res.json(userNickName.nickname)
return res.json(userNickName.nickname)
} catch (error) { } catch (error) {
console.error("error : ",error.message); console.error("error : ",error.message);
res.status(500).send("회원가입 에러. 나중에 다시 시도 해주세요"); res.status(500).send("회원가입 에러. 나중에 다시 시도 해주세요");
} }
} }
const modifyUser = async (req, res) => {
const { userEmail, userNickName, userMbnum, userPassword, userRePassword } = req.body;
// 휴대폰 중복 확인
try {
const emailOverlap = await User.findOne({ where: { email: userEmail } });
console.log("emailOverlap : ",emailOverlap);
if (emailOverlap) {
return res.status(422).send(`이미 있는 이메일입니다.`);
}else{
const user = await User.findOne({ where: { password: userPassword } });
console.log("user", user);
user.email = userEmail;
user.nickname = userNickName;
user.phoneNumber = userMbnum;
user.password = userRePassword;
await user.save({ fields: ['email'] });
await user.reload();
}
res.clearCookie(config.cookieName);
res.cookie(config.cookieName, token, {
maxAge: config.cookieMaxAge,
path: "/",
httpOnly: config.env === "production",
secure: config.env === "production",
});
res.send('successfully cookie cleared.')
} catch (error) {
console.error(error.message);
res.status(500).send("수정 에러. 나중에 다시 시도 해주세요");
}
};
export default { export default {
login, login,
logout, logout,
compareId, compareId,
confirmMbnum, confirmMbnum,
signup, signup,
getNickName getNickName,
modifyUser
} }
...@@ -10,7 +10,7 @@ dotenv.config({ ...@@ -10,7 +10,7 @@ dotenv.config({
}); });
sequelize sequelize
.sync({ force: true }) .sync({ force: false })
.then(async () => { .then(async () => {
await Promise.all( await Promise.all(
Object.keys(ROLE_NAME).map((name) => { Object.keys(ROLE_NAME).map((name) => {
......
...@@ -15,6 +15,16 @@ router ...@@ -15,6 +15,16 @@ router
.route("/signup") .route("/signup")
.post(userCtrl.signup) .post(userCtrl.signup)
router
.route("/modify")
.post(userCtrl.modifyUser)
router
.route("/nickname/:id")
.get(userCtrl.getNickName)
router router
.route("/:userId") .route("/:userId")
.get(userCtrl.compareId) .get(userCtrl.compareId)
...@@ -23,8 +33,4 @@ router ...@@ -23,8 +33,4 @@ router
.route("/:id/:token") .route("/:id/:token")
.get(userCtrl.confirmMbnum) .get(userCtrl.confirmMbnum)
router
.route("/:id")
.get(userCtrl.getNickName)
export default router; 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