import React, { useState, memo } from 'react'; import DefaultTableSkeleton from '../components/DefaultTableSkeleton'; import Td from '../components/Td'; import type { TableProps, RowDataType, ColumnType } from '@/components/types/TableTypes'; import { Checkbox } from '../components/ui/checkbox'; import RowActionsDropdown from '../components/RowActionsDropdown'; import Pagination from '../components/Pagination'; const Table = ({ columns, data, isloading = false, onRowClick, className = '', rowClassName = '', noDataMessage = 'هیچ داده‌ای یافت نشد', headerClassName = 'bg-gray-50', emptyRowsCount = 5, showHeader = true, actions = null, actionsPosition = 'top', selectable = false, selectedActions = null, onSelectionChange, rowActions, pagination, }: TableProps): React.ReactElement => { const [selectedRows, setSelectedRows] = useState([]); const getRowClassName = (item: T, index: number): string => { if (typeof rowClassName === 'function') { return rowClassName(item, index); } return rowClassName; }; const getCellClassName = (column: ColumnType): string => { const alignClass = column.align ? `text-${column.align}` : ''; return `px-3 md:px-6 py-3 md:py-4 whitespace-nowrap text-xs ${alignClass} ${column.className || ''}`.trim(); }; const handleRowClick = (item: T) => { if (onRowClick) { onRowClick(item.id, item); } }; const handleSelectAll = () => { const dataArray = data || []; const newSelectedRows = selectedRows.length === dataArray.length ? [] : [...dataArray]; setSelectedRows(newSelectedRows); if (onSelectionChange) { onSelectionChange(newSelectedRows); } }; const handleSingleRowSelect = (item: T, checked: boolean) => { const newSelectedRows = checked ? [...selectedRows, item] : selectedRows.filter((row) => row.id !== item.id); setSelectedRows(newSelectedRows); if (onSelectionChange) { onSelectionChange(newSelectedRows); } }; const isRowSelected = (item: T): boolean => { return selectedRows.some((row) => row.id === item.id); }; // Gmail-style layout برای وقتی header نمایش داده نمی‌شود const renderGmailStyleRows = () => { const hasActions = (actionsPosition === 'top' || actionsPosition === 'above-header') && (actions || (selectable && selectedRows.length > 0 && selectedActions)); const roundedClass = hasActions ? 'rounded-b-2xl' : 'rounded-2xl'; if (isloading) { return (
{Array.from({ length: emptyRowsCount }).map((_, index) => (
))}
); } if (!data || data.length === 0) { return (
{noDataMessage}
); } return (
{data.map((item, rowIndex) => (
handleRowClick(item)} > {selectable && (
e.stopPropagation()} > handleSingleRowSelect(item, !!checked)} />
)}
{/* محتوای اصلی - ستون اول */}
{columns[0]?.render ? columns[0].render(item, rowIndex) : (item[columns[0]?.key] as React.ReactNode)}
{/* اطلاعات اضافی - سه ستون آخر در یک خط */} {columns.length > 1 && (
{columns.slice(1).map((col) => (
{col.render ? col.render(item, rowIndex) : (item[col.key] as React.ReactNode)}
))}
)}
{rowActions && (
e.stopPropagation()} >
)}
))}
); }; const renderTableBody = () => { if (isloading) { return ( ); } if (!data || data.length === 0) { return ( {noDataMessage} ); } return (data || []).map((item, rowIndex) => ( handleRowClick(item)} > {selectable && ( e.stopPropagation()} > handleSingleRowSelect(item, !!checked)} /> )} {columns.map((col) => ( {col.render ? col.render(item, rowIndex) : item[col.key] as React.ReactNode} ))} {rowActions && ( e.stopPropagation()} > )} )); }; const renderHeader = () => { if (!showHeader || actionsPosition === 'header-replace') return null; return ( {selectable && ( e.stopPropagation()} > 0 && selectedRows.length === (data?.length || 0)} onCheckedChange={handleSelectAll} /> )} {columns.map((col) => ( ))} {rowActions && ( )} ); }; const renderActions = () => { if (!actions && (!selectable || selectedRows.length === 0 || !selectedActions)) return null; return (
{actions} {selectable && selectedRows.length > 0 && selectedActions && selectedActions}
); }; // اگر header نشان داده نمی‌شود، از Gmail-style layout فقط در موبایل استفاده کن if (!showHeader) { return (
{/* نسخه موبایل - Gmail style */}
{(actionsPosition === 'top' || actionsPosition === 'above-header') && (
{actions} {selectable && selectedRows.length > 0 && selectedActions && selectedActions}
)} {renderGmailStyleRows()}
{/* نسخه دسکتاپ - Table معمولی */}
{(actionsPosition === 'top' || actionsPosition === 'above-header') && (
{actions} {selectable && selectedRows.length > 0 && selectedActions && selectedActions}
)}
0 && selectedActions)) ? 'rounded-b-3xl' : 'rounded-3xl'} bg-white`}> {renderTableBody()}
{pagination && ( )}
); } return (
{(actionsPosition === 'top' || actionsPosition === 'above-header') && renderActions()}
{renderHeader()} {actionsPosition === 'header-replace' && ( )} {renderTableBody()}
{renderActions()}
{pagination && ( )}
); }; export default memo(Table) as (props: TableProps) => React.ReactElement;