import { AG_GRID_LOCALE_ES } from "@ag-grid-community/locale"; import type { CellKeyDownEvent, RowClickedEvent, ValueFormatterParams } from "ag-grid-community"; import { ColDef, GridOptions, SizeColumnsToContentStrategy, SizeColumnsToFitGridStrategy, SizeColumnsToFitProvidedWidthStrategy, } from "ag-grid-community"; import { useCallback, useMemo, useState } from "react"; import { ErrorOverlay } from "@repo/rdx-ui/components"; import { Button } from "@repo/shadcn-ui/components"; import { AgGridReact } from "ag-grid-react"; import { ChevronRightIcon } from "lucide-react"; import { useNavigate } from "react-router-dom"; import { useCustomersQuery } from "../hooks"; import { useTranslation } from "../i18n"; import { CustomerStatusBadge } from "./customer-status-badge"; // Create new GridExample component export const CustomersListGrid = () => { const { t } = useTranslation(); const navigate = useNavigate(); const { data: customersData, isLoading: isLoadingCustomers, isError: isLoadError, error: loadError, } = useCustomersQuery({ pagination: { pageSize: 999, }, }); // Column Definitions: Defines & controls grid columns. const [columnDefs] = useState([ { field: "name", headerName: t("pages.list.grid_columns.name"), minWidth: 300 }, { field: "tin", headerName: t("pages.list.grid_columns.tin"), maxWidth: 120, }, { field: "city", headerName: t("pages.list.grid_columns.city"), }, { field: "email_primary", headerName: t("pages.list.grid_columns.email"), }, { field: "phone_primary", headerName: t("pages.list.grid_columns.phone"), maxWidth: 120, }, { field: "mobile_primary", headerName: t("pages.list.grid_columns.mobile"), maxWidth: 120, }, { field: "status", headerName: t("pages.list.grid_columns.status"), maxWidth: 135, cellRenderer: (params: ValueFormatterParams) => { return ; }, }, { colId: "actions", headerName: t("pages.list.grid_columns.actions", "Actions"), cellRenderer: (params: ValueFormatterParams) => { const { data } = params; return ( ); }, }, ]); // Navegación centralizada (click/teclado) const goToRow = useCallback( (id: string, newTab = false) => { const url = `/customers/${id}`; if (newTab) { window.open(url, "_blank", "noopener,noreferrer"); } else { navigate(url); } }, [navigate] ); const onRowClicked = useCallback( (e: RowClickedEvent) => { if (!e.data) return; // Soporta Ctrl/Cmd click para nueva pestaña const newTab = e.event instanceof MouseEvent && (e.event.metaKey || e.event.ctrlKey); goToRow(e.data.id, newTab); }, [goToRow] ); const onCellKeyDown = useCallback( (e: CellKeyDownEvent) => { if (!e.data) return; const key = e.event.key; // Enter o Space disparan navegación if (key === "Enter" || key === " ") { e.event.preventDefault(); goToRow(e.data.id); } // Ctrl/Cmd+Enter abre en nueva pestaña if ((e.event.ctrlKey || e.event.metaKey) && key === "Enter") { e.event.preventDefault(); goToRow(e.data.id, true); } }, [goToRow] ); const autoSizeStrategy = useMemo< | SizeColumnsToFitGridStrategy | SizeColumnsToFitProvidedWidthStrategy | SizeColumnsToContentStrategy >(() => { return { type: "fitGridWidth", defaultMinWidth: 100, columnLimits: [{ colId: "actions", minWidth: 75, maxWidth: 75 }], }; }, []); const gridOptions: GridOptions = useMemo( () => ({ columnDefs: columnDefs, autoSizeStrategy: autoSizeStrategy, defaultColDef: { editable: false, flex: 1, filter: false, sortable: false, resizable: true, }, pagination: true, paginationPageSize: 15, paginationPageSizeSelector: [10, 15, 20, 30, 50], localeText: AG_GRID_LOCALE_ES, // Evita conflictos con selección si la usas suppressRowClickSelection: true, // Clase visual de fila clickeable getRowClass: () => "clickable-row", // Accesibilidad con teclado onCellKeyDown, // Click en cualquier parte de la fila onRowClicked, // IDs estables (opcional pero recomendado) getRowId: (params) => params.data.id, }), [autoSizeStrategy, columnDefs, onCellKeyDown, onRowClicked] ); if (isLoadError) { return ( <> ); } // Container: Defines the grid's theme & dimensions. return (
); };