1
0
Fork 0

Finish teacher marks page

This commit is contained in:
Ethanell 2021-01-20 17:14:33 +01:00
parent 5c2747b149
commit ed34b69b64
15 changed files with 168 additions and 109 deletions

26
app.js
View file

@ -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();
}); });

View file

@ -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;
}; };

View file

@ -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"});
} }
} }

View file

@ -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) {

View 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});
});

View file

@ -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

View file

@ -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));
} }

View file

@ -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
View 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));
}
};

View file

@ -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
View 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();
}
}
}
};

View file

@ -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")

View file

@ -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

View file

@ -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")