feat: Add chat management actions including clear and delete conversation, and enhance session token refresh logic.
This commit is contained in:
@@ -5,6 +5,7 @@ import Image from 'next/image';
|
||||
import { useSession } from 'next-auth/react';
|
||||
import { ChatHeader } from './ChatHeader';
|
||||
import { MessageInput } from './MessageInput';
|
||||
import { ChatDropdownMenu, type DropdownMenuItem } from './ChatDropdownMenu';
|
||||
import { useMessaging } from '@/hooks/useMessaging';
|
||||
import { connectionRequestsService, type ConnectionRequest } from '@/services/connection-requests.service';
|
||||
import { uploadService } from '@/services/upload.service';
|
||||
@@ -107,9 +108,15 @@ export function MessagingPage() {
|
||||
loadMoreMessages,
|
||||
hasMoreMessages,
|
||||
startConversation,
|
||||
markAllAsRead,
|
||||
deleteConversation,
|
||||
clearMessages,
|
||||
} = useMessaging();
|
||||
|
||||
const [searchQuery, setSearchQuery] = useState('');
|
||||
const [isPageMenuOpen, setIsPageMenuOpen] = useState(false);
|
||||
const [isAllMuted, setIsAllMuted] = useState(false);
|
||||
const [confirmDeleteId, setConfirmDeleteId] = useState<string | null>(null);
|
||||
const [isUploading, setIsUploading] = useState(false);
|
||||
const [showScrollButton, setShowScrollButton] = useState(false);
|
||||
const [connectedAgents, setConnectedAgents] = useState<ConnectedAgent[]>([]);
|
||||
@@ -339,6 +346,36 @@ export function MessagingPage() {
|
||||
stopTyping();
|
||||
}, [stopTyping]);
|
||||
|
||||
// Handle delete conversation with confirmation
|
||||
const handleDeleteConversation = useCallback(async () => {
|
||||
if (!currentConversation) return;
|
||||
setConfirmDeleteId(currentConversation.id);
|
||||
}, [currentConversation]);
|
||||
|
||||
const confirmDelete = useCallback(async () => {
|
||||
if (!confirmDeleteId) return;
|
||||
try {
|
||||
await deleteConversation(confirmDeleteId);
|
||||
} catch (error) {
|
||||
console.error('Failed to delete conversation:', error);
|
||||
}
|
||||
setConfirmDeleteId(null);
|
||||
}, [confirmDeleteId, deleteConversation]);
|
||||
|
||||
// Page header menu items
|
||||
const pageMenuItems: DropdownMenuItem[] = [
|
||||
{
|
||||
label: 'Mark All as Read',
|
||||
onClick: () => {
|
||||
markAllAsRead().catch(console.error);
|
||||
},
|
||||
},
|
||||
{
|
||||
label: isAllMuted ? 'Unmute All Notifications' : 'Mute All Notifications',
|
||||
onClick: () => setIsAllMuted((prev) => !prev),
|
||||
},
|
||||
];
|
||||
|
||||
// Handle scroll events
|
||||
const handleScroll = () => {
|
||||
if (messagesContainerRef.current) {
|
||||
@@ -420,6 +457,35 @@ export function MessagingPage() {
|
||||
return (
|
||||
<>
|
||||
<style>{customScrollbarStyles}</style>
|
||||
|
||||
{/* Delete confirmation dialog */}
|
||||
{confirmDeleteId && (
|
||||
<div className="fixed inset-0 bg-black/50 flex items-center justify-center z-50">
|
||||
<div className="bg-white rounded-[15px] p-6 max-w-[400px] w-full mx-4 shadow-xl">
|
||||
<h3 className="font-fractul font-bold text-[16px] text-[#00293D] mb-2">
|
||||
Delete Conversation
|
||||
</h3>
|
||||
<p className="font-serif font-normal text-[14px] text-[#00293D]/70 mb-6">
|
||||
Are you sure you want to delete this conversation? This action cannot be undone and all messages will be permanently removed.
|
||||
</p>
|
||||
<div className="flex items-center justify-end gap-3">
|
||||
<button
|
||||
onClick={() => setConfirmDeleteId(null)}
|
||||
className="px-4 py-2 font-serif font-normal text-[14px] text-[#00293D] rounded-[10px] border border-[#00293d]/10 hover:bg-gray-50 transition-colors cursor-pointer"
|
||||
>
|
||||
Cancel
|
||||
</button>
|
||||
<button
|
||||
onClick={confirmDelete}
|
||||
className="px-4 py-2 font-serif font-normal text-[14px] text-white bg-red-600 rounded-[10px] hover:bg-red-700 transition-colors cursor-pointer"
|
||||
>
|
||||
Delete
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className="border border-[#00293d]/10 rounded-[20px] bg-white overflow-hidden">
|
||||
{/* Header */}
|
||||
<div className="flex items-center gap-4 p-4 border-b border-[#00293d]/10">
|
||||
@@ -456,14 +522,24 @@ export function MessagingPage() {
|
||||
|
||||
{/* Header actions */}
|
||||
<div className="flex items-center gap-2 ml-auto">
|
||||
<button className="p-2 hover:bg-gray-100 rounded-lg transition-colors cursor-pointer">
|
||||
<Image
|
||||
src="/assets/icons/three-dots-horizontal-icon.svg"
|
||||
alt="More options"
|
||||
width={24}
|
||||
height={24}
|
||||
<div className="relative">
|
||||
<button
|
||||
onClick={() => setIsPageMenuOpen((prev) => !prev)}
|
||||
className="p-2 hover:bg-gray-100 rounded-lg transition-colors cursor-pointer"
|
||||
>
|
||||
<Image
|
||||
src="/assets/icons/three-dots-horizontal-icon.svg"
|
||||
alt="More options"
|
||||
width={24}
|
||||
height={24}
|
||||
/>
|
||||
</button>
|
||||
<ChatDropdownMenu
|
||||
items={pageMenuItems}
|
||||
isOpen={isPageMenuOpen}
|
||||
onClose={() => setIsPageMenuOpen(false)}
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
<button className="p-2 hover:bg-gray-100 rounded-lg transition-colors cursor-pointer">
|
||||
<Image
|
||||
src="/assets/icons/compose-icon.svg"
|
||||
@@ -634,6 +710,8 @@ export function MessagingPage() {
|
||||
{...selectedUserInfo}
|
||||
isTyping={typingUserNames.length > 0}
|
||||
typingText={typingUserNames.length > 0 ? `${typingUserNames.join(', ')} is typing...` : undefined}
|
||||
onClearChat={clearMessages}
|
||||
onDeleteConversation={handleDeleteConversation}
|
||||
/>
|
||||
|
||||
{/* Messages area wrapper */}
|
||||
|
||||
Reference in New Issue
Block a user