Finish teacher marks page
This commit is contained in:
parent
5c2747b149
commit
ed34b69b64
15 changed files with 168 additions and 109 deletions
26
app.js
26
app.js
|
@ -1,12 +1,13 @@
|
||||||
let express = require("express");
|
const express = require("express");
|
||||||
let path = require("path");
|
const path = require("path");
|
||||||
let cookieParser = require("cookie-parser");
|
const cookieParser = require("cookie-parser");
|
||||||
let logger = require("morgan");
|
const logger = require("morgan");
|
||||||
const session = require("express-session");
|
const session = require("express-session");
|
||||||
const error = require("./routes/utils/error");
|
const error = require("./routes/utils/error");
|
||||||
let config = process.env.NODE_ENV === "test" ? {} : require("./config/config.json");
|
const config = process.env.NODE_ENV === "test" ? {} : require("./config/config.json");
|
||||||
|
const models = require("./models");
|
||||||
|
|
||||||
let indexRouter = require("./routes/index");
|
const indexRouter = require("./routes/index");
|
||||||
const loginRouter = require("./routes/login");
|
const loginRouter = require("./routes/login");
|
||||||
const edtRouter = require("./routes/edt");
|
const edtRouter = require("./routes/edt");
|
||||||
const marksRouter = require("./routes/marks");
|
const marksRouter = require("./routes/marks");
|
||||||
|
@ -16,7 +17,9 @@ const profilRouter = require("./routes/profil");
|
||||||
|
|
||||||
let app = express();
|
let app = express();
|
||||||
const sessionMiddleware = session({
|
const sessionMiddleware = session({
|
||||||
secret: process.env.NODE_ENV === "test" ? "Keyboard Cat" : config.secret
|
secret: process.env.NODE_ENV === "test" ? "Keyboard Cat" : config.secret,
|
||||||
|
resave: false,
|
||||||
|
saveUninitialized: true
|
||||||
});
|
});
|
||||||
|
|
||||||
// view engine setup
|
// view engine setup
|
||||||
|
@ -31,7 +34,14 @@ app.use(express.urlencoded({ extended: false }));
|
||||||
app.use(cookieParser());
|
app.use(cookieParser());
|
||||||
app.use(express.static(path.join(__dirname, "public")));
|
app.use(express.static(path.join(__dirname, "public")));
|
||||||
app.use(sessionMiddleware);
|
app.use(sessionMiddleware);
|
||||||
app.use((req, res, next) => {
|
app.use(async (req, res, next) => {
|
||||||
|
if (req.session.user) {
|
||||||
|
let user = await models.User.findByPk(req.session.user.email, {include: {model: models.Group, include: models.Semester}});
|
||||||
|
if (user.updatedAt !== req.session.user.updatedAt) {
|
||||||
|
req.session.user = user;
|
||||||
|
req.session.save();
|
||||||
|
}
|
||||||
|
}
|
||||||
res.locals.session = req.session;
|
res.locals.session = req.session;
|
||||||
next();
|
next();
|
||||||
});
|
});
|
||||||
|
|
|
@ -5,19 +5,27 @@ const { Model } = require("sequelize");
|
||||||
module.exports = (sequelize, DataTypes) => {
|
module.exports = (sequelize, DataTypes) => {
|
||||||
class Group extends Model {
|
class Group extends Model {
|
||||||
static associate(models) {
|
static associate(models) {
|
||||||
Group.belongsTo(models.Semester);
|
Group.belongsTo(models.Semester, {foreignKey: {allowNull: false}});
|
||||||
Group.belongsToMany(models.User, {through: "UserGroup"});
|
Group.belongsToMany(models.User, {through: "UserGroup"});
|
||||||
Group.belongsToMany(models.Event, {through: "EventGroup"});
|
Group.belongsToMany(models.Event, {through: "EventGroup"});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Group.init({
|
return Group.init({
|
||||||
number: {
|
number: {
|
||||||
type: DataTypes.STRING,
|
type: DataTypes.STRING,
|
||||||
allowNull: false
|
allowNull: false
|
||||||
|
},
|
||||||
|
displayName: {
|
||||||
|
type: DataTypes.VIRTUAL,
|
||||||
|
get() {
|
||||||
|
if (this.number.startsWith("G"))
|
||||||
|
return this.number + this.Semester.name;
|
||||||
|
else
|
||||||
|
return this.Semester.name + " " + this.number
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
sequelize,
|
sequelize,
|
||||||
modelName: "Group",
|
modelName: "Group"
|
||||||
});
|
});
|
||||||
return Group;
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -5,7 +5,7 @@ const { Model } = require("sequelize");
|
||||||
module.exports = (sequelize, DataTypes) => {
|
module.exports = (sequelize, DataTypes) => {
|
||||||
class Semester extends Model {
|
class Semester extends Model {
|
||||||
static associate(models) {
|
static associate(models) {
|
||||||
Semester.hasMany(models.Group);
|
Semester.hasMany(models.Group, {foreignKey: {allowNull: false}});
|
||||||
Semester.belongsToMany(models.Event, {through: "EventSemester"});
|
Semester.belongsToMany(models.Event, {through: "EventSemester"});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,8 +22,6 @@ module.exports = (sequelize, DataTypes) => {
|
||||||
User.belongsToMany(models.Event, {through: "EventTeacher"});
|
User.belongsToMany(models.Event, {through: "EventTeacher"});
|
||||||
User.belongsToMany(models.Evaluation, {through: "EvaluationTeacher"});
|
User.belongsToMany(models.Evaluation, {through: "EvaluationTeacher"});
|
||||||
User.belongsToMany(models.UE, {through: "UEUser"});
|
User.belongsToMany(models.UE, {through: "UEUser"});
|
||||||
//User.hasMany(models.Grade, {as : "TeacherGrade"});
|
|
||||||
//User.hasMany(models.Grade, {as: "StudentGrade"});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
checkPassword(password) {
|
checkPassword(password) {
|
||||||
|
|
56
public/javascripts/marks-teacher.js
Normal file
56
public/javascripts/marks-teacher.js
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
const socket = io.connect();
|
||||||
|
const group = document.getElementById("group");
|
||||||
|
const evaluation = document.getElementById("evaluation");
|
||||||
|
const marksform = document.getElementById("marksform");
|
||||||
|
const markstable = document.getElementById("markstable").querySelector("tbody");
|
||||||
|
const studentTemplate = document.getElementById("studentTemplate");
|
||||||
|
|
||||||
|
let evaluations = {};
|
||||||
|
let students = [];
|
||||||
|
|
||||||
|
group.addEventListener("change", () => socket.emit("evaluationGet"));
|
||||||
|
|
||||||
|
socket.on("evaluationGet", evals => {
|
||||||
|
evaluations = {};
|
||||||
|
evaluation.innerHTML = "<option selected disabled></option>";
|
||||||
|
for (let ev of evals) {
|
||||||
|
if (!document.getElementById("UE"+ev.UE.id)) {
|
||||||
|
evaluation.insertAdjacentHTML("beforeend", `<optgroup id="UE${ev.UE.id}" label="${ev.UE.name}"></optgroup>`)
|
||||||
|
}
|
||||||
|
document.getElementById("UE"+ev.UE.id).insertAdjacentHTML("beforeend", `<option value="${ev.id}">${ev.name}</option>`);
|
||||||
|
evaluations[ev.id] = ev;
|
||||||
|
}
|
||||||
|
M.FormSelect.init(evaluation);
|
||||||
|
});
|
||||||
|
|
||||||
|
evaluation.addEventListener("change", () => {
|
||||||
|
marksform.querySelector(".evaluationName").innerHTML = evaluations[evaluation.value].UE.name + " - " + evaluations[evaluation.value].name;
|
||||||
|
socket.emit("studentGet", group.value);
|
||||||
|
});
|
||||||
|
|
||||||
|
socket.on("studentGet", sts => {
|
||||||
|
markstable.querySelectorAll("tr:not(.studentTemplate)").forEach(el => el.remove());
|
||||||
|
for (let st of sts) {
|
||||||
|
let el = studentTemplate.cloneNode(true);
|
||||||
|
el.style = "";
|
||||||
|
el.id = "Student"+st.email;
|
||||||
|
el.querySelector(".studentName").innerHTML = st.firstName + " " + st.lastName;
|
||||||
|
|
||||||
|
let gs = el.querySelector(".gradeScore");
|
||||||
|
gs.name = "score"+st.email;
|
||||||
|
let g = evaluations[evaluation.value].Grades.find(s => s.StudentGradeEmail === st.email);
|
||||||
|
if (g)
|
||||||
|
gs.value = g.score;
|
||||||
|
|
||||||
|
students.push(st);
|
||||||
|
markstable.insertAdjacentElement("beforeend", el);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
marksform.addEventListener("submit", e => {
|
||||||
|
e.preventDefault();
|
||||||
|
let grds = {};
|
||||||
|
for (let e of new FormData(marksform))
|
||||||
|
grds[e[0].replace(/^score/i, "")] = e[1];
|
||||||
|
socket.emit("gradeSet", {evaluation: evaluations[evaluation.value].id, grades: grds});
|
||||||
|
});
|
|
@ -484,13 +484,8 @@ div#visible + div
|
||||||
|
|
||||||
#hamburger
|
#hamburger
|
||||||
position: fixed
|
position: fixed
|
||||||
|
top: 0
|
||||||
#notvisible
|
left: 0
|
||||||
display: none
|
|
||||||
|
|
||||||
#marksform
|
|
||||||
display: none
|
|
||||||
|
|
||||||
.grades
|
.grades
|
||||||
border: 2px solid white
|
border: 2px solid white
|
||||||
height: 202px
|
height: 202px
|
||||||
|
|
|
@ -6,7 +6,8 @@ module.exports = socket => {
|
||||||
include: [models.UE, {model: models.User},
|
include: [models.UE, {model: models.User},
|
||||||
{
|
{
|
||||||
model: models.Grade,
|
model: models.Grade,
|
||||||
include: [{model: models.User, as: "TeacherGrade"}, {model: models.User, as: "StudentGrade"}]
|
include: [{attributes: ["email", "firstName", "lastName"], model: models.User, as: "TeacherGrade"},
|
||||||
|
{attributes: ["email", "firstName", "lastName"], model: models.User, as: "StudentGrade"}]
|
||||||
}]
|
}]
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -14,8 +15,8 @@ module.exports = socket => {
|
||||||
options.where.id = data.id;
|
options.where.id = data.id;
|
||||||
|
|
||||||
if (socket.request.session.user.permissions === 2) {
|
if (socket.request.session.user.permissions === 2) {
|
||||||
options.include[1].where = {email: socket.request.session.user.email};
|
options.include[0].through = {where: {UserEmail: socket.request.session.user.email}};
|
||||||
options.include[1].required = true;
|
options.include[0].required = true;
|
||||||
}
|
}
|
||||||
socket.emit("evaluationGet", await models.Evaluation.findAll(options));
|
socket.emit("evaluationGet", await models.Evaluation.findAll(options));
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,8 +3,8 @@ const models = require("../../models");
|
||||||
module.exports = socket => {
|
module.exports = socket => {
|
||||||
return async (data) => {
|
return async (data) => {
|
||||||
const options = {where: {}, include: [{model: models.Evaluation, include: {model: models.UE}},
|
const options = {where: {}, include: [{model: models.Evaluation, include: {model: models.UE}},
|
||||||
{model: models.User, as: "TeacherGrade"},
|
{attributes: ["email", "firstName", "lastName"], model: models.User, as: "TeacherGrade"},
|
||||||
{model: models.User, as: "StudentGrade"}]};
|
{attributes: ["email", "firstName", "lastName"], model: models.User, as: "StudentGrade", include: {model: models.Group, include: models.Semester}}]};
|
||||||
|
|
||||||
if (data && data.id)
|
if (data && data.id)
|
||||||
options.where.id = data.id;
|
options.where.id = data.id;
|
||||||
|
|
23
sockets/get/studentGet.js
Normal file
23
sockets/get/studentGet.js
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
const models = require("../../models");
|
||||||
|
|
||||||
|
module.exports = socket => {
|
||||||
|
return async (data) => {
|
||||||
|
let options = {
|
||||||
|
attributes: ["email", "firstName", "lastName"],
|
||||||
|
where: {permissions: 1},
|
||||||
|
include: [{model: models.Group, include: models.Semester}]
|
||||||
|
};
|
||||||
|
if (data && data.email)
|
||||||
|
options.where.email = data.email;
|
||||||
|
if (data && data.firstName && data.lastName) {
|
||||||
|
options.where.firstName = data.firstName;
|
||||||
|
options.where.lastName = data.lastName;
|
||||||
|
}
|
||||||
|
if (data && data.group) {
|
||||||
|
options.include[0].where = {id: data.group};
|
||||||
|
options.include[0].required = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
socket.emit("studentGet", await models.User.findAll(options));
|
||||||
|
}
|
||||||
|
};
|
|
@ -11,8 +11,11 @@ module.exports = socket => {
|
||||||
socket.on("logout", require("./logout")(socket));
|
socket.on("logout", require("./logout")(socket));
|
||||||
socket.on("agendaGet", require("./get/agendaGet")(socket));
|
socket.on("agendaGet", require("./get/agendaGet")(socket));
|
||||||
socket.on("gradeGet", require("./get/gradeGet")(socket));
|
socket.on("gradeGet", require("./get/gradeGet")(socket));
|
||||||
if (socket.request.session.user.permissions > 1)
|
if (socket.request.session.user.permissions > 1) {
|
||||||
socket.on("evaluationGet", require("./get/evaluationGet")(socket));
|
socket.on("evaluationGet", require("./get/evaluationGet")(socket));
|
||||||
|
socket.on("gradeSet", require("./set/gradeSet")(socket));
|
||||||
|
socket.on("studentGet", require("./get/studentGet")(socket));
|
||||||
|
}
|
||||||
if (socket.request.session.user.permissions > 2) {
|
if (socket.request.session.user.permissions > 2) {
|
||||||
socket.on("groupGet", require("./get/groupGet")(socket));
|
socket.on("groupGet", require("./get/groupGet")(socket));
|
||||||
socket.on("semesterGet", require("./get/semesterGet")(socket));
|
socket.on("semesterGet", require("./get/semesterGet")(socket));
|
||||||
|
|
19
sockets/set/gradeSet.js
Normal file
19
sockets/set/gradeSet.js
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
const models = require("../../models");
|
||||||
|
|
||||||
|
module.exports = socket => {
|
||||||
|
return async (data) => {
|
||||||
|
if (!data || !data.evaluation || !data.grades) {
|
||||||
|
socket.emit("gradeSet", {error: {message: "missing_arguments"}});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (let student in data.grades) {
|
||||||
|
let grade = await models.Grade.findOne({where: {StudentGradeEmail: student, EvaluationId: data.evaluation}});
|
||||||
|
if (!grade) {
|
||||||
|
await models.Grade.create({TeacherGradeEmail: socket.request.session.user.email, StudentGradeEmail: student, EvaluationId: data.evaluation, score: data.grades[student], limit: 20})
|
||||||
|
} else {
|
||||||
|
grade.score = data.grades[student];
|
||||||
|
await grade.save();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
|
@ -28,86 +28,29 @@ block content
|
||||||
|
|
||||||
|
|
||||||
div#marksdetailsbackground.invisible
|
div#marksdetailsbackground.invisible
|
||||||
|
script(src="/javascripts/marks-student.js")
|
||||||
|
|
||||||
if teacher
|
else
|
||||||
div.row
|
form
|
||||||
div(class="col s12 m10 offset-m1 marksgroup")
|
label(for="group") Group:
|
||||||
h3 Select a group
|
select#group(name="group")
|
||||||
div#flexgroup
|
option(selected disabled)
|
||||||
p(onclick="marksformChange(this.getAttribute('id'))") G1S1
|
for group in session.user.Groups
|
||||||
p(onclick="marksformChange(this.getAttribute('id'))") G2S2
|
option(value=group.id)=group.displayName
|
||||||
p(onclick="marksformChange(this.getAttribute('id'))") G3S3
|
label(for="evaluation")
|
||||||
|
select#evaluation(name="evaluation")
|
||||||
|
option(selected disabled)
|
||||||
|
|
||||||
form#marksform
|
form#marksform
|
||||||
table#markstable
|
table#markstable
|
||||||
thead
|
thead
|
||||||
tr
|
tr
|
||||||
th Name
|
th Student
|
||||||
th
|
th.evaluationName
|
||||||
input(type="text" value="DS1")
|
|
||||||
th
|
|
||||||
input(type="text" placeholder="Add a test")
|
|
||||||
tbody
|
tbody
|
||||||
tr
|
tr#studentTemplate(style="display: none")
|
||||||
td Test
|
td.studentName
|
||||||
td
|
td
|
||||||
input(type="number" value="16")
|
input.gradeScore(type="number")
|
||||||
td
|
input#marksubmit(type="submit" value="Save")
|
||||||
input(type="number")
|
script(src="/javascripts/marks-teacher.js")
|
||||||
tr
|
|
||||||
td Keze
|
|
||||||
td
|
|
||||||
input(type="number" value="16")
|
|
||||||
td
|
|
||||||
input(type="number")
|
|
||||||
tr
|
|
||||||
td Kezel
|
|
||||||
td
|
|
||||||
input(type="number" value="16")
|
|
||||||
td
|
|
||||||
input(type="number")
|
|
||||||
tr
|
|
||||||
td Kezel
|
|
||||||
td
|
|
||||||
input(type="number" value="16")
|
|
||||||
td
|
|
||||||
input(type="number")
|
|
||||||
tr
|
|
||||||
td Kezel
|
|
||||||
td
|
|
||||||
input(type="number" value="16")
|
|
||||||
td
|
|
||||||
input(type="number")
|
|
||||||
tr
|
|
||||||
td Kezel
|
|
||||||
td
|
|
||||||
input(type="number" value="16")
|
|
||||||
td
|
|
||||||
input(type="number")
|
|
||||||
tr
|
|
||||||
td Kezel
|
|
||||||
td
|
|
||||||
input(type="number" value="16")
|
|
||||||
td
|
|
||||||
input(type="number")
|
|
||||||
tr
|
|
||||||
td Kezel
|
|
||||||
td
|
|
||||||
input(type="number" value="16")
|
|
||||||
td
|
|
||||||
input(type="number")
|
|
||||||
tr
|
|
||||||
td Kezel
|
|
||||||
td
|
|
||||||
input(type="number" value="16")
|
|
||||||
td
|
|
||||||
input(type="number")
|
|
||||||
tr
|
|
||||||
td Kezel
|
|
||||||
td
|
|
||||||
input(type="number" value="16")
|
|
||||||
td
|
|
||||||
input(type="number")
|
|
||||||
input#marksubmit(type="submit" value="Enregistrer")
|
|
||||||
|
|
||||||
script(src="/javascripts/marks.js")
|
|
||||||
|
|
|
@ -15,8 +15,8 @@ html
|
||||||
meta(name="theme-color" content="#ffffff")
|
meta(name="theme-color" content="#ffffff")
|
||||||
script(src="/socket.io/socket.io.js")
|
script(src="/socket.io/socket.io.js")
|
||||||
body
|
body
|
||||||
- var student = true;
|
- var student = false;
|
||||||
- var teacher = false;
|
- var teacher = true;
|
||||||
- var admin = false;
|
- var admin = false;
|
||||||
div(class="row" id="page")
|
div(class="row" id="page")
|
||||||
block navbar
|
block navbar
|
||||||
|
|
|
@ -9,12 +9,11 @@ block navbar
|
||||||
span.white-text.name=session.user.firstName + " " + session.user.lastName
|
span.white-text.name=session.user.firstName + " " + session.user.lastName
|
||||||
p
|
p
|
||||||
if session.user.Groups[session.user.Groups.length-1]
|
if session.user.Groups[session.user.Groups.length-1]
|
||||||
if session.user.Groups[session.user.Groups.length-1].number.startsWith("G")
|
span.white-text.name=session.user.Groups[session.user.Groups.length-1].displayName
|
||||||
span.white-text.name=session.user.Groups[session.user.Groups.length-1].number + session.user.Groups[session.user.Groups.length-1].Semester.name
|
|
||||||
else
|
|
||||||
span.white-text.name=session.user.Groups[session.user.Groups.length-1].Semester.name + " " + session.user.Groups[session.user.Groups.length-1].number
|
|
||||||
p
|
p
|
||||||
span.white-text.email=session.user.email
|
span.white-text.email=session.user.email
|
||||||
|
a
|
||||||
|
span.white-text Se déconnecter
|
||||||
|
|
||||||
li
|
li
|
||||||
a(href="/" class="waves-effect") Home
|
a(href="/" class="waves-effect") Home
|
||||||
|
@ -36,6 +35,8 @@ block navbar
|
||||||
span.white-text.name=session.user.firstName + " " + session.user.lastName
|
span.white-text.name=session.user.firstName + " " + session.user.lastName
|
||||||
p(href='#email')
|
p(href='#email')
|
||||||
span.white-text.email=session.user.email
|
span.white-text.email=session.user.email
|
||||||
|
a
|
||||||
|
span.white-text Se déconnecter
|
||||||
li
|
li
|
||||||
a(href="/" class="waves-effect") Home
|
a(href="/" class="waves-effect") Home
|
||||||
li
|
li
|
||||||
|
@ -56,6 +57,8 @@ block navbar
|
||||||
span.white-text.name=session.user.firstName + " " + session.user.lastName
|
span.white-text.name=session.user.firstName + " " + session.user.lastName
|
||||||
p(href='#email')
|
p(href='#email')
|
||||||
span.white-text.email=session.user.email
|
span.white-text.email=session.user.email
|
||||||
|
a
|
||||||
|
span.white-text Se déconnecter
|
||||||
li
|
li
|
||||||
a(href="/" class="waves-effect") Home
|
a(href="/" class="waves-effect") Home
|
||||||
li(class="active")
|
li(class="active")
|
||||||
|
|
Reference in a new issue