'use client'; import { useState, useTransition } from 'react'; import { useRouter, useSearchParams } from 'next/navigation'; import { Pencil, ArrowUp, ArrowDown, ArrowUpDown } from 'lucide-react'; import Link from 'next/link'; import { DeleteButton } from '@/components/DeleteButton'; import { ColumnFilter } from './ColumnFilter'; import { FieldDefinition } from '@/lib/schema'; import { updateUserPreferencesAction } from '@/app/actions/user'; interface DataTableProps { entity: string; collectionId: string; documents: any[]; fieldsConfig: FieldDefinition[]; initialHiddenColumns: string[]; currentSortField: string; currentSortDir: 'asc' | 'desc'; user: any; } export const DataTable = ({ entity, collectionId, documents, fieldsConfig, initialHiddenColumns, currentSortField, currentSortDir, user }: DataTableProps) => { const router = useRouter(); const searchParams = useSearchParams(); const [isPending, startTransition] = useTransition(); const [visibleColumns, setVisibleColumns] = useState(() => { const allFields = fieldsConfig.map(f => f.name); return allFields.filter(f => !initialHiddenColumns.includes(f)); }); const handleColumnChange = async (newVisible: string[]) => { setVisibleColumns(newVisible); // Calculate hidden columns to persist const allFields = fieldsConfig.map(f => f.name); const hidden = allFields.filter(f => !newVisible.includes(f)); // Persist to Appwrite Prefs await updateUserPreferencesAction({ hiddenColumns: { [entity]: hidden } }); }; const toggleSort = (field: string) => { const params = new URLSearchParams(searchParams.toString()); let newDir: 'asc' | 'desc' = 'desc'; if (currentSortField === field) { newDir = currentSortDir === 'desc' ? 'asc' : 'desc'; } params.set('sort', field); params.set('dir', newDir); startTransition(() => { router.push(`?${params.toString()}`); }); }; const getHeaderLabel = (key: string) => { const field = fieldsConfig.find(f => f.name === key); return field ? field.label : key.replace(/_/g, ' '); }; const renderSortIcon = (field: string) => { if (currentSortField !== field) return ; return currentSortDir === 'asc' ? : ; }; return (
{isPending && (
)}
{fieldsConfig.map(field => { if (!visibleColumns.includes(field.name)) return null; return ( ); })} {documents.map((doc) => { const canEdit = user?.$id === 'admin-emergency' || user?.labels?.includes('admin') || user?.labels?.includes('editor'); return ( { if (canEdit) { router.push(`/dashboard/${entity}/${doc.$id}`); } }} > {fieldsConfig.map(field => { if (!visibleColumns.includes(field.name)) return null; let value = doc[field.name]; // Resolve Relations if (typeof value === 'object' && value !== null) { if (field.type === 'relation' && field.relationLabel) { value = value[field.relationLabel] || value.$id || '[Vinculado]'; } else { value = Array.isArray(value) ? `[Lista (${value.length})]` : value.$id || '[Vinculado]'; } } if (typeof value === 'boolean') { value = value ? 'Sí' : 'No'; } if (typeof value === 'string' && value.length > 60) { value = value.substring(0, 60) + '...'; } return ( ) })} )})}
toggleSort(field.name)} >
{field.label} {renderSortIcon(field.name)}
Acciones
{String(value || '')}
); };