myems-web/src/components/e-commerce/Customers.js
import React, { createRef, Fragment, useState } from 'react';
import {
Button,
Card,
CardBody,
Col,
CustomInput,
DropdownItem,
DropdownMenu,
DropdownToggle,
InputGroup,
Media,
Row,
UncontrolledDropdown
} from 'reactstrap';
import FalconCardHeader from '../common/FalconCardHeader';
import ButtonIcon from '../common/ButtonIcon';
import paginationFactory, { PaginationProvider } from 'react-bootstrap-table2-paginator';
import BootstrapTable from 'react-bootstrap-table-next';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { Link } from 'react-router-dom';
import Flex from '../common/Flex';
import Avatar from '../common/Avatar';
import { getPaginationArray } from '../../helpers/utils';
import customers from '../../data/e-commerce/customers';
const nameFormatter = (dataField, { avatar, name }) => {
return (
<Link to="/pages/customer-details">
<Media tag={Flex} align="center">
<Avatar {...avatar} />
<Media body className="ml-2">
<h5 className="mb-0 fs--1">{name}</h5>
</Media>
</Media>
</Link>
);
};
const emailFormatter = email => <a href={`mailto:${email}`}>{email}</a>;
const phoneFormatter = phone => <a href={`tel:${phone}`}>{phone}</a>;
const actionFormatter = (dataField, { id }: row) => (
// Control your row with this id
<UncontrolledDropdown>
<DropdownToggle color="link" size="sm" className="text-600 btn-reveal mr-3">
<FontAwesomeIcon icon="ellipsis-h" className="fs--1" />
</DropdownToggle>
<DropdownMenu right className="border py-2">
<DropdownItem onClick={() => console.log('Edit: ', id)}>Edit</DropdownItem>
<DropdownItem onClick={() => console.log('Delete: ', id)} className="text-danger">
Delete
</DropdownItem>
</DropdownMenu>
</UncontrolledDropdown>
);
const columns = [
{
dataField: 'name',
text: 'Name',
headerClasses: 'border-0',
classes: 'border-0 py-2 align-middle',
formatter: nameFormatter,
sort: true
},
{
dataField: 'email',
headerClasses: 'border-0',
text: 'Email',
classes: 'border-0 py-2 align-middle',
formatter: emailFormatter,
sort: true
},
{
dataField: 'phone',
headerClasses: 'border-0',
text: 'Phone',
classes: 'border-0 py-2 align-middle',
formatter: phoneFormatter,
sort: true
},
{
dataField: 'address',
headerClasses: 'border-0',
text: 'Billing Address',
classes: 'border-0 py-2 align-middle',
sort: true
},
{
dataField: 'joined',
headerClasses: 'border-0',
text: 'Joined',
classes: 'border-0 py-2 align-middle',
sort: true,
align: 'right',
headerAlign: 'right'
},
{
dataField: '',
headerClasses: 'border-0',
text: '',
classes: 'border-0 py-2 align-middle',
formatter: actionFormatter,
align: 'right'
}
];
const options = {
custom: true,
sizePerPage: 12,
totalSize: customers.length
};
const SelectRowInput = ({ indeterminate, rowIndex, ...rest }) => (
<div className="custom-control custom-checkbox">
<input
className="custom-control-input"
{...rest}
onChange={() => {}}
ref={input => {
if (input) input.indeterminate = indeterminate;
}}
/>
<label className="custom-control-label" />
</div>
);
const selectRow = onSelect => ({
mode: 'checkbox',
columnClasses: 'py-2 align-middle',
clickToSelect: false,
selectionHeaderRenderer: ({ mode, ...rest }) => <SelectRowInput type="checkbox" {...rest} />,
selectionRenderer: ({ mode, ...rest }) => <SelectRowInput type={mode} {...rest} />,
headerColumnStyle: { border: 0, verticalAlign: 'middle' },
selectColumnStyle: { border: 0, verticalAlign: 'middle' },
onSelect: onSelect,
onSelectAll: onSelect
});
const Customers = () => {
let table = createRef();
// State
const [isSelected, setIsSelected] = useState(false);
const handleNextPage = ({ page, onPageChange }) => () => {
onPageChange(page + 1);
};
const handlePrevPage = ({ page, onPageChange }) => () => {
onPageChange(page - 1);
};
const onSelect = () => {
setImmediate(() => {
setIsSelected(!!table.current.selectionContext.selected.length);
});
};
return (
<Card className="mb-3">
<FalconCardHeader title="Customers" light={false}>
{isSelected ? (
<InputGroup size="sm" className="input-group input-group-sm">
<CustomInput type="select" id="bulk-select">
<option>Bulk actions</option>
<option value="Delete">Delete</option>
<option value="Archive">Archive</option>
</CustomInput>
<Button color="falcon-default" size="sm" className="ml-2">
Apply
</Button>
</InputGroup>
) : (
<Fragment>
<ButtonIcon icon="plus" transform="shrink-3 down-2" color="falcon-default" size="sm">
New
</ButtonIcon>
<ButtonIcon icon="filter" transform="shrink-3 down-2" color="falcon-default" size="sm" className="mx-2">
Filter
</ButtonIcon>
<ButtonIcon icon="external-link-alt" transform="shrink-3 down-2" color="falcon-default" size="sm">
Export
</ButtonIcon>
</Fragment>
)}
</FalconCardHeader>
<CardBody className="p-0">
<PaginationProvider pagination={paginationFactory(options)}>
{({ paginationProps, paginationTableProps }) => {
const lastIndex = paginationProps.page * paginationProps.sizePerPage;
return (
<Fragment>
<div className="table-responsive">
<BootstrapTable
ref={table}
bootstrap4
keyField="id"
data={customers}
columns={columns}
selectRow={selectRow(onSelect)}
bordered={false}
classes="table-dashboard table-striped table-sm fs--1 border-bottom border-200 mb-0 table-dashboard-th-nowrap"
rowClasses="btn-reveal-trigger border-top border-200"
headerClasses="bg-200 text-900 border-y border-200"
{...paginationTableProps}
/>
</div>
<Row noGutters className="px-1 py-3 flex-center">
<Col xs="auto">
<Button
color="falcon-default"
size="sm"
onClick={handlePrevPage(paginationProps)}
disabled={paginationProps.page === 1}
>
<FontAwesomeIcon icon="chevron-left" />
</Button>
{getPaginationArray(paginationProps.totalSize, paginationProps.sizePerPage).map(pageNo => (
<Button
color={paginationProps.page === pageNo ? 'falcon-primary' : 'falcon-default'}
size="sm"
className="ml-2"
onClick={() => paginationProps.onPageChange(pageNo)}
key={pageNo}
>
{pageNo}
</Button>
))}
<Button
color="falcon-default"
size="sm"
className="ml-2"
onClick={handleNextPage(paginationProps)}
disabled={lastIndex >= paginationProps.totalSize}
>
<FontAwesomeIcon icon="chevron-right" />
</Button>
</Col>
</Row>
</Fragment>
);
}}
</PaginationProvider>
</CardBody>
</Card>
);
};
export default Customers;