@finspringinnovations/fdsdk 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +184 -0
- package/lib/api/applicationApi.d.ts +1 -0
- package/lib/api/applicationApi.js +11 -0
- package/lib/api/bankApi.d.ts +352 -0
- package/lib/api/bankApi.js +54 -0
- package/lib/api/baseApi.d.ts +8 -0
- package/lib/api/baseApi.js +456 -0
- package/lib/api/customerApi.d.ts +855 -0
- package/lib/api/customerApi.js +213 -0
- package/lib/api/fdApi.d.ts +979 -0
- package/lib/api/fdApi.js +112 -0
- package/lib/api/fdCalculatorApi.d.ts +179 -0
- package/lib/api/fdCalculatorApi.js +36 -0
- package/lib/api/index.d.ts +14 -0
- package/lib/api/index.js +45 -0
- package/lib/api/interestRateApi.d.ts +585 -0
- package/lib/api/interestRateApi.js +101 -0
- package/lib/api/kycApi.d.ts +486 -0
- package/lib/api/kycApi.js +71 -0
- package/lib/api/masterDataApi.d.ts +158 -0
- package/lib/api/masterDataApi.js +32 -0
- package/lib/api/nomineeApi.d.ts +325 -0
- package/lib/api/nomineeApi.js +46 -0
- package/lib/api/onboardingApi.d.ts +192 -0
- package/lib/api/onboardingApi.js +41 -0
- package/lib/api/panApi.d.ts +0 -0
- package/lib/api/panApi.js +23 -0
- package/lib/api/paymentApi.d.ts +325 -0
- package/lib/api/paymentApi.js +46 -0
- package/lib/api/workflowApi.d.ts +654 -0
- package/lib/api/workflowApi.js +90 -0
- package/lib/assets/images/images.d.ts +4 -0
- package/lib/assets/images/images.js +10 -0
- package/lib/components/AadhaarInput.d.ts +13 -0
- package/lib/components/AadhaarInput.js +47 -0
- package/lib/components/ActionButton.d.ts +12 -0
- package/lib/components/ActionButton.js +87 -0
- package/lib/components/ActiveFDCard.d.ts +16 -0
- package/lib/components/ActiveFDCard.js +95 -0
- package/lib/components/AmountInput.d.ts +20 -0
- package/lib/components/AmountInput.js +144 -0
- package/lib/components/CheckboxOption.d.ts +11 -0
- package/lib/components/CheckboxOption.js +41 -0
- package/lib/components/CompanyHeader.d.ts +7 -0
- package/lib/components/CompanyHeader.js +57 -0
- package/lib/components/DropdownSelector.d.ts +9 -0
- package/lib/components/DropdownSelector.js +49 -0
- package/lib/components/EmptyState.d.ts +17 -0
- package/lib/components/EmptyState.js +44 -0
- package/lib/components/ErrorDisplay.d.ts +17 -0
- package/lib/components/ErrorDisplay.js +69 -0
- package/lib/components/FAQItem.d.ts +9 -0
- package/lib/components/FAQItem.js +52 -0
- package/lib/components/FDCard.d.ts +21 -0
- package/lib/components/FDCard.js +96 -0
- package/lib/components/FormDropdown.d.ts +18 -0
- package/lib/components/FormDropdown.js +155 -0
- package/lib/components/FormSection.d.ts +14 -0
- package/lib/components/FormSection.js +38 -0
- package/lib/components/Header.d.ts +14 -0
- package/lib/components/Header.js +52 -0
- package/lib/components/IFSCSearchResultCard.d.ts +13 -0
- package/lib/components/IFSCSearchResultCard.js +70 -0
- package/lib/components/InfoBox.d.ts +8 -0
- package/lib/components/InfoBox.js +39 -0
- package/lib/components/InterestRateCard.d.ts +8 -0
- package/lib/components/InterestRateCard.js +46 -0
- package/lib/components/LoadingIndicator.d.ts +12 -0
- package/lib/components/LoadingIndicator.js +30 -0
- package/lib/components/OTPInput.d.ts +17 -0
- package/lib/components/OTPInput.js +144 -0
- package/lib/components/PaymentDetailsCard.d.ts +20 -0
- package/lib/components/PaymentDetailsCard.js +68 -0
- package/lib/components/PendingFDBottomSheet.d.ts +18 -0
- package/lib/components/PendingFDBottomSheet.js +122 -0
- package/lib/components/SafeAreaWrapper.d.ts +13 -0
- package/lib/components/SafeAreaWrapper.js +41 -0
- package/lib/components/ScreenHeader.d.ts +11 -0
- package/lib/components/ScreenHeader.js +46 -0
- package/lib/components/StatusDisplay.d.ts +15 -0
- package/lib/components/StatusDisplay.js +88 -0
- package/lib/components/TextFieldWithLabel.d.ts +46 -0
- package/lib/components/TextFieldWithLabel.js +326 -0
- package/lib/components/TrustBox.d.ts +8 -0
- package/lib/components/TrustBox.js +45 -0
- package/lib/components/ValidationErrorAlert.d.ts +23 -0
- package/lib/components/ValidationErrorAlert.js +39 -0
- package/lib/components/ValidationMessage.d.ts +9 -0
- package/lib/components/ValidationMessage.js +98 -0
- package/lib/components/index.d.ts +35 -0
- package/lib/components/index.js +64 -0
- package/lib/config/apiConfig.d.ts +34 -0
- package/lib/config/apiConfig.js +158 -0
- package/lib/config/appDataConfig.d.ts +114 -0
- package/lib/config/appDataConfig.js +264 -0
- package/lib/config/encryptionConfig.d.ts +21 -0
- package/lib/config/encryptionConfig.js +61 -0
- package/lib/config/workflowConstants.d.ts +37 -0
- package/lib/config/workflowConstants.js +38 -0
- package/lib/constants/strings/bank.d.ts +72 -0
- package/lib/constants/strings/bank.js +86 -0
- package/lib/constants/strings/base64Images.d.ts +25 -0
- package/lib/constants/strings/base64Images.js +28 -0
- package/lib/constants/strings/common.d.ts +53 -0
- package/lib/constants/strings/common.js +62 -0
- package/lib/constants/strings/employee.d.ts +61 -0
- package/lib/constants/strings/employee.js +77 -0
- package/lib/constants/strings/faq.d.ts +14 -0
- package/lib/constants/strings/faq.js +20 -0
- package/lib/constants/strings/fd.d.ts +122 -0
- package/lib/constants/strings/fd.js +151 -0
- package/lib/constants/strings/home.d.ts +49 -0
- package/lib/constants/strings/home.js +62 -0
- package/lib/constants/strings/index.d.ts +16 -0
- package/lib/constants/strings/index.js +44 -0
- package/lib/constants/strings/kyc.d.ts +80 -0
- package/lib/constants/strings/kyc.js +94 -0
- package/lib/constants/strings/nominee.d.ts +64 -0
- package/lib/constants/strings/nominee.js +81 -0
- package/lib/hooks/useAuth.d.ts +25 -0
- package/lib/hooks/useAuth.js +39 -0
- package/lib/hooks/useFDData.d.ts +11 -0
- package/lib/hooks/useFDData.js +40 -0
- package/lib/index.d.ts +69 -0
- package/lib/index.js +182 -0
- package/lib/navigation/RootNavigator.d.ts +8 -0
- package/lib/navigation/RootNavigator.js +205 -0
- package/lib/navigation/SimpleNavigator.d.ts +11 -0
- package/lib/navigation/SimpleNavigator.js +107 -0
- package/lib/navigation/helpers.d.ts +11 -0
- package/lib/navigation/helpers.js +83 -0
- package/lib/navigation/index.d.ts +15 -0
- package/lib/navigation/index.js +42 -0
- package/lib/navigation/types.d.ts +113 -0
- package/lib/navigation/types.js +2 -0
- package/lib/navigation/workflowNavigator.d.ts +22 -0
- package/lib/navigation/workflowNavigator.js +104 -0
- package/lib/providers/ApiProvider.d.ts +7 -0
- package/lib/providers/ApiProvider.js +34 -0
- package/lib/providers/MasterDataProvider.d.ts +10 -0
- package/lib/providers/MasterDataProvider.js +54 -0
- package/lib/screens/AadhaarVerification.d.ts +7 -0
- package/lib/screens/AadhaarVerification.js +627 -0
- package/lib/screens/AddBankAccount.d.ts +22 -0
- package/lib/screens/AddBankAccount.js +381 -0
- package/lib/screens/BankDetail.d.ts +16 -0
- package/lib/screens/BankDetail.js +596 -0
- package/lib/screens/BookFD.d.ts +0 -0
- package/lib/screens/BookFD.js +315 -0
- package/lib/screens/Employee.d.ts +18 -0
- package/lib/screens/Employee.js +594 -0
- package/lib/screens/FDCalculator.d.ts +18 -0
- package/lib/screens/FDCalculator.js +759 -0
- package/lib/screens/FDList.d.ts +27 -0
- package/lib/screens/FDList.js +1008 -0
- package/lib/screens/FindIFSC.d.ts +16 -0
- package/lib/screens/FindIFSC.js +248 -0
- package/lib/screens/Home.d.ts +0 -0
- package/lib/screens/Home.js +143 -0
- package/lib/screens/NomineeDetail.d.ts +17 -0
- package/lib/screens/NomineeDetail.js +592 -0
- package/lib/screens/PayNow.d.ts +14 -0
- package/lib/screens/PayNow.js +230 -0
- package/lib/screens/Payment.d.ts +11 -0
- package/lib/screens/Payment.js +191 -0
- package/lib/screens/PaymentStatus.d.ts +16 -0
- package/lib/screens/PaymentStatus.js +397 -0
- package/lib/screens/ReviewKYC.d.ts +21 -0
- package/lib/screens/ReviewKYC.js +660 -0
- package/lib/state/paymentSession.d.ts +8 -0
- package/lib/state/paymentSession.js +13 -0
- package/lib/store/fdListSelectedSlice.d.ts +21 -0
- package/lib/store/fdListSelectedSlice.js +26 -0
- package/lib/store/hooks.d.ts +8 -0
- package/lib/store/hooks.js +31 -0
- package/lib/store/index.d.ts +3 -0
- package/lib/store/index.js +8 -0
- package/lib/store/onboardingSlice.d.ts +12 -0
- package/lib/store/onboardingSlice.js +32 -0
- package/lib/store/store.d.ts +13 -0
- package/lib/store/store.js +33 -0
- package/lib/theme/ThemeContext.d.ts +210 -0
- package/lib/theme/ThemeContext.js +90 -0
- package/lib/theme/colors.d.ts +80 -0
- package/lib/theme/colors.js +85 -0
- package/lib/theme/index.d.ts +34 -0
- package/lib/theme/index.js +69 -0
- package/lib/theme/shadows.d.ts +53 -0
- package/lib/theme/shadows.js +58 -0
- package/lib/theme/typography.d.ts +134 -0
- package/lib/theme/typography.js +143 -0
- package/lib/types/dataTypes.d.ts +34 -0
- package/lib/types/dataTypes.js +2 -0
- package/lib/types/workflowTypes.d.ts +2 -0
- package/lib/types/workflowTypes.js +2 -0
- package/lib/utils/apiLogger.d.ts +48 -0
- package/lib/utils/apiLogger.js +105 -0
- package/lib/utils/encryption.d.ts +28 -0
- package/lib/utils/encryption.js +113 -0
- package/lib/utils/getFDData.d.ts +48 -0
- package/lib/utils/getFDData.js +154 -0
- package/lib/utils/globalData.d.ts +2 -0
- package/lib/utils/globalData.js +10 -0
- package/package.json +76 -0
- package/src/api/applicationApi.ts +12 -0
- package/src/api/bankApi.ts +42 -0
- package/src/api/baseApi.ts +513 -0
- package/src/api/customerApi.ts +291 -0
- package/src/api/fdApi.ts +150 -0
- package/src/api/fdCalculatorApi.ts +41 -0
- package/src/api/index.ts +29 -0
- package/src/api/interestRateApi.ts +143 -0
- package/src/api/kycApi.ts +63 -0
- package/src/api/masterDataApi.ts +34 -0
- package/src/api/nomineeApi.ts +34 -0
- package/src/api/onboardingApi.ts +64 -0
- package/src/api/panApi.ts +25 -0
- package/src/api/paymentApi.ts +34 -0
- package/src/api/workflowApi.ts +94 -0
- package/src/assets/images/arrow-filled.png +0 -0
- package/src/assets/images/arrow-left.png +0 -0
- package/src/assets/images/backicon.png +0 -0
- package/src/assets/images/calendar.png +0 -0
- package/src/assets/images/chevron-down.png +0 -0
- package/src/assets/images/chevron-down@2x.png +0 -0
- package/src/assets/images/chevron-down@3x.png +0 -0
- package/src/assets/images/images.js +8 -0
- package/src/components/AadhaarInput.tsx +91 -0
- package/src/components/ActionButton.tsx +129 -0
- package/src/components/ActiveFDCard.tsx +158 -0
- package/src/components/AmountInput.tsx +217 -0
- package/src/components/CheckboxOption.tsx +93 -0
- package/src/components/CompanyHeader.tsx +78 -0
- package/src/components/DropdownSelector.tsx +77 -0
- package/src/components/EmptyState.tsx +109 -0
- package/src/components/ErrorDisplay.tsx +135 -0
- package/src/components/FAQItem.tsx +90 -0
- package/src/components/FDCard.tsx +165 -0
- package/src/components/FormDropdown.tsx +214 -0
- package/src/components/FormSection.tsx +86 -0
- package/src/components/Header.tsx +110 -0
- package/src/components/IFSCSearchResultCard.tsx +139 -0
- package/src/components/InfoBox.tsx +55 -0
- package/src/components/InterestRateCard.tsx +77 -0
- package/src/components/LoadingIndicator.tsx +63 -0
- package/src/components/OTPInput.tsx +213 -0
- package/src/components/PaymentDetailsCard.tsx +120 -0
- package/src/components/PendingFDBottomSheet.tsx +235 -0
- package/src/components/README.md +210 -0
- package/src/components/SafeAreaWrapper.tsx +68 -0
- package/src/components/ScreenHeader.tsx +83 -0
- package/src/components/StatusDisplay.tsx +139 -0
- package/src/components/TextFieldWithLabel.tsx +502 -0
- package/src/components/TrustBox.tsx +63 -0
- package/src/components/ValidationErrorAlert.tsx +57 -0
- package/src/components/ValidationMessage.tsx +134 -0
- package/src/components/index.tsx +47 -0
- package/src/config/apiConfig.ts +217 -0
- package/src/config/appDataConfig.ts +279 -0
- package/src/config/encryptionConfig.ts +65 -0
- package/src/config/workflowConstants.ts +43 -0
- package/src/constants/strings/README.md +146 -0
- package/src/constants/strings/bank.ts +92 -0
- package/src/constants/strings/base64Images.ts +29 -0
- package/src/constants/strings/common.ts +63 -0
- package/src/constants/strings/employee.ts +85 -0
- package/src/constants/strings/faq.ts +23 -0
- package/src/constants/strings/fd.ts +172 -0
- package/src/constants/strings/home.ts +67 -0
- package/src/constants/strings/index.ts +21 -0
- package/src/constants/strings/kyc.ts +100 -0
- package/src/constants/strings/nominee.ts +90 -0
- package/src/hooks/useAuth.ts +42 -0
- package/src/hooks/useFDData.ts +48 -0
- package/src/index.tsx +173 -0
- package/src/navigation/RootNavigator.tsx +352 -0
- package/src/navigation/SimpleNavigator.tsx +107 -0
- package/src/navigation/helpers.ts +85 -0
- package/src/navigation/index.tsx +81 -0
- package/src/navigation/types.ts +124 -0
- package/src/navigation/workflowNavigator.ts +131 -0
- package/src/providers/ApiProvider.tsx +43 -0
- package/src/providers/MasterDataProvider.tsx +30 -0
- package/src/screens/AadhaarVerification.tsx +809 -0
- package/src/screens/AddBankAccount.tsx +541 -0
- package/src/screens/BankDetail.tsx +826 -0
- package/src/screens/BookFD.tsx +330 -0
- package/src/screens/Employee.tsx +822 -0
- package/src/screens/FDCalculator.tsx +987 -0
- package/src/screens/FDList.tsx +1284 -0
- package/src/screens/FindIFSC.tsx +332 -0
- package/src/screens/Home.tsx +152 -0
- package/src/screens/NomineeDetail.tsx +800 -0
- package/src/screens/PayNow.tsx +282 -0
- package/src/screens/Payment.tsx +224 -0
- package/src/screens/PaymentStatus.tsx +561 -0
- package/src/screens/ReviewKYC.tsx +956 -0
- package/src/state/paymentSession.ts +13 -0
- package/src/store/fdListSelectedSlice.ts +42 -0
- package/src/store/hooks.ts +27 -0
- package/src/store/index.ts +3 -0
- package/src/store/onboardingSlice.ts +37 -0
- package/src/store/store.ts +35 -0
- package/src/theme/ThemeContext.tsx +82 -0
- package/src/theme/colors.ts +90 -0
- package/src/theme/index.ts +64 -0
- package/src/theme/shadows.ts +61 -0
- package/src/theme/typography.ts +151 -0
- package/src/types/dataTypes.ts +37 -0
- package/src/types/env.d.ts +93 -0
- package/src/types/workflowTypes.ts +12 -0
- package/src/utils/apiLogger.ts +166 -0
- package/src/utils/encryption.ts +159 -0
- package/src/utils/getFDData.ts +175 -0
- package/src/utils/globalData.ts +7 -0
|
@@ -0,0 +1,594 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
const react_1 = __importStar(require("react"));
|
|
40
|
+
const react_native_1 = require("react-native");
|
|
41
|
+
const Ionicons_1 = __importDefault(require("react-native-vector-icons/Ionicons"));
|
|
42
|
+
const SafeAreaWrapper_1 = __importDefault(require("../components/SafeAreaWrapper"));
|
|
43
|
+
const components_1 = require("../components");
|
|
44
|
+
const ActionButton_1 = __importDefault(require("../components/ActionButton"));
|
|
45
|
+
const TextFieldWithLabel_1 = __importDefault(require("../components/TextFieldWithLabel"));
|
|
46
|
+
const ThemeContext_1 = require("../theme/ThemeContext");
|
|
47
|
+
const MasterDataProvider_1 = require("../providers/MasterDataProvider");
|
|
48
|
+
const customerApi_1 = require("../api/customerApi");
|
|
49
|
+
const store_1 = require("../store");
|
|
50
|
+
const appDataConfig_1 = require("../config/appDataConfig");
|
|
51
|
+
const workflowApi_1 = require("../api/workflowApi");
|
|
52
|
+
const helpers_1 = require("../navigation/helpers");
|
|
53
|
+
const native_1 = require("@react-navigation/native");
|
|
54
|
+
const employee_1 = require("../constants/strings/employee");
|
|
55
|
+
const common_1 = require("../constants/strings/common");
|
|
56
|
+
// These will be replaced/augmented with master data
|
|
57
|
+
const defaultOccupationOptions = ['Salaried', 'Self Employed', 'Professional', 'Student', 'Retired', 'Other'];
|
|
58
|
+
const defaultNatureOfBusinessOptions = ['IT Services', 'Manufacturing', 'Trading', 'Finance', 'Other'];
|
|
59
|
+
const defaultAnnualIncomeOptions = ['< 2 lakhs', '3-5 lakhs', '5-10 lakhs', '10-20 lakhs', '> 20 lakhs'];
|
|
60
|
+
const defaultSourceOfFundOptions = ['Salary', 'Business', 'Investment', 'Individual', 'Other'];
|
|
61
|
+
const defaultPepOptions = ['Individual', 'Family Member', 'Associate', 'No'];
|
|
62
|
+
const Employee = ({ onGoBack, onContinue, initialData }) => {
|
|
63
|
+
const colors = (0, ThemeContext_1.useColors)();
|
|
64
|
+
const typography = (0, ThemeContext_1.useTypography)();
|
|
65
|
+
const { themeName } = (0, ThemeContext_1.useTheme)();
|
|
66
|
+
const styles = createStyles(colors, typography, themeName);
|
|
67
|
+
const { masterData, setMasterData } = (0, MasterDataProvider_1.useMasterData)();
|
|
68
|
+
const workflowInstanceId = (0, store_1.useAppSelector)((state) => { var _a; return (_a = state === null || state === void 0 ? void 0 : state.onboarding) === null || _a === void 0 ? void 0 : _a.workflowInstanceId; });
|
|
69
|
+
const applicationId = (0, store_1.useAppSelector)((state) => { var _a; return (_a = state === null || state === void 0 ? void 0 : state.onboarding) === null || _a === void 0 ? void 0 : _a.applicationId; });
|
|
70
|
+
const customerId = (0, store_1.useAppSelector)((state) => { var _a; return (_a = state === null || state === void 0 ? void 0 : state.onboarding) === null || _a === void 0 ? void 0 : _a.customerId; });
|
|
71
|
+
// Get providerId from app data or use default
|
|
72
|
+
const defaultProviderId = (0, store_1.useAppSelector)((state) => { var _a; return (_a = state === null || state === void 0 ? void 0 : state.onboarding) === null || _a === void 0 ? void 0 : _a.providerId; }); // Default Shriram provider ID
|
|
73
|
+
// Customer Occupation API
|
|
74
|
+
const [customerOccupation, { data: customerOccupationResponse, error: customerOccupationError, isLoading: isLoadingCustomerOccupation, }] = (0, customerApi_1.useCustomerOccupationMutation)();
|
|
75
|
+
// Previous State API
|
|
76
|
+
const [previousState] = (0, workflowApi_1.usePreviousStateMutation)();
|
|
77
|
+
// Customer Application Details API (called on focus)
|
|
78
|
+
const [getCustomerApplicationDetails, { data: customerApplicationDetailsResponse, error: customerApplicationDetailsError, isLoading: isLoadingCustomerApplicationDetails, }] = (0, customerApi_1.useGetCustomerApplicationDetailsMutation)();
|
|
79
|
+
// Call customer/application/details whenever this screen gains focus
|
|
80
|
+
(0, native_1.useFocusEffect)(react_1.default.useCallback(() => {
|
|
81
|
+
let isActive = true;
|
|
82
|
+
(async () => {
|
|
83
|
+
var _a;
|
|
84
|
+
try {
|
|
85
|
+
const userInfo = (0, appDataConfig_1.getUserInfoForAPI)();
|
|
86
|
+
const req = {
|
|
87
|
+
providerId: defaultProviderId,
|
|
88
|
+
workflowInstanceId,
|
|
89
|
+
userreferenceid: userInfo.userReferenceId,
|
|
90
|
+
applicationid: applicationId,
|
|
91
|
+
entityid: '',
|
|
92
|
+
// Body params
|
|
93
|
+
applicationId: applicationId,
|
|
94
|
+
customerId: customerId,
|
|
95
|
+
};
|
|
96
|
+
const res = await getCustomerApplicationDetails(req).unwrap();
|
|
97
|
+
if (!isActive)
|
|
98
|
+
return;
|
|
99
|
+
// Set form data from employment object in API response
|
|
100
|
+
if ((_a = res === null || res === void 0 ? void 0 : res.data) === null || _a === void 0 ? void 0 : _a.employment) {
|
|
101
|
+
const employment = res.data.employment;
|
|
102
|
+
setForm(prev => (Object.assign(Object.assign({}, prev), { occupation: employment.occupation || '', natureOfBusiness: employment.nature_of_business || '', customOccupation: employment.custom_occupation || '', customNatureOfBusiness: employment.custom_nature_of_business || '', annualIncome: employment.income || '', sourceOfFund: employment.source_of_fund || '', customSourceOfFund: employment.custom_source_of_fund || '', politicallyExposedPerson: employment.politically_exposed_person || '' })));
|
|
103
|
+
}
|
|
104
|
+
else {
|
|
105
|
+
// If employment is empty, clear all fields
|
|
106
|
+
setForm(prev => (Object.assign(Object.assign({}, prev), { occupation: '', natureOfBusiness: '', customOccupation: '', customNatureOfBusiness: '', annualIncome: '', sourceOfFund: '', customSourceOfFund: '', politicallyExposedPerson: '' })));
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
catch (e) {
|
|
110
|
+
if (!isActive)
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
})();
|
|
114
|
+
return () => { isActive = false; };
|
|
115
|
+
}, [defaultProviderId, workflowInstanceId, applicationId, customerId, getCustomerApplicationDetails]));
|
|
116
|
+
// Customer occupation API status monitored
|
|
117
|
+
// Helper to normalize arrays/CSV strings to string[]
|
|
118
|
+
const normalizeOptions = (raw, fallback) => {
|
|
119
|
+
if (Array.isArray(raw))
|
|
120
|
+
return raw.map((v) => String(v)).filter(Boolean);
|
|
121
|
+
if (typeof raw === 'string' && raw.trim().length)
|
|
122
|
+
return raw.split(',').map((v) => v.trim()).filter(Boolean);
|
|
123
|
+
return fallback;
|
|
124
|
+
};
|
|
125
|
+
// Master data root may be data-wrapped
|
|
126
|
+
const md = (masterData === null || masterData === void 0 ? void 0 : masterData.data) || masterData || {};
|
|
127
|
+
// Get options from master data with fallbacks
|
|
128
|
+
const occupationOptions = react_1.default.useMemo(() => {
|
|
129
|
+
const fromGlobal = (md === null || md === void 0 ? void 0 : md.occupation) || (masterData === null || masterData === void 0 ? void 0 : masterData.occupation);
|
|
130
|
+
return normalizeOptions(fromGlobal, defaultOccupationOptions);
|
|
131
|
+
}, [md, masterData]);
|
|
132
|
+
const natureOfBusinessOptions = react_1.default.useMemo(() => {
|
|
133
|
+
const raw = (md === null || md === void 0 ? void 0 : md.natureOfBusiness) || (md === null || md === void 0 ? void 0 : md.natureOfBusinessOptions) || (md === null || md === void 0 ? void 0 : md.natureOfBusinessList);
|
|
134
|
+
return normalizeOptions(raw, defaultNatureOfBusinessOptions);
|
|
135
|
+
}, [md]);
|
|
136
|
+
const annualIncomeOptions = react_1.default.useMemo(() => {
|
|
137
|
+
const raw = (md === null || md === void 0 ? void 0 : md.annualIncome) || (md === null || md === void 0 ? void 0 : md.annualIncomeOptions) || (md === null || md === void 0 ? void 0 : md.annualIncomeList);
|
|
138
|
+
return normalizeOptions(raw, defaultAnnualIncomeOptions);
|
|
139
|
+
}, [md]);
|
|
140
|
+
const sourceOfFundOptions = react_1.default.useMemo(() => {
|
|
141
|
+
const raw = (md === null || md === void 0 ? void 0 : md.sourceOfFund) || (md === null || md === void 0 ? void 0 : md.sourceOfFundOptions) || (md === null || md === void 0 ? void 0 : md.sourceOfFundList) || (md === null || md === void 0 ? void 0 : md.sourceOfFunds);
|
|
142
|
+
return normalizeOptions(raw, defaultSourceOfFundOptions);
|
|
143
|
+
}, [md]);
|
|
144
|
+
const pepOptions = react_1.default.useMemo(() => {
|
|
145
|
+
const raw = (md === null || md === void 0 ? void 0 : md.pepOptions)
|
|
146
|
+
|| (md === null || md === void 0 ? void 0 : md.politicallyExposedPersonOptions)
|
|
147
|
+
|| (md === null || md === void 0 ? void 0 : md.pepList)
|
|
148
|
+
|| (md === null || md === void 0 ? void 0 : md.politicallyExposedPersonList)
|
|
149
|
+
|| (md === null || md === void 0 ? void 0 : md.politicallyExposedPerson) // sometimes provided as CSV/string
|
|
150
|
+
|| (md === null || md === void 0 ? void 0 : md.pep); // alternate short key
|
|
151
|
+
return normalizeOptions(raw, defaultPepOptions);
|
|
152
|
+
}, [md]);
|
|
153
|
+
const [form, setForm] = (0, react_1.useState)({
|
|
154
|
+
occupation: (initialData === null || initialData === void 0 ? void 0 : initialData.occupation) || (occupationOptions[0] || 'Self Employed'),
|
|
155
|
+
natureOfBusiness: (initialData === null || initialData === void 0 ? void 0 : initialData.natureOfBusiness) || (natureOfBusinessOptions[0] || 'Other'),
|
|
156
|
+
customOccupation: (initialData === null || initialData === void 0 ? void 0 : initialData.customOccupation) || '',
|
|
157
|
+
customNatureOfBusiness: (initialData === null || initialData === void 0 ? void 0 : initialData.customNatureOfBusiness) || '',
|
|
158
|
+
annualIncome: (initialData === null || initialData === void 0 ? void 0 : initialData.annualIncome) || (annualIncomeOptions[0] || defaultAnnualIncomeOptions[0]),
|
|
159
|
+
sourceOfFund: (initialData === null || initialData === void 0 ? void 0 : initialData.sourceOfFund) || (sourceOfFundOptions[0] || defaultSourceOfFundOptions[0]),
|
|
160
|
+
customSourceOfFund: (initialData === null || initialData === void 0 ? void 0 : initialData.customSourceOfFund) || '',
|
|
161
|
+
politicallyExposedPerson: (initialData === null || initialData === void 0 ? void 0 : initialData.politicallyExposedPerson) || (pepOptions[0] || defaultPepOptions[0]),
|
|
162
|
+
});
|
|
163
|
+
// Keep selections valid if options change after load
|
|
164
|
+
react_1.default.useEffect(() => {
|
|
165
|
+
setForm(prev => (Object.assign(Object.assign({}, prev), { occupation: occupationOptions.includes(prev.occupation) ? prev.occupation : (occupationOptions[0] || prev.occupation), natureOfBusiness: natureOfBusinessOptions.includes(prev.natureOfBusiness) ? prev.natureOfBusiness : (natureOfBusinessOptions[0] || prev.natureOfBusiness), annualIncome: annualIncomeOptions.includes(prev.annualIncome) ? prev.annualIncome : (annualIncomeOptions[0] || prev.annualIncome), sourceOfFund: sourceOfFundOptions.includes(prev.sourceOfFund) ? prev.sourceOfFund : (sourceOfFundOptions[0] || prev.sourceOfFund), politicallyExposedPerson: pepOptions.includes(prev.politicallyExposedPerson) ? prev.politicallyExposedPerson : (pepOptions[0] || prev.politicallyExposedPerson) })));
|
|
166
|
+
}, [occupationOptions, natureOfBusinessOptions, annualIncomeOptions, sourceOfFundOptions, pepOptions]);
|
|
167
|
+
const [isGoingBack, setIsGoingBack] = (0, react_1.useState)(false);
|
|
168
|
+
const [openMenus, setOpenMenus] = (0, react_1.useState)({
|
|
169
|
+
occupation: false,
|
|
170
|
+
natureOfBusiness: false,
|
|
171
|
+
annualIncome: false,
|
|
172
|
+
sourceOfFund: false,
|
|
173
|
+
pep: false,
|
|
174
|
+
});
|
|
175
|
+
// Error states for custom fields
|
|
176
|
+
const [fieldErrors, setFieldErrors] = (0, react_1.useState)({});
|
|
177
|
+
// Track if continue button was pressed to disable it immediately
|
|
178
|
+
const [isSubmitting, setIsSubmitting] = (0, react_1.useState)(false);
|
|
179
|
+
// Track if component is mounted to prevent API calls after unmount
|
|
180
|
+
const isMountedRef = react_1.default.useRef(true);
|
|
181
|
+
// Use ref for immediate synchronous check to prevent race conditions
|
|
182
|
+
const isApiCallInProgressRef = react_1.default.useRef(false);
|
|
183
|
+
// Validate custom fields when form data changes
|
|
184
|
+
react_1.default.useEffect(() => {
|
|
185
|
+
// Validate custom occupation
|
|
186
|
+
const occupationError = validateCustomField('customOccupation', form.customOccupation, 'occupation');
|
|
187
|
+
setFieldErrors(prev => (Object.assign(Object.assign({}, prev), { customOccupation: occupationError })));
|
|
188
|
+
// Validate custom nature of business
|
|
189
|
+
const natureError = validateCustomField('customNatureOfBusiness', form.customNatureOfBusiness, 'natureOfBusiness');
|
|
190
|
+
setFieldErrors(prev => (Object.assign(Object.assign({}, prev), { customNatureOfBusiness: natureError })));
|
|
191
|
+
// Validate custom source of fund
|
|
192
|
+
const sourceError = validateCustomField('customSourceOfFund', form.customSourceOfFund, 'sourceOfFund');
|
|
193
|
+
setFieldErrors(prev => (Object.assign(Object.assign({}, prev), { customSourceOfFund: sourceError })));
|
|
194
|
+
}, [form.occupation, form.natureOfBusiness, form.sourceOfFund, form.customOccupation, form.customNatureOfBusiness, form.customSourceOfFund]);
|
|
195
|
+
// Validate custom field and set error
|
|
196
|
+
const validateCustomField = (field, value, parentField) => {
|
|
197
|
+
const parentValue = String(form[parentField] || '').trim().toLowerCase();
|
|
198
|
+
const isOther = parentValue === 'other' || parentValue === 'others';
|
|
199
|
+
// Show error immediately when "Other" is selected, even if custom field is empty
|
|
200
|
+
if (isOther) {
|
|
201
|
+
if (!value || value.trim().length === 0) {
|
|
202
|
+
// Get user-friendly label based on parent field
|
|
203
|
+
let label = '';
|
|
204
|
+
switch (parentField) {
|
|
205
|
+
case 'occupation':
|
|
206
|
+
label = employee_1.EMPLOYEE_STRINGS.OCCUPATION_LABEL;
|
|
207
|
+
break;
|
|
208
|
+
case 'natureOfBusiness':
|
|
209
|
+
label = employee_1.EMPLOYEE_STRINGS.NATURE_OF_BUSINESS_LABEL;
|
|
210
|
+
break;
|
|
211
|
+
case 'sourceOfFund':
|
|
212
|
+
label = employee_1.EMPLOYEE_STRINGS.SOURCE_OF_FUND_LABEL;
|
|
213
|
+
break;
|
|
214
|
+
default:
|
|
215
|
+
label = parentField;
|
|
216
|
+
}
|
|
217
|
+
return `${label} is required`;
|
|
218
|
+
}
|
|
219
|
+
// Validate minimum 2 characters
|
|
220
|
+
if (value && value.trim().length > 0 && value.trim().length < 2) {
|
|
221
|
+
// Get user-friendly label based on parent field
|
|
222
|
+
let label = '';
|
|
223
|
+
switch (parentField) {
|
|
224
|
+
case 'occupation':
|
|
225
|
+
label = employee_1.EMPLOYEE_STRINGS.OCCUPATION_LABEL;
|
|
226
|
+
break;
|
|
227
|
+
case 'natureOfBusiness':
|
|
228
|
+
label = employee_1.EMPLOYEE_STRINGS.NATURE_OF_BUSINESS_LABEL;
|
|
229
|
+
break;
|
|
230
|
+
case 'sourceOfFund':
|
|
231
|
+
label = employee_1.EMPLOYEE_STRINGS.SOURCE_OF_FUND_LABEL;
|
|
232
|
+
break;
|
|
233
|
+
default:
|
|
234
|
+
label = parentField;
|
|
235
|
+
}
|
|
236
|
+
return `${label} must be at least 2 characters`;
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
return '';
|
|
240
|
+
};
|
|
241
|
+
// Render error message for a field
|
|
242
|
+
const renderFieldError = (field) => {
|
|
243
|
+
const error = fieldErrors[field];
|
|
244
|
+
if (!error)
|
|
245
|
+
return null;
|
|
246
|
+
return (react_1.default.createElement(react_native_1.View, { style: styles.errorContainer },
|
|
247
|
+
react_native_1.Platform.OS === 'android' && (react_1.default.createElement(Ionicons_1.default, { name: "warning", size: 16, color: colors.error || '#FF0000', style: styles.errorIcon })),
|
|
248
|
+
react_1.default.createElement(react_native_1.Text, { style: styles.errorText }, error)));
|
|
249
|
+
};
|
|
250
|
+
// Check if occupation is "Self Employed" to conditionally show nature of business
|
|
251
|
+
const isSelfEmployed = react_1.default.useMemo(() => {
|
|
252
|
+
const occupation = String(form.occupation || '').trim().toLowerCase();
|
|
253
|
+
return occupation === 'self employed';
|
|
254
|
+
}, [form.occupation]);
|
|
255
|
+
// Validate required fields; require custom fields when "Other" selected
|
|
256
|
+
const isFormValid = react_1.default.useMemo(() => {
|
|
257
|
+
const hasBasic = Boolean(String(form.occupation || '').trim() &&
|
|
258
|
+
(isSelfEmployed ? String(form.natureOfBusiness || '').trim() : true) &&
|
|
259
|
+
String(form.annualIncome || '').trim() &&
|
|
260
|
+
String(form.sourceOfFund || '').trim() &&
|
|
261
|
+
String(form.politicallyExposedPerson || '').trim());
|
|
262
|
+
const occ = String(form.occupation || '').trim().toLowerCase();
|
|
263
|
+
const nbf = String(form.natureOfBusiness || '').trim().toLowerCase();
|
|
264
|
+
const sof = String(form.sourceOfFund || '').trim().toLowerCase();
|
|
265
|
+
const needsCustomOcc = occ === 'other' || occ === 'others';
|
|
266
|
+
const needsCustomNob = isSelfEmployed && (nbf === 'other' || nbf === 'others');
|
|
267
|
+
const needsCustomSof = sof === 'other' || sof === 'others';
|
|
268
|
+
const customOk = ((!needsCustomOcc || String(form.customOccupation || '').trim().length >= 2) &&
|
|
269
|
+
(!needsCustomNob || String(form.customNatureOfBusiness || '').trim().length >= 2) &&
|
|
270
|
+
(!needsCustomSof || String(form.customSourceOfFund || '').trim().length >= 2));
|
|
271
|
+
return hasBasic && customOk;
|
|
272
|
+
}, [form, isSelfEmployed]);
|
|
273
|
+
const updateField = (field, value) => {
|
|
274
|
+
setForm(prev => {
|
|
275
|
+
const newForm = Object.assign(Object.assign({}, prev), { [field]: value });
|
|
276
|
+
// Clear Nature of Business fields when occupation changes to non-self-employed
|
|
277
|
+
if (field === 'occupation') {
|
|
278
|
+
const occupation = String(value || '').trim().toLowerCase();
|
|
279
|
+
const isSelfEmployed = occupation === 'self employed';
|
|
280
|
+
if (!isSelfEmployed) {
|
|
281
|
+
newForm.natureOfBusiness = '';
|
|
282
|
+
newForm.customNatureOfBusiness = '';
|
|
283
|
+
// Also clear any field errors for Nature of Business
|
|
284
|
+
setFieldErrors(prev => (Object.assign(Object.assign({}, prev), { natureOfBusiness: '', customNatureOfBusiness: '' })));
|
|
285
|
+
}
|
|
286
|
+
// If occupation is not Other, clear customOccupation
|
|
287
|
+
const isOccOther = occupation === 'other' || occupation === 'others';
|
|
288
|
+
if (!isOccOther) {
|
|
289
|
+
newForm.customOccupation = '';
|
|
290
|
+
setFieldErrors(prev => (Object.assign(Object.assign({}, prev), { customOccupation: '' })));
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
// If Nature of Business changes away from Other, clear its custom field
|
|
294
|
+
if (field === 'natureOfBusiness') {
|
|
295
|
+
const nob = String(value || '').trim().toLowerCase();
|
|
296
|
+
const isOther = nob === 'other' || nob === 'others';
|
|
297
|
+
if (!isOther) {
|
|
298
|
+
newForm.customNatureOfBusiness = '';
|
|
299
|
+
setFieldErrors(prev => (Object.assign(Object.assign({}, prev), { customNatureOfBusiness: '' })));
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
// If Source of Fund changes away from Other, clear its custom field
|
|
303
|
+
if (field === 'sourceOfFund') {
|
|
304
|
+
const sof = String(value || '').trim().toLowerCase();
|
|
305
|
+
const isOther = sof === 'other' || sof === 'others';
|
|
306
|
+
if (!isOther) {
|
|
307
|
+
newForm.customSourceOfFund = '';
|
|
308
|
+
setFieldErrors(prev => (Object.assign(Object.assign({}, prev), { customSourceOfFund: '' })));
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
return newForm;
|
|
312
|
+
});
|
|
313
|
+
// Validate custom fields when they are updated
|
|
314
|
+
if (field === 'customOccupation') {
|
|
315
|
+
const error = validateCustomField('customOccupation', value, 'occupation');
|
|
316
|
+
setFieldErrors(prev => (Object.assign(Object.assign({}, prev), { customOccupation: error })));
|
|
317
|
+
}
|
|
318
|
+
else if (field === 'customNatureOfBusiness') {
|
|
319
|
+
const error = validateCustomField('customNatureOfBusiness', value, 'natureOfBusiness');
|
|
320
|
+
setFieldErrors(prev => (Object.assign(Object.assign({}, prev), { customNatureOfBusiness: error })));
|
|
321
|
+
}
|
|
322
|
+
else if (field === 'customSourceOfFund') {
|
|
323
|
+
const error = validateCustomField('customSourceOfFund', value, 'sourceOfFund');
|
|
324
|
+
setFieldErrors(prev => (Object.assign(Object.assign({}, prev), { customSourceOfFund: error })));
|
|
325
|
+
}
|
|
326
|
+
// Also validate custom fields when parent fields change
|
|
327
|
+
if (field === 'occupation') {
|
|
328
|
+
const error = validateCustomField('customOccupation', form.customOccupation, 'occupation');
|
|
329
|
+
setFieldErrors(prev => (Object.assign(Object.assign({}, prev), { customOccupation: error })));
|
|
330
|
+
}
|
|
331
|
+
else if (field === 'natureOfBusiness') {
|
|
332
|
+
const error = validateCustomField('customNatureOfBusiness', form.customNatureOfBusiness, 'natureOfBusiness');
|
|
333
|
+
setFieldErrors(prev => (Object.assign(Object.assign({}, prev), { customNatureOfBusiness: error })));
|
|
334
|
+
}
|
|
335
|
+
else if (field === 'sourceOfFund') {
|
|
336
|
+
const error = validateCustomField('customSourceOfFund', form.customSourceOfFund, 'sourceOfFund');
|
|
337
|
+
setFieldErrors(prev => (Object.assign(Object.assign({}, prev), { customSourceOfFund: error })));
|
|
338
|
+
}
|
|
339
|
+
};
|
|
340
|
+
const toggleMenu = (key) => {
|
|
341
|
+
setOpenMenus(prev => ({
|
|
342
|
+
occupation: false,
|
|
343
|
+
natureOfBusiness: false,
|
|
344
|
+
annualIncome: false,
|
|
345
|
+
sourceOfFund: false,
|
|
346
|
+
pep: false,
|
|
347
|
+
[key]: !prev[key],
|
|
348
|
+
}));
|
|
349
|
+
};
|
|
350
|
+
const closeAllMenus = () => {
|
|
351
|
+
setOpenMenus({
|
|
352
|
+
occupation: false,
|
|
353
|
+
natureOfBusiness: false,
|
|
354
|
+
annualIncome: false,
|
|
355
|
+
sourceOfFund: false,
|
|
356
|
+
pep: false,
|
|
357
|
+
});
|
|
358
|
+
};
|
|
359
|
+
const renderDropdown = (label, value, field, options, menuKey) => (react_1.default.createElement(react_native_1.View, null,
|
|
360
|
+
react_1.default.createElement(TextFieldWithLabel_1.default, { label: label, value: value || '', onChangeText: (text) => updateField(field, text), variant: "dropdown", options: options, isDropdownOpen: openMenus[menuKey], onDropdownToggle: () => toggleMenu(menuKey), onDropdownSelect: (option) => {
|
|
361
|
+
closeAllMenus();
|
|
362
|
+
updateField(field, option);
|
|
363
|
+
setOpenMenus(prev => (Object.assign(Object.assign({}, prev), { [menuKey]: false })));
|
|
364
|
+
}, placeholder: employee_1.EMPLOYEE_STRINGS.OCCUPATION_PLACEHOLDER, placeholderColor: themeName === 'dark' ? colors.placeholderColor : 'rgba(0,0,0,0.2)' }),
|
|
365
|
+
openMenus[menuKey] && (react_1.default.createElement(react_native_1.View, { style: styles.inlineMenu }, options.map((option) => (react_1.default.createElement(react_native_1.TouchableOpacity, { key: option, style: styles.modalOption, onPress: () => {
|
|
366
|
+
closeAllMenus();
|
|
367
|
+
updateField(field, option);
|
|
368
|
+
setOpenMenus(prev => (Object.assign(Object.assign({}, prev), { [menuKey]: false })));
|
|
369
|
+
} },
|
|
370
|
+
react_1.default.createElement(react_native_1.Text, { style: styles.modalOptionText }, option))))))));
|
|
371
|
+
// Reset button states when component mounts (in case user navigates back)
|
|
372
|
+
react_1.default.useEffect(() => {
|
|
373
|
+
isApiCallInProgressRef.current = false;
|
|
374
|
+
setIsSubmitting(false);
|
|
375
|
+
}, []);
|
|
376
|
+
// Cleanup on unmount
|
|
377
|
+
react_1.default.useEffect(() => {
|
|
378
|
+
return () => {
|
|
379
|
+
isMountedRef.current = false;
|
|
380
|
+
};
|
|
381
|
+
}, []);
|
|
382
|
+
// customer/occupation API is ONLY called when user clicks Continue button on Employee screen
|
|
383
|
+
const handleContinue = async () => {
|
|
384
|
+
var _a;
|
|
385
|
+
// Immediately disable button for double-click prevention
|
|
386
|
+
if (isApiCallInProgressRef.current || isSubmitting || isLoadingCustomerOccupation) {
|
|
387
|
+
return;
|
|
388
|
+
}
|
|
389
|
+
// Set lock synchronously
|
|
390
|
+
isApiCallInProgressRef.current = true;
|
|
391
|
+
setIsSubmitting(true);
|
|
392
|
+
try {
|
|
393
|
+
// Get user info from app data
|
|
394
|
+
const userInfo = (0, appDataConfig_1.getUserInfoForAPI)();
|
|
395
|
+
// Prepare customer occupation request data
|
|
396
|
+
const customerOccupationRequest = {
|
|
397
|
+
providerId: defaultProviderId,
|
|
398
|
+
workflowInstanceId,
|
|
399
|
+
userreferenceid: userInfo.userReferenceId,
|
|
400
|
+
applicationid: applicationId,
|
|
401
|
+
customerId: customerId,
|
|
402
|
+
name: form.occupation,
|
|
403
|
+
natureOfBusiness: isSelfEmployed ? form.natureOfBusiness : '',
|
|
404
|
+
income: form.annualIncome,
|
|
405
|
+
sourceOfFund: form.sourceOfFund,
|
|
406
|
+
politicallyExposedPerson: form.politicallyExposedPerson,
|
|
407
|
+
customSourceOfFund: form.customSourceOfFund,
|
|
408
|
+
customNatureOfBusiness: isSelfEmployed ? form.customNatureOfBusiness : '',
|
|
409
|
+
customName: form.customOccupation,
|
|
410
|
+
};
|
|
411
|
+
const response = await customerOccupation(customerOccupationRequest).unwrap();
|
|
412
|
+
// Reset states before navigation to ensure button is enabled if user comes back
|
|
413
|
+
isApiCallInProgressRef.current = false;
|
|
414
|
+
setIsSubmitting(false);
|
|
415
|
+
if (!isMountedRef.current)
|
|
416
|
+
return;
|
|
417
|
+
onContinue === null || onContinue === void 0 ? void 0 : onContinue(form);
|
|
418
|
+
}
|
|
419
|
+
catch (error) {
|
|
420
|
+
// Reset states on error so user can retry
|
|
421
|
+
isApiCallInProgressRef.current = false;
|
|
422
|
+
setIsSubmitting(false);
|
|
423
|
+
if (!isMountedRef.current)
|
|
424
|
+
return;
|
|
425
|
+
const apiMessage = (error && error.data && (error.data.message || error.data.error || error.data.detail)) ||
|
|
426
|
+
(error === null || error === void 0 ? void 0 : error.error) ||
|
|
427
|
+
(error === null || error === void 0 ? void 0 : error.message) ||
|
|
428
|
+
'';
|
|
429
|
+
const fieldErrorsArr = (_a = error === null || error === void 0 ? void 0 : error.data) === null || _a === void 0 ? void 0 : _a.errors;
|
|
430
|
+
const fieldErrorsText = Array.isArray(fieldErrorsArr)
|
|
431
|
+
? fieldErrorsArr.map((e) => (typeof e === 'string' ? e : e === null || e === void 0 ? void 0 : e.message)).filter(Boolean).join('\n')
|
|
432
|
+
: '';
|
|
433
|
+
const message = [apiMessage, fieldErrorsText]
|
|
434
|
+
.filter((s) => typeof s === 'string' && s.trim().length)
|
|
435
|
+
.join('\n') || 'Unable to save your occupation details. Please check your information and try again.';
|
|
436
|
+
react_native_1.Alert.alert('Occupation Details Save Failed', message, [{ text: common_1.COMMON_STRINGS.OK }]);
|
|
437
|
+
}
|
|
438
|
+
};
|
|
439
|
+
// Handler for back button (used by both header and hardware back button)
|
|
440
|
+
const handleBackPress = async () => {
|
|
441
|
+
setIsGoingBack(true);
|
|
442
|
+
try {
|
|
443
|
+
const userInfo = (0, appDataConfig_1.getUserInfoForAPI)();
|
|
444
|
+
await previousState({
|
|
445
|
+
providerId: defaultProviderId,
|
|
446
|
+
workflowInstanceId,
|
|
447
|
+
userreferenceid: userInfo.userReferenceId,
|
|
448
|
+
applicationid: applicationId,
|
|
449
|
+
entityid: '',
|
|
450
|
+
});
|
|
451
|
+
}
|
|
452
|
+
catch (e) {
|
|
453
|
+
// Handle error silently
|
|
454
|
+
}
|
|
455
|
+
finally {
|
|
456
|
+
setIsGoingBack(false);
|
|
457
|
+
// Navigate to ReviewKYC screen instead of just going back
|
|
458
|
+
(0, helpers_1.navigate)('ReviewKYC');
|
|
459
|
+
}
|
|
460
|
+
};
|
|
461
|
+
// Handle Android hardware back button
|
|
462
|
+
(0, react_1.useEffect)(() => {
|
|
463
|
+
if (react_native_1.Platform.OS !== 'android')
|
|
464
|
+
return;
|
|
465
|
+
const onHardwareBackPress = () => {
|
|
466
|
+
handleBackPress();
|
|
467
|
+
return true; // Prevent default behavior
|
|
468
|
+
};
|
|
469
|
+
const backHandler = react_native_1.BackHandler.addEventListener('hardwareBackPress', onHardwareBackPress);
|
|
470
|
+
return () => backHandler.remove();
|
|
471
|
+
}, [defaultProviderId, workflowInstanceId, applicationId]);
|
|
472
|
+
return (react_1.default.createElement(SafeAreaWrapper_1.default, { includeTop: false, bottomPadding: 25, statusBarColor: "#000000", statusBarStyle: "light-content" },
|
|
473
|
+
react_1.default.createElement(components_1.Header, { title: employee_1.EMPLOYEE_STRINGS.OCCUPATION_DETAILS_TITLE, onBackPress: handleBackPress, backgroundColor: colors.primary }),
|
|
474
|
+
react_1.default.createElement(react_native_1.KeyboardAvoidingView, { behavior: react_native_1.Platform.OS === 'ios' ? 'padding' : undefined, style: styles.keyboardAvoidingView, keyboardVerticalOffset: react_native_1.Platform.OS === 'ios' ? 0 : 0 },
|
|
475
|
+
react_1.default.createElement(react_native_1.ScrollView, { style: styles.container, showsVerticalScrollIndicator: false, scrollEnabled: !(isLoadingCustomerOccupation || isSubmitting), keyboardShouldPersistTaps: "handled", contentContainerStyle: styles.scrollContent },
|
|
476
|
+
react_1.default.createElement(react_native_1.TouchableWithoutFeedback, { onPress: isLoadingCustomerOccupation || isSubmitting ? undefined : closeAllMenus },
|
|
477
|
+
react_1.default.createElement(react_native_1.View, null,
|
|
478
|
+
renderDropdown(employee_1.EMPLOYEE_STRINGS.OCCUPATION_LABEL, form.occupation, 'occupation', occupationOptions, 'occupation'),
|
|
479
|
+
(() => {
|
|
480
|
+
const val = String(form.occupation || '').trim().toLowerCase();
|
|
481
|
+
const isOther = val === 'other' || val === 'others';
|
|
482
|
+
return isOther ? (react_1.default.createElement(react_native_1.View, null,
|
|
483
|
+
react_1.default.createElement(TextFieldWithLabel_1.default, { label: "", containerStyle: { marginTop: -40 }, value: form.customOccupation || '', onChangeText: (text) => {
|
|
484
|
+
const lettersOnly = text.replace(/[^A-Za-z ]/g, '');
|
|
485
|
+
closeAllMenus();
|
|
486
|
+
updateField('customOccupation', lettersOnly);
|
|
487
|
+
}, placeholder: employee_1.EMPLOYEE_STRINGS.CUSTOM_OCCUPATION_PLACEHOLDER, placeholderColor: themeName === 'dark' ? colors.placeholderColor : 'rgba(0,0,0,0.2)', variant: "text" }),
|
|
488
|
+
renderFieldError('customOccupation'))) : null;
|
|
489
|
+
})(),
|
|
490
|
+
isSelfEmployed && (react_1.default.createElement(react_1.default.Fragment, null,
|
|
491
|
+
renderDropdown(employee_1.EMPLOYEE_STRINGS.NATURE_OF_BUSINESS_LABEL, form.natureOfBusiness, 'natureOfBusiness', natureOfBusinessOptions, 'natureOfBusiness'),
|
|
492
|
+
(() => {
|
|
493
|
+
const val = String(form.natureOfBusiness || '').trim().toLowerCase();
|
|
494
|
+
const isOther = val === 'other' || val === 'others';
|
|
495
|
+
return isOther ? (react_1.default.createElement(react_native_1.View, null,
|
|
496
|
+
react_1.default.createElement(TextFieldWithLabel_1.default, { label: "", containerStyle: { marginTop: -40 }, value: form.customNatureOfBusiness || '', onChangeText: (text) => {
|
|
497
|
+
const lettersOnly = text.replace(/[^A-Za-z ]/g, '');
|
|
498
|
+
closeAllMenus();
|
|
499
|
+
updateField('customNatureOfBusiness', lettersOnly);
|
|
500
|
+
}, placeholder: employee_1.EMPLOYEE_STRINGS.CUSTOM_NATURE_OF_BUSINESS_PLACEHOLDER, placeholderColor: themeName === 'dark' ? colors.placeholderColor : 'rgba(0,0,0,0.2)', variant: "text" }),
|
|
501
|
+
renderFieldError('customNatureOfBusiness'))) : null;
|
|
502
|
+
})())),
|
|
503
|
+
renderDropdown(employee_1.EMPLOYEE_STRINGS.ANNUAL_INCOME_LABEL, form.annualIncome, 'annualIncome', annualIncomeOptions, 'annualIncome'),
|
|
504
|
+
renderDropdown(employee_1.EMPLOYEE_STRINGS.SOURCE_OF_FUND_LABEL, form.sourceOfFund, 'sourceOfFund', sourceOfFundOptions, 'sourceOfFund'),
|
|
505
|
+
(() => {
|
|
506
|
+
const val = String(form.sourceOfFund || '').trim().toLowerCase();
|
|
507
|
+
const isOther = val === 'other' || val === 'others';
|
|
508
|
+
return isOther ? (react_1.default.createElement(react_native_1.View, null,
|
|
509
|
+
react_1.default.createElement(TextFieldWithLabel_1.default, { label: "", containerStyle: { marginTop: -40 }, value: form.customSourceOfFund || '', onChangeText: (text) => {
|
|
510
|
+
const lettersOnly = text.replace(/[^A-Za-z ]/g, '');
|
|
511
|
+
closeAllMenus();
|
|
512
|
+
updateField('customSourceOfFund', lettersOnly);
|
|
513
|
+
}, placeholder: employee_1.EMPLOYEE_STRINGS.CUSTOM_SOURCE_OF_FUND_PLACEHOLDER, placeholderColor: themeName === 'dark' ? colors.placeholderColor : 'rgba(0,0,0,0.2)', variant: "text" }),
|
|
514
|
+
renderFieldError('customSourceOfFund'))) : null;
|
|
515
|
+
})(),
|
|
516
|
+
renderDropdown(employee_1.EMPLOYEE_STRINGS.POLITICALLY_EXPOSED_PERSON_LABEL, form.politicallyExposedPerson, 'politicallyExposedPerson', pepOptions, 'pep'),
|
|
517
|
+
react_1.default.createElement(react_native_1.View, { style: { height: 120 } }))))),
|
|
518
|
+
react_1.default.createElement(react_native_1.View, { style: styles.footer },
|
|
519
|
+
react_1.default.createElement(ActionButton_1.default, { title: common_1.COMMON_STRINGS.CONTINUE, onPress: handleContinue, disabled: isLoadingCustomerOccupation || isSubmitting || !isFormValid, loading: isLoadingCustomerOccupation || isSubmitting })),
|
|
520
|
+
(isLoadingCustomerOccupation || isSubmitting) && (react_1.default.createElement(react_native_1.View, { style: styles.loadingOverlay, pointerEvents: "auto" })),
|
|
521
|
+
isGoingBack && (react_1.default.createElement(react_native_1.View, { style: styles.loadingOverlay, pointerEvents: "auto" },
|
|
522
|
+
react_1.default.createElement(react_native_1.ActivityIndicator, { size: "large", color: colors.primary })))));
|
|
523
|
+
};
|
|
524
|
+
const createStyles = (colors, typography, themeName) => react_native_1.StyleSheet.create({
|
|
525
|
+
keyboardAvoidingView: {
|
|
526
|
+
flex: 1,
|
|
527
|
+
},
|
|
528
|
+
container: {
|
|
529
|
+
flex: 1,
|
|
530
|
+
paddingHorizontal: 16,
|
|
531
|
+
paddingTop: 20,
|
|
532
|
+
},
|
|
533
|
+
scrollContent: {
|
|
534
|
+
flexGrow: 1,
|
|
535
|
+
},
|
|
536
|
+
footer: {
|
|
537
|
+
position: 'absolute',
|
|
538
|
+
left: 0,
|
|
539
|
+
right: 0,
|
|
540
|
+
bottom: 0,
|
|
541
|
+
backgroundColor: colors.background,
|
|
542
|
+
paddingTop: 8,
|
|
543
|
+
paddingBottom: 16,
|
|
544
|
+
},
|
|
545
|
+
inlineMenu: {
|
|
546
|
+
backgroundColor: themeName === 'dark' ? colors.inputBackground : colors.background,
|
|
547
|
+
borderWidth: themeName === 'dark' ? 1 : 0.5,
|
|
548
|
+
borderColor: themeName === 'dark' ? '#ffffff' : 'rgba(0,0,0,0.2)',
|
|
549
|
+
borderRadius: 8,
|
|
550
|
+
marginTop: -20,
|
|
551
|
+
marginBottom: 10,
|
|
552
|
+
paddingHorizontal: 12,
|
|
553
|
+
paddingVertical: 6,
|
|
554
|
+
},
|
|
555
|
+
modalOption: {
|
|
556
|
+
paddingVertical: 14,
|
|
557
|
+
},
|
|
558
|
+
modalOptionText: Object.assign(Object.assign({}, typography.styles.bodyLarge), { color: colors.text }),
|
|
559
|
+
debugButton: {
|
|
560
|
+
paddingHorizontal: 16,
|
|
561
|
+
paddingVertical: 12,
|
|
562
|
+
borderRadius: 8,
|
|
563
|
+
marginBottom: 16,
|
|
564
|
+
alignItems: 'center',
|
|
565
|
+
},
|
|
566
|
+
debugButtonText: Object.assign(Object.assign({}, typography.styles.bodyMedium), { fontWeight: '600' }),
|
|
567
|
+
errorContainer: {
|
|
568
|
+
flexDirection: 'row',
|
|
569
|
+
alignItems: 'center',
|
|
570
|
+
marginTop: -20,
|
|
571
|
+
marginBottom: 20,
|
|
572
|
+
},
|
|
573
|
+
errorIcon: {
|
|
574
|
+
marginRight: 6,
|
|
575
|
+
},
|
|
576
|
+
errorText: {
|
|
577
|
+
fontSize: 12,
|
|
578
|
+
color: colors.error || '#FF0000',
|
|
579
|
+
fontWeight: '500',
|
|
580
|
+
flex: 1,
|
|
581
|
+
},
|
|
582
|
+
loadingOverlay: {
|
|
583
|
+
position: 'absolute',
|
|
584
|
+
top: 0,
|
|
585
|
+
left: 0,
|
|
586
|
+
right: 0,
|
|
587
|
+
bottom: 0,
|
|
588
|
+
backgroundColor: 'rgba(0, 0, 0, 0.3)',
|
|
589
|
+
justifyContent: 'center',
|
|
590
|
+
alignItems: 'center',
|
|
591
|
+
zIndex: 1000,
|
|
592
|
+
},
|
|
593
|
+
});
|
|
594
|
+
exports.default = Employee;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
export interface FDCalculatorProps {
|
|
3
|
+
onGoBack?: () => void;
|
|
4
|
+
onNavigateToReviewKYC?: () => void;
|
|
5
|
+
fdData?: {
|
|
6
|
+
id: string;
|
|
7
|
+
name: string;
|
|
8
|
+
accountNumber: string;
|
|
9
|
+
roi: string;
|
|
10
|
+
tenure: string;
|
|
11
|
+
amount: number;
|
|
12
|
+
maturityDate: string;
|
|
13
|
+
status: 'active' | 'matured' | 'pending';
|
|
14
|
+
creditRating: string;
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
declare const FDCalculator: React.FC<FDCalculatorProps>;
|
|
18
|
+
export default FDCalculator;
|