Files
dmail-front/src/pages/favorite/List.tsx
T
2025-07-20 16:47:01 +03:30

179 lines
6.7 KiB
TypeScript
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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 { RowActionItem } from '../../components/RowActionsDropdown';
import { useNavigate } from 'react-router-dom';
import { useGetFavoriteMessages } from './hooks/useFavoriteData';
import { FavoriteMessage } from './types/FavoriteTypes';
import { formatDate } from '@/config/func';
import { useEmailActions } from '@/hooks/useEmailActions';
const List: FC = () => {
const navigate = useNavigate();
const [currentPage, setCurrentPage] = useState(1);
const [filters, setFilters] = useState<FilterValues>({});
const emailActions = useEmailActions();
const { data: favoriteData, isLoading, refetch, isFetching } = useGetFavoriteMessages({
page: currentPage,
limit: 10,
...filters
});
const [selectedMessages, setSelectedMessages] = useState<FavoriteMessage[]>([]);
const columns: ColumnType<FavoriteMessage>[] = [
{
key: 'subject',
title: 'عنوان پیام',
render: (item) => (
<span className="truncate">{item.subject || 'بدون موضوع'}</span>
)
},
{
key: 'from',
title: 'فرستنده',
render: (item) => (
<div className="flex items-center">
{!item.seen && <div className="w-1.5 h-1.5 md:w-2 md:h-2 rounded-full bg-blue-500 ml-2" />}
<span className="truncate">{item.from.name || item.from.address}</span>
</div>
)
},
{
key: 'date',
title: 'تاریخ',
align: 'center',
render: (item) => (
<span>{formatDate(item.date)}</span>
)
},
];
const tableActions = (
<div className='flex items-center gap-2 md:gap-4'>
<Refresh2
size={18}
color='black'
className={`cursor-pointer ${isFetching ? 'animate-spin-reverse' : ''}`}
onClick={() => refetch()}
/>
<More size={18} color='black' className='rotate-90 cursor-pointer' />
</div>
);
const selectedActions = (
<>
<Star size={18} color='black' onClick={() => handleUnfavoriteSelected()} className="cursor-pointer" />
<Archive size={18} color='black' onClick={() => handleArchiveSelected()} className="cursor-pointer" />
<Trash size={18} color='black' onClick={() => handleDeleteSelected()} className="cursor-pointer" />
</>
);
const handleFilterChange = (newFilters: FilterValues) => {
setFilters(newFilters);
setCurrentPage(1);
};
const handleSelectionChange = (selectedRows: FavoriteMessage[]) => {
setSelectedMessages(selectedRows);
};
const handleDeleteSelected = () => {
const messageIds = selectedMessages.map(message => message.id);
emailActions.bulkMoveToTrash(messageIds, selectedMessages[0].mailbox);
setSelectedMessages([]);
};
const handleArchiveSelected = () => {
const messageIds = selectedMessages.map(message => message.id);
emailActions.bulkArchive(messageIds, selectedMessages[0].mailbox);
setSelectedMessages([]);
};
const handleUnfavoriteSelected = () => {
const messageIds = selectedMessages.map(message => message.id);
emailActions.bulkUnfavorite(messageIds, selectedMessages[0].mailbox);
setSelectedMessages([]);
};
const getRowActions = (message: FavoriteMessage): RowActionItem[] => [
{
label: 'حذف از علاقه‌مندی‌ها',
icon: <Star size={16} color="black" />,
onClick: () => emailActions.unfavorite({ messageId: message.id, mailbox: message.mailbox }),
},
{
label: 'بایگانی',
icon: <Archive size={16} color="black" />,
onClick: () => emailActions.archive({ messageId: message.id, mailbox: message.mailbox }),
},
{
label: 'حذف',
icon: <Trash size={16} color="red" />,
onClick: () => emailActions.moveToTrash({ messageId: message.id, mailbox: message.mailbox }),
},
];
const handlePageChange = (page: number) => {
setCurrentPage(page);
};
const messages = favoriteData?.data?.favoriteMails || [];
const pager = favoriteData?.data?.pager;
return (
<div className='mt-2 md:mt-4 px-2 md:px-0'>
<h1 className="text-lg mb-4 md:mb-0">علاقهمندیها</h1>
<Filters
fields={[
{ type: 'date', name: 'dateFrom', placeholder: 'از تاریخ' },
{ type: 'date', name: 'dateTo', placeholder: 'تا تاریخ' },
{
type: 'select',
name: 'isRead',
placeholder: 'همه',
options: [
{ value: '', label: 'همه' },
{ value: 'true', label: 'خوانده شده' },
{ value: 'false', label: 'خوانده نشده' }
]
},
{ type: 'input', name: 'search', placeholder: 'جستجو...' }
]}
onChange={handleFilterChange}
searchField="search"
/>
<Table<FavoriteMessage>
columns={columns}
data={messages}
isLoading={isLoading || emailActions.isLoading}
showHeader={false}
actions={tableActions}
selectedActions={selectedActions}
onSelectionChange={handleSelectionChange}
selectedRows={selectedMessages}
onRowClick={(id) => navigate(`/mail/${id}`)}
noDataMessage={
<div className="flex flex-col items-center">
<InfoCircle size={32} className="text-gray-300 mb-2" />
<div className="text-sm">هیچ پیامی یافت نشد</div>
</div>
}
selectable={true}
rowActions={getRowActions}
pagination={pager ? {
totalPages: pager.totalPages,
currentPage: pager.page,
onPageChange: handlePageChange
} : undefined}
/>
</div>
)
}
export default List