upload foto, dan bugs import

This commit is contained in:
pajri
2022-12-21 17:22:45 +07:00
parent 88ad144921
commit b1c908a6f6
12 changed files with 576 additions and 169 deletions

View File

@@ -18,6 +18,8 @@ use Illuminate\Http\Request;
use Illuminate\Routing\Controller;
use Maatwebsite\Excel\Facades\Excel;
use Box\Spout\Reader\Common\Creator\ReaderEntityFactory;
use App\Models\File;
use Illuminate\Support\Facades\Storage;
use Modules\Internal\Services\CorporateService;
@@ -220,6 +222,18 @@ class CorporateController extends Controller
$managerOne = User::where('email', 'manager+one@gmail.com')->first();
$managerOne->managedCorporates()->attach($newCorporate);
if ($request->hasFile('logo')) {
$pathFileAvatar = File::storeFile('avatar', $newCorporate->id, $request->file('logo'));
$newCorporate->files()->updateOrCreate([
'type' => 'avatar',
'name' => File::getFileName('avatar', $newCorporate->id, $request->file('logo')),
'extension' => $request->file('logo')->getClientOriginalExtension(),
'path' => $pathFileAvatar,
'created_by' => auth()->user()->id,
'updated_by' => auth()->user()->id,
]);
}
DB::commit();
} catch (\Exception $e) {
@@ -282,9 +296,13 @@ class CorporateController extends Controller
try {
DB::beginTransaction();
//karena pake formdata
$linkingRules = $request->linking_rules;
$linkingRules = explode(',', $linkingRules);
$corporate = Corporate::findOrFail($id);
$corporate->fill($request->toArray());
$corporate->fill($request->all());
$corporate->linking_rules = $linkingRules;
$corporate->save();
$corporate->policies()->updateOrCreate(
@@ -304,6 +322,19 @@ class CorporateController extends Controller
]
);
if ($request->hasFile('logo')) {
$pathFileAvatar = File::storeFile('avatar', $corporate->id, $request->file('logo'));
$corporate->files()->updateOrCreate([
'type' => 'avatar',
'name' => File::getFileName('avatar', $corporate->id, $request->file('logo')),
'extension' => $request->file('logo')->getClientOriginalExtension(),
'path' => $pathFileAvatar,
'created_by' => auth()->user()->id,
'updated_by' => auth()->user()->id,
]);
}
DB::commit();
} catch (\Exception $e) {
DB::rollBack();

View File

@@ -10,7 +10,7 @@ use App\Models\Plan;
use Box\Spout\Writer\Common\Creator\WriterEntityFactory;
class CorporateService
{
{
protected function validatePlanRow($row)
{
if (empty($row['service_code'])) {
@@ -84,12 +84,16 @@ class CorporateService
public function handleBenefitRow(Corporate $corporate, $row)
{
try {
$benefit_data = $row;
$benefit_data["corporate_id"] = $corporate->id;
$this->validateBenefitRow($benefit_data);
$plan = $corporate->plans->where('corporate_plan_id', $benefit_data['plan_code'])->first();
$plan = Plan::where('corporate_plan_id', $benefit_data['plan_code'])->first();
// $corporate->plans->where('corporate_plan_id', $benefit_data['plan_code'])->first();
$benefit_data['plan_code'] = $plan->id;
$benefit = Benefit::updateOrCreate([
@@ -104,11 +108,11 @@ class CorporateService
$corporateBenefit = $corporate->corporateBenefits()->updateOrCreate([
'benefit_id' => $benefit->id,
'plan_id' => $plan->id
], $benefit_data );
], $benefit_data);
return $corporateBenefit;
} catch (\Exception $e) {
dd($e->getMessage());
// dd($e->getMessage());
throw $e;
}
}

View File

@@ -362,8 +362,8 @@ class MemberEnrollmentService
"nik" => $row['nik'] ?? null,
"birth_date" => Carbon::parse(strtotime($row['date_of_birth'])),
"gender" => Helper::genderNormalization($row['sex']),
"language" => $row['language'] ?? null,
"race" => $row['race'] ?? null,
// "language" => $row['language'] ?? null,
// "race" => $row['race'] ?? null,
"marital_status" => $row['marital_status'] ?? null,
"record_type" => $row['record_type'] ?? null,
"principal_id" => $row['principal_id'] ?? null,
@@ -429,15 +429,6 @@ class MemberEnrollmentService
]), 0, null, $row);
} else {
$member = new Member();
$person = Person::create([
'name' => $row['name'],
'birth_date' => Carbon::parse(strtotime($row['date_of_birth'])),
'gender' => Helper::genderPerson($row['sex']),
'language' => $row['language'] ?? null,
'race' => $row['race'] ?? null,
]);
$member->person_id = $person->id;
$member->save();
}
$memberPolicy = $member->policies()
@@ -463,10 +454,22 @@ class MemberEnrollmentService
$this->validateRow($row);
try {
DB::beginTransaction();
$member->fill($member_data);
if ($member->save()) {
$person = Person::create([
'name' => $row['name'],
'birth_date' => Carbon::parse(strtotime($row['date_of_birth'])),
'gender' => Helper::genderPerson($row['sex']),
'language' => $row['language'] ?? null,
'race' => $row['race'] ?? null,
]);
$member->person_id = $person->id;
$member->save();
$memberPolicy = new MemberPolicy();
$memberPolicy->fill([
'member_id' => $member->member_id,

View File

@@ -8,10 +8,10 @@ use Throwable;
class ImportRowException extends Exception
{
protected $data = null;
public function __construct($message, $code = 0, Throwable $previous = null, $data)
{
parent::__construct($message, $code, $previous);
parent::__construct($message, (int)$code, $previous);
$this->data = $data;
}

View File

@@ -26,6 +26,10 @@ class Corporate extends Model
'linking_rules' => 'array',
];
protected $appends = [
'avatar_url',
];
public function imports()
{
return $this->morphMany(ImportLog::class, 'importable');
@@ -36,6 +40,16 @@ class Corporate extends Model
return $this->morphMany(File::class, 'fileable');
}
public function avatar()
{
return $this->morphOne(File::class, 'fileable')->where('type', 'avatar')->latest();
}
public function getAvatarUrlAttribute()
{
return $this->avatar ? $this->avatar->url : null;
}
public function plans()
{
return $this->hasMany(Plan::class, 'corporate_id', 'id');

View File

@@ -22,6 +22,8 @@ class Person extends Model
'gender',
'birth_date',
'birth_place',
'language',
'race',
'citizenship',
'current_employment',
'last_education',

View File

@@ -0,0 +1,93 @@
import React, { Dispatch, FunctionComponent, useCallback, useState } from 'react';
import { useDropzone } from 'react-dropzone';
import { Box, Stack, Typography } from '@mui/material';
import BlockContent from './upload/BlockContent';
import { styled } from '@mui/material/styles';
import { UploadIllustration } from '../assets';
const DropZoneStyle = styled('div')(({ theme }) => ({
outline: 'none',
overflow: 'hidden',
position: 'relative',
padding: theme.spacing(5, 1),
borderRadius: theme.shape.borderRadius,
transition: theme.transitions.create('padding'),
// backgroundColor: theme.palette.background.neutral,
backgroundColor: '#ffffff',
border: `2px dashed ${theme.palette.grey[500_32]}`,
'&:hover': { cursor: 'pointer', backgroundColor: '#f7f7f7' },
}));
const MyDropzone: FunctionComponent<{
setFile: Dispatch<any>;
currentImage: string;
}> = ({
setFile,
currentImage,
// onChanges,
}) => {
const onDrop = useCallback((acceptedFiles) => {
// Do something with the files
console.log(acceptedFiles);
setFile(acceptedFiles[0]);
setImage(acceptedFiles[0]);
// onChanges(acceptedFiles[0]);
}, []);
const { getRootProps, getInputProps, isDragActive, isDragReject } = useDropzone({
onDrop,
multiple: false,
});
const [image, setImage] = useState<File | null>(null);
return (
<DropZoneStyle
{...getRootProps()}
sx={{
...(isDragActive && { opacity: 2.72 }),
}}
>
<input {...getInputProps()} />
<Stack
spacing={2}
alignItems="center"
justifyContent="center"
direction={{ xs: 'column', md: 'row' }}
sx={{ width: 1, textAlign: { xs: 'center', md: 'left' } }}
>
{image ? (
<img src={URL.createObjectURL(image)} alt="preview" width={220} />
) : currentImage ? (
<img src={currentImage} alt="preview" width={220} />
) : (
<UploadIllustration sx={{ width: 220 }} />
)}
<Box sx={{ p: 3 }}>
<Typography gutterBottom variant="h5">
Pilih Foto
</Typography>
<Typography variant="body2" sx={{ color: 'text.secondary' }}>
Letakkan foto disini atau klik jelajahi &nbsp;
<Typography
variant="body2"
component="span"
sx={{ color: 'primary.main', textDecoration: 'underline' }}
>
jelajahi
</Typography>
&nbsp;foto di perangkat Anda
</Typography>
</Box>
</Stack>
{/* <BlockContent file={image} /> */}
{isDragReject && <p>Unsupported file type...</p>}
</DropZoneStyle>
);
};
export default MyDropzone;

View File

@@ -0,0 +1,128 @@
import React, { Dispatch, FunctionComponent, useCallback, useState } from 'react';
import { useDropzone } from 'react-dropzone';
import { Box, Stack, Typography } from '@mui/material';
import BlockContent from './upload/BlockContent';
import { styled } from '@mui/material/styles';
import { UploadIllustration } from '../assets';
import Iconify from './Iconify';
const RootStyle = styled('div')(({ theme }) => ({
width: 144,
height: 144,
margin: 'auto',
borderRadius: '50%',
padding: theme.spacing(1),
border: `2px dashed ${theme.palette.grey[500_32]}`,
}));
const DropZoneStyle = styled('div')({
zIndex: 0,
width: '100%',
height: '100%',
outline: 'none',
display: 'flex',
overflow: 'hidden',
borderRadius: '50%',
position: 'relative',
alignItems: 'center',
justifyContent: 'center',
'& > *': { width: '100%', height: '100%' },
'&:hover': {
cursor: 'pointer',
'& .placeholder': {
zIndex: 9,
},
},
});
const PlaceholderStyle = styled('div')(({ theme }) => ({
display: 'flex',
position: 'absolute',
alignItems: 'center',
flexDirection: 'column',
justifyContent: 'center',
color: theme.palette.text.secondary,
// backgroundColor: theme.palette.background.neutral,
transition: theme.transitions.create('opacity', {
easing: theme.transitions.easing.easeInOut,
duration: theme.transitions.duration.shorter,
}),
'&:hover': { opacity: 0.72 },
}));
const UploadImage: FunctionComponent<{
setFile: Dispatch<any>;
currentImage: string;
}> = ({ setFile, currentImage, setSave, error, file, helperText, sx, ...other }) => {
const onDrop = useCallback(
(acceptedFiles) => {
// Do something with the files
console.log(acceptedFiles);
setFile(acceptedFiles[0]);
setImage(acceptedFiles[0]);
},
[setFile, setSave]
);
const { getRootProps, getInputProps, isDragActive, isDragReject } = useDropzone({
onDrop,
multiple: false,
});
const [image, setImage] = useState<File | null>(null);
return (
<RootStyle
sx={{
...((isDragReject || error) && {
borderColor: 'error.light',
}),
...sx,
}}
>
<DropZoneStyle
{...getRootProps()}
sx={{
...(isDragActive && { opacity: 2.72 }),
}}
>
<input {...getInputProps()} />
{/* <Stack
spacing={2}
alignItems="center"
justifyContent="center"
direction={{ xs: 'column', md: 'row' }}
sx={{ width: 1, textAlign: { xs: 'center', md: 'left' } }}
> */}
{image ? (
<img src={URL.createObjectURL(image)} alt="preview" width={220} />
) : currentImage ? (
<img src={currentImage} alt="preview" width={220} />
) : (
<PlaceholderStyle
className="placeholder"
sx={{
...((isDragReject || error) && {
bgcolor: 'error.lighter',
}),
}}
>
<Iconify icon={'ic:round-add-a-photo'} sx={{ width: 24, height: 24, mb: 1 }} />
<Typography variant="caption">{image ? 'Update photo' : 'Upload photo'}</Typography>
</PlaceholderStyle>
)}
<PlaceholderStyle className="placeholder">
<Iconify icon={'ic:round-add-a-photo'} sx={{ width: 24, height: 24, mb: 1 }} />
<Typography variant="caption">{image ? 'Update photo' : 'Upload photo'}</Typography>
</PlaceholderStyle>
{/* </Stack> */}
{/* <BlockContent file={image} /> */}
{isDragReject && <p>Unsupported file type...</p>}
</DropZoneStyle>
</RootStyle>
);
};
export default UploadImage;

View File

@@ -1,10 +1,18 @@
// form
import { useFormContext, Controller } from 'react-hook-form';
import * as React from 'react';
// @mui
import { TextField, TextFieldProps } from '@mui/material';
import { IconButton, TextField, TextFieldProps } from '@mui/material';
import { LocalizationProvider, MobileDatePicker } from '@mui/x-date-pickers';
import { AdapterDateFns } from '@mui/x-date-pickers/AdapterDateFns';
import { DesktopDatePicker } from '@mui/x-date-pickers/DesktopDatePicker';
import InputAdornment from '@mui/material/InputAdornment';
import EventIcon from '@mui/icons-material/Event';
import { fPostFormat } from '../../utils/formatTime';
// ----------------------------------------------------------------------
interface IProps {
@@ -13,19 +21,43 @@ interface IProps {
export default function RHFDatepicker({ name, ...other }: IProps & TextFieldProps) {
const { control } = useFormContext();
return (
<Controller
name={name}
control={control}
render={({ field, fieldState: { error } }) => (
<LocalizationProvider dateAdapter={AdapterDateFns}>
<MobileDatePicker
inputFormat="yyyy-MM-dd"
value={field.value}
onChange={field.onChange}
renderInput={(field) => <TextField {...field} fullWidth error={!!error} helperText={error?.message} {...other} />}
onChange={(value) => {
field.onChange(fPostFormat(value));
}}
renderInput={(field) => (
<TextField
{...field}
fullWidth
InputProps={{
endAdornment: (
<InputAdornment position="end">
<EventIcon />
</InputAdornment>
),
}}
error={!!error}
helperText={error?.message}
{...other}
/>
)}
/>
{/* <DesktopDatePicker
value={field.value}
onChange={(value) => {
field.onChange(fPostFormat(value));
}}
renderInput={(params) => <TextField {...params} fullWidth />}
/> */}
</LocalizationProvider>
)}
/>

View File

@@ -26,7 +26,6 @@ export function RHFUploadAvatar({ name, ...other }: Props) {
control={control}
render={({ field, fieldState: { error } }) => {
const checkError = !!error && !field.value;
return (
<div>
<UploadAvatar error={checkError} {...other} file={field.value} />

View File

@@ -42,6 +42,7 @@ import { Corporate } from '../../@types/corporates';
import axios from '../../utils/axios';
import { fCurrency } from '../../utils/formatNumber';
import RHFAutocomplete from '../../components/hook-form/RHFAutocomplete';
import UploadImage from '../../components/UploadImage';
const LabelStyle = styled(Typography)(({ theme }) => ({
...theme.typography.subtitle2,
@@ -61,7 +62,7 @@ type Props = {
export default function CorporateForm({ isEdit, currentCorporate }: Props) {
const navigate = useNavigate();
const [corporate_groups, setCorporateGroups] = useState([])
const [corporate_groups, setCorporateGroups] = useState([]);
// const [ errors, setErrors ] = useState<{ [key: string]: string }>({});
@@ -72,10 +73,10 @@ export default function CorporateForm({ isEdit, currentCorporate }: Props) {
code: Yup.string().required('Corporate Code is required'),
active: Yup.boolean().required('Corporate Status is required'),
type: Yup.string().required('Type is required'),
parent_id: Yup.string().when("type", {
parent_id: Yup.string().when('type', {
is: 'subcorporate',
then: Yup.string().required("Corporate is required because type is Sub Corporate")
})
then: Yup.string().required('Corporate is required because type is Sub Corporate'),
}),
});
const defaultValues = useMemo(
@@ -88,16 +89,20 @@ export default function CorporateForm({ isEdit, currentCorporate }: Props) {
policy_id: currentCorporate?.current_policy?.id || '',
policy_code: currentCorporate?.current_policy?.code || '',
policy_total_premi: currentCorporate?.current_policy?.total_premi || 0,
policy_minimal_deposit_percentage: currentCorporate?.current_policy?.minimal_deposit_percentage || 50,
policy_minimal_deposit_percentage:
currentCorporate?.current_policy?.minimal_deposit_percentage || 50,
policy_minimal_deposit_net: currentCorporate?.current_policy?.minimal_deposit_net || 0,
policy_minimal_alert_percentage: currentCorporate?.current_policy?.minimal_alert_percentage || 25,
policy_minimal_alert_percentage:
currentCorporate?.current_policy?.minimal_alert_percentage || 25,
policy_minimal_alert_net: currentCorporate?.current_policy?.minimal_alert_net || 0,
policy_stop_service_percentage: currentCorporate?.current_policy?.minimal_stop_service_percentage || 25,
policy_stop_service_percentage:
currentCorporate?.current_policy?.minimal_stop_service_percentage || 25,
policy_stop_service_net: currentCorporate?.current_policy?.minimal_stop_service_net || 0,
policy_start: currentCorporate?.current_policy?.start || '',
policy_end: currentCorporate?.current_policy?.end || '',
linking_rules: currentCorporate?.linking_rules || ['nrik', 'nik', 'member_id'],
type: currentCorporate?.type || 'corporate'
type: currentCorporate?.type || 'corporate',
logo: currentCorporate?.logo || '',
}),
// eslint-disable-next-line react-hooks/exhaustive-deps
[currentCorporate]
@@ -129,35 +134,65 @@ export default function CorporateForm({ isEdit, currentCorporate }: Props) {
reset(defaultValues);
}
axios.get('/corporates/create')
axios
.get('/corporates/create')
.then((res) => {
setCorporateGroups(res.data.corporate_groups)
setCorporateGroups(res.data.corporate_groups);
})
.catch((err) => {
enqueueSnackbar("Opps, failed to get Corporate Group List", { variant: 'error' })
})
enqueueSnackbar('Opps, failed to get Corporate Group List', { variant: 'error' });
});
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [isEdit, currentCorporate]);
const currentImage = currentCorporate?.avatar_url;
const [file, setFile] = useState(null);
const [save, setSave] = useState(null);
console.log('save', save);
const onSubmit = async (data: FormValuesProps) => {
try {
const formData = new FormData();
formData.append('logo', file);
formData.append('name', data.name);
formData.append('code', data.code);
formData.append('active', data.active ? '1' : '0');
formData.append('type', data.type);
formData.append('welcome_message', data.welcome_message);
formData.append('help_text', data.help_text);
formData.append('policy_id', data.policy_id);
formData.append('policy_code', data.policy_code);
formData.append('policy_total_premi', data.policy_total_premi);
formData.append('policy_minimal_deposit_percentage', data.policy_minimal_deposit_percentage);
formData.append('policy_minimal_deposit_net', data.policy_minimal_deposit_net);
formData.append('policy_minimal_alert_percentage', data.policy_minimal_alert_percentage);
formData.append('policy_minimal_alert_net', data.policy_minimal_alert_net);
formData.append('policy_stop_service_percentage', data.policy_stop_service_percentage);
formData.append('policy_stop_service_net', data.policy_stop_service_net);
formData.append('policy_start', data.policy_start);
formData.append('policy_end', data.policy_end);
formData.append('linking_rules', data.linking_rules);
if (!isEdit) {
const response = await axios.post('/corporates', data);
const response = await axios.post('/corporates', formData);
} else {
const response = await axios.put('/corporates/' + currentCorporate?.id ?? '', data);
formData.append('_method', 'PUT');
const response = await axios.post(`/corporates/${currentCorporate?.id}`, formData);
}
reset();
enqueueSnackbar(!isEdit ? 'Corporate Created Successfully!' : 'Corporate Udpated Successfully!', { variant: 'success' });
enqueueSnackbar(
!isEdit ? 'Corporate Created Successfully!' : 'Corporate Udpated Successfully!',
{ variant: 'success' }
);
navigate('/corporates');
} catch (error: any) {
if (error && error.response.status === 422) {
for (const [key, value] of Object.entries(error.response.data.errors)) {
for (const [key, value] of Object.entries(error.response.data.errors)) {
setError(key, { message: value[0] });
enqueueSnackbar(value[0] ?? 'Failed Processing Request', { variant: 'error' });
}
}
else {
} else {
enqueueSnackbar(error.message ?? 'Failed Processing Request', { variant: 'error' });
}
}
@@ -183,100 +218,103 @@ export default function CorporateForm({ isEdit, currentCorporate }: Props) {
// Only Handle Change on Policy Total Premi
useEffect(() => {
let calc_policy_minimal_deposit_net = values.policy_total_premi * values.policy_minimal_deposit_percentage / 100;
let calc_policy_minimal_deposit_net =
(values.policy_total_premi * values.policy_minimal_deposit_percentage) / 100;
setValue('policy_minimal_deposit_net', calc_policy_minimal_deposit_net);
let calc_policy_minimal_alert_net = values.policy_total_premi * values.policy_minimal_alert_percentage / 100;
let calc_policy_minimal_alert_net =
(values.policy_total_premi * values.policy_minimal_alert_percentage) / 100;
setValue('policy_minimal_alert_net', calc_policy_minimal_alert_net);
let calc_policy_stop_service_net = values.policy_total_premi * values.policy_stop_service_percentage / 100;
let calc_policy_stop_service_net =
(values.policy_total_premi * values.policy_stop_service_percentage) / 100;
setValue('policy_stop_service_net', calc_policy_stop_service_net);
}, [values.policy_total_premi]);
// Only Handle on Change Policy Minimal Deposit
const handleMinimalDepositNetChange = (e) => {
setValue('policy_minimal_deposit_net', e.target.value);
setValue('policy_minimal_deposit_percentage', e.target.value / values.policy_total_premi * 100);
}
setValue(
'policy_minimal_deposit_percentage',
(e.target.value / values.policy_total_premi) * 100
);
};
const handleMinimalDepositPercentageChange = (e) => {
setValue('policy_minimal_deposit_percentage', e.target.value);
setValue('policy_minimal_deposit_net', values.policy_total_premi * e.target.value / 100);
}
setValue('policy_minimal_deposit_net', (values.policy_total_premi * e.target.value) / 100);
};
// Only Handle on Change Minimal Alert
const handleMinimalAlertNetChange = (e) => {
setValue('policy_minimal_alert_net', e.target.value);
setValue('policy_minimal_alert_percentage', e.target.value / values.policy_total_premi * 100);
}
setValue('policy_minimal_alert_percentage', (e.target.value / values.policy_total_premi) * 100);
};
const handleMinimalAlertPercentageChange = (e) => {
setValue('policy_minimal_alert_percentage', e.target.value);
setValue('policy_minimal_alert_net', values.policy_total_premi * e.target.value / 100);
}
setValue('policy_minimal_alert_net', (values.policy_total_premi * e.target.value) / 100);
};
// Only Handle on Change Minimum Stop Service
const handleStopServiceNetChange = (e) => {
setValue('policy_stop_service_net', e.target.value);
setValue('policy_stop_service_percentage', e.target.value / values.policy_total_premi * 100);
}
setValue('policy_stop_service_percentage', (e.target.value / values.policy_total_premi) * 100);
};
const handleStopServicePercentageChange = (e) => {
setValue('policy_stop_service_percentage', e.target.value);
setValue('policy_stop_service_net', values.policy_total_premi * e.target.value / 100);
}
setValue('policy_stop_service_net', (values.policy_total_premi * e.target.value) / 100);
};
const linking_rules_checkbox_name = "linking_rules"
const linking_rules_checkbox_name = 'linking_rules';
const linking_tools = [
{
"value" : "nrik",
"label" : "No. KTP"
value: 'nrik',
label: 'No. KTP',
},
{
"value" : "nik",
"label" : "Nomor Induk Karyawan (NIK)"
value: 'nik',
label: 'Nomor Induk Karyawan (NIK)',
},
{
"value" : "member_id",
"label" : "Member ID"
value: 'member_id',
label: 'Member ID',
},
{
"value" : "phone",
"label" : "Nomor Telepon"
value: 'phone',
label: 'Nomor Telepon',
},
{
"value" : "email",
"label" : "E-Mail"
value: 'email',
label: 'E-Mail',
},
]
];
const types = [
{
"value" : "corporate",
"label" : "Corporate"
value: 'corporate',
label: 'Corporate',
},
{
"value" : "subcorporate",
"label" : "Sub Corporate"
value: 'subcorporate',
label: 'Sub Corporate',
},
]
];
const options = [
{
"label" : "Something",
"id" : "Something"
label: 'Something',
id: 'Something',
},
{
"label" : "Syalalalal",
"id" : "Syalalalal"
label: 'Syalalalal',
id: 'Syalalalal',
},
{
"label" : "Lilili",
"id" : "Lilili"
label: 'Lilili',
id: 'Lilili',
},
]
];
const handleTypeChange = (event: SelectChangeEvent) => {
setValue('type', event.target.value)
}
setValue('type', event.target.value);
};
return (
<FormProvider methods={methods} onSubmit={handleSubmit(onSubmit)}>
@@ -285,7 +323,9 @@ export default function CorporateForm({ isEdit, currentCorporate }: Props) {
<Grid item xs={12} md={8}>
<Card sx={{ p: 3 }}>
<Stack spacing={3}>
<Grid item xs={12}><Typography variant='h5'>Corporate Profile</Typography></Grid>
<Grid item xs={12}>
<Typography variant="h5">Corporate Profile</Typography>
</Grid>
<RHFSelect name="type" label="Type" placeholder="Type">
<option value="" />
@@ -295,30 +335,40 @@ export default function CorporateForm({ isEdit, currentCorporate }: Props) {
</option>
))}
</RHFSelect>
{/* // TODO Use Autocomplete */}
{( values.type == 'subcorporate' && <RHFSelect name="parent_id" label="Parent Corporate Group" placeholder="Parent Corporate Group">
<option value="" />
{corporate_groups
.filter((option) => option.value != values.id)
.map((option, index) => (
<option key={index} value={option.value}>
{option.label}
</option>
))}
</RHFSelect> )}
{values.type == 'subcorporate' && (
<RHFSelect
name="parent_id"
label="Parent Corporate Group"
placeholder="Parent Corporate Group"
>
<option value="" />
{corporate_groups
.filter((option) => option.value != values.id)
.map((option, index) => (
<option key={index} value={option.value}>
{option.label}
</option>
))}
</RHFSelect>
)}
<RHFTextField name="code" label="Corporate Code" />
<RHFTextField name="name" label="Corporate Name" />
<Stack spacing={1}>
<Typography variant='subtitle2' sx={{ color: "text.secondary" }}>Welcome Message</Typography>
<Typography variant="subtitle2" sx={{ color: 'text.secondary' }}>
Welcome Message
</Typography>
<RHFEditor name="welcome_message" />
</Stack>
<Stack spacing={1}>
<Typography variant='subtitle2' sx={{ color: "text.secondary" }}>Help Text</Typography>
<Typography variant="subtitle2" sx={{ color: 'text.secondary' }}>
Help Text
</Typography>
<RHFEditor name="help_text" />
</Stack>
@@ -342,103 +392,149 @@ export default function CorporateForm({ isEdit, currentCorporate }: Props) {
<Grid item xs={12} md={4}>
<Stack spacing={3}>
<Card sx={{ p: 3 }}>
{ JSON.stringify(values.active) }
{JSON.stringify(values.active)}
<RHFSwitch name="active" label="Is Company Active" />
<Stack spacing={3} mt={2}>
<Stack spacing={3} mt={2} alignItems="center">
<Typography align="center">Company Logo</Typography>
<RHFUploadAvatar name="logo"
{/* <RHFUploadAvatar
name="logo"
showPreview
accept={'image/*'}
accept="image/*"
maxSize={3145728}
onDrop={handleDrop}
onRemove={handleRemove}
/>
/> */}
<UploadImage setFile={setFile} currentImage={currentImage} />
</Stack>
</Card>
<Card sx={{ p: 3 }}>
<Stack>
<Typography variant='subtitle2' sx={{ color: "text.secondary" }}>Linking Rules</Typography>
<Stack>
<RHFCustomMultiCheckbox name='linking_rules' options={linking_tools} />
<Typography variant="subtitle2" sx={{ color: 'text.secondary' }}>
Linking Rules
</Typography>
<Stack>
<RHFCustomMultiCheckbox name="linking_rules" options={linking_tools} />
</Stack>
</Stack>
</Card>
</Stack>
</Grid>
{( values.type == 'corporate' && <Grid item xs={12} md={12}>
{/* <Card sx={{ p:3, mb:3, background: 'gray', color: 'white' }}><Typography>Policy Detail</Typography></Card> */}
<Card sx={{ p: 3 }}>
<Stack spacing={3} mt={2}>
<Grid item xs={12}><Typography variant='h5'>Policy Detail</Typography></Grid>
<input type="hidden" name="policy_id" />
<Stack spacing={1}>
<RHFTextField name="policy_code" label="Policy Number" />
{(!(currentCorporate?.id) && <Typography variant="caption">Will be generated if empty</Typography>)}
</Stack>
{/* <Typography>Minimal Deposit Policy Level</Typography> */}
<Stack direction="row" spacing={2}>
<Grid item xs={12} md={6}>
<RHFDatepicker name="policy_start" label="Start Date (YYYY-MM-DD)" />
{values.type == 'corporate' && (
<Grid item xs={12} md={12}>
{/* <Card sx={{ p:3, mb:3, background: 'gray', color: 'white' }}><Typography>Policy Detail</Typography></Card> */}
<Card sx={{ p: 3 }}>
<Stack spacing={3} mt={2}>
<Grid item xs={12}>
<Typography variant="h5">Policy Detail</Typography>
</Grid>
<Grid item xs={12} md={6}>
<RHFDatepicker name="policy_end" label="End Date (YYYY-MM-DD)" />
</Grid>
</Stack>
<RHFTextField name="policy_total_premi" label={"Deposit Intial Fund ("+fCurrency(values.policy_total_premi)+")"}/>
<input type="hidden" name="policy_id" />
<Stack spacing={1}>
<Typography variant='subtitle2' sx={{ color: "text.secondary" }}>Minimal Deposit Policy Level</Typography>
<Grid container>
<Grid item xs={12} md={3}>
<RHFTextField name="policy_minimal_deposit_percentage" label="Percentage (%)" onChange={handleMinimalDepositPercentageChange}/>
<Stack spacing={1}>
<RHFTextField name="policy_code" label="Policy Number" />
{!currentCorporate?.id && (
<Typography variant="caption">Will be generated if empty</Typography>
)}
</Stack>
{/* <Typography>Minimal Deposit Policy Level</Typography> */}
<Stack direction="row" spacing={2}>
<Grid item xs={12} md={6}>
<RHFDatepicker name="policy_start" label="Start Date (YYYY-MM-DD)" />
</Grid>
<Grid item xs={12} md={9}>
<RHFTextField name="policy_minimal_deposit_net" label={"Net ("+fCurrency(values.policy_minimal_deposit_net)+")"} onChange={handleMinimalDepositNetChange}/>
<Grid item xs={12} md={6}>
<RHFDatepicker name="policy_end" label="End Date (YYYY-MM-DD)" />
</Grid>
</Grid>
</Stack>
</Stack>
<Stack spacing={1}>
<Typography variant='subtitle2' sx={{ color: "text.secondary" }}>Minimal Alert Level</Typography>
<Grid container>
<Grid item xs={12} md={3}>
<RHFTextField name="policy_minimal_alert_percentage" label="Percentage (%)" onChange={handleMinimalAlertPercentageChange}/>
</Grid>
<Grid item xs={12} md={9}>
<RHFTextField name="policy_minimal_alert_net" label={"Net ("+fCurrency(values.policy_minimal_alert_net)+")"} onChange={handleMinimalAlertNetChange}/>
</Grid>
</Grid>
</Stack>
<RHFTextField
name="policy_total_premi"
label={'Deposit Intial Fund (' + fCurrency(values.policy_total_premi) + ')'}
/>
<Stack spacing={1}>
<Typography variant='subtitle2' sx={{ color: "text.secondary" }}>Stop Service Level</Typography>
<Grid container>
<Grid item xs={12} md={3}>
<RHFTextField name="policy_stop_service_percentage" label="Percentage (%)" onChange={handleStopServicePercentageChange}/>
</Grid>
<Grid item xs={12} md={9}>
<RHFTextField name="policy_stop_service_net" label={"Net ("+fCurrency(values.policy_stop_service_net)+")"} onChange={handleStopServiceNetChange}/>
</Grid>
</Grid>
<Stack spacing={1}>
<Typography variant="subtitle2" sx={{ color: 'text.secondary' }}>
Minimal Deposit Policy Level
</Typography>
<Grid container>
<Grid item xs={12} md={3}>
<RHFTextField
name="policy_minimal_deposit_percentage"
label="Percentage (%)"
onChange={handleMinimalDepositPercentageChange}
/>
</Grid>
<Grid item xs={12} md={9}>
<RHFTextField
name="policy_minimal_deposit_net"
label={'Net (' + fCurrency(values.policy_minimal_deposit_net) + ')'}
onChange={handleMinimalDepositNetChange}
/>
</Grid>
</Grid>
</Stack>
<Stack spacing={1}>
<Typography variant="subtitle2" sx={{ color: 'text.secondary' }}>
Minimal Alert Level
</Typography>
<Grid container>
<Grid item xs={12} md={3}>
<RHFTextField
name="policy_minimal_alert_percentage"
label="Percentage (%)"
onChange={handleMinimalAlertPercentageChange}
/>
</Grid>
<Grid item xs={12} md={9}>
<RHFTextField
name="policy_minimal_alert_net"
label={'Net (' + fCurrency(values.policy_minimal_alert_net) + ')'}
onChange={handleMinimalAlertNetChange}
/>
</Grid>
</Grid>
</Stack>
<Stack spacing={1}>
<Typography variant="subtitle2" sx={{ color: 'text.secondary' }}>
Stop Service Level
</Typography>
<Grid container>
<Grid item xs={12} md={3}>
<RHFTextField
name="policy_stop_service_percentage"
label="Percentage (%)"
onChange={handleStopServicePercentageChange}
/>
</Grid>
<Grid item xs={12} md={9}>
<RHFTextField
name="policy_stop_service_net"
label={'Net (' + fCurrency(values.policy_stop_service_net) + ')'}
onChange={handleStopServiceNetChange}
/>
</Grid>
</Grid>
</Stack>
</Stack>
</Stack>
</Card>
</Grid> )}
</Card>
</Grid>
)}
<Grid item xs={12} md={4}>
<LoadingButton type="submit" variant="contained" size="large" fullWidth={true} loading={isSubmitting}>
<LoadingButton
type="submit"
variant="contained"
size="large"
fullWidth={true}
loading={isSubmitting}
>
{!isEdit ? 'Save New Corporate' : 'Save Corporate'}
</LoadingButton>
</Grid>
</Grid>
</FormProvider>
);
};
}

View File

@@ -23,3 +23,8 @@ export function fToNow(date: Date | string | number) {
addSuffix: true
});
}
export function fPostFormat(date: Date | string | number) {
return format(new Date(date), 'yyyy-MM-dd HH:mm:ss');
}