change all actions

This commit is contained in:
hamid zarghami
2025-07-20 16:47:01 +03:30
parent 1106952e22
commit 9eed4ede94
22 changed files with 309 additions and 127 deletions
+108 -23
View File
@@ -3,8 +3,9 @@ import { CloseCircle } from 'iconsax-react'
import { useTranslation } from 'react-i18next'
import { useSharedStore } from '@/shared/store/sharedStore'
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 { useUpdateDraft, useSendDraft } from '../../pages/draft/hooks/useDraftData'
import Input from '../Input'
import ReactQuill from 'react-quill-new';
import Button from '../Button'
@@ -16,8 +17,8 @@ import { toast } from '../Toast'
const NewMessage: FC = () => {
const { t } = useTranslation('global')
const [value, setValue] = useState('');
const { setOpenNewMessage, openNewMessage } = useSharedStore()
const [value, setValue] = useState<string>('');
const { setOpenNewMessage, openNewMessage, draftData, setDraftData, editingDraftId, setEditingDraftId } = useSharedStore()
const { email: userEmail } = useAuthStore()
const [isClosing, setIsClosing] = useState(false)
const [shouldRender, setShouldRender] = useState(false)
@@ -38,6 +39,33 @@ const NewMessage: FC = () => {
// API hooks
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(() => {
if (openNewMessage) {
@@ -62,6 +90,9 @@ const NewMessage: FC = () => {
setIsClosing(true)
setTimeout(() => {
setOpenNewMessage(false)
resetForm()
setDraftData(null)
setEditingDraftId(null)
}, 300)
}
@@ -76,6 +107,12 @@ const NewMessage: FC = () => {
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) => {
if (!isValidEmail(email)) {
return
@@ -156,25 +193,18 @@ const NewMessage: FC = () => {
}
const handleEmailAction = async (isDraft: boolean = false) => {
const isEditingDraft = !!editingDraftId
if (!isDraft && (toEmails.length === 0 || !subject)) {
toast('لطفا تمام فیلدهای مورد نیاز را پر کنید', 'error')
return
}
if (isDraft && toEmails.length === 0 && !subject && !value) {
if (isDraft && toEmails.length === 0 && !subject && ensureString(value).trim() === '') {
toast('حداقل یکی از فیلدها باید پر باشد', 'error')
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
if (isDraft) {
setIsSavingDraft(true)
@@ -182,18 +212,73 @@ const NewMessage: FC = () => {
setIsSending(true)
}
await sendEmailMutation.mutateAsync(emailData, {
onSuccess: (data) => {
toast(data.message, 'success')
try {
let messageId = ''
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()
resetForm()
},
onSettled: () => {
// Reset loading states
setIsSending(false)
setIsSavingDraft(false)
} else {
// Creating new email/draft
const emailData: SendEmailDto = {
from: { address: userEmail || 'sender@example.com' },
to: parseEmailAddresses(toEmails),
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)