diff --git a/src/components/UsersComponents/AllUsersTable.tsx b/src/components/UsersComponents/AllUsersTable.tsx index e39535323..b6561db7b 100644 --- a/src/components/UsersComponents/AllUsersTable.tsx +++ b/src/components/UsersComponents/AllUsersTable.tsx @@ -8,12 +8,14 @@ import { MenuItem, InputLabel, Button, + IconButton, + Switch, + Tooltip, } from '@material-ui/core' import React from 'react' import GetAppIcon from '@material-ui/icons/GetApp' +import EditIcon from '@material-ui/icons/Edit' import styled from 'styled-components' -import * as xlsx from 'xlsx' -import { generateUsersXlsx } from '../../services/xlsxGenerator' import * as Types from '../../constants/Types' const TableRow = styled.tr` @@ -38,6 +40,7 @@ const StatusBadge = styled.span<{ archived: boolean }>` interface Props { users: Types.User[] onUserClick?: (user: Types.User) => void + onArchiveClick?: (user: Types.User) => void } interface State { @@ -102,8 +105,21 @@ class AllUsersTable extends React.Component { formatDate = (d: Date | null) => d ? d.toLocaleString([], { dateStyle: 'short', timeStyle: 'short' }) : 'Never' handleExport = () => { - const wb = generateUsersXlsx(this.getFilteredUsers()) - xlsx.writeFile(wb, `users_${new Date().toISOString().split('T')[0]}.xlsx`) + const users = this.getFilteredUsers() + const headers = ['Last Name', 'First Name', 'Email', 'Role', 'School', 'Status', 'Last Login'] + const escape = (val: string) => `"${(val || '').replace(/"/g, '""')}"` + const rows = users.map(u => [ + escape(u.lastName), escape(u.firstName), escape(u.email), + escape(this.formatRole(u.role)), escape(u.school || ''), + escape(u.archived ? 'Archived' : 'Active'), + escape(this.formatDate(u.lastLogin)) + ].join(',')) + const csv = [headers.join(','), ...rows].join('\n') + const blob = new Blob(['\ufeff' + csv], { type: 'text/csv;charset=utf-8;' }) + const link = document.createElement('a') + link.href = URL.createObjectURL(blob) + link.download = `users_${new Date().toISOString().split('T')[0]}.csv` + link.click() } render() { @@ -159,13 +175,14 @@ class AllUsersTable extends React.Component { + Actions {paginated.length === 0 ? ( - No users found + No users found ) : paginated.map(user => ( - this.props.onUserClick?.(user)}> + {user.lastName} {user.firstName} {user.email} @@ -173,6 +190,21 @@ class AllUsersTable extends React.Component { {user.school} {user.archived ? 'Archived' : 'Active'} {this.formatDate(user.lastLogin)} + e.stopPropagation()} style={{ whiteSpace: 'nowrap' }}> + + this.props.onUserClick?.(user)}> + + + + + this.props.onArchiveClick?.(user)} + color="primary" + /> + + ))} @@ -185,6 +217,7 @@ class AllUsersTable extends React.Component { onPageChange={(_, p) => this.setState({ page: p })} onRowsPerPageChange={e => this.setState({ perPage: +e.target.value, page: 0 })} rowsPerPageOptions={[10, 25, 50]} + labelDisplayedRows={({ from, to, count }) => `Showing ${from}-${to} of ${count} records`} /> diff --git a/src/views/protected/AdminViews/AllUsersPage.tsx b/src/views/protected/AdminViews/AllUsersPage.tsx index ac4b4ff71..5d62eb418 100644 --- a/src/views/protected/AdminViews/AllUsersPage.tsx +++ b/src/views/protected/AdminViews/AllUsersPage.tsx @@ -84,7 +84,11 @@ class AllUsersPage extends React.Component { Loading ) : ( - + this.setState({ selected: user, archiveOpen: true })} + /> )} )}