Commit caab7670 authored by Yoon, Daeki's avatar Yoon, Daeki 😅
Browse files

course, admin 추가

parent 8d9a692a
const list = async (signal) => {
try {
let response = await fetch('/api/courses/', {
method: 'GET',
signal: signal,
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
})
return await response.json()
} catch (error) {
console.log(error)
}
}
export {
list,
}
...@@ -67,7 +67,7 @@ function EditProblem() { ...@@ -67,7 +67,7 @@ function EditProblem() {
return ( return (
<div> <div>
문제를 수정합니다. id: {problemId} 문제를 수정합니다.
<Form> <Form>
<Form.Group controlId="question"> <Form.Group controlId="question">
<Form.Label>Question</Form.Label> <Form.Label>Question</Form.Label>
......
import React, { useState } from "react";
import { Link } from "react-router-dom";
import Card from "react-bootstrap/Card";
import Button from "react-bootstrap/Button";
function Problem({ problem, number, onUpdate, onRemove }) {
const [editable, setEditable] = useState(false);
const handleEditable = (event) => {
setEditable(true);
};
return (
<Card>
<Card.Body>
<Card.Title>
{number + 1}번. {problem.question}
</Card.Title>
Answers
{problem.answers.map((answer, index) => {
return <Card.Text key={index}>{answer}</Card.Text>;
})}
<Link to={`/quiz/problem/edit/${problem._id}`}>
<Button onClick={(event) => onUpdate(number)}>수정</Button>
</Link>
<Button onClick={() => onRemove(number)}>삭제</Button>
<Card.Text as={editable ? "input" : "p"}>Hello 안녕!</Card.Text>
<Button onClick={editable}>Editable</Button>
</Card.Body>
</Card>
);
}
export default Problem;
import React, { useState } from "react"; import React, { useState, useEffect } from "react";
import { Link } from "react-router-dom"; import { Link } from "react-router-dom";
import Container from "react-bootstrap/Container"; import Container from "react-bootstrap/Container";
import Button from "react-bootstrap/Button"; import Button from "react-bootstrap/Button";
...@@ -10,33 +10,66 @@ import authHelpers from "../auth/auth-helpers"; ...@@ -10,33 +10,66 @@ import authHelpers from "../auth/auth-helpers";
import { create } from "./api-quiz"; import { create } from "./api-quiz";
// import NewProblem from "./NewProblem"; // import NewProblem from "./NewProblem";
import Problem from "./Problem"; import Problem from "./Problem";
import { list } from "../course/api-course";
function NewQuiz() { function NewQuiz() {
const [title, setTitle] = useState("");
const [problems, setProblems] = useState([]); const [problems, setProblems] = useState([]);
const [show, setShow] = useState(false);
const [quiz, setQuiz] = useState({}); const [quiz, setQuiz] = useState({});
const [startAt, setStartAt] = useState() const [courses, setCourses] = useState([])
const [endAt, setEndAt] = useState()
const [values, setValues] = useState({ const [values, setValues] = useState({
title: '', title: "",
problems: [],
show: false, show: false,
startAt: '', startAt: "",
endAt: '', endAt: "",
}) course: "",
});
const jwt = authHelpers.isAuthenticated(); const jwt = authHelpers.isAuthenticated();
useEffect(() => {
const abortController = new AbortController()
const signal = abortController.signal
list(signal).then(data => {
if (data.error) {
console.log(data.error);
} else {
console.log(data);
setCourses(data)
}
})
return () => {
abortController.abort()
}
}, [])
const handleChange = (event) => { const handleChange = (event) => {
const { name, value } = event.target; const { name, value } = event.target;
console.log("name", name, "value", value); console.log("name", name, "value", value);
console.log('values:', values); console.log("values:", values);
setValues({...values, [name]: value})
if (name === "title") { if (name === "course") {
setTitle(value); console.log(`${name}: ${courses[value]._id}`);
setValues({ ...values, [name]: courses[value]._id });
} else {
setValues({ ...values, [name]: value });
} }
}; };
const handleUpdate = (index) => {
console.log(`Quiz에서 handleUpdate ${index}번 실행`);
// console.log(`Quiz에서 handleUpdate ${JSON.stringify(quiz.problems[index])}`);
}
const handleRemove = (index) => {
console.log('handleRemove 실행');
const problem = problems[index]
console.log(problem);
const list = [...problems]
list.splice(index, 1)
setProblems(list)
}
const addProblem = (problem) => { const addProblem = (problem) => {
console.log(problem); console.log(problem);
setProblems([...problems, problem]); setProblems([...problems, problem]);
...@@ -46,21 +79,26 @@ function NewQuiz() { ...@@ -46,21 +79,26 @@ function NewQuiz() {
event.preventDefault(); event.preventDefault();
const quizData = { const quizData = {
title, title: values.title,
problems, problems: problems,
startAt: values.startAt,
endAt: values.endAt,
course: values.course,
}; };
create({ userId: jwt.user._id }, { t: jwt.token }, quizData).then( console.log(quizData);
(data) => {
if (data.error) { // create({ userId: jwt.user._id }, { t: jwt.token }, quizData).then(
console.log(data.error); // (data) => {
} else { // if (data.error) {
console.log(data); // console.log(data.error);
setQuiz(data); // } else {
setShow(true); // console.log(data);
} // setQuiz(data);
} // setShow(true);
); // }
// }
// );
}; };
return ( return (
...@@ -76,8 +114,21 @@ function NewQuiz() { ...@@ -76,8 +114,21 @@ function NewQuiz() {
placeholder="Title" placeholder="Title"
/> />
</Form.Group> </Form.Group>
<Row className="justify-content-between"> <Form.Row>
<Form.Group> <Form.Group as={Col} md="4">
<Form.Label>Course</Form.Label>
<Form.Control
as="select"
id="course"
name="course"
onChange={handleChange}
>
{courses.map((course, i) => (
<option key={i} value={i}>{course.name}</option>
))}
</Form.Control>
</Form.Group>
<Form.Group as={Col} md="4">
<Form.Label>Start Time</Form.Label> <Form.Label>Start Time</Form.Label>
<Form.Control <Form.Control
type="datetime-local" type="datetime-local"
...@@ -86,7 +137,7 @@ function NewQuiz() { ...@@ -86,7 +137,7 @@ function NewQuiz() {
onChange={handleChange} onChange={handleChange}
/> />
</Form.Group> </Form.Group>
<Form.Group> <Form.Group as={Col} md="4">
<Form.Label>End Time</Form.Label> <Form.Label>End Time</Form.Label>
<Form.Control <Form.Control
type="datetime-local" type="datetime-local"
...@@ -95,16 +146,16 @@ function NewQuiz() { ...@@ -95,16 +146,16 @@ function NewQuiz() {
onChange={handleChange} onChange={handleChange}
/> />
</Form.Group> </Form.Group>
</Row> </Form.Row>
{problems.map((problem, index) => { {problems.map((problem, index) => {
return <Problem key={index} problem={problem} number={index} />; return <Problem key={index} problem={problem} number={index} onUpdate={handleUpdate} onRemove={handleRemove}/>;
})} })}
<NewQuizProblem addProblem={addProblem} /> <NewQuizProblem addProblem={addProblem} />
<Button onClick={clickSubmit}>퀴즈 저장</Button> <Button onClick={clickSubmit}>퀴즈 저장</Button>
</Form> </Form>
<Modal show={show}> <Modal show={values.show}>
<Modal.Header> <Modal.Header>
<Modal.Title>New Quiz</Modal.Title> <Modal.Title>New Quiz</Modal.Title>
</Modal.Header> </Modal.Header>
......
import dbErrorHandler from "../helpers/dbErrorHandler.js"
import Course from "./course.model.js"
const create = async (req, res) => {
try {
const course = new Course(req.body)
await course.save()
return res.json(course)
} catch (error) {
return res.status(400).json({
error: dbErrorHandler.getErrorMessage(error)
})
}
}
const list = async (req, res) => {
try {
const courses = await Course.find({}).exec()
return res.json(courses)
} catch (error) {
return res.status(400).json({
error: dbErrorHandler.getErrorMessage(error)
})
}
}
export default {
create,
list,
}
\ No newline at end of file
...@@ -3,6 +3,14 @@ import mongoose from 'mongoose' ...@@ -3,6 +3,14 @@ import mongoose from 'mongoose'
const CourseSchema = new mongoose.Schema({ const CourseSchema = new mongoose.Schema({
name: String, name: String,
description: String, description: String,
code: {
type: String,
unique: true,
}, // 코스 코드
class: {
type: Number,
default: 0,
}, // 분반
image: {data: Buffer, contentType: String}, image: {data: Buffer, contentType: String},
instructor: { instructor: {
type: mongoose.SchemaTypes.ObjectId, type: mongoose.SchemaTypes.ObjectId,
......
import express from 'express'
import authCtrl from '../auth/auth.controller.js'
import userCtrl from '../user/user.controller.js'
import courseCtrl from './course.controller.js'
const router = express.Router()
router.route('/api/courses')
.get(courseCtrl.list)
router.route('/api/courses/by/:userId')
.post(authCtrl.requireSignin, authCtrl.hasAuthorization, userCtrl.isAdmin, courseCtrl.create)
router.param('userId', userCtrl.userById)
export default router
\ No newline at end of file
...@@ -3,6 +3,7 @@ import bodyParser from 'body-parser' ...@@ -3,6 +3,7 @@ import bodyParser from 'body-parser'
import userRoutes from './user/user.routes.js' import userRoutes from './user/user.routes.js'
import authRoutes from './auth/auth.routes.js' import authRoutes from './auth/auth.routes.js'
import quizRoutes from './quiz/quiz.routes.js' import quizRoutes from './quiz/quiz.routes.js'
import courseRoutes from './course/course.routes.js'
const app = express() const app = express()
...@@ -12,6 +13,7 @@ app.use(bodyParser.urlencoded({ extended: true })) ...@@ -12,6 +13,7 @@ app.use(bodyParser.urlencoded({ extended: true }))
app.use('/', authRoutes) app.use('/', authRoutes)
app.use('/', userRoutes) app.use('/', userRoutes)
app.use('/', quizRoutes) app.use('/', quizRoutes)
app.use('/', courseRoutes)
app.use((err, req, res, next) => { app.use((err, req, res, next) => {
if (err.name === 'UnauthorizedError') { if (err.name === 'UnauthorizedError') {
......
...@@ -90,6 +90,16 @@ const isInstructor = (req, res, next) => { ...@@ -90,6 +90,16 @@ const isInstructor = (req, res, next) => {
next() next()
} }
const isAdmin = (req, res, next) => {
const admin = req.profile && req.profile.admin
if (!admin) {
return res.status(403).json({
error: 'User is not an admin'
})
}
next()
}
const userById = async (req, res, next, id) => { const userById = async (req, res, next, id) => {
// console.log('req.body in userById', req.body); // console.log('req.body in userById', req.body);
try { try {
...@@ -116,5 +126,6 @@ export default { ...@@ -116,5 +126,6 @@ export default {
update, update,
remove, remove,
isInstructor, isInstructor,
isAdmin,
userById, userById,
} }
\ No newline at end of file
...@@ -32,6 +32,10 @@ const UserSchema = new mongoose.Schema({ ...@@ -32,6 +32,10 @@ const UserSchema = new mongoose.Schema({
type: Boolean, type: Boolean,
default: false, default: false,
}, },
admin: {
type: Boolean,
default: false,
}
}) })
UserSchema.virtual('password') UserSchema.virtual('password')
......
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