@djb25/digit-ui-module-ekyc 1.0.25 → 1.0.26

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.
@@ -1,15 +1,8 @@
1
1
  import React, { useState, Fragment, useEffect } from "react";
2
2
  import { useLocation } from "react-router-dom";
3
- import {
4
- CardLabel,
5
- TextInput,
6
- Dropdown,
7
- UploadFile,
8
- Toast,
9
- FormStep,
10
- Loader
11
- } from "@djb25/digit-ui-react-components";
3
+ import { Toast, Loader, FormComposer } from "@djb25/digit-ui-react-components";
12
4
  import { useTranslation } from "react-i18next";
5
+ import PropertyInfoConfig from "../config/PropertyInfoConfig";
13
6
 
14
7
  const PropertyInfo = ({ config, onSelect, formData }) => {
15
8
  const { t } = useTranslation();
@@ -17,10 +10,18 @@ const PropertyInfo = ({ config, onSelect, formData }) => {
17
10
  const flowState = location.state || {};
18
11
  const tenantId = Digit.ULBService.getCurrentTenantId();
19
12
 
20
- const searchKno = flowState?.kNumber || flowState?.kno || formData?.kNumber || formData?.kno || sessionStorage.getItem("EKYC_K_NUMBER");
13
+ const queryParams = new URLSearchParams(location.search);
14
+ const urlKno = queryParams.get("kno");
15
+ const searchKno =
16
+ urlKno ||
17
+ flowState?.kNumber ||
18
+ flowState?.kno ||
19
+ formData?.kNumber ||
20
+ formData?.kno ||
21
+ sessionStorage.getItem("EKYC_K_NUMBER");
21
22
 
22
23
  const { isLoading, data: searchData } = Digit.Hooks.ekyc.useSearchConnection(
23
- { tenantId, details: { kno: searchKno } },
24
+ { tenantId, details: { kno: searchKno, fetchType: "PROPERTY" } },
24
25
  { enabled: !!searchKno, cacheTime: 0 }
25
26
  );
26
27
 
@@ -29,129 +30,179 @@ const PropertyInfo = ({ config, onSelect, formData }) => {
29
30
  const savedData = formData?.propertyDetails || {};
30
31
 
31
32
  // 🔹 STATES
32
- const [pidNumber, setPidNumber] = useState(savedData.pidNumber || "");
33
- const [propertyType, setPropertyType] = useState(savedData.propertyType ? { name: savedData.propertyType } : null);
34
- const [subPropertyCategory, setSubPropertyCategory] = useState(savedData.subPropertyCategory ? { name: savedData.subPropertyCategory } : null);
35
-
36
- const [noOfFloors, setNoOfFloors] = useState(savedData.noOfFloors || "");
37
- const [floorNo, setFloorNo] = useState(savedData.floorNo || "");
38
-
39
- const [noOfRooms, setNoOfRooms] = useState(savedData.noOfRooms || "");
40
- const [noOfBeds, setNoOfBeds] = useState(savedData.noOfBeds || "");
41
- const [dwellingUnits, setDwellingUnits] = useState(savedData.dwellingUnits || "");
42
-
43
33
  const [buildingImage, setBuildingImage] = useState(null);
44
34
  const [buildingImageId, setBuildingImageId] = useState(savedData.buildingImageId || null);
45
-
46
35
  const [toast, setToast] = useState(null);
47
-
48
- // 🔹 PROPERTY TYPE OPTIONS
49
- const propertyTypeOptions = [
50
- { name: "Residential" },
51
- { name: "Commercial" },
52
- { name: "Hotel" },
53
- { name: "Hospital" },
54
- { name: "Nursing Home" },
55
- ];
36
+ const [isDataLoaded, setIsDataLoaded] = useState(false);
37
+ const [canSubmit, setCanSubmit] = useState(false);
38
+
39
+ const [defaultValues, setDefaultValues] = useState(() => ({
40
+ pidNumber: savedData.pidNumber || "",
41
+ propertyType: savedData.propertyType ? { name: savedData.propertyType } : null,
42
+ subPropertyCategory: savedData.subPropertyCategory ? { name: savedData.subPropertyCategory } : null,
43
+ noOfFloors: savedData.noOfFloors || "",
44
+ floorNo: savedData.floorNo || "",
45
+ noOfRooms: savedData.noOfRooms || "",
46
+ noOfBeds: savedData.noOfBeds || "",
47
+ dwellingUnits: savedData.dwellingUnits || "",
48
+ buildingImage: savedData.buildingImageId ? "Uploaded" : null,
49
+ }));
50
+
51
+ const [localFormData, setLocalFormData] = useState(defaultValues);
52
+
53
+ const extractApplicationData = (searchData) => {
54
+ if (!searchData) return null;
55
+ const reviewWrapper =
56
+ searchData?.applicationReviewInfo || searchData?.applicationReview || searchData;
57
+ const applicationData = (Array.isArray(reviewWrapper) ? reviewWrapper[0] : reviewWrapper) || {};
58
+ return applicationData?.newData || applicationData;
59
+ };
56
60
 
57
61
  useEffect(() => {
58
- const rawData = searchData || formData?.connectionDetails;
59
- const propertyInfo = rawData?.propertyInfo || rawData?.propertyDetails || {};
62
+ const appData = extractApplicationData(searchData);
63
+ const rawData = appData || formData?.connectionDetails;
64
+ const propertyInfo = rawData?.propertyInfo || rawData?.propertyDetails || rawData || {};
60
65
 
61
- if (propertyInfo && Object.keys(propertyInfo).length > 0 && !savedData.pidNumber) {
62
- if (propertyInfo.pidNumber) setPidNumber(propertyInfo.pidNumber);
63
- if (propertyInfo.numberOfFloors || propertyInfo.noOfFloor) setNoOfFloors(String(propertyInfo.numberOfFloors || propertyInfo.noOfFloor));
64
- if (propertyInfo.buildingImageFileStoreId) setBuildingImageId(propertyInfo.buildingImageFileStoreId);
66
+ if (propertyInfo && Object.keys(propertyInfo).length > 0 && !isDataLoaded) {
67
+ let propType = null;
68
+ let subPropCat = null;
65
69
 
66
70
  if (propertyInfo.subPropertyCategory) {
67
- const matchingType = propertyTypeOptions.find(type => type.name.toLowerCase() === propertyInfo.subPropertyCategory.toLowerCase());
68
- if (matchingType) setPropertyType(matchingType);
69
- else setPropertyType({ name: propertyInfo.subPropertyCategory });
70
- setSubPropertyCategory({ name: propertyInfo.subPropertyCategory });
71
+ const matchingType = [
72
+ { name: "Residential" },
73
+ { name: "Commercial" },
74
+ { name: "Hotel" },
75
+ { name: "Hospital" },
76
+ { name: "Nursing Home" },
77
+ ].find((type) => type.name.toLowerCase() === propertyInfo.subPropertyCategory.toLowerCase());
78
+ if (matchingType) propType = matchingType;
79
+ else propType = { name: propertyInfo.subPropertyCategory };
80
+ subPropCat = { name: propertyInfo.subPropertyCategory };
71
81
  }
72
82
 
73
83
  if (propertyInfo.propertyType) {
74
- setSubPropertyCategory({ name: propertyInfo.propertyType }); // Just in case, depending on how UI renders it
75
- if (!propertyInfo.subPropertyCategory) setPropertyType({ name: propertyInfo.propertyType });
84
+ subPropCat = { name: propertyInfo.propertyType };
85
+ if (!propertyInfo.subPropertyCategory) propType = { name: propertyInfo.propertyType };
76
86
  }
77
87
 
78
- if (propertyInfo.floorNo) setFloorNo(propertyInfo.floorNo);
79
- if (propertyInfo.numberOfRooms !== null && propertyInfo.numberOfRooms !== undefined) setNoOfRooms(String(propertyInfo.numberOfRooms));
80
- if (propertyInfo.numberOfBeds !== null && propertyInfo.numberOfBeds !== undefined) setNoOfBeds(String(propertyInfo.numberOfBeds));
81
- if (propertyInfo.numberOfDwellingUnits !== null && propertyInfo.numberOfDwellingUnits !== undefined) setDwellingUnits(String(propertyInfo.numberOfDwellingUnits));
88
+ const updatedDefaults = {
89
+ pidNumber: savedData.pidNumber || propertyInfo.pidNumber || "",
90
+ propertyType: savedData.propertyType ? { name: savedData.propertyType } : propType,
91
+ subPropertyCategory: savedData.subPropertyCategory
92
+ ? { name: savedData.subPropertyCategory }
93
+ : subPropCat,
94
+ noOfFloors:
95
+ savedData.noOfFloors ||
96
+ (propertyInfo.numberOfFloors || propertyInfo.noOfFloor
97
+ ? String(propertyInfo.numberOfFloors || propertyInfo.noOfFloor)
98
+ : ""),
99
+ floorNo: savedData.floorNo || propertyInfo.floorNo || "",
100
+ noOfRooms:
101
+ savedData.noOfRooms ||
102
+ (propertyInfo.numberOfRooms !== null && propertyInfo.numberOfRooms !== undefined
103
+ ? String(propertyInfo.numberOfRooms)
104
+ : ""),
105
+ noOfBeds:
106
+ savedData.noOfBeds ||
107
+ (propertyInfo.numberOfBeds !== null && propertyInfo.numberOfBeds !== undefined
108
+ ? String(propertyInfo.numberOfBeds)
109
+ : ""),
110
+ dwellingUnits:
111
+ savedData.dwellingUnits ||
112
+ (propertyInfo.numberOfDwellingUnits !== null && propertyInfo.numberOfDwellingUnits !== undefined
113
+ ? String(propertyInfo.numberOfDwellingUnits)
114
+ : ""),
115
+ buildingImage: savedData.buildingImageId || propertyInfo.buildingImageFileStoreId || null,
116
+ };
117
+
118
+ setDefaultValues(updatedDefaults);
119
+ setLocalFormData(updatedDefaults);
120
+ if (updatedDefaults.buildingImage) {
121
+ setBuildingImageId(updatedDefaults.buildingImage);
122
+ }
123
+ setIsDataLoaded(true);
82
124
  }
83
- }, [searchData, formData?.connectionDetails]);
125
+ }, [searchData, formData?.connectionDetails, isDataLoaded]);
84
126
 
85
127
  // 🔹 FILE UPLOAD
86
- const handleUpload = async (e) => {
128
+ const handleUpload = async (e, onChange) => {
87
129
  const file = e.target.files[0];
88
130
  if (!file) return;
89
131
 
90
132
  if (file.size > 2000000) {
91
- setToast({ type: "error", message: "Max size 2MB exceeded" });
133
+ setToast({ type: "error", message: t("Max size 2MB exceeded") });
92
134
  return;
93
135
  }
94
136
 
95
137
  try {
96
- const res = await Digit.UploadServices.Filestorage(
97
- "EKYC",
98
- file,
99
- tenantId
100
- );
101
-
138
+ const res = await Digit.UploadServices.Filestorage("EKYC", file, tenantId);
102
139
  const fileStoreId = res?.data?.files?.[0]?.fileStoreId;
103
140
 
104
141
  if (fileStoreId) {
142
+ onChange(file.name);
105
143
  setBuildingImageId(fileStoreId);
106
144
 
107
145
  const reader = new FileReader();
108
146
  reader.onloadend = () => setBuildingImage(reader.result);
109
147
  reader.readAsDataURL(file);
110
148
 
111
- setToast({ type: "success", message: "Upload successful" });
149
+ setToast({ type: "success", message: t("Upload successful") });
112
150
  }
113
151
  } catch {
114
- setToast({ type: "error", message: "Upload failed" });
152
+ setToast({ type: "error", message: t("Upload failed") });
115
153
  }
116
154
  };
117
155
 
118
- // 🔹 VALIDATION
119
- const isValid = () => {
120
- if (!propertyType) return false;
121
- if (!subPropertyCategory) return false;
122
- if (!noOfFloors || Number(noOfFloors) < 1) return false;
123
- if (!buildingImageId) return false;
156
+ const onFormValueChange = (setValue, data) => {
157
+ // Check if propertyType changed to re-evaluate mandatory validation or conditional visibility
158
+ const propertyTypeChanged =
159
+ (data?.propertyType?.name || data?.propertyType) !==
160
+ (localFormData?.propertyType?.name || localFormData?.propertyType);
124
161
 
125
- if (propertyType?.name === "Hotel" && !noOfRooms) return false;
162
+ if (propertyTypeChanged) {
163
+ setLocalFormData((prev) => ({
164
+ ...prev,
165
+ ...data,
166
+ }));
167
+ }
168
+
169
+ // Determine validation
170
+ const propTypeVal = data?.propertyType;
171
+ const subPropCatVal = data?.subPropertyCategory;
172
+ const noOfFloorsVal = data?.noOfFloors;
173
+ const buildingImgId = buildingImageId || data?.buildingImage;
174
+ const noOfRoomsVal = data?.noOfRooms;
175
+ const noOfBedsVal = data?.noOfBeds;
176
+
177
+ let valid = true;
178
+ if (!propTypeVal) valid = false;
179
+ if (!subPropCatVal) valid = false;
180
+ if (!noOfFloorsVal || Number(noOfFloorsVal) < 1) valid = false;
181
+ if (!buildingImgId) valid = false;
182
+
183
+ if (propTypeVal?.name === "Hotel" && !noOfRoomsVal) valid = false;
126
184
  if (
127
- (propertyType?.name === "Hospital" ||
128
- propertyType?.name === "Nursing Home") &&
129
- !noOfBeds
185
+ (propTypeVal?.name === "Hospital" || propTypeVal?.name === "Nursing Home") &&
186
+ !noOfBedsVal
130
187
  )
131
- return false;
188
+ valid = false;
132
189
 
133
- return true;
190
+ if (valid !== canSubmit) {
191
+ setCanSubmit(valid);
192
+ }
134
193
  };
135
194
 
136
- // 🔹 SUBMIT
137
- const onStepSelect = async () => {
138
- /* Optional validation enforce
139
- if (!isValid()) {
140
- setToast({ type: "error", message: "Fill all required fields" });
141
- return;
142
- }
143
- */
144
-
145
- const data = {
146
- pidNumber,
147
- propertyType: propertyType?.name,
148
- subPropertyCategory: subPropertyCategory?.name,
149
- noOfFloors,
150
- floorNo,
151
- noOfRooms,
152
- noOfBeds,
153
- dwellingUnits,
154
- buildingImageId,
195
+ const onSubmit = async (data) => {
196
+ const submitData = {
197
+ pidNumber: data.pidNumber,
198
+ propertyType: data.propertyType?.name || data.propertyType,
199
+ subPropertyCategory: data.subPropertyCategory?.name || data.subPropertyCategory,
200
+ noOfFloors: data.noOfFloors,
201
+ floorNo: data.floorNo,
202
+ noOfRooms: data.noOfRooms,
203
+ noOfBeds: data.noOfBeds,
204
+ dwellingUnits: data.dwellingUnits,
205
+ buildingImageId: buildingImageId,
155
206
  };
156
207
 
157
208
  try {
@@ -159,12 +210,12 @@ const PropertyInfo = ({ config, onSelect, formData }) => {
159
210
  RequestInfo: {},
160
211
  updateType: "PROPERTY",
161
212
  kno: searchKno,
162
- ...data,
213
+ ...submitData,
163
214
  });
164
- setToast({ type: "success", message: "Property details updated successfully!" });
165
- onSelect(config.key, data);
215
+ setToast({ type: "success", message: t("Property details updated successfully!") });
216
+ onSelect(config.key, submitData);
166
217
  } catch (error) {
167
- setToast({ type: "error", message: "Failed to update property details" });
218
+ setToast({ type: "error", message: t("Failed to update property details") });
168
219
  }
169
220
  };
170
221
 
@@ -172,130 +223,40 @@ const PropertyInfo = ({ config, onSelect, formData }) => {
172
223
  return <Loader />;
173
224
  }
174
225
 
226
+ const Config = PropertyInfoConfig(
227
+ t,
228
+ localFormData,
229
+ handleUpload,
230
+ buildingImage,
231
+ buildingImageId,
232
+ setBuildingImage,
233
+ setBuildingImageId
234
+ );
235
+
175
236
  return (
176
237
  <Fragment>
177
- <FormStep
178
- t={t}
179
- onSelect={onStepSelect}
180
- config={config}
238
+ <FormComposer
239
+ key={isDataLoaded ? "loaded" : "loading"}
240
+ isDisabled={!canSubmit}
181
241
  label={t("ES_COMMON_CONTINUE")}
182
- isDisabled={!isValid()}
183
- >
184
- <div>
185
- <CardLabel>PID Number</CardLabel>
186
- <TextInput value={pidNumber} onChange={(e) => setPidNumber(e.target.value)} />
187
- </div>
188
-
189
- <div>
190
- <CardLabel>Property Type</CardLabel>
191
- <Dropdown
192
- option={propertyTypeOptions}
193
- selected={propertyType}
194
- select={setPropertyType}
195
- />
196
- </div>
197
-
198
- <div>
199
- <CardLabel>Sub Property Category</CardLabel>
200
- <Dropdown option={[]} selected={subPropertyCategory} select={setSubPropertyCategory} />
201
- </div>
202
-
203
- <div>
204
- <CardLabel>No. of Floors *</CardLabel>
205
- <TextInput
206
- type="number"
207
- value={noOfFloors}
208
- onChange={(e) => setNoOfFloors(e.target.value)}
209
- />
210
- </div>
211
-
212
- <div>
213
- <CardLabel>Floor No. of this KNO</CardLabel>
214
- <TextInput value={floorNo} onChange={(e) => setFloorNo(e.target.value)} />
215
- </div>
216
-
217
- <div>
218
- <CardLabel>No of Beds</CardLabel>
219
- <TextInput
220
- type="number"
221
- value={noOfBeds}
222
- onChange={(e) => setNoOfBeds(e.target.value)}
223
- />
224
- </div>
225
-
226
- <div>
227
- <CardLabel>No. of Rooms</CardLabel>
228
- <TextInput
229
- type="number"
230
- value={noOfRooms}
231
- onChange={(e) => setNoOfRooms(e.target.value)}
232
- />
233
- </div>
234
-
235
- {/* HOTEL CONDITION */}
236
- {propertyType?.name === "Hotel" && (
237
- <div>
238
- <CardLabel>No. of Rooms *</CardLabel>
239
- <TextInput
240
- type="number"
241
- value={noOfRooms}
242
- onChange={(e) => setNoOfRooms(e.target.value)}
243
- />
244
- </div>
245
- )}
246
-
247
- {/* HOSPITAL CONDITION */}
248
- {(propertyType?.name === "Hospital" ||
249
- propertyType?.name === "Nursing Home") && (
250
- <div>
251
- <CardLabel>No. of Beds *</CardLabel>
252
- <TextInput
253
- type="number"
254
- value={noOfBeds}
255
- onChange={(e) => setNoOfBeds(e.target.value)}
256
- />
257
- </div>
258
- )}
259
-
260
- <div>
261
- <CardLabel>Number of Dwelling Units</CardLabel>
262
- <TextInput
263
- type="number"
264
- value={dwellingUnits}
265
- onChange={(e) => setDwellingUnits(e.target.value)}
266
- />
267
- </div>
268
-
269
- <div>
270
- <CardLabel>Building Image *</CardLabel>
271
- <UploadFile
272
- onUpload={handleUpload}
273
- onDelete={() => {
274
- setBuildingImage(null);
275
- setBuildingImageId(null);
276
- }}
277
- message={buildingImageId ? "Uploaded" : "No file selected"}
278
- />
279
- </div>
280
-
281
- {buildingImage && (
282
- <div style={{ gridColumn: "span 2" }}>
283
- <img
284
- src={buildingImage}
285
- alt="preview"
286
- style={{ width: "100%", marginTop: "10px" }}
287
- />
288
- </div>
289
- )}
290
-
291
- {toast && (
292
- <Toast
293
- label={toast.message}
294
- error={toast.type === "error"}
295
- onClose={() => setToast(null)}
296
- />
297
- )}
298
- </FormStep>
242
+ config={Config.map((item) => ({
243
+ ...item,
244
+ isCollapsible: true,
245
+ isDefaultOpen: true,
246
+ }))}
247
+ onSubmit={onSubmit}
248
+ defaultValues={defaultValues}
249
+ onFormValueChange={onFormValueChange}
250
+ noCard={false}
251
+ submitInForm={true}
252
+ />
253
+ {toast && (
254
+ <Toast
255
+ error={toast.type === "error"}
256
+ label={toast.message}
257
+ onClose={() => setToast(null)}
258
+ />
259
+ )}
299
260
  </Fragment>
300
261
  );
301
262
  };
@@ -11,6 +11,8 @@ import {
11
11
  LinkButton,
12
12
  EditIcon,
13
13
  GenericFileIcon,
14
+ Menu,
15
+ Toast,
14
16
  } from "@djb25/digit-ui-react-components";
15
17
  import { useTranslation } from "react-i18next";
16
18
  import { useHistory, useLocation, useParams } from "react-router-dom";
@@ -34,9 +36,7 @@ const boolToYesNo = (value, t) => {
34
36
  if (value === false || value === "false" || String(value).toLowerCase() === "no") return t("CORE_COMMON_NO");
35
37
  if (value === "true") return t("CORE_COMMON_YES");
36
38
  if (value === "false") return t("CORE_COMMON_NO");
37
- return "N/A";
38
39
  };
39
-
40
40
  /**
41
41
  * Robust data extraction for comparison.
42
42
  * The API returns { applicationReviewInfo: { newData: { ... }, oldData: { ... } } }
@@ -172,6 +172,14 @@ const Review = () => {
172
172
  const [isSubmitting, setIsSubmitting] = useState(false);
173
173
  const [showPreview, setShowPreview] = useState(false);
174
174
  const [previewUrl, setPreviewUrl] = useState("");
175
+ const [showOptions, setShowOptions] = useState(false);
176
+ const [showToast, setShowToast] = useState(false);
177
+ const [toastData, setToastData] = useState({ error: false, label: "" });
178
+
179
+ const options = [
180
+ { action: t("Approve") },
181
+ { action: t("Reject") }
182
+ ];
175
183
 
176
184
  const flowState = location.state || {};
177
185
  const { edits = {} } = flowState;
@@ -373,6 +381,7 @@ const Review = () => {
373
381
  apiId: "Rainmaker",
374
382
  ver: "1.0",
375
383
  msgId: "message-id",
384
+ tenantId: tenantId,
376
385
  authToken: Digit.UserService.getUser()?.access_token,
377
386
  },
378
387
  kno: activeKno,
@@ -397,6 +406,7 @@ const Review = () => {
397
406
  apiId: "Rainmaker",
398
407
  ver: "1.0",
399
408
  msgId: "message-id",
409
+ tenantId: tenantId,
400
410
  authToken: Digit.UserService.getUser()?.access_token,
401
411
  },
402
412
  kno: activeKno,
@@ -408,10 +418,22 @@ const Review = () => {
408
418
  try {
409
419
  const result = await workflowMutation.mutateAsync(payload);
410
420
  if (result) {
411
- history.push("/digit-ui/employee/ekyc/response", { success: true, result });
421
+ setToastData({
422
+ error: false,
423
+ label: t("EKYC_APPLICATION_APPROVE_SUCCESSFUL") || "Application Approved Successfully",
424
+ });
425
+ setShowToast(true);
426
+ setTimeout(() => {
427
+ history.push("/digit-ui/employee/ekyc/inbox");
428
+ }, 2000);
412
429
  }
413
430
  } catch (err) {
414
431
  console.error("Approve Error:", err);
432
+ setToastData({
433
+ error: true,
434
+ label: err?.message || err?.response?.data?.message || "Approve Error",
435
+ });
436
+ setShowToast(true);
415
437
  }
416
438
  };
417
439
 
@@ -447,6 +469,15 @@ const Review = () => {
447
469
  setShowPreview(true);
448
470
  };
449
471
 
472
+ const handleMenuSelect = (option) => {
473
+ setShowOptions(false); // close menu
474
+ if (option.action === t("Approve")) {
475
+ handleApprove();
476
+ } else if (option.action === t("Reject")) {
477
+ handleReject();
478
+ }
479
+ };
480
+
450
481
  if (isSearchLoading || isSubmitting) return <Loader />;
451
482
 
452
483
  const baseUrl = "/digit-ui/employee/ekyc";
@@ -461,8 +492,8 @@ const Review = () => {
461
492
  newData={connectionData}
462
493
  oldData={oldDataRaw?.connection}
463
494
  t={t}
464
- jumpTo={`${baseUrl}/consumer-details`}
465
- state={{ ...flowState, reviewData: searchData, edits }}
495
+ jumpTo={`${baseUrl}/consumer-details?kno=${kno}`}
496
+ state={{ ...flowState, kNumber: kno, kno, reviewData: searchData, edits }}
466
497
  />
467
498
 
468
499
  {/* ── 2. Address Details ──────────────────────────────────────── */}
@@ -472,8 +503,8 @@ const Review = () => {
472
503
  newData={addressData}
473
504
  oldData={oldDataRaw?.address}
474
505
  t={t}
475
- jumpTo={`${baseUrl}/address-details`}
476
- state={{ ...flowState, reviewData: searchData, edits }}
506
+ jumpTo={`${baseUrl}/address-details?kno=${kno}`}
507
+ state={{ ...flowState, kNumber: kno, kno, reviewData: searchData, edits }}
477
508
  />
478
509
 
479
510
  {/* ── 3. Property Info ────────────────────────────────────────── */}
@@ -483,8 +514,8 @@ const Review = () => {
483
514
  newData={propertyData}
484
515
  oldData={oldDataRaw?.property}
485
516
  t={t}
486
- jumpTo={`${baseUrl}/property-info`}
487
- state={{ ...flowState, reviewData: searchData, edits }}
517
+ jumpTo={`${baseUrl}/property-info?kno=${kno}`}
518
+ state={{ ...flowState, kNumber: kno, kno, reviewData: searchData, edits }}
488
519
  />
489
520
 
490
521
  {/* ── 4. Meter Details ────────────────────────────────────────── */}
@@ -494,8 +525,8 @@ const Review = () => {
494
525
  newData={meterData}
495
526
  oldData={oldDataRaw?.meter}
496
527
  t={t}
497
- jumpTo={`${baseUrl}/meter-details`}
498
- state={{ ...flowState, reviewData: searchData, edits }}
528
+ jumpTo={`${baseUrl}/meter-details?kno=${kno}`}
529
+ state={{ ...flowState, kNumber: kno, kno, reviewData: searchData, edits }}
499
530
  />
500
531
 
501
532
  {/* ── 5. Documents ────────────────────────────────────────────── */}
@@ -559,10 +590,29 @@ const Review = () => {
559
590
  />
560
591
  </div>
561
592
 
562
- <ActionBar>
593
+ {/* <ActionBar>
563
594
  <SubmitBar label={t("EKYC_REJECT")} onSubmit={handleReject} disabled={!agree} />
564
595
  <SubmitBar label={t("EKYC_APPROVE")} onSubmit={handleApprove} disabled={!agree} />
565
- {/* <SubmitBar label={t("EKYC_SUBMIT_APPLICATION")} onSubmit={handleFinalSubmit} disabled={!agree} /> */}
596
+ <SubmitBar label={t("EKYC_SUBMIT_APPLICATION")} onSubmit={handleFinalSubmit} disabled={!agree} />
597
+ </ActionBar> */}
598
+ <ActionBar>
599
+ <SubmitBar
600
+ label={t("TAKE_ACTION_FOR_APPROVE_REJECT")}
601
+ onSubmit={() => setShowOptions((prev) => !prev)}
602
+ disabled={!agree}
603
+ />
604
+ {showOptions && (
605
+ <Menu
606
+ options={options}
607
+ optionKey={"action"}
608
+ t={t}
609
+ onSelect={handleMenuSelect}
610
+ style={{
611
+ color: "#FFFFFF",
612
+ fontSize: "18px",
613
+ }}
614
+ />
615
+ )}
566
616
  </ActionBar>
567
617
  </Card>
568
618
 
@@ -632,6 +682,13 @@ const Review = () => {
632
682
  </div>
633
683
  </div>
634
684
  )}
685
+ {showToast && (
686
+ <Toast
687
+ error={toastData.error}
688
+ label={toastData.label}
689
+ onClose={() => setShowToast(false)}
690
+ />
691
+ )}
635
692
  </Fragment>
636
693
  );
637
694
  };