diff --git a/src/App.tsx b/src/App.tsx index d1f2bfd..95da014 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -18,6 +18,7 @@ import { Paths } from './utils/Paths'; import Login from './pages/auth/Login'; import { EmailWebSocketProvider } from './contexts/EmailWebSocketContext'; import SocketManagment from './lib/SocketManagment'; +import NajvaToken from './components/NajvaToken'; declare global { interface Window { @@ -135,6 +136,7 @@ const App: FC = () => { + ) : isLogin === 'isNotLogin' ? ( diff --git a/src/components/NajvaToken.tsx b/src/components/NajvaToken.tsx new file mode 100644 index 0000000..0642df1 --- /dev/null +++ b/src/components/NajvaToken.tsx @@ -0,0 +1,33 @@ +import { FC, useEffect } from 'react' +import { updateProfile } from '../pages/profile/service/ProfileService' + +declare global { + interface Window { + NAJVA: { + getUserToken: () => Promise + najvaUserSubscribed: (najvaUserToken: string) => void + } + } +} +const NajvaToken: FC = () => { + + const handleNajvaToken = async () => { + const userToken = await window.NAJVA?.getUserToken() + if (userToken) { + updateProfile({ + pushToken: userToken, + }) + } + } + + useEffect(() => { + handleNajvaToken() + // window.NAJVA.najvaUserSubscribed = function (najvaUserToken) { + // console.log('najvaUserToken', najvaUserToken) + // } + }, []) + + return null +} + +export default NajvaToken \ No newline at end of file diff --git a/src/components/newMessage/EmailEditor.tsx b/src/components/newMessage/EmailEditor.tsx index 6d43999..1a38ff4 100644 --- a/src/components/newMessage/EmailEditor.tsx +++ b/src/components/newMessage/EmailEditor.tsx @@ -1,5 +1,6 @@ -import { FC } from 'react' +import { FC, useMemo } from 'react' import ReactQuill from 'react-quill-new' +import 'react-quill-new/dist/quill.snow.css' interface EmailEditorProps { value: string @@ -10,19 +11,85 @@ interface EmailEditorProps { const EmailEditor: FC = ({ value, onChange, - placeholder = '' + placeholder = 'متن پیام خود را وارد کنید...' }) => { + const modules = useMemo(() => ({ + toolbar: [ + ['bold', 'italic', 'underline'], + [{ 'list': 'ordered' }, { 'list': 'bullet' }], + [{ 'align': [] }], + [{ 'direction': 'rtl' }], + ['link'], + [{ 'color': [] }, { 'background': [] }], + [{ 'font': [] }, { 'size': ['small', false, 'large', 'huge'] }], + ['clean'] + ], + }), []) + const formats = [ + 'bold', 'italic', 'underline', + 'list', 'bullet', + 'align', 'direction', + 'link', + 'color', 'background', + 'font', 'size' + ] return ( - + + + + ) } diff --git a/src/components/newMessage/NewMessage.tsx b/src/components/newMessage/NewMessage.tsx index af6c74f..5387525 100644 --- a/src/components/newMessage/NewMessage.tsx +++ b/src/components/newMessage/NewMessage.tsx @@ -146,7 +146,7 @@ const NewMessage: FC = () => { - + { const draftUpdateData = { to: parseEmailAddresses(toEmails), subject, - html: ensureString(content), + html: `${ensureString( + content + )}`, text: ensureString(content).replace(/<[^>]*>/g, ""), ...(attachments.length > 0 && { attachments }), }; @@ -170,6 +172,9 @@ export const useNewMessage = () => { messageId: editingDraftId.toString(), draftData: { ...draftUpdateData, + html: `${ensureString( + content + )}`, isDraft: true, uploadOnly: true, }, @@ -195,7 +200,9 @@ export const useNewMessage = () => { from: { address: userEmail || "sender@example.com" }, to: parseEmailAddresses(toEmails), subject, - html: ensureString(content), + html: `${ensureString( + content + )}`, text: ensureString(content).replace(/<[^>]*>/g, ""), ...(attachments.length > 0 && { attachments }), ...(isDraft && { isDraft: true, uploadOnly: true }), diff --git a/src/hooks/useEmailWebSocket.ts b/src/hooks/useEmailWebSocket.ts index d5a8ea5..2885d0f 100644 --- a/src/hooks/useEmailWebSocket.ts +++ b/src/hooks/useEmailWebSocket.ts @@ -40,7 +40,7 @@ export const useEmailWebSocket = ({ }); newSocket.on("connection_established", (data) => { - console.log("🎉 اتصال WebSocket ایمیل تأیید شد:", data); + console.log("🎉 اتصال We bSocket ایمیل تأیید شد:", data); }); newSocket.on("connection_error", (error) => { diff --git a/src/index.css b/src/index.css index 1aec8aa..dad22e3 100644 --- a/src/index.css +++ b/src/index.css @@ -238,7 +238,13 @@ textarea::placeholder { @apply rounded-t-xl; } .ql-editor { - @apply !text-right; + text-align: start !important; + unicode-bidi: plaintext !important; +} +.ql-editor p { + unicode-bidi: plaintext !important; + text-align: start !important; + direction: auto !important; } .dltr { diff --git a/src/main.tsx b/src/main.tsx index bef5202..573630b 100644 --- a/src/main.tsx +++ b/src/main.tsx @@ -1,6 +1,7 @@ import { StrictMode } from 'react' import { createRoot } from 'react-dom/client' import './index.css' +import './assets/fonts/irancell/style.css' import App from './App.tsx' createRoot(document.getElementById('root')!).render( diff --git a/src/pages/Trash/service/TrashService.ts b/src/pages/Trash/service/TrashService.ts index 82689b6..35af6cc 100644 --- a/src/pages/Trash/service/TrashService.ts +++ b/src/pages/Trash/service/TrashService.ts @@ -6,8 +6,6 @@ import { MessageListQueryDto, TrashResponse } from "../types/TrashTypes"; export const getTrashMessages = async ( query: MessageListQueryDto ): Promise => { - console.log("query", query); - const isSearch = !!query.search || !!query.datestart || query.dateend || query.from; const url = isSearch ? "search" : "messages/trash"; diff --git a/src/pages/archive/service/ArchiveService.ts b/src/pages/archive/service/ArchiveService.ts index 4679da7..93bb681 100644 --- a/src/pages/archive/service/ArchiveService.ts +++ b/src/pages/archive/service/ArchiveService.ts @@ -5,8 +5,6 @@ import { MessageListQueryDto, ArchiveResponse } from "../types/ArchiveTypes"; export const getArchiveMessages = async ( query: MessageListQueryDto ): Promise => { - console.log("query", query); - const isSearch = !!query.search || !!query.datestart || query.dateend || query.from; const url = isSearch ? "search" : "messages/archive"; diff --git a/src/pages/draft/service/DraftService.ts b/src/pages/draft/service/DraftService.ts index 56ebf55..6591cfc 100644 --- a/src/pages/draft/service/DraftService.ts +++ b/src/pages/draft/service/DraftService.ts @@ -10,8 +10,6 @@ import { export const getDrafts = async ( query: MessageListQueryDto ): Promise => { - console.log("query", query); - const isSearch = !!query.search || !!query.datestart || query.dateend || query.from; const url = isSearch ? "search" : "messages/drafts"; diff --git a/src/pages/favorite/service/FavoriteService.ts b/src/pages/favorite/service/FavoriteService.ts index ad232b6..4890f28 100644 --- a/src/pages/favorite/service/FavoriteService.ts +++ b/src/pages/favorite/service/FavoriteService.ts @@ -5,8 +5,6 @@ import { MessageListQueryDto, FavoriteResponse } from "../types/FavoriteTypes"; export const getFavoriteMessages = async ( query: MessageListQueryDto ): Promise => { - console.log("query", query); - const isSearch = !!query.search || !!query.datestart || query.dateend || query.from; const url = isSearch ? "search" : "messages/favorite"; diff --git a/src/pages/profile/types/ProfileTypes.ts b/src/pages/profile/types/ProfileTypes.ts index 44bc527..ada9745 100644 --- a/src/pages/profile/types/ProfileTypes.ts +++ b/src/pages/profile/types/ProfileTypes.ts @@ -12,6 +12,7 @@ export type UpdateProfileType = { cityId?: string; postalCode?: string; userAddress?: string; + pushToken?: string; }; export type UpdateEmailType = { diff --git a/src/pages/received/Components/Header.tsx b/src/pages/received/Components/Header.tsx index f305d64..9c10643 100644 --- a/src/pages/received/Components/Header.tsx +++ b/src/pages/received/Components/Header.tsx @@ -9,12 +9,89 @@ import MessageSpam from './MessageSpam' import { MailboxEnum } from '../enum/Enum' import MessageFavorite from './MessageFavorite' import MessageTrash from './MessageTrash' +import { MessageDetail } from '../types/Types' +import { sanitizeEmailHTML, detectTextDirection } from '@/config/func' -const Header: FC<{ mailBoxName: MailboxEnum, flagged: boolean }> = ({ mailBoxName, flagged }) => { +const Header: FC<{ + mailBoxName: MailboxEnum, + flagged: boolean, + messageDetail?: MessageDetail +}> = ({ mailBoxName, flagged, messageDetail }) => { const navigate = useNavigate() const { t } = useTranslation() + const handlePrint = () => { + if (!messageDetail) return + + // Create a new window for printing + const printWindow = window.open('', '_blank', 'width=800,height=600') + if (!printWindow) return + + // Get the email content + let content = '' + if (messageDetail.html && messageDetail.html.length > 0) { + content = sanitizeEmailHTML(messageDetail.html.join('')) + } else { + content = messageDetail.text || 'محتوای پیام' + } + + // Detect text direction + const direction = detectTextDirection(content) + + // Create print content + const printContent = ` + + + + + پرینت ایمیل + + + + + موضوع: ${messageDetail.subject || 'بدون موضوع'} + فرستنده: ${messageDetail.from.name || messageDetail.from.address} <${messageDetail.from.address}> + تاریخ: ${new Date(messageDetail.date).toLocaleDateString('fa-IR')} + + + ${content} + + + + ` + + // Write content and print + printWindow.document.write(printContent) + printWindow.document.close() + + // Wait for content to load then print + printWindow.onload = () => { + printWindow.print() + printWindow.close() + } + } + return ( @@ -42,6 +119,7 @@ const Header: FC<{ mailBoxName: MailboxEnum, flagged: boolean }> = ({ mailBoxNam diff --git a/src/pages/received/Detail.tsx b/src/pages/received/Detail.tsx index e30b717..f552d6c 100644 --- a/src/pages/received/Detail.tsx +++ b/src/pages/received/Detail.tsx @@ -141,7 +141,11 @@ const DetailEmail: FC = () => { return ( - + diff --git a/src/pages/received/List.tsx b/src/pages/received/List.tsx index 6bb8ec5..bfa0e38 100644 --- a/src/pages/received/List.tsx +++ b/src/pages/received/List.tsx @@ -206,24 +206,12 @@ const List: FC = () => { }; const messages = inboxData?.data?.results || []; - const pager = inboxData?.data?.pager; const rootData = inboxData?.data as unknown as Record; - // Debug pagination data - console.log('Full response data:', inboxData?.data); - console.log('Pager data:', pager); - console.log('Root nextCursor:', rootData?.nextCursor); - console.log('Root previousCursor:', rootData?.previousCursor); - // Get cursors from response const responseNextCursor = (typeof rootData?.nextCursor === 'string' && rootData.nextCursor !== '') ? rootData.nextCursor as string : undefined; const responsePreviousCursor = (typeof rootData?.previousCursor === 'string' && rootData.previousCursor !== '') ? rootData.previousCursor as string : undefined; - // Debug pagination values - console.log('responseNextCursor:', responseNextCursor); - console.log('responsePreviousCursor:', responsePreviousCursor); - console.log('Will render pagination?', !!(responseNextCursor || responsePreviousCursor)); - return ( {t('received.title')} diff --git a/src/pages/received/service/EmailService.ts b/src/pages/received/service/EmailService.ts index d515241..41a3768 100644 --- a/src/pages/received/service/EmailService.ts +++ b/src/pages/received/service/EmailService.ts @@ -36,8 +36,6 @@ export const getDraft = async ( export const getInbox = async ( query: MessageListQueryDto ): Promise => { - console.log("query", query); - const isSearch = !!query.search || !!query.datestart || diff --git a/src/pages/sent/service/SentService.ts b/src/pages/sent/service/SentService.ts index 17e57bc..88b4d79 100644 --- a/src/pages/sent/service/SentService.ts +++ b/src/pages/sent/service/SentService.ts @@ -10,8 +10,6 @@ import { export const getSentMessages = async ( query: MessageListQueryDto ): Promise => { - console.log("query", query); - const isSearch = !!query.search || !!query.datestart || query.dateend || query.from; const url = isSearch ? "search" : "messages/sent"; diff --git a/src/pages/spam/service/SpamService.ts b/src/pages/spam/service/SpamService.ts index 2d24e94..0a9881a 100644 --- a/src/pages/spam/service/SpamService.ts +++ b/src/pages/spam/service/SpamService.ts @@ -6,8 +6,6 @@ import { MailboxEnum } from "@/pages/received/enum/Enum"; export const getSpamMessages = async ( query: MessageListQueryDto ): Promise => { - console.log("query", query); - const isSearch = !!query.search || !!query.datestart || query.dateend || query.from; const url = isSearch ? "search" : "messages/junk";
فرستنده: ${messageDetail.from.name || messageDetail.from.address} <${messageDetail.from.address}>
تاریخ: ${new Date(messageDetail.date).toLocaleDateString('fa-IR')}