First startup dialog, factory reset
This commit is contained in:
@@ -90,12 +90,12 @@ export async function prepopulateDatabase() {
|
|||||||
{
|
{
|
||||||
await City.create(city)
|
await City.create(city)
|
||||||
.then(async cityDataset => {
|
.then(async cityDataset => {
|
||||||
for (let location of city.locations)
|
for (let { ...location } of city.locations)
|
||||||
{
|
{
|
||||||
location["cityId"] = cityDataset.id
|
location["cityId"] = cityDataset.id
|
||||||
location["urlName"] = location.name.replaceAll(" ", "-").toLowerCase()
|
location["urlName"] = location.name.replaceAll(" ", "-").toLowerCase()
|
||||||
location["imageIndoor"] = "http://localhost:3000/static/" + location["imageIndoor"]
|
location.imageIndoor = "http://localhost:3000/static/" + location["imageIndoor"]
|
||||||
location["imageOutdoor"] = "http://localhost:3000/static/" + location["imageOutdoor"]
|
location.imageOutdoor = "http://localhost:3000/static/" + location["imageOutdoor"]
|
||||||
|
|
||||||
await Location.create(location)
|
await Location.create(location)
|
||||||
.then(async locationDataset => {
|
.then(async locationDataset => {
|
||||||
@@ -240,7 +240,7 @@ export async function prepopulateDatabase() {
|
|||||||
let concerts = []
|
let concerts = []
|
||||||
let ratings = []
|
let ratings = []
|
||||||
|
|
||||||
for(let band of bandsConcerts.bands) {
|
for(let { ...band } of bandsConcerts.bands) {
|
||||||
band.imageMembers = "http://localhost:3000/static/" + band.imageMembers
|
band.imageMembers = "http://localhost:3000/static/" + band.imageMembers
|
||||||
band.images = band.images.map(image => "http://localhost:3000/static/" + image)
|
band.images = band.images.map(image => "http://localhost:3000/static/" + image)
|
||||||
band.logo = "http://localhost:3000/static/" + band.logo
|
band.logo = "http://localhost:3000/static/" + band.logo
|
||||||
@@ -282,11 +282,9 @@ export async function prepopulateDatabase() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (let member of band.members) {
|
for (let member of band.members) {
|
||||||
member.image = "http://localhost:3000/static/" + member.image
|
|
||||||
|
|
||||||
bandMembers.push({
|
bandMembers.push({
|
||||||
name: member.name,
|
name: member.name,
|
||||||
image: member.image,
|
image: "http://localhost:3000/static/" + member.image,
|
||||||
bandId: dataset.dataValues.id
|
bandId: dataset.dataValues.id
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,8 +9,6 @@ import { useFeedbackStore } from './stores/feedback.store';
|
|||||||
import companyFooter from './components/navigation/companyFooter.vue';
|
import companyFooter from './components/navigation/companyFooter.vue';
|
||||||
import urlBar from './components/navigation/urlBar.vue';
|
import urlBar from './components/navigation/urlBar.vue';
|
||||||
import { useRouter } from 'vue-router';
|
import { useRouter } from 'vue-router';
|
||||||
import actionDialog from './components/basics/actionDialog.vue';
|
|
||||||
import CircularProgressIndeterminate from './components/basics/circularProgressIndeterminate.vue';
|
|
||||||
|
|
||||||
const preferencesStore = usePreferencesStore()
|
const preferencesStore = usePreferencesStore()
|
||||||
const feedbackStore = useFeedbackStore()
|
const feedbackStore = useFeedbackStore()
|
||||||
@@ -19,18 +17,18 @@ const router = useRouter()
|
|||||||
|
|
||||||
theme.global.name.value = preferencesStore.theme
|
theme.global.name.value = preferencesStore.theme
|
||||||
|
|
||||||
|
|
||||||
// First startup
|
|
||||||
if (preferencesStore.firstStartup) {
|
|
||||||
preferencesStore.firstStartupRoutine()
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Global watcher
|
// Global watcher
|
||||||
|
// Watch for language change
|
||||||
watch(() => preferencesStore.language, () => {
|
watch(() => preferencesStore.language, () => {
|
||||||
i18n.global.locale = preferencesStore.language
|
i18n.global.locale = preferencesStore.language
|
||||||
}, { immediate: true })
|
}, { immediate: true })
|
||||||
|
|
||||||
|
// Watch for theme change
|
||||||
|
watch(() => preferencesStore.theme, () => {
|
||||||
|
theme.global.name.value = preferencesStore.theme
|
||||||
|
})
|
||||||
|
|
||||||
|
// Watch for 404 page directions
|
||||||
watch(() => feedbackStore.notFound, () => {
|
watch(() => feedbackStore.notFound, () => {
|
||||||
if (feedbackStore.notFound) {
|
if (feedbackStore.notFound) {
|
||||||
feedbackStore.notFound = false
|
feedbackStore.notFound = false
|
||||||
@@ -92,23 +90,4 @@ watch(() => feedbackStore.notFound, () => {
|
|||||||
<company-footer />
|
<company-footer />
|
||||||
</v-main>
|
</v-main>
|
||||||
</v-app>
|
</v-app>
|
||||||
|
|
||||||
<action-dialog
|
|
||||||
v-model="preferencesStore.firstStartup"
|
|
||||||
:title="$t('misc.firstStartup.title')"
|
|
||||||
persistent
|
|
||||||
max-width="600"
|
|
||||||
>
|
|
||||||
<v-row>
|
|
||||||
<v-col>
|
|
||||||
{{ $t('misc.firstStartup.description') }}
|
|
||||||
</v-col>
|
|
||||||
</v-row>
|
|
||||||
|
|
||||||
<v-row>
|
|
||||||
<v-col class="text-center pa-8">
|
|
||||||
<circular-progress-indeterminate />
|
|
||||||
</v-col>
|
|
||||||
</v-row>
|
|
||||||
</action-dialog>
|
|
||||||
</template>
|
</template>
|
||||||
@@ -23,9 +23,11 @@ defineProps({
|
|||||||
:icon="icon"
|
:icon="icon"
|
||||||
:tonal="false"
|
:tonal="false"
|
||||||
>
|
>
|
||||||
|
<template #default v-if="$slots.default">
|
||||||
<slot></slot>
|
<slot></slot>
|
||||||
|
</template>
|
||||||
|
|
||||||
<template #borderless>
|
<template #borderless v-if="$slots.borderless">
|
||||||
<slot name="borderless"></slot>
|
<slot name="borderless"></slot>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|||||||
32
software/src/components/pageParts/serverStateText.vue
Normal file
32
software/src/components/pageParts/serverStateText.vue
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import { usePreferencesStore } from '@/stores/preferences.store';
|
||||||
|
import { ServerStateEnum } from '@/data/enums/serverStateEnum';
|
||||||
|
|
||||||
|
const preferencesStore = usePreferencesStore()
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<span
|
||||||
|
v-if="preferencesStore.serverState == ServerStateEnum.PENDING || preferencesStore.fetchInProgress"
|
||||||
|
class="text-orange"
|
||||||
|
>
|
||||||
|
<v-icon icon="mdi-clock" />
|
||||||
|
Pending...
|
||||||
|
</span>
|
||||||
|
|
||||||
|
<span
|
||||||
|
v-else-if="preferencesStore.serverState == ServerStateEnum.ONLINE"
|
||||||
|
class="text-green"
|
||||||
|
>
|
||||||
|
<v-icon icon="mdi-check" />
|
||||||
|
Online
|
||||||
|
</span>
|
||||||
|
|
||||||
|
<span
|
||||||
|
v-else="preferencesStore.serverState == ServerStateEnum.OFFLINE"
|
||||||
|
class="text-red"
|
||||||
|
>
|
||||||
|
<v-icon icon="mdi-alert-circle" />
|
||||||
|
Offline
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
export enum ThemeEnum {
|
export enum ThemeEnum {
|
||||||
DARKBLUE = "dark",
|
DARK = "dark",
|
||||||
LIGHTBLUE = "light",
|
LIGHT = "light",
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -148,7 +148,15 @@
|
|||||||
"description": "Soll der Bearbeitungsfortschritt der Übungen wirklich zurückgesetzt werden? Dies kann nicht rückgänig gemacht werden!"
|
"description": "Soll der Bearbeitungsfortschritt der Übungen wirklich zurückgesetzt werden? Dies kann nicht rückgänig gemacht werden!"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"aboutProject": "Über das Projekt"
|
"aboutProject": "Über das Projekt",
|
||||||
|
"resetFirstStartup": "Einrichtungsassistenten starten",
|
||||||
|
"factoryReset": {
|
||||||
|
"factoryReset": "Zurücksetzen auf Werkseinstellungen",
|
||||||
|
"dialog": {
|
||||||
|
"title": "Aus Werkseinstellungen zurücksetzen?",
|
||||||
|
"description": "Sollen alle Einstellungen und Daten auf Werkseinstellungen zurückgesetzt werden? Alle Änderungen und Fortschritte gehen verloren!"
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"help": {
|
"help": {
|
||||||
"scoreBoard": {
|
"scoreBoard": {
|
||||||
@@ -201,7 +209,8 @@
|
|||||||
"filtering": "Filtern",
|
"filtering": "Filtern",
|
||||||
"cancel": "Abbrechen",
|
"cancel": "Abbrechen",
|
||||||
"more": "Mehr",
|
"more": "Mehr",
|
||||||
"confirm": "Bestätigen"
|
"confirm": "Bestätigen",
|
||||||
|
"next": "Weiter"
|
||||||
},
|
},
|
||||||
"validation": {
|
"validation": {
|
||||||
"required": "Darf nicht leer bleiben",
|
"required": "Darf nicht leer bleiben",
|
||||||
@@ -216,8 +225,19 @@
|
|||||||
"uploadFile": "Datei hochladen",
|
"uploadFile": "Datei hochladen",
|
||||||
"firstStartup": {
|
"firstStartup": {
|
||||||
"title": "Ersteinrichtung",
|
"title": "Ersteinrichtung",
|
||||||
"description": "Die Datenbank wird eingerichtet. Dies kann 1-2 Minuten dauern. Bitte warten..."
|
"description": "Die Datenbank wird eingerichtet. Bitte warten...",
|
||||||
}
|
"createDatabase": "Erstelle Datenbank...",
|
||||||
|
"complete": "Fertig",
|
||||||
|
"finished": "Abgeschlossen",
|
||||||
|
"createExercises": "Erstelle Aufgaben...",
|
||||||
|
"connectToServer": "Server",
|
||||||
|
"database": "Datenbank",
|
||||||
|
"exercises": "Aufgaben",
|
||||||
|
"userData": "Persönliche Daten"
|
||||||
|
},
|
||||||
|
"user": "Angaben zur Person",
|
||||||
|
"registrationNumber": "Matrikelnummer",
|
||||||
|
"yourFullName": "Vollständiger Name"
|
||||||
},
|
},
|
||||||
"genre": {
|
"genre": {
|
||||||
"withoutBand": "ohne Band"
|
"withoutBand": "ohne Band"
|
||||||
|
|||||||
@@ -148,7 +148,15 @@
|
|||||||
"description": "Do you really want to reset the exercise progress? This is permanent!"
|
"description": "Do you really want to reset the exercise progress? This is permanent!"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"aboutProject": "About the project"
|
"aboutProject": "About the project",
|
||||||
|
"resetFirstStartup": "Start first startup dialog",
|
||||||
|
"factoryReset": {
|
||||||
|
"factoryReset": "Factory reset",
|
||||||
|
"dialog": {
|
||||||
|
"title": "Factory reset?",
|
||||||
|
"description": "Do you really want to reset everything? Every change will be lost!"
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"help": {
|
"help": {
|
||||||
"scoreBoard": {
|
"scoreBoard": {
|
||||||
@@ -201,7 +209,8 @@
|
|||||||
"filtering": "Filter",
|
"filtering": "Filter",
|
||||||
"cancel": "Cancel",
|
"cancel": "Cancel",
|
||||||
"more": "More",
|
"more": "More",
|
||||||
"confirm": "Confirm"
|
"confirm": "Confirm",
|
||||||
|
"next": "Next"
|
||||||
},
|
},
|
||||||
"validation": {
|
"validation": {
|
||||||
"required": "Must not remain empty",
|
"required": "Must not remain empty",
|
||||||
@@ -216,8 +225,19 @@
|
|||||||
"uploadFile": "Upload file",
|
"uploadFile": "Upload file",
|
||||||
"firstStartup": {
|
"firstStartup": {
|
||||||
"title": "First startup",
|
"title": "First startup",
|
||||||
"description": "Creating database. This could take 1-2 minutes. Please wait..."
|
"description": "Creating database. Please wait...",
|
||||||
}
|
"createDatabase": "Create Database...",
|
||||||
|
"complete": "Complete",
|
||||||
|
"createExercises": "Create Exercises...",
|
||||||
|
"finished": "Finished",
|
||||||
|
"connectToServer": "Server",
|
||||||
|
"database": "Database",
|
||||||
|
"exercises": "Exercises",
|
||||||
|
"userData": "User data"
|
||||||
|
},
|
||||||
|
"user": "About person",
|
||||||
|
"registrationNumber": "Matrikel number",
|
||||||
|
"yourFullName": "Full name"
|
||||||
},
|
},
|
||||||
"genre": {
|
"genre": {
|
||||||
"withoutBand": "without Band"
|
"withoutBand": "without Band"
|
||||||
|
|||||||
@@ -4,20 +4,30 @@ import { useLocationStore } from '@/stores/location.store';
|
|||||||
import bandSection from './bandsSection.vue';
|
import bandSection from './bandsSection.vue';
|
||||||
import UpcomingConcertsSection from './upcomingConcertsSection.vue';
|
import UpcomingConcertsSection from './upcomingConcertsSection.vue';
|
||||||
import TopLocationsSection from './topLocationsSection.vue';
|
import TopLocationsSection from './topLocationsSection.vue';
|
||||||
|
import { usePreferencesStore } from '@/stores/preferences.store';
|
||||||
|
import welcomeDialog from './welcomeDialog.vue';
|
||||||
|
import { ref } from 'vue';
|
||||||
|
|
||||||
const concertStore = useConcertStore()
|
const concertStore = useConcertStore()
|
||||||
const locationStore = useLocationStore()
|
const locationStore = useLocationStore()
|
||||||
|
const preferencesStore = usePreferencesStore()
|
||||||
|
const showWelcomeDialog = ref(false)
|
||||||
|
|
||||||
concertStore.getUpcomingConcerts()
|
concertStore.getUpcomingConcerts()
|
||||||
locationStore.getTopLocations()
|
locationStore.getTopLocations()
|
||||||
|
|
||||||
|
// First startup
|
||||||
|
if (preferencesStore.firstStartup) {
|
||||||
|
showWelcomeDialog.value = true
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="pt-4">
|
<div class="pt-4">
|
||||||
<band-section />
|
<band-section v-if="!preferencesStore.firstStartup" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<v-container>
|
<v-container v-if="!preferencesStore.firstStartup">
|
||||||
<v-row>
|
<v-row>
|
||||||
<v-spacer />
|
<v-spacer />
|
||||||
|
|
||||||
@@ -30,4 +40,6 @@ locationStore.getTopLocations()
|
|||||||
<v-spacer />
|
<v-spacer />
|
||||||
</v-row>
|
</v-row>
|
||||||
</v-container>
|
</v-container>
|
||||||
|
|
||||||
|
<welcome-dialog :model-value="showWelcomeDialog" />
|
||||||
</template>
|
</template>
|
||||||
185
software/src/pages/misc/homePage/welcomeDialog.vue
Normal file
185
software/src/pages/misc/homePage/welcomeDialog.vue
Normal file
@@ -0,0 +1,185 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import actionDialog from '@/components/basics/actionDialog.vue';
|
||||||
|
import outlinedButton from '@/components/basics/outlinedButton.vue';
|
||||||
|
import ServerStateText from '@/components/pageParts/serverStateText.vue';
|
||||||
|
import { useFeedbackStore } from '@/stores/feedback.store';
|
||||||
|
import { usePreferencesStore } from '@/stores/preferences.store';
|
||||||
|
import { ref, watch } from 'vue';
|
||||||
|
|
||||||
|
const preferencesStore = usePreferencesStore()
|
||||||
|
const feedbackStore = useFeedbackStore()
|
||||||
|
const showDialog = defineModel()
|
||||||
|
const currentStep = ref(0)
|
||||||
|
|
||||||
|
const steps = [
|
||||||
|
feedbackStore.i18n.t('misc.firstStartup.connectToServer'),
|
||||||
|
feedbackStore.i18n.t('misc.firstStartup.database'),
|
||||||
|
feedbackStore.i18n.t('misc.firstStartup.exercises'),
|
||||||
|
feedbackStore.i18n.t('misc.firstStartup.userData'),
|
||||||
|
]
|
||||||
|
|
||||||
|
preferencesStore.getServerState()
|
||||||
|
|
||||||
|
|
||||||
|
watch(() => currentStep.value, () => {
|
||||||
|
switch(currentStep.value) {
|
||||||
|
case 2: {
|
||||||
|
preferencesStore.resetDb();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 3: {
|
||||||
|
preferencesStore.resetExerciseProg();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 4: {
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<action-dialog
|
||||||
|
v-model="showDialog"
|
||||||
|
:title="$t('misc.firstStartup.title')"
|
||||||
|
icon="mdi-human-greeting"
|
||||||
|
max-width="800"
|
||||||
|
persistent
|
||||||
|
>
|
||||||
|
<template #borderless>
|
||||||
|
<v-stepper
|
||||||
|
v-model="currentStep"
|
||||||
|
alt-labels
|
||||||
|
flat
|
||||||
|
>
|
||||||
|
<template #default="{ prev, next}">
|
||||||
|
<!-- Header items -->
|
||||||
|
<v-stepper-header>
|
||||||
|
<template v-for="(step, n) in steps">
|
||||||
|
<v-stepper-item
|
||||||
|
:complete="currentStep > n + 1"
|
||||||
|
:title="step"
|
||||||
|
:value="n + 1"
|
||||||
|
complete-icon="mdi-check"
|
||||||
|
color="green"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<v-divider v-if="n < steps.length - 1" />
|
||||||
|
</template>
|
||||||
|
</v-stepper-header>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Content -->
|
||||||
|
<v-stepper-window>
|
||||||
|
<v-stepper-window-item
|
||||||
|
:value="1"
|
||||||
|
class="text-h4 text-center"
|
||||||
|
>
|
||||||
|
<div>
|
||||||
|
{{ $t('preferences.serverState') }}:
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<server-state-text />
|
||||||
|
</v-stepper-window-item>
|
||||||
|
|
||||||
|
<v-stepper-window-item
|
||||||
|
:value="2"
|
||||||
|
>
|
||||||
|
<div v-if="preferencesStore.fetchInProgress" class="text-center text-h4 pb-4">
|
||||||
|
<div class="pb-4">
|
||||||
|
{{ $t('misc.firstStartup.createDatabase') }}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<v-progress-linear indeterminate />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div v-else class="text-center text-h4 pb-4 text-green">
|
||||||
|
<v-icon icon="mdi-check" /> {{ $t('misc.firstStartup.finished') }}
|
||||||
|
</div>
|
||||||
|
</v-stepper-window-item>
|
||||||
|
|
||||||
|
|
||||||
|
<v-stepper-window-item
|
||||||
|
:value="3"
|
||||||
|
>
|
||||||
|
<div v-if="preferencesStore.fetchInProgress" class="text-center text-h4 pb-4">
|
||||||
|
<div class="pb-4">
|
||||||
|
{{ $t('misc.firstStartup.createExercises') }}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<v-progress-linear indeterminate />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div v-else class="text-center text-h4 pb-4 text-green">
|
||||||
|
<v-icon icon="mdi-check" /> {{ $t('misc.firstStartup.finished') }}
|
||||||
|
</div>
|
||||||
|
</v-stepper-window-item>
|
||||||
|
|
||||||
|
|
||||||
|
<v-stepper-window-item
|
||||||
|
:value="4"
|
||||||
|
>
|
||||||
|
<v-container class="px-0 py-2">
|
||||||
|
<v-row>
|
||||||
|
<v-col>
|
||||||
|
<v-text-field
|
||||||
|
variant="outlined"
|
||||||
|
hide-details
|
||||||
|
:label="$t('misc.yourFullName')"
|
||||||
|
v-model="preferencesStore.studentName"
|
||||||
|
/>
|
||||||
|
</v-col>
|
||||||
|
</v-row>
|
||||||
|
|
||||||
|
<v-row>
|
||||||
|
<v-col>
|
||||||
|
<v-text-field
|
||||||
|
variant="outlined"
|
||||||
|
hide-details
|
||||||
|
:label="$t('misc.registrationNumber')"
|
||||||
|
v-model="preferencesStore.registrationNumber"
|
||||||
|
/>
|
||||||
|
</v-col>
|
||||||
|
</v-row>
|
||||||
|
</v-container>
|
||||||
|
</v-stepper-window-item>
|
||||||
|
</v-stepper-window>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Next/Previous buttons -->
|
||||||
|
<v-stepper-actions
|
||||||
|
@click:next="next"
|
||||||
|
>
|
||||||
|
<template #prev="{ props }">
|
||||||
|
<v-spacer />
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template #next="{ props }">
|
||||||
|
<outlined-button
|
||||||
|
v-if="currentStep < 4"
|
||||||
|
@click="props.onClick()"
|
||||||
|
:disabled="preferencesStore.fetchInProgress"
|
||||||
|
>
|
||||||
|
{{ $t('misc.actions.next') }}
|
||||||
|
</outlined-button>
|
||||||
|
|
||||||
|
<outlined-button
|
||||||
|
v-else
|
||||||
|
@click="showDialog = false; preferencesStore.firstStartup = false"
|
||||||
|
:disabled="preferencesStore.studentName.length == 0 ||
|
||||||
|
preferencesStore.registrationNumber.length == 0"
|
||||||
|
prepend-icon="mdi-check"
|
||||||
|
color="green"
|
||||||
|
>
|
||||||
|
{{ $t('misc.firstStartup.complete') }}
|
||||||
|
</outlined-button>
|
||||||
|
</template>
|
||||||
|
</v-stepper-actions>
|
||||||
|
</template>
|
||||||
|
</v-stepper>
|
||||||
|
</template>
|
||||||
|
</action-dialog>
|
||||||
|
</template>
|
||||||
@@ -1,7 +1,8 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import pageSetup from './pageSetup.vue';
|
import pageSetup from './pageSetupSection.vue';
|
||||||
import systemSetup from './systemSetup.vue';
|
import systemSetup from './systemSetupSection.vue';
|
||||||
import aboutSection from './aboutSection.vue';
|
import aboutSection from './aboutSection.vue';
|
||||||
|
import userSection from './userSection.vue';
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@@ -12,6 +13,12 @@ import aboutSection from './aboutSection.vue';
|
|||||||
</v-col>
|
</v-col>
|
||||||
</v-row>
|
</v-row>
|
||||||
|
|
||||||
|
<v-row>
|
||||||
|
<v-col>
|
||||||
|
<user-section />
|
||||||
|
</v-col>
|
||||||
|
</v-row>
|
||||||
|
|
||||||
<v-row>
|
<v-row>
|
||||||
<v-col>
|
<v-col>
|
||||||
<system-setup />
|
<system-setup />
|
||||||
|
|||||||
@@ -1,21 +1,10 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ThemeEnum } from '@/data/enums/themeEnums';
|
import { ThemeEnum } from '@/data/enums/themeEnums';
|
||||||
import { useTheme } from 'vuetify/lib/framework.mjs';
|
|
||||||
import { i18n } from '@/plugins/i18n';
|
|
||||||
import cardView from '@/components/basics/cardView.vue';
|
import cardView from '@/components/basics/cardView.vue';
|
||||||
import { usePreferencesStore } from '@/stores/preferences.store';
|
import { usePreferencesStore } from '@/stores/preferences.store';
|
||||||
|
|
||||||
const preferencesStore = usePreferencesStore()
|
const preferencesStore = usePreferencesStore()
|
||||||
const theme = useTheme()
|
|
||||||
const themeEnums = Object.values(ThemeEnum)
|
const themeEnums = Object.values(ThemeEnum)
|
||||||
|
|
||||||
function changeTheme() {
|
|
||||||
theme.global.name.value = preferencesStore.theme
|
|
||||||
}
|
|
||||||
|
|
||||||
function changeLanguage() {
|
|
||||||
i18n.global.locale = preferencesStore.language
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@@ -29,7 +18,6 @@ function changeLanguage() {
|
|||||||
v-model="preferencesStore.theme"
|
v-model="preferencesStore.theme"
|
||||||
:items="themeEnums"
|
:items="themeEnums"
|
||||||
:label="$t('preferences.selectedTheme')"
|
:label="$t('preferences.selectedTheme')"
|
||||||
@update:model-value="changeTheme"
|
|
||||||
variant="outlined"
|
variant="outlined"
|
||||||
hide-details
|
hide-details
|
||||||
/>
|
/>
|
||||||
@@ -42,7 +30,6 @@ function changeLanguage() {
|
|||||||
v-model="preferencesStore.language"
|
v-model="preferencesStore.language"
|
||||||
:items="$i18n.availableLocales"
|
:items="$i18n.availableLocales"
|
||||||
:label="$t('preferences.language')"
|
:label="$t('preferences.language')"
|
||||||
@update:model-value="changeLanguage"
|
|
||||||
variant="outlined"
|
variant="outlined"
|
||||||
hide-details
|
hide-details
|
||||||
/>
|
/>
|
||||||
@@ -1,84 +0,0 @@
|
|||||||
<script setup lang="ts">
|
|
||||||
import cardView from '@/components/basics/cardView.vue';
|
|
||||||
import outlinedButton from '@/components/basics/outlinedButton.vue';
|
|
||||||
import confirmDialog from '@/components/basics/confirmDialog.vue';
|
|
||||||
import { ServerStateEnum } from '@/data/enums/serverStateEnum';
|
|
||||||
import { usePreferencesStore } from '@/stores/preferences.store';
|
|
||||||
|
|
||||||
const preferenceStore = usePreferencesStore()
|
|
||||||
|
|
||||||
preferenceStore.getServerState()
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<card-view
|
|
||||||
:title="$t('preferences.systemSetup')"
|
|
||||||
icon="mdi-engine"
|
|
||||||
>
|
|
||||||
<v-row>
|
|
||||||
<v-col>
|
|
||||||
{{ $t('preferences.serverState') }}:
|
|
||||||
<span v-if="preferenceStore.serverState == ServerStateEnum.ONLINE" class="text-green">
|
|
||||||
<v-icon icon="mdi-check" />
|
|
||||||
Online
|
|
||||||
</span>
|
|
||||||
|
|
||||||
<span v-else-if="preferenceStore.serverState == ServerStateEnum.OFFLINE" class="text-red">
|
|
||||||
<v-icon icon="mdi-alert-circle" />
|
|
||||||
Offline
|
|
||||||
</span>
|
|
||||||
|
|
||||||
<span v-else-if="preferenceStore.serverState == ServerStateEnum.PENDING" class="text-orange">
|
|
||||||
<v-icon icon="mdi-clock" />
|
|
||||||
Pending...
|
|
||||||
</span>
|
|
||||||
</v-col>
|
|
||||||
</v-row>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<v-row>
|
|
||||||
<v-col class="d-flex justify-center align-center">
|
|
||||||
<outlined-button
|
|
||||||
@click="preferenceStore.showDeleteDbDialog = true"
|
|
||||||
prepend-icon="mdi-database-refresh"
|
|
||||||
color="red"
|
|
||||||
:disabled="preferenceStore.serverState != ServerStateEnum.ONLINE"
|
|
||||||
>
|
|
||||||
{{ $t('preferences.resetDatabase.resetDatabase') }}
|
|
||||||
</outlined-button>
|
|
||||||
</v-col>
|
|
||||||
</v-row>
|
|
||||||
|
|
||||||
<v-row>
|
|
||||||
<v-col class="d-flex justify-center align-center">
|
|
||||||
<outlined-button
|
|
||||||
@click="preferenceStore.showDeleteExerciseDialog = true"
|
|
||||||
prepend-icon="mdi-progress-close"
|
|
||||||
color="red"
|
|
||||||
:disabled="preferenceStore.serverState != ServerStateEnum.ONLINE"
|
|
||||||
>
|
|
||||||
{{ $t('preferences.resetExerciseProgress.resetExerciseProgress') }}
|
|
||||||
</outlined-button>
|
|
||||||
</v-col>
|
|
||||||
</v-row>
|
|
||||||
</card-view>
|
|
||||||
|
|
||||||
<!-- Confirm delete database -->
|
|
||||||
<confirm-dialog
|
|
||||||
:title="$t('preferences.resetDatabase.dialog.title')"
|
|
||||||
:description="$t('preferences.resetDatabase.dialog.description')"
|
|
||||||
v-model="preferenceStore.showDeleteDbDialog"
|
|
||||||
:onConfirm="preferenceStore.resetDb"
|
|
||||||
:loading="preferenceStore.fetchInProgress"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<!-- Confirm delete exercise progress -->
|
|
||||||
<confirm-dialog
|
|
||||||
:title="$t('preferences.resetExerciseProgress.dialog.title')"
|
|
||||||
:description="$t('preferences.resetExerciseProgress.dialog.description')"
|
|
||||||
v-model="preferenceStore.showDeleteExerciseDialog"
|
|
||||||
:onConfirm="preferenceStore.resetExerciseProg"
|
|
||||||
:loading="preferenceStore.fetchInProgress"
|
|
||||||
/>
|
|
||||||
</template>
|
|
||||||
@@ -0,0 +1,91 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import cardView from '@/components/basics/cardView.vue';
|
||||||
|
import outlinedButton from '@/components/basics/outlinedButton.vue';
|
||||||
|
import confirmDialog from '@/components/basics/confirmDialog.vue';
|
||||||
|
import { ServerStateEnum } from '@/data/enums/serverStateEnum';
|
||||||
|
import { usePreferencesStore } from '@/stores/preferences.store';
|
||||||
|
import ServerStateText from '@/components/pageParts/serverStateText.vue';
|
||||||
|
import { useRouter } from 'vue-router';
|
||||||
|
|
||||||
|
const preferenceStore = usePreferencesStore()
|
||||||
|
const router = useRouter()
|
||||||
|
|
||||||
|
preferenceStore.getServerState()
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<card-view
|
||||||
|
:title="$t('preferences.systemSetup')"
|
||||||
|
icon="mdi-engine"
|
||||||
|
>
|
||||||
|
<template #borderless>
|
||||||
|
<v-list>
|
||||||
|
<v-list-item class="text-h6 text-center">
|
||||||
|
{{ $t('preferences.serverState') }}: <server-state-text />
|
||||||
|
</v-list-item>
|
||||||
|
|
||||||
|
<v-list-item class="text-center">
|
||||||
|
<outlined-button
|
||||||
|
@click="preferenceStore.showDeleteDbDialog = true"
|
||||||
|
prepend-icon="mdi-database-refresh"
|
||||||
|
color="red"
|
||||||
|
:disabled="preferenceStore.serverState != ServerStateEnum.ONLINE || preferenceStore.fetchInProgress"
|
||||||
|
>
|
||||||
|
{{ $t('preferences.resetDatabase.resetDatabase') }}
|
||||||
|
</outlined-button>
|
||||||
|
</v-list-item>
|
||||||
|
|
||||||
|
<v-list-item class="text-center">
|
||||||
|
<outlined-button
|
||||||
|
@click="preferenceStore.showDeleteExerciseDialog = true"
|
||||||
|
prepend-icon="mdi-progress-close"
|
||||||
|
color="red"
|
||||||
|
:disabled="preferenceStore.serverState != ServerStateEnum.ONLINE || preferenceStore.fetchInProgress"
|
||||||
|
>
|
||||||
|
{{ $t('preferences.resetExerciseProgress.resetExerciseProgress') }}
|
||||||
|
</outlined-button>
|
||||||
|
</v-list-item>
|
||||||
|
|
||||||
|
<v-list-item class="text-center">
|
||||||
|
<outlined-button
|
||||||
|
@click="preferenceStore.showFactoryResetDialog = true"
|
||||||
|
prepend-icon="mdi-factory"
|
||||||
|
color="red"
|
||||||
|
:disabled="preferenceStore.serverState != ServerStateEnum.ONLINE || preferenceStore.fetchInProgress"
|
||||||
|
>
|
||||||
|
{{ $t('preferences.factoryReset.factoryReset') }}
|
||||||
|
</outlined-button>
|
||||||
|
</v-list-item>
|
||||||
|
</v-list>
|
||||||
|
</template>
|
||||||
|
</card-view>
|
||||||
|
|
||||||
|
<!-- Confirm delete database -->
|
||||||
|
<confirm-dialog
|
||||||
|
:title="$t('preferences.resetDatabase.dialog.title')"
|
||||||
|
:description="$t('preferences.resetDatabase.dialog.description')"
|
||||||
|
v-model="preferenceStore.showDeleteDbDialog"
|
||||||
|
:onConfirm="preferenceStore.resetDb"
|
||||||
|
:loading="preferenceStore.fetchInProgress"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<!-- Confirm delete exercise progress -->
|
||||||
|
<confirm-dialog
|
||||||
|
:title="$t('preferences.resetExerciseProgress.dialog.title')"
|
||||||
|
:description="$t('preferences.resetExerciseProgress.dialog.description')"
|
||||||
|
v-model="preferenceStore.showDeleteExerciseDialog"
|
||||||
|
:onConfirm="preferenceStore.resetExerciseProg"
|
||||||
|
:loading="preferenceStore.fetchInProgress"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<confirm-dialog
|
||||||
|
:title="$t('preferences.factoryReset.dialog.title')"
|
||||||
|
:description="$t('preferences.factoryReset.dialog.description')"
|
||||||
|
v-model="preferenceStore.showFactoryResetDialog"
|
||||||
|
:onConfirm="() => {
|
||||||
|
preferenceStore.resetToFactorySettings()
|
||||||
|
router.push('/')
|
||||||
|
}"
|
||||||
|
:loading="preferenceStore.fetchInProgress"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
32
software/src/pages/misc/preferencesPage/userSection.vue
Normal file
32
software/src/pages/misc/preferencesPage/userSection.vue
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import cardView from '@/components/basics/cardView.vue';
|
||||||
|
import { usePreferencesStore } from '@/stores/preferences.store';
|
||||||
|
|
||||||
|
const preferencesStore = usePreferencesStore()
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<card-view icon="mdi-account-school" :title="$t('misc.user')">
|
||||||
|
<v-row>
|
||||||
|
<v-col>
|
||||||
|
<v-text-field
|
||||||
|
variant="outlined"
|
||||||
|
hide-details
|
||||||
|
:label="$t('misc.yourFullName')"
|
||||||
|
v-model="preferencesStore.studentName"
|
||||||
|
/>
|
||||||
|
</v-col>
|
||||||
|
</v-row>
|
||||||
|
|
||||||
|
<v-row>
|
||||||
|
<v-col>
|
||||||
|
<v-text-field
|
||||||
|
variant="outlined"
|
||||||
|
hide-details
|
||||||
|
:label="$t('misc.registrationNumber')"
|
||||||
|
v-model="preferencesStore.registrationNumber"
|
||||||
|
/>
|
||||||
|
</v-col>
|
||||||
|
</v-row>
|
||||||
|
</card-view>
|
||||||
|
</template>
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
import BasketPage from "@/pages/misc/basketPage/index.vue"
|
import BasketPage from "@/pages/misc/basketPage/index.vue"
|
||||||
import HomePage from "@/pages/homePage/index.vue"
|
import HomePage from "@/pages/misc/homePage/index.vue"
|
||||||
import { adminRoutes } from "./admin.routes";
|
import { adminRoutes } from "./admin.routes";
|
||||||
import BandsPage from "@/pages/bands/bandsPage/index.vue"
|
import BandsPage from "@/pages/bands/bandsPage/index.vue"
|
||||||
import BandDetailPage from "@/pages/bands/bandDetailPage/index.vue"
|
import BandDetailPage from "@/pages/bands/bandDetailPage/index.vue"
|
||||||
|
|||||||
@@ -7,11 +7,12 @@ import { fetchFileNames, fetchServerState, resetDatabase, resetExerciseProgress
|
|||||||
import { ServerStateEnum } from "@/data/enums/serverStateEnum";
|
import { ServerStateEnum } from "@/data/enums/serverStateEnum";
|
||||||
import { BannerStateEnum } from "@/data/enums/bannerStateEnum";
|
import { BannerStateEnum } from "@/data/enums/bannerStateEnum";
|
||||||
import { useFeedbackStore } from "./feedback.store";
|
import { useFeedbackStore } from "./feedback.store";
|
||||||
|
import { useBasketStore } from "./basket.store";
|
||||||
|
|
||||||
export const usePreferencesStore = defineStore('preferencesStore', {
|
export const usePreferencesStore = defineStore('preferencesStore', {
|
||||||
state: () => ({
|
state: () => ({
|
||||||
/** Selected theme by user */
|
/** Selected theme by user */
|
||||||
theme: useLocalStorage<ThemeEnum>("hackmycart/preferencesStore/theme", ThemeEnum.DARKBLUE),
|
theme: useLocalStorage<ThemeEnum>("hackmycart/preferencesStore/theme", ThemeEnum.DARK),
|
||||||
|
|
||||||
/** Selected language by user */
|
/** Selected language by user */
|
||||||
language: useLocalStorage<LanguageEnum>("hackmycart/preferencesStore/language", LanguageEnum.GERMAN),
|
language: useLocalStorage<LanguageEnum>("hackmycart/preferencesStore/language", LanguageEnum.GERMAN),
|
||||||
@@ -28,11 +29,20 @@ export const usePreferencesStore = defineStore('preferencesStore', {
|
|||||||
/** Show the "Delete Exercise progress?" confirm dialog */
|
/** Show the "Delete Exercise progress?" confirm dialog */
|
||||||
showDeleteExerciseDialog: ref(false),
|
showDeleteExerciseDialog: ref(false),
|
||||||
|
|
||||||
|
/** Show the "Factory reset" confirm dialog */
|
||||||
|
showFactoryResetDialog: ref(false),
|
||||||
|
|
||||||
/** List of files on the server */
|
/** List of files on the server */
|
||||||
staticFiles: ref([]),
|
staticFiles: ref([]),
|
||||||
|
|
||||||
/** Marks the first run of the app */
|
/** Marks the first run of the app */
|
||||||
firstStartup: useLocalStorage<Boolean>("hackmycart/preferencesStore/firstStartup", true)
|
firstStartup: useLocalStorage<Boolean>("hackmycart/preferencesStore/firstStartup", true),
|
||||||
|
|
||||||
|
/** Full name of student */
|
||||||
|
studentName: useLocalStorage<String>("hackmycart/preferencesStore/studentName", ""),
|
||||||
|
|
||||||
|
/** Matrikel number */
|
||||||
|
registrationNumber: useLocalStorage<String>("hackmycart/preferencesStore/registrationNumber", "")
|
||||||
}),
|
}),
|
||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
@@ -108,11 +118,17 @@ export const usePreferencesStore = defineStore('preferencesStore', {
|
|||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
async firstStartupRoutine() {
|
resetToFactorySettings() {
|
||||||
await this.resetDb()
|
const basketStore = useBasketStore()
|
||||||
await this.resetExerciseProg()
|
|
||||||
|
|
||||||
this.firstStartup = false
|
this.firstStartup = true
|
||||||
|
this.studentName = ""
|
||||||
|
this.registrationNumber = ""
|
||||||
|
this.theme = "dark"
|
||||||
|
this.language = LanguageEnum.GERMAN
|
||||||
|
basketStore.itemsInBasket = []
|
||||||
|
|
||||||
|
this.showFactoryResetDialog = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
Reference in New Issue
Block a user