191 lines
5.2 KiB
Vue
191 lines
5.2 KiB
Vue
<template>
|
||
<h2>{{ $t('socialnetwork.forum.title') }} {{ forumName }}</h2>
|
||
<div class="creationtoggler">
|
||
<button @click="createNewTopic">
|
||
{{ $t(!inCreation
|
||
? 'socialnetwork.forum.showNewTopic'
|
||
: 'socialnetwork.forum.hideNewTopic') }}
|
||
</button>
|
||
</div>
|
||
|
||
<div v-if="inCreation">
|
||
<div>
|
||
<label class="newtitle">
|
||
{{ $t('socialnetwork.forum.topic') }}
|
||
<input type="text" v-model="newTitle" />
|
||
</label>
|
||
</div>
|
||
<div class="editor-container">
|
||
<EditorContent :editor="editor" class="editor" />
|
||
</div>
|
||
<button @click="saveNewTopic">
|
||
{{ $t('socialnetwork.forum.createNewTopic') }}
|
||
</button>
|
||
</div>
|
||
|
||
<div v-else-if="titles.length > 0">
|
||
<!-- hier kommt deine bestehende TABLE + PAGINATION hin -->
|
||
<table>
|
||
<!-- Kopfzeile, Spalten etc. -->
|
||
</table>
|
||
<div class="pagination">
|
||
<button @click="goToPage(page-1)" :disabled="page<=1">‹</button>
|
||
<span>{{ page }} / {{ totalPages }}</span>
|
||
<button @click="goToPage(page+1)" :disabled="page>=totalPages">›</button>
|
||
</div>
|
||
</div>
|
||
|
||
<div v-else>
|
||
{{ $t('socialnetwork.forum.noTitles') }}
|
||
</div>
|
||
</template>
|
||
|
||
<script>
|
||
import { Editor, EditorContent } from '@tiptap/vue-3'
|
||
import StarterKit from '@tiptap/starter-kit'
|
||
import apiClient from '../../utils/axios'
|
||
|
||
export default {
|
||
name: 'ForumView',
|
||
components: { EditorContent },
|
||
data() {
|
||
return {
|
||
forumName: '',
|
||
page: 1,
|
||
numberOfItems: 0,
|
||
titles: [],
|
||
inCreation: false,
|
||
newTitle: '',
|
||
editor: null,
|
||
}
|
||
},
|
||
computed: {
|
||
// Neu: Forum‑ID immer direkt aus der Route ziehen
|
||
forumId() {
|
||
return this.$route.params.id
|
||
},
|
||
totalPages() {
|
||
return Math.ceil(this.numberOfItems / 25)
|
||
}
|
||
},
|
||
watch: {
|
||
// Sobald sich die Route‑ID ändert, zurück auf Seite 1 und neu laden
|
||
forumId: {
|
||
handler() {
|
||
this.page = 1
|
||
this.loadForum()
|
||
},
|
||
immediate: true
|
||
},
|
||
// Wenn sich die Seite ändert, ebenfalls neu laden
|
||
page(newPage, oldPage) {
|
||
if (newPage !== oldPage) {
|
||
this.loadForum()
|
||
}
|
||
}
|
||
},
|
||
async mounted() {
|
||
// Editor initialisieren
|
||
this.editor = new Editor({
|
||
extensions: [StarterKit],
|
||
content: '',
|
||
})
|
||
},
|
||
beforeUnmount() {
|
||
if (this.editor) this.editor.destroy()
|
||
},
|
||
methods: {
|
||
async loadForum() {
|
||
try {
|
||
const { data } = await apiClient.get(
|
||
`/api/forum/${this.forumId}/${this.page}`
|
||
)
|
||
this.forumName = data.name
|
||
this.titles = data.titles
|
||
this.numberOfItems = data.totalTopics
|
||
} catch (err) {
|
||
console.error('Fehler beim Laden des Forums', err)
|
||
}
|
||
},
|
||
createNewTopic() {
|
||
this.inCreation = !this.inCreation
|
||
if (this.inCreation && this.editor) {
|
||
this.editor.commands.setContent('')
|
||
}
|
||
},
|
||
async saveNewTopic() {
|
||
const content = this.editor ? this.editor.getHTML() : ''
|
||
if (!this.newTitle.trim() || !content.trim()) return
|
||
try {
|
||
const { data } = await apiClient.post(
|
||
'/api/forum/topic',
|
||
{
|
||
forumId: this.forumId,
|
||
title: this.newTitle,
|
||
content
|
||
}
|
||
)
|
||
// Neu: Server kann aktuelle Liste zurückliefern
|
||
this.forumName = data.name
|
||
this.titles = data.titles
|
||
this.numberOfItems = data.totalTopics
|
||
this.page = data.page
|
||
this.inCreation = false
|
||
this.newTitle = ''
|
||
} catch (err) {
|
||
console.error('Fehler beim Erstellen des Themas', err)
|
||
}
|
||
},
|
||
goToPage(page) {
|
||
if (page >= 1 && page <= this.totalPages) {
|
||
this.page = page
|
||
}
|
||
},
|
||
openProfile(id) {
|
||
this.$root.$refs.userProfileDialog.userId = id
|
||
this.$root.$refs.userProfileDialog.open()
|
||
},
|
||
openTopic(topicId) {
|
||
this.$router.push(`/socialnetwork/forumtopic/${topicId}`)
|
||
},
|
||
}
|
||
}
|
||
</script>
|
||
|
||
<style lang="scss" scoped>
|
||
.creationtoggler {
|
||
margin-bottom: 1em;
|
||
}
|
||
.newtitle {
|
||
display: flex;
|
||
gap: 1em;
|
||
vertical-align: middle;
|
||
}
|
||
.newtitle input {
|
||
flex: 1;
|
||
}
|
||
.editor-container {
|
||
margin: 1em 0;
|
||
border: 1px solid #ccc;
|
||
padding: 10px;
|
||
min-height: 200px;
|
||
background-color: white;
|
||
}
|
||
.editor {
|
||
min-height: 150px;
|
||
outline: none;
|
||
}
|
||
.pagination {
|
||
display: flex;
|
||
justify-content: center;
|
||
gap: 0.5em;
|
||
margin: 1em 0;
|
||
}
|
||
.pagination button {
|
||
padding: 0.5em 1em;
|
||
}
|
||
.pagination span {
|
||
padding: 0.5em;
|
||
}
|
||
</style>
|