UNPKG

@diagramers/admin

Version:

Diagramers Admin Template - React starter for admin dashboards.

192 lines (176 loc) 6.53 kB
import React, { useEffect, useState } from 'react'; import { useSelector, useDispatch } from 'react-redux'; import { Row, Col, Form } from 'react-bootstrap'; import { useTable, useGlobalFilter, useSortBy, usePagination, useRowSelect, useRowState, useAsyncDebounce } from 'react-table'; import HtmlHead from 'components/html-head/HtmlHead'; import BreadcrumbList from 'components/breadcrumb-list/BreadcrumbList'; import { createContact, deleteContact, getContacts, updateContact } from './contactsSlice'; import ItemList from './components/ItemList'; import ItemListPagination from './components/ItemListPagination'; import AddEditModal from './components/AddEditModal'; import ItemListHeader from './components/ItemListHeader'; import CheckAll from './components/CheckAll'; import SearchInput from './components/SearchInput'; import AddNewButton from './components/AddNewButton'; import MobileSortDropdown from './components/MobileSortDropdown'; import DeleteConfirmModal from './components/DeleteConfirmModal'; const ContactsApp = () => { const title = 'Contacts'; const description = 'User directory application that built with the help of List.js. Can be searched, paged and sorted.'; const breadcrumbs = [ { to: '', text: 'Home' }, { to: 'apps', title: 'Apps' }, ]; const columns = React.useMemo(() => { return [ { Header: 'Name', accessor: 'name', sortable: true, headerClassName: 'ol-3 col-lg-4 d-flex flex-column mb-lg-0 pe-3 d-flex', Cell: ({ cell }) => { return ( <a className="list-item-heading body" href="#!" onClick={(e) => { e.preventDefault(); }} > {cell.value} </a> ); }, }, { Header: 'Email', accessor: 'email', sortable: true, headerClassName: 'col-3 col-lg-3 d-flex flex-column pe-1 justify-content-center', }, { Header: 'Phone', accessor: 'phone', sortable: true, headerClassName: 'col-3 col-lg-3 d-flex flex-column pe-1 justify-content-center', }, { Header: 'Group', accessor: 'group', sortable: true, headerClassName: 'col-3 col-lg-1 d-flex flex-column pe-1 justify-content-center', }, { Header: '', id: 'action', headerClassName: '', Cell: ({ row }) => { const { checked, onChange } = row.getToggleRowSelectedProps(); return <Form.Check className="form-check float-end mt-1" type="checkbox" checked={checked} onChange={onChange} />; }, }, ]; }, []); const dispatch = useDispatch(); const { contacts: data, pageCount, loading } = useSelector((state) => state.contacts); const [isOpenAddEditModal, setIsOpenAddEditModal] = useState(false); const [isOpenDeleteConfirmModal, setIsOpenDeleteConfirmModal] = useState(false); const [term, setTerm] = useState(''); const tableInstance = useTable( { columns, data, isOpenAddEditModal, setIsOpenAddEditModal, isOpenDeleteConfirmModal, setIsOpenDeleteConfirmModal, manualPagination: true, manualFilters: true, manualSortBy: true, autoResetPage: false, autoResetSortBy: false, pageCount, initialState: { pageSize: 8, pageIndex: 0, sortBy: [{ id: 'name', desc: false }], hiddenColumns: ['id'] }, }, useGlobalFilter, useSortBy, usePagination, useRowSelect, useRowState ); const { state: { pageIndex, pageSize, sortBy }, } = tableInstance; const addItem = ({ item }) => { dispatch(createContact({ sortBy, pageSize, pageIndex, item })); }; const editItem = ({ item }) => { dispatch(updateContact({ sortBy, pageSize, pageIndex, item })); }; const deleteItem = (items) => { dispatch(deleteContact({ sortBy, pageSize, pageIndex, ids: items.map((x) => x.id) })); }; const searchItem = useAsyncDebounce((val) => { setTerm(val || undefined); }, 200); useEffect(() => { if (loading) { document.body.classList.add('spinner'); } else { document.body.classList.remove('spinner'); } return () => { document.body.classList.remove('spinner'); }; }, [loading]); useEffect(() => { try { dispatch(getContacts({ term, sortBy, pageSize, pageIndex })); } catch (e) { // console.log('...error : ', e); } }, [sortBy, dispatch, pageIndex, pageSize, term]); return ( <> <HtmlHead title={title} description={description} /> <div className="container" id="contacts"> {/* Title and Top Buttons Start */} <div className="page-title-container"> <Row className="g-0"> <Col xs="auto" className="mb-2 mb-md-0 me-auto"> <div className="w-auto sw-md-30"> <h1 className="mb-0 pb-0 display-4">{title} </h1> <BreadcrumbList items={breadcrumbs} /> </div> </Col> <div className="w-100 d-md-none" /> <Col xs="12" sm="6" md="auto" className="d-flex align-items-start justify-content-end order-3 order-sm-2"> <div className="w-100 w-lg-auto search-input-container border border-separator"> <SearchInput tableInstance={tableInstance} onChange={searchItem} /> </div> </Col> <Col xs="12" sm="6" md="auto" className="d-flex align-items-start justify-content-end mb-2 mb-sm-0 order-sm-3"> <AddNewButton tableInstance={tableInstance} /> <MobileSortDropdown tableInstance={tableInstance} /> <CheckAll tableInstance={tableInstance} /> </Col> </Row> </div> {/* Title and Top Buttons End */} <Row className="g-0"> <Col> {/* List Items Start */} <div id="checkboxTable"> <ItemListHeader tableInstance={tableInstance} /> <ItemList tableInstance={tableInstance} /> <ItemListPagination tableInstance={tableInstance} /> </div> </Col> {isOpenAddEditModal && <AddEditModal tableInstance={tableInstance} addItem={addItem} editItem={editItem} />} {isOpenDeleteConfirmModal && <DeleteConfirmModal tableInstance={tableInstance} deleteItem={deleteItem} />} </Row> </div> </> ); }; export default ContactsApp;