hide notification dashboard & add search employee data

This commit is contained in:
Muhammad Fajar
2024-01-02 11:31:39 +07:00
parent b7ff05bc87
commit df4bd6946f
6 changed files with 226 additions and 223 deletions

View File

@@ -203,6 +203,12 @@ class CorporateMemberService
->whereHas('employeds', function ($query) use ($corporateId) { ->whereHas('employeds', function ($query) use ($corporateId) {
$query->where('corporate_id', $corporateId); $query->where('corporate_id', $corporateId);
}) })
->when($request->input('search'), function ($query, $search) {
$query->where(function ($query) use ($search) {
$query->orWhere('member_id', 'like', "%" . $search . "%")
->orWhere('name', 'like', "%" . $search . "%");
});
})
->when($request->has('orderBy'), function ($query) use ($request) { ->when($request->has('orderBy'), function ($query) use ($request) {
$orderBy = match ($request->input('orderBy')) { $orderBy = match ($request->input('orderBy')) {
'memberId' => 'member_id', 'memberId' => 'member_id',

View File

@@ -84,6 +84,7 @@ export type TableListProps<DataType> = {
}; };
searchs?: { searchs?: {
useSearchs: boolean; useSearchs: boolean;
fullWidth?: boolean;
searchText: string; searchText: string;
setSearchText: Dispatch<SetStateAction<string>>; setSearchText: Dispatch<SetStateAction<string>>;
handleSearchSubmit: (event: FormEvent<HTMLFormElement>) => void; handleSearchSubmit: (event: FormEvent<HTMLFormElement>) => void;

View File

@@ -1,5 +1,4 @@
/* ---------------------------------- @mui ---------------------------------- */ /* ---------------------------------- @mui ---------------------------------- */
import { styled } from '@mui/material/styles';
import { import {
Paper, Paper,
Table as TableContent, Table as TableContent,
@@ -12,49 +11,23 @@ import {
Button, Button,
TableSortLabel, TableSortLabel,
Box, Box,
Card,
Grid, Grid,
FormControl, FormControl,
InputLabel, InputLabel,
Select, Select,
MenuItem, MenuItem,
SelectChangeEvent, InputAdornment,
Stack,
Typography, Typography,
LinearProgress,
linearProgressClasses,
} from '@mui/material'; } from '@mui/material';
import { visuallyHidden } from '@mui/utils'; import { visuallyHidden } from '@mui/utils';
/* ---------------------------------- axios --------------------------------- */
import axios from '../utils/axios';
/* ---------------------------------- react --------------------------------- */ /* ---------------------------------- react --------------------------------- */
import { Fragment, useContext, useEffect, useState } from 'react'; import { Fragment } from 'react';
import { useSearchParams } from 'react-router-dom';
/* -------------------------------- component ------------------------------- */ /* -------------------------------- component ------------------------------- */
import BaseTablePagination from './BaseTablePagination'; import BaseTablePagination from './BaseTablePagination';
/* ---------------------------------- theme --------------------------------- */
import palette from '../theme/palette';
/* ---------------------------------- utils --------------------------------- */ /* ---------------------------------- utils --------------------------------- */
import { UserCurrentCorporateContext } from '../contexts/UserCurrentCorporate'; import { Download, Search as SearchIcon } from '@mui/icons-material';
import { fSplit } from '../utils/formatNumber';
import { Download, Search as SearchIcon, Upload } from '@mui/icons-material';
/* ---------------------------------- types --------------------------------- */ /* ---------------------------------- types --------------------------------- */
import { DivisionDataProps, Order, PaginationTableProps, TableListProps } from '../@types/table'; import { DivisionDataProps, StatusDataProps, TableListProps } from '../@types/table';
import { InputAdornment } from '@mui/material';
import GetAppIcon from '@mui/icons-material/GetApp';
/* --------------------------------- styled --------------------------------- */
const BorderLinearProgress = styled(LinearProgress)(({ theme }) => ({
height: 10,
borderRadius: 6,
[`&.${linearProgressClasses.colorPrimary}`]: {
backgroundColor: '#D1F1F1',
},
[`& .${linearProgressClasses.bar}`]: {
borderRadius: 6,
backgroundColor: theme.palette.primary.main,
},
}));
/* -------------------------------------------------------------------------- */
export default function Table<T>({ export default function Table<T>({
headCells, headCells,
@@ -136,7 +109,7 @@ export default function Table<T>({
const parameters = Object.fromEntries([ const parameters = Object.fromEntries([
...params.searchParams.entries(), ...params.searchParams.entries(),
['page', newPage + 1], ['page', newPage + 1],
['per_page', paginations.rowsPerPage] ['per_page', paginations.rowsPerPage],
]); ]);
paginations.setPage(newPage); paginations.setPage(newPage);
await new Promise((resolve) => setTimeout(resolve, 500)); await new Promise((resolve) => setTimeout(resolve, 500));
@@ -161,96 +134,95 @@ export default function Table<T>({
return ( return (
// <Card> // <Card>
<Grid container> <Grid container>
{/* Field 1 */} {/* Field 1 */}
<Grid item xs={12} paddingX="24px" paddingY="20px"> <Grid item xs={12} paddingX="24px" paddingY="20px">
<Grid container spacing={2}> <Grid container spacing={2}>
{filters && filters.useFilter ? ( {filters && filters.useFilter ? (
<Fragment> <Fragment>
<Grid item xs={12} lg={3} xl={2}> <Grid item xs={12} lg={3} xl={2}>
<FormControl fullWidth> <FormControl fullWidth>
<InputLabel id="simple-division-select-lable">Division</InputLabel> <InputLabel id="simple-division-select-lable">Division</InputLabel>
<Select <Select
labelId="simple-division-select-lable" labelId="simple-division-select-lable"
id="division-select-lable" id="division-select-lable"
value={filters.config.divisionValue} value={filters.config.divisionValue}
label="Division" label="Division"
onChange={filters.config.handleDivisionChange} onChange={filters.config.handleDivisionChange}
> >
<MenuItem value="all">All</MenuItem> <MenuItem value="all">All</MenuItem>
{filters.config.divisionData.map((row: DivisionDataProps, index) => ( {filters.config.divisionData.map((row: DivisionDataProps, index) => (
<MenuItem key={index} value={row.id}> <MenuItem key={index} value={row.id}>
{row.name} {row.name}
</MenuItem> </MenuItem>
))} ))}
</Select> </Select>
</FormControl> </FormControl>
</Grid> </Grid>
<Grid item xs={12} lg={9} xl={10}> <Grid item xs={12} lg={9} xl={10}>
<form onSubmit={searchs?.handleSearchSubmit}>
<TextField
id="search-input"
label="Search"
variant="outlined"
onChange={(event) => searchs?.setSearchText(event.target.value)}
value={searchs?.searchText}
fullWidth
/>
</form>
</Grid>
</Fragment>
) : null}
{searchs && searchs.useSearchs ? (
<Fragment>
{filterStatus && filterStatus.useFilter ? (
<Grid item xs={12} lg={4} xl={4}>
<form onSubmit={searchs.handleSearchSubmit}> <form onSubmit={searchs.handleSearchSubmit}>
<TextField <TextField
id="search-input" id="search-input"
label="Search"
variant="outlined" variant="outlined"
onChange={(event) => searchs.setSearchText(event.target.value)} onChange={(event) => searchs.setSearchText(event.target.value)}
value={searchs.searchText} value={searchs.searchText}
fullWidth fullWidth
InputProps={{
startAdornment: (
<InputAdornment position="start">
<SearchIcon />
</InputAdornment>
),
}}
placeholder="Search Name or Member ID... "
/> />
</form> </form>
</Grid> </Grid>
</Fragment> ) : (
) : null } <Grid item xs={12} lg={searchs.fullWidth ? 12 : 6} xl={searchs.fullWidth ? 12 : 6}>
<form onSubmit={searchs.handleSearchSubmit}>
{searchs && searchs.useSearchs ? ( <TextField
<Fragment> id="search-input"
{filterStatus && filterStatus.useFilter ? ( variant="outlined"
<Grid item xs={12} lg={4} xl={4}> onChange={(event) => searchs.setSearchText(event.target.value)}
<form onSubmit={searchs.handleSearchSubmit}> value={searchs.searchText}
<TextField fullWidth
id="search-input" InputProps={{
variant="outlined" startAdornment: (
onChange={(event) => searchs.setSearchText(event.target.value)} <InputAdornment position="start">
value={searchs.searchText} <SearchIcon />
fullWidth </InputAdornment>
InputProps={{ ),
startAdornment: ( }}
<InputAdornment position="start"> placeholder="Search Name or Member ID... "
<SearchIcon /> />
</InputAdornment> </form>
),
}}
placeholder="Search Name or Member ID... "
/>
</form>
</Grid> </Grid>
) : )}
<Grid item xs={12} lg={6} xl={6}> </Fragment>
<form onSubmit={searchs.handleSearchSubmit}> ) : null}
<TextField
id="search-input"
variant="outlined"
onChange={(event) => searchs.setSearchText(event.target.value)}
value={searchs.searchText}
fullWidth
InputProps={{
startAdornment: (
<InputAdornment position="start">
<SearchIcon />
</InputAdornment>
),
}}
placeholder="Search Name or Member ID... "
/>
</form>
</Grid>
}
</Fragment>
) : null }
{/* Start date */} {/* Start date */}
{filterStartDate && filterStartDate.useFilter ? ( {filterStartDate && filterStartDate.useFilter ? (
<Grid item xs={12} lg={2} xl={2}> <Grid item xs={12} lg={2} xl={2}>
<form onChange={filterStartDate.handleStartDateChange}> <form onChange={filterStartDate.handleStartDateChange}>
<TextField <TextField
id="date-input" id="date-input"
@@ -266,12 +238,12 @@ export default function Table<T>({
/> />
</form> </form>
</Grid> </Grid>
) : null } ) : null}
{/* End Date */} {/* End Date */}
{filterEndDate && filterEndDate.useFilter ? ( {filterEndDate && filterEndDate.useFilter ? (
<Grid item xs={12} lg={2} xl={2}> <Grid item xs={12} lg={2} xl={2}>
<form onChange={filterEndDate.handleEndDateChange}> <form onChange={filterEndDate.handleEndDateChange}>
<TextField <TextField
id="date-input" id="date-input"
@@ -287,101 +259,105 @@ export default function Table<T>({
/> />
</form> </form>
</Grid> </Grid>
) : null } ) : null}
{/* Filter status */} {/* Filter status */}
{filterStatus && filterStatus.useFilter ? ( {filterStatus && filterStatus.useFilter ? (
<Grid item xs={12} lg={2} xl={2}> <Grid item xs={12} lg={2} xl={2}>
<FormControl fullWidth> <FormControl fullWidth>
<InputLabel id="simple-status-select-lable">Status</InputLabel> <InputLabel id="simple-status-select-lable">Status</InputLabel>
<Select <Select
labelId="simple-status-select-lable" labelId="simple-status-select-lable"
id="status-select-lable" id="status-select-lable"
value={filterStatus.config.statusValue} value={filterStatus.config.statusValue}
label="Status" label="Status"
onChange={filterStatus.config.handleStatusChange} onChange={filterStatus.config.handleStatusChange}
> >
<MenuItem value="all">All</MenuItem> <MenuItem value="all">All</MenuItem>
{filterStatus.config.filterData.map((row: StatusDataProps, index) => ( {filterStatus.config.statusData.map((row: StatusDataProps, index) => (
<MenuItem key={index} value={row.id}> <MenuItem key={index} value={row.id}>
{row.name} {row.name}
</MenuItem> </MenuItem>
))} ))}
</Select> </Select>
</FormControl> </FormControl>
</Grid> </Grid>
) : null } ) : null}
{/* Export Report */} {/* Export Report */}
{exportReport && exportReport.useExport ? (
{exportReport && exportReport.useExport ? ( <Grid item xs={12} lg={2} xl={2}>
<Grid item xs={12} lg={2} xl={2}> <FormControl fullWidth>
<FormControl fullWidth> <Button
<Button variant='contained' sx={{p:2}} onClick={exportReport.handleExportReport}> variant="contained"
<Download /> sx={{ p: 2 }}
<Typography variant='inherit' sx={{marginLeft: 1}}>Export</Typography> onClick={() => exportReport.handleExportReport}
</Button> >
</FormControl> <Download />
</Grid> <Typography variant="inherit" sx={{ marginLeft: 1 }}>
) : null } Export
</Typography>
</Grid> </Button>
</FormControl>
</Grid>
) : null}
</Grid> </Grid>
{/* End Field 1 */}
{/* Field 2 */}
<Grid item xs={12}>
{/* Table */}
<TableContainer component={Paper}>
<TableContent aria-label="collapsible table" size="small">
{/* Table Header */}
<EnhancedTableHead />
{/* End Table Header */}
{/* Table Body */}
<TableBody>
{loadings.isLoading && rows.length >= 1 ? (
<TableRow>
<TableCell colSpan={headCells?.length} align="center">
Loading . . .
</TableCell>
</TableRow>
) : rows && rows.length >= 1 ? (
rows.map((row, rowIndex) => (
<TableRow key={rowIndex}>
{headCells &&
//@ts-ignore
headCells.map((head, headIndex) => (
//@ts-ignore
<TableCell align={head.align} key={headIndex}>
{row[head.id]}
</TableCell>
))}
</TableRow>
))
) : (
<TableRow>
<TableCell colSpan={6} align="center">
No Data Found
</TableCell>
</TableRow>
)}
</TableBody>
{/* End Table Body */}
</TableContent>
</TableContainer>
{/* End Table */}
{/* Pagination */}
<BaseTablePagination
count={paginations.paginationTable.total}
onPageChange={onPageChangeHandle}
page={paginations.page}
rowsPerPage={paginations.rowsPerPage}
onRowsPerPageChange={onRowsPerPageChangeHandle}
/>
{/* End Pagination */}
</Grid>
{/* End Field 2 */}
</Grid> </Grid>
{/* End Field 1 */}
{/* Field 2 */}
<Grid item xs={12}>
{/* Table */}
<TableContainer component={Paper}>
<TableContent aria-label="collapsible table" size="small">
{/* Table Header */}
<EnhancedTableHead />
{/* End Table Header */}
{/* Table Body */}
<TableBody>
{loadings.isLoading && rows && rows.length >= 1 ? (
<TableRow>
<TableCell colSpan={headCells?.length} align="center">
Loading . . .
</TableCell>
</TableRow>
) : rows && rows.length >= 1 ? (
rows.map((row, rowIndex) => (
<TableRow key={rowIndex}>
{headCells &&
//@ts-ignore
headCells.map((head, headIndex) => (
//@ts-ignore
<TableCell align={head.align} key={headIndex}>
{row[head.id]}
</TableCell>
))}
</TableRow>
))
) : (
<TableRow>
<TableCell colSpan={6} align="center">
No Data Found
</TableCell>
</TableRow>
)}
</TableBody>
{/* End Table Body */}
</TableContent>
</TableContainer>
{/* End Table */}
{/* Pagination */}
<BaseTablePagination
count={paginations.paginationTable.total}
onPageChange={onPageChangeHandle}
page={paginations.page}
rowsPerPage={paginations.rowsPerPage}
onRowsPerPageChange={onRowsPerPageChangeHandle}
/>
{/* End Pagination */}
</Grid>
{/* End Field 2 */}
</Grid>
// </Card> // </Card>
); );
} }

View File

@@ -60,9 +60,8 @@ export default function DashboardLayout() {
const [corporateValue, setCorporateValue] = useLocalStorage( const [corporateValue, setCorporateValue] = useLocalStorage(
'corporateValue', 'corporateValue',
user.corporate ? `${user.corporate.id}` : '' user && user.corporate ? `${user.corporate.id}` : ''
); );
const value = { corporateValue, setCorporateValue };
if (verticalLayout) { if (verticalLayout) {
return ( return (
@@ -96,7 +95,7 @@ export default function DashboardLayout() {
} }
return ( return (
<UserCurrentCorporateContext.Provider value={value}> <UserCurrentCorporateContext.Provider value={{ corporateValue, setCorporateValue }}>
<Box <Box
sx={{ sx={{
display: { lg: 'flex' }, display: { lg: 'flex' },

View File

@@ -21,7 +21,7 @@ import { Stack } from '@mui/system';
import { UserCurrentCorporateContext } from '../../contexts/UserCurrentCorporate'; import { UserCurrentCorporateContext } from '../../contexts/UserCurrentCorporate';
import Table from '../../components/Table'; import Table from '../../components/Table';
import { HeadCell, Order, PaginationTableProps } from '../../@types/table'; import { HeadCell, Order, PaginationTableProps } from '../../@types/table';
import { useSearchParams } from 'react-router-dom'; import { useLocation, useSearchParams } from 'react-router-dom';
import palette from '../../theme/palette'; import palette from '../../theme/palette';
import { fSplit } from '../../utils/formatNumber'; import { fSplit } from '../../utils/formatNumber';
@@ -80,6 +80,7 @@ type CardPolicyProps = {
export default function Index() { export default function Index() {
const { themeStretch } = useSettings(); const { themeStretch } = useSettings();
const { corporateValue } = useContext(UserCurrentCorporateContext); const { corporateValue } = useContext(UserCurrentCorporateContext);
const { pathname } = useLocation();
const [memberData, setMemberData] = useState([]); const [memberData, setMemberData] = useState([]);
const [policyData, setPolicyData] = useState<CardPolicyProps>(); const [policyData, setPolicyData] = useState<CardPolicyProps>();
@@ -257,8 +258,6 @@ export default function Index() {
(async () => { (async () => {
setIsLoading(true); setIsLoading(true);
await new Promise((resolve) => setTimeout(resolve, 250));
const parameters = const parameters =
Object.keys(appliedParams).length !== 0 Object.keys(appliedParams).length !== 0
? appliedParams ? appliedParams
@@ -270,10 +269,12 @@ export default function Index() {
params: { ...parameters }, params: { ...parameters },
}); });
// console.log('member', corporateMembers);
const corporateTopUpLimit = await axios.get(`${corporateValue}/topup`); const corporateTopUpLimit = await axios.get(`${corporateValue}/topup`);
setSearchParams(parameters); if (pathname === '/dashboard') {
setSearchParams(parameters);
}
setPolicyData({ setPolicyData({
limit: corporatePolicyLimit.data.data, limit: corporatePolicyLimit.data.data,
topUpLimit: corporateTopUpLimit.data.data, topUpLimit: corporateTopUpLimit.data.data,
@@ -325,10 +326,10 @@ export default function Index() {
</Button> </Button>
), ),
/* action: ( /* action: (
<IconButton onClick={handleAction}> <IconButton onClick={handleAction}>
<MoreVertIcon /> <MoreVertIcon />
</IconButton> </IconButton>
), */ ), */
})) }))
); );
setPaginationTable(corporateMembers.data); setPaginationTable(corporateMembers.data);

View File

@@ -85,6 +85,31 @@ export default function List() {
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */
/* ------------------------------ handle search ----------------------------- */
const [searchText, setSearchText] = useState('');
const handleSearchSubmit = async (event: React.FormEvent<HTMLFormElement>) => {
event.preventDefault();
if (searchText === '') {
searchParams.delete('search');
const params = Object.fromEntries([...searchParams.entries()]);
setAppliedParams(params);
} else {
const params = Object.fromEntries([...searchParams.entries(), ['search', searchText]]);
setAppliedParams(params);
}
};
const searchs = {
useSearchs: true,
fullWidth: true,
searchText: searchText,
setSearchText: setSearchText,
handleSearchSubmit: handleSearchSubmit,
};
/* -------------------------------------------------------------------------- */
/* -------------------------------- headCell -------------------------------- */ /* -------------------------------- headCell -------------------------------- */
const headCells: HeadCell<never>[] = [ const headCells: HeadCell<never>[] = [
{ {
@@ -146,11 +171,6 @@ export default function List() {
setData( setData(
response.data.data.map((obj: any) => ({ response.data.data.map((obj: any) => ({
...obj, ...obj,
// memberId:
// <Button
// onClick={() => navigate ('/employee-data/user-profile/'+obj.personId)}
// >{obj.memberId}</Button>
// ,
status: status:
obj.status === 1 ? ( obj.status === 1 ? (
<Label color="success">Active</Label> <Label color="success">Active</Label>
@@ -200,7 +220,7 @@ export default function List() {
paginations={paginations} paginations={paginations}
loadings={loadings} loadings={loadings}
params={params} params={params}
// searchs={searchs} searchs={searchs}
// filters={filters} // filters={filters}
/> />
</Stack> </Stack>