Files
yourpart3/frontend/src/views/social/ForumView.vue

191 lines
5.2 KiB
Vue
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<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: ForumID immer direkt aus der Route ziehen
forumId() {
return this.$route.params.id
},
totalPages() {
return Math.ceil(this.numberOfItems / 25)
}
},
watch: {
// Sobald sich die RouteID ä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>