diff --git a/.env b/.env index a5473ac..900a242 100644 --- a/.env +++ b/.env @@ -11,3 +11,5 @@ VITE_BASE_URL = 'https://dmail-api.danakcorp.com' VITE_SERVICE_ID = 'e51afdc3-ea0b-49cf-8f49-2a6f131b024e' + +VITE_MAILBOXES = 'mailboxes' diff --git a/src/config/func.ts b/src/config/func.ts index cc068fc..cf04bc5 100644 --- a/src/config/func.ts +++ b/src/config/func.ts @@ -156,3 +156,29 @@ export const sanitizeEmailHTML = (html: string): string => { return "خطا در نمایش محتوای ایمیل"; } }; + +// Interface برای mailbox structure +interface MailboxItem { + id: string; + name: string; + unseen: number; + total: number; +} + +// Utility function برای گرفتن mailbox id از localStorage +export const getMailboxId = (mailboxName: string): string | null => { + try { + const mailboxesStr = localStorage.getItem("mailboxes"); + if (!mailboxesStr) return null; + + const mailboxes: MailboxItem[] = JSON.parse(mailboxesStr); + const mailbox = mailboxes.find( + (mb: MailboxItem) => mb.name === mailboxName + ); + + return mailbox?.id || null; + } catch (error) { + console.error("Error getting mailbox id:", error); + return null; + } +}; diff --git a/src/pages/Trash/List.tsx b/src/pages/Trash/List.tsx index d5d5fb8..bcf2c2b 100644 --- a/src/pages/Trash/List.tsx +++ b/src/pages/Trash/List.tsx @@ -116,23 +116,13 @@ const List: FC = () => { return (
-

سطل آشغال

+

سطل زباله

=> { - const { data } = await axios.get(`/email/messages/trash`, { params: query }); + console.log("query", query); + + const isSearch = + !!query.search || !!query.datestart || query.dateend || query.from; + const url = isSearch ? "search" : "messages/trash"; + + // اضافه کردن mailbox id از localStorage + const mailboxId = getMailboxId("Trash"); + const queryWithMailbox = { + ...query, + mailbox: mailboxId, + }; + + const { data } = await axios.get(`/email/${url}`, { + params: queryWithMailbox, + }); return data; }; diff --git a/src/pages/Trash/types/TrashTypes.ts b/src/pages/Trash/types/TrashTypes.ts index 7e2829e..8467dbb 100644 --- a/src/pages/Trash/types/TrashTypes.ts +++ b/src/pages/Trash/types/TrashTypes.ts @@ -37,11 +37,14 @@ export interface TrashMessage extends Record { export interface MessageListQueryDto { page?: number; limit?: number; - order?: "asc" | "desc"; search?: string; - dateFrom?: string; - dateTo?: string; - isRead?: string; + from?: string; + subject?: string; + datestart?: string; + dateend?: string; + attachments?: boolean; + flagged?: boolean; + order?: "asc" | "desc"; } export interface TrashResponse { diff --git a/src/pages/archive/List.tsx b/src/pages/archive/List.tsx index 8fd936a..9612bb4 100644 --- a/src/pages/archive/List.tsx +++ b/src/pages/archive/List.tsx @@ -114,23 +114,13 @@ const List: FC = () => { return (
-

آرشیو

+

آرشیو شده ها

=> { - const { data } = await axios.get(`/email/messages/archive`, { - params: query, + console.log("query", query); + + const isSearch = + !!query.search || !!query.datestart || query.dateend || query.from; + const url = isSearch ? "search" : "messages/archive"; + + // اضافه کردن mailbox id از localStorage + const mailboxId = getMailboxId("Archive"); + const queryWithMailbox = { + ...query, + mailbox: mailboxId, + }; + + const { data } = await axios.get(`/email/${url}`, { + params: queryWithMailbox, }); return data; }; diff --git a/src/pages/archive/types/ArchiveTypes.ts b/src/pages/archive/types/ArchiveTypes.ts index 6de7791..394d550 100644 --- a/src/pages/archive/types/ArchiveTypes.ts +++ b/src/pages/archive/types/ArchiveTypes.ts @@ -37,11 +37,14 @@ export interface ArchiveMessage extends Record { export interface MessageListQueryDto { page?: number; limit?: number; - order?: "asc" | "desc"; search?: string; - dateFrom?: string; - dateTo?: string; - isRead?: string; + from?: string; + subject?: string; + datestart?: string; + dateend?: string; + attachments?: boolean; + flagged?: boolean; + order?: "asc" | "desc"; } export interface ArchiveResponse { diff --git a/src/pages/draft/List.tsx b/src/pages/draft/List.tsx index 07e48b5..0953c79 100644 --- a/src/pages/draft/List.tsx +++ b/src/pages/draft/List.tsx @@ -184,8 +184,8 @@ const List: FC = () => { => { - const { data } = await axios.get(`/email/messages/drafts`, { params: query }); + console.log("query", query); + + const isSearch = + !!query.search || !!query.datestart || query.dateend || query.from; + const url = isSearch ? "search" : "messages/drafts"; + + // اضافه کردن mailbox id از localStorage + const mailboxId = getMailboxId("Drafts"); + const queryWithMailbox = { + ...query, + mailbox: mailboxId, + }; + + const { data } = await axios.get(`/email/${url}`, { + params: queryWithMailbox, + }); return data; }; diff --git a/src/pages/draft/types/DraftTypes.ts b/src/pages/draft/types/DraftTypes.ts index 1e6c572..2f153b3 100644 --- a/src/pages/draft/types/DraftTypes.ts +++ b/src/pages/draft/types/DraftTypes.ts @@ -21,15 +21,14 @@ export interface EmailAttachmentDto { export interface MessageListQueryDto { page?: number; limit?: number; - order?: string; search?: string; from?: string; subject?: string; - dateFrom?: string; - dateTo?: string; - hasAttachment?: boolean; - isRead?: boolean; - isFlagged?: boolean; + datestart?: string; + dateend?: string; + attachments?: boolean; + flagged?: boolean; + order?: "asc" | "desc"; } export interface DraftMessage extends Record { diff --git a/src/pages/favorite/List.tsx b/src/pages/favorite/List.tsx index 163466f..c2985f0 100644 --- a/src/pages/favorite/List.tsx +++ b/src/pages/favorite/List.tsx @@ -2,7 +2,7 @@ import Filters, { FilterValues } from '../../components/Filters'; import { FC, useState } from 'react' import Table from '../../components/Table'; import { ColumnType } from '../../components/types/TableTypes'; -import { InfoCircle, More, Refresh2, Trash, Star, Archive } from 'iconsax-react'; +import { InfoCircle, More, Refresh2, Trash, Archive, Star1 } from 'iconsax-react'; import { RowActionItem } from '../../components/RowActionsDropdown'; import { useNavigate } from 'react-router-dom'; import { useGetFavoriteMessages } from './hooks/useFavoriteData'; @@ -66,7 +66,7 @@ const List: FC = () => { const selectedActions = ( <> - handleUnfavoriteSelected()} className="cursor-pointer" /> + handleUnfavoriteSelected()} className="cursor-pointer" /> handleArchiveSelected()} className="cursor-pointer" /> handleDeleteSelected()} className="cursor-pointer" /> @@ -102,7 +102,7 @@ const List: FC = () => { const getRowActions = (message: FavoriteMessage): RowActionItem[] => [ { label: 'حذف از علاقه‌مندی‌ها', - icon: , + icon: , onClick: () => emailActions.unfavorite({ messageId: message.id, mailbox: message.mailbox }), }, { @@ -126,23 +126,13 @@ const List: FC = () => { return (
-

علاقه‌مندی‌ها

+

نشان شده ها

=> { - const { data } = await axios.get(`/email/messages/favorite`, { - params: query, + console.log("query", query); + + const isSearch = + !!query.search || !!query.datestart || query.dateend || query.from; + const url = isSearch ? "search" : "messages/favorite"; + + // اضافه کردن mailbox id از localStorage + const mailboxId = getMailboxId("FAVORITE"); + const queryWithMailbox = { + ...query, + mailbox: mailboxId, + }; + + const { data } = await axios.get(`/email/${url}`, { + params: queryWithMailbox, }); return data; }; diff --git a/src/pages/favorite/types/FavoriteTypes.ts b/src/pages/favorite/types/FavoriteTypes.ts index 23d74af..63ebfe7 100644 --- a/src/pages/favorite/types/FavoriteTypes.ts +++ b/src/pages/favorite/types/FavoriteTypes.ts @@ -37,11 +37,14 @@ export interface FavoriteMessage extends Record { export interface MessageListQueryDto { page?: number; limit?: number; - order?: "asc" | "desc"; search?: string; - dateFrom?: string; - dateTo?: string; - isRead?: string; + from?: string; + subject?: string; + datestart?: string; + dateend?: string; + attachments?: boolean; + flagged?: boolean; + order?: "asc" | "desc"; } export interface FavoriteResponse { diff --git a/src/pages/received/Components/Favorite.tsx b/src/pages/received/Components/Favorite.tsx new file mode 100644 index 0000000..d2c4908 --- /dev/null +++ b/src/pages/received/Components/Favorite.tsx @@ -0,0 +1,36 @@ +import { FC, useState } from 'react' +import { Star1 } from 'iconsax-react' +import { useMoveToFavorite, useUnFavoriteMessage } from '../hooks/useEmailData'; + +const Favorite: FC<{ flagged: boolean, id: string, mailbox: string }> = ({ flagged, id, mailbox }) => { + + const [isFavorite, setIsFavorite] = useState(flagged) + const { mutate: moveToFavorite } = useMoveToFavorite() + const { mutate: unFavoriteMessage } = useUnFavoriteMessage() + + const handleFavoriteClick = (e: React.MouseEvent) => { + e.preventDefault() + e.stopPropagation() + console.log('Favorite clicked!', { isFavorite, id, mailbox }) + + if (isFavorite) { + unFavoriteMessage({ messageId: id || '', mailbox: mailbox || '' }) + } else { + moveToFavorite({ messageId: id || '', mailbox: mailbox || '' }) + } + setIsFavorite(!isFavorite) + } + + return ( +
+ +
+ ) +}; + +export default Favorite; \ No newline at end of file diff --git a/src/pages/received/Components/Header.tsx b/src/pages/received/Components/Header.tsx index 2377120..56585d4 100644 --- a/src/pages/received/Components/Header.tsx +++ b/src/pages/received/Components/Header.tsx @@ -10,7 +10,7 @@ import { MailboxEnum } from '../enum/Enum' import MessageFavorite from './MessageFavorite' import MessageTrash from './MessageTrash' -const Header: FC<{ mailBoxName: MailboxEnum }> = ({ mailBoxName }) => { +const Header: FC<{ mailBoxName: MailboxEnum, flagged: boolean }> = ({ mailBoxName, flagged }) => { const navigate = useNavigate() const { t } = useTranslation() @@ -22,7 +22,7 @@ const Header: FC<{ mailBoxName: MailboxEnum }> = ({ mailBoxName }) => { - + {/* */} {/* */} diff --git a/src/pages/received/Components/MessageFavorite.tsx b/src/pages/received/Components/MessageFavorite.tsx index 7eda541..e8c4718 100644 --- a/src/pages/received/Components/MessageFavorite.tsx +++ b/src/pages/received/Components/MessageFavorite.tsx @@ -3,8 +3,8 @@ import { FC, useState } from 'react' import { useNavigate, useParams } from 'react-router-dom' import { useMoveToFavorite, useUnFavoriteMessage } from '../hooks/useEmailData' -const MessageFavorite: FC<{ isActiveFavorite: boolean }> = ({ isActiveFavorite }) => { - const [isFavorite, setIsFavorite] = useState(isActiveFavorite) +const MessageFavorite: FC<{ flagged: boolean }> = ({ flagged }) => { + const [isFavorite, setIsFavorite] = useState(flagged) const { id, mailbox } = useParams<{ id: string, mailbox: string }>() const { mutate: moveToFavorite } = useMoveToFavorite() const { mutate: unFavoriteMessage } = useUnFavoriteMessage() diff --git a/src/pages/received/Detail.tsx b/src/pages/received/Detail.tsx index 15cecc9..e30b717 100644 --- a/src/pages/received/Detail.tsx +++ b/src/pages/received/Detail.tsx @@ -141,7 +141,7 @@ const DetailEmail: FC = () => { return (
-
+
diff --git a/src/pages/received/List.tsx b/src/pages/received/List.tsx index 8e572a6..f5b0f1a 100644 --- a/src/pages/received/List.tsx +++ b/src/pages/received/List.tsx @@ -1,22 +1,20 @@ import Filters, { FilterValues } from '../../components/Filters'; -import { FC, useState, useEffect } from 'react' +import { FC, useState } from 'react' import { useTranslation } from 'react-i18next' import Table from '../../components/Table'; import { ColumnType } from '../../components/types/TableTypes'; import { InfoCircle, More, Refresh2, Trash, Edit, Archive, ArchiveTick, Star1 } from 'iconsax-react'; import { RowActionItem } from '../../components/RowActionsDropdown'; -import { useNavigate, useLocation } from 'react-router-dom'; +import { useNavigate } from 'react-router-dom'; import { useGetInbox } from './hooks/useEmailData'; import { InboxMessage } from './types/Types'; import { formatDate } from '@/config/func'; import MarkAsRead from '@/assets/images/mark_as_read.svg' import { useEmailActions } from '@/hooks/useEmailActions'; -import { useQueryClient } from '@tanstack/react-query'; +import Favorite from './Components/Favorite'; const List: FC = () => { - const queryClient = useQueryClient(); const navigate = useNavigate(); - const location = useLocation(); const { t } = useTranslation(); const [currentPage, setCurrentPage] = useState(1); const [filters, setFilters] = useState({}); @@ -28,18 +26,17 @@ const List: FC = () => { ...filters }); - // Force refresh when component mounts or location changes - useEffect(() => { - // Refetch when coming back to inbox from other pages - if (location.pathname === '/') { - refetch(); - queryClient.invalidateQueries({ queryKey: ['mailbox-count'] }); - } - }, [location.pathname, refetch]); const [selectedMessages, setSelectedMessages] = useState([]); const columns: ColumnType[] = [ + { + key: 'flagged', + title: 'علامت گذاری', + render: (item) => ( + + ) + }, { key: 'subject', title: 'عنوان پیام', diff --git a/src/pages/received/service/EmailService.ts b/src/pages/received/service/EmailService.ts index b6cc3a5..b195be2 100644 --- a/src/pages/received/service/EmailService.ts +++ b/src/pages/received/service/EmailService.ts @@ -1,4 +1,5 @@ import axios from "../../../config/axios"; +import { getMailboxId } from "../../../config/func"; import { SendEmailDto, MessageListQueryDto, @@ -37,8 +38,15 @@ export const getInbox = async ( query.from; const url = isSearch ? "search" : "messages/inbox"; + // اضافه کردن mailbox id از localStorage + const mailboxId = getMailboxId("INBOX"); + const queryWithMailbox = { + ...query, + mailbox: mailboxId, + }; + const { data } = await axios.get(`/email/${url}`, { - params: query, + params: queryWithMailbox, }); return data; }; diff --git a/src/pages/sent/List.tsx b/src/pages/sent/List.tsx index 52b81b5..031f760 100644 --- a/src/pages/sent/List.tsx +++ b/src/pages/sent/List.tsx @@ -147,23 +147,13 @@ const List: FC = () => { return (
-

ارسال شده

+

ارسال شده ها

=> { - const { data } = await axios.get(`/email/messages/sent`, { params: query }); + console.log("query", query); + + const isSearch = + !!query.search || !!query.datestart || query.dateend || query.from; + const url = isSearch ? "search" : "messages/sent"; + + // اضافه کردن mailbox id از localStorage + const mailboxId = getMailboxId("Sent Mail"); + const queryWithMailbox = { + ...query, + mailbox: mailboxId, + }; + + const { data } = await axios.get(`/email/${url}`, { + params: queryWithMailbox, + }); return data; }; diff --git a/src/pages/sent/types/SentTypes.ts b/src/pages/sent/types/SentTypes.ts index 1618b63..2aa3fec 100644 --- a/src/pages/sent/types/SentTypes.ts +++ b/src/pages/sent/types/SentTypes.ts @@ -2,9 +2,13 @@ export interface MessageListQueryDto { page?: number; limit?: number; search?: string; - from_date?: string; - to_date?: string; - status?: "all" | "read" | "unread"; + from?: string; + subject?: string; + datestart?: string; + dateend?: string; + attachments?: boolean; + flagged?: boolean; + order?: "asc" | "desc"; } export interface EmailAddress { diff --git a/src/pages/spam/List.tsx b/src/pages/spam/List.tsx index 8d1b8d5..5e2fa40 100644 --- a/src/pages/spam/List.tsx +++ b/src/pages/spam/List.tsx @@ -113,23 +113,13 @@ const List: FC = () => { return (
-

پیام‌های اسپم

+

هرزنامه ها

=> { - const { data } = await axios.get(`/email/messages/junk`, { params: query }); + console.log("query", query); + + const isSearch = + !!query.search || !!query.datestart || query.dateend || query.from; + const url = isSearch ? "search" : "messages/junk"; + + // اضافه کردن mailbox id از localStorage + const mailboxId = getMailboxId("Junk"); + const queryWithMailbox = { + ...query, + mailbox: mailboxId, + }; + + const { data } = await axios.get(`/email/${url}`, { + params: queryWithMailbox, + }); return data; }; diff --git a/src/pages/spam/types/SpamTypes.ts b/src/pages/spam/types/SpamTypes.ts index 4d308d4..0cc527c 100644 --- a/src/pages/spam/types/SpamTypes.ts +++ b/src/pages/spam/types/SpamTypes.ts @@ -37,11 +37,14 @@ export interface SpamMessage extends Record { export interface MessageListQueryDto { page?: number; limit?: number; - order?: "asc" | "desc"; search?: string; - dateFrom?: string; - dateTo?: string; - isRead?: string; + from?: string; + subject?: string; + datestart?: string; + dateend?: string; + attachments?: boolean; + flagged?: boolean; + order?: "asc" | "desc"; } export interface SpamResponse { diff --git a/src/shared/SideBar.tsx b/src/shared/SideBar.tsx index 5046d85..2690af4 100644 --- a/src/shared/SideBar.tsx +++ b/src/shared/SideBar.tsx @@ -1,4 +1,4 @@ -import { FC } from 'react' +import { FC, useEffect } from 'react' import LogoImage from '../assets/images/logo.svg' import { Add, ArchiveTick, DirectInbox, DirectSend, Edit, InfoCircle, Logout, Star1, Trash, Setting2 } from 'iconsax-react' import SideBarItem from './SideBarItem' @@ -22,6 +22,14 @@ const SideBar: FC = () => { const isActive = (path: string) => location.pathname === path + useEffect(() => { + if (mailboxCount?.data) { + localStorage.setItem(import.meta.env.VITE_MAILBOXES, JSON.stringify(mailboxCount?.data?.mailboxes)) + } + + }, [mailboxCount?.data]) + + const iconSizeSideBar = 20 if (!mailboxCount?.data) return null return (