Merge remote-tracking branch 'origin/staging' into origin/production
This commit is contained in:
3010
frontend/client-portal/package-lock.json
generated
3010
frontend/client-portal/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -64,6 +64,7 @@
|
||||
"notistack": "^3.0.1",
|
||||
"nprogress": "^0.2.0",
|
||||
"numeral": "^2.0.6",
|
||||
"pnpm": "^8.6.9",
|
||||
"pusher-js": "^8.0.2",
|
||||
"react": "^17.0.2",
|
||||
"react-apexcharts": "^1.4.0",
|
||||
|
||||
@@ -38,6 +38,10 @@ import {
|
||||
const steps = ['Review', 'Approval', 'Disbursement'];
|
||||
|
||||
const DialogDetailClaim = ({ title, openDialog, setOpenDialog, data }: MuiDialogProps) => {
|
||||
function clickHandler(arg0: string) {
|
||||
throw new Error('Function not implemented.');
|
||||
}
|
||||
|
||||
// const getContent = () => (
|
||||
|
||||
// );
|
||||
@@ -108,6 +112,7 @@ import {
|
||||
fullWidth
|
||||
sx={{ typography: 'subtitle2', borderColor: '#F5F5F5' }}
|
||||
>
|
||||
onClick={() => clickHandler('topUpLimit')}
|
||||
Hasil Pemeriksaan Laboratorium
|
||||
</Button>
|
||||
</Stack>
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -2,6 +2,6 @@ GENERATE_SOURCEMAP=false
|
||||
|
||||
PORT=8083
|
||||
|
||||
REACT_APP_HOST_API_URL="http://127.0.0.1:8000"
|
||||
REACT_APP_HOST_API_URL="http://lms.test"
|
||||
|
||||
VITE_API_URL="http://127.0.0.1:8000/api/internal"
|
||||
|
||||
4155
frontend/dashboard/package-lock.json
generated
4155
frontend/dashboard/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -39,79 +39,80 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@ajoelp/json-to-formdata": "^1.5.0",
|
||||
"@date-io/date-fns": "^2.16.0",
|
||||
"@emotion/cache": "^11.10.5",
|
||||
"@emotion/react": "^11.10.5",
|
||||
"@emotion/styled": "^11.10.5",
|
||||
"@hookform/resolvers": "^2.9.10",
|
||||
"@date-io/date-fns": "^2.17.0",
|
||||
"@emotion/cache": "^11.11.0",
|
||||
"@emotion/react": "^11.11.1",
|
||||
"@emotion/styled": "^11.11.0",
|
||||
"@hookform/resolvers": "^2.9.11",
|
||||
"@iconify/react": "^3.2.2",
|
||||
"@mui/icons-material": "^5.11.0",
|
||||
"@mui/icons-material": "^5.14.6",
|
||||
"@mui/lab": "5.0.0-alpha.80",
|
||||
"@mui/material": "^5.11.5",
|
||||
"@mui/system": "^5.11.5",
|
||||
"@mui/x-data-grid": "^5.17.19",
|
||||
"@mui/material": "^5.14.6",
|
||||
"@mui/system": "^5.14.6",
|
||||
"@mui/x-data-grid": "^5.17.26",
|
||||
"@mui/x-date-pickers": "5.0.0-beta.2",
|
||||
"@vitejs/plugin-react": "^1.3.2",
|
||||
"apexcharts": "^3.36.3",
|
||||
"apexcharts": "^3.42.0",
|
||||
"axios": "^0.27.2",
|
||||
"change-case": "^4.1.2",
|
||||
"csstype": "^3.1.1",
|
||||
"date-fns": "^2.29.3",
|
||||
"esbuild": "^0.17.18",
|
||||
"csstype": "^3.1.2",
|
||||
"date-fns": "^2.30.0",
|
||||
"esbuild": "^0.17.19",
|
||||
"framer-motion": "^6.5.1",
|
||||
"highlight.js": "^11.7.0",
|
||||
"highlight.js": "^11.8.0",
|
||||
"history": "^5.3.0",
|
||||
"jsx-runtime": "^1.2.0",
|
||||
"lodash": "^4.17.21",
|
||||
"notistack": "3.0.0-alpha.11",
|
||||
"nprogress": "^0.2.0",
|
||||
"numeral": "^2.0.6",
|
||||
"pnpm": "^8.6.12",
|
||||
"react": "^17.0.2",
|
||||
"react-apexcharts": "^1.4.0",
|
||||
"react-apexcharts": "^1.4.1",
|
||||
"react-dom": "^17.0.2",
|
||||
"react-dropzone": "^14.2.3",
|
||||
"react-helmet-async": "^1.3.0",
|
||||
"react-hook-form": "^7.42.1",
|
||||
"react-hook-form": "^7.45.4",
|
||||
"react-intersection-observer": "^8.34.0",
|
||||
"react-lazy-load-image-component": "^1.5.6",
|
||||
"react-lazy-load-image-component": "^1.6.0",
|
||||
"react-quill": "2.0.0-beta.4",
|
||||
"react-router": "^6.7.0",
|
||||
"react-router-dom": "^6.7.0",
|
||||
"react-router": "^6.15.0",
|
||||
"react-router-dom": "^6.15.0",
|
||||
"simplebar": "^5.3.9",
|
||||
"simplebar-react": "^2.4.3",
|
||||
"stylis": "^4.1.3",
|
||||
"stylis": "^4.3.0",
|
||||
"stylis-plugin-rtl": "^2.1.1",
|
||||
"vite": "^3.2.5",
|
||||
"vite": "^3.2.7",
|
||||
"vite-plugin-svgr": "^2.4.0",
|
||||
"yup": "^0.32.11"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.20.12",
|
||||
"@babel/eslint-parser": "^7.19.1",
|
||||
"@babel/plugin-syntax-flow": "^7.18.6",
|
||||
"@babel/plugin-transform-react-jsx": "^7.20.7",
|
||||
"@types/lodash": "^4.14.191",
|
||||
"@babel/core": "^7.22.11",
|
||||
"@babel/eslint-parser": "^7.22.11",
|
||||
"@babel/plugin-syntax-flow": "^7.22.5",
|
||||
"@babel/plugin-transform-react-jsx": "^7.22.5",
|
||||
"@types/lodash": "^4.14.197",
|
||||
"@types/nprogress": "^0.2.0",
|
||||
"@types/react": "^17.0.53",
|
||||
"@types/react-dom": "^17.0.18",
|
||||
"@types/react-lazy-load-image-component": "^1.5.2",
|
||||
"@types/stylis": "^4.0.2",
|
||||
"@typescript-eslint/eslint-plugin": "^5.48.2",
|
||||
"@typescript-eslint/parser": "^5.48.2",
|
||||
"eslint": "^8.32.0",
|
||||
"@types/react": "^17.0.65",
|
||||
"@types/react-dom": "^17.0.20",
|
||||
"@types/react-lazy-load-image-component": "^1.5.3",
|
||||
"@types/stylis": "^4.2.0",
|
||||
"@typescript-eslint/eslint-plugin": "^5.62.0",
|
||||
"@typescript-eslint/parser": "^5.62.0",
|
||||
"eslint": "^8.48.0",
|
||||
"eslint-config-airbnb": "19.0.4",
|
||||
"eslint-config-airbnb-typescript": "^16.2.0",
|
||||
"eslint-config-prettier": "^8.6.0",
|
||||
"eslint-config-prettier": "^8.10.0",
|
||||
"eslint-config-react-app": "7.0.0",
|
||||
"eslint-import-resolver-typescript": "^2.7.1",
|
||||
"eslint-plugin-flowtype": "^8.0.3",
|
||||
"eslint-plugin-import": "^2.27.5",
|
||||
"eslint-plugin-import": "^2.28.1",
|
||||
"eslint-plugin-jsx-a11y": "6.5.1",
|
||||
"eslint-plugin-prettier": "^4.2.1",
|
||||
"eslint-plugin-react": "^7.32.1",
|
||||
"eslint-plugin-react": "^7.33.2",
|
||||
"eslint-plugin-react-hooks": "4.3.0",
|
||||
"prettier": "^2.8.3",
|
||||
"typescript": "^4.9.4",
|
||||
"prettier": "^2.8.8",
|
||||
"typescript": "^4.9.5",
|
||||
"vite-plugin-pwa": "^0.12.8"
|
||||
}
|
||||
}
|
||||
|
||||
4297
frontend/dashboard/pnpm-lock.yaml
generated
4297
frontend/dashboard/pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@@ -60,8 +60,8 @@ export default function RHFDatepicker({ name, ...other }: IProps & TextFieldProp
|
||||
|
||||
<DesktopDatePicker
|
||||
value={field.value}
|
||||
// inputFormat="dd/MM/yyyy"
|
||||
inputFormat="yyyy-MM-dd"
|
||||
inputFormat="dd/MMM/yyyy"
|
||||
// inputFormat="dd - MMM - yyyy"
|
||||
onChange={(value) => {
|
||||
field.onChange(value);
|
||||
}}
|
||||
|
||||
@@ -86,6 +86,8 @@ const navConfig = [
|
||||
{ title: 'Live Chat', path: '/report/live-chat' },
|
||||
{ title: 'Linksehat Payment', path: '/report/linksehat-payments' },
|
||||
{ title: 'Prescription', path: '/report/prescription' },
|
||||
{ title: 'Doctor Rating', path: '/report/doctorrating' },
|
||||
|
||||
],
|
||||
},
|
||||
{
|
||||
|
||||
@@ -69,7 +69,7 @@ export default function CorporatePlanForm({ isEdit, currentCorporatePlan }: Prop
|
||||
enqueueSnackbar('Division created successfully', { variant: 'success' });
|
||||
})
|
||||
.then((res) => {
|
||||
navigate('/corporates/' + corporate_id + '/divisions', { replace: true });
|
||||
navigate('/corporate/' + corporate_id + '/divisions', { replace: true });
|
||||
})
|
||||
.catch(({ response }) => {
|
||||
if (response.status === 422) {
|
||||
@@ -89,7 +89,7 @@ export default function CorporatePlanForm({ isEdit, currentCorporatePlan }: Prop
|
||||
enqueueSnackbar('Division updated successfully', { variant: 'success' });
|
||||
})
|
||||
.then((res) => {
|
||||
navigate('/corporates/' + corporate_id + '/divisions/' , { replace: true });
|
||||
navigate('/corporate/' + corporate_id + '/divisions/' , { replace: true });
|
||||
})
|
||||
.catch(({ response }) => {
|
||||
enqueueSnackbar('Update Failed : '+ response.data.message, { variant: 'error' });
|
||||
|
||||
@@ -62,7 +62,6 @@ type Props = {
|
||||
};
|
||||
|
||||
export default function CorporateForm({ isEdit, currentCorporate }: Props) {
|
||||
|
||||
const navigate = useNavigate();
|
||||
const [corporate_groups, setCorporateGroups] = useState([]);
|
||||
|
||||
@@ -70,7 +69,7 @@ export default function CorporateForm({ isEdit, currentCorporate }: Props) {
|
||||
|
||||
const { enqueueSnackbar } = useSnackbar();
|
||||
let NewCorporateSchema = null;
|
||||
if (isEdit){
|
||||
if (isEdit) {
|
||||
NewCorporateSchema = Yup.object().shape({
|
||||
isEdited: Yup.boolean(),
|
||||
name: Yup.string().required('Name is required'),
|
||||
@@ -81,36 +80,36 @@ export default function CorporateForm({ isEdit, currentCorporate }: Props) {
|
||||
help_text: Yup.string().required('Help Text is required'),
|
||||
// policy_code: Yup.string().required('Policy Code is required'),
|
||||
policy_start: Yup.date().required('Start Date is required'),
|
||||
policy_end: Yup.date().required('End Date is required').min(Yup.ref('policy_start'), "end date can't be before start date"),
|
||||
policy_end: Yup.date()
|
||||
.required('End Date is required')
|
||||
.min(Yup.ref('policy_start'), "end date can't be before start date"),
|
||||
policy_total_premi: Yup.number().required('Deposit Initial Fund is required').min(0),
|
||||
// linking_rules: Yup.string().required('Link Rules is required'),
|
||||
policy_minimal_deposit_percentage:
|
||||
Yup.number()
|
||||
.typeError("Please enter a valid number")
|
||||
.required('Percentage Deposit is required')
|
||||
.min(0, "Minimum atleast 0")
|
||||
.max(100, "Allowed maximum is 100"),
|
||||
policy_minimal_alert_percentage:
|
||||
Yup.number()
|
||||
.typeError("Please enter a valid number")
|
||||
.required('Percentage Alert is required')
|
||||
.min(0, "Minimum atleast 0")
|
||||
.max(100, "Allowed maximum is 100"),
|
||||
policy_stop_service_percentage:
|
||||
Yup.number()
|
||||
.typeError("Please enter a valid number")
|
||||
.min(0, "Minimum atleast 0")
|
||||
.required('Percentage Stop is required')
|
||||
.test("max", "Total should not exceed 100 %", function(value) {
|
||||
const { policy_minimal_alert_percentage } = this.parent;
|
||||
const { policy_minimal_deposit_percentage } = this.parent;
|
||||
return value == 100 - policy_minimal_alert_percentage- policy_minimal_deposit_percentage;
|
||||
}),
|
||||
policy_minimal_deposit_percentage: Yup.number()
|
||||
.typeError('Please enter a valid number')
|
||||
.required('Percentage Deposit is required')
|
||||
.min(0, 'Minimum atleast 0')
|
||||
.max(100, 'Allowed maximum is 100'),
|
||||
policy_minimal_alert_percentage: Yup.number()
|
||||
.typeError('Please enter a valid number')
|
||||
.required('Percentage Alert is required')
|
||||
.min(0, 'Minimum atleast 0')
|
||||
.max(100, 'Allowed maximum is 100'),
|
||||
policy_stop_service_percentage: Yup.number()
|
||||
.typeError('Please enter a valid number')
|
||||
.min(0, 'Minimum atleast 0')
|
||||
.max(100, 'Allowed maximum is 100')
|
||||
.required('Percentage Stop is required'),
|
||||
// .test('max', 'Total should not exceed 100 %', function (value) {
|
||||
// const { policy_minimal_alert_percentage } = this.parent;
|
||||
// const { policy_minimal_deposit_percentage } = this.parent;
|
||||
// return value == 100 - policy_minimal_alert_percentage - policy_minimal_deposit_percentage;
|
||||
// }),
|
||||
parent_id: Yup.string().when('type', {
|
||||
is: 'subcorporate',
|
||||
then: Yup.string().required('Corporate is required because type is Sub Corporate'),
|
||||
}),
|
||||
|
||||
|
||||
reason: Yup.string().required('Reason for update is required when editing data'),
|
||||
});
|
||||
} else {
|
||||
@@ -118,108 +117,105 @@ export default function CorporateForm({ isEdit, currentCorporate }: Props) {
|
||||
NewCorporateSchema = Yup.object().shape({
|
||||
isEdited: Yup.boolean(),
|
||||
name: Yup.string().required('Name is required'),
|
||||
code: Yup.string().required('Corporate Code is required').test(
|
||||
'unique-code',
|
||||
'Code must be unique',
|
||||
async function (value) {
|
||||
code: Yup.string()
|
||||
.required('Corporate Code is required')
|
||||
.test('unique-code', 'Code must be unique', async function (value) {
|
||||
const existingCodes = await getExistingCodes();
|
||||
return !existingCodes.includes(value);
|
||||
}
|
||||
),
|
||||
}),
|
||||
active: Yup.boolean().required('Corporate Status is required'),
|
||||
type: Yup.string().required('Type is required'),
|
||||
welcome_message: Yup.string().required('Welcome Message is required'),
|
||||
help_text: Yup.string().required('Help Text is required'),
|
||||
// policy_code: Yup.string().required('Policy Code is required'),
|
||||
policy_start: Yup.date().required('Start Date is required'),
|
||||
policy_end: Yup.date().required('End Date is required').min(Yup.ref('policy_start'), "end date can't be before start date"),
|
||||
policy_end: Yup.date()
|
||||
.required('End Date is required')
|
||||
.min(Yup.ref('policy_start'), "end date can't be before start date"),
|
||||
policy_total_premi: Yup.number().required('Deposit Initial Fund is required').min(0),
|
||||
// linking_rules: Yup.string().required('Link Rules is required'),
|
||||
policy_minimal_deposit_percentage:
|
||||
Yup.number()
|
||||
.typeError("Please enter a valid number")
|
||||
.required('Percentage Deposit is required')
|
||||
.min(0, "Minimum atleast 0")
|
||||
.max(100, "Allowed maximum is 100"),
|
||||
policy_minimal_alert_percentage:
|
||||
Yup.number()
|
||||
.typeError("Please enter a valid number")
|
||||
.required('Percentage Alert is required')
|
||||
.min(0, "Minimum atleast 0")
|
||||
.max(100, "Allowed maximum is 100"),
|
||||
policy_stop_service_percentage:
|
||||
Yup.number()
|
||||
.typeError("Please enter a valid number")
|
||||
.min(0, "Minimum atleast 0")
|
||||
.required('Percentage Stop is required')
|
||||
.test("max", "Total should not exceed 100 %", function(value) {
|
||||
const { policy_minimal_alert_percentage } = this.parent;
|
||||
const { policy_minimal_deposit_percentage } = this.parent;
|
||||
return value == 100 - policy_minimal_alert_percentage- policy_minimal_deposit_percentage;
|
||||
}),
|
||||
policy_minimal_deposit_percentage: Yup.number()
|
||||
.typeError('Please enter a valid number')
|
||||
.required('Percentage Deposit is required')
|
||||
.min(0, 'Minimum atleast 0')
|
||||
.max(100, 'Allowed maximum is 100'),
|
||||
policy_minimal_alert_percentage: Yup.number()
|
||||
.typeError('Please enter a valid number')
|
||||
.required('Percentage Alert is required')
|
||||
.min(0, 'Minimum atleast 0')
|
||||
.max(100, 'Allowed maximum is 100'),
|
||||
policy_stop_service_percentage: Yup.number()
|
||||
.typeError('Please enter a valid number')
|
||||
.min(0, 'Minimum atleast 0')
|
||||
.max(100, 'Allowed maximum is 100')
|
||||
.required('Percentage Stop is required'),
|
||||
// .test('max', 'Total should not exceed 100 %', function (value) {
|
||||
// const { policy_minimal_alert_percentage } = this.parent;
|
||||
// const { policy_minimal_deposit_percentage } = this.parent;
|
||||
// return value == 100 - policy_minimal_alert_percentage - policy_minimal_deposit_percentage;
|
||||
// }),
|
||||
parent_id: Yup.string().when('type', {
|
||||
is: 'subcorporate',
|
||||
then: Yup.string().required('Corporate is required because type is Sub Corporate'),
|
||||
}),
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
async function getExistingCodes() {
|
||||
// axios
|
||||
// .get('/corporates/create')
|
||||
// .then((res) => {
|
||||
// setCorporateGroups(res.data.corporate_groups);
|
||||
// })
|
||||
// .catch((err) => {
|
||||
// enqueueSnackbar('Opps, failed to get Corporate Group List', { variant: 'error' });
|
||||
// });
|
||||
// .get('/corporates/create')
|
||||
// .then((res) => {
|
||||
// setCorporateGroups(res.data.corporate_groups);
|
||||
// })
|
||||
// .catch((err) => {
|
||||
// enqueueSnackbar('Opps, failed to get Corporate Group List', { variant: 'error' });
|
||||
// });
|
||||
|
||||
try {
|
||||
let response = await axios.get('/corporates/1/code'); // get data all corporate
|
||||
let codeCurrent = ""
|
||||
if (isEdit){
|
||||
let responseCodeCurrent = await axios.get(`/corporates/${currentCorporate?.id}/edit`); // get data current corporate
|
||||
codeCurrent = responseCodeCurrent.data.code; // get data code corporate current
|
||||
}
|
||||
// console.log(response.data);
|
||||
let existingCodes = response.data.map(item => item); // get data code corporate all
|
||||
|
||||
let filteredArray = existingCodes.filter(e => e != codeCurrent)
|
||||
return filteredArray;
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
enqueueSnackbar('Failed to fetch existing codes', { variant: 'error' });
|
||||
try {
|
||||
let response = await axios.get('/corporates/1/code'); // get data all corporate
|
||||
let codeCurrent = '';
|
||||
if (isEdit) {
|
||||
let responseCodeCurrent = await axios.get(`/corporates/${currentCorporate?.id}/edit`); // get data current corporate
|
||||
codeCurrent = responseCodeCurrent.data.code; // get data code corporate current
|
||||
}
|
||||
// console.log(response.data);
|
||||
let existingCodes = response.data.map((item) => item); // get data code corporate all
|
||||
|
||||
let filteredArray = existingCodes.filter((e) => e != codeCurrent);
|
||||
return filteredArray;
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
enqueueSnackbar('Failed to fetch existing codes', { variant: 'error' });
|
||||
}
|
||||
}
|
||||
|
||||
async function getExistingPayorId() {
|
||||
// axios
|
||||
// .get('/corporates/create')
|
||||
// .then((res) => {
|
||||
// setCorporateGroups(res.data.corporate_groups);
|
||||
// })
|
||||
// .catch((err) => {
|
||||
// enqueueSnackbar('Opps, failed to get Corporate Group List', { variant: 'error' });
|
||||
// });
|
||||
// .get('/corporates/create')
|
||||
// .then((res) => {
|
||||
// setCorporateGroups(res.data.corporate_groups);
|
||||
// })
|
||||
// .catch((err) => {
|
||||
// enqueueSnackbar('Opps, failed to get Corporate Group List', { variant: 'error' });
|
||||
// });
|
||||
|
||||
try {
|
||||
let response = await axios.get('/corporates/1/code'); // get data all corporate
|
||||
let codeCurrent = ""
|
||||
if (isEdit){
|
||||
let responseCodeCurrent = await axios.get(`/corporates/${currentCorporate?.id}/edit`); // get data current corporate
|
||||
codeCurrent = responseCodeCurrent.data.payor_id; // get data code corporate current
|
||||
}
|
||||
// console.log(response.data);
|
||||
let existingCodes = response.data.map(item => item); // get data code corporate all
|
||||
|
||||
let filteredArray = existingCodes.filter(e => e != codeCurrent)
|
||||
console.log(filteredArray);
|
||||
return filteredArray;
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
enqueueSnackbar('Failed to fetch existing codes', { variant: 'error' });
|
||||
try {
|
||||
let response = await axios.get('/corporates/1/code'); // get data all corporate
|
||||
let codeCurrent = '';
|
||||
if (isEdit) {
|
||||
let responseCodeCurrent = await axios.get(`/corporates/${currentCorporate?.id}/edit`); // get data current corporate
|
||||
codeCurrent = responseCodeCurrent.data.payor_id; // get data code corporate current
|
||||
}
|
||||
// console.log(response.data);
|
||||
let existingCodes = response.data.map((item) => item); // get data code corporate all
|
||||
|
||||
let filteredArray = existingCodes.filter((e) => e != codeCurrent);
|
||||
console.log(filteredArray);
|
||||
return filteredArray;
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
enqueueSnackbar('Failed to fetch existing codes', { variant: 'error' });
|
||||
}
|
||||
}
|
||||
|
||||
const defaultValues = useMemo(
|
||||
@@ -323,7 +319,6 @@ export default function CorporateForm({ isEdit, currentCorporate }: Props) {
|
||||
formData.append('policy_end', fPostFormat(data.policy_end));
|
||||
formData.append('linking_rules', data.linking_rules);
|
||||
|
||||
|
||||
// console.log('MOTHERFUCKER', data.linking_rules)
|
||||
|
||||
if (!isEdit) {
|
||||
@@ -479,7 +474,7 @@ export default function CorporateForm({ isEdit, currentCorporate }: Props) {
|
||||
id: 'Lilili',
|
||||
},
|
||||
];
|
||||
const [isDisabled, setIsDisabled] = useState(isEdit);
|
||||
const [isDisabled, setIsDisabled] = useState(isEdit);
|
||||
const handleTypeChange = (event: SelectChangeEvent) => {
|
||||
setValue('type', event.target.value);
|
||||
};
|
||||
@@ -520,19 +515,16 @@ export default function CorporateForm({ isEdit, currentCorporate }: Props) {
|
||||
</option>
|
||||
))}
|
||||
</RHFSelect>
|
||||
)}
|
||||
)}
|
||||
<RHFTextField name="code" label="Corporate Code" disabled={isDisabled} />
|
||||
|
||||
<RHFTextField name="name" label="Corporate Name" disabled={isDisabled} />
|
||||
|
||||
<RHFTextField name="payor_id" label="Payor ID" disabled={isDisabled} />
|
||||
|
||||
|
||||
{isEdit && (
|
||||
// <RHFTextField name="reason" label="Reason for update" />
|
||||
<RHFSelect
|
||||
name="reason"
|
||||
label="Reason for update"
|
||||
>
|
||||
<RHFSelect name="reason" label="Reason for update">
|
||||
<option value=""></option>
|
||||
<option value="Agreement changed">Agreement changed</option>
|
||||
<option value="Endorsement">Endorsement</option>
|
||||
@@ -575,13 +567,10 @@ export default function CorporateForm({ isEdit, currentCorporate }: Props) {
|
||||
<Grid item xs={12} md={4}>
|
||||
<Stack spacing={3}>
|
||||
<Card sx={{ p: 3 }}>
|
||||
{JSON.stringify(values.active)}
|
||||
<RHFSwitch name="active" label="Is Company Active" />
|
||||
{JSON.stringify(values.automatic_linking)}
|
||||
<RHFSwitch name="automatic_linking" label="Is Company Automatic Linking" />
|
||||
<Stack spacing={3} mt={2} alignItems="center">
|
||||
<Typography align="center">Company Logo</Typography>
|
||||
{/* <RHFUploadAvatar
|
||||
<Stack spacing={3} mt={2}>
|
||||
<Stack spacing={3} alignItems="center">
|
||||
<Typography align="center">Company Logo</Typography>
|
||||
{/* <RHFUploadAvatar
|
||||
name="logo"
|
||||
showPreview
|
||||
accept="image/*"
|
||||
@@ -589,7 +578,22 @@ export default function CorporateForm({ isEdit, currentCorporate }: Props) {
|
||||
onDrop={handleDrop}
|
||||
onRemove={handleRemove}
|
||||
/> */}
|
||||
<UploadImage setFile={setFile} currentImage={currentImage} />
|
||||
<UploadImage setFile={setFile} currentImage={currentImage} />
|
||||
</Stack>
|
||||
<Box>
|
||||
<Box
|
||||
sx={{ display: 'flex', placeContent: 'space-between', placeItems: 'center' }}
|
||||
>
|
||||
<Typography>Company Active</Typography>
|
||||
<RHFSwitch name="active" label="" labelPlacement="start" />
|
||||
</Box>
|
||||
<Box
|
||||
sx={{ display: 'flex', placeContent: 'space-between', placeItems: 'center' }}
|
||||
>
|
||||
<Typography>Company Automatic Linking</Typography>
|
||||
<RHFSwitch name="automatic_linking" label="" labelPlacement="start" />
|
||||
</Box>
|
||||
</Box>
|
||||
</Stack>
|
||||
</Card>
|
||||
<Card sx={{ p: 3 }}>
|
||||
@@ -598,7 +602,6 @@ export default function CorporateForm({ isEdit, currentCorporate }: Props) {
|
||||
Linking Rules
|
||||
</Typography>
|
||||
<Stack>
|
||||
{JSON.stringify(getValues('linking_rules'))}
|
||||
<RHFCustomMultiCheckbox name="linking_rules" options={linking_tools} />
|
||||
</Stack>
|
||||
</Stack>
|
||||
@@ -611,14 +614,12 @@ export default function CorporateForm({ isEdit, currentCorporate }: Props) {
|
||||
{/* <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>
|
||||
<Typography variant="h5">Policy Detail</Typography>
|
||||
|
||||
<input type="hidden" name="policy_id" />
|
||||
|
||||
<Stack spacing={1}>
|
||||
<RHFTextField name="policy_code" label="Policy Number"/>
|
||||
<RHFTextField name="policy_code" label="Policy Number" />
|
||||
{!currentCorporate?.id && (
|
||||
<Typography variant="caption">Will be generated if empty</Typography>
|
||||
)}
|
||||
@@ -627,10 +628,10 @@ export default function CorporateForm({ isEdit, currentCorporate }: Props) {
|
||||
{/* <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)" />
|
||||
<RHFDatepicker name="policy_start" label="Start Date" />
|
||||
</Grid>
|
||||
<Grid item xs={12} md={6}>
|
||||
<RHFDatepicker name="policy_end" label="End Date (YYYY-MM-DD)" />
|
||||
<RHFDatepicker name="policy_end" label="End Date" />
|
||||
</Grid>
|
||||
</Stack>
|
||||
|
||||
@@ -639,11 +640,13 @@ export default function CorporateForm({ isEdit, currentCorporate }: Props) {
|
||||
label={'Deposit Intial Fund (' + fCurrency(values.policy_total_premi) + ')'}
|
||||
/>
|
||||
|
||||
<Stack spacing={1}>
|
||||
<Typography variant="subtitle2" sx={{ color: 'text.secondary' }}>
|
||||
Minimal Deposit Policy Level
|
||||
</Typography>
|
||||
<Grid container>
|
||||
<Grid item xs={12}>
|
||||
<Grid container spacing={2}>
|
||||
<Grid item xs={12}>
|
||||
<Typography variant="subtitle2" sx={{ color: 'text.secondary' }}>
|
||||
Minimal Deposit Policy Level
|
||||
</Typography>
|
||||
</Grid>
|
||||
<Grid item xs={12} md={3}>
|
||||
<RHFTextField
|
||||
name="policy_minimal_deposit_percentage"
|
||||
@@ -659,13 +662,15 @@ export default function CorporateForm({ isEdit, currentCorporate }: Props) {
|
||||
/>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Stack>
|
||||
</Grid>
|
||||
|
||||
<Stack spacing={1}>
|
||||
<Typography variant="subtitle2" sx={{ color: 'text.secondary' }}>
|
||||
Minimal Alert Level
|
||||
</Typography>
|
||||
<Grid container>
|
||||
<Grid item xs={12}>
|
||||
<Grid container spacing={2}>
|
||||
<Grid item xs={12}>
|
||||
<Typography variant="subtitle2" sx={{ color: 'text.secondary' }}>
|
||||
Minimal Alert Level
|
||||
</Typography>
|
||||
</Grid>
|
||||
<Grid item xs={12} md={3}>
|
||||
<RHFTextField
|
||||
name="policy_minimal_alert_percentage"
|
||||
@@ -681,13 +686,15 @@ export default function CorporateForm({ isEdit, currentCorporate }: Props) {
|
||||
/>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Stack>
|
||||
</Grid>
|
||||
|
||||
<Stack spacing={1}>
|
||||
<Typography variant="subtitle2" sx={{ color: 'text.secondary' }}>
|
||||
Stop Service Level
|
||||
</Typography>
|
||||
<Grid container>
|
||||
<Grid item xs={12}>
|
||||
<Grid container spacing={2}>
|
||||
<Grid item xs={12}>
|
||||
<Typography variant="subtitle2" sx={{ color: 'text.secondary' }}>
|
||||
Stop Service Level
|
||||
</Typography>
|
||||
</Grid>
|
||||
<Grid item xs={12} md={3}>
|
||||
<RHFTextField
|
||||
name="policy_stop_service_percentage"
|
||||
@@ -703,7 +710,7 @@ export default function CorporateForm({ isEdit, currentCorporate }: Props) {
|
||||
/>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Stack>
|
||||
</Grid>
|
||||
</Stack>
|
||||
</Card>
|
||||
</Grid>
|
||||
|
||||
@@ -46,6 +46,7 @@ import HeaderBreadcrumbs from '../../components/HeaderBreadcrumbs';
|
||||
import BasePagination from '../../components/BasePagination';
|
||||
import { fCurrency } from '../../utils/formatNumber';
|
||||
import { enqueueSnackbar } from 'notistack';
|
||||
import { fDate } from '@/utils/formatTime';
|
||||
|
||||
export default function Corporates() {
|
||||
const { themeStretch } = useSettings();
|
||||
@@ -341,7 +342,7 @@ export default function Corporates() {
|
||||
</Button>
|
||||
</Link>
|
||||
<Link to={`/corporate/${row.id}/corporate-history`}>
|
||||
<HistoryIcon />
|
||||
<HistoryIcon />
|
||||
</Link>
|
||||
</Stack>
|
||||
</TableCell>
|
||||
@@ -379,36 +380,67 @@ export default function Corporates() {
|
||||
</Grid>
|
||||
|
||||
<Grid item xs={6}>
|
||||
<Grid Grid container>
|
||||
<Grid container>
|
||||
<Grid item xs={6}>
|
||||
Period
|
||||
</Grid>
|
||||
<Grid item xs={6}>
|
||||
: {row.current_policy?.start} - {row.current_policy?.end}
|
||||
<Box sx={{ display: 'flex', placeContent: 'space-between' }}>
|
||||
<span>: {fDate(row.current_policy?.start)}</span>-
|
||||
<span>{fDate(row.current_policy?.end)}</span>
|
||||
</Box>
|
||||
</Grid>
|
||||
|
||||
<Grid item xs={6}>
|
||||
Total Premi
|
||||
</Grid>
|
||||
<Grid item xs={6}>
|
||||
: {row.current_policy ? fCurrency(row.current_policy?.total_premi) : '-'}
|
||||
{row.current_policy ? (
|
||||
<Box sx={{ display: 'flex', placeContent: 'space-between' }}>
|
||||
<span>
|
||||
: {fCurrency(row.current_policy?.total_premi).split(' ')[0]}
|
||||
</span>
|
||||
<span>{fCurrency(row.current_policy?.total_premi).split(' ')[1]}</span>
|
||||
</Box>
|
||||
) : (
|
||||
'-'
|
||||
)}
|
||||
</Grid>
|
||||
|
||||
<Grid item xs={6}>
|
||||
Minimal Deposit
|
||||
</Grid>
|
||||
<Grid item xs={6}>
|
||||
:{' '}
|
||||
{row.current_policy
|
||||
? fCurrency(row.current_policy?.minimal_deposit_net)
|
||||
: '-'}
|
||||
{row.current_policy ? (
|
||||
<Box sx={{ display: 'flex', placeContent: 'space-between' }}>
|
||||
<span>
|
||||
: {fCurrency(row.current_policy?.minimal_deposit_net).split(' ')[0]}
|
||||
</span>
|
||||
<span>
|
||||
{fCurrency(row.current_policy?.minimal_deposit_net).split(' ')[1]}
|
||||
</span>
|
||||
</Box>
|
||||
) : (
|
||||
'-'
|
||||
)}
|
||||
</Grid>
|
||||
|
||||
<Grid item xs={6}>
|
||||
Corporate Limit
|
||||
</Grid>
|
||||
<Grid item xs={6}>
|
||||
: {row.current_policy ? fCurrency(row.current_policy?.limit_balance) : '-'}
|
||||
{row.current_policy ? (
|
||||
<Box sx={{ display: 'flex', placeContent: 'space-between' }}>
|
||||
<span>
|
||||
: {fCurrency(row.current_policy?.limit_balance).split(' ')[0]}
|
||||
</span>
|
||||
<span>
|
||||
{fCurrency(row.current_policy?.limit_balance).split(' ')[1]}
|
||||
</span>
|
||||
</Box>
|
||||
) : (
|
||||
'-'
|
||||
)}
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Grid>
|
||||
|
||||
@@ -560,6 +560,12 @@ export default function CorporatePlanList({handleSubmitSuccess}) {
|
||||
<Grid item xs={6}>
|
||||
: {row.email ?? '-'}
|
||||
</Grid>
|
||||
<Grid item xs={6}>
|
||||
Phone
|
||||
</Grid>
|
||||
<Grid item xs={6}>
|
||||
: {row.person?.phone ?? '-'}
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Grid>
|
||||
<Grid item xs={6}>
|
||||
|
||||
37
frontend/dashboard/src/pages/Report/DoctorRating/Index.tsx
Normal file
37
frontend/dashboard/src/pages/Report/DoctorRating/Index.tsx
Normal file
@@ -0,0 +1,37 @@
|
||||
import { Card, Grid, Container } from '@mui/material';
|
||||
import { useParams } from 'react-router-dom';
|
||||
import HeaderBreadcrumbs from '@/components/HeaderBreadcrumbs';
|
||||
import Page from '@/components/Page';
|
||||
import useSettings from '@/hooks/useSettings';
|
||||
import List from '../Prescription/List';
|
||||
|
||||
export default function DoctorRating(){
|
||||
const { themeStretch } = useSettings();
|
||||
|
||||
const { id } = useParams();
|
||||
|
||||
const pageTitle = 'Doctor Rating';
|
||||
|
||||
return(
|
||||
<Page title = {pageTitle}>
|
||||
<Container maxWidth = {themeStretch ? false : 'xl'}>
|
||||
<HeaderBreadcrumbs heading= {pageTitle}
|
||||
links={[
|
||||
{
|
||||
name: 'Report',
|
||||
href: '/report',
|
||||
|
||||
},
|
||||
{
|
||||
name: 'Doctor Rating',
|
||||
href: '/doctorrating',
|
||||
},
|
||||
]}
|
||||
/>
|
||||
|
||||
<List/>
|
||||
|
||||
</Container>
|
||||
</Page>
|
||||
);
|
||||
}
|
||||
427
frontend/dashboard/src/pages/Report/DoctorRating/List_2.tsx
Normal file
427
frontend/dashboard/src/pages/Report/DoctorRating/List_2.tsx
Normal file
@@ -0,0 +1,427 @@
|
||||
import {
|
||||
Box,
|
||||
Button,
|
||||
Card,
|
||||
Collapse,
|
||||
Paper,
|
||||
Select,
|
||||
SelectChangeEvent,
|
||||
Table,
|
||||
TableBody,
|
||||
TableCell,
|
||||
TableContainer,
|
||||
TableHead,
|
||||
TableRow,
|
||||
TextField,
|
||||
Typography,
|
||||
Stack,
|
||||
ButtonGroup,
|
||||
Grid,
|
||||
Chip,
|
||||
Dialog,
|
||||
DialogContent,
|
||||
DialogContentText,
|
||||
DialogActions,
|
||||
FormControl,
|
||||
Autocomplete,
|
||||
InputAdornment,
|
||||
IconButton,
|
||||
} from '@mui/material';
|
||||
|
||||
import {
|
||||
Link,
|
||||
NavLink as RouterLink,
|
||||
useSearchParams,
|
||||
useNavigate,
|
||||
useParams,
|
||||
} from 'react-router-dom';
|
||||
// hooks
|
||||
import React, { ChangeEvent, Component, useEffect, useRef, useState } from 'react';
|
||||
import useSettings from '../../../hooks/useSettings';
|
||||
// components
|
||||
import axios from '../../../utils/axios';
|
||||
import { LaravelPaginatedData } from '../../../@types/paginated-data';
|
||||
import { Icd } from '../../../@types/diagnosis';
|
||||
import BasePagination from '../../../components/BasePagination';
|
||||
import { Practitioner } from '../../../@types/doctor';
|
||||
import CreateIcon from '@mui/icons-material/Create';
|
||||
import { Props } from '../../../components/editor/index';
|
||||
import { red } from '@mui/material/colors';
|
||||
import { margin, padding } from '@mui/system';
|
||||
import { enqueueSnackbar } from 'notistack';
|
||||
import { Controller } from 'react-hook-form';
|
||||
|
||||
|
||||
import SvgIconStyle from '../../../components/SvgIconStyle';
|
||||
import { GridSearchIcon } from '@mui/x-data-grid';
|
||||
import { Search } from '@mui/icons-material';
|
||||
import { Icon } from '@iconify/react';
|
||||
import KeyboardArrowDownIcon from '@mui/icons-material/KeyboardArrowDown';
|
||||
import KeyboardArrowRightIcon from '@mui/icons-material/KeyboardArrowRight';
|
||||
|
||||
export default function List(){
|
||||
|
||||
const navigate = useNavigate();
|
||||
const { organization_id } = useParams();
|
||||
const [searchParams, setSearchParams] = useSearchParams();
|
||||
const [searchParamsOrganizations, setSearchParamsOrganizations] = useSearchParams();
|
||||
const [searchParamsSpecialities, setSearchParamsSpecialities] = useSearchParams();
|
||||
const [searchParamsFilter, setSearchParamsFilter] = useSearchParams();
|
||||
|
||||
function Filter(props: any) {
|
||||
// SEARCH
|
||||
const searchInput = useRef<HTMLInputElement>(null);
|
||||
const [searchText, setSearchText] = useState('');
|
||||
|
||||
//handle search
|
||||
const handleSearchChange = (event: any) => {
|
||||
const newSearchText = event.target.value ?? '';
|
||||
setSearchText(newSearchText);
|
||||
};
|
||||
|
||||
const handleSearchSubmit = (event: any) => {
|
||||
event.preventDefault();
|
||||
|
||||
props.onSearch(searchText);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
// Trigger First Search
|
||||
setSearchText(searchParams.get('search') ?? '');
|
||||
}, []);
|
||||
|
||||
const item = [
|
||||
{
|
||||
id: '',
|
||||
value: '',
|
||||
name: 'Semua',
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<form style={{ width: '100%' }}>
|
||||
<Grid container spacing={2} sx={{ justifyContent: 'space-between', alignItems: 'center' }}>
|
||||
<Grid item xs={12} sm={12} md={12} lg={12}>
|
||||
<TextField
|
||||
id="search-input"
|
||||
ref={searchInput}
|
||||
variant="outlined"
|
||||
fullWidth
|
||||
onChange={handleSearchChange}
|
||||
onKeyDown={(event) => {
|
||||
if (event.key === 'Enter') {
|
||||
handleSearchSubmit(event);
|
||||
}
|
||||
}}
|
||||
value={searchText}
|
||||
InputProps={{
|
||||
startAdornment: (
|
||||
<InputAdornment position="start">
|
||||
<Search />
|
||||
</InputAdornment>
|
||||
),
|
||||
placeholder: 'Search',
|
||||
}}
|
||||
/>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</form>
|
||||
);
|
||||
}
|
||||
function FilterForm(props: any) {
|
||||
return(
|
||||
<Grid
|
||||
container
|
||||
spacing={2}
|
||||
sx={{ p: 2, justifyContent: 'space-between', alignItems: 'center' }}
|
||||
>
|
||||
<Grid item xs={12} md={12} lg={12}>
|
||||
<Filter onSearch={applyItems} />
|
||||
</Grid>
|
||||
</Grid>
|
||||
);
|
||||
}
|
||||
|
||||
function createData(doctor: Practitioner): Practitioner {
|
||||
return {
|
||||
...doctor,
|
||||
/* user: doctor.user ? new User(doctor.user) : null; */
|
||||
};
|
||||
}
|
||||
|
||||
function Row(props: { row: ReturnType<typeof createData> }) {
|
||||
const { row } = props;
|
||||
const [open, setOpen] = React.useState(false);
|
||||
const [openDialog, setOpenDialog] = React.useState(false);
|
||||
|
||||
|
||||
|
||||
return (
|
||||
<React.Fragment>
|
||||
<TableRow>
|
||||
<TableCell>
|
||||
<IconButton aria-label="expand row" size="small" onClick={() => setOpen(!open)}>
|
||||
{open ? <KeyboardArrowDownIcon /> : <KeyboardArrowRightIcon />}
|
||||
</IconButton>
|
||||
</TableCell>
|
||||
|
||||
<TableCell align="left">{row.user ? row.user.sFirstName : '-'}</TableCell>
|
||||
<TableCell align="left">{row.nIDDokter ? row.nIDDokter : '-'}</TableCell>
|
||||
<TableCell align="left">{row.nRating ? row.nRating : '-'}</TableCell>
|
||||
<TableCell align="left">{row.sNotes ? row.sNotes : '-'}</TableCell>
|
||||
<TableCell align="left">{row.dCreateOn ? row.dCreateOn : '-'}</TableCell>
|
||||
|
||||
{/* <TableCell align="center">
|
||||
<ButtonGroup variant="text" aria-label="text button group">
|
||||
<Link to={'/report/prescription/' + row.id + '/show'}>
|
||||
<Button>
|
||||
<Icon icon="ph:eye-bold" style={{ width: '24px', height: '24px' }} />
|
||||
</Button>
|
||||
</Link>
|
||||
</ButtonGroup>
|
||||
</TableCell> */}
|
||||
</TableRow>
|
||||
{/* COLLAPSIBLE ROW */}
|
||||
<TableRow>
|
||||
<TableCell
|
||||
style={{ paddingBottom: 0, paddingTop: 0, backgroundColor: 'rgba(244, 246, 248, 0.5)' }}
|
||||
colSpan={6}
|
||||
>
|
||||
{/* <Collapse in={open} timeout="auto" unmountOnExit>
|
||||
<Box sx={{ margin: 1, pb: 2, pl: 4 }}>
|
||||
<Grid container>
|
||||
<Grid item xs={12} sx={{ padding: 2 }}>
|
||||
<Grid container>
|
||||
<Grid item xs={6}>
|
||||
Metode Pembayaran
|
||||
</Grid>
|
||||
<Grid item xs={6}>
|
||||
: {row.payment_method ? row.payment_method : '-'}
|
||||
</Grid>
|
||||
|
||||
<Grid item xs={6}>
|
||||
Jenis Benefit
|
||||
</Grid>
|
||||
<Grid item xs={6}>
|
||||
: -
|
||||
</Grid>
|
||||
<Grid item xs={6}>
|
||||
Durasi
|
||||
</Grid>
|
||||
<Grid item xs={6}>
|
||||
: {row.duration ? row.duration : '-'}
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Box>
|
||||
</Collapse> */}
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
|
||||
{/* END COLLAPSIBLE ROW */}
|
||||
<Dialog
|
||||
open={openDialog}
|
||||
onClose={() => {
|
||||
setOpenDialog(false);
|
||||
}}
|
||||
aria-labelledby="alert-dialog-title"
|
||||
aria-describedby="alert-dialog-description"
|
||||
>
|
||||
<DialogContent sx={{ p: 5 }}>
|
||||
<Icon
|
||||
icon="eva:trash-2-outline"
|
||||
style={{
|
||||
width: '100px',
|
||||
height: '100px',
|
||||
color: '#FF0000',
|
||||
margin: 'auto',
|
||||
display: 'block',
|
||||
marginBottom: '20px',
|
||||
alignContent: 'center',
|
||||
}}
|
||||
/>
|
||||
<DialogContentText sx={{ fontWeight: 'bold', pb: 1 }} id="alert-dialog-title">
|
||||
Apakah anda yakin ingin menghapus
|
||||
</DialogContentText>
|
||||
<Typography sx={{ fontWeight: 'bold' }} id="alert-dialog-title">
|
||||
{row.name}?
|
||||
</Typography>
|
||||
</DialogContent>
|
||||
<DialogActions>
|
||||
<Button
|
||||
onClick={() => {
|
||||
setOpenDialog(false);
|
||||
}}
|
||||
color="primary"
|
||||
>
|
||||
Batal
|
||||
</Button>
|
||||
{/* <Button
|
||||
onClick={() => {
|
||||
handleDelete(row.id);
|
||||
}}
|
||||
color="primary"
|
||||
autoFocus
|
||||
>
|
||||
Hapus
|
||||
</Button> */}
|
||||
</DialogActions>
|
||||
</Dialog>
|
||||
</React.Fragment>
|
||||
);
|
||||
}
|
||||
|
||||
const headStyle = {
|
||||
fontWeight: 'bold',
|
||||
};
|
||||
// Dummy Default Data
|
||||
const [dataTableIsLoading, setDataTableLoading] = useState(true);
|
||||
const [dataTableLastRequest, setDataTableLastRequest] = useState(0);
|
||||
const [dataTableResponseState, setDataTableResponseState] = useState('idle');
|
||||
const [dataTableData, setDataTableData] = useState<LaravelPaginatedData>({
|
||||
current_page: 1,
|
||||
data: [],
|
||||
path: '',
|
||||
first_page_url: '',
|
||||
last_page: 1,
|
||||
last_page_url: '',
|
||||
next_page_url: '',
|
||||
prev_page_url: '',
|
||||
per_page: 10,
|
||||
from: 0,
|
||||
to: 0,
|
||||
total: 0,
|
||||
});
|
||||
const [dataTablePage, setDataTablePage] = useState(5);
|
||||
|
||||
const loadDataTableData = async (appliedFilter: any | null = null) => {
|
||||
setDataTableLoading(true);
|
||||
const filter = appliedFilter ? appliedFilter : Object.fromEntries([...searchParams.entries()]);
|
||||
const response = await axios.get('/doctorrating ', {
|
||||
params: filter,
|
||||
});
|
||||
setDataTableLoading(false);
|
||||
setDataTableData(response.data);
|
||||
};
|
||||
|
||||
// const applyFilter = async (searchFilter: string) => {
|
||||
// await loadDataTableData({ search: searchFilter });
|
||||
// setSearchParams({ search: searchFilter });
|
||||
// };
|
||||
|
||||
const applyItems = async (
|
||||
searchFilter: string,
|
||||
searchFilterOrganization: string,
|
||||
searchFilterSpecialities: string
|
||||
) => {
|
||||
await loadDataTableData({
|
||||
search: searchFilter,
|
||||
organization_id: searchFilterOrganization,
|
||||
speciality_id: searchFilterSpecialities,
|
||||
});
|
||||
setSearchParamsFilter({
|
||||
search: searchFilter,
|
||||
organization_id: searchFilterOrganization,
|
||||
speciality_id: searchFilterSpecialities,
|
||||
});
|
||||
};
|
||||
|
||||
const handlePageChange = (event: ChangeEvent, value: number) => {
|
||||
const filter = Object.fromEntries([...searchParams.entries(), ['page', value]]);
|
||||
loadDataTableData(filter);
|
||||
setSearchParams(filter);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
loadDataTableData();
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<Stack>
|
||||
{/* <Ambulace /> */}
|
||||
|
||||
<Card sx={{ marginTop: '30px' }}>
|
||||
<FilterForm sx={{ marginTop: '100px' }} />
|
||||
|
||||
{/* The Main Table */}
|
||||
<TableContainer component={Paper}>
|
||||
<Table>
|
||||
<TableBody>
|
||||
<TableRow>
|
||||
{/* <TableCell colSpan={8} rowSpan={1} align="center" /> */}
|
||||
<TableCell style={headStyle} align="left" />
|
||||
<TableCell style={headStyle} rowSpan={2} align="left">
|
||||
Nama User
|
||||
</TableCell>
|
||||
<TableCell style={headStyle} rowSpan={2} align="left">
|
||||
ID Dokter
|
||||
</TableCell>
|
||||
<TableCell style={headStyle} rowSpan={2} align="left">
|
||||
Rating
|
||||
</TableCell>
|
||||
<TableCell style={headStyle} rowSpan={2} align="left">
|
||||
Notes
|
||||
</TableCell>
|
||||
<TableCell style={headStyle} rowSpan={2} align="left">
|
||||
Created On
|
||||
</TableCell>
|
||||
|
||||
</TableRow>
|
||||
{/* <TableRow>
|
||||
<TableCell style={headStyle} align="left" />
|
||||
<TableCell style={headStyle} align="left">
|
||||
Tanggal Booking
|
||||
</TableCell>
|
||||
<TableCell style={headStyle} align="left">
|
||||
Tanggal Appointment
|
||||
</TableCell>
|
||||
<TableCell style={headStyle} align="left">
|
||||
Faskes
|
||||
</TableCell>
|
||||
<TableCell style={headStyle} align="left">
|
||||
Nama Dokter
|
||||
</TableCell>
|
||||
<TableCell style={headStyle} align="left">
|
||||
Spesialisasi
|
||||
</TableCell>
|
||||
<TableCell style={headStyle} align="left">
|
||||
Pasien
|
||||
</TableCell>
|
||||
<TableCell style={headStyle} align="left">
|
||||
Dokter
|
||||
</TableCell>
|
||||
</TableRow> */}
|
||||
</TableBody>
|
||||
{dataTableIsLoading ? (
|
||||
<TableBody>
|
||||
<TableRow>
|
||||
<TableCell colSpan={8} align="center">
|
||||
Loading
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
</TableBody>
|
||||
) : (dataTableData.data && dataTableData.data.length === 0) ? (
|
||||
|
||||
<TableBody>
|
||||
<TableRow>
|
||||
<TableCell colSpan={8} align="center">
|
||||
No Data
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
</TableBody>
|
||||
) : (
|
||||
<TableBody>
|
||||
{dataTableData && dataTableData.map((row) => (
|
||||
<Row key={row.id} row={row} />
|
||||
))}
|
||||
</TableBody>
|
||||
)}
|
||||
</Table>
|
||||
</TableContainer>
|
||||
|
||||
<BasePagination paginationData={dataTableData} onPageChange={handlePageChange} />
|
||||
</Card>
|
||||
</Stack>
|
||||
);
|
||||
}
|
||||
38
frontend/dashboard/src/pages/Report/DoctorRating/index.tsx
Normal file
38
frontend/dashboard/src/pages/Report/DoctorRating/index.tsx
Normal file
@@ -0,0 +1,38 @@
|
||||
import { Card, Grid, Container } from '@mui/material';
|
||||
import { useParams } from 'react-router-dom';
|
||||
import HeaderBreadcrumbs from '@/components/HeaderBreadcrumbs';
|
||||
import Page from '@/components/Page';
|
||||
import useSettings from '@/hooks/useSettings';
|
||||
import List from './List_2';
|
||||
|
||||
export default function DoctorRating(){
|
||||
const { themeStretch } = useSettings();
|
||||
|
||||
const { id } = useParams();
|
||||
|
||||
const pageTitle = 'Doctor Rating';
|
||||
|
||||
return(
|
||||
<Page title = {pageTitle}>
|
||||
<Container maxWidth = {themeStretch ? false : 'xl'}>
|
||||
<HeaderBreadcrumbs heading= {pageTitle}
|
||||
links={[
|
||||
{
|
||||
name: 'Report',
|
||||
href: '/report',
|
||||
|
||||
},
|
||||
{
|
||||
name: 'Doctor Rating',
|
||||
href: '/doctorrating',
|
||||
},
|
||||
]}
|
||||
/>
|
||||
|
||||
|
||||
<List/>
|
||||
|
||||
</Container>
|
||||
</Page>
|
||||
);
|
||||
}
|
||||
@@ -63,7 +63,7 @@ import KeyboardArrowRightIcon from '@mui/icons-material/KeyboardArrowRight';
|
||||
import { DesktopDatePicker, LocalizationProvider } from '@mui/x-date-pickers';
|
||||
import { AdapterDateFns } from '@mui/x-date-pickers/AdapterDateFns';
|
||||
import { MenuItem } from '@mui/material';
|
||||
import { fPostFormat } from '@/utils/formatTime';
|
||||
import { fDateOnly } from '@/utils/formatTime';
|
||||
import AutocompleteLinksehatHealthcare from '@/components/autocomplete/AutocompleteLinksehatHealthcare';
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
@@ -81,12 +81,10 @@ export default function List() {
|
||||
const [searchParamsFilter, setSearchParamsFilter] = useSearchParams();
|
||||
|
||||
useEffect(() => {
|
||||
|
||||
// axios.get(`/search-organizations`).then((response) => {
|
||||
// setOrganizationOptions(response.data);
|
||||
// });
|
||||
|
||||
}, [])
|
||||
}, []);
|
||||
|
||||
function Filter(props: any) {
|
||||
// SEARCH
|
||||
@@ -123,17 +121,17 @@ export default function List() {
|
||||
];
|
||||
|
||||
const paymentStatusOptions = {
|
||||
'settlement' : 'Diterima',
|
||||
'expired' : 'Kadaluarsa',
|
||||
'capture' : 'Captured',
|
||||
'deny' : 'Ditolak',
|
||||
'pending' : 'Menunggu Pembayaran',
|
||||
'cancel' : 'Dibatalkan',
|
||||
'refund' : 'Dikembalikan',
|
||||
'expire' : 'Kadaluarsa',
|
||||
'cod' : 'COD',
|
||||
'FAILED' : 'Gagal',
|
||||
'COMPLETED' : 'Complete',
|
||||
settlement: 'Diterima',
|
||||
expired: 'Kadaluarsa',
|
||||
capture: 'Captured',
|
||||
deny: 'Ditolak',
|
||||
pending: 'Menunggu Pembayaran',
|
||||
cancel: 'Dibatalkan',
|
||||
refund: 'Dikembalikan',
|
||||
expire: 'Kadaluarsa',
|
||||
cod: 'COD',
|
||||
FAILED: 'Gagal',
|
||||
COMPLETED: 'Complete',
|
||||
};
|
||||
|
||||
const dataOrganizations = [];
|
||||
@@ -151,10 +149,13 @@ export default function List() {
|
||||
onKeyDown={(event) => {
|
||||
if (event.key === 'Enter') {
|
||||
// handleSearchSubmit(event);
|
||||
|
||||
const filter = Object.fromEntries([...searchParams.entries(), ['search', searchText]]);
|
||||
setSearchParams(filter)
|
||||
loadDataTableData(filter)
|
||||
|
||||
const filter = Object.fromEntries([
|
||||
...searchParams.entries(),
|
||||
['search', searchText],
|
||||
]);
|
||||
setSearchParams(filter);
|
||||
loadDataTableData(filter);
|
||||
}
|
||||
}}
|
||||
label="Search"
|
||||
@@ -170,44 +171,55 @@ export default function List() {
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item md={2}>
|
||||
<FormControl fullWidth>
|
||||
<InputLabel>
|
||||
Payment Status
|
||||
</InputLabel>
|
||||
<Select
|
||||
value={searchParams.get('payment_status') ?? 'semua'}
|
||||
label="Payment Status"
|
||||
onChange={(el) => {
|
||||
// console.log(el.target.value)
|
||||
const filter = Object.fromEntries([...searchParams.entries(), ['payment_status', el.target.value]]);
|
||||
setSearchParams(filter)
|
||||
loadDataTableData(filter)
|
||||
}}
|
||||
>
|
||||
<MenuItem value={'semua'}>Semua</MenuItem>
|
||||
{Object.entries(paymentStatusOptions).map((option, index) => (
|
||||
<MenuItem value={option[0]} key={index}>{option[1]}</MenuItem>
|
||||
))}
|
||||
</Select>
|
||||
<FormControl fullWidth>
|
||||
<InputLabel>Payment Status</InputLabel>
|
||||
<Select
|
||||
value={searchParams.get('payment_status') ?? 'semua'}
|
||||
label="Payment Status"
|
||||
onChange={(el) => {
|
||||
// console.log(el.target.value)
|
||||
const filter = Object.fromEntries([
|
||||
...searchParams.entries(),
|
||||
['payment_status', el.target.value],
|
||||
]);
|
||||
setSearchParams(filter);
|
||||
loadDataTableData(filter);
|
||||
}}
|
||||
>
|
||||
<MenuItem value={'semua'}>Semua</MenuItem>
|
||||
{Object.entries(paymentStatusOptions).map((option, index) => (
|
||||
<MenuItem value={option[0]} key={index}>
|
||||
{option[1]}
|
||||
</MenuItem>
|
||||
))}
|
||||
</Select>
|
||||
</FormControl>
|
||||
</Grid>
|
||||
<Grid item md={2}>
|
||||
<AutocompleteLinksehatHealthcare
|
||||
onChange={(value) => {
|
||||
if (value) {
|
||||
const filter = Object.fromEntries([...searchParams.entries(), ['healthcare_id', value.nID ?? '']]);
|
||||
setSearchParams(filter)
|
||||
loadDataTableData(filter)
|
||||
setOrganizationOptions([value])
|
||||
const filter = Object.fromEntries([
|
||||
...searchParams.entries(),
|
||||
['healthcare_id', value.nID ?? ''],
|
||||
]);
|
||||
setSearchParams(filter);
|
||||
loadDataTableData(filter);
|
||||
setOrganizationOptions([value]);
|
||||
} else {
|
||||
const filter = Object.fromEntries([...searchParams.entries(), ['healthcare_id', '']]);
|
||||
setSearchParams(filter)
|
||||
loadDataTableData(filter)
|
||||
setOrganizationOptions([])
|
||||
const filter = Object.fromEntries([
|
||||
...searchParams.entries(),
|
||||
['healthcare_id', ''],
|
||||
]);
|
||||
setSearchParams(filter);
|
||||
loadDataTableData(filter);
|
||||
setOrganizationOptions([]);
|
||||
}
|
||||
}}
|
||||
currentOptions={organizationOptions}
|
||||
currentValue={organizationOptions?.find((org) => org?.nID == searchParams.get('healthcare_id'))}
|
||||
currentValue={organizationOptions?.find(
|
||||
(org) => org?.nID == searchParams.get('healthcare_id')
|
||||
)}
|
||||
textLabel="Rumah Sakit"
|
||||
placeholder="Nama"
|
||||
/>
|
||||
@@ -219,30 +231,21 @@ export default function List() {
|
||||
value={searchParams.get('appointment_start')}
|
||||
inputFormat="dd/MM/yyyy"
|
||||
onChange={(value) => {
|
||||
|
||||
try {
|
||||
|
||||
if (value && !!Date.parse(value)) {
|
||||
const date = value ? fDateOnly(value) : '';
|
||||
var entries = [...searchParams.entries(), ['appointment_start', date ?? '']];
|
||||
if (!searchParams.get('appointment_end')) {
|
||||
entries = [...entries, ['appointment_end', date ?? '']];
|
||||
}
|
||||
const filter = Object.fromEntries(entries);
|
||||
|
||||
const date = value ? fPostFormat(value) : ''
|
||||
var entries = [...searchParams.entries(), ['appointment_start', date ?? '']];
|
||||
if (!searchParams.get('appointment_end')) {
|
||||
entries = [...entries, ['appointment_end', date ?? '']];
|
||||
}
|
||||
const filter = Object.fromEntries(entries);
|
||||
|
||||
setSearchParams(filter)
|
||||
loadDataTableData(filter)
|
||||
}
|
||||
} catch (e) {}
|
||||
setSearchParams(filter);
|
||||
loadDataTableData(filter);
|
||||
}
|
||||
} catch (e) {}
|
||||
}}
|
||||
renderInput={(params) => (
|
||||
<TextField
|
||||
{...params}
|
||||
fullWidth
|
||||
label="Start"
|
||||
/>
|
||||
)}
|
||||
renderInput={(params) => <TextField {...params} fullWidth label="Start" />}
|
||||
/>
|
||||
</LocalizationProvider>
|
||||
</Grid>
|
||||
@@ -254,18 +257,16 @@ export default function List() {
|
||||
inputFormat="dd/MM/yyyy"
|
||||
onChange={(value) => {
|
||||
try {
|
||||
|
||||
if (value && !!Date.parse(value)) {
|
||||
|
||||
const date = fPostFormat(value)
|
||||
const date = fDateOnly(value);
|
||||
var entries = [...searchParams.entries(), ['appointment_end', date ?? '']];
|
||||
if (!searchParams.get('appointment_start')) {
|
||||
entries = [...entries, ['appointment_start', date ?? '']];
|
||||
}
|
||||
const filter = Object.fromEntries(entries);
|
||||
|
||||
setSearchParams(filter)
|
||||
loadDataTableData(filter)
|
||||
|
||||
setSearchParams(filter);
|
||||
loadDataTableData(filter);
|
||||
}
|
||||
} catch (e) {}
|
||||
}}
|
||||
@@ -488,12 +489,9 @@ export default function List() {
|
||||
const loadDataTableData = async (appliedFilter: any | null = null) => {
|
||||
setDataTableLoading(true);
|
||||
const filter = appliedFilter ? appliedFilter : Object.fromEntries([...searchParams.entries()]);
|
||||
const response = await axios.get(
|
||||
'/linksehat/payments',
|
||||
{
|
||||
params: filter,
|
||||
}
|
||||
);
|
||||
const response = await axios.get('/linksehat/payments', {
|
||||
params: filter,
|
||||
});
|
||||
setDataTableLoading(false);
|
||||
setDataTableData(response.data.data);
|
||||
};
|
||||
@@ -508,7 +506,7 @@ export default function List() {
|
||||
searchFilterOrganization: string,
|
||||
searchFilterPaymentStatus: string,
|
||||
searchFilterAppointmentStart: string,
|
||||
searchFilterAppointmentEnd: string,
|
||||
searchFilterAppointmentEnd: string
|
||||
) => {
|
||||
await loadDataTableData({
|
||||
search: searchFilter,
|
||||
|
||||
@@ -27,7 +27,6 @@ export default function Doctor() {
|
||||
},
|
||||
]}
|
||||
/>
|
||||
|
||||
<List />
|
||||
</Container>
|
||||
</Page>
|
||||
|
||||
@@ -53,10 +53,14 @@ import { Controller } from 'react-hook-form';
|
||||
|
||||
import SvgIconStyle from '../../../components/SvgIconStyle';
|
||||
import { GridSearchIcon } from '@mui/x-data-grid';
|
||||
import { Search } from '@mui/icons-material';
|
||||
import { Add, Search } from '@mui/icons-material';
|
||||
import { Icon } from '@iconify/react';
|
||||
import KeyboardArrowDownIcon from '@mui/icons-material/KeyboardArrowDown';
|
||||
import KeyboardArrowRightIcon from '@mui/icons-material/KeyboardArrowRight';
|
||||
import { RHFDatepicker } from '@/components/hook-form';
|
||||
import { DesktopDatePicker, LocalizationProvider } from '@mui/x-date-pickers';
|
||||
import { AdapterDateFns } from '@mui/x-date-pickers/AdapterDateFns';
|
||||
import { fDateOnly } from '@/utils/formatTime';
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
@@ -103,7 +107,7 @@ export default function List() {
|
||||
return (
|
||||
<form style={{ width: '100%' }}>
|
||||
<Grid container spacing={2} sx={{ justifyContent: 'space-between', alignItems: 'center' }}>
|
||||
<Grid item xs={12} sm={12} md={12} lg={12}>
|
||||
<Grid item xs={12} md={6}>
|
||||
<TextField
|
||||
id="search-input"
|
||||
ref={searchInput}
|
||||
@@ -126,6 +130,74 @@ export default function List() {
|
||||
}}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={12} md={2}>
|
||||
<LocalizationProvider dateAdapter={AdapterDateFns}>
|
||||
<DesktopDatePicker
|
||||
value={searchParams.get('startDate')}
|
||||
inputFormat="dd/MM/yyyy"
|
||||
onChange={(value) => {
|
||||
try {
|
||||
if (value && !!Date.parse(value)) {
|
||||
const date = value ? fDateOnly(value) : '';
|
||||
var entries = [...searchParams.entries(), ['startDate', date ?? '']];
|
||||
if (!searchParams.get('endDate')) {
|
||||
entries = [...entries, ['endDate', date ?? '']];
|
||||
}
|
||||
const filter = Object.fromEntries(entries);
|
||||
|
||||
setSearchParams(filter);
|
||||
loadDataTableData(filter);
|
||||
}
|
||||
} catch (e) {}
|
||||
}}
|
||||
renderInput={(params) => <TextField {...params} fullWidth label="Start" />}
|
||||
/>
|
||||
</LocalizationProvider>
|
||||
</Grid>
|
||||
<Grid item xs={12} md={2}>
|
||||
<LocalizationProvider dateAdapter={AdapterDateFns}>
|
||||
<DesktopDatePicker
|
||||
value={searchParams.get('endDate')}
|
||||
inputFormat="dd/MM/yyyy"
|
||||
onChange={(value) => {
|
||||
try {
|
||||
if (value && !!Date.parse(value)) {
|
||||
const date = fDateOnly(value);
|
||||
var entries = [...searchParams.entries(), ['endDate', date ?? '']];
|
||||
if (!searchParams.get('startDate')) {
|
||||
entries = [...entries, ['startDate', date ?? '']];
|
||||
}
|
||||
const filter = Object.fromEntries(entries);
|
||||
|
||||
setSearchParams(filter);
|
||||
loadDataTableData(filter);
|
||||
}
|
||||
} catch (e) {}
|
||||
}}
|
||||
renderInput={(params) => (
|
||||
<TextField
|
||||
{...params}
|
||||
fullWidth
|
||||
label="End"
|
||||
// error={!!error}
|
||||
// helperText={error?.message}
|
||||
// {...other}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
</LocalizationProvider>
|
||||
</Grid>
|
||||
<Grid item xs={12} md={2}>
|
||||
<Button
|
||||
variant="outlined"
|
||||
fullWidth
|
||||
startIcon={<Add />}
|
||||
sx={{ p: 1.8 }}
|
||||
onClick={exportExcel}
|
||||
>
|
||||
Export
|
||||
</Button>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</form>
|
||||
);
|
||||
@@ -188,6 +260,8 @@ export default function List() {
|
||||
<TableCell align="left">{row.health_care ? row.health_care : '-'}</TableCell>
|
||||
<TableCell align="left">{row.doctor_name ? row.doctor_name : '-'}</TableCell>
|
||||
<TableCell align="left">{row.speciality ? row.speciality : '-'}</TableCell>
|
||||
<TableCell align="left">{row.pasien_name ? row.pasien_name : '-'}</TableCell>
|
||||
<TableCell align="left">{row.pasien_phone ? row.pasien_phone : '-'}</TableCell>
|
||||
<TableCell align="left">{row.appointment_media ? row.appointment_media : '-'}</TableCell>
|
||||
<TableCell align="left">{row.patient_media ? row.patient_media : '-'}</TableCell>
|
||||
<TableCell align="left">{row.doctor_media ? row.doctor_media : '-'}</TableCell>
|
||||
@@ -329,6 +403,27 @@ export default function List() {
|
||||
setDataTableData(response.data);
|
||||
};
|
||||
|
||||
const exportExcel = async () => {
|
||||
var filter = Object.fromEntries([...searchParams.entries()]);
|
||||
|
||||
await axios
|
||||
.get('live-chat/export', { params: filter })
|
||||
.then((res) => {
|
||||
enqueueSnackbar('Data berhasil di Export', {
|
||||
variant: 'success',
|
||||
anchorOrigin: { horizontal: 'right', vertical: 'top' },
|
||||
});
|
||||
|
||||
document.location.href = res.data.data.file_url;
|
||||
})
|
||||
.catch((err) =>
|
||||
enqueueSnackbar('Data Gagal di Export', {
|
||||
variant: 'error',
|
||||
anchorOrigin: { horizontal: 'right', vertical: 'top' },
|
||||
})
|
||||
);
|
||||
};
|
||||
|
||||
// const applyFilter = async (searchFilter: string) => {
|
||||
// await loadDataTableData({ search: searchFilter });
|
||||
// setSearchParams({ search: searchFilter });
|
||||
@@ -390,6 +485,12 @@ export default function List() {
|
||||
<TableCell style={headStyle} rowSpan={2} align="left">
|
||||
Spesialisasi
|
||||
</TableCell>
|
||||
<TableCell style={headStyle} rowSpan={2} align="left">
|
||||
Nama Pasien
|
||||
</TableCell>
|
||||
<TableCell style={headStyle} rowSpan={2} align="left">
|
||||
No Telepon Pasien
|
||||
</TableCell>
|
||||
<TableCell style={headStyle} rowSpan={2} align="left">
|
||||
Appointment Via App/Website
|
||||
</TableCell>
|
||||
@@ -411,20 +512,20 @@ export default function List() {
|
||||
<TableRow>
|
||||
<TableCell style={headStyle} align="left" />
|
||||
{/* <TableCell style={headStyle} align="left">
|
||||
Tanggal Booking
|
||||
</TableCell>
|
||||
<TableCell style={headStyle} align="left">
|
||||
Tanggal Appointment
|
||||
</TableCell>
|
||||
<TableCell style={headStyle} align="left">
|
||||
Faskes
|
||||
</TableCell>
|
||||
<TableCell style={headStyle} align="left">
|
||||
Nama Dokter
|
||||
</TableCell>
|
||||
<TableCell style={headStyle} align="left">
|
||||
Spesialisasi
|
||||
</TableCell> */}
|
||||
Tanggal Booking
|
||||
</TableCell>
|
||||
<TableCell style={headStyle} align="left">
|
||||
Tanggal Appointment
|
||||
</TableCell>
|
||||
<TableCell style={headStyle} align="left">
|
||||
Faskes
|
||||
</TableCell>
|
||||
<TableCell style={headStyle} align="left">
|
||||
Nama Dokter
|
||||
</TableCell>
|
||||
<TableCell style={headStyle} align="left">
|
||||
Spesialisasi
|
||||
</TableCell> */}
|
||||
<TableCell style={headStyle} align="left">
|
||||
Pasien
|
||||
</TableCell>
|
||||
|
||||
@@ -1,440 +1,428 @@
|
||||
import {
|
||||
Box,
|
||||
Button,
|
||||
Card,
|
||||
Collapse,
|
||||
Paper,
|
||||
Select,
|
||||
SelectChangeEvent,
|
||||
Table,
|
||||
TableBody,
|
||||
TableCell,
|
||||
TableContainer,
|
||||
TableHead,
|
||||
TableRow,
|
||||
TextField,
|
||||
Typography,
|
||||
Stack,
|
||||
ButtonGroup,
|
||||
Grid,
|
||||
Chip,
|
||||
Dialog,
|
||||
DialogContent,
|
||||
DialogContentText,
|
||||
DialogActions,
|
||||
FormControl,
|
||||
Autocomplete,
|
||||
InputAdornment,
|
||||
IconButton,
|
||||
} from '@mui/material';
|
||||
Box,
|
||||
Button,
|
||||
Card,
|
||||
Collapse,
|
||||
Paper,
|
||||
Select,
|
||||
SelectChangeEvent,
|
||||
Table,
|
||||
TableBody,
|
||||
TableCell,
|
||||
TableContainer,
|
||||
TableHead,
|
||||
TableRow,
|
||||
TextField,
|
||||
Typography,
|
||||
Stack,
|
||||
ButtonGroup,
|
||||
Grid,
|
||||
Chip,
|
||||
Dialog,
|
||||
DialogContent,
|
||||
DialogContentText,
|
||||
DialogActions,
|
||||
FormControl,
|
||||
Autocomplete,
|
||||
InputAdornment,
|
||||
IconButton,
|
||||
} from '@mui/material';
|
||||
|
||||
import {
|
||||
Link,
|
||||
NavLink as RouterLink,
|
||||
useSearchParams,
|
||||
useNavigate,
|
||||
useParams,
|
||||
} from 'react-router-dom';
|
||||
// hooks
|
||||
import React, { ChangeEvent, Component, useEffect, useRef, useState } from 'react';
|
||||
import useSettings from '../../../hooks/useSettings';
|
||||
// components
|
||||
import axios from '../../../utils/axios';
|
||||
import { LaravelPaginatedData } from '../../../@types/paginated-data';
|
||||
import { Icd } from '../../../@types/diagnosis';
|
||||
import BasePagination from '../../../components/BasePagination';
|
||||
import { Practitioner } from '../../../@types/doctor';
|
||||
import CreateIcon from '@mui/icons-material/Create';
|
||||
import { Props } from '../../../components/editor/index';
|
||||
import { red } from '@mui/material/colors';
|
||||
import { margin, padding } from '@mui/system';
|
||||
import { enqueueSnackbar } from 'notistack';
|
||||
import { Controller } from 'react-hook-form';
|
||||
import { User } from '../../../Models/User';
|
||||
|
||||
|
||||
import SvgIconStyle from '../../../components/SvgIconStyle';
|
||||
import { GridSearchIcon } from '@mui/x-data-grid';
|
||||
import { Search } from '@mui/icons-material';
|
||||
import { Icon } from '@iconify/react';
|
||||
import KeyboardArrowDownIcon from '@mui/icons-material/KeyboardArrowDown';
|
||||
import KeyboardArrowRightIcon from '@mui/icons-material/KeyboardArrowRight';
|
||||
|
||||
export default function List(){
|
||||
|
||||
const navigate = useNavigate();
|
||||
const { organization_id } = useParams();
|
||||
const [searchParams, setSearchParams] = useSearchParams();
|
||||
const [searchParamsOrganizations, setSearchParamsOrganizations] = useSearchParams();
|
||||
const [searchParamsSpecialities, setSearchParamsSpecialities] = useSearchParams();
|
||||
const [searchParamsFilter, setSearchParamsFilter] = useSearchParams();
|
||||
|
||||
function Filter(props: any) {
|
||||
// SEARCH
|
||||
const searchInput = useRef<HTMLInputElement>(null);
|
||||
const [searchText, setSearchText] = useState('');
|
||||
|
||||
import {
|
||||
Link,
|
||||
NavLink as RouterLink,
|
||||
useSearchParams,
|
||||
useNavigate,
|
||||
useParams,
|
||||
} from 'react-router-dom';
|
||||
// hooks
|
||||
import React, { ChangeEvent, Component, useEffect, useRef, useState } from 'react';
|
||||
import useSettings from '../../../hooks/useSettings';
|
||||
// components
|
||||
import axios from '../../../utils/axios';
|
||||
import { LaravelPaginatedData } from '../../../@types/paginated-data';
|
||||
import { Icd } from '../../../@types/diagnosis';
|
||||
import BasePagination from '../../../components/BasePagination';
|
||||
import { Practitioner } from '../../../@types/doctor';
|
||||
import CreateIcon from '@mui/icons-material/Create';
|
||||
import { Props } from '../../../components/editor/index';
|
||||
import { red } from '@mui/material/colors';
|
||||
import { margin, padding } from '@mui/system';
|
||||
import { enqueueSnackbar } from 'notistack';
|
||||
import { Controller } from 'react-hook-form';
|
||||
//handle search
|
||||
const handleSearchChange = (event: any) => {
|
||||
const newSearchText = event.target.value ?? '';
|
||||
setSearchText(newSearchText);
|
||||
};
|
||||
|
||||
import SvgIconStyle from '../../../components/SvgIconStyle';
|
||||
import { GridSearchIcon } from '@mui/x-data-grid';
|
||||
import { Search } from '@mui/icons-material';
|
||||
import { Icon } from '@iconify/react';
|
||||
import KeyboardArrowDownIcon from '@mui/icons-material/KeyboardArrowDown';
|
||||
import KeyboardArrowRightIcon from '@mui/icons-material/KeyboardArrowRight';
|
||||
const handleSearchSubmit = (event: any) => {
|
||||
event.preventDefault();
|
||||
|
||||
props.onSearch(searchText);
|
||||
};
|
||||
|
||||
export default function List(){
|
||||
|
||||
const navigate = useNavigate();
|
||||
const { organization_id } = useParams();
|
||||
const [searchParams, setSearchParams] = useSearchParams();
|
||||
const [searchParamsOrganizations, setSearchParamsOrganizations] = useSearchParams();
|
||||
const [searchParamsSpecialities, setSearchParamsSpecialities] = useSearchParams();
|
||||
const [searchParamsFilter, setSearchParamsFilter] = useSearchParams();
|
||||
|
||||
function Filter(props: any) {
|
||||
// SEARCH
|
||||
const searchInput = useRef<HTMLInputElement>(null);
|
||||
const [searchText, setSearchText] = useState('');
|
||||
useEffect(() => {
|
||||
// Trigger First Search
|
||||
setSearchText(searchParams.get('search') ?? '');
|
||||
}, []);
|
||||
|
||||
//handle search
|
||||
const handleSearchChange = (event: any) => {
|
||||
const newSearchText = event.target.value ?? '';
|
||||
setSearchText(newSearchText);
|
||||
};
|
||||
|
||||
const handleSearchSubmit = (event: any) => {
|
||||
event.preventDefault();
|
||||
|
||||
props.onSearch(searchText);
|
||||
};
|
||||
const item = [
|
||||
{
|
||||
id: '',
|
||||
value: '',
|
||||
name: 'Semua',
|
||||
},
|
||||
];
|
||||
|
||||
useEffect(() => {
|
||||
// Trigger First Search
|
||||
setSearchText(searchParams.get('search') ?? '');
|
||||
}, []);
|
||||
|
||||
const item = [
|
||||
{
|
||||
id: '',
|
||||
value: '',
|
||||
name: 'Semua',
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<form style={{ width: '100%' }}>
|
||||
<Grid container spacing={2} sx={{ justifyContent: 'space-between', alignItems: 'center' }}>
|
||||
<Grid item xs={12} sm={12} md={12} lg={12}>
|
||||
<TextField
|
||||
id="search-input"
|
||||
ref={searchInput}
|
||||
variant="outlined"
|
||||
fullWidth
|
||||
onChange={handleSearchChange}
|
||||
onKeyDown={(event) => {
|
||||
if (event.key === 'Enter') {
|
||||
handleSearchSubmit(event);
|
||||
}
|
||||
}}
|
||||
value={searchText}
|
||||
InputProps={{
|
||||
startAdornment: (
|
||||
<InputAdornment position="start">
|
||||
<Search />
|
||||
</InputAdornment>
|
||||
),
|
||||
placeholder: 'Search',
|
||||
}}
|
||||
/>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</form>
|
||||
);
|
||||
}
|
||||
function FilterForm(props: any) {
|
||||
return(
|
||||
<Grid
|
||||
container
|
||||
spacing={2}
|
||||
sx={{ p: 2, justifyContent: 'space-between', alignItems: 'center' }}
|
||||
>
|
||||
<Grid item xs={12} md={12} lg={12}>
|
||||
<Filter onSearch={applyItems} />
|
||||
</Grid>
|
||||
return (
|
||||
<form style={{ width: '100%' }}>
|
||||
<Grid container spacing={2} sx={{ justifyContent: 'space-between', alignItems: 'center' }}>
|
||||
<Grid item xs={12} sm={12} md={12} lg={12}>
|
||||
<TextField
|
||||
id="search-input"
|
||||
ref={searchInput}
|
||||
variant="outlined"
|
||||
fullWidth
|
||||
onChange={handleSearchChange}
|
||||
onKeyDown={(event) => {
|
||||
if (event.key === 'Enter') {
|
||||
handleSearchSubmit(event);
|
||||
}
|
||||
}}
|
||||
value={searchText}
|
||||
InputProps={{
|
||||
startAdornment: (
|
||||
<InputAdornment position="start">
|
||||
<Search />
|
||||
</InputAdornment>
|
||||
),
|
||||
placeholder: 'Search',
|
||||
}}
|
||||
/>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</form>
|
||||
);
|
||||
}
|
||||
function FilterForm(props: any) {
|
||||
return(
|
||||
<Grid
|
||||
container
|
||||
spacing={2}
|
||||
sx={{ p: 2, justifyContent: 'space-between', alignItems: 'center' }}
|
||||
>
|
||||
<Grid item xs={12} md={12} lg={12}>
|
||||
<Filter onSearch={applyItems} />
|
||||
</Grid>
|
||||
);
|
||||
}
|
||||
</Grid>
|
||||
);
|
||||
}
|
||||
|
||||
function createData(doctor: Practitioner): Practitioner {
|
||||
return {
|
||||
...doctor,
|
||||
};
|
||||
}
|
||||
function createData(doctor: Practitioner): Practitioner {
|
||||
return {
|
||||
...doctor,
|
||||
/* user: doctor.user ? new User(doctor.user) : null; */
|
||||
};
|
||||
}
|
||||
|
||||
function Row(props: { row: ReturnType<typeof createData> }) {
|
||||
const { row } = props;
|
||||
const [open, setOpen] = React.useState(false);
|
||||
const [openDialog, setOpenDialog] = React.useState(false);
|
||||
function Row(props: { row: ReturnType<typeof createData> }) {
|
||||
const { row } = props;
|
||||
const [open, setOpen] = React.useState(false);
|
||||
const [openDialog, setOpenDialog] = React.useState(false);
|
||||
|
||||
|
||||
|
||||
return (
|
||||
<React.Fragment>
|
||||
<TableRow>
|
||||
<TableCell>
|
||||
<IconButton aria-label="expand row" size="small" onClick={() => setOpen(!open)}>
|
||||
{open ? <KeyboardArrowDownIcon /> : <KeyboardArrowRightIcon />}
|
||||
</IconButton>
|
||||
</TableCell>
|
||||
<TableCell align="left">{row.nID ? row.nID : '-'}</TableCell>
|
||||
<TableCell align="left">
|
||||
{row.nIDUser ? row.nIDUser : '-'}
|
||||
</TableCell>
|
||||
<TableCell align="left">{row.nIDDokter ? row.nIDDokter : '-'}</TableCell>
|
||||
<TableCell align="left">{row.sDokterName ? row.sDokterName : '-'}</TableCell>
|
||||
<TableCell align="left">{row.dTanggalResep ? row.dTanggalResep : '-'}</TableCell>
|
||||
<TableCell align="left">{row.sSource ? row.sSource : '-'}</TableCell>
|
||||
<TableCell align="left">{row.sKodeResep ? row.sKodeResep : '-'}</TableCell>
|
||||
<TableCell align="left">{row.sDiagnose ? row.sDiagnose : '-'}</TableCell>
|
||||
<TableCell align="left">{row.sStatus ? row.sStatus : '-'}</TableCell>
|
||||
{/* <TableCell align="center">
|
||||
<ButtonGroup variant="text" aria-label="text button group">
|
||||
<Link to={'/report/prescription/' + row.id + '/show'}>
|
||||
<Button>
|
||||
<Icon icon="ph:eye-bold" style={{ width: '24px', height: '24px' }} />
|
||||
</Button>
|
||||
</Link>
|
||||
</ButtonGroup>
|
||||
</TableCell> */}
|
||||
</TableRow>
|
||||
{/* COLLAPSIBLE ROW */}
|
||||
<TableRow>
|
||||
<TableCell
|
||||
style={{ paddingBottom: 0, paddingTop: 0, backgroundColor: 'rgba(244, 246, 248, 0.5)' }}
|
||||
colSpan={6}
|
||||
>
|
||||
return (
|
||||
<React.Fragment>
|
||||
<TableRow>
|
||||
<TableCell>
|
||||
<IconButton aria-label="expand row" size="small" onClick={() => setOpen(!open)}>
|
||||
{open ? <KeyboardArrowDownIcon /> : <KeyboardArrowRightIcon />}
|
||||
</IconButton>
|
||||
</TableCell>
|
||||
|
||||
<TableCell align="left">{row.user ? row.user.sFirstName : '-'}</TableCell>
|
||||
<TableCell align="left">{row.nIDDokter ? row.nIDDokter : '-'}</TableCell>
|
||||
<TableCell align="left">{row.nRating ? row.nRating : '-'}</TableCell>
|
||||
<TableCell align="left">{row.sNotes ? row.sNotes : '-'}</TableCell>
|
||||
<TableCell align="left">{row.dCreateOn ? row.dCreateOn : '-'}</TableCell>
|
||||
|
||||
{/* <TableCell align="center">
|
||||
<ButtonGroup variant="text" aria-label="text button group">
|
||||
<Link to={'/report/prescription/' + row.id + '/show'}>
|
||||
<Button>
|
||||
<Icon icon="ph:eye-bold" style={{ width: '24px', height: '24px' }} />
|
||||
</Button>
|
||||
</Link>
|
||||
</ButtonGroup>
|
||||
</TableCell> */}
|
||||
</TableRow>
|
||||
{/* COLLAPSIBLE ROW */}
|
||||
<TableRow>
|
||||
<TableCell
|
||||
style={{ paddingBottom: 0, paddingTop: 0, backgroundColor: 'rgba(244, 246, 248, 0.5)' }}
|
||||
colSpan={6}
|
||||
>
|
||||
{/* <Collapse in={open} timeout="auto" unmountOnExit>
|
||||
<Box sx={{ margin: 1, pb: 2, pl: 4 }}>
|
||||
<Grid container>
|
||||
<Grid item xs={12} sx={{ padding: 2 }}>
|
||||
<Grid container>
|
||||
<Grid item xs={6}>
|
||||
Metode Pembayaran
|
||||
</Grid>
|
||||
<Grid item xs={6}>
|
||||
: {row.payment_method ? row.payment_method : '-'}
|
||||
</Grid>
|
||||
<Box sx={{ margin: 1, pb: 2, pl: 4 }}>
|
||||
<Grid container>
|
||||
<Grid item xs={12} sx={{ padding: 2 }}>
|
||||
<Grid container>
|
||||
<Grid item xs={6}>
|
||||
Metode Pembayaran
|
||||
</Grid>
|
||||
<Grid item xs={6}>
|
||||
: {row.payment_method ? row.payment_method : '-'}
|
||||
</Grid>
|
||||
|
||||
<Grid item xs={6}>
|
||||
Jenis Benefit
|
||||
</Grid>
|
||||
<Grid item xs={6}>
|
||||
: -
|
||||
</Grid>
|
||||
<Grid item xs={6}>
|
||||
Durasi
|
||||
</Grid>
|
||||
<Grid item xs={6}>
|
||||
: {row.duration ? row.duration : '-'}
|
||||
</Grid>
|
||||
<Grid item xs={6}>
|
||||
Jenis Benefit
|
||||
</Grid>
|
||||
<Grid item xs={6}>
|
||||
: -
|
||||
</Grid>
|
||||
<Grid item xs={6}>
|
||||
Durasi
|
||||
</Grid>
|
||||
<Grid item xs={6}>
|
||||
: {row.duration ? row.duration : '-'}
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Box>
|
||||
</Collapse> */}
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
</Grid>
|
||||
</Box>
|
||||
</Collapse> */}
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
|
||||
{/* END COLLAPSIBLE ROW */}
|
||||
<Dialog
|
||||
open={openDialog}
|
||||
onClose={() => {
|
||||
setOpenDialog(false);
|
||||
}}
|
||||
aria-labelledby="alert-dialog-title"
|
||||
aria-describedby="alert-dialog-description"
|
||||
>
|
||||
<DialogContent sx={{ p: 5 }}>
|
||||
<Icon
|
||||
icon="eva:trash-2-outline"
|
||||
style={{
|
||||
width: '100px',
|
||||
height: '100px',
|
||||
color: '#FF0000',
|
||||
margin: 'auto',
|
||||
display: 'block',
|
||||
marginBottom: '20px',
|
||||
alignContent: 'center',
|
||||
}}
|
||||
/>
|
||||
<DialogContentText sx={{ fontWeight: 'bold', pb: 1 }} id="alert-dialog-title">
|
||||
Apakah anda yakin ingin menghapus
|
||||
</DialogContentText>
|
||||
<Typography sx={{ fontWeight: 'bold' }} id="alert-dialog-title">
|
||||
{row.name}?
|
||||
</Typography>
|
||||
</DialogContent>
|
||||
<DialogActions>
|
||||
<Button
|
||||
onClick={() => {
|
||||
setOpenDialog(false);
|
||||
}}
|
||||
color="primary"
|
||||
>
|
||||
Batal
|
||||
</Button>
|
||||
{/* <Button
|
||||
onClick={() => {
|
||||
handleDelete(row.id);
|
||||
}}
|
||||
color="primary"
|
||||
autoFocus
|
||||
>
|
||||
Hapus
|
||||
</Button> */}
|
||||
</DialogActions>
|
||||
</Dialog>
|
||||
</React.Fragment>
|
||||
);
|
||||
}
|
||||
|
||||
const headStyle = {
|
||||
fontWeight: 'bold',
|
||||
};
|
||||
// Dummy Default Data
|
||||
const [dataTableIsLoading, setDataTableLoading] = useState(true);
|
||||
const [dataTableLastRequest, setDataTableLastRequest] = useState(0);
|
||||
const [dataTableResponseState, setDataTableResponseState] = useState('idle');
|
||||
const [dataTableData, setDataTableData] = useState<LaravelPaginatedData>({
|
||||
current_page: 1,
|
||||
data: [],
|
||||
path: '',
|
||||
first_page_url: '',
|
||||
last_page: 1,
|
||||
last_page_url: '',
|
||||
next_page_url: '',
|
||||
prev_page_url: '',
|
||||
per_page: 10,
|
||||
from: 0,
|
||||
to: 0,
|
||||
total: 0,
|
||||
{/* END COLLAPSIBLE ROW */}
|
||||
<Dialog
|
||||
open={openDialog}
|
||||
onClose={() => {
|
||||
setOpenDialog(false);
|
||||
}}
|
||||
aria-labelledby="alert-dialog-title"
|
||||
aria-describedby="alert-dialog-description"
|
||||
>
|
||||
<DialogContent sx={{ p: 5 }}>
|
||||
<Icon
|
||||
icon="eva:trash-2-outline"
|
||||
style={{
|
||||
width: '100px',
|
||||
height: '100px',
|
||||
color: '#FF0000',
|
||||
margin: 'auto',
|
||||
display: 'block',
|
||||
marginBottom: '20px',
|
||||
alignContent: 'center',
|
||||
}}
|
||||
/>
|
||||
<DialogContentText sx={{ fontWeight: 'bold', pb: 1 }} id="alert-dialog-title">
|
||||
Apakah anda yakin ingin menghapus
|
||||
</DialogContentText>
|
||||
<Typography sx={{ fontWeight: 'bold' }} id="alert-dialog-title">
|
||||
{row.name}?
|
||||
</Typography>
|
||||
</DialogContent>
|
||||
<DialogActions>
|
||||
<Button
|
||||
onClick={() => {
|
||||
setOpenDialog(false);
|
||||
}}
|
||||
color="primary"
|
||||
>
|
||||
Batal
|
||||
</Button>
|
||||
{/* <Button
|
||||
onClick={() => {
|
||||
handleDelete(row.id);
|
||||
}}
|
||||
color="primary"
|
||||
autoFocus
|
||||
>
|
||||
Hapus
|
||||
</Button> */}
|
||||
</DialogActions>
|
||||
</Dialog>
|
||||
</React.Fragment>
|
||||
);
|
||||
}
|
||||
|
||||
const headStyle = {
|
||||
fontWeight: 'bold',
|
||||
};
|
||||
// Dummy Default Data
|
||||
const [dataTableIsLoading, setDataTableLoading] = useState(true);
|
||||
const [dataTableLastRequest, setDataTableLastRequest] = useState(0);
|
||||
const [dataTableResponseState, setDataTableResponseState] = useState('idle');
|
||||
const [dataTableData, setDataTableData] = useState<LaravelPaginatedData>({
|
||||
current_page: 1,
|
||||
data: [],
|
||||
path: '',
|
||||
first_page_url: '',
|
||||
last_page: 1,
|
||||
last_page_url: '',
|
||||
next_page_url: '',
|
||||
prev_page_url: '',
|
||||
per_page: 10,
|
||||
from: 0,
|
||||
to: 0,
|
||||
total: 0,
|
||||
});
|
||||
const [dataTablePage, setDataTablePage] = useState(5);
|
||||
|
||||
const loadDataTableData = async (appliedFilter: any | null = null) => {
|
||||
setDataTableLoading(true);
|
||||
const filter = appliedFilter ? appliedFilter : Object.fromEntries([...searchParams.entries()]);
|
||||
const response = await axios.get('/doctorrating ', {
|
||||
params: filter,
|
||||
});
|
||||
const [dataTablePage, setDataTablePage] = useState(5);
|
||||
setDataTableLoading(false);
|
||||
setDataTableData(response.data);
|
||||
};
|
||||
|
||||
const loadDataTableData = async (appliedFilter: any | null = null) => {
|
||||
setDataTableLoading(true);
|
||||
const filter = appliedFilter ? appliedFilter : Object.fromEntries([...searchParams.entries()]);
|
||||
const response = await axios.get('/prescription', {
|
||||
params: filter,
|
||||
});
|
||||
setDataTableLoading(false);
|
||||
setDataTableData(response.data);
|
||||
};
|
||||
// const applyFilter = async (searchFilter: string) => {
|
||||
// await loadDataTableData({ search: searchFilter });
|
||||
// setSearchParams({ search: searchFilter });
|
||||
// };
|
||||
|
||||
// const applyFilter = async (searchFilter: string) => {
|
||||
// await loadDataTableData({ search: searchFilter });
|
||||
// setSearchParams({ search: searchFilter });
|
||||
// };
|
||||
const applyItems = async (
|
||||
searchFilter: string,
|
||||
searchFilterOrganization: string,
|
||||
searchFilterSpecialities: string
|
||||
) => {
|
||||
await loadDataTableData({
|
||||
search: searchFilter,
|
||||
organization_id: searchFilterOrganization,
|
||||
speciality_id: searchFilterSpecialities,
|
||||
});
|
||||
setSearchParamsFilter({
|
||||
search: searchFilter,
|
||||
organization_id: searchFilterOrganization,
|
||||
speciality_id: searchFilterSpecialities,
|
||||
});
|
||||
};
|
||||
|
||||
const applyItems = async (
|
||||
searchFilter: string,
|
||||
searchFilterOrganization: string,
|
||||
searchFilterSpecialities: string
|
||||
) => {
|
||||
await loadDataTableData({
|
||||
search: searchFilter,
|
||||
organization_id: searchFilterOrganization,
|
||||
speciality_id: searchFilterSpecialities,
|
||||
});
|
||||
setSearchParamsFilter({
|
||||
search: searchFilter,
|
||||
organization_id: searchFilterOrganization,
|
||||
speciality_id: searchFilterSpecialities,
|
||||
});
|
||||
};
|
||||
const handlePageChange = (event: ChangeEvent, value: number) => {
|
||||
const filter = Object.fromEntries([...searchParams.entries(), ['page', value]]);
|
||||
loadDataTableData(filter);
|
||||
setSearchParams(filter);
|
||||
};
|
||||
|
||||
const handlePageChange = (event: ChangeEvent, value: number) => {
|
||||
const filter = Object.fromEntries([...searchParams.entries(), ['page', value]]);
|
||||
loadDataTableData(filter);
|
||||
setSearchParams(filter);
|
||||
};
|
||||
useEffect(() => {
|
||||
loadDataTableData();
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
loadDataTableData();
|
||||
}, []);
|
||||
return (
|
||||
<Stack>
|
||||
{/* <Ambulace /> */}
|
||||
|
||||
return (
|
||||
<Stack>
|
||||
{/* <Ambulace /> */}
|
||||
<Card sx={{ marginTop: '30px' }}>
|
||||
<FilterForm sx={{ marginTop: '100px' }} />
|
||||
|
||||
<Card sx={{ marginTop: '30px' }}>
|
||||
<FilterForm sx={{ marginTop: '100px' }} />
|
||||
{/* The Main Table */}
|
||||
<TableContainer component={Paper}>
|
||||
<Table>
|
||||
<TableBody>
|
||||
<TableRow>
|
||||
{/* <TableCell colSpan={8} rowSpan={1} align="center" /> */}
|
||||
<TableCell style={headStyle} align="left" />
|
||||
<TableCell style={headStyle} rowSpan={2} align="left">
|
||||
Nama User
|
||||
</TableCell>
|
||||
<TableCell style={headStyle} rowSpan={2} align="left">
|
||||
ID Dokter
|
||||
</TableCell>
|
||||
<TableCell style={headStyle} rowSpan={2} align="left">
|
||||
Rating
|
||||
</TableCell>
|
||||
<TableCell style={headStyle} rowSpan={2} align="left">
|
||||
Notes
|
||||
</TableCell>
|
||||
<TableCell style={headStyle} rowSpan={2} align="left">
|
||||
Created On
|
||||
</TableCell>
|
||||
|
||||
{/* The Main Table */}
|
||||
<TableContainer component={Paper}>
|
||||
<Table>
|
||||
</TableRow>
|
||||
{/* <TableRow>
|
||||
<TableCell style={headStyle} align="left" />
|
||||
<TableCell style={headStyle} align="left">
|
||||
Tanggal Booking
|
||||
</TableCell>
|
||||
<TableCell style={headStyle} align="left">
|
||||
Tanggal Appointment
|
||||
</TableCell>
|
||||
<TableCell style={headStyle} align="left">
|
||||
Faskes
|
||||
</TableCell>
|
||||
<TableCell style={headStyle} align="left">
|
||||
Nama Dokter
|
||||
</TableCell>
|
||||
<TableCell style={headStyle} align="left">
|
||||
Spesialisasi
|
||||
</TableCell>
|
||||
<TableCell style={headStyle} align="left">
|
||||
Pasien
|
||||
</TableCell>
|
||||
<TableCell style={headStyle} align="left">
|
||||
Dokter
|
||||
</TableCell>
|
||||
</TableRow> */}
|
||||
</TableBody>
|
||||
{dataTableIsLoading ? (
|
||||
<TableBody>
|
||||
<TableRow>
|
||||
{/* <TableCell colSpan={8} rowSpan={1} align="center" /> */}
|
||||
<TableCell style={headStyle} align="left" />
|
||||
<TableCell style={headStyle} rowSpan={2} align="left">
|
||||
ID Booking
|
||||
</TableCell>
|
||||
<TableCell style={headStyle} rowSpan={2} align="left">
|
||||
ID User
|
||||
</TableCell>
|
||||
<TableCell style={headStyle} rowSpan={2} align="left">
|
||||
ID Dokter
|
||||
</TableCell>
|
||||
<TableCell style={headStyle} rowSpan={2} align="left">
|
||||
Nama Dokter
|
||||
</TableCell>
|
||||
<TableCell style={headStyle} rowSpan={2} align="left">
|
||||
Tanggal Resep
|
||||
</TableCell>
|
||||
<TableCell style={headStyle} rowSpan={2} align="left">
|
||||
Source
|
||||
</TableCell>
|
||||
<TableCell style={headStyle} rowSpan={2} align="left">
|
||||
Kode Resep
|
||||
</TableCell>
|
||||
<TableCell style={headStyle} rowSpan={2} align="left">
|
||||
Diagnosa
|
||||
</TableCell>
|
||||
<TableCell style={headStyle} rowSpan={2} align="left">
|
||||
Status
|
||||
<TableCell colSpan={8} align="center">
|
||||
Loading
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
{/* <TableRow>
|
||||
<TableCell style={headStyle} align="left" />
|
||||
<TableCell style={headStyle} align="left">
|
||||
Tanggal Booking
|
||||
</TableCell>
|
||||
<TableCell style={headStyle} align="left">
|
||||
Tanggal Appointment
|
||||
</TableCell>
|
||||
<TableCell style={headStyle} align="left">
|
||||
Faskes
|
||||
</TableCell>
|
||||
<TableCell style={headStyle} align="left">
|
||||
Nama Dokter
|
||||
</TableCell>
|
||||
<TableCell style={headStyle} align="left">
|
||||
Spesialisasi
|
||||
</TableCell>
|
||||
<TableCell style={headStyle} align="left">
|
||||
Pasien
|
||||
</TableCell>
|
||||
<TableCell style={headStyle} align="left">
|
||||
Dokter
|
||||
</TableCell>
|
||||
</TableRow> */}
|
||||
</TableBody>
|
||||
{dataTableIsLoading ? (
|
||||
<TableBody>
|
||||
<TableRow>
|
||||
<TableCell colSpan={8} align="center">
|
||||
Loading
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
</TableBody>
|
||||
) : (dataTableData.data && dataTableData.data.length === 0) ? (
|
||||
) : (dataTableData.data && dataTableData.data.length === 0) ? (
|
||||
|
||||
<TableBody>
|
||||
<TableRow>
|
||||
<TableCell colSpan={8} align="center">
|
||||
No Data
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
</TableBody>
|
||||
) : (
|
||||
<TableBody>
|
||||
{dataTableData && dataTableData.map((row) => (
|
||||
<Row key={row.id} row={row} />
|
||||
))}
|
||||
</TableBody>
|
||||
)}
|
||||
</Table>
|
||||
</TableContainer>
|
||||
<TableBody>
|
||||
<TableRow>
|
||||
<TableCell colSpan={8} align="center">
|
||||
No Data
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
</TableBody>
|
||||
) : (
|
||||
<TableBody>
|
||||
{dataTableData && dataTableData.map((row) => (
|
||||
<Row key={row.id} row={row} />
|
||||
))}
|
||||
</TableBody>
|
||||
)}
|
||||
</Table>
|
||||
</TableContainer>
|
||||
|
||||
<BasePagination paginationData={dataTableData} onPageChange={handlePageChange} />
|
||||
</Card>
|
||||
</Stack>
|
||||
);
|
||||
<BasePagination paginationData={dataTableData} onPageChange={handlePageChange} />
|
||||
</Card>
|
||||
</Stack>
|
||||
);
|
||||
}
|
||||
@@ -13,6 +13,7 @@ import { AuthProvider } from '../contexts/LaravelAuthContext';
|
||||
import AuthGuard from '../guards/AuthGuard';
|
||||
import { Link, useParams, useSearchParams } from 'react-router-dom';
|
||||
import Prescription from '@/pages/Report/Prescription/Index';
|
||||
import DoctorRating from '@/pages/Report/DoctorRating/Index';
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
@@ -290,6 +291,10 @@ export default function Router() {
|
||||
path: 'report/prescription',
|
||||
element: <Prescription/>,
|
||||
},
|
||||
{
|
||||
path: 'report/doctorrating',
|
||||
element: <DoctorRating/>,
|
||||
},
|
||||
{
|
||||
path: 'report/linksehat-payments',
|
||||
element: <LinksehatPayment />,
|
||||
|
||||
@@ -20,11 +20,14 @@ export function fDateTimeSuffix(date: Date | string | number) {
|
||||
|
||||
export function fToNow(date: Date | string | number) {
|
||||
return formatDistanceToNow(new Date(date), {
|
||||
addSuffix: true
|
||||
addSuffix: true,
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
export function fPostFormat(date: Date | string | number) {
|
||||
return format(new Date(date), 'yyyy-MM-dd HH:mm:ss');
|
||||
}
|
||||
|
||||
export function fDateOnly(date: Date | string | number) {
|
||||
return format(new Date(date), 'yyyy-MM-dd');
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
12532
frontend/hospital-portal/package-lock.json
generated
12532
frontend/hospital-portal/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
15
frontend/hospital-portal/public/image/en-US.json
Normal file
15
frontend/hospital-portal/public/image/en-US.json
Normal file
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"greeting": "Hello",
|
||||
"buttonText": "Click Me",
|
||||
"infoLogin": "Enter the registered account",
|
||||
"txtLogin1" : "Sign in to Hospital Portal",
|
||||
"txtLogin2" : "Enter your details below",
|
||||
"txtCardSearchMember1" : "Guarantee Submission",
|
||||
"txtCardSearchMember2" : "Find Member",
|
||||
"txtCardSearchMember3" : "Date Birth",
|
||||
"txtCardSearchMember4" : "Member ID",
|
||||
"txtCardSearchMember5" : "Member",
|
||||
"txtDialogMember1" : "Benefit Summary",
|
||||
"txtDialogMember2" : "Request LOG",
|
||||
"txtDialogMember3" : "Member Detail"
|
||||
}
|
||||
18
frontend/hospital-portal/public/image/ic_flag_en.svg
Normal file
18
frontend/hospital-portal/public/image/ic_flag_en.svg
Normal file
@@ -0,0 +1,18 @@
|
||||
<svg height="20" viewBox="0 0 28 20" width="28" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<defs><rect id="a" height="20" rx="3" width="28"/>
|
||||
<mask id="b" fill="#fff">
|
||||
<use fill="#fff" fill-rule="evenodd" xlink:href="#a"/>
|
||||
</mask>
|
||||
</defs>
|
||||
<g fill="none" fill-rule="evenodd">
|
||||
<use fill="#0a17a7" xlink:href="#a"/>
|
||||
<path d="m29.2824692-1.91644623 1.4911811 2.21076686-9.4483006 6.37223314 6.6746503.0001129v6.66666663l-6.6746503-.0007795 9.4483006 6.3731256-1.4911811 2.2107668-11.9501195-8.0608924.0009836 7.4777795h-6.6666666l-.000317-7.4777795-11.9488189 8.0608924-1.49118107-2.2107668 9.448-6.3731256-6.67434973.0007795v-6.66666663l6.67434973-.0001129-9.448-6.37223314 1.49118107-2.21076686 11.9488189 8.06.000317-7.4768871h6.6666666l-.0009836 7.4768871z" fill="#fff" mask="url(#b)"/>
|
||||
<g stroke="#db1f35" stroke-linecap="round" stroke-width=".667">
|
||||
<path d="m18.668 6.332 12.665-8.332" mask="url(#b)"/>
|
||||
<path d="m20.013 21.35 11.354-7.652" mask="url(#b)" transform="matrix(1 0 0 -1 0 35.048)"/>
|
||||
<path d="m8.006 6.31-11.843-7.981" mask="url(#b)"/>
|
||||
<path d="m9.29 22.31-13.127-8.705" mask="url(#b)" transform="matrix(1 0 0 -1 0 35.915)"/>
|
||||
</g>
|
||||
<path d="m0 12h12v8h4v-8h12v-4h-12v-8h-4v8h-12z" fill="#e6273e" mask="url(#b)"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.3 KiB |
9
frontend/hospital-portal/public/image/ic_flag_id.svg
Normal file
9
frontend/hospital-portal/public/image/ic_flag_id.svg
Normal file
@@ -0,0 +1,9 @@
|
||||
<svg height="20" viewBox="0 0 28 20" width="28" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<defs>
|
||||
<rect id="a" height="10" rx="0" width="28"/>
|
||||
</defs>
|
||||
<g fill="none" fill-rule="evenodd">
|
||||
<use fill="#D82028" xlink:href="#a"/>
|
||||
<use fill="#FFF" xlink:href="#a" y="10"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 334 B |
15
frontend/hospital-portal/public/image/id-ID.json
Normal file
15
frontend/hospital-portal/public/image/id-ID.json
Normal file
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"greeting": "Halo",
|
||||
"buttonText": "Klik Saya",
|
||||
"infoLogin": "Masukan akun yang telah terdaftar",
|
||||
"txtLogin1" : "Masuk ke Hospital Portal",
|
||||
"txtLogin2" : "Masukkan detail Anda di bawah ini",
|
||||
"txtCardSearchMember1" : "Pengajuan Jaminan",
|
||||
"txtCardSearchMember2" : "Cari Anggota",
|
||||
"txtCardSearchMember3" : "Tanggal Lahir",
|
||||
"txtCardSearchMember4" : "Member ID",
|
||||
"txtCardSearchMember5" : "Member",
|
||||
"txtDialogMember1" : "Ringkasan Manfaat",
|
||||
"txtDialogMember2" : "Request LOG",
|
||||
"txtDialogMember3" : "Detail Member"
|
||||
}
|
||||
9
frontend/hospital-portal/public/logo/ic_flag_id.svg
Normal file
9
frontend/hospital-portal/public/logo/ic_flag_id.svg
Normal file
@@ -0,0 +1,9 @@
|
||||
<svg height="20" viewBox="0 0 28 20" width="28" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<defs>
|
||||
<rect id="a" height="10" rx="0" width="28"/>
|
||||
</defs>
|
||||
<g fill="none" fill-rule="evenodd">
|
||||
<use fill="#D82028" xlink:href="#a"/>
|
||||
<use fill="#FFF" xlink:href="#a" y="10"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 334 B |
@@ -1,5 +1,5 @@
|
||||
const getLocalizedData = async (locale) => {
|
||||
const response = await fetch(`../public/lang/${locale}.json`); // Mengambil file lokal berdasarkan bahasa yang dipilih
|
||||
const response = await fetch(`../public/image/${locale}.json`); // Mengambil file lokal berdasarkan bahasa yang dipilih
|
||||
const data = await response.json();
|
||||
return data;
|
||||
};
|
||||
|
||||
@@ -17,7 +17,7 @@ export default function Logo({ disabledLink = false, sx }: Props) {
|
||||
|
||||
const logo = (
|
||||
<Box sx={{ width: 40, height: 40, ...sx }}>
|
||||
<img src="/logo/logo-linksehat.png" alt="LinkSehat" />
|
||||
<img src="/logo/logo_single.svg" alt="LinkSehat" />
|
||||
</Box>
|
||||
);
|
||||
|
||||
|
||||
@@ -13,12 +13,12 @@ const LANGS = [
|
||||
{
|
||||
label: 'Bahasa Indonesia',
|
||||
value: 'id-ID',
|
||||
icon: '/icons/ic_flag_id.svg',
|
||||
icon: '/image/ic_flag_id.svg',
|
||||
},
|
||||
{
|
||||
label: 'English',
|
||||
value: 'en-US',
|
||||
icon: '/icons/ic_flag_en.svg',
|
||||
icon: '/image/ic_flag_en.svg',
|
||||
},
|
||||
];
|
||||
|
||||
@@ -53,7 +53,23 @@ export default function LanguagePopover() {
|
||||
...(open && { bgcolor: 'action.selected' }),
|
||||
}}
|
||||
>
|
||||
<Image disabledEffect src={!localStorage.getItem('currentLocale') ? LANGS[0].icon : (localStorage.getItem('currentLocale') === 'id-ID' ? LANGS[0].icon : LANGS[1].icon)} alt={!localStorage.getItem('currentLocale') ? LANGS[0].label : (localStorage.getItem('currentLocale') === 'id-ID' ? LANGS[0].label : LANGS[1].label)} />
|
||||
<Image
|
||||
disabledEffect
|
||||
src={(
|
||||
!localStorage.getItem('currentLocale')
|
||||
? LANGS[0].icon
|
||||
: localStorage.getItem('currentLocale') === 'id-ID'
|
||||
? LANGS[0].icon
|
||||
: LANGS[1].icon
|
||||
)}
|
||||
alt={
|
||||
!localStorage.getItem('currentLocale')
|
||||
? LANGS[0].label
|
||||
: localStorage.getItem('currentLocale') === 'id-ID'
|
||||
? LANGS[0].label
|
||||
: LANGS[1].label
|
||||
}
|
||||
/>
|
||||
</IconButtonAnimate>
|
||||
|
||||
|
||||
|
||||
@@ -10,6 +10,14 @@ export default defineConfig({
|
||||
// comment this out if that isn't relevant for your project
|
||||
build: {
|
||||
outDir: 'build',
|
||||
chunkSizeWarningLimit: 100,
|
||||
rollupOptions: {
|
||||
onwarn(warning, warn) {
|
||||
if (warning.code === 'MODULE_LEVEL_DIRECTIVE') {
|
||||
return
|
||||
}
|
||||
warn(warning)
|
||||
}}
|
||||
},
|
||||
plugins: [
|
||||
react(),
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user