Add Vocab Trainer feature with routing, database schema, and translations

- Introduced Vocab Trainer functionality, including new routes for managing languages and chapters.
- Implemented database schema for vocab-related tables to ensure data integrity.
- Updated navigation and UI components to include Vocab Trainer in the social network menu.
- Added translations for Vocab Trainer in both German and English locales, enhancing user accessibility.
This commit is contained in:
Torsten Schulz (local)
2025-12-30 18:34:32 +01:00
parent a09220b881
commit 83597d9e02
24 changed files with 2135 additions and 3 deletions

View File

@@ -0,0 +1,86 @@
<template>
<h2>{{ $t('socialnetwork.vocab.title') }}</h2>
<div class="box">
<p>{{ $t('socialnetwork.vocab.description') }}</p>
<div class="actions">
<button @click="goNewLanguage">{{ $t('socialnetwork.vocab.newLanguage') }}</button>
</div>
<div v-if="loading">{{ $t('general.loading') }}</div>
<div v-else>
<div v-if="languages.length === 0">
{{ $t('socialnetwork.vocab.none') }}
</div>
<ul v-else>
<li v-for="l in languages" :key="l.id">
<span class="langname" @click="openLanguage(l.id)">{{ l.name }}</span>
<span class="role" v-if="l.isOwner">({{ $t('socialnetwork.vocab.owner') }})</span>
<span class="role" v-else>({{ $t('socialnetwork.vocab.subscribed') }})</span>
</li>
</ul>
</div>
</div>
</template>
<script>
import { mapGetters } from 'vuex';
import apiClient from '@/utils/axios.js';
export default {
name: 'VocabTrainerView',
data() {
return {
loading: false,
languages: [],
};
},
computed: {
...mapGetters(['user']),
},
methods: {
goNewLanguage() {
this.$router.push('/socialnetwork/vocab/new');
},
openLanguage(id) {
this.$router.push(`/socialnetwork/vocab/${id}`);
},
async load() {
this.loading = true;
try {
const res = await apiClient.get('/api/vocab/languages');
this.languages = res.data?.languages || [];
} catch (e) {
console.error('Konnte Vokabel-Sprachen nicht laden:', e);
} finally {
this.loading = false;
}
},
},
mounted() {
this.load();
},
};
</script>
<style scoped>
.box {
background: #f6f6f6;
padding: 12px;
border: 1px solid #ccc;
}
.actions {
margin: 10px 0;
}
.langname {
cursor: pointer;
text-decoration: underline;
}
.role {
margin-left: 6px;
color: #666;
}
</style>