Files
breakpilot-lehrer/studio-v2/app/messages/_components/useMessagesPage.ts
Benjamin Admin 0b37c5e692 [split-required] Split website + studio-v2 monoliths (Phase 3 continued)
Website (14 monoliths split):
- compliance/page.tsx (1,519 → 9), docs/audit (1,262 → 20)
- quality (1,231 → 16), alerts (1,203 → 10), docs (1,202 → 11)
- i18n.ts (1,173 → 8 language files)
- unity-bridge (1,094 → 12), backlog (1,087 → 6)
- training (1,066 → 8), rag (1,063 → 8)
- Deleted index_original.ts (4,899 LOC dead backup)

Studio-v2 (5 monoliths split):
- meet/page.tsx (1,481 → 9), messages (1,166 → 9)
- AlertsB2BContext.tsx (1,165 → 5 modules)
- alerts-b2b/page.tsx (1,019 → 6), korrektur/archiv (1,001 → 6)

All existing imports preserved. Zero new TypeScript errors.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-24 17:52:36 +02:00

167 lines
4.9 KiB
TypeScript

'use client'
import { useState, useEffect, useMemo } from 'react'
import {
useMessages,
formatMessageDate,
type Conversation,
type Message,
type Contact,
} from '@/lib/MessagesContext'
export function useMessagesPage() {
const messagesCtx = useMessages()
const {
contacts,
conversations,
messages,
templates,
unreadCount,
recentConversations,
sendMessage,
markAsRead,
createConversation,
addReaction,
deleteMessage,
pinConversation,
muteConversation,
currentConversationId,
setCurrentConversationId,
} = messagesCtx
const [messageInput, setMessageInput] = useState('')
const [sendWithEmail, setSendWithEmail] = useState(false)
const [isSending, setIsSending] = useState(false)
const [showNewConversation, setShowNewConversation] = useState(false)
const [showEmojiPicker, setShowEmojiPicker] = useState(false)
const [showTemplates, setShowTemplates] = useState(false)
const [showContactInfo, setShowContactInfo] = useState(false)
const [searchQuery, setSearchQuery] = useState('')
const [contextMenu, setContextMenu] = useState<{ x: number; y: number; messageId: string } | null>(null)
// Current conversation data
const currentConversation = conversations.find(c => c.id === currentConversationId)
const currentMessages = currentConversationId ? (messages[currentConversationId] || []) : []
// Find contact for conversation
const getConversationContact = (conv: Conversation): Contact | undefined => {
if (conv.is_group) return undefined
return contacts.find(c => conv.participant_ids.includes(c.id))
}
// Get sender name for group messages
const getSenderName = (senderId: string): string => {
if (senderId === 'self') return 'Du'
const contact = contacts.find(c => c.id === senderId)
return contact?.name?.split(' ')[0] || 'Unbekannt'
}
// Filter conversations by search
const filteredConversations = useMemo(() => {
if (!searchQuery) return recentConversations
const q = searchQuery.toLowerCase()
return recentConversations.filter(c =>
c.title?.toLowerCase().includes(q) ||
c.last_message?.toLowerCase().includes(q)
)
}, [recentConversations, searchQuery])
// Group messages by date
const groupedMessages = useMemo(() => {
const groups: { date: string; messages: Message[] }[] = []
let currentDate = ''
for (const msg of currentMessages) {
const msgDate = formatMessageDate(msg.timestamp)
if (msgDate !== currentDate) {
currentDate = msgDate
groups.push({ date: msgDate, messages: [] })
}
groups[groups.length - 1].messages.push(msg)
}
return groups
}, [currentMessages])
// Select conversation
const selectConversation = async (conv: Conversation) => {
setCurrentConversationId(conv.id)
if (conv.unread_count > 0) {
await markAsRead(conv.id)
}
setShowContactInfo(false)
}
// Send message
const handleSendMessage = async () => {
if (!messageInput.trim() || !currentConversationId) return
setIsSending(true)
await sendMessage(currentConversationId, messageInput.trim(), sendWithEmail)
setMessageInput('')
setIsSending(false)
setShowEmojiPicker(false)
setShowTemplates(false)
}
// Insert emoji
const handleEmojiSelect = (emoji: string) => {
setMessageInput(prev => prev + emoji)
}
// Start new conversation
const handleStartConversation = async (contact: Contact) => {
const conv = await createConversation(contact.id)
if (conv) {
setCurrentConversationId(conv.id)
setShowNewConversation(false)
}
}
// Handle context menu
const handleContextMenu = (e: React.MouseEvent, messageId: string) => {
e.preventDefault()
setContextMenu({ x: e.clientX, y: e.clientY, messageId })
}
// Close context menu on click outside
useEffect(() => {
const handleClick = () => setContextMenu(null)
if (contextMenu) {
document.addEventListener('click', handleClick)
return () => document.removeEventListener('click', handleClick)
}
}, [contextMenu])
const currentContact = currentConversation ? getConversationContact(currentConversation) : undefined
return {
// Context data
contacts, templates, unreadCount,
currentConversationId, currentConversation, currentContact,
filteredConversations, groupedMessages,
// UI state
messageInput, setMessageInput,
sendWithEmail, setSendWithEmail,
isSending,
showNewConversation, setShowNewConversation,
showEmojiPicker, setShowEmojiPicker,
showTemplates, setShowTemplates,
showContactInfo, setShowContactInfo,
searchQuery, setSearchQuery,
contextMenu, setContextMenu,
// Actions
selectConversation,
handleSendMessage,
handleEmojiSelect,
handleStartConversation,
handleContextMenu,
getSenderName,
getConversationContact,
// From context
pinConversation,
muteConversation,
deleteMessage,
}
}