@djb25/digit-ui-module-ekyc 1.0.5 → 1.0.7
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/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/index.modern.js +1142 -497
- package/dist/index.modern.js.map +1 -1
- package/package.json +4 -2
- package/src/components/DesktopInbox.js +208 -60
- package/src/components/Filter.js +5 -4
- package/src/components/StatusCards.js +167 -16
- package/src/pages/employee/AadhaarVerification.js +341 -249
- package/src/pages/employee/AddressDetails.js +148 -124
- package/src/pages/employee/Create.js +31 -19
- package/src/pages/employee/Inbox.js +14 -8
- package/src/pages/employee/PropertyInfo.js +382 -302
- package/src/pages/employee/Review.js +365 -179
- package/src/utils/index.js +46 -0
|
@@ -1,13 +1,15 @@
|
|
|
1
|
-
import React, { Fragment } from "react";
|
|
1
|
+
import React, { Fragment, useState, useEffect } from "react";
|
|
2
2
|
import {
|
|
3
3
|
Card,
|
|
4
4
|
CardHeader,
|
|
5
5
|
SubmitBar,
|
|
6
6
|
HomeIcon,
|
|
7
7
|
ActionBar,
|
|
8
|
+
Toast,
|
|
8
9
|
} from "@djb25/digit-ui-react-components";
|
|
9
10
|
import { useTranslation } from "react-i18next";
|
|
10
11
|
import { useHistory, useLocation } from "react-router-dom";
|
|
12
|
+
import { getPayloadDiff, getSavedData } from "../../utils";
|
|
11
13
|
|
|
12
14
|
// ─── Icons ────────────────────────────────────────────────────────────────────
|
|
13
15
|
|
|
@@ -59,7 +61,7 @@ const SectionHead = ({ icon, label }) => (
|
|
|
59
61
|
|
|
60
62
|
// ─── Reusable: Review section card ───────────────────────────────────────────
|
|
61
63
|
|
|
62
|
-
const ReviewCard = ({ icon, title, onEdit, editLabel, rows }) => (
|
|
64
|
+
const ReviewCard = ({ icon, title, onEdit, editLabel, rows, t }) => (
|
|
63
65
|
<div style={{
|
|
64
66
|
border: "0.5px solid #EAECF0",
|
|
65
67
|
borderRadius: "10px",
|
|
@@ -109,8 +111,22 @@ const ReviewCard = ({ icon, title, onEdit, editLabel, rows }) => (
|
|
|
109
111
|
}}>
|
|
110
112
|
{row.label}
|
|
111
113
|
</div>
|
|
112
|
-
<div style={{ flex: 1, fontSize: "14px", color: "#101828", fontWeight: "500", wordBreak: "break-word" }}>
|
|
114
|
+
<div style={{ flex: 1, fontSize: "14px", color: "#101828", fontWeight: "500", wordBreak: "break-word", display: "flex", alignItems: "center", gap: "8px" }}>
|
|
113
115
|
{row.value}
|
|
116
|
+
{row.isModified && (
|
|
117
|
+
<span style={{
|
|
118
|
+
fontSize: "10px",
|
|
119
|
+
background: "#FFF4ED",
|
|
120
|
+
color: "#B45309",
|
|
121
|
+
border: "0.5px solid #FDE68A",
|
|
122
|
+
borderRadius: "4px",
|
|
123
|
+
padding: "2px 6px",
|
|
124
|
+
fontWeight: "600",
|
|
125
|
+
textTransform: "uppercase"
|
|
126
|
+
}}>
|
|
127
|
+
{t("EKYC_MODIFIED") || "Modified"}
|
|
128
|
+
</span>
|
|
129
|
+
)}
|
|
114
130
|
</div>
|
|
115
131
|
</div>
|
|
116
132
|
) : null
|
|
@@ -126,15 +142,163 @@ const Review = () => {
|
|
|
126
142
|
const history = useHistory();
|
|
127
143
|
const location = useLocation();
|
|
128
144
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
145
|
+
// ── Restore State Logic ──
|
|
146
|
+
const state = location.state || {};
|
|
147
|
+
const initialData = state.initialData || getSavedData("EKYC_INITIAL_DATA", {});
|
|
148
|
+
const kNumber = state.kNumber || sessionStorage.getItem("EKYC_K_NUMBER") || "EKYC-1234567890";
|
|
149
|
+
|
|
150
|
+
// Reconstruct nested objects if state is lost on refresh
|
|
151
|
+
const aadhaarDetails = state.aadhaarDetails || {
|
|
152
|
+
userName: sessionStorage.getItem("EKYC_USER_NAME"),
|
|
153
|
+
mobileNumber: sessionStorage.getItem("EKYC_MOBILE_NUMBER"),
|
|
154
|
+
whatsappNumber: sessionStorage.getItem("EKYC_WHATSAPP_NUMBER"),
|
|
155
|
+
email: sessionStorage.getItem("EKYC_EMAIL"),
|
|
156
|
+
noOfPersons: sessionStorage.getItem("EKYC_NO_OF_PERSONS"),
|
|
157
|
+
};
|
|
158
|
+
|
|
159
|
+
const addressDetails = state.addressDetails || {
|
|
160
|
+
fullAddress: sessionStorage.getItem("EKYC_FULL_ADDRESS"),
|
|
161
|
+
flatNo: sessionStorage.getItem("EKYC_FLAT_NO"),
|
|
162
|
+
building: sessionStorage.getItem("EKYC_BUILDING"),
|
|
163
|
+
landmark: sessionStorage.getItem("EKYC_LANDMARK"),
|
|
164
|
+
pincode: sessionStorage.getItem("EKYC_PINCODE"),
|
|
165
|
+
assembly: getSavedData("EKYC_ASSEMBLY_DATA")?.name,
|
|
166
|
+
ward: getSavedData("EKYC_WARD_DATA")?.name,
|
|
167
|
+
doorPhoto: sessionStorage.getItem("EKYC_DOOR_PHOTO"),
|
|
168
|
+
doorPhotoFileStoreId: sessionStorage.getItem("EKYC_DOOR_PHOTO_FILESTORE_ID"),
|
|
169
|
+
};
|
|
170
|
+
|
|
171
|
+
const propertyDetails = state.propertyDetails || {
|
|
172
|
+
ownerType: sessionStorage.getItem("EKYC_OWNER_TYPE"),
|
|
173
|
+
pidNumber: sessionStorage.getItem("EKYC_PID_NUMBER"),
|
|
174
|
+
connectionCategory: getSavedData("EKYC_TYPE_OF_CONNECTION_DATA"),
|
|
175
|
+
connectionType: getSavedData("EKYC_CONNECTION_CATEGORY_DATA"),
|
|
176
|
+
userType: getSavedData("EKYC_USER_TYPE_DATA"),
|
|
177
|
+
noOfFloors: getSavedData("EKYC_NO_OF_FLOORS_DATA"),
|
|
178
|
+
propertyDocument: sessionStorage.getItem("EKYC_PROPERTY_DOC"),
|
|
179
|
+
propertyDocumentFileStoreId: sessionStorage.getItem("EKYC_PROPERTY_DOC_FILESTORE_ID"),
|
|
180
|
+
buildingPhoto: sessionStorage.getItem("EKYC_BUILDING_PHOTO"),
|
|
181
|
+
buildingPhotoFileStoreId: sessionStorage.getItem("EKYC_BUILDING_PHOTO_FILESTORE_ID"),
|
|
182
|
+
};
|
|
183
|
+
|
|
184
|
+
useEffect(() => {
|
|
185
|
+
sessionStorage.setItem("EKYC_CURRENT_STEP", "REVIEW");
|
|
186
|
+
}, []);
|
|
187
|
+
|
|
188
|
+
// Helper to check if a field is modified
|
|
189
|
+
const isFieldModified = (key, currentVal) => {
|
|
190
|
+
const initialVal = initialData[key];
|
|
191
|
+
if (initialVal === undefined) return false;
|
|
192
|
+
return JSON.stringify(initialVal) !== JSON.stringify(currentVal);
|
|
193
|
+
};
|
|
194
|
+
|
|
195
|
+
const [toast, setToast] = useState(null);
|
|
196
|
+
const tenantId = Digit.ULBService.getCurrentTenantId() || "dl";
|
|
197
|
+
const { mutate, isLoading: isMutationLoading } = Digit.Hooks.ekyc.useEkycApplicationUpdate(tenantId);
|
|
198
|
+
const isSubmitting = isMutationLoading;
|
|
199
|
+
|
|
200
|
+
// ── Helper: upload a File object to Filestore ──────────────────────────────
|
|
201
|
+
const uploadFile = async (file, tenantId) => {
|
|
202
|
+
if (!file) return null;
|
|
203
|
+
const res = await Digit.UploadServices.Filestorage("EKYC", file, tenantId);
|
|
204
|
+
return res?.data?.files?.[0]?.fileStoreId || null;
|
|
205
|
+
};
|
|
206
|
+
|
|
207
|
+
// ── Helper: convert a data-URL (base64 string) to a File blob ─────────────
|
|
208
|
+
const dataUrlToFile = (dataUrl, filename) => {
|
|
209
|
+
const arr = dataUrl.split(",");
|
|
210
|
+
const mime = arr[0].match(/:(.*?);/)[1];
|
|
211
|
+
const bstr = atob(arr[1]);
|
|
212
|
+
let n = bstr.length;
|
|
213
|
+
const u8arr = new Uint8Array(n);
|
|
214
|
+
while (n--) u8arr[n] = bstr.charCodeAt(n);
|
|
215
|
+
return new File([u8arr], filename, { type: mime });
|
|
216
|
+
};
|
|
135
217
|
|
|
136
|
-
const handleSubmit = () => {
|
|
137
|
-
|
|
218
|
+
const handleSubmit = async () => {
|
|
219
|
+
setToast(null);
|
|
220
|
+
try {
|
|
221
|
+
const userInfo = Digit.UserService.getUser()?.info || {};
|
|
222
|
+
|
|
223
|
+
// ── 1. Upload property document ──────────────────────────────────────
|
|
224
|
+
let propertyDocFileStoreId = propertyDetails.propertyDocumentFileStoreId || null;
|
|
225
|
+
if (!propertyDocFileStoreId && propertyDetails.propertyDocument instanceof File) {
|
|
226
|
+
propertyDocFileStoreId = await uploadFile(propertyDetails.propertyDocument, tenantId);
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
// ── 2. Upload building photo ──────────────────────────────────────────
|
|
230
|
+
let buildingImageFileStoreId = propertyDetails.buildingPhotoFileStoreId || null;
|
|
231
|
+
if (!buildingImageFileStoreId && propertyDetails.buildingPhoto) {
|
|
232
|
+
// Fallback if we only have the dataURL
|
|
233
|
+
const photoFile = dataUrlToFile(propertyDetails.buildingPhoto, "building_photo.jpg");
|
|
234
|
+
buildingImageFileStoreId = await uploadFile(photoFile, tenantId);
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
// ── 3. Upload door photo ──────────────────────────────────────────────
|
|
238
|
+
let doorPhotoFileStoreId = addressDetails.doorPhotoFileStoreId || null;
|
|
239
|
+
if (!doorPhotoFileStoreId && addressDetails.doorPhoto) {
|
|
240
|
+
const doorFile = dataUrlToFile(addressDetails.doorPhoto, "door_photo.jpg");
|
|
241
|
+
doorPhotoFileStoreId = await uploadFile(doorFile, tenantId);
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
// ── 4. Build optimized request payload ────────────────────────────────
|
|
245
|
+
// Note: RequestInfo is added automatically by the Digit Request utility
|
|
246
|
+
const requestBody = {
|
|
247
|
+
updateType: "PROPERTY",
|
|
248
|
+
kno: kNumber,
|
|
249
|
+
pidNumber: propertyDetails.pidNumber || null,
|
|
250
|
+
propertyDocumentFileStoreId: propertyDocFileStoreId,
|
|
251
|
+
buildingImageFileStoreId: buildingImageFileStoreId,
|
|
252
|
+
userType: propertyDetails.userType?.value || null,
|
|
253
|
+
noOfFloor: propertyDetails.noOfFloors?.value ? parseInt(propertyDetails.noOfFloors.value, 10) : null,
|
|
254
|
+
typeOfConnection: propertyDetails.connectionCategory?.value || null,
|
|
255
|
+
connectionCategory: propertyDetails.connectionType?.value || null,
|
|
256
|
+
modifiedBy: userInfo.name || userInfo.userName || null,
|
|
257
|
+
mobileNumber: aadhaarDetails.mobileNumber || null,
|
|
258
|
+
email: aadhaarDetails.email || null,
|
|
259
|
+
userName: aadhaarDetails.userName || null,
|
|
260
|
+
noOfPersons: aadhaarDetails.noOfPersons || null,
|
|
261
|
+
doorPhotoFileStoreId: doorPhotoFileStoreId,
|
|
262
|
+
fullAddress: addressDetails.fullAddress || null,
|
|
263
|
+
flatNo: addressDetails.flatNo || null,
|
|
264
|
+
building: addressDetails.building || null,
|
|
265
|
+
landmark: addressDetails.landmark || null,
|
|
266
|
+
pincode: addressDetails.pincode || null,
|
|
267
|
+
assembly: addressDetails.assembly || null,
|
|
268
|
+
ward: addressDetails.ward || null,
|
|
269
|
+
};
|
|
270
|
+
|
|
271
|
+
// ── 4. Call the update API using the new Hook ──────────────────────────
|
|
272
|
+
mutate(requestBody, {
|
|
273
|
+
onSuccess: (res) => {
|
|
274
|
+
setToast({ type: "success", message: t("EKYC_SUBMIT_SUCCESS") || "Application submitted successfully!" });
|
|
275
|
+
|
|
276
|
+
// Cleanup sessionStorage on success
|
|
277
|
+
Object.keys(sessionStorage).forEach(key => {
|
|
278
|
+
if (key.startsWith("EKYC_")) sessionStorage.removeItem(key);
|
|
279
|
+
});
|
|
280
|
+
|
|
281
|
+
setTimeout(() => {
|
|
282
|
+
history.push("/digit-ui/employee/ekyc/dashboard");
|
|
283
|
+
}, 1800);
|
|
284
|
+
},
|
|
285
|
+
onError: (err) => {
|
|
286
|
+
console.error("eKYC Submit Error:", err);
|
|
287
|
+
setToast({
|
|
288
|
+
type: "error",
|
|
289
|
+
message: err?.response?.data?.Errors?.[0]?.message ||
|
|
290
|
+
t("EKYC_SUBMIT_ERROR") || "Submission failed. Please try again.",
|
|
291
|
+
});
|
|
292
|
+
}
|
|
293
|
+
});
|
|
294
|
+
|
|
295
|
+
} catch (err) {
|
|
296
|
+
console.error("eKYC Frontend Error:", err);
|
|
297
|
+
setToast({
|
|
298
|
+
type: "error",
|
|
299
|
+
message: t("EKYC_SUBMIT_ERROR") || "An error occurred during submission.",
|
|
300
|
+
});
|
|
301
|
+
}
|
|
138
302
|
};
|
|
139
303
|
|
|
140
304
|
const handleEditAadhaar = () => {
|
|
@@ -150,193 +314,215 @@ const Review = () => {
|
|
|
150
314
|
};
|
|
151
315
|
|
|
152
316
|
return (
|
|
153
|
-
<div className="
|
|
154
|
-
|
|
317
|
+
<div className="ground-container employee-app-container form-container">
|
|
318
|
+
|
|
319
|
+
<Fragment>
|
|
320
|
+
<div className="inbox-container">
|
|
321
|
+
<style>{`
|
|
155
322
|
@keyframes fadeSlideIn {
|
|
156
323
|
from { opacity: 0; transform: translateY(8px); }
|
|
157
324
|
to { opacity: 1; transform: translateY(0); }
|
|
158
325
|
}
|
|
159
326
|
`}</style>
|
|
160
327
|
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
328
|
+
{/* ── Sidebar ── */}
|
|
329
|
+
<div className="filters-container">
|
|
330
|
+
<Card style={{ display: "flex", alignItems: "center", padding: "12px 16px", marginBottom: "12px", borderRadius: "8px" }}>
|
|
331
|
+
<div style={{ color: "#185FA5", marginRight: "10px", display: "flex" }}>
|
|
332
|
+
<HomeIcon style={{ width: "20px", height: "20px" }} />
|
|
333
|
+
</div>
|
|
334
|
+
<div style={{ fontWeight: "600", fontSize: "15px", color: "#0B0C0C" }}>
|
|
335
|
+
{t("EKYC_PROCESS") || "eKYC Process"}
|
|
336
|
+
</div>
|
|
337
|
+
</Card>
|
|
338
|
+
|
|
339
|
+
<div style={{ background: "#fff", padding: "16px 14px", borderRadius: "8px", border: "1px solid #EAECF0" }}>
|
|
340
|
+
{[
|
|
341
|
+
{ label: t("EKYC_STEP_AADHAAR") || "Aadhaar", done: true, active: false },
|
|
342
|
+
{ label: t("EKYC_STEP_ADDRESS") || "Address", done: true, active: false },
|
|
343
|
+
{ label: t("EKYC_STEP_PROPERTY") || "Property", done: true, active: false },
|
|
344
|
+
{ label: t("EKYC_STEP_REVIEW") || "Review", done: false, active: true },
|
|
345
|
+
].map((step, i) => (
|
|
346
|
+
<div key={i} style={{
|
|
347
|
+
display: "flex", gap: "10px", alignItems: "flex-start",
|
|
348
|
+
position: "relative", paddingBottom: i < 3 ? "18px" : 0,
|
|
349
|
+
}}>
|
|
350
|
+
{i < 3 && (
|
|
351
|
+
<div style={{
|
|
352
|
+
position: "absolute", left: "10px", top: "22px",
|
|
353
|
+
width: "1px", height: "calc(100% - 10px)", background: "#EAECF0",
|
|
354
|
+
}} />
|
|
355
|
+
)}
|
|
356
|
+
<div style={{
|
|
357
|
+
width: "20px", height: "20px", borderRadius: "50%", flexShrink: 0, marginTop: "1px",
|
|
358
|
+
border: step.done ? "none" : step.active ? "1.5px solid #185FA5" : "1.5px solid #D0D5DD",
|
|
359
|
+
background: step.done ? "#0F6E56" : step.active ? "#E6F1FB" : "#fff",
|
|
360
|
+
display: "flex", alignItems: "center", justifyContent: "center",
|
|
361
|
+
fontSize: "10px", fontWeight: "500",
|
|
362
|
+
color: step.done ? "#fff" : step.active ? "#185FA5" : "#98A2B3",
|
|
363
|
+
}}>
|
|
364
|
+
{step.done ? <CheckIcon size={11} color="#fff" /> : i + 1}
|
|
365
|
+
</div>
|
|
366
|
+
<div style={{
|
|
367
|
+
fontSize: "12px", paddingTop: "2px",
|
|
368
|
+
color: step.done ? "#0F6E56" : step.active ? "#0B0C0C" : "#667085",
|
|
369
|
+
fontWeight: step.done || step.active ? "600" : "400",
|
|
370
|
+
}}>
|
|
371
|
+
{step.label}
|
|
372
|
+
</div>
|
|
373
|
+
</div>
|
|
374
|
+
))}
|
|
375
|
+
</div>
|
|
169
376
|
</div>
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
display: "flex", gap: "10px", alignItems: "flex-start",
|
|
181
|
-
position: "relative", paddingBottom: i < 3 ? "18px" : 0,
|
|
182
|
-
}}>
|
|
183
|
-
{i < 3 && (
|
|
377
|
+
|
|
378
|
+
{/* ── Main Content ── */}
|
|
379
|
+
<div style={{ flex: 1, marginLeft: "16px" }}>
|
|
380
|
+
<Card>
|
|
381
|
+
|
|
382
|
+
{/* Page header */}
|
|
383
|
+
<div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", marginBottom: "20px" }}>
|
|
384
|
+
<CardHeader style={{ margin: 0, fontSize: "18px" }}>
|
|
385
|
+
{t("EKYC_REVIEW_DETAILS") || "Review Details"}
|
|
386
|
+
</CardHeader>
|
|
184
387
|
<div style={{
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
background: step.done ? "#0F6E56" : step.active ? "#E6F1FB" : "#fff",
|
|
193
|
-
display: "flex", alignItems: "center", justifyContent: "center",
|
|
194
|
-
fontSize: "10px", fontWeight: "500",
|
|
195
|
-
color: step.done ? "#fff" : step.active ? "#185FA5" : "#98A2B3",
|
|
196
|
-
}}>
|
|
197
|
-
{step.done ? <CheckIcon size={11} color="#fff" /> : i + 1}
|
|
388
|
+
background: "#F9FAFB", border: "0.5px solid #EAECF0",
|
|
389
|
+
borderRadius: "20px", padding: "4px 14px",
|
|
390
|
+
fontSize: "12px", color: "#667085",
|
|
391
|
+
}}>
|
|
392
|
+
{t("EKYC_K_NUMBER") || "K Number"}:{" "}
|
|
393
|
+
<span style={{ color: "#0B0C0C", fontWeight: "600" }}>{kNumber}</span>
|
|
394
|
+
</div>
|
|
198
395
|
</div>
|
|
396
|
+
|
|
397
|
+
{/* Confirmation banner */}
|
|
199
398
|
<div style={{
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
399
|
+
backgroundColor: "#E1F5EE", border: "0.5px solid #5DCAA5",
|
|
400
|
+
borderRadius: "8px", padding: "12px 16px",
|
|
401
|
+
display: "flex", alignItems: "center", gap: "10px",
|
|
402
|
+
marginBottom: "24px",
|
|
203
403
|
}}>
|
|
204
|
-
{
|
|
404
|
+
<div style={{ backgroundColor: "#9FE1CB", padding: "5px", borderRadius: "6px", display: "flex", flexShrink: 0 }}>
|
|
405
|
+
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="#085041" strokeWidth="3" strokeLinecap="round">
|
|
406
|
+
<polyline points="20 6 9 17 4 12" />
|
|
407
|
+
</svg>
|
|
408
|
+
</div>
|
|
409
|
+
<div style={{ fontSize: "13px", color: "#04342C", fontWeight: "500" }}>
|
|
410
|
+
{t("EKYC_REVIEW_NOTICE") || "Please review all details carefully before submitting. You can edit any section by clicking Edit."}
|
|
411
|
+
</div>
|
|
205
412
|
</div>
|
|
206
|
-
</div>
|
|
207
|
-
))}
|
|
208
|
-
</div>
|
|
209
|
-
</div>
|
|
210
|
-
|
|
211
|
-
{/* ── Main Content ── */}
|
|
212
|
-
<div style={{ flex: 1, marginLeft: "16px" }}>
|
|
213
|
-
<Card>
|
|
214
413
|
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
414
|
+
<div style={{ animation: "fadeSlideIn 0.3s ease" }}>
|
|
415
|
+
|
|
416
|
+
{/* ── Aadhaar section head ── */}
|
|
417
|
+
<SectionHead
|
|
418
|
+
icon={<PersonIcon size={16} />}
|
|
419
|
+
label={t("EKYC_AADHAAR_VERIFICATION_HEADER") || "Aadhaar details"}
|
|
420
|
+
/>
|
|
421
|
+
|
|
422
|
+
<ReviewCard
|
|
423
|
+
icon={<PersonIcon size={16} />}
|
|
424
|
+
title={t("EKYC_AADHAAR_VERIFICATION_HEADER") || "Aadhaar details"}
|
|
425
|
+
onEdit={handleEditAadhaar}
|
|
426
|
+
editLabel={t("CS_COMMON_EDIT") || "Edit"}
|
|
427
|
+
t={t}
|
|
428
|
+
rows={[
|
|
429
|
+
{ label: t("EKYC_NAME") || "Name", value: aadhaarDetails.userName || "Rajesh Kumar Singh", isModified: isFieldModified("userName", aadhaarDetails.userName) },
|
|
430
|
+
{ label: t("EKYC_AADHAAR") || "Aadhaar no.", value: aadhaarDetails.aadhaarLastFour ? `${aadhaarDetails.aadhaarLastFour}` : "XXXX XXXX 1234" },
|
|
431
|
+
{ label: t("EKYC_MOBILE_NO") || "Mobile no.", value: aadhaarDetails.mobileNumber || "XXXXXXXXXX", isModified: isFieldModified("mobileNumber", aadhaarDetails.mobileNumber) },
|
|
432
|
+
{ label: t("EKYC_EMAIL_ADDRESS") || "Email", value: aadhaarDetails.email || null, isModified: isFieldModified("email", aadhaarDetails.email) },
|
|
433
|
+
]}
|
|
434
|
+
/>
|
|
435
|
+
|
|
436
|
+
<hr style={{ margin: "20px 0", border: 0, borderTop: "1px solid #EAECF0" }} />
|
|
437
|
+
|
|
438
|
+
{/* ── Address section head ── */}
|
|
439
|
+
<SectionHead
|
|
440
|
+
icon={<LocationIcon2 size={16} />}
|
|
441
|
+
label={t("EKYC_ADDRESS_DETAILS_HEADER") || "Address details"}
|
|
442
|
+
/>
|
|
443
|
+
|
|
444
|
+
<ReviewCard
|
|
445
|
+
icon={<LocationIcon2 size={16} />}
|
|
446
|
+
title={t("EKYC_ADDRESS_DETAILS_HEADER") || "Address details"}
|
|
447
|
+
onEdit={handleEditAddress}
|
|
448
|
+
editLabel={t("CS_COMMON_EDIT") || "Edit"}
|
|
449
|
+
t={t}
|
|
450
|
+
rows={[
|
|
451
|
+
{ label: t("EKYC_FULL_ADDRESS") || "Full address", value: addressDetails.fullAddress || "H.No. 123, Sector 15, Rohini, Delhi – 110085", isModified: isFieldModified("fullAddress", addressDetails.fullAddress) },
|
|
452
|
+
{ label: t("EKYC_FLAT_HOUSE_NUMBER") || "Flat / House no.", value: addressDetails.flatNo || null, isModified: isFieldModified("flatNo", addressDetails.flatNo) },
|
|
453
|
+
{ label: t("EKYC_BUILDING_TOWER") || "Building", value: addressDetails.building || null, isModified: isFieldModified("building", addressDetails.building) },
|
|
454
|
+
{ label: t("EKYC_LANDMARK") || "Landmark", value: addressDetails.landmark || null, isModified: isFieldModified("landmark", addressDetails.landmark) },
|
|
455
|
+
{ label: t("EKYC_PINCODE") || "Pincode", value: addressDetails.pincode || "110085", isModified: isFieldModified("pincode", addressDetails.pincode) },
|
|
456
|
+
{ label: t("EKYC_ASSEMBLY") || "Assembly", value: addressDetails.assembly || "AC-12 Chandni Chowk", isModified: isFieldModified("assembly", addressDetails.assembly) },
|
|
457
|
+
{ label: t("EKYC_WARD") || "Ward", value: addressDetails.ward || "WARD-45 Civil Lines", isModified: isFieldModified("ward", addressDetails.ward) },
|
|
458
|
+
]}
|
|
459
|
+
/>
|
|
460
|
+
|
|
461
|
+
<hr style={{ margin: "20px 0", border: 0, borderTop: "1px solid #EAECF0" }} />
|
|
462
|
+
|
|
463
|
+
{/* ── Property section head ── */}
|
|
464
|
+
<SectionHead
|
|
465
|
+
icon={<BuildingIcon size={16} />}
|
|
466
|
+
label={t("EKYC_PROPERTY_INFO") || "Property details"}
|
|
467
|
+
/>
|
|
468
|
+
|
|
469
|
+
<ReviewCard
|
|
470
|
+
icon={<BuildingIcon size={16} />}
|
|
471
|
+
title={t("EKYC_PROPERTY_INFO") || "Property details"}
|
|
472
|
+
onEdit={handleEditProperty}
|
|
473
|
+
editLabel={t("CS_COMMON_EDIT") || "Edit"}
|
|
474
|
+
t={t}
|
|
475
|
+
rows={[
|
|
476
|
+
{ label: t("EKYC_PROPERTY_OWNER") || "Property owner", value: propertyDetails.ownerType || "Owner" },
|
|
477
|
+
{ label: t("EKYC_PID_NUMBER") || "PID number", value: propertyDetails.pidNumber || null, isModified: isFieldModified("pidNumber", propertyDetails.pidNumber) },
|
|
478
|
+
{ label: t("EKYC_TYPE_OF_CONNECTION") || "Type of connection", value: propertyDetails.connectionCategory?.label || null, isModified: isFieldModified("typeOfConnection", propertyDetails.connectionCategory?.value) },
|
|
479
|
+
{ label: t("EKYC_CONNECTION_CATEGORY") || "Connection category", value: propertyDetails.connectionType?.label || null, isModified: isFieldModified("connectionCategory", propertyDetails.connectionType?.value) },
|
|
480
|
+
{ label: t("EKYC_USER_TYPE") || "User type", value: propertyDetails.userType?.label || null, isModified: isFieldModified("userType", propertyDetails.userType?.value) },
|
|
481
|
+
{ label: t("EKYC_NO_OF_FLOORS") || "No. of floors", value: propertyDetails.noOfFloors?.label || null, isModified: isFieldModified("noOfFloor", propertyDetails.noOfFloors?.value) },
|
|
482
|
+
]}
|
|
483
|
+
/>
|
|
246
484
|
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
{/* ── Aadhaar section head ── */}
|
|
250
|
-
<SectionHead
|
|
251
|
-
icon={<PersonIcon size={16} />}
|
|
252
|
-
label={t("EKYC_AADHAAR_VERIFICATION_HEADER") || "Aadhaar details"}
|
|
253
|
-
/>
|
|
254
|
-
|
|
255
|
-
<ReviewCard
|
|
256
|
-
icon={<PersonIcon size={16} />}
|
|
257
|
-
title={t("EKYC_AADHAAR_VERIFICATION_HEADER") || "Aadhaar details"}
|
|
258
|
-
onEdit={handleEditAadhaar}
|
|
259
|
-
editLabel={t("CS_COMMON_EDIT") || "Edit"}
|
|
260
|
-
rows={[
|
|
261
|
-
{ label: t("EKYC_NAME") || "Name", value: aadhaarDetails.userName || "Rajesh Kumar Singh" },
|
|
262
|
-
{ label: t("EKYC_AADHAAR") || "Aadhaar no.", value: aadhaarDetails.aadhaarLastFour ? `XXXX XXXX ${aadhaarDetails.aadhaarLastFour}` : "XXXX XXXX 1234" },
|
|
263
|
-
{ label: t("EKYC_MOBILE_NO") || "Mobile no.", value: aadhaarDetails.mobileNumber || "XXXXXXXXXX" },
|
|
264
|
-
{ label: t("EKYC_EMAIL_ADDRESS") || "Email", value: aadhaarDetails.email || null },
|
|
265
|
-
]}
|
|
266
|
-
/>
|
|
267
|
-
|
|
268
|
-
<hr style={{ margin: "20px 0", border: 0, borderTop: "1px solid #EAECF0" }} />
|
|
269
|
-
|
|
270
|
-
{/* ── Address section head ── */}
|
|
271
|
-
<SectionHead
|
|
272
|
-
icon={<LocationIcon2 size={16} />}
|
|
273
|
-
label={t("EKYC_ADDRESS_DETAILS_HEADER") || "Address details"}
|
|
274
|
-
/>
|
|
275
|
-
|
|
276
|
-
<ReviewCard
|
|
277
|
-
icon={<LocationIcon2 size={16} />}
|
|
278
|
-
title={t("EKYC_ADDRESS_DETAILS_HEADER") || "Address details"}
|
|
279
|
-
onEdit={handleEditAddress}
|
|
280
|
-
editLabel={t("CS_COMMON_EDIT") || "Edit"}
|
|
281
|
-
rows={[
|
|
282
|
-
{ label: t("EKYC_FULL_ADDRESS") || "Full address", value: addressDetails.fullAddress || "H.No. 123, Sector 15, Rohini, Delhi – 110085" },
|
|
283
|
-
{ label: t("EKYC_FLAT_HOUSE_NUMBER") || "Flat / House no.", value: addressDetails.flatNo || null },
|
|
284
|
-
{ label: t("EKYC_BUILDING_TOWER") || "Building", value: addressDetails.building || null },
|
|
285
|
-
{ label: t("EKYC_LANDMARK") || "Landmark", value: addressDetails.landmark || null },
|
|
286
|
-
{ label: t("EKYC_PINCODE") || "Pincode", value: addressDetails.pincode || "110085" },
|
|
287
|
-
{ label: t("EKYC_ASSEMBLY") || "Assembly", value: addressDetails.assembly || "AC-12 Chandni Chowk" },
|
|
288
|
-
{ label: t("EKYC_WARD") || "Ward", value: addressDetails.ward || "WARD-45 Civil Lines" },
|
|
289
|
-
]}
|
|
290
|
-
/>
|
|
291
|
-
|
|
292
|
-
<hr style={{ margin: "20px 0", border: 0, borderTop: "1px solid #EAECF0" }} />
|
|
293
|
-
|
|
294
|
-
{/* ── Property section head ── */}
|
|
295
|
-
<SectionHead
|
|
296
|
-
icon={<BuildingIcon size={16} />}
|
|
297
|
-
label={t("EKYC_PROPERTY_INFO") || "Property details"}
|
|
298
|
-
/>
|
|
299
|
-
|
|
300
|
-
<ReviewCard
|
|
301
|
-
icon={<BuildingIcon size={16} />}
|
|
302
|
-
title={t("EKYC_PROPERTY_INFO") || "Property details"}
|
|
303
|
-
onEdit={handleEditProperty}
|
|
304
|
-
editLabel={t("CS_COMMON_EDIT") || "Edit"}
|
|
305
|
-
rows={[
|
|
306
|
-
{ label: t("EKYC_PROPERTY_OWNER") || "Property owner", value: propertyDetails.ownerType || "Owner" },
|
|
307
|
-
{ label: t("EKYC_PID_NUMBER") || "PID number", value: propertyDetails.pidNumber || null },
|
|
308
|
-
{ label: t("EKYC_TYPE_OF_CONNECTION") || "Type of connection", value: propertyDetails.connectionCategory?.label || null },
|
|
309
|
-
{ label: t("EKYC_CONNECTION_CATEGORY") || "Connection category", value: propertyDetails.connectionType?.label || null },
|
|
310
|
-
{ label: t("EKYC_USER_TYPE") || "User type", value: propertyDetails.userType?.label || null },
|
|
311
|
-
{ label: t("EKYC_NO_OF_FLOORS") || "No. of floors", value: propertyDetails.noOfFloors?.label || null },
|
|
312
|
-
]}
|
|
313
|
-
/>
|
|
485
|
+
</div>
|
|
314
486
|
|
|
315
|
-
|
|
487
|
+
{/* Submit (Non-sticky, at form end) */}
|
|
488
|
+
<div style={{ marginTop: "24px" }}>
|
|
489
|
+
<SubmitBar
|
|
490
|
+
label={isSubmitting
|
|
491
|
+
? (t("EKYC_SUBMITTING") || "Submitting...")
|
|
492
|
+
: (t("ES_COMMON_SUBMIT") || "Submit")
|
|
493
|
+
}
|
|
494
|
+
onSubmit={handleSubmit}
|
|
495
|
+
disabled={isSubmitting}
|
|
496
|
+
/>
|
|
497
|
+
</div>
|
|
316
498
|
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
499
|
+
{/* Secure notice */}
|
|
500
|
+
<div style={{
|
|
501
|
+
display: "flex", alignItems: "center", justifyContent: "center",
|
|
502
|
+
gap: "5px", marginTop: "16px",
|
|
503
|
+
fontSize: "11px", color: "#98A2B3",
|
|
504
|
+
}}>
|
|
505
|
+
<svg width="11" height="11" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round">
|
|
506
|
+
<rect x="3" y="11" width="18" height="11" rx="2" />
|
|
507
|
+
<path d="M7 11V7a5 5 0 0 1 10 0v4" />
|
|
508
|
+
</svg>
|
|
509
|
+
{t("EKYC_SECURE_DATA_NOTICE") || "Your data is encrypted and secure"}
|
|
510
|
+
</div>
|
|
324
511
|
|
|
325
|
-
|
|
326
|
-
<div style={{
|
|
327
|
-
display: "flex", alignItems: "center", justifyContent: "center",
|
|
328
|
-
gap: "5px", marginTop: "16px",
|
|
329
|
-
fontSize: "11px", color: "#98A2B3",
|
|
330
|
-
}}>
|
|
331
|
-
<svg width="11" height="11" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round">
|
|
332
|
-
<rect x="3" y="11" width="18" height="11" rx="2" />
|
|
333
|
-
<path d="M7 11V7a5 5 0 0 1 10 0v4" />
|
|
334
|
-
</svg>
|
|
335
|
-
{t("EKYC_SECURE_DATA_NOTICE") || "Your data is encrypted and secure"}
|
|
512
|
+
</Card>
|
|
336
513
|
</div>
|
|
514
|
+
</div>
|
|
337
515
|
|
|
338
|
-
|
|
339
|
-
|
|
516
|
+
{/* Toast notification */}
|
|
517
|
+
{toast && (
|
|
518
|
+
<Toast
|
|
519
|
+
label={toast.message}
|
|
520
|
+
error={toast.type === "error"}
|
|
521
|
+
success={toast.type === "success"}
|
|
522
|
+
onClose={() => setToast(null)}
|
|
523
|
+
/>
|
|
524
|
+
)}
|
|
525
|
+
</Fragment>
|
|
340
526
|
</div>
|
|
341
527
|
);
|
|
342
528
|
};
|