diff --git a/src/components/AssignmentVoucherForm.js b/src/components/AssignmentVoucherForm.js new file mode 100644 index 0000000..50fc55d --- /dev/null +++ b/src/components/AssignmentVoucherForm.js @@ -0,0 +1,62 @@ +import React from 'react'; + +import { Grid, Divider } from '@material-ui/core'; + +import { PublishedComponent, TextInput } from '@openimis/fe-core'; + +function AssignmentVoucherForm({ + classes, readOnly = false, edited, onEditedChange, formatMessage, +}) { + return ( + <> + + + onEditedChange({ ...edited, workers })} + previousWorkers + /> + + + + + + + + + + + + + + onEditedChange({ ...edited, dateRanges })} + /> + + + + ); +} + +export default AssignmentVoucherForm; diff --git a/src/components/VoucherAcquirementGenericVoucher.js b/src/components/VoucherAcquirementGenericVoucher.js index 8f55d2f..bbf33d4 100644 --- a/src/components/VoucherAcquirementGenericVoucher.js +++ b/src/components/VoucherAcquirementGenericVoucher.js @@ -29,7 +29,7 @@ function VoucherAcquirementGenericVoucher() { const [voucherAcquirement, setVoucherAcquirement] = useState({}); const [isPaymentModalOpen, setIsPaymentModalOpen] = useState(false); - const canAcquire = (voucherAcquirement) => !voucherAcquirement?.quantity + const acquirementBlocked = (voucherAcquirement) => !voucherAcquirement?.quantity || voucherAcquirement?.quantity > VOUCHER_QUANTITY_THRESHOLD; const onVoucherAcquire = () => { @@ -58,8 +58,8 @@ function VoucherAcquirementGenericVoucher() { {formatMessage('workerVoucher.acquirement.method.GENERIC_VOUCHER')} - @@ -67,7 +67,7 @@ function VoucherAcquirementGenericVoucher() { variant="outlined" style={{ border: 0 }} onClick={onVoucherAcquire} - disabled={canAcquire(voucherAcquirement)} + disabled={acquirementBlocked(voucherAcquirement)} > {formatMessage('workerVoucher.acquire.voucher')} diff --git a/src/components/VoucherAcquirementPaymentModal.js b/src/components/VoucherAcquirementPaymentModal.js index c34004c..0dd2c2d 100644 --- a/src/components/VoucherAcquirementPaymentModal.js +++ b/src/components/VoucherAcquirementPaymentModal.js @@ -98,7 +98,7 @@ function VoucherAcquirementPaymentModal({ {acquireButtonDisabled ? ( diff --git a/src/components/VoucherAcquirementSpecificWorker.js b/src/components/VoucherAcquirementSpecificWorker.js index d68259f..7f7b8a5 100644 --- a/src/components/VoucherAcquirementSpecificWorker.js +++ b/src/components/VoucherAcquirementSpecificWorker.js @@ -29,7 +29,7 @@ function VoucherAcquirementSpecificWorker() { const [voucherAcquirement, setVoucherAcquirement] = useState({}); const [isPaymentModalOpen, setIsPaymentModalOpen] = useState(false); - const canAcquire = (voucherAcquirement) => !voucherAcquirement?.workers?.length + const acquirementBlocked = (voucherAcquirement) => !voucherAcquirement?.workers?.length || !voucherAcquirement?.dateRanges?.length; const onVoucherAcquire = () => { @@ -58,8 +58,8 @@ function VoucherAcquirementSpecificWorker() { {formatMessage('workerVoucher.acquirement.method.SPECIFIC_WORKER')} - @@ -67,7 +67,7 @@ function VoucherAcquirementSpecificWorker() { variant="outlined" style={{ border: 0 }} onClick={onVoucherAcquire} - disabled={canAcquire(voucherAcquirement)} + disabled={acquirementBlocked(voucherAcquirement)} > {formatMessage('workerVoucher.acquire.voucher')} diff --git a/src/components/VoucherAssignmentConfirmModal.js b/src/components/VoucherAssignmentConfirmModal.js new file mode 100644 index 0000000..0df0cca --- /dev/null +++ b/src/components/VoucherAssignmentConfirmModal.js @@ -0,0 +1,105 @@ +import React, { useState } from 'react'; + +import { + Button, + Dialog, + DialogActions, + DialogContent, + DialogTitle, + Divider, + CircularProgress, + Grid, + Typography, + Checkbox, + FormControlLabel, + Tooltip, +} from '@material-ui/core'; +import { makeStyles } from '@material-ui/styles'; + +import { useTranslations, useModulesManager, NumberInput } from '@openimis/fe-core'; +import { MODULE_NAME } from '../constants'; + +export const useStyles = makeStyles((theme) => ({ + primaryButton: theme.dialog.primaryButton, + secondaryButton: theme.dialog.secondaryButton, + item: theme.paper.item, +})); + +function VoucherAssignmentConfirmModal({ + openState, + onClose, + onConfirm, + isLoading, + error, + assignmentSummary, + readOnly = true, +}) { + const classes = useStyles(); + const modulesManager = useModulesManager(); + const { formatMessage } = useTranslations(MODULE_NAME, modulesManager); + const [acceptAssignment, setAcceptAssignment] = useState(false); + const acquireButtonDisabled = !acceptAssignment || isLoading || error; + + const renderContent = () => { + if (error) { + return {error}; + } + + if (isLoading) { + return ; + } + + return ( + + + + + setAcceptAssignment(e.target.checked)} + /> + )} + label={formatMessage('workerVoucher.assign.confirmation')} + /> + + ); + }; + + return ( + + {formatMessage('workerVoucher.VoucherAssignmentConfirmModal.title')} + + {renderContent()} + + + + {acquireButtonDisabled ? ( + + + + + + ) : ( + + )} + + + ); +} + +export default VoucherAssignmentConfirmModal; diff --git a/src/components/VoucherAssignmentForm.js b/src/components/VoucherAssignmentForm.js new file mode 100644 index 0000000..9c7195a --- /dev/null +++ b/src/components/VoucherAssignmentForm.js @@ -0,0 +1,107 @@ +import React, { useState, useEffect } from 'react'; + +import { + Divider, Grid, Paper, Typography, Button, Tooltip, +} from '@material-ui/core'; +import { makeStyles } from '@material-ui/styles'; + +import { useModulesManager, useTranslations } from '@openimis/fe-core'; +import { MODULE_NAME, USER_ECONOMIC_UNIT_STORAGE_KEY } from '../constants'; +import AssignmentVoucherForm from './AssignmentVoucherForm'; +import VoucherAssignmentConfirmModal from './VoucherAssignmentConfirmModal'; + +export const useStyles = makeStyles((theme) => ({ + paper: { ...theme.paper.paper, margin: '10px 0 0 0' }, + paperHeaderTitle: { + ...theme.paper.title, + display: 'flex', + alignItems: 'center', + justifyContent: 'space-between', + }, + tableTitle: theme.table.title, + item: theme.paper.item, +})); + +function VoucherAssignmentForm() { + const modulesManager = useModulesManager(); + const classes = useStyles(); + const { formatMessage } = useTranslations(MODULE_NAME, modulesManager); + const [voucherAssignment, setVoucherAssignment] = useState({}); + const [isConfirmationModalOpen, setIsConfirmationModalOpen] = useState(false); + + const assignmentBlocked = (voucherAssignment) => !voucherAssignment?.workers?.length + || !voucherAssignment?.dateRanges?.length; + + const onVoucherAssign = () => { + setIsConfirmationModalOpen((prevState) => !prevState); + // TODO: Fetch info about assignment (assignmentSummary) + }; + + const onAssignmentConfirmation = () => { + // TODO: After summary fetch, assign vouchers to the Workers. + setIsConfirmationModalOpen((prevState) => !prevState); + console.log('Assign Vouchers to the Workers'); + }; + + useEffect(() => { + const storedUserEconomicUnit = localStorage.getItem(USER_ECONOMIC_UNIT_STORAGE_KEY); + + if (storedUserEconomicUnit) { + const userEconomicUnit = JSON.parse(storedUserEconomicUnit); + + setVoucherAssignment((prevState) => ({ ...prevState, employer: userEconomicUnit })); + } + }, [setVoucherAssignment]); + + return ( + + + + + + {formatMessage('workerVoucher.menu.voucherAssignment')} + + + + + + + + + + setIsConfirmationModalOpen((prevState) => !prevState)} + onConfirm={onAssignmentConfirmation} + // TODO: Change after BE implementation + isLoading={false} + error={false} + assignmentSummary={{ + vouchers: 100, + }} + /> + + + + ); +} + +export default VoucherAssignmentForm; diff --git a/src/constants.js b/src/constants.js index 44cace8..f4bed34 100644 --- a/src/constants.js +++ b/src/constants.js @@ -1,4 +1,5 @@ export const VOUCHER_RIGHT_SEARCH = 204001; +export const EMPLOYER_RIGHT_SEARCH = 204001; export const MODULE_NAME = 'workerVoucher'; export const REF_ROUTE_WORKER_VOUCHER = 'workerVoucher.route.workerVoucher'; diff --git a/src/pages/VoucherAssignmentPage.js b/src/pages/VoucherAssignmentPage.js index 73d4f0e..ec747c4 100644 --- a/src/pages/VoucherAssignmentPage.js +++ b/src/pages/VoucherAssignmentPage.js @@ -1,10 +1,29 @@ import React from 'react'; +import { useSelector } from 'react-redux'; + +import { makeStyles } from '@material-ui/styles'; + +import { Helmet, useModulesManager, useTranslations } from '@openimis/fe-core'; +import { EMPLOYER_RIGHT_SEARCH, MODULE_NAME } from '../constants'; +import VoucherAssignmentForm from '../components/VoucherAssignmentForm'; + +export const useStyles = makeStyles((theme) => ({ + page: theme.page, +})); function VoucherAssignmentPage() { + const modulesManager = useModulesManager(); + const classes = useStyles(); + const { formatMessage } = useTranslations(MODULE_NAME, modulesManager); + const rights = useSelector((state) => state.core?.user?.i_user?.rights ?? []); + return ( -
- VoucherAssignmentPage -
+ rights.includes(EMPLOYER_RIGHT_SEARCH) && ( +
+ + +
+ ) ); } diff --git a/src/translations/en.json b/src/translations/en.json index 07580c6..c1c91f5 100644 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -33,12 +33,15 @@ "workerVoucher.acquirement.method.GENERIC_VOUCHER": "Generic Voucher", "workerVoucher.acquirement.method.SPECIFIC_WORKER": "Specific Workers", "workerVoucher.acquire.voucher": "ACQUIRE VOUCHER", + "workerVoucher.assign.voucher": "ASSIGN VOUCHER", "workerVoucher.acquire.vouchersQuantity": "Quantity of Vouchers", "workerVoucher.acquire.pricePerVoucher": "Voucher Price", "workerVoucher.acquire.toBePaid": "Acquirement Price", "workerVoucher.acquire.vouchers": "Acquire Vouchers", + "workerVoucher.assign.vouchers": "Assign Vouchers", "workerVoucher.acquire.confirmation": "I confirm the voucher acquirement, acknowledging that I have read and agree to the terms and policies.", - "workerVoucher.acquire.vouchers.required": "You need to fill out all required fields to continue", + "workerVoucher.assign.confirmation": "I confirm the voucher assignment, acknowledging that I have read and agree to the terms and policies.", + "workerVoucher.vouchers.required": "You need to fill out all required fields to continue", "workerVoucher.WorkerMultiplePicker.placeholder": "Search for Worker", "workerVoucher.WorkerMultiplePicker.underThreshold": "Enter at least 3 characters of National ID", "workerVoucher.WorkerMultiplePicker.noOptions": "Worker not found", @@ -53,7 +56,10 @@ "workerVoucher.WorkerDateRangePicker.noRanges": "No date ranges registered", "workerVoucher.WorkerDateRangePicker.notAvailable": "NOT AVAILABLE", "workerVoucher.VoucherAcquirementPaymentModal.title": "Voucher Acquirement Summary", + "workerVoucher.VoucherAssignmentConfirmModal.title": "Voucher Assignment Summary", "workerVoucher.VoucherAcquirementPaymentModal.confirm": "Acquire", + "workerVoucher.VoucherAssignmentConfirmModal.confirm": "Assign", "workerVoucher.VoucherAcquirementPaymentModal.confirm.tooltip": "Please ensure that there are no errors and that you have checked the acquirement confirmation", - "workerVoucher.VoucherAcquirementPaymentModal.close": "Cancel" + "workerVoucher.VoucherAssignmentConfirmModal.confirm.tooltip": "Please ensure that there are no errors and that you have checked the assignment confirmation", + "workerVoucher.close": "Cancel" }