[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>
This commit is contained in:
166
studio-v2/app/messages/_components/useMessagesPage.ts
Normal file
166
studio-v2/app/messages/_components/useMessagesPage.ts
Normal file
@@ -0,0 +1,166 @@
|
||||
'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,
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user