forward and reply
This commit is contained in:
+41
-158
@@ -4,112 +4,26 @@ import { useTranslation } from 'react-i18next'
|
||||
import { useParams } from 'react-router-dom'
|
||||
import AvatarImage from '@/assets/images/avatar.svg'
|
||||
import { DocumentDownload, EmojiHappy } from 'iconsax-react'
|
||||
import ForwardIcon from '@/assets/images/forward.svg'
|
||||
import AnswerIcon from '@/assets/images/answer.svg'
|
||||
import Header from './Components/Header'
|
||||
import ReactQuill from 'react-quill-new';
|
||||
import Select from '@/components/Select'
|
||||
import { useGetMessageDetail, useSendEmail, useDownloadAttachment } from './hooks/useEmailData'
|
||||
import { useAuthStore } from '../auth/store/AuthStore'
|
||||
import { SendEmailDto } from './types/Types'
|
||||
import { useGetMessageDetail, useDownloadAttachment } from './hooks/useEmailData'
|
||||
import { toast } from '@/components/Toast'
|
||||
import { formatDate, sanitizeEmailHTML, detectTextDirection } from '@/config/func'
|
||||
import SkeletonDetail from './Components/SkeletonDetail'
|
||||
import { useEmailActions } from '@/hooks/useEmailActions'
|
||||
import { MailboxEnum } from './enum/Enum'
|
||||
import Reply from '@/components/newMessage/Reply'
|
||||
import Forward from '@/components/newMessage/Forward'
|
||||
|
||||
const DetailEmail: FC = () => {
|
||||
|
||||
const { t } = useTranslation()
|
||||
const emailActions = useEmailActions()
|
||||
const { id, mailbox } = useParams<{ id: string, mailbox: string }>()
|
||||
const { email: userEmail } = useAuthStore()
|
||||
const [showAnswer, setShowAnswer] = useState<boolean>(false)
|
||||
const [value, setValue] = useState<string>('')
|
||||
const [priority, setPriority] = useState<string>('')
|
||||
const [activeAction, setActiveAction] = useState<'reply' | 'forward' | null>(null)
|
||||
|
||||
// API hooks
|
||||
const { data: messageDetail, isLoading, error } = useGetMessageDetail(id || '', mailbox || '')
|
||||
const sendEmailMutation = useSendEmail()
|
||||
const downloadAttachmentMutation = useDownloadAttachment()
|
||||
// const saveDraftMutation = useSaveDraft()
|
||||
|
||||
const priorityOptions = [
|
||||
{ value: 'high', label: 'بالا' },
|
||||
{ value: 'medium', label: 'متوسط' },
|
||||
{ value: 'low', label: 'پایین' },
|
||||
]
|
||||
|
||||
const handleSendReply = async () => {
|
||||
if (!value.trim()) {
|
||||
toast('لطفا متن پیام را وارد کنید', 'error')
|
||||
return
|
||||
}
|
||||
|
||||
if (!messageDetail) {
|
||||
toast('اطلاعات پیام یافت نشد', 'error')
|
||||
return
|
||||
}
|
||||
|
||||
const replyData: SendEmailDto = {
|
||||
from: { address: userEmail || 'sender@example.com' },
|
||||
to: [{ address: messageDetail.from.address, name: messageDetail.from.name }],
|
||||
subject: `Re: ${messageDetail.subject}`,
|
||||
html: value,
|
||||
text: value.replace(/<[^>]*>/g, ''),
|
||||
reference: {
|
||||
inReplyTo: messageDetail.messageId,
|
||||
originalMessageId: messageDetail.id.toString()
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
await sendEmailMutation.mutateAsync(replyData)
|
||||
toast('پاسخ با موفقیت ارسال شد', 'success')
|
||||
setShowAnswer(false)
|
||||
setValue('')
|
||||
setPriority('')
|
||||
} catch {
|
||||
toast('خطا در ارسال پاسخ', 'error')
|
||||
}
|
||||
}
|
||||
|
||||
const handleSaveDraft = async () => {
|
||||
if (!value.trim()) {
|
||||
toast('متن پیام خالی است', 'error')
|
||||
return
|
||||
}
|
||||
|
||||
if (!messageDetail) {
|
||||
toast('اطلاعات پیام یافت نشد', 'error')
|
||||
return
|
||||
}
|
||||
|
||||
// const draftData: SendEmailDto = {
|
||||
// from: { address: userEmail || 'sender@example.com' },
|
||||
// to: [{ address: messageDetail.from.address, name: messageDetail.from.name }],
|
||||
// subject: `Re: ${messageDetail.subject}`,
|
||||
// html: value,
|
||||
// text: value.replace(/<[^>]*>/g, ''),
|
||||
// isDraft: true,
|
||||
// reference: {
|
||||
// inReplyTo: messageDetail.messageId,
|
||||
// originalMessageId: messageDetail.id.toString()
|
||||
// }
|
||||
// }
|
||||
|
||||
try {
|
||||
// await saveDraftMutation.mutateAsync(draftData)
|
||||
toast('پیشنویس ذخیره شد', 'success')
|
||||
} catch {
|
||||
toast('خطا در ذخیره پیشنویس', 'error')
|
||||
}
|
||||
}
|
||||
|
||||
const handleForward = () => {
|
||||
// TODO: Implement forward functionality
|
||||
toast('قابلیت ارسال به دیگران به زودی اضافه خواهد شد', 'info')
|
||||
}
|
||||
|
||||
const handleDownloadAttachment = async (attachmentId: string, filename: string) => {
|
||||
if (!id) {
|
||||
@@ -245,78 +159,47 @@ const DetailEmail: FC = () => {
|
||||
)}
|
||||
</div>
|
||||
|
||||
{
|
||||
!showAnswer ?
|
||||
<div className='flex mt-9 justify-end'>
|
||||
<div className='flex gap-5 text-sm'>
|
||||
<EmojiHappy size={24} color='black' />
|
||||
{/* Email Actions */}
|
||||
{activeAction === null && (
|
||||
<div className='flex mt-9 justify-end'>
|
||||
<div className='flex gap-5 text-sm'>
|
||||
<EmojiHappy size={24} color='black' />
|
||||
|
||||
<div onClick={() => setShowAnswer(true)} className='flex gap-2 cursor-pointer items-center border-r border-border pr-5'>
|
||||
<img src={AnswerIcon} className='w-[17px]' />
|
||||
<div>{t('mail.answer')}</div>
|
||||
</div>
|
||||
<Reply
|
||||
originalMessage={messageDetail}
|
||||
className='border-r border-border pr-5'
|
||||
showInitialButton={true}
|
||||
onClose={() => setActiveAction(null)}
|
||||
onExpand={() => setActiveAction('reply')}
|
||||
/>
|
||||
|
||||
<div onClick={handleForward} className='flex gap-2 cursor-pointer items-center border-r border-border pr-5'>
|
||||
<img src={ForwardIcon} className='w-[17px]' />
|
||||
<div>{t('mail.forward')}</div>
|
||||
</div>
|
||||
</div>
|
||||
<Forward
|
||||
originalMessage={messageDetail}
|
||||
showInitialButton={true}
|
||||
onClose={() => setActiveAction(null)}
|
||||
onExpand={() => setActiveAction('forward')}
|
||||
/>
|
||||
</div>
|
||||
:
|
||||
<div className='mt-9 flex gap-4'>
|
||||
<img src={AvatarImage} className='size-10' />
|
||||
<div className='w-full'>
|
||||
<div className='mb-2 text-sm'>
|
||||
{t('mail.message')}
|
||||
</div>
|
||||
<ReactQuill
|
||||
modules={{
|
||||
toolbar: [
|
||||
[{ header: '1' }, { header: '2' }, { font: [] }],
|
||||
[{ list: 'ordered' }, { list: 'bullet' }],
|
||||
['bold', 'italic', 'underline'],
|
||||
['link', 'image'],
|
||||
[{ align: [] }],
|
||||
['clean']
|
||||
]
|
||||
}}
|
||||
theme="snow"
|
||||
value={value}
|
||||
onChange={setValue}
|
||||
style={{ minHeight: '120px', width: '100%' }}
|
||||
className='text-sm'
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div>
|
||||
<div className='flex flex-col gap-4 sm:flex-row pt-4'>
|
||||
<div>
|
||||
<Select
|
||||
items={priorityOptions}
|
||||
placeholder={t('new_message.select_priority')}
|
||||
className='xl:w-[190px]'
|
||||
value={priority}
|
||||
onChange={(e) => setPriority(e.target.value)}
|
||||
/>
|
||||
</div>
|
||||
<div className='flex-1 justify-end flex gap-3'>
|
||||
<Button
|
||||
className='!w-full sm:!w-fit px-6 md:px-10 bg-white text-black border border-primary order-2 sm:order-1'
|
||||
label={t('new_message.draft')}
|
||||
onClick={handleSaveDraft}
|
||||
// loading={saveDraftMutation.isPending}
|
||||
/>
|
||||
<Button
|
||||
className='w-full sm:w-fit px-6 md:px-10 order-1 sm:order-2'
|
||||
label={t('new_message.send')}
|
||||
onClick={handleSendReply}
|
||||
loading={sendEmailMutation.isPending}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
{/* Full width Reply */}
|
||||
{activeAction === 'reply' && (
|
||||
<Reply
|
||||
originalMessage={messageDetail}
|
||||
showInitialButton={false}
|
||||
onClose={() => setActiveAction(null)}
|
||||
/>
|
||||
)}
|
||||
|
||||
{/* Full width Forward */}
|
||||
{activeAction === 'forward' && (
|
||||
<Forward
|
||||
originalMessage={messageDetail}
|
||||
showInitialButton={false}
|
||||
onClose={() => setActiveAction(null)}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -50,6 +50,7 @@ export interface SendEmailDto {
|
||||
sendTime?: string;
|
||||
uploadOnly?: boolean;
|
||||
envelope?: EmailEnvelopeDto;
|
||||
isForward?: boolean;
|
||||
}
|
||||
|
||||
export interface MessageListQueryDto {
|
||||
|
||||
Reference in New Issue
Block a user