import { useState, useEffect, useCallback } from "react"; interface UseTableColumnsOptions { allColumns: string[]; storageKey: string; defaultVisibleColumns?: string[]; } export function useTableColumns({ allColumns, storageKey, defaultVisibleColumns }: UseTableColumnsOptions) { // Carregar as colunas visíveis do localStorage na inicialização const initVisibleColumns = () => { try { const saved = localStorage.getItem(`visible${storageKey}Columns`); if (saved) { const parsed = JSON.parse(saved); if (Array.isArray(parsed) && parsed.length > 0) { return parsed; } } } catch (error) { console.error('Erro ao carregar configurações de colunas:', error); } return defaultVisibleColumns || allColumns; }; // Inicializar a ordem das colunas const initColumnOrder = () => { try { const saved = localStorage.getItem(`${storageKey}ColumnsOrder`); if (saved) { const parsed = JSON.parse(saved); if (Array.isArray(parsed) && parsed.length > 0) { return parsed; } } } catch (error) { console.error('Erro ao carregar ordem das colunas:', error); } return allColumns; }; // Estado para controlar quais colunas estão visíveis const [visibleColumns, setVisibleColumns] = useState(initVisibleColumns); // Estado para controlar a ordem das colunas const [columnOrder, setColumnOrder] = useState(initColumnOrder); // Estado para rastrear coluna sendo arrastada const [draggedColumn, setDraggedColumn] = useState(null); // Estado para notificar sobre novas colunas const [newColumnsDetected, setNewColumnsDetected] = useState([]); useEffect(() => { try { const savedAllColumns = localStorage.getItem(`all${storageKey}Columns`); if (savedAllColumns) { const parsedAllColumns = JSON.parse(savedAllColumns); if (JSON.stringify(parsedAllColumns) !== JSON.stringify(allColumns)) { // Detectar novas colunas const newColumns = allColumns.filter(col => !parsedAllColumns.includes(col)); if (newColumns.length > 0) { // Adicionar novas colunas às colunas visíveis setVisibleColumns(prev => { const updated = [...prev, ...newColumns]; // Remover duplicatas return [...new Set(updated)]; }); // Atualizar a ordem das colunas incluindo as novas setColumnOrder(prev => { const updated = [...prev, ...newColumns]; // Remover duplicatas return [...new Set(updated)]; }); // Notificar sobre as novas colunas setNewColumnsDetected(newColumns); // Limpar a notificação após 5 segundos setTimeout(() => { setNewColumnsDetected([]); }, 5000); } // Salvar as novas colunas no localStorage localStorage.setItem(`all${storageKey}Columns`, JSON.stringify(allColumns)); } } else { localStorage.setItem(`all${storageKey}Columns`, JSON.stringify(allColumns)); } } catch (error) { console.error('Erro ao verificar as colunas no localStorage:', error); } }, [allColumns, storageKey]); // Salvar as colunas visíveis no localStorage sempre que elas mudarem useEffect(() => { try { localStorage.setItem(`visible${storageKey}Columns`, JSON.stringify(visibleColumns)); } catch (error) { console.error('Erro ao salvar configurações de colunas:', error); } }, [visibleColumns, storageKey]); // Salvar a ordem das colunas no localStorage useEffect(() => { try { localStorage.setItem(`${storageKey}ColumnsOrder`, JSON.stringify(columnOrder)); } catch (error) { console.error('Erro ao salvar ordem das colunas:', error); } }, [columnOrder, storageKey]); // Funções para drag & drop const handleDragStart = useCallback((e: React.DragEvent, column: string) => { setDraggedColumn(column); e.dataTransfer.effectAllowed = 'move'; e.dataTransfer.setData('text/plain', column); const target = e.currentTarget as HTMLDivElement; target.classList.add('opacity-50'); }, []); const handleDragEnd = useCallback((e: React.DragEvent) => { setDraggedColumn(null); e.currentTarget.classList.remove('opacity-50'); }, []); const handleDragOver = useCallback((e: React.DragEvent) => { e.preventDefault(); e.dataTransfer.dropEffect = 'move'; }, []); const handleDrop = useCallback((e: React.DragEvent, targetColumn: string) => { e.preventDefault(); if (!draggedColumn || draggedColumn === targetColumn) return; // Reordenar as colunas const newColumnOrder = [...columnOrder]; const draggedIndex = newColumnOrder.indexOf(draggedColumn); const targetIndex = newColumnOrder.indexOf(targetColumn); if (draggedIndex !== -1 && targetIndex !== -1) { newColumnOrder.splice(draggedIndex, 1); newColumnOrder.splice(targetIndex, 0, draggedColumn); setColumnOrder(newColumnOrder); } }, [draggedColumn, columnOrder]); // Função para alternar a visibilidade de uma coluna const toggleColumn = useCallback((column: string) => { setVisibleColumns((current) => { if (current.includes(column)) { return current.filter((c) => c !== column); } else { return [...current, column]; } }); }, []); // Função para selecionar todas as colunas const selectAllColumns = useCallback(() => { setVisibleColumns(allColumns); }, [allColumns]); // Função para desmarcar todas as colunas const unselectAllColumns = useCallback(() => { // Mantém pelo menos uma coluna para garantir que a tabela não fique vazia const firstColumn = allColumns[0] || "Código"; setVisibleColumns([firstColumn]); }, [allColumns]); // Função para verificar se uma coluna está visível const isColumnVisible = useCallback((column: string) => { return visibleColumns.includes(column); }, [visibleColumns]); // Função para ordenar as colunas visíveis na ordem definida pelo usuário const getOrderedVisibleColumns = useCallback(() => { // Primeiro, filtrar as colunas que são visíveis const visibleColumnSet = new Set(visibleColumns); // Depois, ordenar as colunas de acordo com a ordem definida pelo usuário return columnOrder.filter(column => visibleColumnSet.has(column)); }, [visibleColumns, columnOrder]); // Resetar a ordem das colunas const resetColumnOrder = useCallback(() => { setColumnOrder(allColumns); }, [allColumns]); // Função para limpar a notificação de novas colunas const dismissNewColumnsNotification = useCallback(() => { setNewColumnsDetected([]); }, []); return { visibleColumns, columnOrder, getOrderedVisibleColumns, resetColumnOrder, toggleColumn, selectAllColumns, unselectAllColumns, isColumnVisible, handleDragStart, handleDragEnd, handleDragOver, handleDrop, newColumnsDetected, dismissNewColumnsNotification, }; }