Welcome dialog: New page for look and feel, redesign pages, merge database and exercise creating in one step

This commit is contained in:
2025-07-05 14:35:48 +02:00
parent 48c59936ec
commit b69c63ea53
8 changed files with 196 additions and 88 deletions

View File

@@ -229,6 +229,7 @@
"cancel": "Abbrechen",
"more": "Mehr",
"confirm": "Bestätigen",
"back": "Zurück",
"next": "Weiter"
},
"validation": {
@@ -245,7 +246,7 @@
"firstStartup": {
"title": "Ersteinrichtung",
"description": "Die Datenbank wird eingerichtet. Bitte warten...",
"createDatabase": "Erstelle Datenbank...",
"createDatabase": "Datenbank Einrichtung",
"complete": "Fertig",
"finished": "Abgeschlossen",
"createExercises": "Erstelle Aufgaben...",
@@ -253,6 +254,7 @@
"database": "Datenbank",
"exercises": "Aufgaben",
"userData": "Persönliche Daten",
"lookAndFeel": "Look and feel",
"enterYourPersonalData": "Bitte gebe nun deinen Namen und deine Matrikelnummer von der Universität ein. Überprüfe die Angaben vor dem Absenden genau! Die Angaben können später nicht ohne Verlust des Bearbeitungsfortschrittes geändert werden!"
},
"user": "Angaben zur Person",

View File

@@ -229,6 +229,7 @@
"cancel": "Cancel",
"more": "More",
"confirm": "Confirm",
"back": "Back",
"next": "Next"
},
"validation": {
@@ -245,14 +246,13 @@
"firstStartup": {
"title": "First startup",
"description": "Creating database. Please wait...",
"createDatabase": "Create Database...",
"createDatabase": "Create Database",
"complete": "Complete",
"createExercises": "Create Exercises...",
"finished": "Finished",
"connectToServer": "Server",
"database": "Database",
"exercises": "Exercises",
"userData": "User data",
"lookAndFeel": "Look and feel",
"enterYourPersonalData": "Please enter your name and your Matrikel number from your university. Check it twice! You can't change it later without loosing your exercise progress!"
},
"user": "About person",

View File

@@ -5,7 +5,7 @@ import bandSection from './bandsSection.vue';
import UpcomingConcertsSection from './upcomingConcertsSection.vue';
import TopLocationsSection from './topLocationsSection.vue';
import { usePreferencesStore } from '@/stores/preferences.store';
import welcomeDialog from './welcomeDialog.vue';
import welcomeDialog from './welcomeDialog/dialog.vue';
import { ref } from 'vue';
const concertStore = useConcertStore()
@@ -17,8 +17,8 @@ concertStore.getUpcomingConcerts()
locationStore.getTopLocations()
// First startup
showWelcomeDialog.value = true
if (preferencesStore.firstStartup) {
showWelcomeDialog.value = true
}
</script>

View File

@@ -1,43 +1,36 @@
<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 { getRegisterNumberRules, getStringRules } from '@/scripts/validationRules';
import { useFeedbackStore } from '@/stores/feedback.store';
import { usePreferencesStore } from '@/stores/preferences.store';
import { ref, watch } from 'vue';
import step1 from './step1.vue';
import step2 from './step2.vue';
import step3 from './step3.vue';
import step4 from './step4.vue';
const preferencesStore = usePreferencesStore()
const feedbackStore = useFeedbackStore()
const showDialog = defineModel()
const currentStep = ref(0)
const currentStep = ref(1)
const databaseCreated = ref(false)
const steps = [
feedbackStore.i18n.t('misc.firstStartup.connectToServer'),
feedbackStore.i18n.t('misc.firstStartup.lookAndFeel'),
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;
}
watch(() => currentStep.value, async () => {
if (currentStep.value == 3 && !databaseCreated.value) {
await preferencesStore.resetDb();
await preferencesStore.resetExerciseProg();
case 3: {
preferencesStore.resetExerciseProg();
break;
}
case 4: {
break;
}
databaseCreated.value = true;
}
})
</script>
@@ -77,83 +70,31 @@ watch(() => currentStep.value, () => {
<!-- Step 1: Check connection to backend server -->
<v-stepper-window-item
:value="1"
class="text-h4 text-center"
>
<div>
{{ $t('preferences.serverState') + ':' }}
</div>
<server-state-text />
<step1 />
</v-stepper-window-item>
<!-- Step 2: Reset the database -->
<!-- Step 2: Select theme and language -->
<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>
<step2 />
</v-stepper-window-item>
<!-- Step 3: Create exercises -->
<!-- Step 3: Reset the database -->
<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>
<step3 />
</v-stepper-window-item>
<!-- Step 4: Personal data -->
<v-stepper-window-item
:value="4"
>
<v-container class="px-0 py-2">
<v-row>
<v-col>
<v-alert color="warning" icon="mdi-alert">
{{ $t('misc.firstStartup.enterYourPersonalData') }}
</v-alert>
</v-col>
</v-row>
<v-row>
<v-col>
<v-text-field
variant="outlined"
:label="$t('misc.yourFullName')"
v-model="preferencesStore.studentName"
:rules="getStringRules(4)"
/>
</v-col>
</v-row>
<v-row>
<v-col>
<v-text-field
variant="outlined"
:label="$t('misc.registrationNumber')"
v-model="preferencesStore.registrationNumber"
:rules="getRegisterNumberRules()"
/>
</v-col>
</v-row>
</v-container>
<step4 />
</v-stepper-window-item>
</v-stepper-window>
@@ -161,16 +102,25 @@ watch(() => currentStep.value, () => {
<!-- Next/Previous buttons -->
<v-stepper-actions
@click:next="next"
@click:prev="prev"
>
<template #prev="{ props }">
<v-spacer />
<outlined-button
@click="props.onClick()"
:disabled="currentStep == 1 || preferencesStore.fetchInProgress"
color="grey"
prepend-icon="mdi-arrow-left"
>
{{ $t('misc.actions.back') }}
</outlined-button>
</template>
<template #next="{ props }">
<outlined-button
v-if="currentStep < 4"
v-if="currentStep < steps.length"
@click="props.onClick()"
:disabled="preferencesStore.fetchInProgress"
append-icon="mdi-arrow-right"
>
{{ $t('misc.actions.next') }}
</outlined-button>
@@ -180,7 +130,7 @@ watch(() => currentStep.value, () => {
@click="showDialog = false; preferencesStore.firstStartup = false"
:disabled="preferencesStore.studentName.length < 5 ||
preferencesStore.registrationNumber.length < 8"
prepend-icon="mdi-check"
append-icon="mdi-check"
color="success"
>
{{ $t('misc.firstStartup.complete') }}

View File

@@ -0,0 +1,23 @@
<script setup lang="ts">
import ServerStateText from '@/components/pageParts/serverStateText.vue';
</script>
<template>
<v-container class="text-h4 text-center">
<v-row>
<v-col>
<v-icon icon="mdi-server" />
</v-col>
</v-row>
<v-row>
<v-col>
<div>
{{ $t('preferences.serverState') + ':' }}
</div>
<server-state-text />
</v-col>
</v-row>
</v-container>
</template>

View File

@@ -0,0 +1,48 @@
<script setup lang="ts">
import { ThemeEnum } from '@/data/enums/themeEnums';
import { usePreferencesStore } from '@/stores/preferences.store';
const preferencesStore = usePreferencesStore()
const themeEnums = Object.values(ThemeEnum)
</script>
<template>
<v-container width="600" class="text-h4 text-center">
<v-row>
<v-col>
<v-icon icon="mdi-palette" />
</v-col>
</v-row>
<v-row>
<v-col>
{{ $t('misc.firstStartup.lookAndFeel') }}
</v-col>
</v-row>
<v-row>
<v-col>
<v-select
v-model="preferencesStore.theme"
:items="themeEnums"
:label="$t('preferences.selectedTheme')"
variant="outlined"
hide-details
/>
</v-col>
</v-row>
<v-row>
<v-col>
<v-select
v-model="preferencesStore.language"
:items="$i18n.availableLocales"
:label="$t('preferences.language')"
variant="outlined"
hide-details
/>
</v-col>
</v-row>
</v-container>
</template>

View File

@@ -0,0 +1,31 @@
<script setup lang="ts">
import { usePreferencesStore } from '@/stores/preferences.store';
const preferencesStore = usePreferencesStore()
</script>
<template>
<v-container width="600" class="text-h4 text-center">
<v-row>
<v-col>
<v-icon icon="mdi-database" />
</v-col>
</v-row>
<v-row>
<v-col>
{{ $t('misc.firstStartup.createDatabase') }}
</v-col>
</v-row>
<v-row>
<v-col v-if="preferencesStore.fetchInProgress">
<v-progress-linear indeterminate />
</v-col>
<v-col v-else class="text-green">
<v-icon icon="mdi-check" /> {{ $t('misc.firstStartup.finished') }}
</v-col>
</v-row>
</v-container>
</template>

View File

@@ -0,0 +1,54 @@
<script setup lang="ts">
import { getRegisterNumberRules, getStringRules } from '@/scripts/validationRules';
import { usePreferencesStore } from '@/stores/preferences.store';
const preferencesStore = usePreferencesStore()
</script>
<template>
<v-container class="px-0 py-2" width="600">
<v-row>
<v-col class="text-h4 text-center">
<v-icon icon="mdi-account" />
</v-col>
</v-row>
<v-row>
<v-col class="text-h4 text-center">
{{ $t('misc.firstStartup.userData') }}
</v-col>
</v-row>
<v-row>
<v-col>
<v-alert color="warning" icon="mdi-alert">
{{ $t('misc.firstStartup.enterYourPersonalData') }}
</v-alert>
</v-col>
</v-row>
<v-row>
<v-col>
<v-text-field
variant="outlined"
:label="$t('misc.yourFullName')"
v-model="preferencesStore.studentName"
:rules="getStringRules(4)"
hide-details
/>
</v-col>
</v-row>
<v-row>
<v-col>
<v-text-field
variant="outlined"
:label="$t('misc.registrationNumber')"
v-model="preferencesStore.registrationNumber"
:rules="getRegisterNumberRules()"
hide-details
/>
</v-col>
</v-row>
</v-container>
</template>