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() {
return (
<div>
문제를 수정합니다. id: {problemId}
문제를 수정합니다.
<Form>
<Form.Group controlId="question">
<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 Container from "react-bootstrap/Container";
import Button from "react-bootstrap/Button";
......@@ -10,33 +10,66 @@ import authHelpers from "../auth/auth-helpers";
import { create } from "./api-quiz";
// import NewProblem from "./NewProblem";
import Problem from "./Problem";
import { list } from "../course/api-course";
function NewQuiz() {
const [title, setTitle] = useState("");
const [problems, setProblems] = useState([]);
const [show, setShow] = useState(false);
const [quiz, setQuiz] = useState({});
const [startAt, setStartAt] = useState()
const [endAt, setEndAt] = useState()
const [courses, setCourses] = useState([])
const [values, setValues] = useState({
title: '',
title: "",
problems: [],
show: false,
startAt: '',
endAt: '',
})
startAt: "",
endAt: "",
course: "",
});
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 { name, value } = event.target;
console.log("name", name, "value", value);
console.log('values:', values);
setValues({...values, [name]: value})
if (name === "title") {
setTitle(value);
console.log("values:", values);
if (name === "course") {
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) => {
console.log(problem);
setProblems([...problems, problem]);
......@@ -46,21 +79,26 @@ function NewQuiz() {
event.preventDefault();
const quizData = {
title,
problems,
title: values.title,
problems: problems,
startAt: values.startAt,
endAt: values.endAt,
course: values.course,
};
create({ userId: jwt.user._id }, { t: jwt.token }, quizData).then(
(data) => {
if (data.error) {
console.log(data.error);
} else {
console.log(data);
setQuiz(data);
setShow(true);
}
}
);
console.log(quizData);
// create({ userId: jwt.user._id }, { t: jwt.token }, quizData).then(
// (data) => {
// if (data.error) {
// console.log(data.error);
// } else {
// console.log(data);
// setQuiz(data);
// setShow(true);
// }
// }
// );
};
return (
......@@ -76,8 +114,21 @@ function NewQuiz() {
placeholder="Title"
/>
</Form.Group>
<Row className="justify-content-between">
<Form.Group>
<Form.Row>
<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.Control
type="datetime-local"
......@@ -86,7 +137,7 @@ function NewQuiz() {
onChange={handleChange}
/>
</Form.Group>
<Form.Group>
<Form.Group as={Col} md="4">
<Form.Label>End Time</Form.Label>
<Form.Control
type="datetime-local"
......@@ -95,16 +146,16 @@ function NewQuiz() {
onChange={handleChange}
/>
</Form.Group>
</Row>
</Form.Row>
{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} />
<Button onClick={clickSubmit}>퀴즈 저장</Button>
</Form>
<Modal show={show}>
<Modal show={values.show}>
<Modal.Header>
<Modal.Title>New Quiz</Modal.Title>
</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'
const CourseSchema = new mongoose.Schema({
name: String,
description: String,
code: {
type: String,
unique: true,
}, // 코스 코드
class: {
type: Number,
default: 0,
}, // 분반
image: {data: Buffer, contentType: String},
instructor: {
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'
import userRoutes from './user/user.routes.js'
import authRoutes from './auth/auth.routes.js'
import quizRoutes from './quiz/quiz.routes.js'
import courseRoutes from './course/course.routes.js'
const app = express()
......@@ -12,6 +13,7 @@ app.use(bodyParser.urlencoded({ extended: true }))
app.use('/', authRoutes)
app.use('/', userRoutes)
app.use('/', quizRoutes)
app.use('/', courseRoutes)
app.use((err, req, res, next) => {
if (err.name === 'UnauthorizedError') {
......
......@@ -90,6 +90,16 @@ const isInstructor = (req, res, 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) => {
// console.log('req.body in userById', req.body);
try {
......@@ -116,5 +126,6 @@ export default {
update,
remove,
isInstructor,
isAdmin,
userById,
}
\ No newline at end of file
......@@ -32,6 +32,10 @@ const UserSchema = new mongoose.Schema({
type: Boolean,
default: false,
},
admin: {
type: Boolean,
default: false,
}
})
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