Skip to content

Commit 6336467

Browse files
committed
feat: add classrooms functionalities (get, add, edit, delete)
1 parent fdb3a92 commit 6336467

32 files changed

+1195
-13
lines changed

public/app/config/channels.js

+7
Original file line numberDiff line numberDiff line change
@@ -52,4 +52,11 @@ module.exports = {
5252
SET_USER_MODE_CHANNEL: 'user:mode:set',
5353
SET_SPACE_AS_FAVORITE_CHANNEL: 'user:set-space-favorite:set',
5454
SET_SPACE_AS_RECENT_CHANNEL: 'user:set-space-recent:set',
55+
GET_CLASSROOMS_CHANNEL: 'teacher-board:classrooms:get',
56+
ADD_CLASSROOM_CHANNEL: 'teacher-board:classroom:add',
57+
DELETE_CLASSROOM_CHANNEL: 'teacher-board:classroom:delete',
58+
SHOW_DELETE_CLASSROOM_PROMPT_CHANNEL: 'prompt:classroom:delete:show',
59+
RESPOND_DELETE_CLASSROOM_PROMPT_CHANNEL: 'prompt:classroom:delete:respond',
60+
EDIT_CLASSROOM_CHANNEL: 'teacher-board:classroom:edit',
61+
GET_CLASSROOM_CHANNEL: 'teacher-board:classroom:get',
5562
};

public/app/config/errors.js

+2
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,13 @@ const ERROR_JSON_CORRUPTED = 'ERROR_JSON_CORRUPTED';
66
const ERROR_SPACE_ALREADY_AVAILABLE = 'ERROR_SPACE_ALREADY_AVAILABLE';
77
const ERROR_DOWNLOADING_FILE = 'ERROR_DOWNLOADING_FILE';
88
const ERROR_GENERAL = 'ERROR_GENERAL';
9+
const ERROR_DUPLICATE_CLASSROOM_NAME = 'ERROR_DUPLICATE_CLASSROOM_NAME';
910

1011
module.exports = {
1112
ERROR_ZIP_CORRUPTED,
1213
ERROR_JSON_CORRUPTED,
1314
ERROR_SPACE_ALREADY_AVAILABLE,
1415
ERROR_DOWNLOADING_FILE,
1516
ERROR_GENERAL,
17+
ERROR_DUPLICATE_CLASSROOM_NAME,
1618
};

public/app/config/messages.js

+24
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,22 @@ const ERROR_SETTING_SPACE_AS_RECENT =
6666
const ERROR_STUDENT_LOAD_OUT_OF_DATE_SPACE_MESSAGE =
6767
'The space contained in this file is out of date. Ask your teacher for more information.';
6868
const ERROR_STUDENT_FORBIDDEN_MESSAGE = 'Students cannot access this page';
69+
const ERROR_ADDING_CLASSROOM_MESSAGE =
70+
'There was an error adding the classroom';
71+
const ERROR_DUPLICATE_CLASSROOM_NAME_MESSAGE =
72+
'This classroom name already exists';
73+
const SUCCESS_ADDING_CLASSROOM_MESSAGE =
74+
'The classroom was successfully created';
75+
const SUCCESS_DELETING_CLASSROOM_MESSAGE =
76+
'The classroom was successfully deleted';
77+
const ERROR_DELETING_CLASSROOM_MESSAGE =
78+
'There was an error deleting this classroom';
79+
const ERROR_EDITING_CLASSROOM_MESSAGE =
80+
'There was an error editing this classroom';
81+
const SUCCESS_EDITING_CLASSROOM_MESSAGE =
82+
'The classroom was successfully edited';
83+
const ERROR_GETTING_CLASSROOM_MESSAGE =
84+
'There was an error getting the classroom';
6985

7086
module.exports = {
7187
ERROR_GETTING_DEVELOPER_MODE,
@@ -116,4 +132,12 @@ module.exports = {
116132
ERROR_SETTING_SPACE_AS_RECENT,
117133
ERROR_STUDENT_LOAD_OUT_OF_DATE_SPACE_MESSAGE,
118134
ERROR_STUDENT_FORBIDDEN_MESSAGE,
135+
ERROR_ADDING_CLASSROOM_MESSAGE,
136+
ERROR_DUPLICATE_CLASSROOM_NAME_MESSAGE,
137+
SUCCESS_ADDING_CLASSROOM_MESSAGE,
138+
SUCCESS_DELETING_CLASSROOM_MESSAGE,
139+
ERROR_DELETING_CLASSROOM_MESSAGE,
140+
ERROR_EDITING_CLASSROOM_MESSAGE,
141+
SUCCESS_EDITING_CLASSROOM_MESSAGE,
142+
ERROR_GETTING_CLASSROOM_MESSAGE,
119143
};

public/app/db.js

+3
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ const SPACES_COLLECTION = 'spaces';
1212
const ACTIONS_COLLECTION = 'actions';
1313
const USERS_COLLECTION = 'users';
1414
const APP_INSTANCE_RESOURCES_COLLECTION = 'appInstanceResources';
15+
const CLASSROOMS_COLLECTION = 'classrooms';
1516

1617
// bootstrap database
1718
const ensureDatabaseExists = async (dbPath = DATABASE_PATH) => {
@@ -39,6 +40,7 @@ const bootstrapDatabase = (dbPath = DATABASE_PATH) => {
3940
user: { lang: DEFAULT_LANG },
4041
[ACTIONS_COLLECTION]: [],
4142
[APP_INSTANCE_RESOURCES_COLLECTION]: [],
43+
[CLASSROOMS_COLLECTION]: [],
4244
}).write();
4345
return db;
4446
};
@@ -48,6 +50,7 @@ module.exports = {
4850
USERS_COLLECTION,
4951
APP_INSTANCE_RESOURCES_COLLECTION,
5052
ACTIONS_COLLECTION,
53+
CLASSROOMS_COLLECTION,
5154
ensureDatabaseExists,
5255
bootstrapDatabase,
5356
};

public/app/listeners/addClassroom.js

+62
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
const ObjectId = require('bson-objectid');
2+
const { ADD_CLASSROOM_CHANNEL } = require('../config/channels');
3+
const {
4+
ERROR_GENERAL,
5+
ERROR_DUPLICATE_CLASSROOM_NAME,
6+
} = require('../config/errors');
7+
const {
8+
CLASSROOMS_COLLECTION,
9+
SPACES_COLLECTION,
10+
APP_INSTANCE_RESOURCES_COLLECTION,
11+
ACTIONS_COLLECTION,
12+
USERS_COLLECTION,
13+
} = require('../db');
14+
const logger = require('../logger');
15+
16+
const DEFAULT_CLASSROOM = {
17+
[SPACES_COLLECTION]: [],
18+
[APP_INSTANCE_RESOURCES_COLLECTION]: [],
19+
[ACTIONS_COLLECTION]: [],
20+
[USERS_COLLECTION]: [],
21+
};
22+
23+
const addClassroom = (mainWindow, db) => async (event, { name, userId }) => {
24+
logger.debug('adding a classroom');
25+
26+
try {
27+
// check name does not already exists
28+
const found = db
29+
.get(CLASSROOMS_COLLECTION)
30+
.find({ name })
31+
.value();
32+
if (found) {
33+
mainWindow.webContents.send(
34+
ADD_CLASSROOM_CHANNEL,
35+
ERROR_DUPLICATE_CLASSROOM_NAME
36+
);
37+
}
38+
39+
// create new classroom
40+
const id = ObjectId().str;
41+
const now = new Date();
42+
const newClassroom = {
43+
...DEFAULT_CLASSROOM,
44+
id,
45+
name,
46+
createdAt: now,
47+
lastUpdatedAt: now,
48+
teacherId: userId,
49+
};
50+
51+
db.get(CLASSROOMS_COLLECTION)
52+
.push(newClassroom)
53+
.write();
54+
55+
mainWindow.webContents.send(ADD_CLASSROOM_CHANNEL, newClassroom);
56+
} catch (err) {
57+
logger.error(err);
58+
mainWindow.webContents.send(ADD_CLASSROOM_CHANNEL, ERROR_GENERAL);
59+
}
60+
};
61+
62+
module.exports = addClassroom;
+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
const { CLASSROOMS_COLLECTION } = require('../db');
2+
const { DELETE_CLASSROOM_CHANNEL } = require('../config/channels');
3+
const { ERROR_GENERAL } = require('../config/errors');
4+
const logger = require('../logger');
5+
6+
const deleteClassroomAndResources = (db, id) => {
7+
db.get(CLASSROOMS_COLLECTION)
8+
.remove({ id })
9+
.write();
10+
11+
// todo: remove containing spaces
12+
};
13+
14+
const deleteClassroom = (mainWindow, db) => async (event, { id }) => {
15+
logger.debug('deleting classroom');
16+
17+
try {
18+
deleteClassroomAndResources(db, id);
19+
mainWindow.webContents.send(DELETE_CLASSROOM_CHANNEL);
20+
} catch (err) {
21+
logger.error(err);
22+
mainWindow.webContents.send(DELETE_CLASSROOM_CHANNEL, ERROR_GENERAL);
23+
}
24+
};
25+
26+
module.exports = deleteClassroom;

public/app/listeners/editClassroom.js

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
const { EDIT_CLASSROOM_CHANNEL } = require('../config/channels');
2+
const { ERROR_GENERAL } = require('../config/errors');
3+
const { CLASSROOMS_COLLECTION } = require('../db');
4+
const logger = require('../logger');
5+
6+
const editClassroom = (mainWindow, db) => async (event, { name, id }) => {
7+
logger.debug('editing classroom');
8+
9+
try {
10+
const classroom = db.get(CLASSROOMS_COLLECTION).find({ id });
11+
12+
// check classroom exists
13+
const found = classroom.value();
14+
if (!found) {
15+
mainWindow.webContents.send(EDIT_CLASSROOM_CHANNEL, ERROR_GENERAL);
16+
}
17+
18+
// update data
19+
const now = new Date();
20+
classroom.assign({ name, lastUpdatedAt: now }).write();
21+
22+
mainWindow.webContents.send(EDIT_CLASSROOM_CHANNEL);
23+
} catch (err) {
24+
logger.error(err);
25+
mainWindow.webContents.send(EDIT_CLASSROOM_CHANNEL, ERROR_GENERAL);
26+
}
27+
};
28+
29+
module.exports = editClassroom;

public/app/listeners/getClassroom.js

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
const { GET_CLASSROOM_CHANNEL } = require('../config/channels');
2+
const logger = require('../logger');
3+
const { CLASSROOMS_COLLECTION } = require('../db');
4+
5+
const getClassroom = (mainWindow, db) => async (event, { id }) => {
6+
try {
7+
// todo: check teacher can access this classroom
8+
9+
// get classroom from local db
10+
const classroom = db
11+
.get(CLASSROOMS_COLLECTION)
12+
.find({ id })
13+
.value();
14+
mainWindow.webContents.send(GET_CLASSROOM_CHANNEL, classroom);
15+
} catch (err) {
16+
logger.error(err);
17+
mainWindow.webContents.send(GET_CLASSROOM_CHANNEL, null);
18+
}
19+
};
20+
21+
module.exports = getClassroom;

public/app/listeners/getClassrooms.js

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
const { GET_CLASSROOMS_CHANNEL } = require('../config/channels');
2+
const logger = require('../logger');
3+
const { CLASSROOMS_COLLECTION } = require('../db');
4+
const { ERROR_GENERAL } = require('../config/errors');
5+
6+
const getClassrooms = (mainWindow, db) => async () => {
7+
try {
8+
// get handle to spaces collection
9+
const classrooms = db.get(CLASSROOMS_COLLECTION).value();
10+
mainWindow.webContents.send(GET_CLASSROOMS_CHANNEL, classrooms);
11+
} catch (e) {
12+
logger.error(e);
13+
mainWindow.webContents.send(GET_CLASSROOMS_CHANNEL, ERROR_GENERAL);
14+
}
15+
};
16+
17+
module.exports = getClassrooms;

public/app/listeners/index.js

+12
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,12 @@ const patchAppInstanceResource = require('./patchAppInstanceResource');
3535
const getAppInstance = require('./getAppInstance');
3636
const setSpaceAsFavorite = require('./setSpaceAsFavorite');
3737
const setSpaceAsRecent = require('./setSpaceAsRecent');
38+
const addClassroom = require('./addClassroom');
39+
const getClassrooms = require('./getClassrooms');
40+
const deleteClassroom = require('./deleteClassroom');
41+
const editClassroom = require('./editClassroom');
42+
const showDeleteClassroomPrompt = require('./showDeleteClassroomPrompt');
43+
const getClassroom = require('./getClassroom');
3844

3945
module.exports = {
4046
loadSpace,
@@ -73,4 +79,10 @@ module.exports = {
7379
setUserMode,
7480
setSpaceAsFavorite,
7581
setSpaceAsRecent,
82+
addClassroom,
83+
deleteClassroom,
84+
editClassroom,
85+
getClassrooms,
86+
getClassroom,
87+
showDeleteClassroomPrompt,
7688
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// eslint-disable-next-line import/no-extraneous-dependencies
2+
const { dialog } = require('electron');
3+
const {
4+
RESPOND_DELETE_CLASSROOM_PROMPT_CHANNEL,
5+
} = require('../config/channels');
6+
const logger = require('../logger');
7+
8+
const showDeleteClassroomPrompt = mainWindow => () => {
9+
logger.debug('showing delete classroom prompt');
10+
11+
const options = {
12+
type: 'warning',
13+
buttons: ['Cancel', 'Delete'],
14+
defaultId: 0,
15+
cancelId: 0,
16+
message: 'Are you sure you want to delete this classroom?',
17+
};
18+
19+
dialog.showMessageBox(mainWindow, options).then(({ response }) => {
20+
mainWindow.webContents.send(
21+
RESPOND_DELETE_CLASSROOM_PROMPT_CHANNEL,
22+
response
23+
);
24+
});
25+
};
26+
27+
module.exports = showDeleteClassroomPrompt;

public/electron.js

+33
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,12 @@ const {
6060
SET_SPACE_AS_RECENT_CHANNEL,
6161
EXTRACT_FILE_TO_LOAD_SPACE_CHANNEL,
6262
CLEAR_LOAD_SPACE_CHANNEL,
63+
ADD_CLASSROOM_CHANNEL,
64+
GET_CLASSROOMS_CHANNEL,
65+
DELETE_CLASSROOM_CHANNEL,
66+
SHOW_DELETE_CLASSROOM_PROMPT_CHANNEL,
67+
EDIT_CLASSROOM_CHANNEL,
68+
GET_CLASSROOM_CHANNEL,
6369
} = require('./app/config/channels');
6470
const env = require('./env.json');
6571
const {
@@ -98,6 +104,12 @@ const {
98104
setSpaceAsRecent,
99105
clearLoadSpace,
100106
extractFileToLoadSpace,
107+
addClassroom,
108+
getClassrooms,
109+
deleteClassroom,
110+
showDeleteClassroomPrompt,
111+
editClassroom,
112+
getClassroom,
101113
} = require('./app/listeners');
102114
const isMac = require('./app/utils/isMac');
103115

@@ -477,6 +489,27 @@ app.on('ready', async () => {
477489
// called when getting an AppInstance
478490
ipcMain.on(GET_APP_INSTANCE_CHANNEL, getAppInstance(mainWindow, db));
479491

492+
// called when getting classrooms
493+
ipcMain.on(GET_CLASSROOMS_CHANNEL, getClassrooms(mainWindow, db));
494+
495+
// called when getting a classroom
496+
ipcMain.on(GET_CLASSROOM_CHANNEL, getClassroom(mainWindow, db));
497+
498+
// called when adding a classroom
499+
ipcMain.on(ADD_CLASSROOM_CHANNEL, addClassroom(mainWindow, db));
500+
501+
// called when editing a classroom
502+
ipcMain.on(EDIT_CLASSROOM_CHANNEL, editClassroom(mainWindow, db));
503+
504+
// prompt when deleting a classroom
505+
ipcMain.on(
506+
SHOW_DELETE_CLASSROOM_PROMPT_CHANNEL,
507+
showDeleteClassroomPrompt(mainWindow, db)
508+
);
509+
510+
// called when deleting a classroom
511+
ipcMain.on(DELETE_CLASSROOM_CHANNEL, deleteClassroom(mainWindow, db));
512+
480513
// called when getting the database
481514
ipcMain.on(GET_DATABASE_CHANNEL, async () => {
482515
try {

0 commit comments

Comments
 (0)