change all actions
This commit is contained in:
@@ -3,8 +3,9 @@ import { CloseCircle } from 'iconsax-react'
|
|||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
import { useSharedStore } from '@/shared/store/sharedStore'
|
import { useSharedStore } from '@/shared/store/sharedStore'
|
||||||
import { useAuthStore } from '../../pages/auth/store/AuthStore'
|
import { useAuthStore } from '../../pages/auth/store/AuthStore'
|
||||||
import { useSendEmail } from '../../pages/received/hooks/useEmailData'
|
import { useGetMessageDetail, useSendEmail } from '../../pages/received/hooks/useEmailData'
|
||||||
import { SendEmailDto } from '../../pages/received/types/Types'
|
import { SendEmailDto } from '../../pages/received/types/Types'
|
||||||
|
import { useUpdateDraft, useSendDraft } from '../../pages/draft/hooks/useDraftData'
|
||||||
import Input from '../Input'
|
import Input from '../Input'
|
||||||
import ReactQuill from 'react-quill-new';
|
import ReactQuill from 'react-quill-new';
|
||||||
import Button from '../Button'
|
import Button from '../Button'
|
||||||
@@ -16,8 +17,8 @@ import { toast } from '../Toast'
|
|||||||
|
|
||||||
const NewMessage: FC = () => {
|
const NewMessage: FC = () => {
|
||||||
const { t } = useTranslation('global')
|
const { t } = useTranslation('global')
|
||||||
const [value, setValue] = useState('');
|
const [value, setValue] = useState<string>('');
|
||||||
const { setOpenNewMessage, openNewMessage } = useSharedStore()
|
const { setOpenNewMessage, openNewMessage, draftData, setDraftData, editingDraftId, setEditingDraftId } = useSharedStore()
|
||||||
const { email: userEmail } = useAuthStore()
|
const { email: userEmail } = useAuthStore()
|
||||||
const [isClosing, setIsClosing] = useState(false)
|
const [isClosing, setIsClosing] = useState(false)
|
||||||
const [shouldRender, setShouldRender] = useState(false)
|
const [shouldRender, setShouldRender] = useState(false)
|
||||||
@@ -38,6 +39,33 @@ const NewMessage: FC = () => {
|
|||||||
|
|
||||||
// API hooks
|
// API hooks
|
||||||
const sendEmailMutation = useSendEmail()
|
const sendEmailMutation = useSendEmail()
|
||||||
|
const updateDraftMutation = useUpdateDraft()
|
||||||
|
const sendDraftMutation = useSendDraft()
|
||||||
|
|
||||||
|
// Get draft detail if draftData exists
|
||||||
|
const { data: draftDetail } = useGetMessageDetail(
|
||||||
|
draftData?.id.toString() || '',
|
||||||
|
draftData?.mailbox || '',
|
||||||
|
!!draftData?.id
|
||||||
|
)
|
||||||
|
|
||||||
|
// Load draft data into form when draft detail is available
|
||||||
|
useEffect(() => {
|
||||||
|
if (draftDetail) {
|
||||||
|
// Extract emails from to array
|
||||||
|
const toEmailsList = draftDetail.to?.map(recipient => recipient.address) || []
|
||||||
|
setToEmails(toEmailsList)
|
||||||
|
setSubject(draftDetail.subject || '')
|
||||||
|
|
||||||
|
// Try to load HTML content if available, fallback to text or intro
|
||||||
|
const draftWithContent = draftDetail as unknown as { html?: string; text?: string; intro: string }
|
||||||
|
const content = ensureString(draftWithContent.html || draftWithContent.text || draftWithContent.intro)
|
||||||
|
setValue(content)
|
||||||
|
|
||||||
|
// Clear draft data after loading
|
||||||
|
setDraftData(null)
|
||||||
|
}
|
||||||
|
}, [draftDetail, setDraftData])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (openNewMessage) {
|
if (openNewMessage) {
|
||||||
@@ -62,6 +90,9 @@ const NewMessage: FC = () => {
|
|||||||
setIsClosing(true)
|
setIsClosing(true)
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
setOpenNewMessage(false)
|
setOpenNewMessage(false)
|
||||||
|
resetForm()
|
||||||
|
setDraftData(null)
|
||||||
|
setEditingDraftId(null)
|
||||||
}, 300)
|
}, 300)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -76,6 +107,12 @@ const NewMessage: FC = () => {
|
|||||||
return emailRegex.test(email)
|
return emailRegex.test(email)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const ensureString = (val: unknown): string => {
|
||||||
|
if (typeof val === 'string') return val
|
||||||
|
if (val === null || val === undefined) return ''
|
||||||
|
return String(val)
|
||||||
|
}
|
||||||
|
|
||||||
const addEmailToList = (email: string) => {
|
const addEmailToList = (email: string) => {
|
||||||
if (!isValidEmail(email)) {
|
if (!isValidEmail(email)) {
|
||||||
return
|
return
|
||||||
@@ -156,25 +193,18 @@ const NewMessage: FC = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const handleEmailAction = async (isDraft: boolean = false) => {
|
const handleEmailAction = async (isDraft: boolean = false) => {
|
||||||
|
const isEditingDraft = !!editingDraftId
|
||||||
|
|
||||||
if (!isDraft && (toEmails.length === 0 || !subject)) {
|
if (!isDraft && (toEmails.length === 0 || !subject)) {
|
||||||
toast('لطفا تمام فیلدهای مورد نیاز را پر کنید', 'error')
|
toast('لطفا تمام فیلدهای مورد نیاز را پر کنید', 'error')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isDraft && toEmails.length === 0 && !subject && !value) {
|
if (isDraft && toEmails.length === 0 && !subject && ensureString(value).trim() === '') {
|
||||||
toast('حداقل یکی از فیلدها باید پر باشد', 'error')
|
toast('حداقل یکی از فیلدها باید پر باشد', 'error')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
const emailData: SendEmailDto = {
|
|
||||||
from: { address: userEmail || 'sender@example.com' },
|
|
||||||
to: parseEmailAddresses(toEmails),
|
|
||||||
subject,
|
|
||||||
html: value,
|
|
||||||
text: value.replace(/<[^>]*>/g, ''), // Strip HTML for text version
|
|
||||||
...(isDraft && { isDraft: true, uploadOnly: true }),
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set appropriate loading state
|
// Set appropriate loading state
|
||||||
if (isDraft) {
|
if (isDraft) {
|
||||||
setIsSavingDraft(true)
|
setIsSavingDraft(true)
|
||||||
@@ -182,18 +212,73 @@ const NewMessage: FC = () => {
|
|||||||
setIsSending(true)
|
setIsSending(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
await sendEmailMutation.mutateAsync(emailData, {
|
try {
|
||||||
onSuccess: (data) => {
|
let messageId = ''
|
||||||
toast(data.message, 'success')
|
if (isEditingDraft) {
|
||||||
|
// We're editing an existing draft
|
||||||
|
const draftUpdateData = {
|
||||||
|
to: parseEmailAddresses(toEmails),
|
||||||
|
subject,
|
||||||
|
html: ensureString(value),
|
||||||
|
text: ensureString(value).replace(/<[^>]*>/g, ''),
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isDraft) {
|
||||||
|
// Just update the draft
|
||||||
|
await updateDraftMutation.mutateAsync({
|
||||||
|
messageId: editingDraftId.toString(),
|
||||||
|
draftData: draftUpdateData
|
||||||
|
}, {
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
|
onSuccess: (data: any) => {
|
||||||
|
messageId = data.data?.messageId
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
// Update first, then send
|
||||||
|
await updateDraftMutation.mutateAsync({
|
||||||
|
messageId: editingDraftId.toString(),
|
||||||
|
draftData: {
|
||||||
|
...draftUpdateData,
|
||||||
|
isDraft: true,
|
||||||
|
uploadOnly: true
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
|
onSuccess: (data: any) => {
|
||||||
|
messageId = data.data?.messageId
|
||||||
|
}
|
||||||
|
})
|
||||||
|
await sendDraftMutation.mutateAsync(messageId || editingDraftId.toString())
|
||||||
|
toast('پیام با موفقیت ارسال شد', 'success')
|
||||||
|
}
|
||||||
handleClose()
|
handleClose()
|
||||||
resetForm()
|
} else {
|
||||||
},
|
// Creating new email/draft
|
||||||
onSettled: () => {
|
const emailData: SendEmailDto = {
|
||||||
// Reset loading states
|
from: { address: userEmail || 'sender@example.com' },
|
||||||
setIsSending(false)
|
to: parseEmailAddresses(toEmails),
|
||||||
setIsSavingDraft(false)
|
subject,
|
||||||
|
html: ensureString(value),
|
||||||
|
text: ensureString(value).replace(/<[^>]*>/g, ''),
|
||||||
|
...(isDraft && { isDraft: true, uploadOnly: true }),
|
||||||
|
}
|
||||||
|
|
||||||
|
await sendEmailMutation.mutateAsync(emailData, {
|
||||||
|
onSuccess: (data) => {
|
||||||
|
toast(data.message, 'success')
|
||||||
|
handleClose()
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
})
|
} catch (error) {
|
||||||
|
console.error('Error in email action:', error)
|
||||||
|
toast('خطا در انجام عملیات', 'error')
|
||||||
|
} finally {
|
||||||
|
// Reset loading states
|
||||||
|
setIsSending(false)
|
||||||
|
setIsSavingDraft(false)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleSend = () => handleEmailAction(false)
|
const handleSend = () => handleEmailAction(false)
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ export const useEmailActions = (customRefetch?: () => void) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const markAsSeenMutation = useMutation({
|
const markAsSeenMutation = useMutation({
|
||||||
mutationFn: markMessageAsSeen,
|
mutationFn: ({ messageId, mailbox }: { messageId: number; mailbox: string }) => markMessageAsSeen(messageId, mailbox),
|
||||||
onSuccess: (data) => {
|
onSuccess: (data) => {
|
||||||
toast(data?.data?.message || 'پیام به عنوان خوانده شده علامتگذاری شد', 'success');
|
toast(data?.data?.message || 'پیام به عنوان خوانده شده علامتگذاری شد', 'success');
|
||||||
invalidateAllQueries();
|
invalidateAllQueries();
|
||||||
@@ -58,7 +58,7 @@ export const useEmailActions = (customRefetch?: () => void) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const archiveMutation = useMutation({
|
const archiveMutation = useMutation({
|
||||||
mutationFn: moveMessageToArchive,
|
mutationFn: ({ messageId, mailbox }: { messageId: number; mailbox: string }) => moveMessageToArchive(messageId, mailbox),
|
||||||
onSuccess: (data) => {
|
onSuccess: (data) => {
|
||||||
toast(data?.data?.message || 'پیام به آرشیو منتقل شد', 'success');
|
toast(data?.data?.message || 'پیام به آرشیو منتقل شد', 'success');
|
||||||
invalidateAllQueries();
|
invalidateAllQueries();
|
||||||
@@ -66,7 +66,7 @@ export const useEmailActions = (customRefetch?: () => void) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const favoriteMutation = useMutation({
|
const favoriteMutation = useMutation({
|
||||||
mutationFn: moveMessageToFavorite,
|
mutationFn: ({ messageId, mailbox }: { messageId: number; mailbox: string }) => moveMessageToFavorite(messageId, mailbox),
|
||||||
onSuccess: (data) => {
|
onSuccess: (data) => {
|
||||||
toast(data?.data?.message || 'پیام به علاقهمندیها اضافه شد', 'success');
|
toast(data?.data?.message || 'پیام به علاقهمندیها اضافه شد', 'success');
|
||||||
invalidateAllQueries();
|
invalidateAllQueries();
|
||||||
@@ -74,7 +74,7 @@ export const useEmailActions = (customRefetch?: () => void) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const moveToTrashMutation = useMutation({
|
const moveToTrashMutation = useMutation({
|
||||||
mutationFn: moveMessageToTrash,
|
mutationFn: ({ messageId, mailbox }: { messageId: number; mailbox: string }) => moveMessageToTrash(messageId, mailbox),
|
||||||
onSuccess: (data) => {
|
onSuccess: (data) => {
|
||||||
toast(data?.data?.message || 'پیام به سطل زباله منتقل شد', 'success');
|
toast(data?.data?.message || 'پیام به سطل زباله منتقل شد', 'success');
|
||||||
invalidateAllQueries();
|
invalidateAllQueries();
|
||||||
@@ -82,7 +82,7 @@ export const useEmailActions = (customRefetch?: () => void) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const deletePermanentlyMutation = useMutation({
|
const deletePermanentlyMutation = useMutation({
|
||||||
mutationFn: deleteMessagePermanently,
|
mutationFn: ({ messageId, mailbox }: { messageId: number; mailbox: string }) => deleteMessagePermanently(messageId, mailbox),
|
||||||
onSuccess: (data) => {
|
onSuccess: (data) => {
|
||||||
toast(data?.data?.message || 'پیام به طور کامل حذف شد', 'success');
|
toast(data?.data?.message || 'پیام به طور کامل حذف شد', 'success');
|
||||||
invalidateAllQueries();
|
invalidateAllQueries();
|
||||||
@@ -90,7 +90,7 @@ export const useEmailActions = (customRefetch?: () => void) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const sendEmailMutation = useMutation({
|
const sendEmailMutation = useMutation({
|
||||||
mutationFn: sendEmail,
|
mutationFn: ({ messageId }: { messageId: number }) => sendEmail(messageId),
|
||||||
onSuccess: (data) => {
|
onSuccess: (data) => {
|
||||||
toast(data?.data?.message || 'ایمیل با موفقیت ارسال شد', 'success');
|
toast(data?.data?.message || 'ایمیل با موفقیت ارسال شد', 'success');
|
||||||
invalidateAllQueries();
|
invalidateAllQueries();
|
||||||
@@ -107,7 +107,7 @@ export const useEmailActions = (customRefetch?: () => void) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const deleteDraftMutation = useMutation({
|
const deleteDraftMutation = useMutation({
|
||||||
mutationFn: deleteDraft,
|
mutationFn: ({ messageId, mailbox }: { messageId: number; mailbox: string }) => deleteDraft(messageId, mailbox),
|
||||||
onSuccess: (data) => {
|
onSuccess: (data) => {
|
||||||
toast(data?.data?.message || 'پیشنویس حذف شد', 'success');
|
toast(data?.data?.message || 'پیشنویس حذف شد', 'success');
|
||||||
invalidateAllQueries();
|
invalidateAllQueries();
|
||||||
@@ -115,7 +115,7 @@ export const useEmailActions = (customRefetch?: () => void) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const sendDraftMutation = useMutation({
|
const sendDraftMutation = useMutation({
|
||||||
mutationFn: sendDraft,
|
mutationFn: ({ messageId }: { messageId: number }) => sendDraft(messageId),
|
||||||
onSuccess: (data) => {
|
onSuccess: (data) => {
|
||||||
toast(data?.data?.message || 'پیشنویس ارسال شد', 'success');
|
toast(data?.data?.message || 'پیشنویس ارسال شد', 'success');
|
||||||
invalidateAllQueries();
|
invalidateAllQueries();
|
||||||
@@ -123,7 +123,7 @@ export const useEmailActions = (customRefetch?: () => void) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const unfavoriteMutation = useMutation({
|
const unfavoriteMutation = useMutation({
|
||||||
mutationFn: unfavoriteMessage,
|
mutationFn: ({ messageId, mailbox }: { messageId: number; mailbox: string }) => unfavoriteMessage(messageId, mailbox),
|
||||||
onSuccess: (data) => {
|
onSuccess: (data) => {
|
||||||
toast(data?.data?.message || 'پیام از علاقهمندیها حذف شد', 'success');
|
toast(data?.data?.message || 'پیام از علاقهمندیها حذف شد', 'success');
|
||||||
invalidateAllQueries();
|
invalidateAllQueries();
|
||||||
@@ -131,7 +131,7 @@ export const useEmailActions = (customRefetch?: () => void) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const unarchiveMutation = useMutation({
|
const unarchiveMutation = useMutation({
|
||||||
mutationFn: unarchiveMessage,
|
mutationFn: ({ messageId, mailbox }: { messageId: number; mailbox: string }) => unarchiveMessage(messageId, mailbox),
|
||||||
onSuccess: (data) => {
|
onSuccess: (data) => {
|
||||||
toast(data?.data?.message || 'پیام از آرشیو خارج شد', 'success');
|
toast(data?.data?.message || 'پیام از آرشیو خارج شد', 'success');
|
||||||
invalidateAllQueries();
|
invalidateAllQueries();
|
||||||
@@ -139,7 +139,7 @@ export const useEmailActions = (customRefetch?: () => void) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const restoreMutation = useMutation({
|
const restoreMutation = useMutation({
|
||||||
mutationFn: restoreMessage,
|
mutationFn: ({ messageId, mailbox }: { messageId: number; mailbox: string }) => restoreMessage(messageId, mailbox),
|
||||||
onSuccess: (data) => {
|
onSuccess: (data) => {
|
||||||
toast(data?.data?.message || 'پیام بازگردانی شد', 'success');
|
toast(data?.data?.message || 'پیام بازگردانی شد', 'success');
|
||||||
invalidateAllQueries();
|
invalidateAllQueries();
|
||||||
@@ -164,24 +164,24 @@ export const useEmailActions = (customRefetch?: () => void) => {
|
|||||||
return {
|
return {
|
||||||
// Bulk actions
|
// Bulk actions
|
||||||
bulkAction: bulkActionMutation.mutate,
|
bulkAction: bulkActionMutation.mutate,
|
||||||
bulkMarkAsSeen: (messageIds: number[]) =>
|
bulkMarkAsSeen: (messageIds: number[], mailbox: string) =>
|
||||||
bulkActionMutation.mutate({ messageIds, action: BulkActionType.SEEN }),
|
bulkActionMutation.mutate({ messageIds, action: BulkActionType.SEEN, mailbox: mailbox }),
|
||||||
bulkArchive: (messageIds: number[]) =>
|
bulkArchive: (messageIds: number[], mailbox: string) =>
|
||||||
bulkActionMutation.mutate({ messageIds, action: BulkActionType.ARCHIVE }),
|
bulkActionMutation.mutate({ messageIds, action: BulkActionType.ARCHIVE, mailbox: mailbox }),
|
||||||
bulkFavorite: (messageIds: number[]) =>
|
bulkFavorite: (messageIds: number[], mailbox: string) =>
|
||||||
bulkActionMutation.mutate({ messageIds, action: BulkActionType.FAVORITE }),
|
bulkActionMutation.mutate({ messageIds, action: BulkActionType.FAVORITE, mailbox: mailbox }),
|
||||||
bulkMoveToTrash: (messageIds: number[]) =>
|
bulkMoveToTrash: (messageIds: number[], mailbox: string) =>
|
||||||
bulkActionMutation.mutate({ messageIds, action: BulkActionType.TRASH }),
|
bulkActionMutation.mutate({ messageIds, action: BulkActionType.TRASH, mailbox: mailbox }),
|
||||||
bulkDelete: (messageIds: number[]) =>
|
bulkDelete: (messageIds: number[], mailbox: string) =>
|
||||||
bulkActionMutation.mutate({ messageIds, action: BulkActionType.DELETE }),
|
bulkActionMutation.mutate({ messageIds, action: BulkActionType.DELETE, mailbox: mailbox }),
|
||||||
bulkJunk: (messageIds: number[]) =>
|
bulkJunk: (messageIds: number[], mailbox: string) =>
|
||||||
bulkActionMutation.mutate({ messageIds, action: BulkActionType.JUNK }),
|
bulkActionMutation.mutate({ messageIds, action: BulkActionType.JUNK, mailbox: mailbox }),
|
||||||
bulkUnfavorite: (messageIds: number[]) =>
|
bulkUnfavorite: (messageIds: number[], mailbox: string) =>
|
||||||
bulkActionMutation.mutate({ messageIds, action: BulkActionType.UNFAVORITE }),
|
bulkActionMutation.mutate({ messageIds, action: BulkActionType.UNFAVORITE, mailbox: mailbox }),
|
||||||
bulkUnarchive: (messageIds: number[]) =>
|
bulkUnarchive: (messageIds: number[], mailbox: string) =>
|
||||||
bulkActionMutation.mutate({ messageIds, action: BulkActionType.UNARCHIVE }),
|
bulkActionMutation.mutate({ messageIds, action: BulkActionType.UNARCHIVE, mailbox: mailbox }),
|
||||||
bulkRestore: (messageIds: number[]) =>
|
bulkRestore: (messageIds: number[], mailbox: string) =>
|
||||||
bulkActionMutation.mutate({ messageIds, action: BulkActionType.RESTORE }),
|
bulkActionMutation.mutate({ messageIds, action: BulkActionType.RESTORE, mailbox: mailbox }),
|
||||||
|
|
||||||
// Single actions (keeping for backward compatibility)
|
// Single actions (keeping for backward compatibility)
|
||||||
markAsSeen: markAsSeenMutation.mutate,
|
markAsSeen: markAsSeenMutation.mutate,
|
||||||
|
|||||||
@@ -95,6 +95,7 @@
|
|||||||
"NOTIFICATION": "اعلان",
|
"NOTIFICATION": "اعلان",
|
||||||
"FINANCE": "مالی"
|
"FINANCE": "مالی"
|
||||||
},
|
},
|
||||||
|
"success": "عملیات با موفقیت انجام شد",
|
||||||
"attachment_select": "اضافه کردن فایل ضمیمه",
|
"attachment_select": "اضافه کردن فایل ضمیمه",
|
||||||
"domain": {
|
"domain": {
|
||||||
"table": {
|
"table": {
|
||||||
|
|||||||
@@ -82,13 +82,13 @@ const List: FC = () => {
|
|||||||
|
|
||||||
const handleDeleteSelected = () => {
|
const handleDeleteSelected = () => {
|
||||||
const messageIds = selectedMessages.map(message => message.id);
|
const messageIds = selectedMessages.map(message => message.id);
|
||||||
emailActions.bulkDelete(messageIds);
|
emailActions.bulkDelete(messageIds, selectedMessages[0].mailbox);
|
||||||
setSelectedMessages([]);
|
setSelectedMessages([]);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleRestoreSelected = () => {
|
const handleRestoreSelected = () => {
|
||||||
const messageIds = selectedMessages.map(message => message.id);
|
const messageIds = selectedMessages.map(message => message.id);
|
||||||
emailActions.bulkRestore(messageIds);
|
emailActions.bulkRestore(messageIds, selectedMessages[0].mailbox);
|
||||||
setSelectedMessages([]);
|
setSelectedMessages([]);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -96,12 +96,12 @@ const List: FC = () => {
|
|||||||
{
|
{
|
||||||
label: 'بازگردانی',
|
label: 'بازگردانی',
|
||||||
icon: <RecoveryConvert size={16} color="black" />,
|
icon: <RecoveryConvert size={16} color="black" />,
|
||||||
onClick: () => emailActions.restore(message.id),
|
onClick: () => emailActions.restore({ messageId: message.id, mailbox: message.mailbox }),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'حذف دائم',
|
label: 'حذف دائم',
|
||||||
icon: <Trash size={16} color="red" />,
|
icon: <Trash size={16} color="red" />,
|
||||||
onClick: () => emailActions.deletePermanently(message.id),
|
onClick: () => emailActions.deletePermanently({ messageId: message.id, mailbox: message.mailbox }),
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|||||||
@@ -82,13 +82,13 @@ const List: FC = () => {
|
|||||||
|
|
||||||
const handleDeleteSelected = () => {
|
const handleDeleteSelected = () => {
|
||||||
const messageIds = selectedMessages.map(message => message.id);
|
const messageIds = selectedMessages.map(message => message.id);
|
||||||
emailActions.bulkMoveToTrash(messageIds);
|
emailActions.bulkMoveToTrash(messageIds, selectedMessages[0].mailbox);
|
||||||
setSelectedMessages([]);
|
setSelectedMessages([]);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleUnarchiveSelected = () => {
|
const handleUnarchiveSelected = () => {
|
||||||
const messageIds = selectedMessages.map(message => message.id);
|
const messageIds = selectedMessages.map(message => message.id);
|
||||||
emailActions.bulkUnarchive(messageIds);
|
emailActions.bulkUnarchive(messageIds, selectedMessages[0].mailbox);
|
||||||
setSelectedMessages([]);
|
setSelectedMessages([]);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -96,12 +96,12 @@ const List: FC = () => {
|
|||||||
{
|
{
|
||||||
label: 'خروج از آرشیو',
|
label: 'خروج از آرشیو',
|
||||||
icon: <ArchiveSlash size={16} color="black" />,
|
icon: <ArchiveSlash size={16} color="black" />,
|
||||||
onClick: () => emailActions.unarchive(message.id),
|
onClick: () => emailActions.unarchive({ messageId: message.id, mailbox: message.mailbox }),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'حذف',
|
label: 'حذف',
|
||||||
icon: <Trash size={16} color="red" />,
|
icon: <Trash size={16} color="red" />,
|
||||||
onClick: () => emailActions.moveToTrash(message.id),
|
onClick: () => emailActions.moveToTrash({ messageId: message.id, mailbox: message.mailbox }),
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import { useGetDrafts } from './hooks/useDraftData';
|
|||||||
import { DraftMessage } from './types/DraftTypes';
|
import { DraftMessage } from './types/DraftTypes';
|
||||||
import { formatDate } from '@/config/func';
|
import { formatDate } from '@/config/func';
|
||||||
import { useEmailActions } from '@/hooks/useEmailActions';
|
import { useEmailActions } from '@/hooks/useEmailActions';
|
||||||
|
import { useSharedStore } from '@/shared/store/sharedStore';
|
||||||
|
|
||||||
const List: FC = () => {
|
const List: FC = () => {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
@@ -17,6 +18,7 @@ const List: FC = () => {
|
|||||||
const [currentPage, setCurrentPage] = useState(1);
|
const [currentPage, setCurrentPage] = useState(1);
|
||||||
const [filters, setFilters] = useState<FilterValues>({});
|
const [filters, setFilters] = useState<FilterValues>({});
|
||||||
const emailActions = useEmailActions();
|
const emailActions = useEmailActions();
|
||||||
|
const { setDraftData, setOpenNewMessage, setEditingDraftId } = useSharedStore();
|
||||||
|
|
||||||
const { data: draftData, isLoading, refetch, isFetching } = useGetDrafts({
|
const { data: draftData, isLoading, refetch, isFetching } = useGetDrafts({
|
||||||
page: currentPage,
|
page: currentPage,
|
||||||
@@ -113,14 +115,14 @@ const List: FC = () => {
|
|||||||
|
|
||||||
const handleDeleteSelected = () => {
|
const handleDeleteSelected = () => {
|
||||||
selectedMessages.forEach(message => {
|
selectedMessages.forEach(message => {
|
||||||
emailActions.deleteDraft(message.id);
|
emailActions.deleteDraft({ messageId: message.id, mailbox: message.mailbox });
|
||||||
});
|
});
|
||||||
setSelectedMessages([]);
|
setSelectedMessages([]);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleSendSelected = () => {
|
const handleSendSelected = () => {
|
||||||
selectedMessages.forEach(message => {
|
selectedMessages.forEach(message => {
|
||||||
emailActions.sendDraft(message.id);
|
emailActions.sendDraft({ messageId: message.id });
|
||||||
});
|
});
|
||||||
setSelectedMessages([]);
|
setSelectedMessages([]);
|
||||||
};
|
};
|
||||||
@@ -134,17 +136,23 @@ const List: FC = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handleDeleteDraft = (messageId: number) => {
|
const handleDeleteDraft = (messageId: number) => {
|
||||||
emailActions.deleteDraft(messageId);
|
emailActions.deleteDraft({ messageId: messageId, mailbox: '' });
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleSendDraft = (messageId: number) => {
|
const handleSendDraft = (messageId: number) => {
|
||||||
emailActions.sendDraft(messageId);
|
emailActions.sendDraft({ messageId: messageId });
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleEditDraft = (messageId: number) => {
|
const handleEditDraft = (messageId: number) => {
|
||||||
navigate(`/draft/edit/${messageId}`);
|
navigate(`/draft/edit/${messageId}`);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleRowClick = (messageId: number, item: DraftMessage) => {
|
||||||
|
setDraftData(item);
|
||||||
|
setEditingDraftId(messageId);
|
||||||
|
setOpenNewMessage(true);
|
||||||
|
};
|
||||||
|
|
||||||
const getRowActions = (message: DraftMessage): RowActionItem[] => [
|
const getRowActions = (message: DraftMessage): RowActionItem[] => [
|
||||||
{
|
{
|
||||||
label: 'ارسال',
|
label: 'ارسال',
|
||||||
@@ -193,7 +201,7 @@ const List: FC = () => {
|
|||||||
selectedActions={selectedActions}
|
selectedActions={selectedActions}
|
||||||
onSelectionChange={handleSelectionChange}
|
onSelectionChange={handleSelectionChange}
|
||||||
selectedRows={selectedMessages}
|
selectedRows={selectedMessages}
|
||||||
onRowClick={(id) => navigate(`/draft/edit/${id}`)}
|
onRowClick={handleRowClick}
|
||||||
noDataMessage={
|
noDataMessage={
|
||||||
<div className="flex flex-col items-center ">
|
<div className="flex flex-col items-center ">
|
||||||
<InfoCircle size={32} className="text-gray-300 mb-2" />
|
<InfoCircle size={32} className="text-gray-300 mb-2" />
|
||||||
|
|||||||
@@ -43,3 +43,28 @@ export const useEditDraft = () => {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const useUpdateDraft = () => {
|
||||||
|
const queryClient = useQueryClient();
|
||||||
|
|
||||||
|
return useMutation({
|
||||||
|
mutationFn: ({ messageId, draftData }: { messageId: string; draftData: DraftUpdateDto }) =>
|
||||||
|
api.updateDraft(messageId, draftData),
|
||||||
|
onSuccess: () => {
|
||||||
|
// Invalidate drafts queries to refresh the list
|
||||||
|
queryClient.invalidateQueries({ queryKey: ['drafts'] });
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
export const useSendDraft = () => {
|
||||||
|
const queryClient = useQueryClient();
|
||||||
|
|
||||||
|
return useMutation({
|
||||||
|
mutationFn: (messageId: string) => api.sendDraft(messageId),
|
||||||
|
onSuccess: () => {
|
||||||
|
// Invalidate drafts queries to refresh the list
|
||||||
|
queryClient.invalidateQueries({ queryKey: ['drafts'] });
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
@@ -29,9 +29,25 @@ export const editDraft = async (
|
|||||||
return data;
|
return data;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const updateDraft = async (
|
||||||
|
messageId: string,
|
||||||
|
draftData: DraftUpdateDto
|
||||||
|
): Promise<void> => {
|
||||||
|
const { data } = await axios.patch(
|
||||||
|
`/email/messages/drafts/${messageId}`,
|
||||||
|
draftData
|
||||||
|
);
|
||||||
|
return data;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const sendDraft = async (messageId: string): Promise<void> => {
|
||||||
|
const { data } = await axios.post(`/email/messages/drafts/${messageId}/send`);
|
||||||
|
return data;
|
||||||
|
};
|
||||||
|
|
||||||
export const getDraftDetail = async (
|
export const getDraftDetail = async (
|
||||||
messageId: string
|
messageId: string
|
||||||
): Promise<InboxMessage> => {
|
): Promise<InboxMessage> => {
|
||||||
const { data } = await axios.get(`/email/messages/drafts/${messageId}`);
|
const { data } = await axios.get(`/email/messages/${messageId}`);
|
||||||
return data.data.message;
|
return data.data.message;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -104,4 +104,6 @@ export interface DraftUpdateDto {
|
|||||||
text?: string;
|
text?: string;
|
||||||
html?: string;
|
html?: string;
|
||||||
attachments?: EmailAttachmentDto[];
|
attachments?: EmailAttachmentDto[];
|
||||||
|
isDraft?: boolean;
|
||||||
|
uploadOnly?: boolean;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -83,19 +83,19 @@ const List: FC = () => {
|
|||||||
|
|
||||||
const handleDeleteSelected = () => {
|
const handleDeleteSelected = () => {
|
||||||
const messageIds = selectedMessages.map(message => message.id);
|
const messageIds = selectedMessages.map(message => message.id);
|
||||||
emailActions.bulkMoveToTrash(messageIds);
|
emailActions.bulkMoveToTrash(messageIds, selectedMessages[0].mailbox);
|
||||||
setSelectedMessages([]);
|
setSelectedMessages([]);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleArchiveSelected = () => {
|
const handleArchiveSelected = () => {
|
||||||
const messageIds = selectedMessages.map(message => message.id);
|
const messageIds = selectedMessages.map(message => message.id);
|
||||||
emailActions.bulkArchive(messageIds);
|
emailActions.bulkArchive(messageIds, selectedMessages[0].mailbox);
|
||||||
setSelectedMessages([]);
|
setSelectedMessages([]);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleUnfavoriteSelected = () => {
|
const handleUnfavoriteSelected = () => {
|
||||||
const messageIds = selectedMessages.map(message => message.id);
|
const messageIds = selectedMessages.map(message => message.id);
|
||||||
emailActions.bulkUnfavorite(messageIds);
|
emailActions.bulkUnfavorite(messageIds, selectedMessages[0].mailbox);
|
||||||
setSelectedMessages([]);
|
setSelectedMessages([]);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -103,17 +103,17 @@ const List: FC = () => {
|
|||||||
{
|
{
|
||||||
label: 'حذف از علاقهمندیها',
|
label: 'حذف از علاقهمندیها',
|
||||||
icon: <Star size={16} color="black" />,
|
icon: <Star size={16} color="black" />,
|
||||||
onClick: () => emailActions.unfavorite(message.id),
|
onClick: () => emailActions.unfavorite({ messageId: message.id, mailbox: message.mailbox }),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'بایگانی',
|
label: 'بایگانی',
|
||||||
icon: <Archive size={16} color="black" />,
|
icon: <Archive size={16} color="black" />,
|
||||||
onClick: () => emailActions.archive(message.id),
|
onClick: () => emailActions.archive({ messageId: message.id, mailbox: message.mailbox }),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'حذف',
|
label: 'حذف',
|
||||||
icon: <Trash size={16} color="red" />,
|
icon: <Trash size={16} color="red" />,
|
||||||
onClick: () => emailActions.moveToTrash(message.id),
|
onClick: () => emailActions.moveToTrash({ messageId: message.id, mailbox: message.mailbox }),
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|||||||
@@ -21,14 +21,14 @@ const DetailEmail: FC = () => {
|
|||||||
|
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
const emailActions = useEmailActions()
|
const emailActions = useEmailActions()
|
||||||
const { id } = useParams<{ id: string }>()
|
const { id, mailbox } = useParams<{ id: string, mailbox: string }>()
|
||||||
const { email: userEmail } = useAuthStore()
|
const { email: userEmail } = useAuthStore()
|
||||||
const [showAnswer, setShowAnswer] = useState<boolean>(false)
|
const [showAnswer, setShowAnswer] = useState<boolean>(false)
|
||||||
const [value, setValue] = useState<string>('')
|
const [value, setValue] = useState<string>('')
|
||||||
const [priority, setPriority] = useState<string>('')
|
const [priority, setPriority] = useState<string>('')
|
||||||
|
|
||||||
// API hooks
|
// API hooks
|
||||||
const { data: messageDetail, isLoading, error } = useGetMessageDetail(id || '', !!id)
|
const { data: messageDetail, isLoading, error } = useGetMessageDetail(id || '', mailbox || '', !!id)
|
||||||
const sendEmailMutation = useSendEmail()
|
const sendEmailMutation = useSendEmail()
|
||||||
// const saveDraftMutation = useSaveDraft()
|
// const saveDraftMutation = useSaveDraft()
|
||||||
|
|
||||||
@@ -113,7 +113,7 @@ const DetailEmail: FC = () => {
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (messageDetail && !messageDetail.seen && id) {
|
if (messageDetail && !messageDetail.seen && id) {
|
||||||
console.log('Marking message as seen:', id, 'Current seen status:', messageDetail.seen)
|
console.log('Marking message as seen:', id, 'Current seen status:', messageDetail.seen)
|
||||||
emailActions.markAsSeen(Number(id))
|
emailActions.markAsSeen({ messageId: Number(id), mailbox: mailbox || '' })
|
||||||
}
|
}
|
||||||
}, [messageDetail, emailActions, id])
|
}, [messageDetail, emailActions, id])
|
||||||
|
|
||||||
|
|||||||
@@ -144,25 +144,25 @@ const List: FC = () => {
|
|||||||
|
|
||||||
const handleDeleteSelected = () => {
|
const handleDeleteSelected = () => {
|
||||||
const messageIds = selectedMessages.map(message => message.id);
|
const messageIds = selectedMessages.map(message => message.id);
|
||||||
emailActions.bulkMoveToTrash(messageIds);
|
emailActions.bulkMoveToTrash(messageIds, selectedMessages[0].mailbox);
|
||||||
setSelectedMessages([]);
|
setSelectedMessages([]);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleArchiveSelected = () => {
|
const handleArchiveSelected = () => {
|
||||||
const messageIds = selectedMessages.map(message => message.id);
|
const messageIds = selectedMessages.map(message => message.id);
|
||||||
emailActions.bulkArchive(messageIds);
|
emailActions.bulkArchive(messageIds, selectedMessages[0].mailbox);
|
||||||
setSelectedMessages([]);
|
setSelectedMessages([]);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleMarkAsReadSelected = () => {
|
const handleMarkAsReadSelected = () => {
|
||||||
const messageIds = selectedMessages.map(message => message.id);
|
const messageIds = selectedMessages.map(message => message.id);
|
||||||
emailActions.bulkMarkAsSeen(messageIds);
|
emailActions.bulkMarkAsSeen(messageIds, selectedMessages[0].mailbox);
|
||||||
setSelectedMessages([]);
|
setSelectedMessages([]);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleFavoriteSelected = () => {
|
const handleFavoriteSelected = () => {
|
||||||
const messageIds = selectedMessages.map(message => message.id);
|
const messageIds = selectedMessages.map(message => message.id);
|
||||||
emailActions.bulkFavorite(messageIds);
|
emailActions.bulkFavorite(messageIds, selectedMessages[0].mailbox);
|
||||||
setSelectedMessages([]);
|
setSelectedMessages([]);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -170,22 +170,22 @@ const List: FC = () => {
|
|||||||
{
|
{
|
||||||
label: message.seen ? 'علامتگذاری به عنوان خوانده نشده' : 'علامتگذاری به عنوان خوانده شده',
|
label: message.seen ? 'علامتگذاری به عنوان خوانده نشده' : 'علامتگذاری به عنوان خوانده شده',
|
||||||
icon: <Edit size={16} color="black" />,
|
icon: <Edit size={16} color="black" />,
|
||||||
onClick: () => emailActions.markAsSeen(message.id),
|
onClick: () => emailActions.markAsSeen({ messageId: message.id, mailbox: message.mailbox }),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'اضافه به علاقهمندیها',
|
label: 'اضافه به علاقهمندیها',
|
||||||
icon: <Star1 size={16} color="black" />,
|
icon: <Star1 size={16} color="black" />,
|
||||||
onClick: () => emailActions.favorite(message.id),
|
onClick: () => emailActions.favorite({ messageId: message.id, mailbox: message.mailbox }),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'بایگانی',
|
label: 'بایگانی',
|
||||||
icon: <Archive size={16} color="black" />,
|
icon: <Archive size={16} color="black" />,
|
||||||
onClick: () => emailActions.archive(message.id),
|
onClick: () => emailActions.archive({ messageId: message.id, mailbox: message.mailbox }),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'حذف',
|
label: 'حذف',
|
||||||
icon: <Trash size={16} color="red" />,
|
icon: <Trash size={16} color="red" />,
|
||||||
onClick: () => emailActions.moveToTrash(message.id),
|
onClick: () => emailActions.moveToTrash({ messageId: message.id, mailbox: message.mailbox }),
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
@@ -229,7 +229,7 @@ const List: FC = () => {
|
|||||||
selectedActions={selectedActions}
|
selectedActions={selectedActions}
|
||||||
onSelectionChange={handleSelectionChange}
|
onSelectionChange={handleSelectionChange}
|
||||||
selectedRows={selectedMessages}
|
selectedRows={selectedMessages}
|
||||||
onRowClick={(id) => navigate(`/mail/${id}`)}
|
onRowClick={(id, item) => navigate(`/mail/${id}/${item.mailbox}`)}
|
||||||
noDataMessage={
|
noDataMessage={
|
||||||
<div className="flex flex-col items-center">
|
<div className="flex flex-col items-center">
|
||||||
<InfoCircle size={32} className="text-gray-300 mb-2" />
|
<InfoCircle size={32} className="text-gray-300 mb-2" />
|
||||||
|
|||||||
@@ -31,10 +31,10 @@ export const useGetInbox = (query: MessageListQueryDto) => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
export const useGetMessageDetail = (messageId: string, enabled: boolean = true) => {
|
export const useGetMessageDetail = (messageId: string, mailbox: string, enabled: boolean = true) => {
|
||||||
return useQuery({
|
return useQuery({
|
||||||
queryKey: ['message', messageId],
|
queryKey: ['message', messageId, mailbox],
|
||||||
queryFn: () => api.getMessageDetail(messageId),
|
queryFn: () => api.getMessageDetail(messageId, mailbox),
|
||||||
enabled: !!messageId && enabled,
|
enabled: !!messageId && enabled,
|
||||||
staleTime: 0, // Always fetch fresh data for message details
|
staleTime: 0, // Always fetch fresh data for message details
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -32,10 +32,11 @@ export const getInbox = async (
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const getMessageDetail = async (
|
export const getMessageDetail = async (
|
||||||
messageId: string
|
messageId: string,
|
||||||
|
mailbox: string
|
||||||
): Promise<MessageDetail> => {
|
): Promise<MessageDetail> => {
|
||||||
const { data }: { data: MessageDetailResponse } = await axios.get(
|
const { data }: { data: MessageDetailResponse } = await axios.get(
|
||||||
`/email/messages/${messageId}`
|
`/email/messages/${messageId}?mailbox=${mailbox}`
|
||||||
);
|
);
|
||||||
return data.data.message;
|
return data.data.message;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -303,4 +303,5 @@ export enum BulkActionType {
|
|||||||
export interface BulkActionRequest {
|
export interface BulkActionRequest {
|
||||||
messageIds: number[];
|
messageIds: number[];
|
||||||
action: BulkActionType;
|
action: BulkActionType;
|
||||||
|
mailbox: string;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -90,19 +90,19 @@ const List: FC = () => {
|
|||||||
|
|
||||||
const handleDeleteSelected = () => {
|
const handleDeleteSelected = () => {
|
||||||
const messageIds = selectedMessages.map(message => message.id);
|
const messageIds = selectedMessages.map(message => message.id);
|
||||||
emailActions.bulkMoveToTrash(messageIds);
|
emailActions.bulkMoveToTrash(messageIds, selectedMessages[0].mailbox);
|
||||||
setSelectedMessages([]);
|
setSelectedMessages([]);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleArchiveSelected = () => {
|
const handleArchiveSelected = () => {
|
||||||
const messageIds = selectedMessages.map(message => message.id);
|
const messageIds = selectedMessages.map(message => message.id);
|
||||||
emailActions.bulkArchive(messageIds);
|
emailActions.bulkArchive(messageIds, selectedMessages[0].mailbox);
|
||||||
setSelectedMessages([]);
|
setSelectedMessages([]);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleFavoriteSelected = () => {
|
const handleFavoriteSelected = () => {
|
||||||
const messageIds = selectedMessages.map(message => message.id);
|
const messageIds = selectedMessages.map(message => message.id);
|
||||||
emailActions.bulkFavorite(messageIds);
|
emailActions.bulkFavorite(messageIds, selectedMessages[0].mailbox);
|
||||||
setSelectedMessages([]);
|
setSelectedMessages([]);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -110,17 +110,17 @@ const List: FC = () => {
|
|||||||
{
|
{
|
||||||
label: 'اضافه به علاقهمندیها',
|
label: 'اضافه به علاقهمندیها',
|
||||||
icon: <Star size={16} color="black" />,
|
icon: <Star size={16} color="black" />,
|
||||||
onClick: () => emailActions.favorite(message.id),
|
onClick: () => emailActions.favorite({ messageId: message.id, mailbox: message.mailbox }),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'بایگانی',
|
label: 'بایگانی',
|
||||||
icon: <Archive size={16} color="black" />,
|
icon: <Archive size={16} color="black" />,
|
||||||
onClick: () => emailActions.archive(message.id),
|
onClick: () => emailActions.archive({ messageId: message.id, mailbox: message.mailbox }),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'حذف',
|
label: 'حذف',
|
||||||
icon: <Trash size={16} color="red" />,
|
icon: <Trash size={16} color="red" />,
|
||||||
onClick: () => emailActions.moveToTrash(message.id),
|
onClick: () => emailActions.moveToTrash({ messageId: message.id, mailbox: message.mailbox }),
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|||||||
@@ -94,8 +94,8 @@ const List: FC = () => {
|
|||||||
setCurrentPage(1);
|
setCurrentPage(1);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleRowClick = (id: number) => {
|
const handleRowClick = (id: number, item: InboxMessage) => {
|
||||||
navigate(`${Paths.detailEmail}${id}`);
|
navigate(`${Paths.detailEmail}${id}/${item.mailbox}`);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleSelectionChange = (selectedRows: InboxMessage[]) => {
|
const handleSelectionChange = (selectedRows: InboxMessage[]) => {
|
||||||
@@ -104,19 +104,19 @@ const List: FC = () => {
|
|||||||
|
|
||||||
const handleDeleteSelected = () => {
|
const handleDeleteSelected = () => {
|
||||||
const messageIds = selectedMessages.map(message => message.id);
|
const messageIds = selectedMessages.map(message => message.id);
|
||||||
emailActions.bulkMoveToTrash(messageIds);
|
emailActions.bulkMoveToTrash(messageIds, selectedMessages[0].mailbox);
|
||||||
setSelectedMessages([]);
|
setSelectedMessages([]);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleArchiveSelected = () => {
|
const handleArchiveSelected = () => {
|
||||||
const messageIds = selectedMessages.map(message => message.id);
|
const messageIds = selectedMessages.map(message => message.id);
|
||||||
emailActions.bulkArchive(messageIds);
|
emailActions.bulkArchive(messageIds, selectedMessages[0].mailbox);
|
||||||
setSelectedMessages([]);
|
setSelectedMessages([]);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleFavoriteSelected = () => {
|
const handleFavoriteSelected = () => {
|
||||||
const messageIds = selectedMessages.map(message => message.id);
|
const messageIds = selectedMessages.map(message => message.id);
|
||||||
emailActions.bulkFavorite(messageIds);
|
emailActions.bulkFavorite(messageIds, selectedMessages[0].mailbox);
|
||||||
setSelectedMessages([]);
|
setSelectedMessages([]);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -124,17 +124,17 @@ const List: FC = () => {
|
|||||||
{
|
{
|
||||||
label: 'اضافه به علاقهمندیها',
|
label: 'اضافه به علاقهمندیها',
|
||||||
icon: <Star size={16} color="black" />,
|
icon: <Star size={16} color="black" />,
|
||||||
onClick: () => emailActions.favorite(message.id),
|
onClick: () => emailActions.favorite({ messageId: message.id, mailbox: message.mailbox }),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'بایگانی',
|
label: 'بایگانی',
|
||||||
icon: <Archive size={16} color="black" />,
|
icon: <Archive size={16} color="black" />,
|
||||||
onClick: () => emailActions.archive(message.id),
|
onClick: () => emailActions.archive({ messageId: message.id, mailbox: message.mailbox }),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'حذف',
|
label: 'حذف',
|
||||||
icon: <Trash size={16} color="red" />,
|
icon: <Trash size={16} color="red" />,
|
||||||
onClick: () => emailActions.moveToTrash(message.id),
|
onClick: () => emailActions.moveToTrash({ messageId: message.id, mailbox: message.mailbox }),
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|||||||
@@ -81,7 +81,7 @@ const List: FC = () => {
|
|||||||
|
|
||||||
const handleDeleteSelected = () => {
|
const handleDeleteSelected = () => {
|
||||||
const messageIds = selectedMessages.map(message => message.id);
|
const messageIds = selectedMessages.map(message => message.id);
|
||||||
emailActions.bulkMoveToTrash(messageIds);
|
emailActions.bulkMoveToTrash(messageIds, selectedMessages[0].mailbox);
|
||||||
setSelectedMessages([]);
|
setSelectedMessages([]);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -100,7 +100,7 @@ const List: FC = () => {
|
|||||||
{
|
{
|
||||||
label: 'حذف',
|
label: 'حذف',
|
||||||
icon: <Trash size={16} color="red" />,
|
icon: <Trash size={16} color="red" />,
|
||||||
onClick: () => emailActions.moveToTrash(message.id),
|
onClick: () => emailActions.moveToTrash({ messageId: message.id, mailbox: message.mailbox }),
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ const AppRouter: FC = () => {
|
|||||||
<Route path={Paths.favorite} element={<FavoriteList />} />
|
<Route path={Paths.favorite} element={<FavoriteList />} />
|
||||||
<Route path={Paths.spam} element={<SpamList />} />
|
<Route path={Paths.spam} element={<SpamList />} />
|
||||||
<Route path={Paths.search} element={<SearchList />} />
|
<Route path={Paths.search} element={<SearchList />} />
|
||||||
<Route path={Paths.detailEmail + ':id'} element={<DetailEmail />} />
|
<Route path={Paths.detailEmail + ':id/:mailbox'} element={<DetailEmail />} />
|
||||||
<Route path={Paths.login} element={<Login />} />
|
<Route path={Paths.login} element={<Login />} />
|
||||||
<Route path={Paths.setting} element={<Setting />} />
|
<Route path={Paths.setting} element={<Setting />} />
|
||||||
</Routes>
|
</Routes>
|
||||||
|
|||||||
@@ -3,43 +3,68 @@ import { BulkActionRequest } from "../pages/received/types/Types";
|
|||||||
|
|
||||||
// Bulk action for multiple messages
|
// Bulk action for multiple messages
|
||||||
export const bulkAction = async (request: BulkActionRequest) => {
|
export const bulkAction = async (request: BulkActionRequest) => {
|
||||||
const { data } = await axios.post(`/email/messages/bulk-action`, request);
|
const { data } = await axios.post(
|
||||||
|
`/email/messages/bulk-action?mailbox=${request.mailbox}`,
|
||||||
|
request
|
||||||
|
);
|
||||||
return data;
|
return data;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Mark message as seen
|
// Mark message as seen
|
||||||
export const markMessageAsSeen = async (messageId: number) => {
|
export const markMessageAsSeen = async (messageId: number, mailbox: string) => {
|
||||||
const { data } = await axios.patch(`/email/messages/${messageId}/seen`);
|
const { data } = await axios.patch(
|
||||||
|
`/email/messages/${messageId}/seen?mailbox=${mailbox}`
|
||||||
|
);
|
||||||
return data;
|
return data;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Move message to archive
|
// Move message to archive
|
||||||
export const moveMessageToArchive = async (messageId: number) => {
|
export const moveMessageToArchive = async (
|
||||||
const { data } = await axios.patch(`/email/messages/${messageId}/archive`);
|
messageId: number,
|
||||||
|
mailbox: string
|
||||||
|
) => {
|
||||||
|
const { data } = await axios.patch(
|
||||||
|
`/email/messages/${messageId}/archive?mailbox=${mailbox}`
|
||||||
|
);
|
||||||
return data;
|
return data;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Move message to favorite
|
// Move message to favorite
|
||||||
export const moveMessageToFavorite = async (messageId: number) => {
|
export const moveMessageToFavorite = async (
|
||||||
const { data } = await axios.patch(`/email/messages/${messageId}/favorite`);
|
messageId: number,
|
||||||
|
mailbox: string
|
||||||
|
) => {
|
||||||
|
const { data } = await axios.patch(
|
||||||
|
`/email/messages/${messageId}/favorite?mailbox=${mailbox}`
|
||||||
|
);
|
||||||
return data;
|
return data;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Move message to trash
|
// Move message to trash
|
||||||
export const moveMessageToTrash = async (messageId: number) => {
|
export const moveMessageToTrash = async (
|
||||||
const { data } = await axios.patch(`/email/messages/${messageId}/trash`);
|
messageId: number,
|
||||||
|
mailbox: string
|
||||||
|
) => {
|
||||||
|
const { data } = await axios.patch(
|
||||||
|
`/email/messages/${messageId}/trash?mailbox=${mailbox}`
|
||||||
|
);
|
||||||
return data;
|
return data;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Delete message permanently (only for trash mailbox)
|
// Delete message permanently (only for trash mailbox)
|
||||||
export const deleteMessagePermanently = async (messageId: number) => {
|
export const deleteMessagePermanently = async (
|
||||||
const { data } = await axios.delete(`/email/messages/${messageId}`);
|
messageId: number,
|
||||||
|
mailbox: string
|
||||||
|
) => {
|
||||||
|
const { data } = await axios.delete(
|
||||||
|
`/email/messages/${messageId}?mailbox=${mailbox}`
|
||||||
|
);
|
||||||
return data;
|
return data;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Send email
|
// Send email
|
||||||
export const sendEmail = async (emailData: unknown) => {
|
export const sendEmail = async (messageId: number) => {
|
||||||
const { data } = await axios.post(`/email/send`, emailData);
|
const { data } = await axios.post(`/email/send?messageId=${messageId}`);
|
||||||
return data;
|
return data;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -53,8 +78,10 @@ export const updateDraft = async (messageId: number, draftData: unknown) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Delete draft
|
// Delete draft
|
||||||
export const deleteDraft = async (messageId: number) => {
|
export const deleteDraft = async (messageId: number, mailbox: string) => {
|
||||||
const { data } = await axios.delete(`/email/messages/drafts/${messageId}`);
|
const { data } = await axios.delete(
|
||||||
|
`/email/messages/drafts/${messageId}?mailbox=${mailbox}`
|
||||||
|
);
|
||||||
return data;
|
return data;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -65,19 +92,25 @@ export const sendDraft = async (messageId: number) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Unfavorite message
|
// Unfavorite message
|
||||||
export const unfavoriteMessage = async (messageId: number) => {
|
export const unfavoriteMessage = async (messageId: number, mailbox: string) => {
|
||||||
const { data } = await axios.patch(`/email/messages/${messageId}/unfavorite`);
|
const { data } = await axios.patch(
|
||||||
|
`/email/messages/${messageId}/unfavorite?mailbox=${mailbox}`
|
||||||
|
);
|
||||||
return data;
|
return data;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Unarchive message
|
// Unarchive message
|
||||||
export const unarchiveMessage = async (messageId: number) => {
|
export const unarchiveMessage = async (messageId: number, mailbox: string) => {
|
||||||
const { data } = await axios.patch(`/email/messages/${messageId}/unarchive`);
|
const { data } = await axios.patch(
|
||||||
|
`/email/messages/${messageId}/unarchive?mailbox=${mailbox}`
|
||||||
|
);
|
||||||
return data;
|
return data;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Restore message from trash
|
// Restore message from trash
|
||||||
export const restoreMessage = async (messageId: number) => {
|
export const restoreMessage = async (messageId: number, mailbox: string) => {
|
||||||
const { data } = await axios.patch(`/email/messages/${messageId}/restore`);
|
const { data } = await axios.patch(
|
||||||
|
`/email/messages/${messageId}/restore?mailbox=${mailbox}`
|
||||||
|
);
|
||||||
return data;
|
return data;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -6,4 +6,8 @@ export const useSharedStore = create<SharedStoreType>((set) => ({
|
|||||||
setOpenSidebar: (value) => set({ openSidebar: value }),
|
setOpenSidebar: (value) => set({ openSidebar: value }),
|
||||||
openNewMessage: false,
|
openNewMessage: false,
|
||||||
setOpenNewMessage: (value) => set({ openNewMessage: value }),
|
setOpenNewMessage: (value) => set({ openNewMessage: value }),
|
||||||
|
draftData: null,
|
||||||
|
setDraftData: (draft) => set({ draftData: draft }),
|
||||||
|
editingDraftId: null,
|
||||||
|
setEditingDraftId: (id) => set({ editingDraftId: id }),
|
||||||
}));
|
}));
|
||||||
|
|||||||
@@ -1,6 +1,12 @@
|
|||||||
|
import { DraftMessage } from "@/pages/draft/types/DraftTypes";
|
||||||
|
|
||||||
export type SharedStoreType = {
|
export type SharedStoreType = {
|
||||||
openSidebar: boolean;
|
openSidebar: boolean;
|
||||||
setOpenSidebar: (value: boolean) => void;
|
setOpenSidebar: (value: boolean) => void;
|
||||||
openNewMessage: boolean;
|
openNewMessage: boolean;
|
||||||
setOpenNewMessage: (value: boolean) => void;
|
setOpenNewMessage: (value: boolean) => void;
|
||||||
|
draftData: DraftMessage | null;
|
||||||
|
setDraftData: (draft: DraftMessage | null) => void;
|
||||||
|
editingDraftId: number | null;
|
||||||
|
setEditingDraftId: (id: number | null) => void;
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user