@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,592 @@
|
|
|
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 datetimepicker_1 = __importDefault(require("@react-native-community/datetimepicker"));
|
|
43
|
+
// import DatePicker from 'react-native-date-picker'; // Commented out old date picker
|
|
44
|
+
const SafeAreaWrapper_1 = __importDefault(require("../components/SafeAreaWrapper"));
|
|
45
|
+
const components_1 = require("../components");
|
|
46
|
+
const ActionButton_1 = __importDefault(require("../components/ActionButton"));
|
|
47
|
+
const TextFieldWithLabel_1 = __importDefault(require("../components/TextFieldWithLabel"));
|
|
48
|
+
const ThemeContext_1 = require("../theme/ThemeContext");
|
|
49
|
+
const customerApi_1 = require("../api/customerApi");
|
|
50
|
+
const MasterDataProvider_1 = require("../providers/MasterDataProvider");
|
|
51
|
+
const store_1 = require("../store");
|
|
52
|
+
const appDataConfig_1 = require("../config/appDataConfig");
|
|
53
|
+
const workflowApi_1 = require("../api/workflowApi");
|
|
54
|
+
const native_1 = require("@react-navigation/native");
|
|
55
|
+
const helpers_1 = require("../navigation/helpers");
|
|
56
|
+
const base64Images_1 = require("../constants/strings/base64Images");
|
|
57
|
+
const nominee_1 = require("../constants/strings/nominee");
|
|
58
|
+
const common_1 = require("../constants/strings/common");
|
|
59
|
+
const makeNominationOptions = ['Yes', 'No'];
|
|
60
|
+
const NomineeDetail = ({ onGoBack, onSave, initialData }) => {
|
|
61
|
+
var _a;
|
|
62
|
+
const colors = (0, ThemeContext_1.useColors)();
|
|
63
|
+
const typography = (0, ThemeContext_1.useTypography)();
|
|
64
|
+
const { themeName } = (0, ThemeContext_1.useTheme)();
|
|
65
|
+
const styles = createStyles(colors, typography, themeName);
|
|
66
|
+
const { masterData, setMasterData } = (0, MasterDataProvider_1.useMasterData)();
|
|
67
|
+
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; });
|
|
68
|
+
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; });
|
|
69
|
+
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; });
|
|
70
|
+
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
|
|
71
|
+
const [customerNominee, { data: customerNomineeResponse, error: customerNomineeError, isLoading: isLoadingCustomerNominee, }] = (0, customerApi_1.useCustomerNomineeMutation)();
|
|
72
|
+
const [previousState] = (0, workflowApi_1.usePreviousStateMutation)();
|
|
73
|
+
const [getCustomerApplicationDetails] = (0, customerApi_1.useGetCustomerApplicationDetailsMutation)();
|
|
74
|
+
// Master data state
|
|
75
|
+
// const [masterData, setMasterData] = useState<{
|
|
76
|
+
// nomineePrefix: string[];
|
|
77
|
+
// nomineeRelation: string[];
|
|
78
|
+
// }>({
|
|
79
|
+
// nomineePrefix: [],
|
|
80
|
+
// nomineeRelation: [],
|
|
81
|
+
// });
|
|
82
|
+
// Loading state for back navigation
|
|
83
|
+
const [isGoingBack, setIsGoingBack] = (0, react_1.useState)(false);
|
|
84
|
+
// Form state
|
|
85
|
+
const [form, setForm] = (0, react_1.useState)({
|
|
86
|
+
makeNomination: (initialData === null || initialData === void 0 ? void 0 : initialData.makeNomination) || 'Yes',
|
|
87
|
+
nomineeTitle: '', // will be set after master data loads
|
|
88
|
+
nomineeName: (initialData === null || initialData === void 0 ? void 0 : initialData.nomineeName) || '',
|
|
89
|
+
relationship: '', // will be set after master data loads
|
|
90
|
+
customRelationship: (initialData === null || initialData === void 0 ? void 0 : initialData.customRelationship) || '',
|
|
91
|
+
dateOfBirth: (initialData === null || initialData === void 0 ? void 0 : initialData.dateOfBirth) || '',
|
|
92
|
+
printNameOnCertificate: (_a = initialData === null || initialData === void 0 ? void 0 : initialData.printNameOnCertificate) !== null && _a !== void 0 ? _a : false,
|
|
93
|
+
});
|
|
94
|
+
// Dropdown menu state
|
|
95
|
+
const [openMenus, setOpenMenus] = (0, react_1.useState)({
|
|
96
|
+
makeNomination: false,
|
|
97
|
+
title: false,
|
|
98
|
+
relationship: false,
|
|
99
|
+
});
|
|
100
|
+
// Error state for custom relationship
|
|
101
|
+
const [fieldErrors, setFieldErrors] = (0, react_1.useState)({});
|
|
102
|
+
// Date picker state
|
|
103
|
+
const [showDatePicker, setShowDatePicker] = (0, react_1.useState)(false);
|
|
104
|
+
const datePickerLockRef = (0, react_1.useRef)(false);
|
|
105
|
+
const [selectedDate, setSelectedDate] = (0, react_1.useState)(new Date());
|
|
106
|
+
// ScrollView ref for auto-scrolling
|
|
107
|
+
const scrollViewRef = (0, react_1.useRef)(null);
|
|
108
|
+
// Ref for nominee name text field
|
|
109
|
+
const nomineeNameRef = (0, react_1.useRef)(null);
|
|
110
|
+
// Derive nominee prefix and relationship options from master data
|
|
111
|
+
const normalizeOptions = (raw) => {
|
|
112
|
+
if (Array.isArray(raw))
|
|
113
|
+
return raw.map((v) => String(v)).filter(Boolean);
|
|
114
|
+
if (typeof raw === 'string' && raw.trim().length)
|
|
115
|
+
return raw.split(',').map((v) => v.trim()).filter(Boolean);
|
|
116
|
+
return [];
|
|
117
|
+
};
|
|
118
|
+
const mdRoot = (masterData === null || masterData === void 0 ? void 0 : masterData.data) || masterData || {};
|
|
119
|
+
const nomineePrefixOptions = react_1.default.useMemo(() => {
|
|
120
|
+
const raw = (mdRoot === null || mdRoot === void 0 ? void 0 : mdRoot.nomineePrefix) || (mdRoot === null || mdRoot === void 0 ? void 0 : mdRoot.titleOptions) || (mdRoot === null || mdRoot === void 0 ? void 0 : mdRoot.prefixOptions);
|
|
121
|
+
const opts = normalizeOptions(raw);
|
|
122
|
+
return opts.length ? opts : ['Mr', 'Ms', 'Mrsww'];
|
|
123
|
+
}, [mdRoot]);
|
|
124
|
+
const nomineeRelationOptions = react_1.default.useMemo(() => {
|
|
125
|
+
const raw = (mdRoot === null || mdRoot === void 0 ? void 0 : mdRoot.nomineeRelation) || (mdRoot === null || mdRoot === void 0 ? void 0 : mdRoot.relationshipOptions) || (mdRoot === null || mdRoot === void 0 ? void 0 : mdRoot.relations) || (mdRoot === null || mdRoot === void 0 ? void 0 : mdRoot.relationOptions);
|
|
126
|
+
const opts = normalizeOptions(raw);
|
|
127
|
+
return opts.length ? opts : ['Father', 'Mother', 'Spouse', 'Son', 'Daughter', 'Others'];
|
|
128
|
+
}, [mdRoot]);
|
|
129
|
+
// Do not auto-select defaults; placeholders should remain if API does not provide data
|
|
130
|
+
// Intentionally no-op here to avoid preselecting values
|
|
131
|
+
(0, react_1.useEffect)(() => {
|
|
132
|
+
// no-op to preserve empty state when no API data
|
|
133
|
+
}, [nomineePrefixOptions, nomineeRelationOptions]);
|
|
134
|
+
// Sync selectedDate with form.dateOfBirth when form data changes
|
|
135
|
+
(0, react_1.useEffect)(() => {
|
|
136
|
+
if (form.dateOfBirth && form.dateOfBirth.trim() !== '') {
|
|
137
|
+
const dateParts = form.dateOfBirth.split('/');
|
|
138
|
+
if (dateParts.length === 3) {
|
|
139
|
+
const day = parseInt(dateParts[0], 10);
|
|
140
|
+
const month = parseInt(dateParts[1], 10);
|
|
141
|
+
const year = parseInt(dateParts[2], 10);
|
|
142
|
+
if (day >= 1 && day <= 31 && month >= 1 && month <= 12 && year >= 1900 && year <= new Date().getFullYear()) {
|
|
143
|
+
const parsedDate = new Date(year, month - 1, day);
|
|
144
|
+
if (!isNaN(parsedDate.getTime()) && parsedDate.getDate() === day && parsedDate.getMonth() === month - 1 && parsedDate.getFullYear() === year) {
|
|
145
|
+
setSelectedDate(parsedDate);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
}, [form.dateOfBirth]);
|
|
151
|
+
// Fetch customer application details on focus and set form from nominee data
|
|
152
|
+
(0, native_1.useFocusEffect)(react_1.default.useCallback(() => {
|
|
153
|
+
let isActive = true;
|
|
154
|
+
(async () => {
|
|
155
|
+
var _a;
|
|
156
|
+
try {
|
|
157
|
+
const userInfo = (0, appDataConfig_1.getUserInfoForAPI)();
|
|
158
|
+
const req = {
|
|
159
|
+
providerId: defaultProviderId,
|
|
160
|
+
workflowInstanceId,
|
|
161
|
+
userreferenceid: userInfo.userReferenceId,
|
|
162
|
+
applicationid: applicationId,
|
|
163
|
+
entityid: '',
|
|
164
|
+
applicationId: applicationId,
|
|
165
|
+
customerId: customerId,
|
|
166
|
+
};
|
|
167
|
+
const res = await getCustomerApplicationDetails(req).unwrap();
|
|
168
|
+
if (!isActive)
|
|
169
|
+
return;
|
|
170
|
+
const nominee = (_a = res === null || res === void 0 ? void 0 : res.data) === null || _a === void 0 ? void 0 : _a.nominee;
|
|
171
|
+
if (nominee && Object.keys(nominee).length > 0) {
|
|
172
|
+
// ✅ Prefill only if nominee has valid data
|
|
173
|
+
const makeNomination = (nominee === null || nominee === void 0 ? void 0 : nominee.intend_to_nominate) ? 'Yes' : 'No';
|
|
174
|
+
const convertFromISO = (iso) => {
|
|
175
|
+
if (!iso)
|
|
176
|
+
return '';
|
|
177
|
+
const [y, m, d] = iso.split('-');
|
|
178
|
+
if (y && m && d)
|
|
179
|
+
return `${d.padStart(2, '0')}/${m.padStart(2, '0')}/${y}`;
|
|
180
|
+
return '';
|
|
181
|
+
};
|
|
182
|
+
setForm(prev => (Object.assign(Object.assign({}, prev), { makeNomination, nomineeTitle: (nominee === null || nominee === void 0 ? void 0 : nominee.prefix) || '', nomineeName: (nominee === null || nominee === void 0 ? void 0 : nominee.full_name) || '', relationship: (nominee === null || nominee === void 0 ? void 0 : nominee.relation) || '', dateOfBirth: convertFromISO((nominee === null || nominee === void 0 ? void 0 : nominee.dob) || ''), printNameOnCertificate: !!(nominee === null || nominee === void 0 ? void 0 : nominee.print_name_on_certificate) })));
|
|
183
|
+
}
|
|
184
|
+
else {
|
|
185
|
+
// 🧹 No nominee data — leave dropdowns empty
|
|
186
|
+
setForm({
|
|
187
|
+
makeNomination: '',
|
|
188
|
+
nomineeTitle: '',
|
|
189
|
+
nomineeName: '',
|
|
190
|
+
relationship: '',
|
|
191
|
+
dateOfBirth: '',
|
|
192
|
+
printNameOnCertificate: false,
|
|
193
|
+
});
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
catch (e) {
|
|
197
|
+
// On error, do not prefill anything
|
|
198
|
+
setForm({
|
|
199
|
+
makeNomination: '',
|
|
200
|
+
nomineeTitle: '', // Empty to show placeholder "No"
|
|
201
|
+
nomineeName: '',
|
|
202
|
+
relationship: '', // Empty to show placeholder "No"
|
|
203
|
+
dateOfBirth: '',
|
|
204
|
+
printNameOnCertificate: false,
|
|
205
|
+
});
|
|
206
|
+
}
|
|
207
|
+
})();
|
|
208
|
+
return () => { isActive = false; };
|
|
209
|
+
}, [defaultProviderId, workflowInstanceId, applicationId, customerId, getCustomerApplicationDetails]));
|
|
210
|
+
const closeAllMenus = () => {
|
|
211
|
+
setOpenMenus({ makeNomination: false, title: false, relationship: false });
|
|
212
|
+
};
|
|
213
|
+
const updateField = (field, value) => {
|
|
214
|
+
closeAllMenus();
|
|
215
|
+
setForm(prev => {
|
|
216
|
+
// Handle dependent clearing when user selects No for nomination
|
|
217
|
+
if (field === 'makeNomination') {
|
|
218
|
+
const isYes = String(value).toLowerCase() === 'yes';
|
|
219
|
+
if (!isYes) {
|
|
220
|
+
return Object.assign(Object.assign({}, prev), { makeNomination: String(value), nomineeTitle: '', nomineeName: '', relationship: '', customRelationship: '', dateOfBirth: '', printNameOnCertificate: false });
|
|
221
|
+
}
|
|
222
|
+
// If switching to Yes and fields are empty, prefill with first master data options
|
|
223
|
+
return Object.assign(Object.assign({}, prev), { makeNomination: String(value), nomineeTitle: prev.nomineeTitle || "", relationship: prev.relationship || "" });
|
|
224
|
+
}
|
|
225
|
+
const next = Object.assign(Object.assign({}, prev), { [field]: value });
|
|
226
|
+
if (field === 'relationship') {
|
|
227
|
+
const rel = String(value || '').trim().toLowerCase();
|
|
228
|
+
const isOther = rel === 'other' || rel === 'others';
|
|
229
|
+
if (!isOther) {
|
|
230
|
+
next.customRelationship = '';
|
|
231
|
+
setFieldErrors(prevErr => (Object.assign(Object.assign({}, prevErr), { customRelationship: '' })));
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
return next;
|
|
235
|
+
});
|
|
236
|
+
};
|
|
237
|
+
const toggleMenu = (key) => {
|
|
238
|
+
var _a;
|
|
239
|
+
// Remove focus from nominee name field when any dropdown is clicked
|
|
240
|
+
(_a = nomineeNameRef.current) === null || _a === void 0 ? void 0 : _a.blur();
|
|
241
|
+
setOpenMenus(prev => ({
|
|
242
|
+
makeNomination: key === 'makeNomination' ? !prev.makeNomination : false,
|
|
243
|
+
title: key === 'title' ? !prev.title : false,
|
|
244
|
+
relationship: key === 'relationship' ? !prev.relationship : false,
|
|
245
|
+
}));
|
|
246
|
+
};
|
|
247
|
+
// Date picker functions
|
|
248
|
+
const openDatePicker = () => {
|
|
249
|
+
var _a;
|
|
250
|
+
if (datePickerLockRef.current || showDatePicker)
|
|
251
|
+
return;
|
|
252
|
+
datePickerLockRef.current = true;
|
|
253
|
+
closeAllMenus();
|
|
254
|
+
// Remove focus from nominee name field when date picker is opened
|
|
255
|
+
(_a = nomineeNameRef.current) === null || _a === void 0 ? void 0 : _a.blur();
|
|
256
|
+
// Parse existing date from field
|
|
257
|
+
if (form.dateOfBirth && form.dateOfBirth.trim() !== '') {
|
|
258
|
+
const dateParts = form.dateOfBirth.split('/');
|
|
259
|
+
if (dateParts.length === 3) {
|
|
260
|
+
const day = parseInt(dateParts[0], 10);
|
|
261
|
+
const month = parseInt(dateParts[1], 10);
|
|
262
|
+
const year = parseInt(dateParts[2], 10);
|
|
263
|
+
// Validate the parsed values
|
|
264
|
+
if (day >= 1 && day <= 31 && month >= 1 && month <= 12 && year >= 1900 && year <= new Date().getFullYear()) {
|
|
265
|
+
const parsedDate = new Date(year, month - 1, day);
|
|
266
|
+
if (!isNaN(parsedDate.getTime()) && parsedDate.getDate() === day && parsedDate.getMonth() === month - 1 && parsedDate.getFullYear() === year) {
|
|
267
|
+
setSelectedDate(parsedDate);
|
|
268
|
+
}
|
|
269
|
+
else {
|
|
270
|
+
// If parsing fails, use current date
|
|
271
|
+
setSelectedDate(new Date());
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
else {
|
|
275
|
+
// If validation fails, use current date
|
|
276
|
+
setSelectedDate(new Date());
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
else {
|
|
280
|
+
// If format is invalid, use current date
|
|
281
|
+
setSelectedDate(new Date());
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
else {
|
|
285
|
+
// If no date in field, use current date
|
|
286
|
+
setSelectedDate(new Date());
|
|
287
|
+
}
|
|
288
|
+
setShowDatePicker(true);
|
|
289
|
+
};
|
|
290
|
+
const closeDatePicker = () => {
|
|
291
|
+
setShowDatePicker(false);
|
|
292
|
+
// Release the lock shortly after closing to avoid immediate re-open from the same tap
|
|
293
|
+
setTimeout(() => { datePickerLockRef.current = false; }, 500);
|
|
294
|
+
};
|
|
295
|
+
const onDateChange = (event, selectedDate) => {
|
|
296
|
+
closeDatePicker();
|
|
297
|
+
if (react_native_1.Platform.OS === 'android') {
|
|
298
|
+
// Android fires with types: 'set' and 'dismissed'
|
|
299
|
+
if ((event === null || event === void 0 ? void 0 : event.type) === 'set' && selectedDate) {
|
|
300
|
+
setSelectedDate(selectedDate);
|
|
301
|
+
const today = new Date();
|
|
302
|
+
let age = today.getFullYear() - selectedDate.getFullYear();
|
|
303
|
+
const m = today.getMonth() - selectedDate.getMonth();
|
|
304
|
+
if (m < 0 || (m === 0 && today.getDate() < selectedDate.getDate())) {
|
|
305
|
+
age--;
|
|
306
|
+
}
|
|
307
|
+
if (age < 18) {
|
|
308
|
+
updateField('dateOfBirth', '');
|
|
309
|
+
react_native_1.Alert.alert('Invalid Age', 'Nominee must be at least 18 years old.');
|
|
310
|
+
closeDatePicker();
|
|
311
|
+
return;
|
|
312
|
+
}
|
|
313
|
+
const day = selectedDate.getDate().toString().padStart(2, '0');
|
|
314
|
+
const month = (selectedDate.getMonth() + 1).toString().padStart(2, '0');
|
|
315
|
+
const year = selectedDate.getFullYear().toString();
|
|
316
|
+
const formattedDate = `${day}/${month}/${year}`;
|
|
317
|
+
updateField('dateOfBirth', formattedDate);
|
|
318
|
+
closeDatePicker();
|
|
319
|
+
return;
|
|
320
|
+
}
|
|
321
|
+
if ((event === null || event === void 0 ? void 0 : event.type) === 'dismissed') {
|
|
322
|
+
closeDatePicker();
|
|
323
|
+
return;
|
|
324
|
+
}
|
|
325
|
+
return;
|
|
326
|
+
}
|
|
327
|
+
// iOS inline/spinner handling
|
|
328
|
+
if (selectedDate) {
|
|
329
|
+
setSelectedDate(selectedDate);
|
|
330
|
+
const day = selectedDate.getDate().toString().padStart(2, '0');
|
|
331
|
+
const month = (selectedDate.getMonth() + 1).toString().padStart(2, '0');
|
|
332
|
+
const year = selectedDate.getFullYear().toString();
|
|
333
|
+
const formattedDate = `${day}/${month}/${year}`;
|
|
334
|
+
updateField('dateOfBirth', formattedDate);
|
|
335
|
+
}
|
|
336
|
+
};
|
|
337
|
+
const renderDropdown = (label, value, field, options, menuKey) => {
|
|
338
|
+
// Determine placeholder based on field
|
|
339
|
+
let placeholderText = nominee_1.NOMINEE_STRINGS.MAKE_NOMINATION_PLACEHOLDER;
|
|
340
|
+
if (field === 'relationship') {
|
|
341
|
+
placeholderText = nominee_1.NOMINEE_STRINGS.RELATIONSHIP_PLACEHOLDER;
|
|
342
|
+
}
|
|
343
|
+
else if (field === 'nomineeTitle') {
|
|
344
|
+
placeholderText = nominee_1.NOMINEE_STRINGS.NOMINEE_TITLE_PLACEHOLDER;
|
|
345
|
+
}
|
|
346
|
+
return (react_1.default.createElement(react_native_1.View, null,
|
|
347
|
+
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) => {
|
|
348
|
+
closeAllMenus();
|
|
349
|
+
updateField(field, option);
|
|
350
|
+
setOpenMenus(prev => (Object.assign(Object.assign({}, prev), { [menuKey]: false })));
|
|
351
|
+
}, placeholder: placeholderText, placeholderColor: themeName === 'dark' ? colors.placeholderColor : 'rgba(0,32,34,0.2)' }),
|
|
352
|
+
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: () => {
|
|
353
|
+
closeAllMenus();
|
|
354
|
+
updateField(field, option);
|
|
355
|
+
setOpenMenus(prev => (Object.assign(Object.assign({}, prev), { [menuKey]: false })));
|
|
356
|
+
} },
|
|
357
|
+
react_1.default.createElement(react_native_1.Text, { style: styles.modalOptionText }, option)))))),
|
|
358
|
+
field === 'relationship' && ((String(value || '').trim().toLowerCase() === 'other') || (String(value || '').trim().toLowerCase() === 'others')) && (react_1.default.createElement(react_native_1.View, null,
|
|
359
|
+
react_1.default.createElement(TextFieldWithLabel_1.default, { label: "", containerStyle: { marginTop: -40 }, value: form.customRelationship || '', onChangeText: (text) => {
|
|
360
|
+
const lettersOnly = text.replace(/[^A-Za-z ]/g, '');
|
|
361
|
+
// Validate on change
|
|
362
|
+
const rel = String(form.relationship || '').trim().toLowerCase();
|
|
363
|
+
const isOther = rel === 'other' || rel === 'others';
|
|
364
|
+
if (isOther) {
|
|
365
|
+
if (!lettersOnly || lettersOnly.trim().length === 0) {
|
|
366
|
+
setFieldErrors(prev => (Object.assign(Object.assign({}, prev), { customRelationship: 'Relationship is required' })));
|
|
367
|
+
}
|
|
368
|
+
else if (lettersOnly.trim().length < 2) {
|
|
369
|
+
setFieldErrors(prev => (Object.assign(Object.assign({}, prev), { customRelationship: 'Relationship must be at least 2 characters' })));
|
|
370
|
+
}
|
|
371
|
+
else {
|
|
372
|
+
setFieldErrors(prev => (Object.assign(Object.assign({}, prev), { customRelationship: '' })));
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
else {
|
|
376
|
+
setFieldErrors(prev => (Object.assign(Object.assign({}, prev), { customRelationship: '' })));
|
|
377
|
+
}
|
|
378
|
+
updateField('customRelationship', lettersOnly);
|
|
379
|
+
}, placeholder: 'Enter Custom Relationship', placeholderColor: themeName === 'dark' ? colors.placeholderColor : 'rgba(0,0,0,0.2)', variant: "text" }),
|
|
380
|
+
fieldErrors.customRelationship ? (react_1.default.createElement(react_native_1.View, { style: styles.errorContainer },
|
|
381
|
+
react_native_1.Platform.OS === 'android' && (react_1.default.createElement(Ionicons_1.default, { name: "warning", size: 16, color: colors.error || '#FF0000', style: styles.errorIcon })),
|
|
382
|
+
react_1.default.createElement(react_native_1.Text, { style: styles.errorText }, fieldErrors.customRelationship))) : null))));
|
|
383
|
+
};
|
|
384
|
+
const renderNomineeNameFields = () => (react_1.default.createElement(react_native_1.View, null,
|
|
385
|
+
react_1.default.createElement(react_native_1.Text, { style: styles.fieldLabel }, nominee_1.NOMINEE_STRINGS.NOMINEE_NAME_LABEL),
|
|
386
|
+
react_1.default.createElement(react_native_1.View, { style: styles.nameFieldsContainer },
|
|
387
|
+
react_1.default.createElement(react_native_1.View, { style: styles.titleField }, renderDropdown('', form.nomineeTitle, 'nomineeTitle', nomineePrefixOptions, 'title')),
|
|
388
|
+
react_1.default.createElement(react_native_1.View, { style: styles.nameField },
|
|
389
|
+
react_1.default.createElement(TextFieldWithLabel_1.default, { label: "", value: form.nomineeName, onChangeText: (text) => { closeAllMenus(); updateField('nomineeName', text); }, onFocus: () => { closeAllMenus(); }, textInputRef: nomineeNameRef, placeholder: nominee_1.NOMINEE_STRINGS.NOMINEE_NAME_PLACEHOLDER, placeholderColor: themeName === 'dark' ? colors.placeholderColor : 'rgba(0,0,0,0.2)', variant: "text" })))));
|
|
390
|
+
const renderDateField = (label, value, field) => (react_1.default.createElement(TextFieldWithLabel_1.default, { label: label, value: value, onChangeText: (text) => updateField(field, text), variant: "date", placeholder: "DD/MM/YYYY", placeholderColor: themeName === 'dark' ? colors.placeholderColor : 'rgba(0,0,0,0.2)', maxLength: 10, dateFormat: "DD/MM/YYYY", onDatePress: () => {
|
|
391
|
+
if (datePickerLockRef.current || showDatePicker)
|
|
392
|
+
return;
|
|
393
|
+
closeAllMenus();
|
|
394
|
+
openDatePicker();
|
|
395
|
+
}, editable: false, keepWhiteBackground: true, inputStyle: { color: 'white' } }));
|
|
396
|
+
// Validation function to check if all required fields are filled (pure function - no setState)
|
|
397
|
+
const validateForm = () => {
|
|
398
|
+
// If makeNomination is "No", no other fields are required
|
|
399
|
+
if (form.makeNomination.toLowerCase() === 'no') {
|
|
400
|
+
return true;
|
|
401
|
+
}
|
|
402
|
+
// If makeNomination is "Yes", all nominee fields are required
|
|
403
|
+
const requiredFields = [
|
|
404
|
+
form.nomineeTitle,
|
|
405
|
+
form.nomineeName,
|
|
406
|
+
form.relationship,
|
|
407
|
+
form.dateOfBirth,
|
|
408
|
+
];
|
|
409
|
+
const baseValid = requiredFields.every(field => field && field.trim().length > 0);
|
|
410
|
+
const rel = String(form.relationship || '').trim().toLowerCase();
|
|
411
|
+
const needsCustom = rel === 'other' || rel === 'others';
|
|
412
|
+
if (needsCustom) {
|
|
413
|
+
const customRel = String(form.customRelationship || '').trim();
|
|
414
|
+
if (!customRel || customRel.length < 2) {
|
|
415
|
+
return false;
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
return baseValid;
|
|
419
|
+
};
|
|
420
|
+
const handleSave = async () => {
|
|
421
|
+
try {
|
|
422
|
+
// Clear previous errors
|
|
423
|
+
setFieldErrors({});
|
|
424
|
+
// Validate all required fields
|
|
425
|
+
const rel = String(form.relationship || '').trim().toLowerCase();
|
|
426
|
+
const needsCustom = rel === 'other' || rel === 'others';
|
|
427
|
+
if (needsCustom) {
|
|
428
|
+
const customRel = String(form.customRelationship || '').trim();
|
|
429
|
+
if (!customRel) {
|
|
430
|
+
setFieldErrors(prev => (Object.assign(Object.assign({}, prev), { customRelationship: 'Relationship is required' })));
|
|
431
|
+
react_native_1.Alert.alert(common_1.COMMON_STRINGS.REQUIRED_FIELD, common_1.COMMON_STRINGS.FILL_REQUIRED_FIELDS);
|
|
432
|
+
return;
|
|
433
|
+
}
|
|
434
|
+
if (customRel.length < 2) {
|
|
435
|
+
setFieldErrors(prev => (Object.assign(Object.assign({}, prev), { customRelationship: 'Relationship must be at least 2 characters' })));
|
|
436
|
+
react_native_1.Alert.alert(common_1.COMMON_STRINGS.REQUIRED_FIELD, 'Relationship must be at least 2 characters');
|
|
437
|
+
return;
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
if (!validateForm()) {
|
|
441
|
+
react_native_1.Alert.alert(common_1.COMMON_STRINGS.REQUIRED_FIELD, common_1.COMMON_STRINGS.FILL_REQUIRED_FIELDS);
|
|
442
|
+
return;
|
|
443
|
+
}
|
|
444
|
+
// Get user info from app data
|
|
445
|
+
const userInfo = (0, appDataConfig_1.getUserInfoForAPI)();
|
|
446
|
+
// Convert date from DD/MM/YYYY to ISO 8601 format (YYYY-MM-DD)
|
|
447
|
+
const convertToISO8601 = (dateString) => {
|
|
448
|
+
if (!dateString)
|
|
449
|
+
return '';
|
|
450
|
+
const [day, month, year] = dateString.split('/');
|
|
451
|
+
if (day && month && year) {
|
|
452
|
+
const isoDate = `${year}-${month.padStart(2, '0')}-${day.padStart(2, '0')}`;
|
|
453
|
+
return isoDate;
|
|
454
|
+
}
|
|
455
|
+
return '';
|
|
456
|
+
};
|
|
457
|
+
const customerNomineeRequest = {
|
|
458
|
+
providerId: defaultProviderId,
|
|
459
|
+
workflowInstanceId, // from store
|
|
460
|
+
userreferenceid: userInfo.userReferenceId,
|
|
461
|
+
applicationid: applicationId,
|
|
462
|
+
// Only the specified parameters
|
|
463
|
+
customerId: customerId,
|
|
464
|
+
intentToNominate: form.makeNomination === 'Yes',
|
|
465
|
+
fullName: form.nomineeName,
|
|
466
|
+
nomineePrefix: form.nomineeTitle,
|
|
467
|
+
relation: form.relationship,
|
|
468
|
+
customRelation: form.customRelationship || '',
|
|
469
|
+
dob: convertToISO8601(form.dateOfBirth),
|
|
470
|
+
nomineeNameOnCertificate: form.printNameOnCertificate,
|
|
471
|
+
};
|
|
472
|
+
const response = await customerNominee(customerNomineeRequest).unwrap();
|
|
473
|
+
onSave === null || onSave === void 0 ? void 0 : onSave(form);
|
|
474
|
+
}
|
|
475
|
+
catch (error) {
|
|
476
|
+
// Show error message to user
|
|
477
|
+
react_native_1.Alert.alert(nominee_1.NOMINEE_STRINGS.NOMINEE_SAVED_FAILED, nominee_1.NOMINEE_STRINGS.NOMINEE_SAVE_ERROR, [{ text: common_1.COMMON_STRINGS.OK }]);
|
|
478
|
+
// Do not call onSave on failure - stay on current screen
|
|
479
|
+
// User can retry or correct their information
|
|
480
|
+
}
|
|
481
|
+
};
|
|
482
|
+
// Handler for back button (used by both header and hardware back button)
|
|
483
|
+
const handleBackPress = async () => {
|
|
484
|
+
setIsGoingBack(true);
|
|
485
|
+
try {
|
|
486
|
+
const userInfo = (0, appDataConfig_1.getUserInfoForAPI)();
|
|
487
|
+
await previousState({
|
|
488
|
+
providerId: defaultProviderId,
|
|
489
|
+
workflowInstanceId,
|
|
490
|
+
userreferenceid: userInfo.userReferenceId,
|
|
491
|
+
applicationid: applicationId,
|
|
492
|
+
entityid: '',
|
|
493
|
+
});
|
|
494
|
+
}
|
|
495
|
+
catch (e) {
|
|
496
|
+
// Handle error silently
|
|
497
|
+
}
|
|
498
|
+
finally {
|
|
499
|
+
setIsGoingBack(false);
|
|
500
|
+
(0, helpers_1.navigate)('Employee');
|
|
501
|
+
}
|
|
502
|
+
};
|
|
503
|
+
// Handle Android hardware back button
|
|
504
|
+
(0, react_1.useEffect)(() => {
|
|
505
|
+
if (react_native_1.Platform.OS !== 'android')
|
|
506
|
+
return;
|
|
507
|
+
const onHardwareBackPress = () => {
|
|
508
|
+
handleBackPress();
|
|
509
|
+
return true; // Prevent default behavior
|
|
510
|
+
};
|
|
511
|
+
const backHandler = react_native_1.BackHandler.addEventListener('hardwareBackPress', onHardwareBackPress);
|
|
512
|
+
return () => backHandler.remove();
|
|
513
|
+
}, [defaultProviderId, workflowInstanceId, applicationId]);
|
|
514
|
+
return (react_1.default.createElement(SafeAreaWrapper_1.default, { includeTop: false, bottomPadding: 25, statusBarColor: "#000000", statusBarStyle: "light-content" },
|
|
515
|
+
react_1.default.createElement(components_1.Header, { title: nominee_1.NOMINEE_STRINGS.NOMINEE_DETAILS_TITLE, onBackPress: handleBackPress, backgroundColor: colors.primary }),
|
|
516
|
+
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 },
|
|
517
|
+
react_1.default.createElement(react_native_1.ScrollView, { ref: scrollViewRef, style: styles.container, showsVerticalScrollIndicator: false, contentContainerStyle: styles.scrollContent, scrollEnabled: !isLoadingCustomerNominee, keyboardShouldPersistTaps: "handled" },
|
|
518
|
+
react_1.default.createElement(react_native_1.TouchableWithoutFeedback, { onPress: isLoadingCustomerNominee ? undefined : closeAllMenus },
|
|
519
|
+
react_1.default.createElement(react_native_1.View, null,
|
|
520
|
+
renderDropdown(nominee_1.NOMINEE_STRINGS.MAKE_NOMINATION_LABEL, form.makeNomination, 'makeNomination', makeNominationOptions, 'makeNomination'),
|
|
521
|
+
String(form.makeNomination).toLowerCase() === 'yes' && (react_1.default.createElement(react_1.default.Fragment, null,
|
|
522
|
+
renderNomineeNameFields(),
|
|
523
|
+
renderDropdown(nominee_1.NOMINEE_STRINGS.RELATIONSHIP_LABEL, form.relationship, 'relationship', nomineeRelationOptions, 'relationship'),
|
|
524
|
+
renderDateField(nominee_1.NOMINEE_STRINGS.DATE_OF_BIRTH_LABEL, form.dateOfBirth, 'dateOfBirth'),
|
|
525
|
+
showDatePicker && (react_1.default.createElement(react_native_1.View, { style: styles.datePickerContainer },
|
|
526
|
+
react_1.default.createElement(datetimepicker_1.default, { value: selectedDate, mode: "date", display: react_native_1.Platform.OS === 'ios' ? 'spinner' : 'default', onChange: onDateChange, maximumDate: new Date(new Date().getFullYear() - 18, new Date().getMonth(), new Date().getDate()), themeVariant: "light" }))),
|
|
527
|
+
react_1.default.createElement(react_native_1.View, { style: styles.checkboxContainer },
|
|
528
|
+
react_1.default.createElement(react_native_1.TouchableOpacity, { style: styles.checkbox, onPress: () => updateField('printNameOnCertificate', !form.printNameOnCertificate) },
|
|
529
|
+
react_1.default.createElement(react_native_1.View, { style: [styles.checkboxBox, form.printNameOnCertificate && styles.checkboxChecked] }, form.printNameOnCertificate ? (react_1.default.createElement(react_native_1.Image, { source: { uri: ((0, ThemeContext_1.useTheme)().themeName === 'dark') ? base64Images_1.base64Images.checkBoxDark : base64Images_1.base64Images.filledCheckBox }, style: { width: 22, height: 22 }, resizeMode: "contain" })) : (((0, ThemeContext_1.useTheme)().themeName === 'dark') ? (react_1.default.createElement(react_native_1.Image, { source: { uri: base64Images_1.base64Images.unCheckBoxDark }, style: { width: 22, height: 22 }, resizeMode: "contain" })) : null))),
|
|
530
|
+
react_1.default.createElement(react_native_1.Text, { style: styles.checkboxText }, nominee_1.NOMINEE_STRINGS.PRINT_NAME_INSTRUCTIONS)))))))),
|
|
531
|
+
react_1.default.createElement(react_native_1.View, { style: styles.footer },
|
|
532
|
+
react_1.default.createElement(ActionButton_1.default, { title: common_1.COMMON_STRINGS.SAVE, onPress: () => { closeAllMenus(); handleSave(); }, disabled: isLoadingCustomerNominee || !validateForm(), loading: isLoadingCustomerNominee })),
|
|
533
|
+
isLoadingCustomerNominee && (react_1.default.createElement(react_native_1.View, { style: styles.loadingOverlay, pointerEvents: "auto" })),
|
|
534
|
+
isGoingBack && (react_1.default.createElement(react_native_1.View, { style: styles.loadingOverlay, pointerEvents: "auto" },
|
|
535
|
+
react_1.default.createElement(react_native_1.ActivityIndicator, { size: "large", color: colors.primary })))));
|
|
536
|
+
};
|
|
537
|
+
const createStyles = (colors, typography, themeName) => react_native_1.StyleSheet.create({
|
|
538
|
+
keyboardAvoidingView: {
|
|
539
|
+
flex: 1,
|
|
540
|
+
},
|
|
541
|
+
container: { flex: 1, paddingHorizontal: 16, paddingTop: 20 },
|
|
542
|
+
scrollContent: {
|
|
543
|
+
flexGrow: 1,
|
|
544
|
+
paddingBottom: 120,
|
|
545
|
+
},
|
|
546
|
+
footer: {
|
|
547
|
+
position: 'absolute',
|
|
548
|
+
left: 0,
|
|
549
|
+
right: 0,
|
|
550
|
+
bottom: 0,
|
|
551
|
+
backgroundColor: colors.background,
|
|
552
|
+
paddingTop: 8,
|
|
553
|
+
paddingBottom: 16,
|
|
554
|
+
},
|
|
555
|
+
fieldLabel: Object.assign(Object.assign({}, typography.styles.bodySmall), { color: colors.textLight, marginBottom: -16 }),
|
|
556
|
+
nameFieldsContainer: { flexDirection: 'row', gap: 12, marginBottom: 0 },
|
|
557
|
+
titleField: { width: 80 },
|
|
558
|
+
nameField: { flex: 1 },
|
|
559
|
+
datePickerContainer: {
|
|
560
|
+
backgroundColor: '#FFFFFF',
|
|
561
|
+
borderRadius: 12,
|
|
562
|
+
padding: 16,
|
|
563
|
+
marginBottom: 20,
|
|
564
|
+
marginTop: 10,
|
|
565
|
+
},
|
|
566
|
+
checkboxContainer: { flexDirection: 'row', alignItems: 'flex-start', marginBottom: 40, paddingHorizontal: 4, marginTop: 16 },
|
|
567
|
+
checkbox: { marginRight: 12, marginTop: 2 },
|
|
568
|
+
checkboxBox: { width: 20, height: 20, borderWidth: 2, borderColor: themeName === 'dark' ? colors.tabSelected : colors.primary, borderRadius: 4, alignItems: 'center', justifyContent: 'center', backgroundColor: 'white' },
|
|
569
|
+
checkboxChecked: {
|
|
570
|
+
// backgroundColor: colors.primary
|
|
571
|
+
},
|
|
572
|
+
checkboxText: Object.assign(Object.assign({}, typography.styles.bodySmall), { color: colors.textLight, flex: 1, lineHeight: 18 }),
|
|
573
|
+
inlineMenu: { backgroundColor: themeName === 'dark' ? colors.inputBackground : colors.background, borderWidth: themeName === 'dark' ? 1 : 0.5, borderColor: themeName === 'dark' ? '#ffffff' : 'rgba(0,0,0,0.2)', borderRadius: 8, marginTop: -20, marginBottom: 10, paddingHorizontal: 12, paddingVertical: 6 },
|
|
574
|
+
modalOption: { paddingVertical: 14 },
|
|
575
|
+
modalOptionText: Object.assign(Object.assign({}, typography.styles.bodyLarge), { color: colors.text }),
|
|
576
|
+
// Added to fix TS error where these styles are referenced above
|
|
577
|
+
errorContainer: { flexDirection: 'row', alignItems: 'center', marginTop: -20, marginBottom: 20 },
|
|
578
|
+
errorIcon: { marginRight: 6 },
|
|
579
|
+
errorText: { fontSize: 12, color: colors.error || '#FF0000', fontWeight: '500', flex: 1 },
|
|
580
|
+
loadingOverlay: {
|
|
581
|
+
position: 'absolute',
|
|
582
|
+
top: 0,
|
|
583
|
+
left: 0,
|
|
584
|
+
right: 0,
|
|
585
|
+
bottom: 0,
|
|
586
|
+
backgroundColor: 'rgba(0, 0, 0, 0.3)',
|
|
587
|
+
justifyContent: 'center',
|
|
588
|
+
alignItems: 'center',
|
|
589
|
+
zIndex: 1000,
|
|
590
|
+
},
|
|
591
|
+
});
|
|
592
|
+
exports.default = NomineeDetail;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
export interface PayNowProps {
|
|
3
|
+
onGoBack?: () => void;
|
|
4
|
+
onConfirm?: () => void;
|
|
5
|
+
fdData?: {
|
|
6
|
+
companyName: string;
|
|
7
|
+
amount: number;
|
|
8
|
+
fdRate: string;
|
|
9
|
+
tenure: string;
|
|
10
|
+
interestPayout: string;
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
declare const PayNow: React.FC<PayNowProps>;
|
|
14
|
+
export default PayNow;
|