UNPKG

react-garden

Version:

React + TypeScript + ThreeJS app using Material UI on NextJS, Apollo Client, GraphQL + WordPress REST APIs, for ThreeD web development.. a part of the threed.ai code family.

243 lines (221 loc) 6.75 kB
// ** React Imports import { useEffect, useCallback, useState } from 'react' // ** Next Images import Link from 'next/link' // ** MUI Imports import Box from '@mui/material/Box' import Card from '@mui/material/Card' import Grid from '@mui/material/Grid' import { DataGrid } from '@mui/x-data-grid' import { styled } from '@mui/material/styles' import IconButton from '@mui/material/IconButton' import Typography from '@mui/material/Typography' // ** Icons Imports import Laptop from 'mdi-material-ui/Laptop' import ChartDonut from 'mdi-material-ui/ChartDonut' import CogOutline from 'mdi-material-ui/CogOutline' import EyeOutline from 'mdi-material-ui/EyeOutline' import PencilOutline from 'mdi-material-ui/PencilOutline' import AccountOutline from 'mdi-material-ui/AccountOutline' // ** Store Imports import { useDispatch, useSelector } from 'react-redux' // ** Custom Components Imports import CustomChip from '~/@core/components/mui/chip' import CustomAvatar from '~/@core/components/mui/avatar' // ** Utils Import import { getInitials } from '~/@core/utils/get-initials' // ** Actions Imports import { fetchData } from '~/store/apps/user' // ** Custom Components Imports import TableHeader from '~/views/apps/roles/TableHeader' // ** Vars const userRoleObj = { admin: <Laptop fontSize='small' sx={{ mr: 3, color: 'error.main' }} />, author: <CogOutline fontSize='small' sx={{ mr: 3, color: 'warning.main' }} />, editor: <PencilOutline fontSize='small' sx={{ mr: 3, color: 'info.main' }} />, maintainer: <ChartDonut fontSize='small' sx={{ mr: 3, color: 'success.main' }} />, subscriber: <AccountOutline fontSize='small' sx={{ mr: 3, color: 'primary.main' }} /> } const userStatusObj = { active: 'success', pending: 'warning', inactive: 'secondary' } // ** Styled component for the link for the avatar with image const AvatarWithImageLink = styled(Link)(({ theme }) => ({ marginRight: theme.spacing(3) })) // ** Styled component for the link for the avatar without image const AvatarWithoutImageLink = styled(Link)(({ theme }) => ({ textDecoration: 'none', marginRight: theme.spacing(3) })) // ** renders client column const renderClient = row => { if (row.avatar.length) { return ( <AvatarWithImageLink href={`/apps/user/view/${row.id}`}> <CustomAvatar src={row.avatar} sx={{ mr: 3, width: 30, height: 30 }} /> </AvatarWithImageLink> ) } else { return ( <AvatarWithoutImageLink href={`/apps/user/view/${row.id}`}> <CustomAvatar skin='light' color={row.avatarColor} sx={{ mr: 3, width: 30, height: 30, fontSize: '.875rem' }}> {getInitials(row.fullName ? row.fullName : 'Marty McGee')} </CustomAvatar> </AvatarWithoutImageLink> ) } } const columns = [ { flex: 0.2, minWidth: 230, field: 'fullName', headerName: 'User', renderCell: ({ row }) => { const { id, fullName, username } = row return ( <Box sx={{ display: 'flex', alignItems: 'center' }}> {renderClient(row)} <Box sx={{ display: 'flex', alignItems: 'flex-start', flexDirection: 'column' }}> <Link href={`/apps/user/view/${id}`} passHref> <Typography noWrap component='a' variant='body2' sx={{ fontWeight: 600, color: 'text.primary', textDecoration: 'none' }} > {fullName} </Typography> </Link> <Link href={`/apps/user/view/${id}`} passHref> <Typography noWrap component='a' variant='caption' sx={{ textDecoration: 'none' }}> @{username} </Typography> </Link> </Box> </Box> ) } }, { flex: 0.2, minWidth: 250, field: 'email', headerName: 'Email', renderCell: ({ row }) => { return ( <Typography variant='body2' noWrap> {row.email} </Typography> ) } }, { flex: 0.15, field: 'role', minWidth: 150, headerName: 'Role', renderCell: ({ row }) => { return ( <Box sx={{ display: 'flex', alignItems: 'center' }}> {userRoleObj[row.role]} <Typography noWrap sx={{ color: 'text.secondary', textTransform: 'capitalize' }}> {row.role} </Typography> </Box> ) } }, { flex: 0.15, minWidth: 120, headerName: 'Plan', field: 'currentPlan', renderCell: ({ row }) => { return ( <Typography noWrap sx={{ textTransform: 'capitalize' }}> {row.currentPlan} </Typography> ) } }, { flex: 0.1, minWidth: 110, field: 'status', headerName: 'Status', renderCell: ({ row }) => { return ( <CustomChip skin='light' size='small' label={row.status} color={userStatusObj[row.status]} sx={{ textTransform: 'capitalize' }} /> ) } }, { flex: 0.1, minWidth: 100, sortable: false, field: 'actions', headerName: 'Actions', renderCell: ({ row }) => ( <Link href={`/apps/user/view/${row.id}`} passHref> <IconButton> <EyeOutline /> </IconButton> </Link> ) } ] const UserList = () => { // ** State const [plan, setPlan] = useState('') const [value, setValue] = useState('') const [pageSize, setPageSize] = useState(10) // ** Hooks const dispatch = useDispatch() const store = useSelector(state => state.user) useEffect(() => { dispatch( fetchData({ role: '', q: value, status: '', currentPlan: plan }) ) }, [dispatch, plan, value]) const handleFilter = useCallback(val => { setValue(val) }, []) const handlePlanChange = useCallback(e => { setPlan(e.target.value) }, []) return ( <Grid container spacing={6}> <Grid item xs={12}> <Card> <TableHeader plan={plan} value={value} handleFilter={handleFilter} handlePlanChange={handlePlanChange} /> <DataGrid autoHeight rows={store.data} columns={columns} checkboxSelection pageSize={pageSize} disableSelectionOnClick rowsPerPageOptions={[10, 25, 50]} onPageSizeChange={newPageSize => setPageSize(newPageSize)} /> </Card> </Grid> </Grid> ) } export default UserList