✨ Add timetable group settings
This commit is contained in:
42
src/components/settings/multiselect-buttons.vue
Normal file
42
src/components/settings/multiselect-buttons.vue
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
<script setup>
|
||||||
|
import { CircleIcon, CheckCircleIcon } from "lucide-vue-next";
|
||||||
|
|
||||||
|
const props = defineProps(["options", "values", "modelValue"]);
|
||||||
|
const emit = defineEmits(["update:modelValue"]);
|
||||||
|
|
||||||
|
function toggleSelection(element) {
|
||||||
|
const selection = props.modelValue;
|
||||||
|
if (selection.includes(element)) {
|
||||||
|
const index = selection.indexOf(element);
|
||||||
|
if (index > -1) selection.splice(index, 1);
|
||||||
|
} else {
|
||||||
|
selection.push(element);
|
||||||
|
}
|
||||||
|
emit("update:modelValue", selection);
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div
|
||||||
|
class="button"
|
||||||
|
v-for="(value, index) in values"
|
||||||
|
:key="value"
|
||||||
|
@click="toggleSelection(value)"
|
||||||
|
>
|
||||||
|
<CheckCircleIcon v-if="modelValue.includes(value)" />
|
||||||
|
<CircleIcon v-else />
|
||||||
|
|
||||||
|
<span class="text">{{ options[index] }}</span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.button {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
padding: 10px 5px;
|
||||||
|
cursor: pointer;
|
||||||
|
user-select: none;
|
||||||
|
}
|
||||||
|
</style>
|
@ -44,11 +44,11 @@ function goBack() {
|
|||||||
.title {
|
.title {
|
||||||
font-size: 25px;
|
font-size: 25px;
|
||||||
padding-left: 13px;
|
padding-left: 13px;
|
||||||
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.settings {
|
.settings {
|
||||||
display: flex;
|
display: flex;
|
||||||
width: 100%;
|
|
||||||
justify-content: flex-end;
|
justify-content: flex-end;
|
||||||
padding-right: 13px;
|
padding-right: 13px;
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,7 @@ import SettingsView from "@/views/SettingsView.vue";
|
|||||||
import LoginView from "@/views/LoginView.vue";
|
import LoginView from "@/views/LoginView.vue";
|
||||||
import TokenView from "@/views/TokenView.vue";
|
import TokenView from "@/views/TokenView.vue";
|
||||||
import FilteringSettings from "@/views/settings/FilteringSettings.vue";
|
import FilteringSettings from "@/views/settings/FilteringSettings.vue";
|
||||||
|
import TimetableGroupSettings from "@/views/settings/TimetableGroupSettings.vue";
|
||||||
import AppearanceSettings from "@/views/settings/AppearanceSettings.vue";
|
import AppearanceSettings from "@/views/settings/AppearanceSettings.vue";
|
||||||
import AboutPage from "@/views/settings/AboutPage.vue";
|
import AboutPage from "@/views/settings/AboutPage.vue";
|
||||||
|
|
||||||
@ -52,6 +53,11 @@ const router = createRouter({
|
|||||||
name: "title.settings.filtering",
|
name: "title.settings.filtering",
|
||||||
component: FilteringSettings,
|
component: FilteringSettings,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: "groups",
|
||||||
|
name: "title.settings.groups",
|
||||||
|
component: TimetableGroupSettings,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: "appearance",
|
path: "appearance",
|
||||||
name: "title.settings.appearance",
|
name: "title.settings.appearance",
|
||||||
|
@ -9,6 +9,7 @@ export const strings = {
|
|||||||
settings: {
|
settings: {
|
||||||
main: "Settings",
|
main: "Settings",
|
||||||
filtering: "Filtering",
|
filtering: "Filtering",
|
||||||
|
groups: "Timetable Groups",
|
||||||
appearance: "Appearance",
|
appearance: "Appearance",
|
||||||
about: "About",
|
about: "About",
|
||||||
},
|
},
|
||||||
@ -112,6 +113,7 @@ export const strings = {
|
|||||||
settings: {
|
settings: {
|
||||||
main: "Einstellungen",
|
main: "Einstellungen",
|
||||||
filtering: "Filter",
|
filtering: "Filter",
|
||||||
|
groups: "Stundenplan-Gruppen",
|
||||||
appearance: "Aussehen",
|
appearance: "Aussehen",
|
||||||
about: "Über",
|
about: "Über",
|
||||||
},
|
},
|
||||||
|
@ -3,6 +3,7 @@ import ScrollableContainer from "@/components/scrollable-container.vue";
|
|||||||
import PageCard from "@/components/settings/page-card.vue";
|
import PageCard from "@/components/settings/page-card.vue";
|
||||||
import {
|
import {
|
||||||
FilterIcon,
|
FilterIcon,
|
||||||
|
CopyCheckIcon,
|
||||||
PaletteIcon,
|
PaletteIcon,
|
||||||
InfoIcon,
|
InfoIcon,
|
||||||
ChevronLeft,
|
ChevronLeft,
|
||||||
@ -18,6 +19,11 @@ import {
|
|||||||
:icon="FilterIcon"
|
:icon="FilterIcon"
|
||||||
route="settings/filtering"
|
route="settings/filtering"
|
||||||
/>
|
/>
|
||||||
|
<PageCard
|
||||||
|
:name="$t('title.settings.groups')"
|
||||||
|
:icon="CopyCheckIcon"
|
||||||
|
route="settings/groups"
|
||||||
|
/>
|
||||||
<PageCard
|
<PageCard
|
||||||
:name="$t('title.settings.appearance')"
|
:name="$t('title.settings.appearance')"
|
||||||
:icon="PaletteIcon"
|
:icon="PaletteIcon"
|
||||||
|
24
src/views/settings/TimetableGroupSettings.vue
Normal file
24
src/views/settings/TimetableGroupSettings.vue
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
<script setup>
|
||||||
|
import { possibleTimetableGroups, timetableGroups } from "@/store";
|
||||||
|
import MultiselectButtons from "@/components/settings/multiselect-buttons.vue";
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<h2>{{ $t("settings.heading.timetableGroups") }}</h2>
|
||||||
|
<p>{{ $t("settings.text.timetableGroups") }}</p>
|
||||||
|
<MultiselectButtons
|
||||||
|
:options="possibleTimetableGroups"
|
||||||
|
:values="possibleTimetableGroups"
|
||||||
|
v-model="timetableGroups"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
h2 {
|
||||||
|
margin: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
margin: 5px 0px;
|
||||||
|
}
|
||||||
|
</style>
|
Reference in New Issue
Block a user