'use client' import React, { useState, useMemo } from 'react' import { AgGridReact } from 'ag-grid-react' import { ColDef } from 'ag-grid-community' import 'ag-grid-community/styles/ag-grid.css' import 'ag-grid-community/styles/ag-theme-alpine.css' import { formatDate } from '@/lib/utils' interface User { id: string email: string firstName: string lastName: string role: string phone?: string createdAt: Date client?: { id: string membershipType: string membershipStatus: string joinDate: Date lastVisit?: Date } } interface UserGridProps { users: User[] onUserSelect?: (user: User) => void loading?: boolean } export function UserGrid({ users, onUserSelect, loading = false }: UserGridProps) { const [selectedUser, setSelectedUser] = useState(null) const columnDefs: ColDef[] = useMemo(() => [ { headerName: 'Name', valueGetter: (params) => `${params.data?.firstName} ${params.data?.lastName}`, filter: 'agTextColumnFilter', sortable: true, minWidth: 150, }, { headerName: 'Email', field: 'email', filter: 'agTextColumnFilter', sortable: true, minWidth: 200, }, { headerName: 'Role', field: 'role', filter: 'agSetColumnFilter', sortable: true, cellRenderer: (params: any) => { const roleColors = { admin: 'bg-purple-100 text-purple-800', trainer: 'bg-blue-100 text-blue-800', client: 'bg-green-100 text-green-800', } const colorClass = roleColors[params.value as keyof typeof roleColors] || 'bg-gray-100 text-gray-800' return `${params.value}` }, minWidth: 120, }, { headerName: 'Phone', field: 'phone', filter: 'agTextColumnFilter', sortable: true, minWidth: 130, }, { headerName: 'Membership', valueGetter: (params) => params.data?.client?.membershipType || 'N/A', filter: 'agSetColumnFilter', sortable: true, cellRenderer: (params: any) => { if (!params.value || params.value === 'N/A') return 'N/A' const membershipColors = { vip: 'bg-yellow-100 text-yellow-800', premium: 'bg-blue-100 text-blue-800', basic: 'bg-gray-100 text-gray-800', } const colorClass = membershipColors[params.value as keyof typeof membershipColors] || 'bg-gray-100 text-gray-800' return `${params.value}` }, minWidth: 120, }, { headerName: 'Status', valueGetter: (params) => params.data?.client?.membershipStatus || 'N/A', filter: 'agSetColumnFilter', sortable: true, cellRenderer: (params: any) => { if (!params.value || params.value === 'N/A') return 'N/A' const statusColors = { active: 'bg-green-100 text-green-800', inactive: 'bg-red-100 text-red-800', suspended: 'bg-yellow-100 text-yellow-800', } const colorClass = statusColors[params.value as keyof typeof statusColors] || 'bg-gray-100 text-gray-800' return `${params.value}` }, minWidth: 120, }, { headerName: 'Join Date', valueGetter: (params) => params.data?.client?.joinDate || params.data?.createdAt, filter: 'agDateColumnFilter', sortable: true, valueFormatter: (params: any) => formatDate(new Date(params.value)), minWidth: 120, }, { headerName: 'Last Visit', valueGetter: (params) => params.data?.client?.lastVisit, filter: 'agDateColumnFilter', sortable: true, valueFormatter: (params: any) => params.value ? formatDate(new Date(params.value)) : 'Never', minWidth: 120, }, ], []) const defaultColDef: ColDef = useMemo(() => ({ flex: 1, resizable: true, floatingFilter: true, suppressMenu: true, }), []) const onSelectionChanged = () => { const selectedNodes = gridRef.current?.api.getSelectedNodes() if (selectedNodes?.length > 0) { const user = selectedNodes[0].data setSelectedUser(user) onUserSelect?.(user) } } const gridRef = React.useRef>(null) const gridOptions = { columnDefs, defaultColDef, rowData: users, rowSelection: 'single', onSelectionChanged, enableRangeSelection: true, enableCellTextSelection: true, suppressRowClickSelection: false, animateRows: true, loading: loading, pagination: true, paginationPageSize: 20, paginationPageSizeSelector: [10, 20, 50, 100], } return (
{...gridOptions} ref={gridRef} />
) }