Merge remote-tracking branch 'origin/staging' into origin/production

This commit is contained in:
Server D3 Linksehat
2024-10-14 11:31:59 +07:00
91 changed files with 2823 additions and 12555 deletions

View File

@@ -1,6 +1,8 @@
export type Organizations = {
id: number;
code: string;
no_hp: number;
email: string;
name: string;
address: string;
type: string;

View File

@@ -134,6 +134,16 @@ export type Role = {
permissions: number[]
};
export type Organization = {
id: number;
name: string;
};
export type Corporate = {
id: number;
name: string;
};
export type Permisions = {
name: string;
guard_name: string;
@@ -146,6 +156,8 @@ export type UserAccess = {
email: string;
person: Person;
role: Role;
organization_id: Organization;
corporate_id: Corporate;
}
export type Person = {

View File

@@ -116,6 +116,8 @@ export default function OrganizationsForm({ isEdit, currentOrganizations }: Prop
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 || '',
@@ -185,6 +187,8 @@ export default function OrganizationsForm({ isEdit, currentOrganizations }: Prop
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);
@@ -361,7 +365,7 @@ export default function OrganizationsForm({ isEdit, currentOrganizations }: Prop
const findValueCorporate = selectedCorporatID.find(
(item: any) => item.value === currentOrganizations?.corporate_id_partner
);
return (
<FormProvider methods={methods} onSubmit={handleSubmit(onSubmit)}>
<Stack spacing={3}>
@@ -391,6 +395,14 @@ export default function OrganizationsForm({ isEdit, currentOrganizations }: Prop
<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" />

View File

@@ -301,9 +301,21 @@ export default function List() {
<Grid item xs={10}>
: {row.code ? row.code : '-'}
</Grid>
<Grid item xs={2}>
No. HP
</Grid>
<Grid item xs={10}>
: {row.no_hp ? row.no_hp : '-'}
</Grid>
<Grid item xs={2}>
Email
</Grid>
<Grid item xs={10}>
: {row.email ? row.email : '-'}
</Grid>
<Grid item xs={2}>
Rekanan
Rekanan
</Grid>
<Grid item xs={10}>
: {row.corporate_name ? row.corporate_name : '-'}

View File

@@ -158,7 +158,6 @@ export default function List() {
setSearchText(searchParams.get('search') ?? '');
}, []);
return (
<form style={{ width: '100%' }}>
@@ -337,6 +336,7 @@ export default function List() {
<TableCell align="left">{row.date_consultation ? fDateTime(row.date_consultation) : '-'}</TableCell>
<TableCell align="left">{row.patient_name ?? '-'}</TableCell>
<TableCell align="left">{row.doctor_name ?? '-'}</TableCell>
<TableCell align="left">{row.status_prescription ?? '-'}</TableCell>
{/* <TableCell align="center">
<ButtonGroup variant="text" aria-label="text button group">
<Link to={'/report/appointments/' + row.id + '/show'}>
@@ -390,7 +390,7 @@ export default function List() {
</Collapse>
</TableCell>
</TableRow>
{/* END COLLAPSIBLE ROW */}
<Dialog
@@ -542,6 +542,9 @@ export default function List() {
<TableCell style={headStyle} align="left">
Doctor
</TableCell>
<TableCell style={headStyle} align="left">
Status
</TableCell>
{/* <TableCell style={headStyle} align="center">
Aksi
</TableCell> */}

View File

@@ -6,6 +6,7 @@ import {useContext, useEffect, useMemo, useState } from 'react';
import axios from '../../../utils/axios';
import UserAccessForm from './Form';
import { Role, UserAccess } from '../../../@types/user';
import Organizations from "@/pages/Master/Hospitals/Index";
@@ -13,6 +14,8 @@ export default function UserAccessCreate() {
const { id } = useParams();
const [ currentUserAccess, setCurrentUserAccess ] = useState<UserAccess>();
const [ roles, setRole ] = useState<any>();
const [ corporate, setCorporate ] = useState<any>();
const [ organizations, setOrganization ] = useState<any>();
const navigate = useNavigate();
@@ -40,9 +43,30 @@ export default function UserAccessCreate() {
navigate('/404');
}
})
axios.get('/organization-list')
.then((res)=> {
setOrganization(res.data)
})
.catch((err) => {
if (err.response.status === 404) {
navigate('/404');
}
})
axios.get('/corporates')
.then((res)=> {
setCorporate(res.data)
})
.catch((err) => {
if (err.response.status === 404) {
navigate('/404');
}
})
}, [id]);
console.log(corporate, 'test')
return (
<Page title= "User Access">
@@ -57,7 +81,7 @@ export default function UserAccessCreate() {
]}
/>
<UserAccessForm isEdit={isEdit} currentUserAccess={currentUserAccess} roles={roles}/>
<UserAccessForm isEdit={isEdit} currentUserAccess={currentUserAccess} roles={roles} organizations={organizations} corporate={corporate} />
</Page>
);
}

View File

@@ -1,23 +1,26 @@
import * as Yup from 'yup';
import { LoadingButton } from "@mui/lab";
import { Box, Card, Grid, Stack, Typography } from "@mui/material";
import { Role, UserAccess } from "../../../@types/user";
import { FormProvider, RHFSelect, RHFSwitch, RHFTextField } from "../../../components/hook-form";
import { useEffect, useMemo } from 'react';
import { Role, UserAccess, Organization } from "../../../@types/user";
import { FormProvider, RHFSelect, RHFTextField } from "../../../components/hook-form";
import { useEffect, useMemo, useState } from 'react';
import { useForm } from 'react-hook-form';
import { yupResolver } from '@hookform/resolvers/yup';
import { useSnackbar } from 'notistack';
import { useNavigate, useParams } from 'react-router-dom';
import axios from '../../../utils/axios';
import palette from '@/theme/palette';
import { Corporate } from '@/@types/corporates';
type Props = {
isEdit: boolean;
currentUserAccess?: UserAccess;
roles: Role
roles: Role;
organizations: Organization;
corporate: Corporate;
};
export default function AccsessForm({ isEdit, currentUserAccess, roles }: Props) {
export default function AccessForm({ isEdit, currentUserAccess, roles, organizations, corporate }: Props) {
const { enqueueSnackbar } = useSnackbar();
const navigate = useNavigate();
@@ -27,13 +30,14 @@ export default function AccsessForm({ isEdit, currentUserAccess, roles }: Props)
name: Yup.string().required('Name is required'),
});
console.log(currentUserAccess, 'test')
const defaultValues = useMemo(
() => ({
name: currentUserAccess?.person?.name || '',
username: currentUserAccess?.username || '',
username: currentUserAccess?.username || '',
email: currentUserAccess?.email || '',
roles: currentUserAccess?.role?.id || [],
roles: currentUserAccess?.role?.id || '',
organizations: currentUserAccess?.organization_id || '',
corporates: currentUserAccess?.corporate_id || '',
password: '',
}),
[currentUserAccess]
@@ -56,92 +60,119 @@ export default function AccsessForm({ isEdit, currentUserAccess, roles }: Props)
const {
reset,
watch,
control,
setValue,
getValues,
setError,
handleSubmit,
setError,
formState: { isSubmitting },
} = methods;
// Watch 'roles' field to conditionally render other fields
const selectedRole = watch('roles');
const onSubmit = async (data: any) => {
console.log(data);
console.log(data, 'test123');
if (!isEdit) {
await axios
.post('/user/access', data)
.then((res) => {
enqueueSnackbar('User created successfully', { variant: 'success' });
})
.then((res) => {
navigate('/user-access', { replace: true });
})
.catch(({ response }) => {
if (response.status === 422) {
for (const [key, value] of Object.entries(response.data.errors)) {
setError(key, { message: value[0] });
enqueueSnackbar(value[0] ?? 'Failed Processing Request', { variant: 'error' });
.post('/user/access', data)
.then((res) => {
enqueueSnackbar('User created successfully', { variant: 'success' });
navigate('/user-access', { replace: true });
})
.catch(({ response }) => {
if (response.status === 422) {
for (const [key, value] of Object.entries(response.data.errors)) {
setError(key, { message: value[0] });
enqueueSnackbar(value[0] ?? 'Failed Processing Request', { variant: 'error' });
}
} else {
enqueueSnackbar('Create Failed : ' + response.data.message, { variant: 'error' });
}
}
else {
enqueueSnackbar('Create Failed : '+ response.data.message, { variant: 'error' });
}
});
});
} else {
await axios
.put('/user/access/' + currentUserAccess?.id, data)
.then((res) => {
enqueueSnackbar('User updated successfully', { variant: 'success' });
})
.then((res) => {
navigate('/user-access' , { replace: true });
navigate('/user-access', { replace: true });
})
.catch(({ response }) => {
enqueueSnackbar('Update Failed : '+ response.data.message, { variant: 'error' });
enqueueSnackbar('Update Failed : ' + response.data.message, { variant: 'error' });
});
}
};
const optionsRoles = roles?.data?.map(item => ({
// Map role, organization, and corporate options
const optionsRoles = roles?.data?.map((item) => ({
value: item.id,
label: item.name
label: item.name,
})) ?? [];
const optionsOrganization = organizations?.data?.map((item) => ({
value: item.id,
label: item.name,
})) ?? [];
const optionsCorporate = corporate?.data?.map((item) => ({
value: item.id,
label: item.name,
})) ?? [];
if (optionsRoles.length > 0) {
optionsRoles.unshift({ value: '', label: '' });
}
return (
<FormProvider methods={methods} onSubmit={handleSubmit(onSubmit)}>
<Box sx={{ px: 2 }}>
<Grid container spacing={2}>
<Grid item xs={12} sm={12}>
<Card sx={{ px: 3, py: 4 }}>
<Stack spacing={2}>
<Typography variant="h6" color={palette.light.primary.main}>User Access</Typography>
<RHFTextField name="name" label="Name" />
<RHFTextField name="username" label="Username" />
<RHFTextField type="email" name="email" label="Email" />
<RHFTextField type="password" name="password" label="Password" />
<RHFSelect name="roles" label="Roles">
{optionsRoles.map((option, index) => (
<option key={index} value={option.value}>
{option.label}
</option>
))}
</RHFSelect>
<Box sx={{ px: 2 }}>
<Grid container spacing={2}>
<Grid item xs={12} sm={12}>
<Card sx={{ px: 3, py: 4 }}>
<Stack spacing={2}>
<Typography variant="h6" color={palette.light.primary.main}>
User Access
</Typography>
<RHFTextField name="name" label="Name" />
<RHFTextField name="username" label="Username" />
<RHFTextField type="email" name="email" label="Email" />
<RHFTextField type="password" name="password" label="Password" />
{/* Select for roles */}
<RHFSelect name="roles" label="Roles">
{optionsRoles.map((option, index) => (
<option key={index} value={option.value}>
{option.label}
</option>
))}
</RHFSelect>
<LoadingButton type="submit" variant="contained" size="large" fullWidth={true} loading={isSubmitting}>
{ isEdit? 'Update' : 'Create' }
</LoadingButton>
{/* Conditional rendering based on selectedRole */}
{selectedRole && (['8'].includes(selectedRole) ? (
<RHFSelect name="organizations" label="Organizations">
{optionsOrganization.map((option, index) => (
<option key={index} value={option.value}>
{option.label}
</option>
))}
</RHFSelect>
) : ['2'].includes(selectedRole) ? (
<RHFSelect name="corporates" label="Corporates">
{optionsCorporate.map((option, index) => (
<option key={index} value={option.value}>
{option.label}
</option>
))}
</RHFSelect>
) : null)}
</Stack>
</Card>
</Grid>
</Grid>
</Box>
</FormProvider>
<LoadingButton
type="submit"
variant="contained"
size="large"
fullWidth={true}
loading={isSubmitting}
>
{isEdit ? 'Update' : 'Create'}
</LoadingButton>
</Stack>
</Card>
</Grid>
</Grid>
</Box>
</FormProvider>
);
}