Files
aso/frontend/dashboard/src/pages/Master/Hospitals/Form.tsx
ivan-sim 9a4e9db798 Update
2024-10-09 10:31:33 +07:00

581 lines
20 KiB
TypeScript
Executable File

import * as Yup from 'yup';
import { useSnackbar } from 'notistack';
import { useNavigate } from 'react-router-dom';
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
import MenuItem from '@mui/material/MenuItem';
import Select, { SelectChangeEvent } from '@mui/material/Select';
import * as React from 'react';
// form
import { Controller, useForm } from 'react-hook-form';
import { yupResolver } from '@hookform/resolvers/yup';
// @mui
import { styled } from '@mui/material/styles';
import { LoadingButton } from '@mui/lab';
import {
Box,
Button,
ButtonGroup,
Card,
Grid,
Stack,
Typography,
TextField,
Tab,
Chip,
Autocomplete,
} from '@mui/material';
import TabContext from '@mui/lab/TabContext';
import TabList from '@mui/lab/TabList';
import TabPanel from '@mui/lab/TabPanel';
import CancelIcon from '@mui/icons-material/Cancel';
// components
import {
FormProvider,
RHFTextField,
RHFRadioGroup,
RHFUploadAvatar,
RHFSwitch,
RHFSelect,
RHFEditor,
RHFDatepicker,
RHFMultiCheckbox,
RHFCheckbox,
RHFCustomMultiCheckbox,
} from '../../../components/hook-form';
import axios from '../../../utils/axios';
import { fCurrency } from '../../../utils/formatNumber';
import { Organizations } from '../../../@types/organization';
import { Provinces } from '../../../@types/organization';
import { Cities } from '../../../@types/organization';
import { Districts } from '../../../@types/organization';
import { Villages } from '../../../@types/organization';
import { Label } from '@mui/icons-material';
import MyDropzone from '../../../components/MyDropzone';
const LabelStyle = styled(Typography)(({ theme }) => ({
...theme.typography.h6,
marginBottom: theme.spacing(2),
marginTop: theme.spacing(2),
}));
const HeaderStyle = styled('header')(({ theme }) => ({
display: 'flex',
alignItems: 'center',
justifyContent: 'space-between',
}));
const Title = styled(Typography)(({ theme }) => ({
...theme.typography.h4,
boxShadow: 'none',
// paddingBottom: theme.spacing(3),
fontWeight: 700,
}));
// const [timezone, setTimezone] = React.useState('');
// const selectInput = (event: SelectChangeEvent) => {
// setTimezone(event.target.value as string);
// const name = event.target.name;
// const value = event.target.value;
// setInputs((values) => ({ ...values, [name]: value }));
// };
// const [inputs, setInputs] = useState({});
interface FormValuesProps extends Partial<Organizations> {
taxes: boolean;
inStock: boolean;
}
type Props = {
isEdit: boolean;
currentOrganizations?: Organizations;
};
export default function OrganizationsForm({ isEdit, currentOrganizations }: Props) {
const navigate = useNavigate();
const [organizations_group, setOrganizationsGroups] = useState([]);
// const [ errors, setErrors ] = useState<{ [key: string]: string }>({});
const { enqueueSnackbar } = useSnackbar();
const NewCorporateSchema = Yup.object().shape({
name: Yup.string().required('Name is required'),
code: Yup.string().required('Corporate Code is required'),
// file: Yup.boolean().required('Corporate Status is required'),
});
const defaultValues = useMemo(
() => ({
name: currentOrganizations?.name || '',
code: currentOrganizations?.code || '',
phone: currentOrganizations?.phone || '',
no_hp: currentOrganizations?.no_hp || '',
email: currentOrganizations?.email || '',
lat: currentOrganizations?.lat || '',
lng: currentOrganizations?.lng || '',
address: currentOrganizations?.address || '',
timezone: currentOrganizations?.timezone || '',
active: currentOrganizations?.active === 1 ? true : false,
province_id: currentOrganizations?.province_id || '',
city_id: currentOrganizations?.city_id || '',
district_id: currentOrganizations?.district_id || '',
village_id: currentOrganizations?.village_id || '',
postal_code: currentOrganizations?.postal_code || '',
description: currentOrganizations?.description || '',
corporate_id_partner: currentOrganizations?.corporate_id_partner || [],
}),
// eslint-disable-next-line react-hooks/exhaustive-deps
[currentOrganizations]
);
function StatusLabel({ value }: { value: boolean }) {
return (
<Chip
label={value ? 'Aktif' : 'Tidak Aktif'}
size="medium"
sx={{
backgroundColor: value ? 'rgba(84, 214, 44, 0.16)' : 'rgba(255, 72, 66, 0.16)',
color: value ? '#229A16' : '#B72136',
padding: '1 8 1 8 px',
borderRadius: '4px',
fontSize: '12px',
fontWeight: 'bold',
}}
/>
);
}
const methods = useForm<FormValuesProps>({
resolver: yupResolver(NewCorporateSchema),
defaultValues,
});
const {
reset,
watch,
control,
setValue,
getValues,
setError,
handleSubmit,
formState: { isSubmitting },
} = methods;
const values = watch();
useEffect(() => {
if (isEdit && currentOrganizations) {
reset(defaultValues);
}
if (!isEdit) {
reset(defaultValues);
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [isEdit, currentOrganizations]);
const onSubmit = async (data: FormValuesProps) => {
try {
const formData = new FormData();
formData.append('name', data.name);
formData.append('code', data.code);
formData.append('phone', data.phone);
formData.append('no_hp', data.no_hp);
formData.append('email', data.email);
formData.append('lat', data.lat);
formData.append('lng', data.lng);
formData.append('address', data.address);
formData.append('active', data.active ? '1' : '0');
if (data.province_id === currentOrganizations?.province_id) {
formData.append('province_id', data.province_id);
} else {
formData.append('province_id', data.province_id?.value ?? '');
}
if (data.city_id === currentOrganizations?.city_id) {
formData.append('city_id', data.city_id);
} else {
formData.append('city_id', data.city_id?.value ?? '');
}
if (data.district_id === currentOrganizations?.district_id) {
formData.append('district_id', data.district_id);
} else {
formData.append('district_id', data.district_id?.value ?? '');
}
if (data.village_id === currentOrganizations?.village_id) {
formData.append('village_id', data.village_id);
} else {
formData.append('village_id', data.village_id?.value ?? '');
}
formData.append('postal_code', data.postal_code);
formData.append('description', data.description);
formData.append('corporate_id_partner', data.corporate_id_partner);
if (!isEdit) {
console.log('formData', formData);
const response = await axios.post('/organizations', formData);
} else {
formData.append('_method', 'PUT');
const response = await axios.post(
'/organizations/' + currentOrganizations?.id ?? '',
formData
);
}
reset();
enqueueSnackbar(
!isEdit ? 'Organizations Created Successfully!' : 'Organizations Udpated Successfully!',
{ variant: 'success' }
);
navigate('/master/hospitals');
} catch (error: any) {
if (error && error.response.status === 422) {
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 {
enqueueSnackbar(error.message ?? 'Failed Processing Request', { variant: 'error' });
}
}
const ascent = document?.querySelector('ascent');
if (ascent != null) {
ascent.innerHTML = '';
}
};
const [province, setProvince] = useState<any>([]);
const [city, setCity] = useState<any>([]);
const [district, setDistrict] = useState<any>([]);
const [village, setVillage] = useState<any>([]);
let corporate_selected = [];
if (defaultValues?.corporate_id_partner) {
if (defaultValues.corporate_id_partner.includes(',')) {
corporate_selected = defaultValues.corporate_id_partner.split(",").map(Number);
} else {
corporate_selected = [Number(defaultValues.corporate_id_partner)];
}
}
const [corporate_id_partner, setCorporateIdPartner] = useState<any>([]);
const [selectedCorporatID, setSelectedCorporateID] = useState<any>([]);
useEffect(()=> {
setSelectedCorporateID(corporate_selected)
}, [defaultValues])
const handleSelectChange = (event, selectedOptions:any) => {
const selectedValues = selectedOptions.map(option => option.value);
setSelectedCorporateID(selectedValues);
setValue('corporate_id_partner', selectedValues)
};
useEffect(() => {
axios.get('/province').then((res) => {
setProvince(res.data.data.map((item: any) => ({ value: item.id, label: item.name })));
});
const loadCity = async () => {
if (values.province_id == currentOrganizations?.province_id) {
const res = await axios.get('/city?province_id=' + values.province_id);
setCity(res.data.data.map((item: any) => ({ value: item.id, label: item.name })));
} else {
const res = await axios.get('/city?province_id=' + values.province_id?.value);
setCity(res.data.data.map((item: any) => ({ value: item.id, label: item.name })));
}
};
const loadDistrict = async () => {
if (values.city_id == currentOrganizations?.city_id) {
const res = await axios.get('/district?city_id=' + values.city_id);
setDistrict(res.data.data.map((item: any) => ({ value: item.id, label: item.name })));
} else {
const res = await axios.get('/district?city_id=' + values.city_id?.value);
setDistrict(res.data.data.map((item: any) => ({ value: item.id, label: item.name })));
}
};
const loadVillage = async () => {
if (values.district_id == currentOrganizations?.district_id) {
const res = await axios.get('/village?district_id=' + values.district_id);
setVillage(res.data.data.map((item: any) => ({ value: item.id, label: item.name })));
} else {
const res = await axios.get('/village?district_id=' + values.district_id?.value);
setVillage(res.data.data.map((item: any) => ({ value: item.id, label: item.name })));
}
};
if (values.province_id) {
loadCity();
}
if (values.city_id) {
loadDistrict();
}
if (values.district_id) {
loadVillage();
}
}, [values.province_id, values.city_id, values.district_id, values.village_id]);
useEffect(() => {
axios.get('/corporates').then((res) => {
setCorporateIdPartner(res.data.data.map((item: any) => ({ value: item.id, label: item.name })));
});
const loadCorporateIdPartner = async () => {
if (values.corporate_id_partner == currentOrganizations?.corporate_id_partner){
const res = await axios.get('/corporates');
setCorporateIdPartner(res.data.data.map((item: any) => ({ value: item.id, label: item.name })));
}
}
if (values.corporate_id_partner) {
loadCorporateIdPartner();
}
}, [values.corporate_id_partner])
const findValueProvince = province.find(
(item: any) => item.value === currentOrganizations?.province_id
);
const findValueCity = city.find((item: any) => item.value === currentOrganizations?.city_id);
const findValueDistrict = district.find(
(item: any) => item.value === currentOrganizations?.district_id
);
const findValueVillage = village.find(
(item: any) => item.value === currentOrganizations?.village_id
);
const findValueCorporate = selectedCorporatID.find(
(item: any) => item.value === currentOrganizations?.corporate_id_partner
);
return (
<FormProvider methods={methods} onSubmit={handleSubmit(onSubmit)}>
<Stack spacing={3}>
<Card sx={{ p: 5 }}>
<HeaderStyle>
<Grid item xs={6} md={6}>
<Title>Data Rumah Sakit</Title>
</Grid>
<Grid item xs={6} md={6}>
{/* <Typography>Status Rumah Sakit</Typography> */}
<RHFSwitch name="active" label="" />
<StatusLabel value={values.active} />
</Grid>
</HeaderStyle>
<Box sx={{ width: '100%', typography: 'body1', mt: 2 }}>
<Grid container rowSpacing={4} columnSpacing={{ xs: 1, sm: 2, md: 3 }}>
<Grid item xs={12}>
<LabelStyle>Nama Rumah Sakit</LabelStyle>
<RHFTextField name="name" placeholder="Tuliskan Nama Rumah Sakit" />
</Grid>
<Grid item xs={12} md={6}>
<LabelStyle>Code Rumah Sakit</LabelStyle>
<RHFTextField name="code" placeholder="Tuliskan Code Rumah Sakit" />
</Grid>
<Grid item xs={12} md={6}>
<LabelStyle>Nomor IGD</LabelStyle>
<RHFTextField name="phone" placeholder="Tuliskan No IGD" />
</Grid>
<Grid item xs={12} md={6}>
<LabelStyle>No. HP</LabelStyle>
<RHFTextField name="no_hp" placeholder="Tuliskan No. HP" />
</Grid>
<Grid item xs={12} md={6}>
<LabelStyle>Email</LabelStyle>
<RHFTextField name="email" placeholder="Tuliskan Email" />
</Grid>
<Grid item xs={12}>
<LabelStyle>Alamat</LabelStyle>
<RHFTextField name="address" placeholder="Tuliskan Alamat" />
</Grid>
<Grid item xs={12} md={6}>
<LabelStyle>Provinsi</LabelStyle>
<Controller
name="province_id"
control={control}
render={({ field: { onChange, value } }) => (
<Autocomplete
id="combo-box-demo"
options={province}
getOptionLabel={(option) => option.label ?? findValueProvince?.label ?? ''}
value={value}
onChange={(event: any, newValue: any) => {
console.log('newValue', newValue);
setValue('province_id', newValue?.value);
onChange(newValue);
}}
renderInput={(params) => (
<TextField {...params} label="Provinsi" variant="outlined" fullWidth />
)}
/>
)}
/>
</Grid>
<Grid item xs={12} md={6}>
<LabelStyle>Kabupaten / Kota</LabelStyle>
<Controller
name="city_id"
control={control}
render={({ field: { onChange, value } }) => (
<Autocomplete
id="combo-box-demo"
options={city}
getOptionLabel={(option) => option.label ?? findValueCity?.label ?? ''}
value={value}
onChange={(event: any, newValue: any) => {
console.log('newValue', newValue);
setValue('city_id', newValue?.value);
onChange(newValue);
}}
renderInput={(params) => (
<TextField
{...params}
label="Kabupaten / Kota"
variant="outlined"
fullWidth
/>
)}
/>
)}
/>
</Grid>
<Grid item xs={12} md={6}>
<LabelStyle>Kecamatan</LabelStyle>
<Controller
name="district_id"
control={control}
render={({ field: { onChange, value } }) => (
<Autocomplete
id="combo-box-demo"
options={district}
getOptionLabel={(option) => option.label ?? findValueDistrict?.label ?? ''}
value={value}
onChange={(event: any, newValue: any) => {
console.log('newValue', newValue);
setValue('district_id', newValue?.value);
onChange(newValue);
}}
renderInput={(params) => (
<TextField {...params} label="Kecamatan" variant="outlined" fullWidth />
)}
/>
)}
/>
</Grid>
<Grid item xs={12} md={6}>
<LabelStyle>Desa</LabelStyle>
<Controller
name="village_id"
control={control}
render={({ field: { onChange, value } }) => (
<Autocomplete
id="combo-box-demo"
options={village}
getOptionLabel={(option) => option.label ?? findValueVillage?.label ?? ''}
value={value}
onChange={(event: any, newValue: any) => {
console.log('newValue', newValue);
setValue('village_id', newValue?.value);
onChange(newValue);
}}
renderInput={(params) => (
<TextField {...params} label="Desa" variant="outlined" fullWidth />
)}
/>
)}
/>
</Grid>
<Grid item xs={12} md={4}>
<LabelStyle>Kode Pos</LabelStyle>
<RHFTextField name="postal_code" placeholder="Tuliskan Kode Pos" />
</Grid>
<Grid item xs={12} md={4}>
<LabelStyle>Latitude</LabelStyle>
<RHFTextField name="lat" placeholder="Tuliskan Lattitude" />
</Grid>
<Grid item xs={12} md={4}>
<LabelStyle>Longitude</LabelStyle>
<RHFTextField name="lng" placeholder="Tuliskan Longitude" />
</Grid>
<Grid item xs={12}>
<LabelStyle>Rekanan</LabelStyle>
<Controller
name="corporate_id_partner"
control={control}
render={({ field: { onChange, value } }) => (
<Autocomplete
id="combo-box-demo"
options={corporate_id_partner}
getOptionLabel={(option) => option.label ?? findValueCorporate.label ?? ''}
value={corporate_id_partner.filter(option => selectedCorporatID.includes(option.value))}
onChange={handleSelectChange}
multiple // Enable multiple selections
renderInput={(params) => (
<TextField {...params} label="Corporate" variant="outlined" fullWidth />
)}
/>
)}
/>
</Grid>
<Grid item xs={12}>
<LabelStyle>Deskripsi</LabelStyle>
<RHFEditor name="description" placeholder="Tuliskan Deskripsi" />
</Grid>
</Grid>
</Box>
<Box sx={{ width: '100%', mt: 5 }}>
<Stack
alignItems="center"
justifyContent="end"
direction={{ xs: 'column', md: 'row' }}
sx={{ width: 1, textAlign: { xs: 'center', md: 'left' } }}
>
<Grid item xs={12} md={4}>
<LoadingButton
sx={{ boxShadow: '0px 2px 4px rgba(0, 0, 0, 0.1)' }}
type="submit"
variant="contained"
size="large"
// fullWidth={true}
loading={isSubmitting}
>
{!isEdit ? 'Simpan' : 'Simpan Perubahan'}
</LoadingButton>
</Grid>
</Stack>
</Box>
</Card>
</Stack>
</FormProvider>
);
}