This commit is contained in:
R
2022-12-13 12:47:26 +07:00
17 changed files with 356 additions and 219 deletions

View File

@@ -0,0 +1,63 @@
<?php
namespace Modules\Client\Http\Controllers\Api;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
class ClaimReportController extends Controller
{
/**
* Display a listing of the resource.
*
* @return \Illuminate\Http\Response
*/
public function index()
{
}
/**
* Store a newly created resource in storage.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function store(Request $request)
{
//
}
/**
* Display the specified resource.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function show($id)
{
//
}
/**
* Update the specified resource in storage.
*
* @param \Illuminate\Http\Request $request
* @param int $id
* @return \Illuminate\Http\Response
*/
public function update(Request $request, $id)
{
//
}
/**
* Remove the specified resource from storage.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function destroy($id)
{
//
}
}

View File

@@ -9,7 +9,7 @@ use Illuminate\Routing\Controller;
use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\Auth;
use Illuminate\Validation\Rule; use Illuminate\Validation\Rule;
class DivisionController extends Controller class CorporateDivisionController extends Controller
{ {
/** /**
* Display a listing of the resource. * Display a listing of the resource.

View File

@@ -9,7 +9,7 @@ use Illuminate\Http\Request;
use Illuminate\Routing\Controller; use Illuminate\Routing\Controller;
use Modules\Client\Transformers\MemberResources; use Modules\Client\Transformers\MemberResources;
class MemberController extends Controller class CorporateMemberController extends Controller
{ {
/** /**
* Display a listing of the resource. * Display a listing of the resource.
@@ -22,18 +22,26 @@ class MemberController extends Controller
$members = Member::query() $members = Member::query()
->whereHas('employeds', function ($corporateEmployee) use ($corporate_id) { ->whereHas('employeds', function ($corporateEmployee) use ($corporate_id) {
$corporateEmployee->where('corporate_id', $corporate_id); $corporateEmployee->where('corporate_id', $corporate_id);
})->when($request->input('division'), function ($division, $division_id) {
$division->whereHas('division', function ($corporateEmployee) use ($division_id) {
$corporateEmployee->where('division_id', $division_id);
});
})->when($request->input('search'), function ($query, $search) { })->when($request->input('search'), function ($query, $search) {
$query->where('member_id', 'like', "%" . $search . "%") $query->where('member_id', 'like', "%" . $search . "%")
->orWhere('name', 'like', "%" . $search . "%"); ->orWhere('name', 'like', "%" . $search . "%");
});
if ($request->input('claimMember') === 'false') {
$members = $members->when($request->input('division'), function ($division, $division_id) {
$division->whereHas('division', function ($corporateEmployee) use ($division_id) {
$corporateEmployee->where('division_id', $division_id);
});
})->when($request->has('orderBy'), function ($query) use ($request) { })->when($request->has('orderBy'), function ($query) use ($request) {
$query->orderBy($request->orderBy, $request->order); $query->orderBy($request->orderBy, $request->order);
})->paginate($limit); })->paginate($limit);
return response()->json(Helper::paginateResources(MemberResources::collection($members))); return response()->json(Helper::paginateResources(MemberResources::collection($members)));
} else {
$members = $members->get();
return response()->json(MemberResources::collection($members));
}
} }
/** /**

View File

@@ -1,10 +1,10 @@
<?php <?php
use Modules\Client\Http\Controllers\Api\AuthController; use Modules\Client\Http\Controllers\Api\AuthController;
use Modules\Client\Http\Controllers\Api\CorporateDivisionController;
use Modules\Client\Http\Controllers\Api\CorporateManageController; use Modules\Client\Http\Controllers\Api\CorporateManageController;
use Modules\Client\Http\Controllers\Api\CorporateMemberController;
use Modules\Client\Http\Controllers\Api\CorporatePolicyController; use Modules\Client\Http\Controllers\Api\CorporatePolicyController;
use Modules\Client\Http\Controllers\Api\DivisionController;
use Modules\Client\Http\Controllers\Api\MemberController;
use Modules\Client\Http\Controllers\Api\UserController; use Modules\Client\Http\Controllers\Api\UserController;
/* /*
@@ -26,15 +26,14 @@ Route::prefix('client')->group(function () {
}); });
Route::middleware('auth:sanctum')->group(function () { Route::middleware('auth:sanctum')->group(function () {
Route::post('logout', [AuthController::class, 'logout'])->name('logout'); Route::post('logout', [AuthController::class, 'logout'])->name('logout');
Route::get('user', [UserController::class, 'index']); Route::get('user', [UserController::class, 'index']);
Route::get('corporate-manage', [CorporateManageController::class, 'index']); Route::get('corporate-manage', [CorporateManageController::class, 'index']);
Route::prefix('{corporate_id}')->group(function () { Route::prefix('{corporate_id}')->group(function () {
Route::get('policy', [CorporatePolicyController::class, 'index']); Route::get('policy', [CorporatePolicyController::class, 'index']);
Route::get('division', [DivisionController::class, 'index']); Route::get('division', [CorporateDivisionController::class, 'index']);
Route::get('members', [MemberController::class, 'index']); Route::get('members', [CorporateMemberController::class, 'index']);
}); });
}); });
}); });

View File

@@ -15,15 +15,18 @@ class MemberResources extends JsonResource
public function toArray($request) public function toArray($request)
{ {
return [ return [
'id' => $this->id,
'memberId' => $this->member_id, 'memberId' => $this->member_id,
'fullName' => $this->full_name, 'fullName' => $this->full_name,
'division' => $this->division->name ?? '', $this->mergeWhen($request->input('claimMember') === 'false', [
'division' => $this->division->name ?? '',
'status' => $this->active
]),
'limit' => [ 'limit' => [
'current' => 2000000, 'current' => 2000000,
'total' => 4000000, 'total' => 4000000,
'percentage' => (2000000 / 4000000) * 100 'percentage' => (2000000 / 4000000) * 100
], ],
'status' => $this->active
]; ];
} }
} }

View File

@@ -453,32 +453,19 @@ class MemberEnrollmentService
]); ]);
$memberPolicy->save(); $memberPolicy->save();
// if (!empty($row['division_name'])) { if (!empty($row['division_name'])) {
// $division_id = CorporateDivision::query()->where('code', $row['division_name'])->pluck('id')->first(); $division_id = CorporateDivision::query()->where('code', $row['division_name'])->pluck('id')->first();
// if (empty($division_id)) { if (empty($division_id)) {
// $corporateCodeArray = explode(' ', $row['division_name']); $division = CorporateDivision::query()->updateOrCreate(['name' => $row['division_name'], 'code' => $row['division_name']], [
'corporate_id' => $corporate->id,
'name' => $row['division_name'],
'code' => $row['division_name'],
]);
// if (!empty($corporateCodeArray[1])) { $division_id = $division->id;
// $corporateCode = substr($corporateCodeArray[0], 0, 1) . substr($corporateCodeArray[1], 0, 1); }
// } elseif (!empty($corporateCodeArray[2])) { }
// $corporateCode = substr($corporateCodeArray[0], 0, 1) . substr($corporateCodeArray[1], 0, 1);
// } else {
// $corporateCode = substr($row['division_name'], 0, 1);
// }
// $division = CorporateDivision::updateOrCreate([
// 'corporate_id' => $corporate->id,
// 'code' => $corporateCode
// ], [
// 'corporate_id' => $corporate->id,
// 'name' => $row['division_name'],
// 'code' => $corporateCode,
// ]);
// $division_id = $division->id;
// }
// }
$member->employeds()->create([ $member->employeds()->create([
'corporate_id' => $corporate->id, 'corporate_id' => $corporate->id,

View File

@@ -35,6 +35,8 @@ class Helper
'last_page_url' => '', 'last_page_url' => '',
'links' => $resource->links(null, $resource->items()), 'links' => $resource->links(null, $resource->items()),
'next_page_url' => $resource->nextPageUrl(), 'next_page_url' => $resource->nextPageUrl(),
'per_page' => $resource->perPage(),
'total' => $resource->total()
]; ];
} }

View File

@@ -8,12 +8,15 @@ type Props = {
children: ReactNode; children: ReactNode;
methods: UseFormReturn<any>; methods: UseFormReturn<any>;
onSubmit?: VoidFunction; onSubmit?: VoidFunction;
encType?: string;
}; };
export default function FormProvider({ children, onSubmit, methods }: Props) { export default function FormProvider({ children, onSubmit, methods, encType }: Props) {
return ( return (
<Form {...methods}> <Form {...methods}>
<form onSubmit={onSubmit}>{children}</form> <form onSubmit={onSubmit} encType={encType}>
{children}
</form>
</Form> </Form>
); );
} }

View File

@@ -75,11 +75,12 @@ type AuthProviderProps = {
function AuthProvider({ children }: AuthProviderProps) { function AuthProvider({ children }: AuthProviderProps) {
const [state, dispatch] = useReducer(JWTReducer, initialState); const [state, dispatch] = useReducer(JWTReducer, initialState);
const accessToken = getSession();
useEffect(() => { useEffect(() => {
(async () => { (async () => {
try { try {
const accessToken = getSession(); // const accessToken = getSession();
if (accessToken) { if (accessToken) {
setSession(accessToken); setSession(accessToken);
@@ -113,7 +114,7 @@ function AuthProvider({ children }: AuthProviderProps) {
}); });
} }
})(); })();
}, []); }, [accessToken]);
const login = async (phoneOrEmail: string) => const login = async (phoneOrEmail: string) =>
axios axios

View File

@@ -1,7 +1,7 @@
import { createContext } from 'react'; import { createContext } from 'react';
const UserCurrentCorporateContext = createContext({ const UserCurrentCorporateContext = createContext({
corporateValue: '', corporateValue: '0',
setCorporateValue: (value: string) => Promise<void>, setCorporateValue: (value: string) => Promise<void>,
}); });

View File

@@ -1,6 +1,6 @@
// @mui // @mui
import { styled } from '@mui/material/styles'; import { styled } from '@mui/material/styles';
import { Box, Stack, AppBar, Toolbar } from '@mui/material'; import { Box, Stack, AppBar, Toolbar, Divider } from '@mui/material';
// hooks // hooks
import useOffSetTop from '../../../hooks/useOffSetTop'; import useOffSetTop from '../../../hooks/useOffSetTop';
import useResponsive from '../../../hooks/useResponsive'; import useResponsive from '../../../hooks/useResponsive';
@@ -94,6 +94,7 @@ export default function DashboardHeader({
<Stack direction="row" alignItems="center" spacing={{ xs: 0.5, sm: 1.5 }}> <Stack direction="row" alignItems="center" spacing={{ xs: 0.5, sm: 1.5 }}>
<CorporatePopover /> <CorporatePopover />
<Divider orientation="vertical" flexItem />
<LanguagePopover /> <LanguagePopover />
<NotificationsPopover /> <NotificationsPopover />
<ContactsPopover /> <ContactsPopover />

View File

@@ -60,7 +60,7 @@ export default function DashboardLayout() {
const [corporateValue, setCorporateValue] = useLocalStorage( const [corporateValue, setCorporateValue] = useLocalStorage(
'corporateValue', 'corporateValue',
`${user.corporate.id}` user.corporate ? `${user.corporate.id}` : ''
); );
const value = { corporateValue, setCorporateValue }; const value = { corporateValue, setCorporateValue };

View File

@@ -156,7 +156,6 @@ export default function CardBalance(props: CardBalanceProps) {
openDialog={openDialog} openDialog={openDialog}
setOpenDialog={setOpenDialog} setOpenDialog={setOpenDialog}
title={{ name: dialogTitle }} title={{ name: dialogTitle }}
// data={data?.members}
/> />
)} )}

View File

@@ -15,15 +15,26 @@ import { Search as SearchIcon } from '@mui/icons-material';
import MuiDialog from '../../components/MuiDialog'; import MuiDialog from '../../components/MuiDialog';
import Iconify from '../../components/Iconify'; import Iconify from '../../components/Iconify';
// React // React
import { ReactElement, useRef, useState } from 'react'; import { ReactElement, useContext, useEffect, useRef, useState } from 'react';
import DialogClaimSubmitMemberSubmission from './DialogClaimSubmitMemberSubmission'; import DialogClaimSubmitMemberSubmission from './DialogClaimSubmitMemberSubmission';
import axios from '../../utils/axios';
import { UserCurrentCorporateContext } from '../../contexts/UserCurrentCorporate';
// ---------------------------------------------------------------------- // ----------------------------------------------------------------------
type DataContent = { type DataContentType = {
name: string; id: number;
fullName: string;
memberId: string; memberId: string;
saldo: string; limit: {
current: number;
total: number;
percentage: number;
};
avatar?: {
url?: string;
title?: string;
};
}; };
type MuiDialogProps = { type MuiDialogProps = {
@@ -34,25 +45,11 @@ type MuiDialogProps = {
openDialog: boolean; openDialog: boolean;
setOpenDialog: Function; setOpenDialog: Function;
content?: ReactElement; content?: ReactElement;
data?: DataContent[]; // data?: DataContent[];
}; };
// ---------------------------------------------------------------------- // ----------------------------------------------------------------------
function createData(name: string, memberId: string, saldo: string) {
return { name, memberId, saldo };
}
const rows = [
createData('Alexandra tjoa tri atmaja kurniadi', '0122122', '10.000.000'),
createData('Marina kurniadi', '0122123', '10.000.000'),
createData('Tjoa Indri', '0122124', '10.000.000'),
createData('Atmaja Tirta', '0122125', '10.000.000'),
createData('Alexandra kurniadi', '0122126', '10.000.000'),
];
// ----------------------------------------------------------------------
const BorderLinearProgress = styled(LinearProgress)(({ theme }) => ({ const BorderLinearProgress = styled(LinearProgress)(({ theme }) => ({
height: 10, height: 10,
borderRadius: 6, borderRadius: 6,
@@ -67,42 +64,81 @@ const BorderLinearProgress = styled(LinearProgress)(({ theme }) => ({
// ---------------------------------------------------------------------- // ----------------------------------------------------------------------
const DialogClaimSubmitMember = ({ title, openDialog, setOpenDialog, data }: MuiDialogProps) => { export default function DialogClaimSubmitMember({
/* --------------------------------- Search --------------------------------- */ title,
openDialog,
setOpenDialog,
}: MuiDialogProps) {
const { corporateValue } = useContext(UserCurrentCorporateContext);
const searchInput = useRef<HTMLInputElement>(null); /* ---------------------------------- data ---------------------------------- */
const [searchText, setSearchText] = useState(''); const [data, setData] = useState([]);
const [dataMemberClaim, setDataMemberClaim] = useState({ const [dataMemberClaim, setDataMemberClaim] = useState<DataContentType>({
name: '', id: 0,
fullName: '',
memberId: '', memberId: '',
saldo: '', limit: {
current: 0,
total: 0,
percentage: 0,
},
}); });
/* -------------------------------------------------------------------------- */
const handleSearchChange = (event: any) => { /* --------------------------------- Search --------------------------------- */
const newSearchText = event.target.value ?? ''; const [searchText, setSearchText] = useState('');
setSearchText(newSearchText); const [appliedParams, setAppliedParams] = useState({});
const handleSearchSubmit = async (event: React.FormEvent<HTMLFormElement>) => {
event.preventDefault();
if (searchText === '') {
setAppliedParams({});
} else {
setAppliedParams({ search: searchText });
}
await new Promise((resolve) => setTimeout(resolve, 500));
}; };
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */
/* ---------------------------- Get Current Date ---------------------------- */ /* ---------------------------- Get Current Date ---------------------------- */
const current = new Date(); const current = new Date();
const date = `${current.getDate()} / ${current.getMonth() + 1} / ${current.getFullYear()}`; const date = `${current.getDate()} / ${current.getMonth() + 1} / ${current.getFullYear()}`;
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */
/* ------------------------------ Icon On Click ----------------------------- */ /* ------------------------------ Icon On Click ----------------------------- */
const [openDialogClaimMember, setOpenDialogMemberClaim] = useState(false); const [openDialogClaimMember, setOpenDialogMemberClaim] = useState(false);
const clickHandler = (name: string, memberId: string, saldo: string) => { const clickHandler = ({ id, fullName, memberId, limit, avatar }: DataContentType) => {
setDataMemberClaim({ name: name, memberId: memberId, saldo: saldo }); setDataMemberClaim({
id: id,
fullName: fullName,
memberId: memberId,
limit: {
current: limit.current,
total: limit.total,
percentage: limit.percentage,
},
avatar: {
url: avatar && avatar.url,
title: avatar && avatar.title,
},
});
setOpenDialogMemberClaim(true); setOpenDialogMemberClaim(true);
}; };
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */
useEffect(() => {
(async () => {
if (openDialog === true) {
const response = await axios.get(`${corporateValue}/members`, {
params: { ...appliedParams, claimMember: true },
});
setData(response.data);
}
})();
}, [corporateValue, openDialog, appliedParams]);
const getContent = () => ( const getContent = () => (
<Stack> <Stack>
<Stack direction="row" justifyContent="space-between" alignItems="center" paddingY={1}> <Stack direction="row" justifyContent="space-between" alignItems="center" paddingY={1}>
@@ -112,36 +148,37 @@ const DialogClaimSubmitMember = ({ title, openDialog, setOpenDialog, data }: Mui
<Typography variant="caption">{date}</Typography> <Typography variant="caption">{date}</Typography>
</Stack> </Stack>
</Stack> </Stack>
<TextField <form onSubmit={handleSearchSubmit}>
id="search-input" <TextField
ref={searchInput} id="search-input"
variant="outlined" variant="outlined"
fullWidth fullWidth
onChange={handleSearchChange} onChange={(event) => setSearchText(event?.target.value)}
value={searchText} value={searchText}
InputProps={{ InputProps={{
startAdornment: ( startAdornment: (
<InputAdornment position="start"> <InputAdornment position="start">
<SearchIcon /> <SearchIcon />
</InputAdornment> </InputAdornment>
), ),
}} }}
placeholder="Cari nama atau member ID disini..." placeholder="Cari nama atau member ID disini..."
sx={{ marginTop: 2 }} sx={{ marginTop: 2 }}
/> />
</form>
<Stack marginTop={2} spacing={1}> <Stack marginTop={2} spacing={1}>
{rows.map((row, key) => ( {data.map((row: DataContentType, key) => (
<Card key={key} sx={{ paddingY: 1, paddingX: 2 }}> <Card key={key} sx={{ paddingY: 1, paddingX: 2 }}>
<Stack direction="row" alignItems="center" spacing={2}> <Stack direction="row" alignItems="center" spacing={2}>
<img <img
width={40} width={40}
height={40} height={40}
src="/images/member.png" src={row.avatar ? row.avatar.url : '/images/member.png'}
alt="user-profile" alt={row.avatar ? row.avatar.url : 'user-profile'}
style={{ borderRadius: '50%' }} style={{ borderRadius: '50%' }}
/> />
<Stack sx={{ flex: '45%' }}> <Stack sx={{ flex: '45%' }}>
<Typography variant="subtitle1">{row.name}</Typography> <Typography variant="subtitle1">{row.fullName}</Typography>
<Typography color="#637381" variant="body2" sx={{ fontWeight: 500 }}> <Typography color="#637381" variant="body2" sx={{ fontWeight: 500 }}>
Member ID : {row.memberId} Member ID : {row.memberId}
</Typography> </Typography>
@@ -150,15 +187,31 @@ const DialogClaimSubmitMember = ({ title, openDialog, setOpenDialog, data }: Mui
<Typography color="#0A0A0A" variant="caption"> <Typography color="#0A0A0A" variant="caption">
Total Limit Total Limit
</Typography> </Typography>
<BorderLinearProgress variant="determinate" value={100} /> <BorderLinearProgress
variant="determinate"
value={row.limit && row.limit.percentage}
/>
<Typography variant="subtitle2" sx={{ fontWeight: 500 }}> <Typography variant="subtitle2" sx={{ fontWeight: 500 }}>
{row.saldo} /{' '} {row.limit && row.limit.current} /{' '}
<Typography variant="body2" color="#757575" component="span"> <Typography variant="body2" color="#757575" component="span">
10.000.000 {row.limit && row.limit.total}
</Typography> </Typography>
</Typography> </Typography>
</Stack> </Stack>
<IconButton onClick={() => clickHandler(row.name, row.memberId, row.saldo)}> <IconButton
onClick={() =>
clickHandler({
id: row.id,
fullName: row.fullName,
memberId: row.memberId,
limit: {
current: row.limit.current,
total: row.limit.total,
percentage: row.limit.percentage,
},
})
}
>
<Iconify icon="ic:round-chevron-right" /> <Iconify icon="ic:round-chevron-right" />
</IconButton> </IconButton>
</Stack> </Stack>
@@ -186,6 +239,4 @@ const DialogClaimSubmitMember = ({ title, openDialog, setOpenDialog, data }: Mui
/> />
</> </>
); );
}; }
export default DialogClaimSubmitMember;

View File

@@ -10,28 +10,37 @@ import {
Link, Link,
Switch, Switch,
SwitchProps, SwitchProps,
FormControlLabel, ButtonGroup,
} from '@mui/material'; } from '@mui/material';
import { Add as AddIcon } from '@mui/icons-material'; import { Add as AddIcon, Cancel as CancelIcon } from '@mui/icons-material';
// components // components
import MuiDialog from '../../components/MuiDialog'; import MuiDialog from '../../components/MuiDialog';
import Iconify from '../../components/Iconify'; import Iconify from '../../components/Iconify';
import { FormProvider } from '../../components/hook-form'; import { FormProvider } from '../../components/hook-form';
// React // React
import { ReactElement, useEffect, useRef, useState } from 'react'; import { ReactElement, useEffect, useState } from 'react';
// yup // yup
import * as Yup from 'yup'; import * as Yup from 'yup';
// form // form
import { useForm } from 'react-hook-form'; import { useForm } from 'react-hook-form';
import { yupResolver } from '@hookform/resolvers/yup'; import { yupResolver } from '@hookform/resolvers/yup';
import { LoadingButton } from '@mui/lab'; import { LoadingButton } from '@mui/lab';
import { fSplit } from '../../utils/formatNumber';
// ---------------------------------------------------------------------- /* ---------------------------------- types --------------------------------- */
type DataContentType = {
type DataContent = { id: number;
name: string; fullName: string;
memberId: string; memberId: string;
saldo: string; limit: {
current: number;
total: number;
percentage: number;
};
avatar?: {
url?: string;
title?: string;
};
}; };
type MuiDialogProps = { type MuiDialogProps = {
@@ -42,24 +51,43 @@ type MuiDialogProps = {
openDialog: boolean; openDialog: boolean;
setOpenDialog: Function; setOpenDialog: Function;
content?: ReactElement; content?: ReactElement;
data?: DataContent; data: DataContentType;
}; };
// ---------------------------------------------------------------------- type BorderLinearProgressProps = {
percentage: number;
};
const BorderLinearProgress = styled(LinearProgress)(({ theme }) => ({ type FormValuesProps = {
height: 10, invoice: '';
borderRadius: 6, };
[`&.${linearProgressClasses.colorPrimary}`]: { /* -------------------------------------------------------------------------- */
backgroundColor: theme.palette.grey[theme.palette.mode === 'light' ? 300 : 800],
}, /* --------------------------------- styles --------------------------------- */
[`& .${linearProgressClasses.bar}`]: { const BorderLinearProgress = styled(LinearProgress)<BorderLinearProgressProps>(
({ theme, percentage }) => ({
height: 10,
borderRadius: 6, borderRadius: 6,
background: 'linear-gradient(270deg, #19BBBB 38.42%, #FF9565 76.21%, #FE7253 104.02%)', [`&.${linearProgressClasses.colorPrimary}`]: {
}, backgroundColor: theme.palette.grey[theme.palette.mode === 'light' ? 300 : 800],
})); },
[`& .${linearProgressClasses.bar}`]: {
// ---------------------------------------------------------------------- borderRadius: 6,
background: 'linear-gradient(270deg, #19BBBB 38.42%, #FF9565 76.21%, #FE7253 104.02%)',
'&::before': {
content: '""',
position: 'absolute',
right: 0,
top: 0,
width: `${100 - percentage}%`,
zIndex: 1,
bottom: 0,
background: '#DFE3E8',
},
},
})
);
/* -------------------------------------------------------------------------- */
const DialogClaimSubmitMemberSubmission = ({ const DialogClaimSubmitMemberSubmission = ({
title, title,
@@ -67,64 +95,74 @@ const DialogClaimSubmitMemberSubmission = ({
setOpenDialog, setOpenDialog,
data, data,
}: MuiDialogProps) => { }: MuiDialogProps) => {
/* --------------------------------- Search --------------------------------- */
const searchInput = useRef<HTMLInputElement>(null);
const [searchText, setSearchText] = useState('');
const handleSearchChange = (event: any) => {
const newSearchText = event.target.value ?? '';
setSearchText(newSearchText);
};
/* -------------------------------------------------------------------------- */
/* ---------------------------- Get Current Date ---------------------------- */ /* ---------------------------- Get Current Date ---------------------------- */
const current = new Date(); const current = new Date();
const date = `${current.getDate()} / ${current.getMonth() + 1} / ${current.getFullYear()}`; const date = `${current.getDate()} / ${current.getMonth() + 1} / ${current.getFullYear()}`;
/* -------------------------------------------------------------------------- */
/* ------------------------------- file input ------------------------------- */
// const [multipleImages, setMultipleImages] = useState([]);
// Functions to preview multiple images
// const changeMultipleFiles = (e) => {
// if (e.target.files) {
// const imageArray = Array.from(e.target.files).map((file) => URL.createObjectURL(file));
// setMultipleImages((prevImages) => prevImages.concat(imageArray));
// }
// };
// const render = (data) => {
// data.map((image) => {
// <Typography key={image}>{image}</Typography>;
// });
// };
// const FileForm = (props: any) => (
// <input
// type="file"
// multiple
// {...register('invoice', { required: true })}
// onChange={changeMultipleFiles}
// />
// );
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */
/* ------------------------------- Form Submit ------------------------------ */ /* ------------------------------- Form Submit ------------------------------ */
const ClaimSubmitSchema = Yup.object().shape({
type FormValuesProps = { invoice: Yup.mixed()
topup: string; .required('You need to provide a file')
}; // @ts-ignore
.test('fileSize', 'The file is too large', (value) => {
const TopUpSchema = Yup.object().shape({ for (let index = 0; index < value.length; index++) {
topup: Yup.string(), return value ? value[index].size <= 2000000 : false;
}
}),
}); });
const defaultValues = {
topup: '',
};
const methods = useForm<FormValuesProps>({ const methods = useForm<FormValuesProps>({
resolver: yupResolver(TopUpSchema), resolver: yupResolver(ClaimSubmitSchema),
defaultValues,
}); });
const { const {
register,
reset, reset,
handleSubmit, handleSubmit,
formState: { isSubmitting }, formState: { isSubmitting, errors },
} = methods; } = methods;
useEffect(() => { // const {
if (openDialog === false) { // register,
reset(); // reset,
} // handleSubmit,
}, [openDialog, reset]); // formState: { isSubmitting },
// } = useForm({ resolver: yupResolver(ClaimSubmitSchema) });
const onSubmit = async (data: FormValuesProps) => { const onSubmit = ({ invoice }: FormValuesProps) => {
reset(); // console.log(invoice);
}; };
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */
/* ---------------------------- Ios Switch Style ---------------------------- */ /* ---------------------------- Ios Switch Style ---------------------------- */
const IosSwitch = styled((props: SwitchProps) => ( const IosSwitch = styled((props: SwitchProps) => (
<Switch focusVisibleClassName=".Mui-focusVisible" disableRipple {...props} /> <Switch focusVisibleClassName=".Mui-focusVisible" disableRipple {...props} />
))(({ theme }) => ({ ))(({ theme }) => ({
@@ -171,9 +209,14 @@ const DialogClaimSubmitMemberSubmission = ({
}), }),
}, },
})); }));
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */
useEffect(() => {
if (openDialog === false) {
reset();
}
}, [openDialog, reset]);
const getContent = () => ( const getContent = () => (
<Stack> <Stack>
<Stack direction="row" justifyContent="space-between" alignItems="center" paddingY={1}> <Stack direction="row" justifyContent="space-between" alignItems="center" paddingY={1}>
@@ -193,7 +236,7 @@ const DialogClaimSubmitMemberSubmission = ({
style={{ borderRadius: '50%' }} style={{ borderRadius: '50%' }}
/> />
<Stack sx={{ flex: '45%' }}> <Stack sx={{ flex: '45%' }}>
<Typography variant="subtitle1">{data && data.name}</Typography> <Typography variant="subtitle1">{data && data.fullName}</Typography>
<Typography color="#637381" variant="body2" sx={{ fontWeight: 500 }}> <Typography color="#637381" variant="body2" sx={{ fontWeight: 500 }}>
Member ID : {data && data.memberId} Member ID : {data && data.memberId}
</Typography> </Typography>
@@ -206,15 +249,19 @@ const DialogClaimSubmitMemberSubmission = ({
<Typography color="#0A0A0A" variant="caption"> <Typography color="#0A0A0A" variant="caption">
Total Limit Total Limit
</Typography> </Typography>
<Link variant="caption" textAlign="center" href=""> <Link variant="caption" textAlign="center" href="#">
Details Benefits <Iconify icon="ic:round-chevron-right" /> Details Benefits <Iconify icon="ic:round-chevron-right" />
</Link> </Link>
</Stack> </Stack>
<BorderLinearProgress variant="determinate" value={100} /> <BorderLinearProgress
variant="determinate"
value={100}
percentage={data && data.limit ? data.limit.percentage : 100}
/>
<Typography variant="subtitle2" sx={{ fontWeight: 500 }}> <Typography variant="subtitle2" sx={{ fontWeight: 500 }}>
{data && data.saldo} /{' '} {fSplit(data && data.limit ? data.limit.current : 0)} /{' '}
<Typography variant="body2" color="#757575" component="span"> <Typography variant="body2" color="#757575" component="span">
10.000.000 {fSplit(data && data.limit ? data.limit.total : 0)}
</Typography> </Typography>
</Typography> </Typography>
</Stack> </Stack>
@@ -228,20 +275,11 @@ const DialogClaimSubmitMemberSubmission = ({
Real invoice required Real invoice required
</Typography> </Typography>
</Stack> </Stack>
<Card> <input {...register('invoice')} type="file" />
<Button {errors.invoice && errors.invoice.message ? <p>{errors.invoice.message}</p> : ''}
variant="outlined"
startIcon={<AddIcon />}
component="label"
sx={{ border: 'none', paddingY: 2, width: '100%', ':hover': { border: 'none' } }}
>
Add Invoice
<input name="invoice" hidden accept="image/*" multiple type="file" />
</Button>
</Card>
</Stack> </Stack>
{/* Prescription */} {/* Prescription */}
<Stack marginTop={2} spacing={1}> {/* <Stack marginTop={2} spacing={1}>
<Stack direction="row" justifyContent="space-between" alignItems="center"> <Stack direction="row" justifyContent="space-between" alignItems="center">
<Stack> <Stack>
<Typography variant="subtitle2"> <Typography variant="subtitle2">
@@ -268,20 +306,10 @@ const DialogClaimSubmitMemberSubmission = ({
</Typography> </Typography>
</Stack> </Stack>
</Stack> </Stack>
<Card> <ImportForm label="Add Prescription" />
<Button </Stack> */}
variant="outlined"
startIcon={<AddIcon />}
component="label"
sx={{ border: 'none', paddingY: 2, width: '100%', ':hover': { border: 'none' } }}
>
Add Prescription
<input name="invoice" hidden accept="image/*" multiple type="file" />
</Button>
</Card>
</Stack>
{/* Laboratory */} {/* Laboratory */}
<Stack marginTop={2} spacing={1}> {/* <Stack marginTop={2} spacing={1}>
<Stack direction="row" justifyContent="space-between" alignItems="center"> <Stack direction="row" justifyContent="space-between" alignItems="center">
<Stack> <Stack>
<Typography variant="subtitle2"> <Typography variant="subtitle2">
@@ -308,18 +336,9 @@ const DialogClaimSubmitMemberSubmission = ({
</Typography> </Typography>
</Stack> </Stack>
</Stack> </Stack>
<Card> <ImportForm label="Add Result" />
<Button </Stack> */}
variant="outlined" {/* Submit */}
startIcon={<AddIcon />}
component="label"
sx={{ border: 'none', paddingY: 2, width: '100%', ':hover': { border: 'none' } }}
>
Add Result
<input name="invoice" hidden accept="image/*" multiple type="file" />
</Button>
</Card>
</Stack>
<Stack marginTop={1}> <Stack marginTop={1}>
<LoadingButton <LoadingButton
fullWidth fullWidth

View File

@@ -76,9 +76,9 @@ const DialogTopUpLimit = ({ title, openDialog, setOpenDialog, data }: MuiDialogP
const TopUpSchema = Yup.object().shape({ const TopUpSchema = Yup.object().shape({
topup: Yup.number(), topup: Yup.number(),
// /* /*
// // @ts-ignore */ // @ts-ignore */
// .test('limit', 'Maximum Top Up Rp. 5.000.000', (val) => (val > 5000000 ? false : true)), // .test('limit', 'Maximum Top Up Rp. 5.000.000', (val) => (val > 5000000 ? false : true)),
}); });
const defaultValues = { const defaultValues = {
@@ -87,6 +87,7 @@ const DialogTopUpLimit = ({ title, openDialog, setOpenDialog, data }: MuiDialogP
const methods = useForm<FormValuesProps>({ const methods = useForm<FormValuesProps>({
resolver: yupResolver(TopUpSchema), resolver: yupResolver(TopUpSchema),
// @ts-ignore
defaultValues, defaultValues,
}); });
@@ -110,6 +111,7 @@ const DialogTopUpLimit = ({ title, openDialog, setOpenDialog, data }: MuiDialogP
const onCheckHandler = (data: FormValuesProps) => { const onCheckHandler = (data: FormValuesProps) => {
setIsDisabledCheckbox(!isDisabledCheckbox); setIsDisabledCheckbox(!isDisabledCheckbox);
setIsDisabledButton(false); setIsDisabledButton(false);
// @ts-ignore
setValue('topup', testData.totalLimit - testData.myLimit); setValue('topup', testData.totalLimit - testData.myLimit);
}; };

View File

@@ -262,14 +262,13 @@ export default function TableList(props: any) {
await new Promise((resolve) => setTimeout(resolve, 500)); await new Promise((resolve) => setTimeout(resolve, 500));
setAppliedParams(params); setAppliedParams(params);
setIsLoading(false); setIsLoading(false);
// setSearchParams.set('page', newPage + 1);
}; };
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */
/* --------------------------- row page per limit --------------------------- */ /* --------------------------- row page per limit --------------------------- */
const onRowsPerPageChangeHandle = async (event: React.ChangeEvent<HTMLInputElement>) => { const onRowsPerPageChangeHandle = async (event: React.ChangeEvent<HTMLInputElement>) => {
setIsLoading(true); setIsLoading(true);
setPage(0); searchParams.delete('page');
const params = Object.fromEntries([ const params = Object.fromEntries([
...searchParams.entries(), ...searchParams.entries(),
['per_page', parseInt(event.target.value, 10)], ['per_page', parseInt(event.target.value, 10)],
@@ -294,13 +293,13 @@ export default function TableList(props: any) {
: Object.fromEntries([...searchParams.entries(), ['order', order], ['orderBy', orderBy]]); : Object.fromEntries([...searchParams.entries(), ['order', order], ['orderBy', orderBy]]);
const corporateMembers = await axios.get(`${corporateValue}/members`, { const corporateMembers = await axios.get(`${corporateValue}/members`, {
params, params: { ...params, claimMember: false },
}); });
setSearchParams(params); setSearchParams(params);
setDataTable(corporateMembers.data.data); setDataTable(corporateMembers.data.data);
// setPaginationTable(response.data.meta); setPaginationTable(corporateMembers.data);
// setRowsPerPage(response.data.meta.per_page); setRowsPerPage(corporateMembers.data.per_page);
setIsLoading(false); setIsLoading(false);
})(); })();
}, [appliedParams, searchParams, order, orderBy, setSearchParams, corporateValue]); }, [appliedParams, searchParams, order, orderBy, setSearchParams, corporateValue]);