Skip to content

Commit

Permalink
GOK-382 | Add. API call for aadhaar demographics auth and added toggl…
Browse files Browse the repository at this point in the history
…e for date of birth | [Sweety/Riya]
  • Loading branch information
riyaTw committed Oct 13, 2023
1 parent 1adf604 commit 964be58
Show file tree
Hide file tree
Showing 9 changed files with 624 additions and 74 deletions.
5 changes: 5 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@
"homepage": "./",
"private": true,
"dependencies": {
"@emotion/react": "^11.11.1",
"@emotion/styled": "^11.11.0",
"@mui/material": "^5.14.12",
"moment": "^2.29.4",
"react-datepicker": "^4.11.0",
"@testing-library/jest-dom": "^5.11.4",
"@testing-library/react": "^11.1.0",
"@testing-library/user-event": "^12.1.10",
Expand Down
1 change: 1 addition & 0 deletions src/api/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ export const headers = {
export const purpose = "KYC_AND_LINK";
export const bahmniUrl = "/openmrs/ws/rest/v1/hip";
export const hipServiceUrl ="/hiprovider";
export const hipAadhaarDemographicsUrl = "/v1/hid/benefit/createHealthId/demo/auth";

export const authModesUrl = "/v0.5/hip/fetch-modes";
export const authInitUrl = "/v0.5/hip/auth/init";
Expand Down
13 changes: 13 additions & 0 deletions src/api/hipServiceApi.js
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,19 @@ export const authConfirm = async (healthId, otp, demographics) => {
}
}

export const aadhaarDemographicsAuth = async (demographics) => {
try {
const response = await axios.post(Constants.hipServiceUrl + Constants.hipAadhaarDemographicsUrl, demographics, Constants.headers);
return response.data;
}
catch (error) {
if (error.response !== undefined)
return error.response.data;
else
return Constants.serviceUnavailableError;
}
}

export const checkAndGetPatientDetails = async (healthId) => {
try {
const response = await axios.post(Constants.hipServiceUrl + Constants.getPatientForDirectAuthUrl + "?healthId=" + healthId ,Constants.headers);
Expand Down
2 changes: 1 addition & 1 deletion src/components/creation/verifyAadhaar.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ const VerifyAadhaar = props => {
{error !== '' && <h6 className="error">{error}</h6>}
{loader && <Spinner />}
</div>}
{showDemographics && <DemoAuth isAadhaarDemoAuth={true}/>}
{showDemographics && <DemoAuth aadhaar={aadhaar} isAadhaarDemoAuth={true} />}
{otpVerified && <PatientAadhaarProfile patient={patient} setBack={setBack} />}
</div>

Expand Down
197 changes: 131 additions & 66 deletions src/components/demo-auth/demoAuth.jsx
Original file line number Diff line number Diff line change
@@ -1,45 +1,81 @@
import React, {useEffect, useState} from "react";
import {authConfirm, checkAndGetPatientDetails} from '../../api/hipServiceApi';
import moment from 'moment';
import {authConfirm, aadhaarDemographicsAuth} from '../../api/hipServiceApi';
import Spinner from '../spinner/spinner';
import {getDate} from "../Common/DateUtil";
import Footer from "../creation/Footer";
import FormGroup from '@mui/material/FormGroup';
import FormControlLabel from '@mui/material/FormControlLabel';
import Switch from '@mui/material/Switch';
import Typography from "@mui/material/Typography";
import DatePicker from 'react-datepicker';
import 'react-datepicker/dist/react-datepicker.css';
import './demoAuth.scss';
import { checkIfNotNull } from "../verifyHealthId/verifyHealthId";
import PatientDetails from "../patient-details/patientDetails";

const DemoAuth = (props) => {
const [errorMessage, setErrorMessage] = useState('');
const [showError, setShowError] = useState(false);
const [loader, setLoader] = useState(false);
const [ndhmDetails, setNdhmDetails] = [props.ndhmDetails,props.setNdhmDetails];
const [aadhaarDemographicsResponse, setAadhaarDemographicsResponse] = useState({});
const isAadhaarDemoAuth = props.isAadhaarDemoAuth;
const [demographics, setDemographics] = useState({
name: '',
gender: '',
dateOfBirth: '',
mobile: '',
mobileNumber: '',
identifier: null,
state: '',
district: ''
district: '',
aadhaarNumber: props.aadhaar
});
const [isValid, setIsValid] = useState(false);
const [isDisabled, setIsDisabled] = useState(true);
const [checked, setChecked] = useState(false);
const [selectedDate, setSelectedDate] = useState('');
const year = moment(selectedDate).format('yyyy');

const handleChange = () => {
setChecked(!checked);
setDemographics(prevState => ({
...prevState,
dateOfBirth: year.toString()
}));
};

const handleDateOfBirthChange = (date) => {
const dateObject = new Date(date);
let formattedDate = checked ? `${dateObject.getFullYear()}` : `${dateObject.getDate().toString().padStart(2, '0')}-${(dateObject.getMonth() + 1).toString().padStart(2, '0')}-${dateObject.getFullYear()}`;
setSelectedDate(date);
setDemographics(prevState => ({
...prevState,
dateOfBirth: formattedDate
}));
};

async function confirmAuth() {
setLoader(true);
setShowError(false);
demographics.identifier = { type : "MOBILE", value: demographics.mobile }
const response = await authConfirm(props.id, null, demographics);
if (response.error !== undefined || response.Error !== undefined) {
setShowError(true);
if(response.error.code === 1441) {
setErrorMessage("The authentication was unsuccessful. Please check the details you entered.");
}
else {
setErrorMessage((response.Error && response.Error.Message) || response.error.message);
}
}
else {
setNdhmDetails(parseNdhmDetails(response));
}
setLoader(false);
}
setLoader(true);
setShowError(false);
let response;
if (isAadhaarDemoAuth) {
response = await aadhaarDemographicsAuth(demographics);
} else {
demographics.identifier = { type: "MOBILE", value: demographics.mobileNumber };
response = await authConfirm(props.id, null, demographics);
}
if (("error" in response && response.error !== undefined) || ("Error" in response && response.Error !== undefined)) {
setShowError(true);
if (response.error.code === 1441) {
setErrorMessage("The authentication was unsuccessful. Please check the details you entered.");
} else {
setErrorMessage((response.Error && response.Error.Message) || response.error.message);
}
} else {
isAadhaarDemoAuth ? setAadhaarDemographicsResponse(parseDemographicsNdhmDetails(response)) : setNdhmDetails(parseNdhmDetails(response));
}
setLoader(false);
}

function parseNdhmDetails(patient) {
const ndhm = {
Expand All @@ -54,19 +90,28 @@ const DemoAuth = (props) => {
return ndhm;
}

function parseDemographicsNdhmDetails(patient) {
const ndhm = {
id: patient.healthId,
gender: patient.gender,
name: patient.firstName + " " + patient.middleName + " " + patient.lastName,
dateOfBirth: getDate(patient),
phoneNumber: patient.mobile,
address: {line:patient.address, district: patient.districtName, state: patient.stateName, pincode: patient.pincode},
healthIdNumber: patient.healthIdNumber
};
return ndhm;
}

useEffect(() => {
if(demographics.name === '' || demographics.gender === '' || demographics.dateOfBirth === '' || demographics.mobile === ''){
setIsValid(false);
}
else {
setIsValid(true);
if(demographics.name !== '' && demographics.gender !== '' && demographics.dateOfBirth !== '' && demographics.district !== '' && demographics.state !== ''){
setIsDisabled(false);
}
}, [demographics])

const handleInputChange = (event) => {
const { name, value } = event.target;
if(name === "mobile"){
if(name === "mobileNumber"){
const regEx = /^[0-9\b]+$/;
if (!regEx.test(value)) {
return;
Expand All @@ -80,46 +125,66 @@ const DemoAuth = (props) => {

return (
<div>
{checkIfNotNull(aadhaarDemographicsResponse) ? <PatientDetails ndhmDetails={aadhaarDemographicsResponse} /> :
<>
<p className="note">Please provide your demographic details</p>
<div className="demo-auth-form-field">
<label htmlFor="name" className="required-label">Enter Name: </label>
<input type="text" name="name" value={demographics.name} onChange={handleInputChange} placeholder="Name" required/>
</div>
<div className="demo-auth-form-field">
<label htmlFor="gender" className="required-label">Choose Gender: </label>
<select name="gender" onChange={handleInputChange} required>
<option value=''>Select gender..</option>
<option value="M">Male</option>
<option value="F">Female</option>
<option value="O">Other</option>
<option value="U">Undisclosed</option>
</select>
</div>
<div className="demo-auth-form-field">
<label htmlFor="dateOfBirth" className="required-label">Enter Date of Birth: </label>
<input type="date" name="dateOfBirth" value={demographics.dateOfBirth} onChange={handleInputChange}
max={new Date().toISOString().split('T')[0]} placeholder="Date of Birth" required/>
</div>
<div className="demo-auth-form-field">
<label htmlFor="mobile" className={isAadhaarDemoAuth ? "label": "required-label"}>Enter Mobile Number: </label>
<input type="text" name="mobile" value={demographics.mobile} onChange={handleInputChange} placeholder="Mobile" required={!isAadhaarDemoAuth}/>
</div>
{isAadhaarDemoAuth && <div>
<div className="demo-auth-form-field">
<label htmlFor="district" className="required-label">Enter District: </label>
<input type="text" name="mobile" value={demographics.district} onChange={handleInputChange} placeholder="District" required/>
</div>
<div className="demo-auth-form-field">
<label htmlFor="state" className="required-label">Enter State: </label>
<input type="text" name="mobile" value={demographics.state} onChange={handleInputChange} placeholder="State" required/>
</div>
</div>}
<div className="fetch-abdm-record">
<Footer setBack={props.setBack} />
<button className="demo-fetch-button" type="button" disabled={!isValid} onClick={confirmAuth}>
{isAadhaarDemoAuth ? 'Create ABHA' : 'Fetch ABDM Data'}</button>
{showError && <h6 className="error">{errorMessage}</h6>}
<div className="demo-auth-form-field">
<label htmlFor="name" className="required-label">Enter Name: </label>
<input type="text" name="name" value={demographics.name} onChange={handleInputChange} placeholder="Name" required/>
</div>
<div className="demo-auth-form-field">
<label htmlFor="gender" className="required-label">Choose Gender: </label>
<select name="gender" onChange={handleInputChange} required>
<option value=''>Select gender..</option>
<option value="M">Male</option>
<option value="F">Female</option>
<option value="O">Other</option>
<option value="U">Undisclosed</option>
</select>
</div>
<FormGroup>
<FormControlLabel
style={{marginLeft: "2.7%"}}
control={<Switch checked={checked} onChange={handleChange} />}
label={
<Typography style={{ fontFamily: '-apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen, Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif', fontSize: '12px' }}>
Do you have only year of birth as per Aadhaar?
</Typography>
}
/>
</FormGroup>
<div className="demo-auth-form-date-field">
<label htmlFor="dateOfBirth" className="required-label">{checked ? "Enter Year of Birth:" : "Enter Date of Birth:" } </label>
<DatePicker
selected={selectedDate}
onChange={handleDateOfBirthChange}
showYearPicker={checked}
dateFormat={checked ? 'yyyy' : 'dd-MM-yyyy'}
placeholderText={checked ? 'yyyy' : 'dd-mm-yyyy'}
/>
</div>
<div className="demo-auth-form-field">
<label htmlFor="mobile" className={isAadhaarDemoAuth ? "label": "required-label"}>Enter Mobile Number: </label>
<input type="text" name="mobileNumber" value={demographics.mobileNumber} onChange={handleInputChange} placeholder="Mobile" required={!isAadhaarDemoAuth}/>
</div>
{isAadhaarDemoAuth && <div>
<div className="demo-auth-form-field">
<label htmlFor="district" className="required-label">Enter District: </label>
<input type="text" name="district" value={demographics.district} onChange={handleInputChange} placeholder="District" required/>
</div>
<div className="demo-auth-form-field">
<label htmlFor="state" className="required-label">Enter State: </label>
<input type="text" name="state" value={demographics.state} onChange={handleInputChange} placeholder="State" required/>
</div>
</div>}
<div className="fetch-abdm-record">
<Footer setBack={props.setBack} />
<button className="demo-fetch-button" type="button" disabled={isDisabled} onClick={confirmAuth}>
{isAadhaarDemoAuth ? 'Create ABHA' : 'Fetch ABDM Data'}</button>
{showError && <h6 className="error">{errorMessage}</h6>}
</div>
</>
}
{loader && <Spinner />}
</div>
);
Expand Down
18 changes: 18 additions & 0 deletions src/components/demo-auth/demoAuth.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
.react-datepicker__input-container input {
width: 283%;
}

.demo-auth-form-date-field {
label {
width: 50%;
}

.required-label:after {
content:" *";
color: red;
margin-right: 9%;
}
margin-left: 3.55%;
padding: 2px;
width: auto;
}
7 changes: 5 additions & 2 deletions src/components/patient-details/patientDetails.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,10 @@ const PatientDetails = (props) => {
}

function getPhoneNumber() {
if(ndhmDetails?.identifiers !== undefined && ndhmDetails?.identifiers.length > 0){
if(ndhmDetails.phoneNumber){
return ndhmDetails.phoneNumber;
}
else if(ndhmDetails?.identifiers !== undefined && ndhmDetails?.identifiers.length > 0){
var phoneNumber = ndhmDetails?.identifiers[0].value;
var len = phoneNumber.length;
return "+91".concat(phoneNumber.substring(len-10,len));
Expand Down Expand Up @@ -105,7 +108,7 @@ const PatientDetails = (props) => {
<div className={checkIfNotNull(selectedPatient) ? 'greyed-out' : ''}>
<b>ABDM Record: </b>
<PatientInfo patient={ndhmDetails}/><br/>
{!props.isVerifyABHAThroughFetchModes &&
{!props.isVerifyABHAThroughFetchModes && props.isVerifyABHAThroughFetchModes !== undefined &&
<div className="abha-card">
<ABHACard healthIdNumber={ndhmDetails?.healthIdNumber}/>
</div>}
Expand Down
2 changes: 1 addition & 1 deletion src/components/patient-details/patientInfo.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ const PatientInfo = (props) => {
(Age:<strong> {!isNaN(age) ? age : '-'} </strong>,
Gender:<strong> {getPatientGender(patient?.gender) || '-'}</strong>)<br/>
{address.length !== 0 && <span>Address: {address}<br/></span>}
Mobile: {patient?.phoneNumber || (patient?.identifiers != null ? patient?.identifiers[0]?.value : '-')}
Mobile: {patient?.phoneNumber || (patient?.identifiers != null && patient?.identifiers[0]?.type === "MOBILE" ? patient?.identifiers[0]?.value : '-')}
{patient?.id !== undefined && <span><br/>ABHA Address: {patient?.id}</span>}
{patient?.healthId !== undefined && <span><br/>ABHA Address: {patient?.healthId}</span>}
{healthIdNumber !== undefined && healthIdNumber !== null && <span><br/>ABHA Number: {healthIdNumber}</span>}
Expand Down
Loading

0 comments on commit 964be58

Please sign in to comment.