attachment + download attach + suggestion
This commit is contained in:
@@ -9,7 +9,7 @@ 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 } from './hooks/useEmailData'
|
||||
import { useGetMessageDetail, useSendEmail, useDownloadAttachment } from './hooks/useEmailData'
|
||||
import { useAuthStore } from '../auth/store/AuthStore'
|
||||
import { SendEmailDto } from './types/Types'
|
||||
import { toast } from '@/components/Toast'
|
||||
@@ -31,6 +31,7 @@ const DetailEmail: FC = () => {
|
||||
// API hooks
|
||||
const { data: messageDetail, isLoading, error } = useGetMessageDetail(id || '', mailbox || '')
|
||||
const sendEmailMutation = useSendEmail()
|
||||
const downloadAttachmentMutation = useDownloadAttachment()
|
||||
// const saveDraftMutation = useSaveDraft()
|
||||
|
||||
const priorityOptions = [
|
||||
@@ -110,6 +111,36 @@ const DetailEmail: FC = () => {
|
||||
toast('قابلیت ارسال به دیگران به زودی اضافه خواهد شد', 'info')
|
||||
}
|
||||
|
||||
const handleDownloadAttachment = async (attachmentId: string, filename: string) => {
|
||||
if (!id) {
|
||||
toast('شناسه پیام یافت نشد', 'error')
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
const blob = await downloadAttachmentMutation.mutateAsync({
|
||||
messageId: id,
|
||||
attachmentId: attachmentId,
|
||||
mailbox: mailbox || ''
|
||||
})
|
||||
|
||||
// Create download link
|
||||
const url = window.URL.createObjectURL(blob)
|
||||
const link = document.createElement('a')
|
||||
link.href = url
|
||||
link.download = filename || `attachment-${attachmentId}`
|
||||
document.body.appendChild(link)
|
||||
link.click()
|
||||
document.body.removeChild(link)
|
||||
window.URL.revokeObjectURL(url)
|
||||
|
||||
toast('فایل با موفقیت دانلود شد', 'success')
|
||||
} catch (error) {
|
||||
console.error('Download error:', error)
|
||||
toast('خطا در دانلود فایل', 'error')
|
||||
}
|
||||
}
|
||||
|
||||
// Mark message as seen when it's loaded and not already seen
|
||||
useEffect(() => {
|
||||
if (messageDetail && !messageDetail.seen && id) {
|
||||
@@ -161,9 +192,14 @@ const DetailEmail: FC = () => {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className='mt-6 flex gap-4 items-center'>
|
||||
<img src={AvatarImage} className='size-10' />
|
||||
<div className='text-sm'>{messageDetail.from.name || messageDetail.from.address}</div>
|
||||
<div>
|
||||
<div className='mt-6 flex gap-4 items-center'>
|
||||
<img src={AvatarImage} className='size-10' />
|
||||
<div>
|
||||
<div className='text-sm'>{messageDetail.from.name || messageDetail.from.address}</div>
|
||||
<div className='text-xs text-description mt-0.5'>{messageDetail.from?.address}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className='xl:mt-8 mt-3 text-[13px] leading-7 font-light'>
|
||||
@@ -191,13 +227,20 @@ const DetailEmail: FC = () => {
|
||||
messageDetail.attachments.map((attachment, index) => (
|
||||
<div key={index} className='bg-[#EBEDF5] text-sm flex gap-2 h-10 rounded-full items-center px-4'>
|
||||
<span>{attachment.filename || `attachment-${index + 1}`}</span>
|
||||
<DocumentDownload size={20} color='#0038FF' className='cursor-pointer' />
|
||||
<DocumentDownload
|
||||
size={20}
|
||||
color='#0038FF'
|
||||
className='cursor-pointer hover:opacity-70 transition-opacity'
|
||||
onClick={() => handleDownloadAttachment(
|
||||
attachment.id || `ATT${String(index + 1).padStart(5, '0')}`,
|
||||
attachment.filename || `attachment-${index + 1}`
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
))
|
||||
) : (
|
||||
<div className='bg-[#EBEDF5] text-sm flex gap-2 h-10 rounded-full items-center px-4'>
|
||||
<span>Lorem Ipsum.pdf</span>
|
||||
<DocumentDownload size={20} color='#0038FF' />
|
||||
<span>فایل ضمیمهای وجود ندارد</span>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -111,4 +111,11 @@ export const useRestoreMessage = () => {
|
||||
return useMutation({
|
||||
mutationFn: ({ messageId, mailbox }: SingleActionRequest) => api.restoreMessage(messageId, mailbox),
|
||||
});
|
||||
};
|
||||
|
||||
export const useDownloadAttachment = () => {
|
||||
return useMutation({
|
||||
mutationFn: ({ messageId, attachmentId, mailbox }: { messageId: string; attachmentId: string; mailbox: string }) =>
|
||||
api.downloadAttachment(messageId, attachmentId, mailbox),
|
||||
});
|
||||
};
|
||||
@@ -145,3 +145,17 @@ export const markAsUnread = async (
|
||||
);
|
||||
return data;
|
||||
};
|
||||
|
||||
export const downloadAttachment = async (
|
||||
messageId: string,
|
||||
attachmentId: string,
|
||||
mailbox: string
|
||||
): Promise<Blob> => {
|
||||
const response = await axios.get(
|
||||
`/email/messages/${messageId}/attachment?attachmentId=${attachmentId}&mailbox=${mailbox}`,
|
||||
{
|
||||
responseType: "blob",
|
||||
}
|
||||
);
|
||||
return response.data;
|
||||
};
|
||||
|
||||
@@ -9,6 +9,7 @@ export interface EmailHeaderDto {
|
||||
}
|
||||
|
||||
export interface EmailAttachmentDto {
|
||||
id?: string;
|
||||
filename?: string;
|
||||
contentType?: string;
|
||||
encoding?: string;
|
||||
|
||||
Reference in New Issue
Block a user