Merge branch 'dev' into feat/leerpad-vragen
This commit is contained in:
commit
8240059c2c
60 changed files with 10729 additions and 1042 deletions
|
@ -11,7 +11,7 @@
|
|||
selectedAge: { type: String, required: true },
|
||||
});
|
||||
|
||||
const { locale } = useI18n();
|
||||
const { t, locale } = useI18n();
|
||||
const language = computed(() => locale.value);
|
||||
|
||||
const { data: allThemes, isLoading, error } = useThemeQuery(language);
|
||||
|
@ -74,6 +74,22 @@
|
|||
class="fill-height"
|
||||
/>
|
||||
</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-container>
|
||||
</template>
|
||||
|
|
|
@ -1,21 +1,26 @@
|
|||
<script setup lang="ts">
|
||||
import { computed } from "vue";
|
||||
import { useI18n } from "vue-i18n";
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
defineProps<{
|
||||
const props = defineProps<{
|
||||
path: string;
|
||||
isAbsolutePath?: boolean;
|
||||
title: string;
|
||||
description: string;
|
||||
image: string;
|
||||
image?: string;
|
||||
icon?: string;
|
||||
}>();
|
||||
|
||||
const routerLink = computed(() => (props.isAbsolutePath ? props.path : `/theme/${props.path}`));
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<v-card
|
||||
variant="outlined"
|
||||
class="theme-card d-flex flex-column"
|
||||
:to="`theme/${path}`"
|
||||
:to="routerLink"
|
||||
link
|
||||
>
|
||||
<v-card-title class="title-container">
|
||||
|
@ -27,12 +32,18 @@
|
|||
contain
|
||||
class="title-image"
|
||||
></v-img>
|
||||
<v-icon
|
||||
v-if="icon"
|
||||
class="title-image"
|
||||
>{{ icon }}</v-icon
|
||||
>
|
||||
|
||||
<span class="title">{{ title }}</span>
|
||||
</v-card-title>
|
||||
<v-card-text class="description flex-grow-1">{{ description }}</v-card-text>
|
||||
<v-card-actions>
|
||||
<v-btn
|
||||
:to="`theme/${path}`"
|
||||
:to="routerLink"
|
||||
variant="text"
|
||||
>
|
||||
{{ t("read-more") }}
|
||||
|
|
49
frontend/src/components/assignments/DeadlineSelector.vue
Normal file
49
frontend/src/components/assignments/DeadlineSelector.vue
Normal file
|
@ -0,0 +1,49 @@
|
|||
<script setup lang="ts">
|
||||
import { ref, computed } from "vue";
|
||||
import { deadlineRules } from "@/utils/assignment-rules.ts";
|
||||
|
||||
const date = ref("");
|
||||
const time = ref("23:59");
|
||||
const emit = defineEmits(["update:deadline"]);
|
||||
|
||||
const formattedDeadline = computed(() => {
|
||||
if (!date.value || !time.value) return "";
|
||||
return `${date.value} ${time.value}`;
|
||||
});
|
||||
|
||||
function updateDeadline(): void {
|
||||
if (date.value && time.value) {
|
||||
emit("update:deadline", formattedDeadline.value);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<v-card-text>
|
||||
<v-text-field
|
||||
v-model="date"
|
||||
label="Select Deadline Date"
|
||||
type="date"
|
||||
variant="outlined"
|
||||
density="compact"
|
||||
:rules="deadlineRules"
|
||||
required
|
||||
@update:modelValue="updateDeadline"
|
||||
></v-text-field>
|
||||
</v-card-text>
|
||||
|
||||
<v-card-text>
|
||||
<v-text-field
|
||||
v-model="time"
|
||||
label="Select Deadline Time"
|
||||
type="time"
|
||||
variant="outlined"
|
||||
density="compact"
|
||||
@update:modelValue="updateDeadline"
|
||||
></v-text-field>
|
||||
</v-card-text>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped></style>
|
75
frontend/src/components/assignments/GroupSelector.vue
Normal file
75
frontend/src/components/assignments/GroupSelector.vue
Normal file
|
@ -0,0 +1,75 @@
|
|||
<script setup lang="ts">
|
||||
import { ref } from "vue";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import UsingQueryResult from "@/components/UsingQueryResult.vue";
|
||||
import type { StudentsResponse } from "@/controllers/students.ts";
|
||||
import { useClassStudentsQuery } from "@/queries/classes.ts";
|
||||
|
||||
const props = defineProps<{
|
||||
classId: string | undefined;
|
||||
groups: string[][];
|
||||
}>();
|
||||
const emit = defineEmits(["groupCreated"]);
|
||||
const { t } = useI18n();
|
||||
|
||||
const selectedStudents = ref([]);
|
||||
|
||||
const studentQueryResult = useClassStudentsQuery(() => props.classId, true);
|
||||
|
||||
function filterStudents(data: StudentsResponse): { title: string; value: string }[] {
|
||||
const students = data.students;
|
||||
const studentsInGroups = props.groups.flat();
|
||||
|
||||
return students
|
||||
?.map((st) => ({
|
||||
title: `${st.firstName} ${st.lastName}`,
|
||||
value: st.username,
|
||||
}))
|
||||
.filter((student) => !studentsInGroups.includes(student.value));
|
||||
}
|
||||
|
||||
function createGroup(): void {
|
||||
if (selectedStudents.value.length) {
|
||||
// Extract only usernames (student.value)
|
||||
const usernames = selectedStudents.value.map((student) => student.value);
|
||||
emit("groupCreated", usernames);
|
||||
selectedStudents.value = []; // Reset selection after creating group
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<using-query-result
|
||||
:query-result="studentQueryResult"
|
||||
v-slot="{ data }: { data: StudentsResponse }"
|
||||
>
|
||||
<h3>{{ t("create-groups") }}</h3>
|
||||
<v-card-text>
|
||||
<v-combobox
|
||||
v-model="selectedStudents"
|
||||
:items="filterStudents(data)"
|
||||
item-title="title"
|
||||
item-value="value"
|
||||
:label="t('choose-students')"
|
||||
variant="outlined"
|
||||
clearable
|
||||
multiple
|
||||
hide-details
|
||||
density="compact"
|
||||
chips
|
||||
append-inner-icon="mdi-magnify"
|
||||
></v-combobox>
|
||||
|
||||
<v-btn
|
||||
@click="createGroup"
|
||||
color="primary"
|
||||
class="mt-2"
|
||||
size="small"
|
||||
>
|
||||
{{ t("create-group") }}
|
||||
</v-btn>
|
||||
</v-card-text>
|
||||
</using-query-result>
|
||||
</template>
|
||||
|
||||
<style scoped></style>
|
Loading…
Add table
Add a link
Reference in a new issue