attachment + download attach + suggestion
This commit is contained in:
@@ -0,0 +1,262 @@
|
||||
import { useState, useEffect } from "react";
|
||||
import { useSharedStore } from "@/shared/store/sharedStore";
|
||||
import { useAuthStore } from "@/pages/auth/store/AuthStore";
|
||||
import {
|
||||
useGetMessageDetail,
|
||||
useSendEmail,
|
||||
} from "@/pages/received/hooks/useEmailData";
|
||||
import { SendEmailDto, EmailAttachmentDto } from "@/pages/received/types/Types";
|
||||
import { useUpdateDraft, useSendDraft } from "@/pages/draft/hooks/useDraftData";
|
||||
import { toast } from "@/components/Toast";
|
||||
import { useEmailSuggestions } from "./useEmailSuggestions";
|
||||
|
||||
export const useNewMessage = () => {
|
||||
const {
|
||||
draftData,
|
||||
setDraftData,
|
||||
editingDraftId,
|
||||
setEditingDraftId,
|
||||
} = useSharedStore();
|
||||
const { email: userEmail } = useAuthStore();
|
||||
|
||||
// Form state
|
||||
const [toEmails, setToEmails] = useState<string[]>([]);
|
||||
const [subject, setSubject] = useState("");
|
||||
const [content, setContent] = useState("");
|
||||
const [priority, setPriority] = useState("");
|
||||
const [attachments, setAttachments] = useState<EmailAttachmentDto[]>([]);
|
||||
|
||||
// Loading states
|
||||
const [isSending, setIsSending] = useState(false);
|
||||
const [isSavingDraft, setIsSavingDraft] = useState(false);
|
||||
|
||||
// API hooks
|
||||
const sendEmailMutation = useSendEmail();
|
||||
const updateDraftMutation = useUpdateDraft();
|
||||
const sendDraftMutation = useSendDraft();
|
||||
|
||||
// Email suggestions
|
||||
const {
|
||||
suggestions: emailSuggestions,
|
||||
searchSuggestions,
|
||||
} = useEmailSuggestions();
|
||||
|
||||
// Get draft detail if draftData exists
|
||||
const { data: draftDetail } = useGetMessageDetail(
|
||||
draftData?.id.toString() || "",
|
||||
draftData?.mailbox || ""
|
||||
);
|
||||
|
||||
// Load draft data into form
|
||||
useEffect(() => {
|
||||
if (draftDetail) {
|
||||
const toEmailsList =
|
||||
draftDetail.to?.map((recipient) => recipient.address) || [];
|
||||
setToEmails(toEmailsList);
|
||||
setSubject(draftDetail.subject || "");
|
||||
|
||||
const draftWithContent = (draftDetail as unknown) as {
|
||||
html?: string;
|
||||
text?: string;
|
||||
intro: string;
|
||||
};
|
||||
const draftContent = ensureString(
|
||||
draftWithContent.html || draftWithContent.text || draftWithContent.intro
|
||||
);
|
||||
setContent(draftContent);
|
||||
|
||||
setDraftData(null);
|
||||
}
|
||||
}, [draftDetail, setDraftData]);
|
||||
|
||||
const ensureString = (val: unknown): string => {
|
||||
if (typeof val === "string") return val;
|
||||
if (val === null || val === undefined) return "";
|
||||
return String(val);
|
||||
};
|
||||
|
||||
const isValidEmail = (email: string) => {
|
||||
const emailRegex = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/;
|
||||
return emailRegex.test(email);
|
||||
};
|
||||
|
||||
// Function to search email suggestions
|
||||
const searchEmailSuggestions = (query: string) => {
|
||||
searchSuggestions(query);
|
||||
};
|
||||
|
||||
const addEmail = (email: string) => {
|
||||
if (!isValidEmail(email)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (toEmails.includes(email)) {
|
||||
toast("این ایمیل قبلاً اضافه شده است", "error");
|
||||
return;
|
||||
}
|
||||
|
||||
setToEmails([...toEmails, email]);
|
||||
};
|
||||
|
||||
const removeEmail = (emailToRemove: string) => {
|
||||
setToEmails(toEmails.filter((email) => email !== emailToRemove));
|
||||
};
|
||||
|
||||
const parseEmailAddresses = (emails: string[]) => {
|
||||
return emails
|
||||
.filter((email) => email.length > 0)
|
||||
.map((email) => ({ address: email }));
|
||||
};
|
||||
|
||||
const resetForm = () => {
|
||||
setToEmails([]);
|
||||
setSubject("");
|
||||
setContent("");
|
||||
setPriority("");
|
||||
setAttachments([]);
|
||||
};
|
||||
|
||||
const handleEmailAction = async (isDraft: boolean = false) => {
|
||||
const isEditingDraft = !!editingDraftId;
|
||||
|
||||
if (!isDraft && (toEmails.length === 0 || !subject)) {
|
||||
toast("لطفا تمام فیلدهای مورد نیاز را پر کنید", "error");
|
||||
return;
|
||||
}
|
||||
|
||||
if (
|
||||
isDraft &&
|
||||
toEmails.length === 0 &&
|
||||
!subject &&
|
||||
ensureString(content).trim() === ""
|
||||
) {
|
||||
toast("حداقل یکی از فیلدها باید پر باشد", "error");
|
||||
return;
|
||||
}
|
||||
|
||||
if (isDraft) {
|
||||
setIsSavingDraft(true);
|
||||
} else {
|
||||
setIsSending(true);
|
||||
}
|
||||
|
||||
try {
|
||||
let messageId = "";
|
||||
if (isEditingDraft) {
|
||||
const draftUpdateData = {
|
||||
to: parseEmailAddresses(toEmails),
|
||||
subject,
|
||||
html: ensureString(content),
|
||||
text: ensureString(content).replace(/<[^>]*>/g, ""),
|
||||
...(attachments.length > 0 && { attachments }),
|
||||
};
|
||||
|
||||
if (isDraft) {
|
||||
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 {
|
||||
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");
|
||||
}
|
||||
|
||||
resetForm();
|
||||
setEditingDraftId(null);
|
||||
return true;
|
||||
} else {
|
||||
const emailData: SendEmailDto = {
|
||||
from: { address: userEmail || "sender@example.com" },
|
||||
to: parseEmailAddresses(toEmails),
|
||||
subject,
|
||||
html: ensureString(content),
|
||||
text: ensureString(content).replace(/<[^>]*>/g, ""),
|
||||
...(attachments.length > 0 && { attachments }),
|
||||
...(isDraft && { isDraft: true, uploadOnly: true }),
|
||||
};
|
||||
|
||||
await sendEmailMutation.mutateAsync(emailData, {
|
||||
onSuccess: (data) => {
|
||||
toast(data?.data.message, "success");
|
||||
},
|
||||
});
|
||||
|
||||
resetForm();
|
||||
return true;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Error in email action:", error);
|
||||
toast("خطا در انجام عملیات", "error");
|
||||
return false;
|
||||
} finally {
|
||||
setIsSending(false);
|
||||
setIsSavingDraft(false);
|
||||
}
|
||||
};
|
||||
|
||||
const handleSend = async () => {
|
||||
const result = await handleEmailAction(false);
|
||||
return result || false;
|
||||
};
|
||||
|
||||
const handleSaveDraft = async () => {
|
||||
const result = await handleEmailAction(true);
|
||||
return result || false;
|
||||
};
|
||||
|
||||
return {
|
||||
// Form state
|
||||
toEmails,
|
||||
subject,
|
||||
content,
|
||||
priority,
|
||||
attachments,
|
||||
emailSuggestions,
|
||||
|
||||
// Loading states
|
||||
isSending,
|
||||
isSavingDraft,
|
||||
|
||||
// Form handlers
|
||||
addEmail,
|
||||
removeEmail,
|
||||
setSubject,
|
||||
setContent,
|
||||
setPriority,
|
||||
setAttachments,
|
||||
|
||||
// Search functions
|
||||
searchEmailSuggestions,
|
||||
|
||||
// Actions
|
||||
handleSend,
|
||||
handleSaveDraft,
|
||||
resetForm,
|
||||
};
|
||||
};
|
||||
Reference in New Issue
Block a user