spam list + socket events
This commit is contained in:
@@ -9,17 +9,18 @@ import AnswerIcon from '@/assets/images/answer.svg'
|
||||
import Header from './Components/Header'
|
||||
import ReactQuill from 'react-quill-new';
|
||||
import Select from '@/components/Select'
|
||||
import { useGetInbox, useGetMessageDetail, useSendEmail } from './hooks/useEmailData'
|
||||
import { useGetMessageDetail, useSendEmail } from './hooks/useEmailData'
|
||||
import { useAuthStore } from '../auth/store/AuthStore'
|
||||
import { SendEmailDto } from './types/Types'
|
||||
import { toast } from '@/components/Toast'
|
||||
import { formatDate, sanitizeEmailHTML } from '@/config/func'
|
||||
import { formatDate, sanitizeEmailHTML, detectTextDirection } from '@/config/func'
|
||||
import SkeletonDetail from './Components/SkeletonDetail'
|
||||
import { useEmailActions } from '@/hooks/useEmailActions'
|
||||
|
||||
const DetailEmail: FC = () => {
|
||||
|
||||
const { t } = useTranslation()
|
||||
const { refetch } = useGetInbox({ page: 1 })
|
||||
const emailActions = useEmailActions()
|
||||
const { id } = useParams<{ id: string }>()
|
||||
const { email: userEmail } = useAuthStore()
|
||||
const [showAnswer, setShowAnswer] = useState<boolean>(false)
|
||||
@@ -27,7 +28,7 @@ const DetailEmail: FC = () => {
|
||||
const [priority, setPriority] = useState<string>('')
|
||||
|
||||
// API hooks
|
||||
const { data: messageDetail, isLoading, error, isSuccess } = useGetMessageDetail(id || '', !!id)
|
||||
const { data: messageDetail, isLoading, error } = useGetMessageDetail(id || '', !!id)
|
||||
const sendEmailMutation = useSendEmail()
|
||||
// const saveDraftMutation = useSaveDraft()
|
||||
|
||||
@@ -108,11 +109,13 @@ const DetailEmail: FC = () => {
|
||||
toast('قابلیت ارسال به دیگران به زودی اضافه خواهد شد', 'info')
|
||||
}
|
||||
|
||||
// Mark message as seen when it's loaded and not already seen
|
||||
useEffect(() => {
|
||||
if (isSuccess) {
|
||||
refetch()
|
||||
if (messageDetail && !messageDetail.seen && id) {
|
||||
console.log('Marking message as seen:', id, 'Current seen status:', messageDetail.seen)
|
||||
emailActions.markAsSeen(Number(id))
|
||||
}
|
||||
}, [isSuccess])
|
||||
}, [messageDetail, emailActions, id])
|
||||
|
||||
if (isLoading) {
|
||||
return (
|
||||
@@ -166,10 +169,15 @@ const DetailEmail: FC = () => {
|
||||
{messageDetail.html && messageDetail.html.length > 0 ? (
|
||||
<div
|
||||
className='email-content-container border border-gray-200 rounded-lg p-4 overflow-hidden'
|
||||
style={{
|
||||
direction: detectTextDirection(messageDetail.html.join(''))
|
||||
}}
|
||||
dangerouslySetInnerHTML={{ __html: sanitizeEmailHTML(messageDetail.html.join('')) }}
|
||||
/>
|
||||
) : (
|
||||
<p>{messageDetail.text || 'محتوای پیام'}</p>
|
||||
<p style={{
|
||||
direction: detectTextDirection(messageDetail.text || '')
|
||||
}}>{messageDetail.text || 'محتوای پیام'}</p>
|
||||
)}
|
||||
</div>
|
||||
|
||||
|
||||
@@ -1,19 +1,22 @@
|
||||
import Filters, { FilterValues } from '../../components/Filters';
|
||||
import { FC, useState } from 'react'
|
||||
import { FC, useState, useEffect, useCallback } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import Table from '../../components/Table';
|
||||
import { ColumnType } from '../../components/types/TableTypes';
|
||||
import { InfoCircle, More, Refresh2, Trash, Edit, Archive, ArchiveTick, Star1 } from 'iconsax-react';
|
||||
import { RowActionItem } from '../../components/RowActionsDropdown';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import { useNavigate, useLocation } from 'react-router-dom';
|
||||
import { useGetInbox } from './hooks/useEmailData';
|
||||
import { InboxMessage } from './types/Types';
|
||||
import { formatDate } from '@/config/func';
|
||||
import MarkAsRead from '@/assets/images/mark_as_read.svg'
|
||||
import { useEmailActions } from '@/hooks/useEmailActions';
|
||||
import { useEmailWebSocketContext } from '@/contexts/EmailWebSocketContext';
|
||||
import { useEmailEvents } from '@/hooks/useEmailEvents';
|
||||
|
||||
const List: FC = () => {
|
||||
const navigate = useNavigate();
|
||||
const location = useLocation();
|
||||
const { t } = useTranslation();
|
||||
const [currentPage, setCurrentPage] = useState(1);
|
||||
const [filters, setFilters] = useState<FilterValues>({});
|
||||
@@ -21,10 +24,38 @@ const List: FC = () => {
|
||||
|
||||
const { data: inboxData, isLoading, refetch, isFetching } = useGetInbox({
|
||||
page: currentPage,
|
||||
limit: 10,
|
||||
limit: 25,
|
||||
...filters
|
||||
});
|
||||
|
||||
// WebSocket integration
|
||||
const { socket } = useEmailWebSocketContext();
|
||||
|
||||
const handleNewEmailEvent = useCallback(() => {
|
||||
// Refresh inbox when new email arrives
|
||||
refetch();
|
||||
}, [refetch]);
|
||||
|
||||
const handleEmailActionEvent = useCallback(() => {
|
||||
// Refresh inbox when email actions occur
|
||||
refetch();
|
||||
}, [refetch]);
|
||||
|
||||
useEmailEvents(socket, {
|
||||
onNewEmail: handleNewEmailEvent,
|
||||
onEmailRead: handleEmailActionEvent,
|
||||
onEmailDeleted: handleEmailActionEvent,
|
||||
// onMailboxUpdated: handleEmailActionEvent,
|
||||
});
|
||||
|
||||
// Force refresh when component mounts or location changes
|
||||
useEffect(() => {
|
||||
// Refetch when coming back to inbox from other pages
|
||||
if (location.pathname === '/') {
|
||||
refetch();
|
||||
}
|
||||
}, [location.pathname, refetch]);
|
||||
|
||||
const [selectedMessages, setSelectedMessages] = useState<InboxMessage[]>([]);
|
||||
|
||||
const columns: ColumnType<InboxMessage>[] = [
|
||||
@@ -32,7 +63,14 @@ const List: FC = () => {
|
||||
key: 'subject',
|
||||
title: 'عنوان پیام',
|
||||
render: (item) => (
|
||||
<span className="truncate">{item.subject || 'بدون موضوع'}</span>
|
||||
<div className="truncate max-w-[250px]">{item.subject || 'بدون موضوع'}</div>
|
||||
)
|
||||
},
|
||||
{
|
||||
key: 'intro',
|
||||
title: 'پیش نمایش',
|
||||
render: (item) => (
|
||||
<div className="truncate max-w-[250px]">{item.intro || 'بدون موضوع'}</div>
|
||||
)
|
||||
},
|
||||
{
|
||||
|
||||
@@ -26,7 +26,8 @@ export const useGetInbox = (query: MessageListQueryDto) => {
|
||||
return useQuery({
|
||||
queryKey: ['inbox', query],
|
||||
queryFn: () => api.getInbox(query),
|
||||
staleTime: 1000 * 60 * 5, // 5 minutes
|
||||
staleTime: 0, // Always fetch fresh data
|
||||
refetchOnWindowFocus: true,
|
||||
});
|
||||
};
|
||||
|
||||
@@ -35,7 +36,7 @@ export const useGetMessageDetail = (messageId: string, enabled: boolean = true)
|
||||
queryKey: ['message', messageId],
|
||||
queryFn: () => api.getMessageDetail(messageId),
|
||||
enabled: !!messageId && enabled,
|
||||
staleTime: 1000 * 60 * 10, // 10 minutes
|
||||
staleTime: 0, // Always fetch fresh data for message details
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user