'use client'; import { useState, useMemo } from 'react'; import { useReactTable, getCoreRowModel, getSortedRowModel, getPaginationRowModel, getFilteredRowModel, ColumnDef, SortingState, ColumnFiltersState, } from '@tanstack/react-table'; import { IconImageFile, IconVideoFile, IconAudioFile, IconEye, IconDownload, IconShield, DoubleArrowRight, ArrowRight, DoubleArrowLeft, ArrowLeft, ArrowUp, ArrowDown, Filter } from '@/app/ui/icons/icons'; import { useTranslations } from 'next-intl'; import DropDownList from '@/app/components/dropDownList'; // Типы данных type FileType = 'image' | 'video' | 'audio'; type FileItem = { id: number; fileName: string; fileType: FileType; violations: number; checks: number; lastCheck: number; // timestamp в миллисекундах }; // Иконки для типов файлов const FileTypeIcon = ({ type }: { type: FileType }) => { switch (type) { case 'image': return ; case 'video': return ; case 'audio': return ; default: return 📄; } }; // Форматирование даты из timestamp const formatDate = (timestamp: number) => { const date = new Date(timestamp); const day = date.getDate().toString().padStart(2, '0'); const month = (date.getMonth() + 1).toString().padStart(2, '0'); const year = date.getFullYear(); return `${day}.${month}.${year}`; }; // Компонент таблицы export default function TanstakFilesTable() { // Данные с timestamp вместо Date объектов const [data] = useState([ { id: 1, fileName: 'image1.jpg', fileType: 'image', violations: 5, checks: 12, lastCheck: 1705267200000 }, // 15.01.2024 { id: 2, fileName: 'presentation.mp4', fileType: 'video', violations: 2, checks: 8, lastCheck: 1705180800000 }, // 14.01.2024 { id: 3, fileName: 'song.mp3', fileType: 'audio', violations: 0, checks: 5, lastCheck: 1705094400000 }, // 13.01.2024 { id: 4, fileName: 'photo1.jpg', fileType: 'image', violations: 3, checks: 10, lastCheck: 1705008000000 }, // 12.01.2024 { id: 5, fileName: 'movie.mp4', fileType: 'video', violations: 1, checks: 7, lastCheck: 1704921600000 }, // 11.01.2024 { id: 6, fileName: 'podcast.mp3', fileType: 'audio', violations: 4, checks: 9, lastCheck: 1704835200000 }, // 10.01.2024 { id: 7, fileName: 'screenshot.png', fileType: 'image', violations: 0, checks: 3, lastCheck: 1704748800000 }, // 09.01.2024 { id: 8, fileName: 'tutorial.mp4', fileType: 'video', violations: 2, checks: 6, lastCheck: 1704662400000 }, // 08.01.2024 { id: 9, fileName: 'music.mp3', fileType: 'audio', violations: 1, checks: 4, lastCheck: 1704576000000 }, // 07.01.2024 { id: 10, fileName: 'image2.jpg', fileType: 'image', violations: 5, checks: 11, lastCheck: 1704489600000 }, // 06.01.2024 { id: 11, fileName: 'film.mov', fileType: 'video', violations: 0, checks: 2, lastCheck: 1704403200000 }, // 05.01.2024 { id: 12, fileName: 'sound.wav', fileType: 'audio', violations: 3, checks: 8, lastCheck: 1704316800000 }, // 04.01.2024 { id: 13, fileName: 'picture.png', fileType: 'image', violations: 2, checks: 7, lastCheck: 1704230400000 }, // 03.01.2024 { id: 14, fileName: 'video2.mp4', fileType: 'video', violations: 1, checks: 5, lastCheck: 1704144000000 }, // 02.01.2024 { id: 15, fileName: 'audio2.mp3', fileType: 'audio', violations: 0, checks: 3, lastCheck: 1704057600000 }, // 01.01.2024 ]); // Состояния const [sorting, setSorting] = useState([]); const [columnFilters, setColumnFilters] = useState([]); const [dateFilter, setDateFilter] = useState('all'); const [typeFilter, setTypeFilter] = useState('all'); const t = useTranslations("Global"); // Определение колонок const columns = useMemo[]>( () => [ { accessorKey: 'fileName', header: ({ column }) => (
{t('file')}
), cell: ({ row }) => (
{row.original.fileName}
), enableColumnFilter: false, }, { accessorKey: 'violations', header: ({ column }) => (
{t('violations')}
), cell: ({ row }) => (
0 ? 'text-red-600' : 'text-green-600'}`}> {row.original.violations}
), }, { accessorKey: 'checks', header: ({ column }) => (
{t('checks')}
), cell: ({ row }) => (
{row.original.checks}
), }, { accessorKey: 'lastCheck', header: ({ column }) => (
{t('last-check')}
), cell: ({ row }) => (
{formatDate(row.original.lastCheck)}
), enableColumnFilter: false, }, { id: 'actions', header: () => { return (
{t('actions')}
) }, cell: ({ row }) => (
), enableSorting: false, enableColumnFilter: false, }, ], [] ); // Обработчики действий const handleView = (file: FileItem) => { console.log(`Просмотр файла: ${file.fileName}`); }; const handleDownload = (file: FileItem) => { console.log(`Скачать: ${file.fileName}`); }; const handleProtect = (file: FileItem) => { console.log(`Щиток: ${file.fileName}`); }; // Фильтрация по типу файла и дате const filteredData = useMemo(() => { let result = data; // Фильтр по типу файла if (typeFilter !== 'all') { result = result.filter(item => item.fileType === typeFilter); } // Фильтр по дате if (dateFilter !== 'all') { const now = Date.now(); const oneDay = 24 * 60 * 60 * 1000; const sevenDays = 7 * oneDay; const thirtyDays = 30 * oneDay; switch (dateFilter) { case 'today': const todayStart = new Date().setHours(0, 0, 0, 0); result = result.filter(item => item.lastCheck >= todayStart); break; case 'week': const weekAgo = now - sevenDays; result = result.filter(item => item.lastCheck >= weekAgo); break; case 'month': const monthAgo = now - thirtyDays; result = result.filter(item => item.lastCheck >= monthAgo); break; case 'older': const monthAgo2 = now - thirtyDays; result = result.filter(item => item.lastCheck < monthAgo2); break; } } return result; }, [data, typeFilter, dateFilter]); // Создание таблицы const table = useReactTable({ data: filteredData, columns, state: { sorting, columnFilters, }, onSortingChange: setSorting, onColumnFiltersChange: setColumnFilters, getCoreRowModel: getCoreRowModel(), getSortedRowModel: getSortedRowModel(), getPaginationRowModel: getPaginationRowModel(), getFilteredRowModel: getFilteredRowModel(), initialState: { pagination: { pageSize: 10, }, }, }); return (
{/* Фильтры */}
{t('date-filter')}:
  • {t('all-dates')}
  • {t('today')}
  • {t('for-a-week')}
  • {t('for-a-month')}
  • {t('older-than-a-month')}
  • {t('type-filter')}:
  • {t('all-types')}
  • {t('images')}
  • {t('videos')}
  • {t('audios')}
  • {t('items-per-page')}:
    {[5, 10, 20, 50, 100].map(pageSize => (
  • {t('show')} {pageSize}
  • ))}
    {/* Таблица */}
    {table.getHeaderGroups().map(headerGroup => ( {headerGroup.headers.map(header => ( ))} ))} {table.getRowModel().rows.length > 0 ? ( table.getRowModel().rows.map(row => ( {row.getVisibleCells().map(cell => ( ))} )) ) : ( )}
    {header.isPlaceholder ? null : typeof header.column.columnDef.header === 'function' ? header.column.columnDef.header(header.getContext()) : header.column.columnDef.header as string}
    {typeof cell.column.columnDef.cell === 'function' ? cell.column.columnDef.cell(cell.getContext()) : cell.getValue() as string}
    {t('no-data-for-selected-filters')}
    {/* Пагинация */}
    {t('page')}{' '} {table.getState().pagination.pageIndex + 1} {t('out-of')} {table.getPageCount()} | {t('shown')} {table.getRowModel().rows.length} {t('out-of')} {filteredData.length} {t('files')}
    {Array.from({ length: Math.min(5, table.getPageCount()) }, (_, i) => { const pageIndex = Math.max( 0, Math.min( table.getPageCount() - 5, table.getState().pagination.pageIndex - 2 ) ) + i; if (pageIndex < table.getPageCount()) { return ( ); } return null; })}
    ); }