pixel perfect
This commit is contained in:
@@ -0,0 +1,38 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<svg id="Layer_1" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 378.82 428.04">
|
||||||
|
<!-- Generator: Adobe Illustrator 29.4.0, SVG Export Plug-In . SVG Version: 2.1.0 Build 152) -->
|
||||||
|
<defs>
|
||||||
|
<style>
|
||||||
|
.st0 {
|
||||||
|
fill: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.st0, .st1 {
|
||||||
|
stroke: #231f20;
|
||||||
|
stroke-miterlimit: 10;
|
||||||
|
stroke-width: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.st2 {
|
||||||
|
fill: #f1f2f2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.st1 {
|
||||||
|
fill: #fff;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</defs>
|
||||||
|
<path class="st2" d="M26.33,134.89l139.31,26.29.91-75.8s4.58-51.64-32.93-72.01c0,0-14.37-12.9-28.87-12.22,0,0-35.27-3.06-61.2,23.83,0,0-17.22,16.87-17.22,43.16v66.77-.02Z"/>
|
||||||
|
<g>
|
||||||
|
<line class="st0" x1="234.92" y1="161.17" x2="234.92" y2="428.04"/>
|
||||||
|
<line class="st0" x1="210.55" y1="161.17" x2="210.55" y2="428.04"/>
|
||||||
|
<path class="st0" d="M309.35,2.08H114.32c8.68,3.97,20.29,10.61,31.51,21.61l.16.16c9.16,9.03,15.39,20.65,17.97,33.25.26,1.26.5,2.55.73,3.87,1.61,9.3,1.99,17.6,1.85,24.4-.3,25.27-.6,50.53-.91,75.8h211.69v-91.1c0-37.55-30.44-67.99-67.99-67.99h.02Z"/>
|
||||||
|
<path class="st0" d="M114.32,2.08S71.25-5.98,43.55,24.96c-11.33,12.66-17.22,29.28-17.22,46.27v63.65l139.31,26.29c-11.47,21.17-22.94,42.33-34.41,63.5-2.96,5.64-16.53,29.99-45.53,38.79-14.39,4.37-27.02,3.22-34.46,1.89-4.58-.98-11.14-2.9-18.23-6.91-4.37-2.47-17.15-9.92-25.19-25.84-7-13.85-6.69-26.75-6.2-32.48.76-8.29,2.53-18.8,6.52-30.44,5.24-15.26,12.4-26.89,18.19-34.79"/>
|
||||||
|
<line class="st0" x1="26.73" y1="133.12" x2="152.45" y2="133.12"/>
|
||||||
|
<polygon class="st1" points="198.72 101.68 198.72 191.03 169.06 191.03 169.06 175.6 179.74 175.6 179.74 101.68 198.72 101.68"/>
|
||||||
|
<circle class="st0" cx="188.68" cy="86.27" r="11.86"/>
|
||||||
|
<path class="st0" d="M240.22,93.77s37.36,31.83,60.09-7.5"/>
|
||||||
|
<path class="st0" d="M232.32,76.86s12.65,8.41,18.58-4.04"/>
|
||||||
|
<path class="st0" d="M287.86,68.75s12.65,8.41,18.58-4.04"/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 1.9 KiB |
@@ -77,7 +77,7 @@ const RowActionsDropdown: React.FC<RowActionsDropdownProps> = ({ actions, classN
|
|||||||
return createPortal(
|
return createPortal(
|
||||||
<div
|
<div
|
||||||
ref={dropdownRef}
|
ref={dropdownRef}
|
||||||
className="fixed py-1 md:py-2 bg-white rounded-xl md:rounded-2xl shadow-lg z-[5] min-w-[140px] md:min-w-[150px]"
|
className="fixed py-3 md:py-3 bg-white rounded-xl md:rounded-2xl shadow-lg z-[5] min-w-[140px] md:min-w-[150px]"
|
||||||
style={{
|
style={{
|
||||||
top: `${position.top}px`,
|
top: `${position.top}px`,
|
||||||
left: `${position.left}px`,
|
left: `${position.left}px`,
|
||||||
@@ -87,11 +87,11 @@ const RowActionsDropdown: React.FC<RowActionsDropdownProps> = ({ actions, classN
|
|||||||
<button
|
<button
|
||||||
key={index}
|
key={index}
|
||||||
onClick={() => handleActionClick(action)}
|
onClick={() => handleActionClick(action)}
|
||||||
className={`w-full text-right px-2 md:px-3 py-1 md:py-1.5 text-xs md:text-[13px] flex items-center gap-2 hover:bg-gray-50 ${index === 0 ? 'rounded-t-lg' : ''
|
className={`w-full mt-1 text-right px-2 md:px-3 py-1 md:py-1.5 text-xs md:text-[13px] flex items-center gap-2 hover:bg-gray-50 ${index === 0 ? 'rounded-t-lg' : ''
|
||||||
} ${action.className || ''}`}
|
} ${action.className || ''}`}
|
||||||
>
|
>
|
||||||
{action.icon && <span className="ml-2">{action.icon}</span>}
|
{action.icon && <span className="ml-2">{action.icon}</span>}
|
||||||
{action.label}
|
<span className={action.label === 'حذف' ? 'text-red-500' : ''}>{action.label}</span>
|
||||||
</button>
|
</button>
|
||||||
))}
|
))}
|
||||||
</div>,
|
</div>,
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import { TableProps, RowDataType, ColumnType } from './types/TableTypes';
|
|||||||
import { Checkbox } from './ui/checkbox';
|
import { Checkbox } from './ui/checkbox';
|
||||||
import RowActionsDropdown from './RowActionsDropdown';
|
import RowActionsDropdown from './RowActionsDropdown';
|
||||||
import Pagination from './Pagination';
|
import Pagination from './Pagination';
|
||||||
|
import NoData from '@/assets/images/empty.svg';
|
||||||
|
|
||||||
const Table = <T extends RowDataType>({
|
const Table = <T extends RowDataType>({
|
||||||
columns,
|
columns,
|
||||||
@@ -13,7 +14,7 @@ const Table = <T extends RowDataType>({
|
|||||||
onRowClick,
|
onRowClick,
|
||||||
className = '',
|
className = '',
|
||||||
rowClassName = '',
|
rowClassName = '',
|
||||||
noDataMessage = 'هیچ دادهای یافت نشد',
|
noDataMessage = 'هیچ دادهای یافت نشد.',
|
||||||
headerClassName = 'bg-gray-50',
|
headerClassName = 'bg-gray-50',
|
||||||
emptyRowsCount = 5,
|
emptyRowsCount = 5,
|
||||||
showHeader = true,
|
showHeader = true,
|
||||||
@@ -117,7 +118,8 @@ const Table = <T extends RowDataType>({
|
|||||||
if (data.length === 0) {
|
if (data.length === 0) {
|
||||||
return (
|
return (
|
||||||
<div className={`bg-white ${roundedClass} text-center text-gray-500`}>
|
<div className={`bg-white ${roundedClass} text-center text-gray-500`}>
|
||||||
{noDataMessage}
|
<img src={NoData} alt='no data' className='w-[100px] mx-auto pt-[70px]' />
|
||||||
|
<div className='-mt-5 pb-[70px]'>{noDataMessage}</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -134,7 +136,7 @@ const Table = <T extends RowDataType>({
|
|||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
key={item.id}
|
key={item.id}
|
||||||
className={`w-full min-h-[48px] ${bgColor} ${hoverColor} ${onRowClick ? 'cursor-pointer' : ''} ${getRowClassName(item, rowIndex)} px-4 py-3 flex items-center gap-3 ${rowIndex !== 0 ? 'border-t border-[#EAEDF5]' : ''}`}
|
className={`w-full min-h-[85px] ${bgColor} ${hoverColor} ${onRowClick ? 'cursor-pointer' : ''} ${getRowClassName(item, rowIndex)} px-4 py-3 flex items-center gap-3 ${rowIndex !== 0 ? 'border-t border-[#EAEDF5]' : ''}`}
|
||||||
onClick={() => handleRowClick(item)}
|
onClick={() => handleRowClick(item)}
|
||||||
>
|
>
|
||||||
{selectable && (
|
{selectable && (
|
||||||
@@ -215,8 +217,9 @@ const Table = <T extends RowDataType>({
|
|||||||
if (data.length === 0) {
|
if (data.length === 0) {
|
||||||
return (
|
return (
|
||||||
<tr>
|
<tr>
|
||||||
<td colSpan={columns.length + (selectable ? 1 : 0) + (inlineActions ? 1 : 0) + (rowActions ? 1 : 0)} className="px-3 md:px-6 pb-6 md:pb-8 text-center text-gray-500">
|
<td colSpan={columns.length + (selectable ? 1 : 0) + (inlineActions ? 1 : 0) + (rowActions ? 1 : 0)} className="px-3 md:px-6 pb-6 md:pb-14 text-center text-gray-500">
|
||||||
{noDataMessage}
|
<img src={NoData} alt='no data' className='w-[100px] mx-auto' />
|
||||||
|
<div className='-mt-5'>{noDataMessage}</div>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
);
|
);
|
||||||
@@ -231,7 +234,7 @@ const Table = <T extends RowDataType>({
|
|||||||
return (
|
return (
|
||||||
<tr
|
<tr
|
||||||
key={item.id}
|
key={item.id}
|
||||||
className={`w-full h-[64px] md:h-[74px] ${bgColor} border-t border-[#EAEDF5] ${hoverColor} ${onRowClick ? 'cursor-pointer' : ''} ${getRowClassName(item, rowIndex)}`}
|
className={`w-full md:h-[64px] !h-[74px] ${bgColor} border-t border-[#EAEDF5] ${hoverColor} ${onRowClick ? 'cursor-pointer' : ''} ${getRowClassName(item, rowIndex)}`}
|
||||||
onClick={() => handleRowClick(item)}
|
onClick={() => handleRowClick(item)}
|
||||||
>
|
>
|
||||||
{selectable && (
|
{selectable && (
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ function Checkbox({
|
|||||||
<CheckboxPrimitive.Root
|
<CheckboxPrimitive.Root
|
||||||
data-slot="checkbox"
|
data-slot="checkbox"
|
||||||
className={cn(
|
className={cn(
|
||||||
"peer border-input dark:bg-input/30 data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground dark:data-[state=checked]:bg-primary data-[state=checked]:border-primary focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive size-4 shrink-0 rounded-[4px] border shadow-xs transition-shadow outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50",
|
"peer border-[#8C90A3] dark:bg-input/30 data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground dark:data-[state=checked]:bg-primary data-[state=checked]:border-primary focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive size-4 shrink-0 rounded-[4px] border shadow-xs transition-shadow outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50",
|
||||||
className
|
className
|
||||||
)}
|
)}
|
||||||
{...props}
|
{...props}
|
||||||
|
|||||||
@@ -141,7 +141,7 @@ const List: FC = () => {
|
|||||||
noDataMessage={
|
noDataMessage={
|
||||||
<div className="flex flex-col items-center">
|
<div className="flex flex-col items-center">
|
||||||
<InfoCircle size={32} className="text-gray-300 mb-2" />
|
<InfoCircle size={32} className="text-gray-300 mb-2" />
|
||||||
<div className="text-sm">هیچ پیامی یافت نشد</div>
|
<div className="text-sm">هیچ پیامی یافت نشد.</div>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
selectable={true}
|
selectable={true}
|
||||||
|
|||||||
@@ -139,7 +139,7 @@ const List: FC = () => {
|
|||||||
noDataMessage={
|
noDataMessage={
|
||||||
<div className="flex flex-col items-center">
|
<div className="flex flex-col items-center">
|
||||||
<InfoCircle size={32} className="text-gray-300 mb-2" />
|
<InfoCircle size={32} className="text-gray-300 mb-2" />
|
||||||
<div className="text-sm">هیچ پیامی یافت نشد</div>
|
<div className="text-sm">هیچ پیامی یافت نشد.</div>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
selectable={true}
|
selectable={true}
|
||||||
|
|||||||
@@ -205,7 +205,7 @@ const List: FC = () => {
|
|||||||
noDataMessage={
|
noDataMessage={
|
||||||
<div className="flex flex-col items-center ">
|
<div className="flex flex-col items-center ">
|
||||||
<InfoCircle size={32} className="text-gray-300 mb-2" />
|
<InfoCircle size={32} className="text-gray-300 mb-2" />
|
||||||
<div className="text-sm">هیچ پیشنویسی یافت نشد</div>
|
<div className="text-sm">هیچ پیشنویسی یافت نشد.</div>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
selectable={true}
|
selectable={true}
|
||||||
|
|||||||
@@ -159,7 +159,7 @@ const List: FC = () => {
|
|||||||
noDataMessage={
|
noDataMessage={
|
||||||
<div className="flex flex-col items-center">
|
<div className="flex flex-col items-center">
|
||||||
<InfoCircle size={32} className="text-gray-300 mb-2" />
|
<InfoCircle size={32} className="text-gray-300 mb-2" />
|
||||||
<div className="text-sm">هیچ پیامی یافت نشد</div>
|
<div className="text-sm">هیچ پیامی یافت نشد.</div>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
selectable={true}
|
selectable={true}
|
||||||
|
|||||||
@@ -17,8 +17,9 @@ const Header: FC<{ mailBoxName: MailboxEnum, flagged: boolean }> = ({ mailBoxNam
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='flex justify-between items-center border-b border-border pb-6'>
|
<div className='flex justify-between items-center border-b border-border pb-6'>
|
||||||
<div className='flex xl:gap-4 gap-2'>
|
<div className='flex flex-1 lg:gap-4'>
|
||||||
<ArrowRight size={18} color='#8C90A3' onClick={() => navigate(-1)} />
|
<ArrowRight size={18} color='black' onClick={() => navigate(-1)} />
|
||||||
|
<div className='flex xl:gap-4 gap-4 flex-1 lg:justify-start justify-center '>
|
||||||
<MessageUnread />
|
<MessageUnread />
|
||||||
<MessageSpam isActiveSpam={mailBoxName === MailboxEnum.Junk} />
|
<MessageSpam isActiveSpam={mailBoxName === MailboxEnum.Junk} />
|
||||||
<MessageArchive isActiveArchive={mailBoxName === MailboxEnum.ARCHIVE} />
|
<MessageArchive isActiveArchive={mailBoxName === MailboxEnum.ARCHIVE} />
|
||||||
@@ -27,10 +28,12 @@ const Header: FC<{ mailBoxName: MailboxEnum, flagged: boolean }> = ({ mailBoxNam
|
|||||||
<MessageTrash isActiveTrash={mailBoxName === MailboxEnum.TRASH} />
|
<MessageTrash isActiveTrash={mailBoxName === MailboxEnum.TRASH} />
|
||||||
{/* <More size={18} color='black' className='rotate-90' /> */}
|
{/* <More size={18} color='black' className='rotate-90' /> */}
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div className='flex gap-2'>
|
<div className='flex gap-2'>
|
||||||
<Button
|
<Button
|
||||||
variant='secondary'
|
variant='secondary'
|
||||||
|
className='lg:block hidden'
|
||||||
>
|
>
|
||||||
<div className='flex gap-2 items-center xl:px-5'>
|
<div className='flex gap-2 items-center xl:px-5'>
|
||||||
<DocumentDownload size={20} color='black' />
|
<DocumentDownload size={20} color='black' />
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ const MessageArchive: FC<{ isActiveArchive: boolean }> = ({ isActiveArchive }) =
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
setIsArchive(!isArchive)
|
setIsArchive(!isArchive)
|
||||||
}} size={18} variant={isArchive ? 'Bold' : 'Outline'} color='black' />
|
}} className='lg:size-[18px] size-[20px]' variant={isArchive ? 'Bold' : 'Outline'} color='black' />
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ const MessageFavorite: FC<{ flagged: boolean }> = ({ flagged }) => {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
setIsFavorite(!isFavorite)
|
setIsFavorite(!isFavorite)
|
||||||
}} size={18} variant={isFavorite ? 'Bold' : 'Outline'} color={isFavorite ? '#FFC107' : 'black'} />
|
}} className='lg:size-[18px] size-[20px]' variant={isFavorite ? 'Bold' : 'Outline'} color={isFavorite ? '#FFC107' : 'black'} />
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ const MessageSpam: FC<{ isActiveSpam: boolean }> = ({ isActiveSpam }) => {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
setIsSpam(!isSpam)
|
setIsSpam(!isSpam)
|
||||||
}} size={18} variant={isSpam ? 'Bold' : 'Outline'} color='black' />
|
}} className='lg:size-[18px] size-[20px]' variant={isSpam ? 'Bold' : 'Outline'} color='black' />
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ const MessageTrash: FC<{ isActiveTrash: boolean }> = ({ isActiveTrash }) => {
|
|||||||
const { mutate: restoreMessage } = useRestoreMessage()
|
const { mutate: restoreMessage } = useRestoreMessage()
|
||||||
const navigate = useNavigate()
|
const navigate = useNavigate()
|
||||||
return (
|
return (
|
||||||
<Trash variant={isTrash ? 'Bold' : 'Outline'} size={18} color='#CD0000' onClick={() => {
|
<Trash variant={isTrash ? 'Bold' : 'Outline'} className='lg:size-[18px] size-[20px]' color='#CD0000' onClick={() => {
|
||||||
setIsTrash(!isTrash)
|
setIsTrash(!isTrash)
|
||||||
if (isTrash) {
|
if (isTrash) {
|
||||||
restoreMessage({ messageId: id || '', mailbox: mailbox || '' }, {
|
restoreMessage({ messageId: id || '', mailbox: mailbox || '' }, {
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ const MessageUnread: FC = () => {
|
|||||||
markAsRead({ messageId: id || '', mailbox: mailbox || '' })
|
markAsRead({ messageId: id || '', mailbox: mailbox || '' })
|
||||||
}
|
}
|
||||||
setIsRead(!isRead)
|
setIsRead(!isRead)
|
||||||
}} size={18} variant={isRead ? 'Outline' : 'Bold'} color='black' />
|
}} className='lg:size-[18px] size-[22px]' variant={isRead ? 'Outline' : 'Bold'} color='black' />
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,77 @@
|
|||||||
|
import DefaulModal from '@/components/DefaulModal'
|
||||||
|
import { InboxMessage } from '../types/Types'
|
||||||
|
import Button from '@/components/Button'
|
||||||
|
import { FC } from 'react'
|
||||||
|
import Skeleton from 'react-loading-skeleton'
|
||||||
|
import { useNavigate } from 'react-router-dom'
|
||||||
|
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
|
const SummarizeModal: FC<{ open: boolean, onClose: () => void, isPending: boolean, item: InboxMessage, id: string, mailbox: string, data: any }> = ({ open, onClose, isPending, item, id, mailbox, data }) => {
|
||||||
|
const navigate = useNavigate()
|
||||||
|
return (
|
||||||
|
<DefaulModal
|
||||||
|
open={open}
|
||||||
|
close={onClose}
|
||||||
|
isHeader
|
||||||
|
title_header='پیش نمایش ایمیل'
|
||||||
|
>
|
||||||
|
<div className='mt-5'>
|
||||||
|
{isPending ? (
|
||||||
|
<div>
|
||||||
|
<div className='text-xs'>
|
||||||
|
موضوع:
|
||||||
|
</div>
|
||||||
|
<div className='mt-1.5'>
|
||||||
|
<Skeleton height={16} />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className='mt-7'>
|
||||||
|
<div className='text-xs'>
|
||||||
|
خلاصه متن:
|
||||||
|
</div>
|
||||||
|
<div className='mt-3'>
|
||||||
|
<Skeleton height={16} count={4} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<div>
|
||||||
|
<div className='text-xs'>
|
||||||
|
موضوع:
|
||||||
|
</div>
|
||||||
|
<div className='mt-1.5 text-xs'>
|
||||||
|
{item.subject}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className='mt-7'>
|
||||||
|
<div className='text-xs'>
|
||||||
|
خلاصه متن:
|
||||||
|
</div>
|
||||||
|
<div className='mt-3 leading-5 text-xs text-description'>
|
||||||
|
{data?.data?.summary}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
<div className='mt-14 flex justify-end'>
|
||||||
|
<div className='flex gap-3'>
|
||||||
|
<Button
|
||||||
|
label='بستن'
|
||||||
|
variant='secondary'
|
||||||
|
className='w-fit !px-10'
|
||||||
|
onClick={onClose}
|
||||||
|
/>
|
||||||
|
<Button
|
||||||
|
label='مشاهده'
|
||||||
|
className='w-fit !px-10'
|
||||||
|
onClick={() => navigate(`/mail/${id}/${mailbox}`)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</DefaulModal>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default SummarizeModal
|
||||||
@@ -1,11 +1,8 @@
|
|||||||
import { FC, useState } from 'react'
|
import { FC, useState } from 'react'
|
||||||
import { useSummarizeEmail } from '../hooks/useEmailData';
|
import { useSummarizeEmail } from '../hooks/useEmailData';
|
||||||
import DefaulModal from '@/components/DefaulModal';
|
|
||||||
import Button from '@/components/Button';
|
|
||||||
import { InboxMessage } from '@/pages/draft/types/DraftTypes';
|
import { InboxMessage } from '@/pages/draft/types/DraftTypes';
|
||||||
import Intelligense from '@/assets/images/intelligense.svg'
|
import Intelligense from '@/assets/images/intelligense.svg'
|
||||||
import Skeleton from 'react-loading-skeleton'
|
import SummarizeModal from './SummarizeModal';
|
||||||
import { useNavigate } from 'react-router-dom'
|
|
||||||
|
|
||||||
const Summerize: FC<{ id: string, mailbox: string, item: InboxMessage }> = ({ id, mailbox, item }) => {
|
const Summerize: FC<{ id: string, mailbox: string, item: InboxMessage }> = ({ id, mailbox, item }) => {
|
||||||
|
|
||||||
@@ -13,7 +10,6 @@ const Summerize: FC<{ id: string, mailbox: string, item: InboxMessage }> = ({ id
|
|||||||
const { mutate: summarizeEmail, isPending } = useSummarizeEmail();
|
const { mutate: summarizeEmail, isPending } = useSummarizeEmail();
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
const [data, setData] = useState<any>()
|
const [data, setData] = useState<any>()
|
||||||
const navigate = useNavigate()
|
|
||||||
|
|
||||||
const handleSummarizeEmail = () => {
|
const handleSummarizeEmail = () => {
|
||||||
setOpen(true)
|
setOpen(true)
|
||||||
@@ -28,72 +24,11 @@ const Summerize: FC<{ id: string, mailbox: string, item: InboxMessage }> = ({ id
|
|||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<div onClick={handleSummarizeEmail}>
|
<div onClick={handleSummarizeEmail}>
|
||||||
<img src={Intelligense} alt='summerize' className='w-[18px] z-1 absolute -mt-2 ' />
|
<img src={Intelligense} alt='summerize' className='min-w-[18px] z-1 ' />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<DefaulModal
|
<SummarizeModal open={open} onClose={() => setOpen(false)} isPending={isPending} item={item} id={id} mailbox={mailbox} data={data} />
|
||||||
open={open}
|
|
||||||
close={() => setOpen(false)}
|
|
||||||
isHeader
|
|
||||||
title_header='پیش نمایش ایمیل'
|
|
||||||
>
|
|
||||||
<div className='mt-5'>
|
|
||||||
{isPending ? (
|
|
||||||
<div>
|
|
||||||
<div className='text-xs'>
|
|
||||||
موضوع:
|
|
||||||
</div>
|
|
||||||
<div className='mt-1.5'>
|
|
||||||
<Skeleton height={16} />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className='mt-7'>
|
|
||||||
<div className='text-xs'>
|
|
||||||
خلاصه متن:
|
|
||||||
</div>
|
|
||||||
<div className='mt-3'>
|
|
||||||
<Skeleton height={16} count={4} />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
) : (
|
|
||||||
<div>
|
|
||||||
<div className='text-xs'>
|
|
||||||
موضوع:
|
|
||||||
</div>
|
|
||||||
<div className='mt-1.5 text-xs'>
|
|
||||||
{item.subject}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className='mt-7'>
|
|
||||||
<div className='text-xs'>
|
|
||||||
خلاصه متن:
|
|
||||||
</div>
|
|
||||||
<div className='mt-3 leading-5 text-xs text-description'>
|
|
||||||
{data?.data?.summary}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
|
|
||||||
<div className='mt-14 flex justify-end'>
|
|
||||||
<div className='flex gap-3'>
|
|
||||||
<Button
|
|
||||||
label='بستن'
|
|
||||||
variant='secondary'
|
|
||||||
className='w-fit !px-10'
|
|
||||||
onClick={() => setOpen(false)}
|
|
||||||
/>
|
|
||||||
<Button
|
|
||||||
label='مشاهده'
|
|
||||||
className='w-fit !px-10'
|
|
||||||
onClick={() => navigate(`/mail/${id}/${mailbox}`)}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</DefaulModal>
|
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,29 +6,35 @@ import { ColumnType } from '../../components/types/TableTypes';
|
|||||||
import { InfoCircle, More, Refresh2, Trash, Edit, Archive, ArchiveTick, Star1 } from 'iconsax-react';
|
import { InfoCircle, More, Refresh2, Trash, Edit, Archive, ArchiveTick, Star1 } from 'iconsax-react';
|
||||||
import { RowActionItem } from '../../components/RowActionsDropdown';
|
import { RowActionItem } from '../../components/RowActionsDropdown';
|
||||||
import { useNavigate } from 'react-router-dom';
|
import { useNavigate } from 'react-router-dom';
|
||||||
import { useGetInbox } from './hooks/useEmailData';
|
import { useGetInbox, useSummarizeEmail } from './hooks/useEmailData';
|
||||||
import { InboxMessage } from './types/Types';
|
import { InboxMessage } from './types/Types';
|
||||||
import { formatDate } from '@/config/func';
|
import { formatDate } from '@/config/func';
|
||||||
import MarkAsRead from '@/assets/images/mark_as_read.svg'
|
import MarkAsRead from '@/assets/images/mark_as_read.svg'
|
||||||
import { useEmailActions } from '@/hooks/useEmailActions';
|
import { useEmailActions } from '@/hooks/useEmailActions';
|
||||||
import Favorite from './Components/Favorite';
|
import Favorite from './Components/Favorite';
|
||||||
import Summerize from './Components/Summerize';
|
import Summerize from './Components/Summerize';
|
||||||
|
import Intelligense from '@/assets/images/intelligense.svg'
|
||||||
|
import SummarizeModal from './Components/SummarizeModal';
|
||||||
|
|
||||||
const List: FC = () => {
|
const List: FC = () => {
|
||||||
|
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const [currentPage, setCurrentPage] = useState(1);
|
const [currentPage, setCurrentPage] = useState(1);
|
||||||
const [filters, setFilters] = useState<FilterValues>({});
|
const [filters, setFilters] = useState<FilterValues>({});
|
||||||
const emailActions = useEmailActions();
|
const emailActions = useEmailActions();
|
||||||
|
const [openSummarizeModal, setOpenSummarizeModal] = useState(false);
|
||||||
|
const { mutate: summarizeEmail, isPending: isSummarizing, data: summarizeData } = useSummarizeEmail();
|
||||||
|
|
||||||
const { data: inboxData, isLoading, refetch, isFetching } = useGetInbox({
|
const { data: inboxData, isLoading, refetch, isFetching } = useGetInbox({
|
||||||
page: currentPage,
|
page: currentPage,
|
||||||
limit: 25,
|
limit: 10,
|
||||||
...filters
|
...filters
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
const [selectedMessages, setSelectedMessages] = useState<InboxMessage[]>([]);
|
const [selectedMessages, setSelectedMessages] = useState<InboxMessage[]>([]);
|
||||||
|
const [selectedMessage, setSelectedMessage] = useState<InboxMessage | null>(null);
|
||||||
|
|
||||||
const columns: ColumnType<InboxMessage>[] = [
|
const columns: ColumnType<InboxMessage>[] = [
|
||||||
{
|
{
|
||||||
@@ -152,6 +158,15 @@ const List: FC = () => {
|
|||||||
];
|
];
|
||||||
|
|
||||||
const getRowActions = (message: InboxMessage): RowActionItem[] => [
|
const getRowActions = (message: InboxMessage): RowActionItem[] => [
|
||||||
|
{
|
||||||
|
label: 'مشاهده خلاصه',
|
||||||
|
icon: <img src={Intelligense} alt='summerize' className='w-[18px] ' />,
|
||||||
|
onClick: () => {
|
||||||
|
setSelectedMessage(message)
|
||||||
|
setOpenSummarizeModal(true)
|
||||||
|
summarizeEmail({ messageId: message.id, mailbox: message.mailbox })
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
label: message.seen ? 'علامتگذاری به عنوان خوانده نشده' : 'علامتگذاری به عنوان خوانده شده',
|
label: message.seen ? 'علامتگذاری به عنوان خوانده نشده' : 'علامتگذاری به عنوان خوانده شده',
|
||||||
icon: <Edit size={16} color="black" />,
|
icon: <Edit size={16} color="black" />,
|
||||||
@@ -231,6 +246,18 @@ const List: FC = () => {
|
|||||||
} : undefined}
|
} : undefined}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
{selectedMessage && (
|
||||||
|
<SummarizeModal
|
||||||
|
open={openSummarizeModal}
|
||||||
|
onClose={() => setOpenSummarizeModal(false)}
|
||||||
|
isPending={isSummarizing}
|
||||||
|
item={selectedMessage}
|
||||||
|
id={selectedMessage.id.toString()}
|
||||||
|
mailbox={selectedMessage.mailbox}
|
||||||
|
data={summarizeData}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -173,7 +173,7 @@ const List: FC = () => {
|
|||||||
<div className="flex flex-col items-center">
|
<div className="flex flex-col items-center">
|
||||||
<InfoCircle size={32} className="text-gray-300 mb-2" />
|
<InfoCircle size={32} className="text-gray-300 mb-2" />
|
||||||
<div className="text-sm">
|
<div className="text-sm">
|
||||||
{filters.q ? 'هیچ نتیجهای یافت نشد' : 'برای جستجو کلمه مورد نظر را وارد کنید'}
|
{filters.q ? 'هیچ نتیجهای یافت نشد.' : 'برای جستجو کلمه مورد نظر را وارد کنید.'}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -172,7 +172,7 @@ const List: FC = () => {
|
|||||||
noDataMessage={
|
noDataMessage={
|
||||||
<div className="flex flex-col items-center">
|
<div className="flex flex-col items-center">
|
||||||
<InfoCircle size={32} className="text-gray-300 mb-2" />
|
<InfoCircle size={32} className="text-gray-300 mb-2" />
|
||||||
<div className="text-sm">هیچ پیامی یافت نشد</div>
|
<div className="text-sm">هیچ پیامی یافت نشد.</div>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
selectable={true}
|
selectable={true}
|
||||||
|
|||||||
@@ -138,7 +138,7 @@ const List: FC = () => {
|
|||||||
noDataMessage={
|
noDataMessage={
|
||||||
<div className="flex flex-col items-center">
|
<div className="flex flex-col items-center">
|
||||||
<InfoCircle size={32} className="text-gray-300 mb-2" />
|
<InfoCircle size={32} className="text-gray-300 mb-2" />
|
||||||
<div className="text-sm">هیچ پیامی یافت نشد</div>
|
<div className="text-sm">هیچ پیامی یافت نشد.</div>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
selectable={true}
|
selectable={true}
|
||||||
|
|||||||
Reference in New Issue
Block a user