Merge branch 'dev' into fix/testdata-niet-meer-correct-opgezet
This commit is contained in:
commit
4cb1469479
27 changed files with 9638 additions and 934 deletions
|
@ -37,6 +37,7 @@
|
||||||
"jwks-rsa": "^3.1.0",
|
"jwks-rsa": "^3.1.0",
|
||||||
"loki-logger-ts": "^1.0.2",
|
"loki-logger-ts": "^1.0.2",
|
||||||
"marked": "^15.0.7",
|
"marked": "^15.0.7",
|
||||||
|
"nanoid": "^5.1.5",
|
||||||
"response-time": "^2.3.3",
|
"response-time": "^2.3.3",
|
||||||
"swagger-ui-express": "^5.0.1",
|
"swagger-ui-express": "^5.0.1",
|
||||||
"uuid": "^11.1.0",
|
"uuid": "^11.1.0",
|
||||||
|
|
|
@ -1,15 +1,17 @@
|
||||||
import { Collection, Entity, ManyToMany, PrimaryKey, Property } from '@mikro-orm/core';
|
import { Collection, Entity, ManyToMany, PrimaryKey, Property } from '@mikro-orm/core';
|
||||||
import { v4 } from 'uuid';
|
|
||||||
import { Teacher } from '../users/teacher.entity.js';
|
import { Teacher } from '../users/teacher.entity.js';
|
||||||
import { Student } from '../users/student.entity.js';
|
import { Student } from '../users/student.entity.js';
|
||||||
import { ClassRepository } from '../../data/classes/class-repository.js';
|
import { ClassRepository } from '../../data/classes/class-repository.js';
|
||||||
|
import { customAlphabet } from 'nanoid';
|
||||||
|
|
||||||
|
const generateClassId = customAlphabet('ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789', 6);
|
||||||
|
|
||||||
@Entity({
|
@Entity({
|
||||||
repository: () => ClassRepository,
|
repository: () => ClassRepository,
|
||||||
})
|
})
|
||||||
export class Class {
|
export class Class {
|
||||||
@PrimaryKey()
|
@PrimaryKey()
|
||||||
classId? = v4();
|
classId? = generateClassId();
|
||||||
|
|
||||||
@Property({ type: 'string' })
|
@Property({ type: 'string' })
|
||||||
displayName!: string;
|
displayName!: string;
|
||||||
|
|
47
backend/tests/controllers/classes.test.ts
Normal file
47
backend/tests/controllers/classes.test.ts
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
import { setupTestApp } from '../setup-tests.js';
|
||||||
|
import { describe, it, expect, beforeAll, beforeEach, vi, Mock } from 'vitest';
|
||||||
|
import { Request, Response } from 'express';
|
||||||
|
import { createClassHandler, deleteClassHandler } from '../../src/controllers/classes';
|
||||||
|
|
||||||
|
describe('Class controllers', () => {
|
||||||
|
let req: Partial<Request>;
|
||||||
|
let res: Partial<Response>;
|
||||||
|
|
||||||
|
let jsonMock: Mock;
|
||||||
|
let statusMock: Mock;
|
||||||
|
|
||||||
|
beforeAll(async () => {
|
||||||
|
await setupTestApp();
|
||||||
|
});
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
jsonMock = vi.fn();
|
||||||
|
statusMock = vi.fn().mockReturnThis();
|
||||||
|
|
||||||
|
res = {
|
||||||
|
json: jsonMock,
|
||||||
|
status: statusMock,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
it('create and delete class', async () => {
|
||||||
|
req = {
|
||||||
|
body: { displayName: 'coole_nieuwe_klas' },
|
||||||
|
};
|
||||||
|
|
||||||
|
await createClassHandler(req as Request, res as Response);
|
||||||
|
|
||||||
|
const result = jsonMock.mock.lastCall?.[0];
|
||||||
|
// Console.log('class', result.class);
|
||||||
|
|
||||||
|
expect(jsonMock).toHaveBeenCalledWith(expect.objectContaining({ class: expect.anything() }));
|
||||||
|
|
||||||
|
req = {
|
||||||
|
params: { id: result.class.id },
|
||||||
|
};
|
||||||
|
|
||||||
|
await deleteClassHandler(req as Request, res as Response);
|
||||||
|
|
||||||
|
expect(jsonMock).toHaveBeenCalledWith(expect.objectContaining({ class: expect.anything() }));
|
||||||
|
});
|
||||||
|
});
|
|
@ -3,6 +3,7 @@ import { ClassRepository } from '../../../src/data/classes/class-repository';
|
||||||
import { setupTestApp } from '../../setup-tests';
|
import { setupTestApp } from '../../setup-tests';
|
||||||
import { getClassRepository } from '../../../src/data/repositories';
|
import { getClassRepository } from '../../../src/data/repositories';
|
||||||
import { getClass01, getClass04 } from '../../test_assets/classes/classes.testdata';
|
import { getClass01, getClass04 } from '../../test_assets/classes/classes.testdata';
|
||||||
|
import { getClass01, getClass04 } from '../../test_assets/classes/classes.testdata';
|
||||||
|
|
||||||
describe('ClassRepository', () => {
|
describe('ClassRepository', () => {
|
||||||
let classRepository: ClassRepository;
|
let classRepository: ClassRepository;
|
||||||
|
|
|
@ -10,7 +10,7 @@ export function makeTestClasses(em: EntityManager): Class[] {
|
||||||
const teacherClass01: Teacher[] = [getTestleerkracht1()];
|
const teacherClass01: Teacher[] = [getTestleerkracht1()];
|
||||||
|
|
||||||
class01 = em.create(Class, {
|
class01 = em.create(Class, {
|
||||||
classId: '8764b861-90a6-42e5-9732-c0d9eb2f55f9',
|
classId: 'X2J9QT', // 8764b861-90a6-42e5-9732-c0d9eb2f55f9
|
||||||
displayName: 'class01',
|
displayName: 'class01',
|
||||||
teachers: teacherClass01,
|
teachers: teacherClass01,
|
||||||
students: studentsClass01,
|
students: studentsClass01,
|
||||||
|
@ -20,7 +20,7 @@ export function makeTestClasses(em: EntityManager): Class[] {
|
||||||
const teacherClass02: Teacher[] = [getLimpBizkit()];
|
const teacherClass02: Teacher[] = [getLimpBizkit()];
|
||||||
|
|
||||||
class02 = em.create(Class, {
|
class02 = em.create(Class, {
|
||||||
classId: '34d484a1-295f-4e9f-bfdc-3e7a23d86a89',
|
classId: '7KLPMA', // 34d484a1-295f-4e9f-bfdc-3e7a23d86a89
|
||||||
displayName: 'class02',
|
displayName: 'class02',
|
||||||
teachers: teacherClass02,
|
teachers: teacherClass02,
|
||||||
students: studentsClass02,
|
students: studentsClass02,
|
||||||
|
@ -30,7 +30,7 @@ export function makeTestClasses(em: EntityManager): Class[] {
|
||||||
const teacherClass03: Teacher[] = [getStaind()];
|
const teacherClass03: Teacher[] = [getStaind()];
|
||||||
|
|
||||||
class03 = em.create(Class, {
|
class03 = em.create(Class, {
|
||||||
classId: '80dcc3e0-1811-4091-9361-42c0eee91cfa',
|
classId: 'R0D3UZ', // 80dcc3e0-1811-4091-9361-42c0eee91cfa
|
||||||
displayName: 'class03',
|
displayName: 'class03',
|
||||||
teachers: teacherClass03,
|
teachers: teacherClass03,
|
||||||
students: studentsClass03,
|
students: studentsClass03,
|
||||||
|
@ -41,14 +41,14 @@ export function makeTestClasses(em: EntityManager): Class[] {
|
||||||
|
|
||||||
// gets deleted in test
|
// gets deleted in test
|
||||||
class04 = em.create(Class, {
|
class04 = em.create(Class, {
|
||||||
classId: '33d03536-83b8-4880-9982-9bbf2f908ddf',
|
classId: 'Q8N5YC', // 33d03536-83b8-4880-9982-9bbf2f908ddf
|
||||||
displayName: 'class04',
|
displayName: 'class04',
|
||||||
teachers: teacherClass04,
|
teachers: teacherClass04,
|
||||||
students: studentsClass04,
|
students: studentsClass04,
|
||||||
});
|
});
|
||||||
|
|
||||||
classWithTestleerlingAndTestleerkracht = em.create(Class, {
|
classWithTestleerlingAndTestleerkracht = em.create(Class, {
|
||||||
classId: 'a75298b5-18aa-471d-8eeb-5d77eb989393',
|
classId: 'ZAV71B', // Was a75298b5-18aa-471d-8eeb-5d77eb989393
|
||||||
displayName: 'Testklasse',
|
displayName: 'Testklasse',
|
||||||
teachers: [getTestleerkracht1()],
|
teachers: [getTestleerkracht1()],
|
||||||
students: [getTestleerling1()],
|
students: [getTestleerling1()],
|
||||||
|
|
54
frontend/src/assets/common.css
Normal file
54
frontend/src/assets/common.css
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
.h1 {
|
||||||
|
color: #0e6942;
|
||||||
|
text-transform: uppercase;
|
||||||
|
font-weight: bolder;
|
||||||
|
font-size: 50px;
|
||||||
|
padding-left: 1%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.empty-message {
|
||||||
|
text-align: center;
|
||||||
|
font-size: 18px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header {
|
||||||
|
font-weight: bold !important;
|
||||||
|
background-color: #0e6942;
|
||||||
|
color: white;
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table thead th:first-child {
|
||||||
|
border-top-left-radius: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table thead th:last-child {
|
||||||
|
border-top-right-radius: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table tbody tr:nth-child(odd) {
|
||||||
|
background-color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table tbody tr:nth-child(even) {
|
||||||
|
background-color: #f6faf2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table td,
|
||||||
|
.table th {
|
||||||
|
border-bottom: 1px solid #0e6942;
|
||||||
|
border-top: 1px solid #0e6942;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table {
|
||||||
|
width: 90%;
|
||||||
|
padding-top: 10px;
|
||||||
|
border-collapse: collapse;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: 850px) {
|
||||||
|
.h1 {
|
||||||
|
text-align: center;
|
||||||
|
padding-left: 0;
|
||||||
|
}
|
||||||
|
}
|
|
@ -57,6 +57,22 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<v-row v-else>
|
<v-row v-else>
|
||||||
|
<v-col
|
||||||
|
cols="12"
|
||||||
|
sm="6"
|
||||||
|
md="4"
|
||||||
|
lg="4"
|
||||||
|
class="d-flex"
|
||||||
|
>
|
||||||
|
<ThemeCard
|
||||||
|
path="/learningPath/search"
|
||||||
|
:is-absolute-path="true"
|
||||||
|
:title="t('searchAllLearningPathsTitle')"
|
||||||
|
:description="t('searchAllLearningPathsDescription')"
|
||||||
|
icon="mdi-magnify"
|
||||||
|
class="fill-height grey-bg-card"
|
||||||
|
/>
|
||||||
|
</v-col>
|
||||||
<v-col
|
<v-col
|
||||||
v-for="card in cards"
|
v-for="card in cards"
|
||||||
:key="card.key"
|
:key="card.key"
|
||||||
|
@ -74,24 +90,13 @@
|
||||||
class="fill-height"
|
class="fill-height"
|
||||||
/>
|
/>
|
||||||
</v-col>
|
</v-col>
|
||||||
<v-col
|
|
||||||
cols="12"
|
|
||||||
sm="6"
|
|
||||||
md="4"
|
|
||||||
lg="4"
|
|
||||||
class="d-flex"
|
|
||||||
>
|
|
||||||
<ThemeCard
|
|
||||||
path="/learningPath/search"
|
|
||||||
:is-absolute-path="true"
|
|
||||||
:title="t('searchAllLearningPathsTitle')"
|
|
||||||
:description="t('searchAllLearningPathsDescription')"
|
|
||||||
icon="mdi-magnify"
|
|
||||||
class="fill-height"
|
|
||||||
/>
|
|
||||||
</v-col>
|
|
||||||
</v-row>
|
</v-row>
|
||||||
</v-container>
|
</v-container>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped></style>
|
<style scoped>
|
||||||
|
.grey-bg-card {
|
||||||
|
background-color: #f6faf2;
|
||||||
|
border: 2px solid #0e6942;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
const _router = useRouter(); // Zonder '_' gaf dit een linter error voor unused variable
|
const _router = useRouter(); // Zonder '_' gaf dit een linter error voor unused variable
|
||||||
|
|
||||||
const name: string = auth.authState.user!.profile.name!;
|
const name: string = auth.authState.user!.profile.name!;
|
||||||
|
const email = auth.authState.user!.profile.email;
|
||||||
const initials: string = name
|
const initials: string = name
|
||||||
.split(" ")
|
.split(" ")
|
||||||
.map((n) => n[0])
|
.map((n) => n[0])
|
||||||
|
@ -90,7 +91,11 @@
|
||||||
<!-- >-->
|
<!-- >-->
|
||||||
<!-- {{ t("discussions") }}-->
|
<!-- {{ t("discussions") }}-->
|
||||||
<!-- </v-btn>-->
|
<!-- </v-btn>-->
|
||||||
<v-menu open-on-hover>
|
</v-toolbar-items>
|
||||||
|
<v-menu
|
||||||
|
open-on-hover
|
||||||
|
open-on-click
|
||||||
|
>
|
||||||
<template v-slot:activator="{ props }">
|
<template v-slot:activator="{ props }">
|
||||||
<v-btn
|
<v-btn
|
||||||
v-bind="props"
|
v-bind="props"
|
||||||
|
@ -114,7 +119,6 @@
|
||||||
</v-list-item>
|
</v-list-item>
|
||||||
</v-list>
|
</v-list>
|
||||||
</v-menu>
|
</v-menu>
|
||||||
</v-toolbar-items>
|
|
||||||
<v-spacer></v-spacer>
|
<v-spacer></v-spacer>
|
||||||
<v-dialog max-width="500">
|
<v-dialog max-width="500">
|
||||||
<template v-slot:activator="{ props: activatorProps }">
|
<template v-slot:activator="{ props: activatorProps }">
|
||||||
|
@ -158,12 +162,43 @@
|
||||||
</v-card>
|
</v-card>
|
||||||
</template>
|
</template>
|
||||||
</v-dialog>
|
</v-dialog>
|
||||||
<v-avatar
|
<v-menu min-width="200px">
|
||||||
size="large"
|
<template v-slot:activator="{ props }">
|
||||||
color="#0e6942"
|
<v-btn
|
||||||
class="user-button"
|
icon
|
||||||
>{{ initials }}</v-avatar
|
v-bind="props"
|
||||||
>
|
>
|
||||||
|
<v-avatar
|
||||||
|
color="#0e6942"
|
||||||
|
size="large"
|
||||||
|
class="user-button"
|
||||||
|
>
|
||||||
|
<span>{{ initials }}</span>
|
||||||
|
</v-avatar>
|
||||||
|
</v-btn>
|
||||||
|
</template>
|
||||||
|
<v-card>
|
||||||
|
<v-card-text>
|
||||||
|
<div class="mx-auto text-center">
|
||||||
|
<v-avatar color="#0e6942">
|
||||||
|
<span class="text-h5">{{ initials }}</span>
|
||||||
|
</v-avatar>
|
||||||
|
<h3>{{ name }}</h3>
|
||||||
|
<p class="text-caption mt-1">{{ email }}</p>
|
||||||
|
<v-divider class="my-3"></v-divider>
|
||||||
|
<v-btn
|
||||||
|
variant="text"
|
||||||
|
rounded
|
||||||
|
append-icon="mdi-logout"
|
||||||
|
@click="performLogout"
|
||||||
|
to="/login"
|
||||||
|
>{{ t("logout") }}</v-btn
|
||||||
|
>
|
||||||
|
<v-divider class="my-3"></v-divider>
|
||||||
|
</div>
|
||||||
|
</v-card-text>
|
||||||
|
</v-card>
|
||||||
|
</v-menu>
|
||||||
</v-app-bar>
|
</v-app-bar>
|
||||||
<v-navigation-drawer
|
<v-navigation-drawer
|
||||||
v-model="drawer"
|
v-model="drawer"
|
||||||
|
@ -248,6 +283,12 @@
|
||||||
text-transform: none;
|
text-transform: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.translate-button {
|
||||||
|
z-index: 1;
|
||||||
|
position: relative;
|
||||||
|
margin-left: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
@media (max-width: 700px) {
|
@media (max-width: 700px) {
|
||||||
.menu {
|
.menu {
|
||||||
display: none;
|
display: none;
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
"JoinClassExplanation": "Geben Sie den Code ein, den Ihnen die Lehrkraft mitgeteilt hat, um der Klasse beizutreten.",
|
"JoinClassExplanation": "Geben Sie den Code ein, den Ihnen die Lehrkraft mitgeteilt hat, um der Klasse beizutreten.",
|
||||||
"invalidFormat": "Ungültiges Format",
|
"invalidFormat": "Ungültiges Format",
|
||||||
"submitCode": "senden",
|
"submitCode": "senden",
|
||||||
|
"submit": "senden",
|
||||||
"members": "Mitglieder",
|
"members": "Mitglieder",
|
||||||
"themes": "Themen",
|
"themes": "Themen",
|
||||||
"choose-theme": "Wählen Sie ein Thema",
|
"choose-theme": "Wählen Sie ein Thema",
|
||||||
|
@ -68,10 +69,10 @@
|
||||||
"pick-class": "Wählen Sie eine klasse",
|
"pick-class": "Wählen Sie eine klasse",
|
||||||
"choose-students": "Studenten auswählen",
|
"choose-students": "Studenten auswählen",
|
||||||
"create-group": "Gruppe erstellen",
|
"create-group": "Gruppe erstellen",
|
||||||
"class": "klasse",
|
"class": "Klasse",
|
||||||
"delete": "löschen",
|
"delete": "löschen",
|
||||||
"view-assignment": "Auftrag anzeigen",
|
"view-assignment": "Auftrag anzeigen",
|
||||||
"code": "code",
|
"code": "Code",
|
||||||
"invitations": "Einladungen",
|
"invitations": "Einladungen",
|
||||||
"createClass": "Klasse erstellen",
|
"createClass": "Klasse erstellen",
|
||||||
"createClassInstructions": "Geben Sie einen Namen für Ihre Klasse ein und klicken Sie auf „Erstellen“. Es erscheint ein Fenster mit einem Code, den Sie kopieren können. Geben Sie diesen Code an Ihre Schüler weiter und sie können Ihrer Klasse beitreten.",
|
"createClassInstructions": "Geben Sie einen Namen für Ihre Klasse ein und klicken Sie auf „Erstellen“. Es erscheint ein Fenster mit einem Code, den Sie kopieren können. Geben Sie diesen Code an Ihre Schüler weiter und sie können Ihrer Klasse beitreten.",
|
||||||
|
@ -83,7 +84,7 @@
|
||||||
"onlyUse": "nur Buchstaben, Zahlen, Bindestriche (-) und Unterstriche (_) verwenden",
|
"onlyUse": "nur Buchstaben, Zahlen, Bindestriche (-) und Unterstriche (_) verwenden",
|
||||||
"close": "schließen",
|
"close": "schließen",
|
||||||
"copied": "kopiert!",
|
"copied": "kopiert!",
|
||||||
"accept": "akzeptieren",
|
"accept": "Akzeptieren",
|
||||||
"deny": "ablehnen",
|
"deny": "ablehnen",
|
||||||
"sent": "sent",
|
"sent": "sent",
|
||||||
"failed": "fehlgeschlagen",
|
"failed": "fehlgeschlagen",
|
||||||
|
@ -110,7 +111,7 @@
|
||||||
"remove": "entfernen",
|
"remove": "entfernen",
|
||||||
"students": "Studenten",
|
"students": "Studenten",
|
||||||
"classJoinRequests": "Beitrittsanfragen",
|
"classJoinRequests": "Beitrittsanfragen",
|
||||||
"reject": "ablehnen",
|
"reject": "Ablehnen",
|
||||||
"areusure": "Sind Sie sicher?",
|
"areusure": "Sind Sie sicher?",
|
||||||
"yes": "ja",
|
"yes": "ja",
|
||||||
"teachers": "Lehrer",
|
"teachers": "Lehrer",
|
||||||
|
@ -121,5 +122,16 @@
|
||||||
"invite": "einladen",
|
"invite": "einladen",
|
||||||
"assignmentIndicator": "AUFGABE",
|
"assignmentIndicator": "AUFGABE",
|
||||||
"searchAllLearningPathsTitle": "Alle Lernpfade durchsuchen",
|
"searchAllLearningPathsTitle": "Alle Lernpfade durchsuchen",
|
||||||
"searchAllLearningPathsDescription": "Nicht gefunden, was Sie gesucht haben? Klicken Sie hier, um unsere gesamte Lernpfad-Datenbank zu durchsuchen."
|
"searchAllLearningPathsDescription": "Nicht gefunden, was Sie gesucht haben? Klicken Sie hier, um unsere gesamte Lernpfad-Datenbank zu durchsuchen.",
|
||||||
|
"no-students-found": "Diese Klasse hat keine Schüler.",
|
||||||
|
"no-invitations-found": "Sie haben keine ausstehenden Einladungen.",
|
||||||
|
"no-join-requests-found": "Es gibt keine ausstehenden Beitrittsanfragen für diese Klasse.",
|
||||||
|
"no-classes-found": "Sie sind noch keinem Kurs beigetreten.",
|
||||||
|
"classCreated": "Klasse erstellt!",
|
||||||
|
"success": "Erfolg",
|
||||||
|
"submitted": "eingereicht",
|
||||||
|
"see-submission": "Einsendung anzeigen",
|
||||||
|
"view-submissions": "Einsendungen anzeigen",
|
||||||
|
"valid-username": "Bitte geben Sie einen gültigen Benutzernamen ein",
|
||||||
|
"creationFailed": "Erstellung fehlgeschlagen, bitte versuchen Sie es erneut"
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,6 +33,7 @@
|
||||||
"JoinClassExplanation": "Enter the code the teacher has given you to join the class.",
|
"JoinClassExplanation": "Enter the code the teacher has given you to join the class.",
|
||||||
"invalidFormat": "Invalid format.",
|
"invalidFormat": "Invalid format.",
|
||||||
"submitCode": "submit",
|
"submitCode": "submit",
|
||||||
|
"submit": "submit",
|
||||||
"members": "Members",
|
"members": "Members",
|
||||||
"themes": "Themes",
|
"themes": "Themes",
|
||||||
"choose-theme": "Select a theme",
|
"choose-theme": "Select a theme",
|
||||||
|
@ -68,21 +69,21 @@
|
||||||
"pick-class": "Pick a class",
|
"pick-class": "Pick a class",
|
||||||
"choose-students": "Select students",
|
"choose-students": "Select students",
|
||||||
"create-group": "Create group",
|
"create-group": "Create group",
|
||||||
"class": "class",
|
"class": "Class",
|
||||||
"delete": "delete",
|
"delete": "delete",
|
||||||
"view-assignment": "View assignment",
|
"view-assignment": "View assignment",
|
||||||
"code": "code",
|
"code": "Code",
|
||||||
"invitations": "invitations",
|
"invitations": "Invitations",
|
||||||
"createClass": "create class",
|
"createClass": "Create class",
|
||||||
"classname": "classname",
|
"classname": "classname",
|
||||||
"EnterNameOfClass": "Enter a classname.",
|
"EnterNameOfClass": "Enter a classname.",
|
||||||
"create": "create",
|
"create": "create",
|
||||||
"sender": "sender",
|
"sender": "Sender",
|
||||||
"nameIsMandatory": "classname is mandatory",
|
"nameIsMandatory": "classname is mandatory",
|
||||||
"onlyUse": "only use letters, numbers, dashes (-) and underscores (_)",
|
"onlyUse": "only use letters, numbers, dashes (-) and underscores (_)",
|
||||||
"close": "close",
|
"close": "close",
|
||||||
"copied": "copied!",
|
"copied": "copied!",
|
||||||
"accept": "accept",
|
"accept": "Accept",
|
||||||
"deny": "deny",
|
"deny": "deny",
|
||||||
"createClassInstructions": "Enter a name for your class and click on create. A window will appear with a code that you can copy. Give this code to your students and they will be able to join.",
|
"createClassInstructions": "Enter a name for your class and click on create. A window will appear with a code that you can copy. Give this code to your students and they will be able to join.",
|
||||||
"sent": "sent",
|
"sent": "sent",
|
||||||
|
@ -108,12 +109,12 @@
|
||||||
"progress": "Progress",
|
"progress": "Progress",
|
||||||
"created": "created",
|
"created": "created",
|
||||||
"remove": "remove",
|
"remove": "remove",
|
||||||
"students": "students",
|
"students": "Students",
|
||||||
"classJoinRequests": "join requests",
|
"classJoinRequests": "Join requests",
|
||||||
"reject": "reject",
|
"reject": "Reject",
|
||||||
"areusure": "Are you sure?",
|
"areusure": "Are you sure?",
|
||||||
"yes": "yes",
|
"yes": "yes",
|
||||||
"teachers": "teachers",
|
"teachers": "Teachers",
|
||||||
"accepted": "accepted",
|
"accepted": "accepted",
|
||||||
"rejected": "rejected",
|
"rejected": "rejected",
|
||||||
"enterUsername": "enter the username of the teacher you would like to invite",
|
"enterUsername": "enter the username of the teacher you would like to invite",
|
||||||
|
@ -121,5 +122,16 @@
|
||||||
"invite": "invite",
|
"invite": "invite",
|
||||||
"assignmentIndicator": "ASSIGNMENT",
|
"assignmentIndicator": "ASSIGNMENT",
|
||||||
"searchAllLearningPathsTitle": "Search all learning paths",
|
"searchAllLearningPathsTitle": "Search all learning paths",
|
||||||
"searchAllLearningPathsDescription": "You didn't find what you were looking for? Click here to search our whole database of available learning paths."
|
"searchAllLearningPathsDescription": "You didn't find what you were looking for? Click here to search our whole database of available learning paths.",
|
||||||
|
"no-students-found": "This class has no students.",
|
||||||
|
"no-invitations-found": "You have no pending invitations.",
|
||||||
|
"no-join-requests-found": "There are no pending join requests for this class.",
|
||||||
|
"no-classes-found": "You are not yet part of a class.",
|
||||||
|
"classCreated": "class created!",
|
||||||
|
"success": "success",
|
||||||
|
"submitted": "submitted",
|
||||||
|
"see-submission": "view submission",
|
||||||
|
"view-submissions": "view submissions",
|
||||||
|
"valid-username": "please enter a valid username",
|
||||||
|
"creationFailed": "creation failed, please try again"
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,6 +33,7 @@
|
||||||
"JoinClassExplanation": "Entrez le code que l'enseignant vous a donné pour rejoindre la classe.",
|
"JoinClassExplanation": "Entrez le code que l'enseignant vous a donné pour rejoindre la classe.",
|
||||||
"invalidFormat": "Format non valide.",
|
"invalidFormat": "Format non valide.",
|
||||||
"submitCode": "envoyer",
|
"submitCode": "envoyer",
|
||||||
|
"submit": "envoyer",
|
||||||
"members": "Membres",
|
"members": "Membres",
|
||||||
"themes": "Thèmes",
|
"themes": "Thèmes",
|
||||||
"choose-theme": "Choisis un thème",
|
"choose-theme": "Choisis un thème",
|
||||||
|
@ -68,22 +69,22 @@
|
||||||
"pick-class": "Choisissez une classe",
|
"pick-class": "Choisissez une classe",
|
||||||
"choose-students": "Sélectionnez des élèves",
|
"choose-students": "Sélectionnez des élèves",
|
||||||
"create-group": "Créer un groupe",
|
"create-group": "Créer un groupe",
|
||||||
"class": "classe",
|
"class": "Classe",
|
||||||
"delete": "supprimer",
|
"delete": "supprimer",
|
||||||
"view-assignment": "Voir le travail",
|
"view-assignment": "Voir le travail",
|
||||||
"code": "code",
|
"code": "Code",
|
||||||
"invitations": "invitations",
|
"invitations": "Invitations",
|
||||||
"createClass": "créer une classe",
|
"createClass": "Créer une classe",
|
||||||
"createClassInstructions": "Entrez un nom pour votre classe et cliquez sur créer. Une fenêtre apparaît avec un code que vous pouvez copier. Donnez ce code à vos élèves et ils pourront rejoindre votre classe.",
|
"createClassInstructions": "Entrez un nom pour votre classe et cliquez sur créer. Une fenêtre apparaît avec un code que vous pouvez copier. Donnez ce code à vos élèves et ils pourront rejoindre votre classe.",
|
||||||
"classname": "nom de classe",
|
"classname": "nom de classe",
|
||||||
"EnterNameOfClass": "saisir un nom de classe.",
|
"EnterNameOfClass": "saisir un nom de classe.",
|
||||||
"create": "créer",
|
"create": "créer",
|
||||||
"sender": "expéditeur",
|
"sender": "Expéditeur",
|
||||||
"nameIsMandatory": "le nom de classe est obligatoire",
|
"nameIsMandatory": "le nom de classe est obligatoire",
|
||||||
"onlyUse": "n'utiliser que des lettres, des chiffres, des tirets (-) et des traits de soulignement (_)",
|
"onlyUse": "n'utiliser que des lettres, des chiffres, des tirets (-) et des traits de soulignement (_)",
|
||||||
"close": "fermer",
|
"close": "fermer",
|
||||||
"copied": "copié!",
|
"copied": "copié!",
|
||||||
"accept": "accepter",
|
"accept": "Accepter",
|
||||||
"deny": "refuser",
|
"deny": "refuser",
|
||||||
"sent": "envoyé",
|
"sent": "envoyé",
|
||||||
"failed": "échoué",
|
"failed": "échoué",
|
||||||
|
@ -108,12 +109,13 @@
|
||||||
"submission": "Soumission",
|
"submission": "Soumission",
|
||||||
"progress": "Progrès",
|
"progress": "Progrès",
|
||||||
"remove": "supprimer",
|
"remove": "supprimer",
|
||||||
"students": "étudiants",
|
"students": "Étudiants",
|
||||||
"classJoinRequests": "demandes d'adhésion",
|
|
||||||
"reject": "rejeter",
|
"classJoinRequests": "Demandes d'adhésion",
|
||||||
|
"reject": "Rejeter",
|
||||||
"areusure": "Êtes-vous sûr?",
|
"areusure": "Êtes-vous sûr?",
|
||||||
"yes": "oui",
|
"yes": "oui",
|
||||||
"teachers": "enseignants",
|
"teachers": "Enseignants",
|
||||||
"accepted": "acceptée",
|
"accepted": "acceptée",
|
||||||
"rejected": "rejetée",
|
"rejected": "rejetée",
|
||||||
"enterUsername": "entrez le nom d'utilisateur de l'enseignant que vous souhaitez inviter",
|
"enterUsername": "entrez le nom d'utilisateur de l'enseignant que vous souhaitez inviter",
|
||||||
|
@ -121,5 +123,16 @@
|
||||||
"invite": "inviter",
|
"invite": "inviter",
|
||||||
"assignmentIndicator": "DEVOIR",
|
"assignmentIndicator": "DEVOIR",
|
||||||
"searchAllLearningPathsTitle": "Rechercher tous les parcours d'apprentissage",
|
"searchAllLearningPathsTitle": "Rechercher tous les parcours d'apprentissage",
|
||||||
"searchAllLearningPathsDescription": "Vous n'avez pas trouvé ce que vous cherchiez ? Cliquez ici pour rechercher dans toute notre base de données de parcours d'apprentissage disponibles."
|
"searchAllLearningPathsDescription": "Vous n'avez pas trouvé ce que vous cherchiez ? Cliquez ici pour rechercher dans toute notre base de données de parcours d'apprentissage disponibles.",
|
||||||
|
"no-students-found": "Cette classe n'a pas d'élèves.",
|
||||||
|
"no-invitations-found": "Vous n'avez aucune invitation en attente.",
|
||||||
|
"no-join-requests-found": "Il n'y a aucune demande d'adhésion en attente pour cette classe.",
|
||||||
|
"no-classes-found": "Vous ne faites pas encore partie d'une classe.",
|
||||||
|
"classCreated": "Classe créée !",
|
||||||
|
"success": "succès",
|
||||||
|
"submitted": "soumis",
|
||||||
|
"see-submission": "voir la soumission",
|
||||||
|
"view-submissions": "voir les soumissions",
|
||||||
|
"valid-username": "veuillez entrer un nom d'utilisateur valide",
|
||||||
|
"creationFailed": "échec de la création, veuillez réessayer"
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,6 +33,7 @@
|
||||||
"JoinClassExplanation": "Voer de code in die je van de docent hebt gekregen om lid te worden van de klas.",
|
"JoinClassExplanation": "Voer de code in die je van de docent hebt gekregen om lid te worden van de klas.",
|
||||||
"invalidFormat": "Ongeldig formaat.",
|
"invalidFormat": "Ongeldig formaat.",
|
||||||
"submitCode": "verzenden",
|
"submitCode": "verzenden",
|
||||||
|
"submit": "verzenden",
|
||||||
"members": "Leden",
|
"members": "Leden",
|
||||||
"themes": "Lesthema's",
|
"themes": "Lesthema's",
|
||||||
"choose-theme": "Kies een thema",
|
"choose-theme": "Kies een thema",
|
||||||
|
@ -68,22 +69,22 @@
|
||||||
"pick-class": "Kies een klas",
|
"pick-class": "Kies een klas",
|
||||||
"choose-students": "Studenten selecteren",
|
"choose-students": "Studenten selecteren",
|
||||||
"create-group": "Groep aanmaken",
|
"create-group": "Groep aanmaken",
|
||||||
"class": "klas",
|
"class": "Klas",
|
||||||
"delete": "verwijderen",
|
"delete": "verwijderen",
|
||||||
"view-assignment": "Opdracht bekijken",
|
"view-assignment": "Opdracht bekijken",
|
||||||
"code": "code",
|
"code": "Code",
|
||||||
"invitations": "uitnodigingen",
|
"invitations": "Uitnodigingen",
|
||||||
"createClass": "klas aanmaken",
|
"createClass": "Klas aanmaken",
|
||||||
"createClassInstructions": "Voer een naam in voor je klas en klik op create. Er verschijnt een venster met een code die je kunt kopiëren. Geef deze code aan je leerlingen en ze kunnen deelnemen aan je klas.",
|
"createClassInstructions": "Voer een naam in voor je klas en klik op create. Er verschijnt een venster met een code die je kunt kopiëren. Geef deze code aan je leerlingen en ze kunnen deelnemen aan je klas.",
|
||||||
"classname": "klasnaam",
|
"classname": "klasnaam",
|
||||||
"EnterNameOfClass": "Geef een klasnaam op.",
|
"EnterNameOfClass": "Geef een klasnaam op.",
|
||||||
"create": "aanmaken",
|
"create": "aanmaken",
|
||||||
"sender": "afzender",
|
"sender": "Afzender",
|
||||||
"nameIsMandatory": "klasnaam is verplicht",
|
"nameIsMandatory": "klasnaam is verplicht",
|
||||||
"onlyUse": "gebruik enkel letters, cijfers, dashes (-) en underscores (_)",
|
"onlyUse": "gebruik enkel letters, cijfers, dashes (-) en underscores (_)",
|
||||||
"close": "sluiten",
|
"close": "sluiten",
|
||||||
"copied": "gekopieerd!",
|
"copied": "gekopieerd!",
|
||||||
"accept": "accepteren",
|
"accept": "Accepteren",
|
||||||
"deny": "weigeren",
|
"deny": "weigeren",
|
||||||
"sent": "verzonden",
|
"sent": "verzonden",
|
||||||
"failed": "mislukt",
|
"failed": "mislukt",
|
||||||
|
@ -108,12 +109,12 @@
|
||||||
"submission": "Indiening",
|
"submission": "Indiening",
|
||||||
"progress": "Vooruitgang",
|
"progress": "Vooruitgang",
|
||||||
"remove": "verwijder",
|
"remove": "verwijder",
|
||||||
"students": "studenten",
|
"students": "Studenten",
|
||||||
"classJoinRequests": "deelname verzoeken",
|
"classJoinRequests": "Deelname verzoeken",
|
||||||
"reject": "weiger",
|
"reject": "Weiger",
|
||||||
"areusure": "Bent u zeker?",
|
"areusure": "Bent u zeker?",
|
||||||
"yes": "ja",
|
"yes": "ja",
|
||||||
"teachers": "leerkrachten",
|
"teachers": "Leerkrachten",
|
||||||
"accepted": "geaccepteerd",
|
"accepted": "geaccepteerd",
|
||||||
"rejected": "geweigerd",
|
"rejected": "geweigerd",
|
||||||
"enterUsername": "vul de gebruikersnaam van de leerkracht die je wilt uitnodigen in",
|
"enterUsername": "vul de gebruikersnaam van de leerkracht die je wilt uitnodigen in",
|
||||||
|
@ -121,5 +122,16 @@
|
||||||
"invite": "uitnodigen",
|
"invite": "uitnodigen",
|
||||||
"assignmentIndicator": "OPDRACHT",
|
"assignmentIndicator": "OPDRACHT",
|
||||||
"searchAllLearningPathsTitle": "Alle leerpaden doorzoeken",
|
"searchAllLearningPathsTitle": "Alle leerpaden doorzoeken",
|
||||||
"searchAllLearningPathsDescription": "Niet gevonden waar je naar op zoek was? Klik hier om onze volledige databank van beschikbare leerpaden te doorzoeken."
|
"searchAllLearningPathsDescription": "Niet gevonden waar je naar op zoek was? Klik hier om onze volledige databank van beschikbare leerpaden te doorzoeken.",
|
||||||
|
"no-students-found": "Deze klas heeft geen leerlingen.",
|
||||||
|
"no-invitations-found": "U heeft geen openstaande uitnodigingen.",
|
||||||
|
"no-join-requests-found": "Er zijn geen openstaande verzoeken om lid te worden van deze klas.",
|
||||||
|
"no-classes-found": "U maakt nog geen deel uit van een klas.",
|
||||||
|
"classCreated": "Klas aangemaakt!",
|
||||||
|
"success": "succes",
|
||||||
|
"submitted": "ingediend",
|
||||||
|
"see-submission": "inzending bekijken",
|
||||||
|
"view-submissions": "inzendingen bekijken",
|
||||||
|
"valid-username": "voer een geldige gebruikersnaam in",
|
||||||
|
"creationFailed": "aanmaak mislukt, probeer het opnieuw"
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,7 +28,7 @@
|
||||||
alt="Dwengo logo"
|
alt="Dwengo logo"
|
||||||
style="align-self: center"
|
style="align-self: center"
|
||||||
/>
|
/>
|
||||||
<h1>{{ t("homeTitle") }}</h1>
|
<h1 class="h1">{{ t("homeTitle") }}</h1>
|
||||||
<p class="info">
|
<p class="info">
|
||||||
{{ t("homeIntroduction1") }}
|
{{ t("homeIntroduction1") }}
|
||||||
</p>
|
</p>
|
||||||
|
@ -84,7 +84,10 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="container_right">
|
<div class="container_right">
|
||||||
<v-menu open-on-hover>
|
<v-menu
|
||||||
|
open-on-hover
|
||||||
|
open-on-click
|
||||||
|
>
|
||||||
<template v-slot:activator="{ props }">
|
<template v-slot:activator="{ props }">
|
||||||
<v-btn
|
<v-btn
|
||||||
v-bind="props"
|
v-bind="props"
|
||||||
|
|
|
@ -1,6 +1,20 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
import { useRouter } from "vue-router";
|
||||||
import dwengoLogo from "../../../assets/img/dwengo-groen-zwart.svg";
|
import dwengoLogo from "../../../assets/img/dwengo-groen-zwart.svg";
|
||||||
import auth from "@/services/auth/auth-service.ts";
|
import auth from "@/services/auth/auth-service.ts";
|
||||||
|
import { watch } from "vue";
|
||||||
|
|
||||||
|
const router = useRouter();
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => auth.isLoggedIn.value,
|
||||||
|
async (newVal) => {
|
||||||
|
if (newVal) {
|
||||||
|
await router.push("/user");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{ immediate: true },
|
||||||
|
);
|
||||||
|
|
||||||
async function loginAsStudent(): Promise<void> {
|
async function loginAsStudent(): Promise<void> {
|
||||||
await auth.loginAs("student");
|
await auth.loginAs("student");
|
||||||
|
@ -9,10 +23,6 @@
|
||||||
async function loginAsTeacher(): Promise<void> {
|
async function loginAsTeacher(): Promise<void> {
|
||||||
await auth.loginAs("teacher");
|
await auth.loginAs("teacher");
|
||||||
}
|
}
|
||||||
|
|
||||||
async function performLogout(): Promise<void> {
|
|
||||||
await auth.logout();
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
@ -65,13 +75,6 @@
|
||||||
</div>
|
</div>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="auth.isLoggedIn.value">
|
|
||||||
<p>
|
|
||||||
You are currently logged in as {{ auth.authState.user!.profile.name }} ({{ auth.authState.activeRole }})
|
|
||||||
</p>
|
|
||||||
<v-btn @click="performLogout">Logout</v-btn>
|
|
||||||
<v-btn to="/user">home</v-btn>
|
|
||||||
</div>
|
|
||||||
</main>
|
</main>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
|
@ -96,7 +96,7 @@
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="main-container">
|
<div class="main-container">
|
||||||
<h1 class="title">{{ t("new-assignment") }}</h1>
|
<h1 class="h1">{{ t("new-assignment") }}</h1>
|
||||||
<v-card class="form-card">
|
<v-card class="form-card">
|
||||||
<v-form
|
<v-form
|
||||||
ref="form"
|
ref="form"
|
||||||
|
|
|
@ -22,8 +22,7 @@
|
||||||
) => { groupProgressMap: Map<number, number> };
|
) => { groupProgressMap: Map<number, number> };
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const { t, locale } = useI18n();
|
const { t } = useI18n();
|
||||||
const language = ref<Language>(locale.value as Language);
|
|
||||||
const learningPath = ref();
|
const learningPath = ref();
|
||||||
// Get the user's username/id
|
// Get the user's username/id
|
||||||
const username = asyncComputed(async () => {
|
const username = asyncComputed(async () => {
|
||||||
|
@ -38,7 +37,7 @@
|
||||||
|
|
||||||
const lpQueryResult = useGetLearningPathQuery(
|
const lpQueryResult = useGetLearningPathQuery(
|
||||||
computed(() => assignmentQueryResult.data.value?.assignment?.learningPath ?? ""),
|
computed(() => assignmentQueryResult.data.value?.assignment?.learningPath ?? ""),
|
||||||
computed(() => language.value),
|
computed(() => assignmentQueryResult.data.value?.assignment.language as Language),
|
||||||
);
|
);
|
||||||
|
|
||||||
const groupsQueryResult = useGroupsQuery(props.classId, props.assignmentId, true);
|
const groupsQueryResult = useGroupsQuery(props.classId, props.assignmentId, true);
|
||||||
|
@ -100,7 +99,7 @@ language
|
||||||
>
|
>
|
||||||
<v-btn
|
<v-btn
|
||||||
v-if="lpData"
|
v-if="lpData"
|
||||||
:to="`/learningPath/${lpData.hruid}/${language}/${lpData.startNode.learningobjectHruid}?forGroup=${group?.groupNumber}&assignmentNo=${assignmentId}&classId=${classId}`"
|
:to="`/learningPath/${lpData.hruid}/${assignmentQueryResult.data.value?.assignment.language}/${lpData.startNode.learningobjectHruid}?forGroup=${group?.groupNumber}&assignmentNo=${assignmentId}&classId=${classId}`"
|
||||||
variant="tonal"
|
variant="tonal"
|
||||||
color="primary"
|
color="primary"
|
||||||
>
|
>
|
||||||
|
|
|
@ -19,8 +19,7 @@
|
||||||
) => { groupProgressMap: Map<number, number> };
|
) => { groupProgressMap: Map<number, number> };
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const { t, locale } = useI18n();
|
const { t } = useI18n();
|
||||||
const language = computed(() => locale.value);
|
|
||||||
const groups = ref();
|
const groups = ref();
|
||||||
const learningPath = ref();
|
const learningPath = ref();
|
||||||
|
|
||||||
|
@ -29,7 +28,7 @@
|
||||||
// Get learning path object
|
// Get learning path object
|
||||||
const lpQueryResult = useGetLearningPathQuery(
|
const lpQueryResult = useGetLearningPathQuery(
|
||||||
computed(() => assignmentQueryResult.data.value?.assignment?.learningPath ?? ""),
|
computed(() => assignmentQueryResult.data.value?.assignment?.learningPath ?? ""),
|
||||||
computed(() => language.value as Language),
|
computed(() => assignmentQueryResult.data.value?.assignment.language as Language),
|
||||||
);
|
);
|
||||||
|
|
||||||
// Get all the groups withing the assignment
|
// Get all the groups withing the assignment
|
||||||
|
@ -121,7 +120,7 @@ Const {groupProgressMap} = props.useGroupsWithProgress(
|
||||||
>
|
>
|
||||||
<v-btn
|
<v-btn
|
||||||
v-if="lpData"
|
v-if="lpData"
|
||||||
:to="`/learningPath/${lpData.hruid}/${language}/${lpData.startNode.learningobjectHruid}?assignmentNo=${assignmentId}&classId=${classId}`"
|
:to="`/learningPath/${lpData.hruid}/${assignmentQueryResult.data.value?.assignment.language}/${lpData.startNode.learningobjectHruid}?assignmentNo=${assignmentId}&classId=${classId}`"
|
||||||
variant="tonal"
|
variant="tonal"
|
||||||
color="primary"
|
color="primary"
|
||||||
>
|
>
|
||||||
|
@ -203,8 +202,8 @@ Const {groupProgressMap} = props.useGroupsWithProgress(
|
||||||
<v-btn
|
<v-btn
|
||||||
color="primary"
|
color="primary"
|
||||||
@click="dialog = false"
|
@click="dialog = false"
|
||||||
>Close</v-btn
|
>Close
|
||||||
>
|
</v-btn>
|
||||||
</v-card-actions>
|
</v-card-actions>
|
||||||
</v-card>
|
</v-card>
|
||||||
</v-dialog>
|
</v-dialog>
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
import type { ClassDTO } from "@dwengo-1/common/interfaces/class";
|
import type { ClassDTO } from "@dwengo-1/common/interfaces/class";
|
||||||
import { asyncComputed } from "@vueuse/core";
|
import { asyncComputed } from "@vueuse/core";
|
||||||
import { useDeleteAssignmentMutation } from "@/queries/assignments.ts";
|
import { useDeleteAssignmentMutation } from "@/queries/assignments.ts";
|
||||||
|
import "../../assets/common.css";
|
||||||
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
@ -80,7 +81,7 @@
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="assignments-container">
|
<div class="assignments-container">
|
||||||
<h1>{{ t("assignments") }}</h1>
|
<h1 class="h1">{{ t("assignments") }}</h1>
|
||||||
|
|
||||||
<v-btn
|
<v-btn
|
||||||
v-if="isTeacher"
|
v-if="isTeacher"
|
||||||
|
@ -139,7 +140,6 @@
|
||||||
.assignments-container {
|
.assignments-container {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
padding: 2% 4%;
|
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
import { useCreateTeacherInvitationMutation } from "@/queries/teacher-invitations";
|
import { useCreateTeacherInvitationMutation } from "@/queries/teacher-invitations";
|
||||||
import type { TeacherInvitationData } from "@dwengo-1/common/interfaces/teacher-invitation";
|
import type { TeacherInvitationData } from "@dwengo-1/common/interfaces/teacher-invitation";
|
||||||
import { useDisplay } from "vuetify";
|
import { useDisplay } from "vuetify";
|
||||||
|
import "../../assets/common.css";
|
||||||
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
|
||||||
|
@ -112,7 +113,7 @@
|
||||||
|
|
||||||
function sentInvite(): void {
|
function sentInvite(): void {
|
||||||
if (!usernameTeacher.value) {
|
if (!usernameTeacher.value) {
|
||||||
showSnackbar(t("please enter a valid username"), "error");
|
showSnackbar(t("valid-username"), "error");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const data: TeacherInvitationData = {
|
const data: TeacherInvitationData = {
|
||||||
|
@ -186,7 +187,7 @@
|
||||||
v-slot="classResponse: { data: ClassResponse }"
|
v-slot="classResponse: { data: ClassResponse }"
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
<h1 class="title">{{ classResponse.data.class.displayName }}</h1>
|
<h1 class="h1">{{ classResponse.data.class.displayName }}</h1>
|
||||||
<using-query-result
|
<using-query-result
|
||||||
:query-result="getStudents"
|
:query-result="getStudents"
|
||||||
v-slot="studentsResponse: { data: StudentsResponse }"
|
v-slot="studentsResponse: { data: StudentsResponse }"
|
||||||
|
@ -211,19 +212,34 @@
|
||||||
<th class="header"></th>
|
<th class="header"></th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
|
||||||
|
<tbody v-if="studentsResponse.data.students.length">
|
||||||
<tr
|
<tr
|
||||||
v-for="s in studentsResponse.data.students as StudentDTO[]"
|
v-for="s in studentsResponse.data.students as StudentDTO[]"
|
||||||
:key="s.id"
|
:key="s.id"
|
||||||
>
|
>
|
||||||
<td>
|
<td>{{ s.firstName + " " + s.lastName }}</td>
|
||||||
{{ s.firstName + " " + s.lastName }}
|
|
||||||
</td>
|
|
||||||
<td>
|
<td>
|
||||||
<v-btn @click="showPopup(s)">{{ t("remove") }}</v-btn>
|
<v-btn @click="showPopup(s)">{{ t("remove") }}</v-btn>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
|
|
||||||
|
<tbody v-else>
|
||||||
|
<tr>
|
||||||
|
<td
|
||||||
|
colspan="2"
|
||||||
|
class="empty-message"
|
||||||
|
>
|
||||||
|
<v-icon
|
||||||
|
icon="mdi-information-outline"
|
||||||
|
size="small"
|
||||||
|
>
|
||||||
|
</v-icon>
|
||||||
|
{{ t("no-students-found") }}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
</v-table>
|
</v-table>
|
||||||
</v-col>
|
</v-col>
|
||||||
<using-query-result
|
<using-query-result
|
||||||
|
@ -242,7 +258,7 @@
|
||||||
<th class="header">{{ t("accept") + "/" + t("reject") }}</th>
|
<th class="header">{{ t("accept") + "/" + t("reject") }}</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody v-if="joinRequests.data.joinRequests.length">
|
||||||
<tr
|
<tr
|
||||||
v-for="jr in joinRequests.data.joinRequests as ClassJoinRequestDTO[]"
|
v-for="jr in joinRequests.data.joinRequests as ClassJoinRequestDTO[]"
|
||||||
:key="(jr.class, jr.requester, jr.status)"
|
:key="(jr.class, jr.requester, jr.status)"
|
||||||
|
@ -287,6 +303,21 @@
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
|
<tbody v-else>
|
||||||
|
<tr>
|
||||||
|
<td
|
||||||
|
colspan="2"
|
||||||
|
class="empty-message"
|
||||||
|
>
|
||||||
|
<v-icon
|
||||||
|
icon="mdi-information-outline"
|
||||||
|
size="small"
|
||||||
|
>
|
||||||
|
</v-icon>
|
||||||
|
{{ t("no-join-requests-found") }}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
</v-table>
|
</v-table>
|
||||||
</v-col>
|
</v-col>
|
||||||
</using-query-result>
|
</using-query-result>
|
||||||
|
@ -356,49 +387,6 @@
|
||||||
</main>
|
</main>
|
||||||
</template>
|
</template>
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.header {
|
|
||||||
font-weight: bold !important;
|
|
||||||
background-color: #0e6942;
|
|
||||||
color: white;
|
|
||||||
padding: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
table thead th:first-child {
|
|
||||||
border-top-left-radius: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.table thead th:last-child {
|
|
||||||
border-top-right-radius: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.table tbody tr:nth-child(odd) {
|
|
||||||
background-color: white;
|
|
||||||
}
|
|
||||||
|
|
||||||
.table tbody tr:nth-child(even) {
|
|
||||||
background-color: #f6faf2;
|
|
||||||
}
|
|
||||||
|
|
||||||
td,
|
|
||||||
th {
|
|
||||||
border-bottom: 1px solid #0e6942;
|
|
||||||
border-top: 1px solid #0e6942;
|
|
||||||
}
|
|
||||||
|
|
||||||
.table {
|
|
||||||
width: 90%;
|
|
||||||
padding-top: 10px;
|
|
||||||
border-collapse: collapse;
|
|
||||||
}
|
|
||||||
|
|
||||||
h1 {
|
|
||||||
color: #0e6942;
|
|
||||||
text-transform: uppercase;
|
|
||||||
font-weight: bolder;
|
|
||||||
padding-top: 2%;
|
|
||||||
font-size: 50px;
|
|
||||||
}
|
|
||||||
|
|
||||||
h2 {
|
h2 {
|
||||||
color: #0e6942;
|
color: #0e6942;
|
||||||
font-size: 30px;
|
font-size: 30px;
|
||||||
|
@ -407,6 +395,7 @@
|
||||||
.join {
|
.join {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
margin-left: 1%;
|
||||||
gap: 20px;
|
gap: 20px;
|
||||||
margin-top: 50px;
|
margin-top: 50px;
|
||||||
}
|
}
|
||||||
|
@ -416,16 +405,7 @@
|
||||||
text-decoration: underline;
|
text-decoration: underline;
|
||||||
}
|
}
|
||||||
|
|
||||||
main {
|
|
||||||
margin-left: 30px;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media screen and (max-width: 800px) {
|
@media screen and (max-width: 800px) {
|
||||||
h1 {
|
|
||||||
text-align: center;
|
|
||||||
padding-left: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.join {
|
.join {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
import { useClassStudentsQuery, useClassTeachersQuery } from "@/queries/classes";
|
import { useClassStudentsQuery, useClassTeachersQuery } from "@/queries/classes";
|
||||||
import type { StudentsResponse } from "@/controllers/students";
|
import type { StudentsResponse } from "@/controllers/students";
|
||||||
import type { TeachersResponse } from "@/controllers/teachers";
|
import type { TeachersResponse } from "@/controllers/teachers";
|
||||||
|
import "../../assets/common.css";
|
||||||
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
|
||||||
|
@ -135,7 +136,7 @@
|
||||||
></v-empty-state>
|
></v-empty-state>
|
||||||
</div>
|
</div>
|
||||||
<div v-else>
|
<div v-else>
|
||||||
<h1 class="title">{{ t("classes") }}</h1>
|
<h1 class="h1">{{ t("classes") }}</h1>
|
||||||
<using-query-result
|
<using-query-result
|
||||||
:query-result="classesQuery"
|
:query-result="classesQuery"
|
||||||
v-slot="classResponse: { data: ClassesResponse }"
|
v-slot="classResponse: { data: ClassesResponse }"
|
||||||
|
@ -161,7 +162,7 @@
|
||||||
<th class="header">{{ t("members") }}</th>
|
<th class="header">{{ t("members") }}</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody v-if="classResponse.data.classes.length">
|
||||||
<tr
|
<tr
|
||||||
v-for="c in classResponse.data.classes as ClassDTO[]"
|
v-for="c in classResponse.data.classes as ClassDTO[]"
|
||||||
:key="c.id"
|
:key="c.id"
|
||||||
|
@ -181,6 +182,21 @@
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
|
<tbody v-else>
|
||||||
|
<tr>
|
||||||
|
<td
|
||||||
|
colspan="3"
|
||||||
|
class="empty-message"
|
||||||
|
>
|
||||||
|
<v-icon
|
||||||
|
icon="mdi-information-outline"
|
||||||
|
size="small"
|
||||||
|
>
|
||||||
|
</v-icon>
|
||||||
|
{{ t("no-classes-found") }}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
</v-table>
|
</v-table>
|
||||||
</v-col>
|
</v-col>
|
||||||
</v-row>
|
</v-row>
|
||||||
|
@ -271,49 +287,6 @@
|
||||||
</main>
|
</main>
|
||||||
</template>
|
</template>
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.header {
|
|
||||||
font-weight: bold !important;
|
|
||||||
background-color: #0e6942;
|
|
||||||
color: white;
|
|
||||||
padding: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
table thead th:first-child {
|
|
||||||
border-top-left-radius: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.table thead th:last-child {
|
|
||||||
border-top-right-radius: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.table tbody tr:nth-child(odd) {
|
|
||||||
background-color: white;
|
|
||||||
}
|
|
||||||
|
|
||||||
.table tbody tr:nth-child(even) {
|
|
||||||
background-color: #f6faf2;
|
|
||||||
}
|
|
||||||
|
|
||||||
td,
|
|
||||||
th {
|
|
||||||
border-bottom: 1px solid #0e6942;
|
|
||||||
border-top: 1px solid #0e6942;
|
|
||||||
}
|
|
||||||
|
|
||||||
.table {
|
|
||||||
width: 90%;
|
|
||||||
padding-top: 10px;
|
|
||||||
border-collapse: collapse;
|
|
||||||
}
|
|
||||||
|
|
||||||
h1 {
|
|
||||||
color: #0e6942;
|
|
||||||
text-transform: uppercase;
|
|
||||||
font-weight: bolder;
|
|
||||||
padding-top: 2%;
|
|
||||||
font-size: 50px;
|
|
||||||
}
|
|
||||||
|
|
||||||
h2 {
|
h2 {
|
||||||
color: #0e6942;
|
color: #0e6942;
|
||||||
font-size: 30px;
|
font-size: 30px;
|
||||||
|
@ -321,6 +294,7 @@
|
||||||
|
|
||||||
.join {
|
.join {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
margin-left: 1%;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 20px;
|
gap: 20px;
|
||||||
margin-top: 50px;
|
margin-top: 50px;
|
||||||
|
@ -331,16 +305,7 @@
|
||||||
text-decoration: underline;
|
text-decoration: underline;
|
||||||
}
|
}
|
||||||
|
|
||||||
main {
|
|
||||||
margin-left: 30px;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media screen and (max-width: 800px) {
|
@media screen and (max-width: 800px) {
|
||||||
h1 {
|
|
||||||
text-align: center;
|
|
||||||
padding-left: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.join {
|
.join {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
useTeacherInvitationsReceivedQuery,
|
useTeacherInvitationsReceivedQuery,
|
||||||
} from "@/queries/teacher-invitations";
|
} from "@/queries/teacher-invitations";
|
||||||
import { useDisplay } from "vuetify";
|
import { useDisplay } from "vuetify";
|
||||||
|
import "../../assets/common.css";
|
||||||
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
|
||||||
|
@ -112,7 +113,7 @@
|
||||||
dialog.value = true;
|
dialog.value = true;
|
||||||
}
|
}
|
||||||
if (!className.value || className.value === "") {
|
if (!className.value || className.value === "") {
|
||||||
showSnackbar(t("name is mandatory"), "error");
|
showSnackbar(t("nameIsMandatory"), "error");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -137,6 +138,13 @@
|
||||||
copied.value = true;
|
copied.value = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function copyCode(selectedCode: string): Promise<void> {
|
||||||
|
code.value = selectedCode;
|
||||||
|
await copyToClipboard();
|
||||||
|
showSnackbar(t("copied"), "white");
|
||||||
|
copied.value = false;
|
||||||
|
}
|
||||||
|
|
||||||
// Custom breakpoints
|
// Custom breakpoints
|
||||||
const customBreakpoints = {
|
const customBreakpoints = {
|
||||||
xs: 0,
|
xs: 0,
|
||||||
|
@ -183,7 +191,7 @@
|
||||||
></v-empty-state>
|
></v-empty-state>
|
||||||
</div>
|
</div>
|
||||||
<div v-else>
|
<div v-else>
|
||||||
<h1 class="title">{{ t("classes") }}</h1>
|
<h1 class="h1">{{ t("classes") }}</h1>
|
||||||
<using-query-result
|
<using-query-result
|
||||||
:query-result="classesQuery"
|
:query-result="classesQuery"
|
||||||
v-slot="classesResponse: { data: ClassesResponse }"
|
v-slot="classesResponse: { data: ClassesResponse }"
|
||||||
|
@ -212,7 +220,7 @@
|
||||||
<th class="header">{{ t("members") }}</th>
|
<th class="header">{{ t("members") }}</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody v-if="classesResponse.data.classes.length">
|
||||||
<tr
|
<tr
|
||||||
v-for="c in classesResponse.data.classes as ClassDTO[]"
|
v-for="c in classesResponse.data.classes as ClassDTO[]"
|
||||||
:key="c.id"
|
:key="c.id"
|
||||||
|
@ -227,7 +235,14 @@
|
||||||
</v-btn>
|
</v-btn>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<span v-if="!isMdAndDown">{{ c.id }}</span>
|
<v-btn
|
||||||
|
v-if="!isMdAndDown"
|
||||||
|
variant="text"
|
||||||
|
append-icon="mdi-content-copy"
|
||||||
|
@click="copyCode(c.id)"
|
||||||
|
>
|
||||||
|
{{ c.id }}
|
||||||
|
</v-btn>
|
||||||
<span
|
<span
|
||||||
v-else
|
v-else
|
||||||
style="cursor: pointer"
|
style="cursor: pointer"
|
||||||
|
@ -239,6 +254,21 @@
|
||||||
<td>{{ c.students.length }}</td>
|
<td>{{ c.students.length }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
|
<tbody v-else>
|
||||||
|
<tr>
|
||||||
|
<td
|
||||||
|
colspan="3"
|
||||||
|
class="empty-message"
|
||||||
|
>
|
||||||
|
<v-icon
|
||||||
|
icon="mdi-information-outline"
|
||||||
|
size="small"
|
||||||
|
>
|
||||||
|
</v-icon>
|
||||||
|
{{ t("no-classes-found") }}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
</v-table>
|
</v-table>
|
||||||
</v-col>
|
</v-col>
|
||||||
<v-col
|
<v-col
|
||||||
|
@ -318,7 +348,7 @@
|
||||||
</v-container>
|
</v-container>
|
||||||
</using-query-result>
|
</using-query-result>
|
||||||
|
|
||||||
<h1 class="title">
|
<h1 class="h1">
|
||||||
{{ t("invitations") }}
|
{{ t("invitations") }}
|
||||||
</h1>
|
</h1>
|
||||||
<v-container
|
<v-container
|
||||||
|
@ -342,6 +372,7 @@
|
||||||
:query-result="allClassesQuery"
|
:query-result="allClassesQuery"
|
||||||
v-slot="classesResponse: { data: ClassesResponse }"
|
v-slot="classesResponse: { data: ClassesResponse }"
|
||||||
>
|
>
|
||||||
|
<template v-if="invitationsResponse.data.invitations.length">
|
||||||
<tr
|
<tr
|
||||||
v-for="i in invitationsResponse.data.invitations as TeacherInvitationDTO[]"
|
v-for="i in invitationsResponse.data.invitations as TeacherInvitationDTO[]"
|
||||||
:key="i.classId"
|
:key="i.classId"
|
||||||
|
@ -355,7 +386,9 @@
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
{{
|
{{
|
||||||
(i.sender as TeacherDTO).firstName + " " + (i.sender as TeacherDTO).lastName
|
(i.sender as TeacherDTO).firstName +
|
||||||
|
" " +
|
||||||
|
(i.sender as TeacherDTO).lastName
|
||||||
}}
|
}}
|
||||||
</td>
|
</td>
|
||||||
<td class="text-right">
|
<td class="text-right">
|
||||||
|
@ -397,6 +430,22 @@
|
||||||
></span>
|
></span>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
</template>
|
||||||
|
<template v-else>
|
||||||
|
<tr>
|
||||||
|
<td
|
||||||
|
colspan="3"
|
||||||
|
class="empty-message"
|
||||||
|
>
|
||||||
|
<v-icon
|
||||||
|
icon="mdi-information-outline"
|
||||||
|
size="small"
|
||||||
|
>
|
||||||
|
</v-icon>
|
||||||
|
{{ t("no-invitations-found") }}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</template>
|
||||||
</using-query-result>
|
</using-query-result>
|
||||||
</using-query-result>
|
</using-query-result>
|
||||||
</tbody>
|
</tbody>
|
||||||
|
@ -449,49 +498,6 @@
|
||||||
</main>
|
</main>
|
||||||
</template>
|
</template>
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.header {
|
|
||||||
font-weight: bold !important;
|
|
||||||
background-color: #0e6942;
|
|
||||||
color: white;
|
|
||||||
padding: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
table thead th:first-child {
|
|
||||||
border-top-left-radius: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.table thead th:last-child {
|
|
||||||
border-top-right-radius: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.table tbody tr:nth-child(odd) {
|
|
||||||
background-color: white;
|
|
||||||
}
|
|
||||||
|
|
||||||
.table tbody tr:nth-child(even) {
|
|
||||||
background-color: #f6faf2;
|
|
||||||
}
|
|
||||||
|
|
||||||
td,
|
|
||||||
th {
|
|
||||||
border-bottom: 1px solid #0e6942;
|
|
||||||
border-top: 1px solid #0e6942;
|
|
||||||
}
|
|
||||||
|
|
||||||
.table {
|
|
||||||
width: 90%;
|
|
||||||
padding-top: 10px;
|
|
||||||
border-collapse: collapse;
|
|
||||||
}
|
|
||||||
|
|
||||||
h1 {
|
|
||||||
color: #0e6942;
|
|
||||||
text-transform: uppercase;
|
|
||||||
font-weight: bolder;
|
|
||||||
padding-top: 2%;
|
|
||||||
font-size: 50px;
|
|
||||||
}
|
|
||||||
|
|
||||||
h2 {
|
h2 {
|
||||||
color: #0e6942;
|
color: #0e6942;
|
||||||
font-size: 30px;
|
font-size: 30px;
|
||||||
|
@ -509,16 +515,7 @@
|
||||||
text-decoration: underline;
|
text-decoration: underline;
|
||||||
}
|
}
|
||||||
|
|
||||||
main {
|
|
||||||
margin-left: 30px;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media screen and (max-width: 850px) {
|
@media screen and (max-width: 850px) {
|
||||||
h1 {
|
|
||||||
text-align: center;
|
|
||||||
padding-left: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.join {
|
.join {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
@ -541,10 +538,6 @@
|
||||||
flex-direction: column !important;
|
flex-direction: column !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.table {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.responsive-col {
|
.responsive-col {
|
||||||
max-width: 100% !important;
|
max-width: 100% !important;
|
||||||
flex-basis: 100% !important;
|
flex-basis: 100% !important;
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
import { useI18n } from "vue-i18n";
|
import { useI18n } from "vue-i18n";
|
||||||
import { THEMESITEMS, AGE_TO_THEMES } from "@/utils/constants.ts";
|
import { THEMESITEMS, AGE_TO_THEMES } from "@/utils/constants.ts";
|
||||||
import BrowseThemes from "@/components/BrowseThemes.vue";
|
import BrowseThemes from "@/components/BrowseThemes.vue";
|
||||||
|
import "../../assets/common.css";
|
||||||
|
|
||||||
const { t, locale } = useI18n();
|
const { t, locale } = useI18n();
|
||||||
|
|
||||||
|
@ -46,7 +47,7 @@
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="main-container">
|
<div class="main-container">
|
||||||
<h1 class="title">{{ t("themes") }}</h1>
|
<h1 class="h1">{{ t("themes") }}</h1>
|
||||||
<v-container class="dropdowns">
|
<v-container class="dropdowns">
|
||||||
<v-select
|
<v-select
|
||||||
class="v-select"
|
class="v-select"
|
||||||
|
@ -77,24 +78,6 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.main-container {
|
|
||||||
min-height: 100vh;
|
|
||||||
min-width: 100vw;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: flex-start;
|
|
||||||
justify-content: flex-start;
|
|
||||||
}
|
|
||||||
|
|
||||||
.title {
|
|
||||||
max-width: 50rem;
|
|
||||||
margin-left: 1rem;
|
|
||||||
margin-top: 1rem;
|
|
||||||
text-align: center;
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.dropdowns {
|
.dropdowns {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
|
@ -107,12 +90,6 @@
|
||||||
min-width: 100px;
|
min-width: 100px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width: 768px) {
|
|
||||||
.main-container {
|
|
||||||
padding: 1rem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (max-width: 700px) {
|
@media (max-width: 700px) {
|
||||||
.dropdowns {
|
.dropdowns {
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
|
|
@ -287,6 +287,8 @@
|
||||||
<template v-slot:default>
|
<template v-slot:default>
|
||||||
<v-btn
|
<v-btn
|
||||||
class="button-in-nav"
|
class="button-in-nav"
|
||||||
|
width="100%"
|
||||||
|
:color="COLORS.teacherExclusive"
|
||||||
@click="assign()"
|
@click="assign()"
|
||||||
>{{ t("assignLearningPath") }}</v-btn
|
>{{ t("assignLearningPath") }}</v-btn
|
||||||
>
|
>
|
||||||
|
|
|
@ -17,32 +17,52 @@
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="search-field-container">
|
<v-container class="search-page-container">
|
||||||
<learning-path-search-field class="search-field"></learning-path-search-field>
|
<v-row
|
||||||
</div>
|
justify="center"
|
||||||
|
class="mb-6"
|
||||||
|
>
|
||||||
|
<v-col
|
||||||
|
cols="12"
|
||||||
|
sm="8"
|
||||||
|
md="6"
|
||||||
|
lg="4"
|
||||||
|
>
|
||||||
|
<learning-path-search-field class="search-field" />
|
||||||
|
</v-col>
|
||||||
|
</v-row>
|
||||||
|
|
||||||
|
<v-row justify="center">
|
||||||
|
<v-col cols="12">
|
||||||
<using-query-result
|
<using-query-result
|
||||||
:query-result="searchQueryResults"
|
:query-result="searchQueryResults"
|
||||||
v-slot="{ data }: { data: LearningPath[] }"
|
v-slot="{ data }: { data: LearningPath[] }"
|
||||||
>
|
>
|
||||||
<learning-paths-grid :learning-paths="data"></learning-paths-grid>
|
<learning-paths-grid :learning-paths="data" />
|
||||||
</using-query-result>
|
</using-query-result>
|
||||||
<div content="empty-state-container">
|
|
||||||
<v-empty-state
|
<div
|
||||||
v-if="!query"
|
v-if="!query"
|
||||||
|
class="empty-state-container"
|
||||||
|
>
|
||||||
|
<v-empty-state
|
||||||
icon="mdi-magnify"
|
icon="mdi-magnify"
|
||||||
:title="t('enterSearchTerm')"
|
:title="t('enterSearchTerm')"
|
||||||
:text="t('enterSearchTermDescription')"
|
:text="t('enterSearchTermDescription')"
|
||||||
></v-empty-state>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
</v-col>
|
||||||
|
</v-row>
|
||||||
|
</v-container>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.search-field-container {
|
.search-page-container {
|
||||||
display: block;
|
padding-top: 40px;
|
||||||
margin: 20px;
|
padding-bottom: 40px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.search-field {
|
.search-field {
|
||||||
max-width: 300px;
|
max-width: 100%;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -5,7 +5,7 @@ describe("AssignmentController Tests", () => {
|
||||||
let controller: AssignmentController;
|
let controller: AssignmentController;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
controller = new AssignmentController("8764b861-90a6-42e5-9732-c0d9eb2f55f9"); // Example class ID
|
controller = new AssignmentController("X2J9QT"); // Example class ID (class01)
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should fetch all assignments", async () => {
|
it("should fetch all assignments", async () => {
|
||||||
|
|
|
@ -3,7 +3,7 @@ import { GroupController } from "../../src/controllers/groups";
|
||||||
|
|
||||||
describe("Test controller groups", () => {
|
describe("Test controller groups", () => {
|
||||||
it("Get groups", async () => {
|
it("Get groups", async () => {
|
||||||
const classId = "8764b861-90a6-42e5-9732-c0d9eb2f55f9";
|
const classId = "X2J9QT"; // Class01
|
||||||
const assignmentNumber = 21000;
|
const assignmentNumber = 21000;
|
||||||
|
|
||||||
const controller = new GroupController(classId, assignmentNumber);
|
const controller = new GroupController(classId, assignmentNumber);
|
||||||
|
|
9631
package-lock.json
generated
9631
package-lock.json
generated
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue