Skip to content

Educator version #981

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 80 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
80 commits
Select commit Hold shift + click to select a range
b837745
feat: add supporting entity definitions
saachibm Dec 3, 2023
33e24ca
chore: add migration for education mode entities
sgfost Jan 29, 2024
d2ba905
feat(WIP): set up initial client-side routes for edu-mode
sgfost Feb 5, 2024
fa204bb
feat: add edu mode toggle and separate vue router instance
sgfost Feb 13, 2024
bcab532
feat: add requiresTeacher client-side route guard
sgfost Feb 13, 2024
957a243
WIP: Student login page with game code text field
saachibm Feb 19, 2024
38e3f01
fix: compile error with .ts settings, allow access to lobby
sgfost Feb 19, 2024
9b3ccae
FEAT (WIP): Add display wrapover for player grid
sabrinanel3 Mar 18, 2024
b42f8c3
WIP: re-join game checkbox and password text field
saachibm Mar 11, 2024
6cfe53c
FIX: Classroom Lobby layout & WIP Classroom Navbar
sabrinanel3 Apr 4, 2024
465e84b
feat: add student login with classroom code
sgfost Mar 18, 2024
b43cbdf
Completed student login page/re-login page (correct)
saachibm Mar 27, 2024
1afeef1
feat: set-up routes and added first name, last name, password, and jo…
saachibm Apr 3, 2024
06a951a
feat: add classroom/teacher creation, student login
sgfost Apr 8, 2024
930e877
feat(WIP): edu mode password generation/student confirmation
sgfost Apr 15, 2024
8b2a28a
FIX: tabs on login, teacher start btn in lobby
sabrinanel3 May 28, 2024
aebe223
FEAT (WIP): Set up Teacher Dashboard & temp button in educator nav ba…
sabrinanel3 Jun 7, 2024
0f3d7e6
feat: add/remove classroom buttons, set up tabs, organize student cards
sabrinanel3 Jun 7, 2024
5b75e08
feat: student auth and temporary rejoin code generation
sgfost Jun 10, 2024
7191e9f
test: add educator service test suite
sgfost Jun 11, 2024
a11869c
feat: added code generator for teacher password,
kellytea Jun 12, 2024
8cf50c5
feat: fixed educator test suites and code generator
kellytea Jun 15, 2024
a098db4
fix: add plus sign btn, fix group and class btns and indexes, add stu…
sabrinanel3 Jun 12, 2024
00940e2
feat: add error message for wrong game code, add sidebar expand/colla…
sabrinanel3 Jun 14, 2024
caa19d3
fix: educator mode build and typeorm changes
sgfost Jun 18, 2024
e694871
fix: use sh shebang in build script
sabrinanel3 Jun 18, 2024
c6ae8f8
fix: teacher login and error messages
sabrinanel3 Jun 19, 2024
666a7b8
feat (WIP): add verification for students and handle name setting
sabrinanel3 Jun 24, 2024
8cd12f5
feat (WIP): Set up partitioning algo. for groups
kellytea Jun 24, 2024
cf5d775
fix (WIP): edit student rejoin, set name, and verification functionality
sabrinanel3 Jun 26, 2024
26c4a1a
feat: Fixed teacher dashboard list overflow + added classroom rename …
kellytea Jun 26, 2024
2b49529
fix: rejoin code login
sabrinanel3 Jul 2, 2024
efaa5d6
fix: remove profile editing from edu mode
sgfost Jul 3, 2024
538991c
feat: add classroom lobby game room
sgfost Jul 3, 2024
d338099
fix: leave the classroom lobby when leaving the page
sgfost Jul 3, 2024
65591cd
feat: add new educator routes and suporting services, fix minor UI da…
sabrinanel3 Jul 6, 2024
f2e647e
fix (WIP): set up group and reports containers for classrooms
kellytea Jul 6, 2024
77e05cc
feat: add more educator routes and supporting services
sabrinanel3 Jul 8, 2024
c713de1
fix: update educator routes and services
sabrinanel3 Jul 9, 2024
359e416
fix: login flow visual tweaks and route guarding
sgfost Jul 9, 2024
5113ed2
feat (WIP): teacher dashboard layout
kellytea Jul 10, 2024
4e86a11
fix: add StudentData interface for getting students by classroom, upd…
sabrinanel3 Jul 10, 2024
3903ab9
fix: connect dashboard to server side for add, delete, and update cla…
sabrinanel3 Jul 16, 2024
7c849f5
feat: reports container + additional UI fixes
kellytea Jul 15, 2024
02c8f3e
fix: (WIP) refresh issues for rename and delete classroom
sabrinanel3 Jul 17, 2024
d3acd24
feat: start games button for educator
sgfost Jul 16, 2024
dd40a11
fix: classroom crud operations
sgfost Jul 18, 2024
1171501
chore: add educator setup script
sgfost Jul 19, 2024
a5d9105
fix: add classroom error handling and modal conditions
sabrinanel3 Jul 19, 2024
ebf1ff3
fix (WIP): filtering active rooms by classroomId, chat monitoring in …
kellytea Jul 19, 2024
4ca2d78
feat: (WIP) completed games route & services
sabrinanel3 Jul 23, 2024
d9bb8aa
fix: implement fetching active games
kellytea Jul 23, 2024
eeaaa23
fix: refactor dashboard, fix lobby and completed games routes
sabrinanel3 Jul 27, 2024
dfad40f
fix: refactor dashboard, clean up educator routes + services
kellytea Jul 30, 2024
057ac7b
fix: add logging for startGames and remove games tab on dashboard
sabrinanel3 Jul 31, 2024
92215b2
fix: refactoring dashboard by tabs + UI fixes
kellytea Aug 7, 2024
30cd734
fix: fetching selectedClassroom data
kellytea Aug 16, 2024
8bf7af9
fix: cleanup request.ts, fix query params, fix server lint complaints
sabrinanel3 Aug 16, 2024
34a68b4
fix (WIP): request & service promises
kellytea Aug 20, 2024
199c2ed
fix: student/teacher roles and cleanup
sgfost Aug 21, 2024
f5b35a4
test: force delete classroom
sgfost Aug 21, 2024
a159781
fix: set client accepted game invitation to avoid delay
sgfost Sep 3, 2024
56d9e7f
feat(WIP): include round introduction in game round snapshot
sgfost Sep 3, 2024
b59ddbb
feat: add educator privacy page
sabrinanel3 Sep 6, 2024
7111d52
feat (WIP): refactor reports tab, add post-game stats
kellytea Sep 20, 2024
f69a503
feat: set up basic educator mode deployment
alee Oct 16, 2024
b766a01
feat: add Educator tab to Admin page for teacher management
saachibm Oct 3, 2024
f261009
fix (WIP): fix completed games route and use data in reports
sabrinanel3 Nov 2, 2024
d1e8b07
fix: update points by round & reports tables to use game data
sabrinanel3 Jan 25, 2025
1ee9bee
fix: weird spacing for nav components + rerport UI tweaks
kellytea Nov 5, 2024
f93abd1
fix: privacy page showing up in new round summary
kellytea Nov 18, 2024
dedb694
feat: refactored edu mode log-in & added user-friendly info
kellytea Dec 14, 2024
f34b09f
fix: clean educator version and squash migrations
sgfost Feb 18, 2025
3d14ba2
fix: wait for store init before deciding where to go on first route
sgfost Mar 10, 2025
b7decb9
fix: add privacy policy text and stop collecting student names
sgfost Mar 10, 2025
1b0e8a0
fix: use client env accessor to tell vue whether we are in edu mode
sgfost Mar 10, 2025
922f21f
fix: don't show navbar on game view
sgfost Mar 10, 2025
50940d9
feat: connect reports tab charts to backend
sabrinanel3 Mar 13, 2025
38d7a47
fix: cleanup educator code, remove unnecessary comments, check fixme's
sabrinanel3 Mar 13, 2025
496743b
fix: edit text on teacher dashboard
sabrinanel3 Mar 25, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -64,12 +64,12 @@ secrets: keys $(GENERATED_SECRETS)

.PHONY: release-version
release-version: .env
$(ENVREPLACE) SHARED_RELEASE_VERSION $$(git describe --tags --abbrev=1) .env
$(ENVREPLACE) SHARED_RELEASE_VERSION $$(git describe --tags --abbrev=1 --always) .env

docker-compose.yml: base.yml $(DEPLOY_ENVIRONMENT).yml config.mk $(DB_DATA_PATH) $(DATA_DUMP_PATH) $(LOG_DATA_PATH) $(DYNAMIC_SETTINGS_PATH) secrets $(PGPASS_PATH) release-version
case "$(DEPLOY_ENVIRONMENT)" in \
dev|staging|prod) docker compose -f base.yml -f "$(DEPLOY_ENVIRONMENT).yml" config > docker-compose.yml;; \
*) echo "invalid environment. must be either dev, staging or prod" 1>&2; exit 1;; \
dev|staging|prod|learn) docker compose -f base.yml -f "$(DEPLOY_ENVIRONMENT).yml" config > docker-compose.yml;; \
*) echo "invalid environment. must be either dev, staging, prod, or learn" 1>&2; exit 1;; \
esac

.PHONY: build
Expand Down
27 changes: 27 additions & 0 deletions client/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
"bootstrap": "^4.5.3",
"bootstrap-vue": "^2.21.2",
"calendar-link": "^2.0.8",
"chart.js": "^4.4.4",
"colyseus.js": "^0.14.12",
"howler": "^2.2.3",
"jquery": "^3.5.1",
Expand All @@ -32,6 +33,7 @@
"popper.js": "^1.16.0",
"vue": "2.7",
"vue-carousel-3d": "^1.0.1",
"vue-chartjs": "^5.3.1",
"vue-class-component": "^7.2.6",
"vue-gtag": "^1.16.1",
"vue-meta": "^2.4.0",
Expand Down
13 changes: 12 additions & 1 deletion client/src/App.vue
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
<template>
<b-container class="h-100 p-0 m-0 bg" fluid>
<b-row no-gutters class="h-100 w-100">
<Navbar v-if="showNav"></Navbar>
<EducatorNavbar v-if="isEducatorMode && showNav"></EducatorNavbar>
<Navbar v-else-if="showNav"></Navbar>
<router-view :class="bodyClass" :key="topLevelPath"></router-view>
</b-row>
</b-container>
Expand All @@ -11,6 +12,7 @@
import { Component, Vue } from "vue-property-decorator";
import BootstrapVue from "bootstrap-vue";
import Navbar from "@port-of-mars/client/components/global/Navbar.vue";
import EducatorNavbar from "@port-of-mars/client/components/global/EducatorNavbar.vue";
import Footer from "@port-of-mars/client/components/global/Footer.vue";
import {
GAME_PAGE,
Expand All @@ -20,12 +22,15 @@ import {
ABOUT_PAGE,
PRIVACY_PAGE,
PROLIFIC_STUDY_PAGE,
EDUCATOR_PRIVACY_PAGE,
} from "@port-of-mars/shared/routes";
import { isEducatorMode } from "@port-of-mars/client/util";
Vue.use(BootstrapVue);

@Component({
components: {
Navbar,
EducatorNavbar,
Footer,
},
})
Expand All @@ -36,6 +41,7 @@ export default class App extends Vue {
home = { name: HOME_PAGE };
about = { name: ABOUT_PAGE };
privacy = { name: PRIVACY_PAGE };
educatorPrivacy = { name: EDUCATOR_PRIVACY_PAGE };
study = { name: PROLIFIC_STUDY_PAGE };

get topLevelPath() {
Expand All @@ -52,9 +58,14 @@ export default class App extends Vue {
}
}

get isEducatorMode() {
return isEducatorMode();
}

get isScrollable() {
switch (this.$route.name) {
case this.manual.name:
case this.educatorPrivacy.name:
case this.privacy.name:
case this.about.name:
case this.home.name:
Expand Down
110 changes: 110 additions & 0 deletions client/src/api/auth/request.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
import { url } from "@port-of-mars/client/util";
import { TStore } from "@port-of-mars/client/plugins/tstore";
import { AjaxRequest } from "@port-of-mars/client/plugins/ajax";
import {
CLASSROOM_LOBBY_PAGE,
CONSENT_PAGE,
FREE_PLAY_LOBBY_PAGE,
STUDENT_CONFIRM_PAGE,
TEACHER_DASHBOARD_PAGE,
} from "@port-of-mars/shared/routes";
import VueRouter from "vue-router";

export class AuthAPI {
constructor(public store: TStore, public ajax: AjaxRequest, public router: VueRouter) {}

async devLogin(formData: { username: string; password: string }, shouldSkipVerification = true) {
try {
const devLoginUrl = url(`/auth/dev-login?shouldSkipVerification=${shouldSkipVerification}`);
await this.ajax.post(
devLoginUrl,
({ data, status }) => {
if (status === 200) {
this.store.commit("SET_USER", data.user);
// FIXME: not terribly important but we might want to move to the tournament dashboard if isTournamentEnabled
if (data.user.isVerified) this.router.push({ name: FREE_PLAY_LOBBY_PAGE });
else this.router.push({ name: CONSENT_PAGE });
} else {
return data;
}
},
formData
);
} catch (e) {
console.log("Unable to login");
console.log(e);
throw e;
}
}

async studentLogin(classroomAuthToken: string) {
try {
const loginUrl = url("/auth/student-login");
await this.ajax.post(
loginUrl,
({ data, status }) => {
if (status === 200) {
this.store.commit("SET_USER", data.user);
this.router.push({ name: STUDENT_CONFIRM_PAGE });
} else {
throw new Error(data.message || "Login failed");
}
},
{ classroomAuthToken, password: "unused" }
);
} catch (e) {
console.log("Unable to login");
console.log(e);
throw e;
}
}

async studentRejoin(rejoinCode: string) {
try {
const rejoinUrl = url("/auth/student-rejoin");
await this.ajax.post(
rejoinUrl,
({ data, status }) => {
if (status === 200) {
console.log(data);
this.store.commit("SET_USER", data.user);
if (data.user.isVerified) {
console.log("Student verified");
this.router.push({ name: CLASSROOM_LOBBY_PAGE });
} else {
console.log("Student not verified");
this.router.push({ name: STUDENT_CONFIRM_PAGE });
}
} else {
throw new Error(data.message || "Rejoin failed");
}
},
{ rejoinCode, password: "unused" }
);
} catch (e) {
console.log("Unable to rejoin", e);
throw new Error("Invalid rejoin code");
}
}

async teacherLogin(formData: { username: string; password: string }) {
try {
const loginUrl = url("/auth/teacher-login");
await this.ajax.post(
loginUrl,
({ data, status }) => {
if (status === 200) {
this.store.commit("SET_USER", data.user);
this.router.push({ name: TEACHER_DASHBOARD_PAGE });
} else {
throw new Error(data.message || "Login failed");
}
},
formData
);
} catch (e) {
console.log("Unable to login", e);
throw new Error("Invalid username or password");
}
}
}
Loading