From 190cf626f9189d294d15986561d4103a58acbca8 Mon Sep 17 00:00:00 2001 From: "Torsten Schulz (local)" Date: Wed, 4 Mar 2026 23:22:16 +0100 Subject: [PATCH] Add functionality for managing user-owned chat rooms: Implement getOwnRooms and deleteOwnRoom methods in ChatController and ChatService, add corresponding API routes in chatRouter, and enhance MultiChatDialog for displaying and deleting owned rooms with localized messages. Update i18n files for new features. --- backend/controllers/chatController.js | 28 +++ backend/routers/chatRouter.js | 2 + backend/services/chatService.js | 41 +++++ frontend/src/api/chatApi.js | 9 + .../src/dialogues/chat/MultiChatDialog.vue | 160 +++++++++++++++++- frontend/src/i18n/locales/de/chat.json | 40 ++++- frontend/src/i18n/locales/en/chat.json | 40 ++++- frontend/src/i18n/locales/es/chat.json | 40 ++++- 8 files changed, 334 insertions(+), 26 deletions(-) diff --git a/backend/controllers/chatController.js b/backend/controllers/chatController.js index 411e970..6f8b537 100644 --- a/backend/controllers/chatController.js +++ b/backend/controllers/chatController.js @@ -14,6 +14,8 @@ class ChatController { this.getOneToOneMessageHistory = this.getOneToOneMessageHistory.bind(this); this.getRoomList = this.getRoomList.bind(this); this.getRoomCreateOptions = this.getRoomCreateOptions.bind(this); + this.getOwnRooms = this.getOwnRooms.bind(this); + this.deleteOwnRoom = this.deleteOwnRoom.bind(this); } async getMessages(req, res) { @@ -185,6 +187,32 @@ class ChatController { res.status(500).json({ error: error.message }); } } + + async getOwnRooms(req, res) { + try { + const { userid: hashedUserId } = req.headers; + const rooms = await chatService.getOwnRooms(hashedUserId); + res.status(200).json(rooms); + } catch (error) { + const status = error.message === 'user_not_found' ? 404 : 500; + res.status(status).json({ error: error.message }); + } + } + + async deleteOwnRoom(req, res) { + try { + const { userid: hashedUserId } = req.headers; + const roomId = Number.parseInt(req.params.id, 10); + if (!Number.isInteger(roomId) || roomId <= 0) { + return res.status(400).json({ error: 'invalid_room_id' }); + } + await chatService.deleteOwnRoom(hashedUserId, roomId); + res.status(204).send(); + } catch (error) { + const status = error.message === 'room_not_found_or_not_owner' || error.message === 'user_not_found' ? 404 : 500; + res.status(status).json({ error: error.message }); + } + } } export default ChatController; diff --git a/backend/routers/chatRouter.js b/backend/routers/chatRouter.js index ee4bfd9..c52ab69 100644 --- a/backend/routers/chatRouter.js +++ b/backend/routers/chatRouter.js @@ -16,5 +16,7 @@ router.post('/oneToOne/sendMessage', authenticate, chatController.sendOneToOneMe router.get('/oneToOne/messageHistory', authenticate, chatController.getOneToOneMessageHistory); // Neue Route zum Abrufen der Nachrichtengeschichte router.get('/rooms', chatController.getRoomList); router.get('/room-create-options', authenticate, chatController.getRoomCreateOptions); +router.get('/my-rooms', authenticate, chatController.getOwnRooms); +router.delete('/my-rooms/:id', authenticate, chatController.deleteOwnRoom); export default router; diff --git a/backend/services/chatService.js b/backend/services/chatService.js index 255c1ef..393c96a 100644 --- a/backend/services/chatService.js +++ b/backend/services/chatService.js @@ -1,5 +1,7 @@ import { v4 as uuidv4 } from 'uuid'; import amqp from 'amqplib/callback_api.js'; +import User from '../models/community/user.js'; +import Room from '../models/chat/room.js'; const RABBITMQ_URL = 'amqp://localhost'; const QUEUE = 'oneToOne_messages'; @@ -169,6 +171,45 @@ class ChatService { roomTypes: interests.map((i) => ({ id: i.id, name: i.name })) }; } + + async getOwnRooms(hashedUserId) { + const user = await User.findOne({ + where: { hashedId: hashedUserId }, + attributes: ['id'] + }); + if (!user) { + throw new Error('user_not_found'); + } + + return Room.findAll({ + where: { ownerId: user.id }, + attributes: ['id', 'title', 'isPublic', 'roomTypeId', 'ownerId'], + order: [['title', 'ASC']] + }); + } + + async deleteOwnRoom(hashedUserId, roomId) { + const user = await User.findOne({ + where: { hashedId: hashedUserId }, + attributes: ['id'] + }); + if (!user) { + throw new Error('user_not_found'); + } + + const deleted = await Room.destroy({ + where: { + id: roomId, + ownerId: user.id + } + }); + + if (!deleted) { + throw new Error('room_not_found_or_not_owner'); + } + + return true; + } } export default new ChatService(); diff --git a/frontend/src/api/chatApi.js b/frontend/src/api/chatApi.js index da86789..6454630 100644 --- a/frontend/src/api/chatApi.js +++ b/frontend/src/api/chatApi.js @@ -9,3 +9,12 @@ export const fetchRoomCreateOptions = async () => { const response = await apiClient.get("/api/chat/room-create-options"); return response.data; }; + +export const fetchOwnRooms = async () => { + const response = await apiClient.get("/api/chat/my-rooms"); + return response.data; +}; + +export const deleteOwnRoom = async (roomId) => { + await apiClient.delete(`/api/chat/my-rooms/${roomId}`); +}; diff --git a/frontend/src/dialogues/chat/MultiChatDialog.vue b/frontend/src/dialogues/chat/MultiChatDialog.vue index 2eada01..3de2e1d 100644 --- a/frontend/src/dialogues/chat/MultiChatDialog.vue +++ b/frontend/src/dialogues/chat/MultiChatDialog.vue @@ -71,17 +71,17 @@ {{ $t('chat.multichat.createRoom.labels.visibility') }}