Commit 04f7c521 authored by Kim, Subin's avatar Kim, Subin
Browse files

Merge remote-tracking branch 'origin/rkyoung7'

parents 147e12a8 914ed2b6
......@@ -10,35 +10,38 @@ import StudyPlanPage from "./pages/StudyPlanPage";
import StudyPlanEditPage from "./pages/StudyPlanEditPage";
import SubjectEditPage from "./pages/SubjectEditPage";
import AdminPage from "./pages/Admin/AdminPage";
import { AuthProvider } from "./utils/context.js";
import PrivateRoute from "./components/PrivateRoute";
import ErrorPage from "./pages/ErrorPage";
function App() {
return (
<Router basename={process.env.PUBLIC_URL}>
<div id="box" className="container position-relative vh-100 mx-sm-auto">
<Switch>
<Route exact path="/" component={LoginPage} />
<Route path="/login" component={LoginPage} />
<Route path="/signup" component={SignupPage} />
<Route path="/home" component={HomePage} />
<Route path="/schedule/edit" component={ScheduleEditPage} />
<Route path="/schedule/:date" component={SchedulePage} />
<Route path="/todo/:date" component={ToDoPage} />
<Route path="/studyplan/edit" component={StudyPlanEditPage} />
<Route path="/studyplan/:" component={StudyPlanPage} />
<Route path="/studyplan" component={StudyPlanListPage} />
<Route path="/subject/edit/:subjectId" component={SubjectEditPage} />
<Route path="/subject/edit" component={SubjectEditPage} />
<Route path="/admin/edit/:scheduleId" component={ScheduleEditPage} />
<Route path="/admin/edit" component={ScheduleEditPage} />
<Route path="/admin" component={AdminPage} />
{/* <PrivateRoute path="/admin" component={AdminPage} role="admin" /> */}
<AuthProvider >
<Router basename={process.env.PUBLIC_URL}>
<div id="box" className="container position-relative vh-100 mx-sm-auto">
<Switch>
<Route exact path="/" component={LoginPage} />
<Route path="/login" component={LoginPage} />
<Route path="/signup" component={SignupPage} />
<Route path="/home" component={HomePage} />
<Route path="/schedule/edit" component={ScheduleEditPage} />
<Route path="/schedule/:date" component={SchedulePage} />
<Route path="/todo/:date" component={ToDoPage} />
<Route path="/studyplan/edit" component={StudyPlanEditPage} />
<Route path="/studyplan/:" component={StudyPlanPage} />
<Route path="/studyplan" component={StudyPlanListPage} />
<Route path="/subject/edit/:subjectId" component={SubjectEditPage} />
<Route path="/subject/edit" component={SubjectEditPage} />
<Route path="/admin/edit/:scheduleId" component={ScheduleEditPage} />
<Route path="/admin/edit" component={ScheduleEditPage} />
<Route path="/admin" component={AdminPage} />
{/* <PrivateRoute path="/admin" component={AdminPage} role="admin" /> */}
<Route component={ErrorPage} />
</Switch>
</div>
</Router>
<Route component={ErrorPage} />
</Switch>
</div>
</Router>
</AuthProvider>
);
}
......
import axios from "axios";
import baseUrl from "../utils/baseUrl.js";
const getUser = async () => {
const url = `${baseUrl}/api/auth/user`
const { data } = await axios.get(url)
return data
}
const signup = async (user) => {
const url = `${baseUrl}/api/auth/signup`;
const { data, status } = await axios.post(url, user);
return { data, status }
const { data } = await axios.post(url, user);
return data
}
const login = async (user) => {
const url = `${baseUrl}/api/auth/login`;
const { data, status } = await axios.post(url, user);
return { data, status }
const { data } = await axios.post(url, user);
return data
}
const logout = async () => {
const url = `${baseUrl}/api/auth/logout`;
const { data } = await axios.get(url);
return data
}
const authApi = {
getUser,
signup,
login
login,
logout
};
export default authApi
\ No newline at end of file
import axios from "axios";
import baseUrl from "../utils/baseUrl.js";
const addsubject = async (info) => {
console.log('info확인', info)
const addsubject = async (info, userId) => {
console.log('subject check', userId)
// info.user = userId;
const url = `${baseUrl}/api/subject/addsubject`;
const { data, status } = await axios.post(url, info);
console.log('data status', data, '|', status)
return { data, status }
const { data } = await axios.post(url, { info, userId });
return data
}
const editSubject = async (info, id) => {
console.log("editSubject check", info, ',', id)
const url = `${baseUrl}/api/subject/editsubject`
const { data } = await axios.post(url, { info, id })
return data
}
const getSubInfo = async (info) => {
console.log('info', info)
const url = `${baseUrl}/api/subject/${info}`
const { data } = await axios.get(url);
return data
}
const subjectApi = {
addsubject
addsubject,
getSubInfo,
editSubject
};
export default subjectApi
\ No newline at end of file
......@@ -3,12 +3,7 @@ import { Link } from "react-router-dom";
import styles from "../Form/form.module.scss";
const StudyPlanCard = () => {
const [studyplan, setStudyplan] = useState({
subject: "",
info: "",
contents: []
})
// studyPlanList에서 props로 받아서 뿌리기
return (
<>
<div className="d-flex justify-content-center mt-3">
......@@ -18,7 +13,7 @@ const StudyPlanCard = () => {
<div className="d-flex justify-content-between">
<h5 className="card-title col-10">운영체제</h5>
<div className="col-2 d-flex justify-content-end">
<Link className="text-decoration-none link-dark" to="/subject/edit"><i className="bi bi-pencil-square pe-2"></i></Link>
<Link className="text-decoration-none link-dark" to="/subject/edit/ed56bebd-b9ae-4065-aae2-d39aeac5f18e"><i className="bi bi-pencil-square pe-2"></i></Link>
<i className="bi bi-trash"></i>
</div>
</div>
......
import { useState } from 'react';
import { Redirect, Link } from "react-router-dom";
import { Formik } from 'formik';
import { useAuth } from "../../utils/context.js";
import * as Yup from 'yup';
import authApi from '../../apis/auth.api';
import catchErrors from "../../utils/catchErrors.js";
import styles from "./form.module.scss";
const LoginForm = () => {
const { login } = useAuth();
const [success, setSuccess] = useState(false);
const [error, setError] = useState("");
......@@ -28,9 +29,10 @@ const LoginForm = () => {
})}
onSubmit={async (values, { setSubmitting, resetForm }) => {
try {
console.log('login values', values)
setError("")
const result = await authApi.login(values)
if (result.status === 201) {
const result = await login(values)
if (result) {
setSuccess(true)
}
} catch (error) {
......
import { useState, useEffect } from 'react';
import { Redirect, useParams } from 'react-router-dom';
import { useAuth } from '../../utils/context.js';
import BtnGroup from "../Buttons/BtnGroup";
import styles from "./form.module.scss";
import { useParams } from 'react-router-dom';
import subjectApi from '../../apis/subject.api';
import catchErrors from '../../utils/catchErrors.js';
const SubjectForm = () => {
const { user } = useAuth();
const { subjectId } = useParams();
const [success, setSuccess] = useState(false)
const [error, setError] = useState("");
const [subject, setSubject] = useState({
lectureName: "",
......@@ -15,6 +18,11 @@ const SubjectForm = () => {
})
const [disabled, setDisabled] = useState(true)
useEffect(() => {
getInfo(subjectId);
}, [])
useEffect(() => {
let isMounted = true;
const checkInfo = { lectureName: subject.lectureName }
......@@ -34,36 +42,60 @@ const SubjectForm = () => {
}
async function getInfo(id) {
const result = await subjectApi.getSubInfo(id)
console.log('과목수정 result확인', result)
setSubject({
lectureName: result.name,
prof: result.prof,
classRoom: result.room
})
}
async function handleSubmit(e) {
e.preventDefault();
try {
setError("")
if (subjectId) {
//수정함수 실행
await subjectApi.editSubject(subject, subjectId)
alert("과목정보가 수정되었습니다.")
setSuccess(true)
} else {
await subjectApi.addsubject(subject)
//등록함수 실행
await subjectApi.addsubject(subject, user.id)
}
} catch (error) {
catchErrors(error, setError)
setSubject({
lectureName: "",
prof: "",
classRoom: ""
})
}
}
if (success) {
return <Redirect to="/studyplan" />
}
return (
<>
<div className="position-absolute top-50 start-50 translate-middle" style={{ width: "80%" }}>
<div>
<div className="mb-5 d-flex flex-row">
<label className="form-label fs-4" style={{ width: "100px" }}>강의명</label>
<input className={`form-control shadow-none rounded-0 ${styles.textInput}`} name="lectureName" onChange={handleChange} />
<input className={`form-control shadow-none rounded-0 ${styles.textInput}`} value={subject.lectureName} name="lectureName" onChange={handleChange} />
</div>
<div className="mb-5 pt-2 d-flex flex-row">
<label className="form-label fs-4" style={{ width: "100px" }}>교수명</label>
<input className={`form-control shadow-none rounded-0 ${styles.textInput}`} name="prof" onChange={handleChange} />
<input className={`form-control shadow-none rounded-0 ${styles.textInput}`} value={subject.prof} name="prof" onChange={handleChange} />
</div>
<div className="mb-5 pt-2 d-flex flex-row">
<label className="form-label fs-4 " style={{ width: "100px", letterSpacing: "15px" }}>장소</label>
<input className={`form-control shadow-none rounded-0 ${styles.textInput}`} name="classRoom" onChange={handleChange} />
<input className={`form-control shadow-none rounded-0 ${styles.textInput}`} value={subject.classRoom} name="classRoom" onChange={handleChange} />
</div>
</div>
<div className="pt-2">
......
import { Link, Redirect } from "react-router-dom";
import { useAuth } from "../../utils/context.js";
import moment from "moment";
import styles from "./menu.module.scss";
const Menu = () => {
const { logout } = useAuth();
return (
<>
<button className="btn btn-crimson shadow-none mt-2" type="button" data-bs-toggle="collapse" data-bs-target="#menuContent" aria-controls="menuContent" aria-expanded="false" aria-label="menu">
......@@ -39,7 +41,7 @@ const Menu = () => {
<Link className="text-dark text-decoration-none" to={`/schedule/${moment().format("YYYY-MM-DD")}`}><i className="bi bi-check"></i>일정</Link>
<Link className="text-dark text-decoration-none" to="/studyplan"><i className="bi bi-check"></i>학업별 계획</Link>
</div>
<p className={`position-absolute bottom-0 text-dark ${styles.logout}`}>로그아웃</p>
<p className={`position-absolute bottom-0 text-dark ${styles.logout}`} onClick={logout}>로그아웃</p>
</div>
</div>
</div>
......
import { Redirect, Route } from "react-router-dom";
// import { useAuth } from "../context/auth_context";
import { useAuth } from "../utils/context.js"
import ErrorPage from "../pages/ErrorPage";
const PrivateRoute = ({ component: Component, ...rest }) => {
// const { user } = useAuth();
// return (
const { user } = useAuth();
// return (
// <Route
// {...rest}
// render={(props) => {
// if (user) {
// if (rest.role) {
// if (rest.role === user.role) {
// return <Component {...props} />;
// {...rest}
// render={(props) => {
// if (user) {
// if (rest.role) {
// if (rest.role === user.role) {
// return <Component {...props} />;
// } else {
// return <ErrorPage />
// }
// } else {
// return <Component {...props} />
// }
// } else {
// return <ErrorPage />
// return <Redirect to="/login" />;
// }
// } else {
// return <Component {...props} />
// }
// } else {
// return <Redirect to="/login" />;
// }
// }}
// }}
// />
// );
// );
return (
<Route {...rest} render={(props) => <Component {...props} />} />
)
......
import { createContext, useCallback, useContext, useEffect, useState } from 'react';
import { Redirect } from 'react-router-dom';
import authApi from "../apis/auth.api";
import catchErrors from './catchErrors';
const AuthContext = createContext({
error: "",
user: { id: "", role: "user", name: "" },
setUser: () => { },
login: () => Promise.resolve(false),
logout: () => { },
catchErrorAuth: (error, displayError) => { },
});
const AuthProvider = ({ children }) => {
const [error, setError] = useState("");
const [user, setUser] = useState({ id: "", role: "user", name: "" });
const getUser = async () => {
const { id, role, userName } = await authApi.getUser();
const user = { id: id, role: role, name: userName };
setUser(user);
}
useEffect(() => {
getUser();
}, []);
const login = useCallback(async (data) => {
try {
setError("");
const user = await authApi.login(data);
localStorage.setItem("login", true)
setUser(user);
console.log('setUser 결과', user)
return true;
} catch (error) {
catchErrors(error, setError);
return false;
}
}, []);
const logout = useCallback(async () => {
try {
setError("");
const user = await authApi.logout();
localStorage.removeItem("login")
setUser(user);
alert("로그아웃 되었습니다.");
} catch (error) {
catchErrors(error, setError);
}
}, []);
const catchErrorAuth = useCallback(async (error, displayError) => {
let errMsg;
if (error.response) {
if (typeof error.response.data === "string") {
errMsg = error.response.data;
console.log('Error response:', errMsg);
} else {
const { data } = error.response;
if (data.redirectUrl) {
errMsg = data.message;
console.log('Error response with redirected message:', errMsg);
return await logout();
}
}
} else if (error.request) {
errMsg = error.request;
console.log('Error request:', errMsg);
} else {
errMsg = error.message;
console.log("Error message:", errMsg)
}
displayError(errMsg);
}, []);
return (
<AuthContext.Provider value={{ error, user, setUser, login, logout, catchErrorAuth }} >
{children}
</AuthContext.Provider>
);
};
const useAuth = () => useContext(AuthContext);
export { AuthProvider, useAuth };
......@@ -2,28 +2,67 @@ import { Subject } from '../db/index.js';
const addsubject = async (req, res) => {
console.log('server/addsubject req.body', req.body)
const { lectureName, prof, classRoom } = req.body;
try {
const findName = await Subject.findOne({ where: { name: lectureName } });
const { info, userId } = req.body;
const findName = await Subject.findOne({ where: { name: info.lectureName } });
if (findName) {
throw new Error("이미 있는 과목입니다.")
}
await Subject.create({
name: lectureName,
prof: prof,
room: classRoom,
name: info.lectureName,
prof: info.prof,
room: info.classRoom,
userId: userId
})
} catch (error) {
console.log(error)
return res.status(500).send(error.message || "과목저장 에러발생")
}
}
const getSubInfo = async (req, res) => {
console.log('server/getSubInfo req.body', req.params)
try {
const { subjectId } = req.params;
const findSubInfo = await Subject.findOne({ where: { id: subjectId } })
if (findSubInfo) {
res.json({
name: findSubInfo.dataValues.name,
prof: findSubInfo.dataValues.prof,
room: findSubInfo.dataValues.room
})
} else {
throw new Error("과목 찾기 실패")
}
} catch (error) {
console.log(error)
return res.status(500).send(error.message || "과목정보 가져오기 에러발생")
}
}
const editSubject = async (req, res) => {
console.log('server/editSubject req.body', req.body)
try {
const { info, id } = req.body;
const result = await Subject.update({
name: info.lectureName,
prof: info.prof,
room: info.classRoom,
}, { where: { id: id } })
if (!result) {
throw new Error("과목정보 수정 에러발생")
} else {
res.send(200)
}
} catch (error) {
console.log(error)
return res.status(500).send(error.message || "과목정보 수정 에러발생")
}
}
export default {
addsubject
addsubject,
getSubInfo,
editSubject
}
\ No newline at end of file
......@@ -2,6 +2,22 @@ import jwt from "jsonwebtoken";
import { User } from '../db/index.js';
import config from "../config/app.config.js";
const getUser = async (req, res) => {
try {
if (req.cookies.todayku) {
const token = req.cookies.todayku;
const { id, role, name } = jwt.verify(token, config.jwtSecret);
res.json({ id, role, name });
} else {
res.json({ id: "", role: "user", name: "" });
}
} catch (error) {
console.error(error);
return res.status(500).send("유저를 가져오지 못했습니다.");
}
}
const signup = async (req, res) => {
console.log('server/signup req.body', req.body)
const { userId, password, userName, userStudNum } = req.body;
......@@ -15,7 +31,7 @@ const signup = async (req, res) => {
password: password,
userName: userName,
studNum: userStudNum,
role:"user"
role: "user"
});
res.status(201).json("success")
} catch (error) {
......@@ -37,9 +53,10 @@ const login = async (req, res) => {
if (passwordMatch) {
const signData = {
id: user.userID,
name: user.userName
};
id: user.id,
role: "user",
name: user.userName,
};
const token = jwt.sign(signData, config.jwtSecret, {
expiresIn: config.jwtExpires,
......@@ -52,8 +69,8 @@ const login = async (req, res) => {
secure: config.env === "production",
});
res.status(201).json(user)
} else {
res.status(201).json(signData)
} else {
res.status(401).send("비밀번호가 일치하지 않습니다.")
}
......@@ -63,7 +80,23 @@ const login = async (req, res) => {
}
}
const logout = async (req, res) => {
try {
res.clearCookie(config.cookieName);
res.json({
id:"",
role:"user",
name:""
})
} catch (error) {
console.log(error);
return res.status(500).send("로그아웃 에러발생")
}
}
export default {
getUser,
signup,
login
login,
logout
}
\ No newline at end of file
......@@ -7,4 +7,13 @@ router
.route("/addsubject")
.post(subjectCtrl.addsubject)
router
.route("/:subjectId")
.get(subjectCtrl.getSubInfo)
router
.route("/editsubject")
.post(subjectCtrl.editSubject)
export default router;
\ No newline at end of file
......@@ -11,4 +11,7 @@ router
.route("/login")
.post(userCtrl.login)
router
.route("/logout")
.get(userCtrl.logout )
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