@djb25/digit-ui-module-ekyc 1.0.4 → 1.0.6
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 +385 -243
- package/dist/index.modern.js.map +1 -1
- package/package.json +1 -1
- package/src/components/DesktopInbox.js +7 -7
- package/src/components/Filter.js +5 -4
- package/src/components/SearchConsumer.js +11 -2
- package/src/pages/employee/AadhaarVerification.js +61 -9
- package/src/pages/employee/AddressDetails.js +135 -47
- package/src/pages/employee/Inbox.js +43 -38
- package/src/pages/employee/PropertyInfo.js +31 -14
- package/src/pages/employee/Review.js +103 -5
|
@@ -4,13 +4,7 @@ import DesktopInbox from "../../components/DesktopInbox";
|
|
|
4
4
|
import MobileInbox from "../../components/MobileInbox";
|
|
5
5
|
import Filter from "../../components/Filter";
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
{ applicationNumber: "EKYC-2024-001", citizenName: "Rahul Sharma", mobileNumber: "9876543210", status: "COMPLETED" },
|
|
9
|
-
{ applicationNumber: "EKYC-2024-002", citizenName: "Anjali Devi", mobileNumber: "9123456789", status: "PENDING" },
|
|
10
|
-
{ applicationNumber: "EKYC-2024-003", citizenName: "Amit Kumar", mobileNumber: "8888888888", status: "REJECTED" },
|
|
11
|
-
{ applicationNumber: "EKYC-2024-004", citizenName: "Priya Singh", mobileNumber: "7777777777", status: "COMPLETED" },
|
|
12
|
-
{ applicationNumber: "EKYC-2024-005", citizenName: "Suresh Gupta", mobileNumber: "6666666666", status: "PENDING" },
|
|
13
|
-
];
|
|
7
|
+
// Mock data removed in favor of API integration
|
|
14
8
|
|
|
15
9
|
const Inbox = ({
|
|
16
10
|
parentRoute,
|
|
@@ -33,28 +27,40 @@ const Inbox = ({
|
|
|
33
27
|
// Maintain the full search objects for the Search component
|
|
34
28
|
const [searchParams, setSearchParams] = useState(initialStates.searchParams || { status: defaultStatusOption });
|
|
35
29
|
|
|
36
|
-
// 2.
|
|
37
|
-
const
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
const
|
|
30
|
+
// 2. API Data Fetching
|
|
31
|
+
const { isLoading, data: dashboardData, isFetching } = Digit.Hooks.ekyc.useEkycSurveyorDashboard(
|
|
32
|
+
{},
|
|
33
|
+
{
|
|
34
|
+
tenantId,
|
|
35
|
+
offset: pageOffset,
|
|
36
|
+
limit: pageSize,
|
|
37
|
+
status: searchParams.status?.value || ""
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
enabled: !!tenantId,
|
|
41
|
+
}
|
|
42
|
+
);
|
|
43
|
+
|
|
44
|
+
const filteredData = useMemo(() => {
|
|
45
|
+
const items = dashboardData?.dashboardInfo?.consumerList || [];
|
|
46
|
+
return items.map(item => ({
|
|
47
|
+
...item,
|
|
48
|
+
applicationNumber: item.kno || item.applicationNumber,
|
|
49
|
+
citizenName: item.consumerName || item.citizenName,
|
|
50
|
+
}));
|
|
51
|
+
}, [dashboardData]);
|
|
52
|
+
|
|
53
|
+
const countData = useMemo(() => {
|
|
54
|
+
const info = dashboardData?.dashboardInfo || {};
|
|
51
55
|
return {
|
|
52
|
-
total:
|
|
53
|
-
completed:
|
|
54
|
-
pending:
|
|
55
|
-
rejected:
|
|
56
|
+
total: info.total || 0,
|
|
57
|
+
completed: info.completed || 0,
|
|
58
|
+
pending: info.pending || 0,
|
|
59
|
+
rejected: info.rejected || 0
|
|
56
60
|
};
|
|
57
|
-
}, []);
|
|
61
|
+
}, [dashboardData]);
|
|
62
|
+
|
|
63
|
+
const totalRecords = dashboardData?.dashboardInfo?.totalRecords || dashboardData?.totalCount || 0;
|
|
58
64
|
|
|
59
65
|
// 3. Handlers
|
|
60
66
|
const handleSearch = useCallback((filterParam) => {
|
|
@@ -84,10 +90,9 @@ const Inbox = ({
|
|
|
84
90
|
name: "status",
|
|
85
91
|
type: "dropdown",
|
|
86
92
|
options: [
|
|
87
|
-
{ label: t("
|
|
88
|
-
{ label: t("
|
|
89
|
-
{ label: t("EKYC_STATUS_PENDING"), value: "PENDING" },
|
|
90
|
-
{ label: t("EKYC_STATUS_REJECTED"), value: "REJECTED" },
|
|
93
|
+
{ label: t("EKYC_STATUS_ALL"), value: "" },
|
|
94
|
+
{ label: t("EKYC_STATUS_ACTIVE"), value: "ACTIVE" },
|
|
95
|
+
{ label: t("EKYC_STATUS_PENDING"), value: "PENDING START" },
|
|
91
96
|
],
|
|
92
97
|
optionsKey: "label"
|
|
93
98
|
},
|
|
@@ -98,19 +103,19 @@ const Inbox = ({
|
|
|
98
103
|
<div className="inbox-main-container">
|
|
99
104
|
{Digit.Utils.browser.isMobile() ? (
|
|
100
105
|
<MobileInbox
|
|
101
|
-
data={{ items:
|
|
102
|
-
isLoading={
|
|
106
|
+
data={{ items: filteredData, totalCount: totalRecords }}
|
|
107
|
+
isLoading={isLoading || isFetching}
|
|
103
108
|
onSearch={handleSearch}
|
|
104
109
|
searchFields={searchFields}
|
|
105
110
|
searchParams={searchParams}
|
|
106
111
|
parentRoute={parentRoute}
|
|
107
|
-
countData={
|
|
112
|
+
countData={countData}
|
|
108
113
|
/>
|
|
109
114
|
) : (
|
|
110
115
|
<DesktopInbox
|
|
111
116
|
businessService={businessService}
|
|
112
|
-
data={{ items:
|
|
113
|
-
isLoading={
|
|
117
|
+
data={{ items: filteredData, totalCount: totalRecords }}
|
|
118
|
+
isLoading={isLoading || isFetching}
|
|
114
119
|
searchFields={searchFields}
|
|
115
120
|
onSearch={handleSearch}
|
|
116
121
|
onSort={handleSort}
|
|
@@ -122,8 +127,8 @@ const Inbox = ({
|
|
|
122
127
|
parentRoute={parentRoute}
|
|
123
128
|
searchParams={searchParams}
|
|
124
129
|
sortParams={sortParams}
|
|
125
|
-
totalRecords={
|
|
126
|
-
countData={
|
|
130
|
+
totalRecords={totalRecords}
|
|
131
|
+
countData={countData}
|
|
127
132
|
filterComponent="EKYC_INBOX_FILTER"
|
|
128
133
|
/>
|
|
129
134
|
)}
|
|
@@ -366,20 +366,34 @@ const PropertyInfo = () => {
|
|
|
366
366
|
</div>
|
|
367
367
|
<input type="file" ref={fileRef} accept=".pdf" style={{ display: "none" }} onChange={handleFileUpload} />
|
|
368
368
|
<div
|
|
369
|
-
onClick={() => fileRef.current.click()}
|
|
370
|
-
onMouseOver={(e) => e.currentTarget.style.borderColor = "#185FA5"}
|
|
371
|
-
onMouseOut={(e) => e.currentTarget.style.borderColor = "#B5D4F4"}
|
|
369
|
+
onClick={() => pidNumber && fileRef.current.click()}
|
|
370
|
+
onMouseOver={(e) => { if (pidNumber) e.currentTarget.style.borderColor = "#185FA5"; }}
|
|
371
|
+
onMouseOut={(e) => { if (pidNumber) e.currentTarget.style.borderColor = "#B5D4F4"; }}
|
|
372
372
|
style={{
|
|
373
|
-
border: "1.5px dashed #B5D4F4"
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
373
|
+
border: pidNumber ? "1.5px dashed #B5D4F4" : "1.5px dashed #D0D5DD",
|
|
374
|
+
borderRadius: "10px",
|
|
375
|
+
padding: "28px 20px",
|
|
376
|
+
textAlign: "center",
|
|
377
|
+
cursor: pidNumber ? "pointer" : "not-allowed",
|
|
378
|
+
backgroundColor: pidNumber ? "#E6F1FB" : "#F9FAFB",
|
|
379
|
+
minHeight: "160px",
|
|
380
|
+
display: "flex",
|
|
381
|
+
flexDirection: "column",
|
|
382
|
+
alignItems: "center",
|
|
383
|
+
justifyContent: "center",
|
|
384
|
+
gap: "10px",
|
|
385
|
+
transition: "all 0.15s",
|
|
386
|
+
opacity: pidNumber ? 1 : 0.6,
|
|
379
387
|
}}
|
|
380
388
|
>
|
|
381
|
-
<div style={{
|
|
382
|
-
|
|
389
|
+
<div style={{
|
|
390
|
+
background: pidNumber ? "#fff" : "#EAECF0",
|
|
391
|
+
padding: "10px",
|
|
392
|
+
borderRadius: "10px",
|
|
393
|
+
display: "flex",
|
|
394
|
+
filter: pidNumber ? "none" : "grayscale(100%)"
|
|
395
|
+
}}>
|
|
396
|
+
<svg width="32" height="32" viewBox="0 0 24 24" fill={pidNumber ? "#185FA5" : "#98A2B3"}>
|
|
383
397
|
<path d="M14 2H6c-1.1 0-2 .9-2 2v16c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V8l-6-6zm-1 7V3.5L18.5 9H13z" />
|
|
384
398
|
<path d="M12 18v-4M12 14l-2 2M12 14l2 2" stroke="#fff" strokeWidth="1.5" strokeLinecap="round" />
|
|
385
399
|
</svg>
|
|
@@ -390,10 +404,10 @@ const PropertyInfo = () => {
|
|
|
390
404
|
</div>
|
|
391
405
|
) : (
|
|
392
406
|
<>
|
|
393
|
-
<div style={{ fontSize: "13px", fontWeight: "600", color: "#185FA5" }}>
|
|
394
|
-
{t("EKYC_UPLOAD_PROPERTY_DOC_CTA") || "Tap to upload"}
|
|
407
|
+
<div style={{ fontSize: "13px", fontWeight: "600", color: pidNumber ? "#185FA5" : "#98A2B3" }}>
|
|
408
|
+
{pidNumber ? (t("EKYC_UPLOAD_PROPERTY_DOC_CTA") || "Tap to upload") : (t("EKYC_ENTER_PID_FIRST_CTA") || "Enter PID to upload")}
|
|
395
409
|
</div>
|
|
396
|
-
<div style={{ fontSize: "12px", color: "#378ADD" }}>PDF
|
|
410
|
+
<div style={{ fontSize: "12px", color: pidNumber ? "#378ADD" : "#98A2B3" }}>{pidNumber ? "PDF | Max 5MB" : "Requires PID"}</div>
|
|
397
411
|
</>
|
|
398
412
|
)}
|
|
399
413
|
</div>
|
|
@@ -431,6 +445,9 @@ const PropertyInfo = () => {
|
|
|
431
445
|
<div style={{ fontSize: "12px", color: "#667085", marginTop: "2px" }}>
|
|
432
446
|
{t("EKYC_BUILDING_PHOTO") || "Building photo with GPS"}
|
|
433
447
|
</div>
|
|
448
|
+
<div style={{ fontSize: "11px", color: "#98A2B3", marginTop: "2px" }}>
|
|
449
|
+
JPG, PNG | Max 2MB
|
|
450
|
+
</div>
|
|
434
451
|
</>
|
|
435
452
|
) : (
|
|
436
453
|
<>
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import React, { Fragment } from "react";
|
|
1
|
+
import React, { Fragment, useState } 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";
|
|
@@ -133,8 +134,89 @@ const Review = () => {
|
|
|
133
134
|
propertyDetails = {},
|
|
134
135
|
} = location.state || {};
|
|
135
136
|
|
|
136
|
-
const
|
|
137
|
-
|
|
137
|
+
const [isSubmitting, setIsSubmitting] = useState(false);
|
|
138
|
+
const [toast, setToast] = useState(null);
|
|
139
|
+
|
|
140
|
+
// ── Helper: upload a File object to Filestore ──────────────────────────────
|
|
141
|
+
const uploadFile = async (file, tenantId) => {
|
|
142
|
+
if (!file) return null;
|
|
143
|
+
const res = await Digit.UploadServices.Filestorage("EKYC", file, tenantId);
|
|
144
|
+
return res?.data?.files?.[0]?.fileStoreId || null;
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
// ── Helper: convert a data-URL (base64 string) to a File blob ─────────────
|
|
148
|
+
const dataUrlToFile = (dataUrl, filename) => {
|
|
149
|
+
const arr = dataUrl.split(",");
|
|
150
|
+
const mime = arr[0].match(/:(.*?);/)[1];
|
|
151
|
+
const bstr = atob(arr[1]);
|
|
152
|
+
let n = bstr.length;
|
|
153
|
+
const u8arr = new Uint8Array(n);
|
|
154
|
+
while (n--) u8arr[n] = bstr.charCodeAt(n);
|
|
155
|
+
return new File([u8arr], filename, { type: mime });
|
|
156
|
+
};
|
|
157
|
+
|
|
158
|
+
const handleSubmit = async () => {
|
|
159
|
+
setIsSubmitting(true);
|
|
160
|
+
setToast(null);
|
|
161
|
+
try {
|
|
162
|
+
const tenantId = Digit.ULBService.getCurrentTenantId() || "dl.djb";
|
|
163
|
+
const userInfo = Digit.UserService.getUser()?.info || {};
|
|
164
|
+
|
|
165
|
+
// ── 1. Upload property document (PDF File object) ──────────────────────
|
|
166
|
+
const propertyDocFile = propertyDetails.propertyDocument || null; // File object from <input>
|
|
167
|
+
const propertyDocFileStoreId = await uploadFile(propertyDocFile, tenantId);
|
|
168
|
+
|
|
169
|
+
// ── 2. Upload building photo (data-URL string from camera capture) ─────
|
|
170
|
+
let buildingImageFileStoreId = null;
|
|
171
|
+
if (propertyDetails.buildingPhoto) {
|
|
172
|
+
const photoFile = dataUrlToFile(propertyDetails.buildingPhoto, "building_photo.jpg");
|
|
173
|
+
buildingImageFileStoreId = await uploadFile(photoFile, tenantId);
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
// ── 3. Build request payload ───────────────────────────────────────────
|
|
177
|
+
const requestBody = {
|
|
178
|
+
RequestInfo: {
|
|
179
|
+
apiId: "Rainmaker",
|
|
180
|
+
ver: "1.0",
|
|
181
|
+
msgId: `${Date.now()}|${navigator.language || "en_IN"}`,
|
|
182
|
+
tenantId,
|
|
183
|
+
authToken: userInfo.access_token || Digit.UserService.getUser()?.access_token || "",
|
|
184
|
+
},
|
|
185
|
+
updateType: "PROPERTY",
|
|
186
|
+
kno: kNumber,
|
|
187
|
+
pidNumber: propertyDetails.pidNumber || null,
|
|
188
|
+
propertyDocumentFileStoreId: propertyDocFileStoreId,
|
|
189
|
+
buildingImageFileStoreId: buildingImageFileStoreId,
|
|
190
|
+
userType: propertyDetails.userType?.value || null,
|
|
191
|
+
noOfFloor: propertyDetails.noOfFloors?.value ? parseInt(propertyDetails.noOfFloors.value, 10) : null,
|
|
192
|
+
typeOfConnection: propertyDetails.connectionCategory?.value || null,
|
|
193
|
+
connectionCategory: propertyDetails.connectionType?.value || null,
|
|
194
|
+
modifiedBy: userInfo.name || userInfo.userName || null,
|
|
195
|
+
};
|
|
196
|
+
|
|
197
|
+
// ── 4. Call the update API ─────────────────────────────────────────────
|
|
198
|
+
await Digit.CustomService.getResponse({
|
|
199
|
+
url: "/ekyc-service/user/application/_update",
|
|
200
|
+
params: { tenantId },
|
|
201
|
+
body: requestBody,
|
|
202
|
+
useCache: false,
|
|
203
|
+
method: "POST",
|
|
204
|
+
});
|
|
205
|
+
|
|
206
|
+
setToast({ type: "success", message: t("EKYC_SUBMIT_SUCCESS") || "Application submitted successfully!" });
|
|
207
|
+
setTimeout(() => {
|
|
208
|
+
history.push("/digit-ui/employee/ekyc/dashboard");
|
|
209
|
+
}, 1800);
|
|
210
|
+
} catch (err) {
|
|
211
|
+
console.error("eKYC Submit Error:", err);
|
|
212
|
+
setToast({
|
|
213
|
+
type: "error",
|
|
214
|
+
message: err?.response?.data?.Errors?.[0]?.message ||
|
|
215
|
+
t("EKYC_SUBMIT_ERROR") || "Submission failed. Please try again.",
|
|
216
|
+
});
|
|
217
|
+
} finally {
|
|
218
|
+
setIsSubmitting(false);
|
|
219
|
+
}
|
|
138
220
|
};
|
|
139
221
|
|
|
140
222
|
const handleEditAadhaar = () => {
|
|
@@ -150,6 +232,7 @@ const Review = () => {
|
|
|
150
232
|
};
|
|
151
233
|
|
|
152
234
|
return (
|
|
235
|
+
<Fragment>
|
|
153
236
|
<div className="inbox-container">
|
|
154
237
|
<style>{`
|
|
155
238
|
@keyframes fadeSlideIn {
|
|
@@ -259,7 +342,7 @@ const Review = () => {
|
|
|
259
342
|
editLabel={t("CS_COMMON_EDIT") || "Edit"}
|
|
260
343
|
rows={[
|
|
261
344
|
{ label: t("EKYC_NAME") || "Name", value: aadhaarDetails.userName || "Rajesh Kumar Singh" },
|
|
262
|
-
{ label: t("EKYC_AADHAAR") || "Aadhaar no.", value: aadhaarDetails.aadhaarLastFour ?
|
|
345
|
+
{ label: t("EKYC_AADHAAR") || "Aadhaar no.", value: aadhaarDetails.aadhaarLastFour ? `${aadhaarDetails.aadhaarLastFour}` : "XXXX XXXX 1234" },
|
|
263
346
|
{ label: t("EKYC_MOBILE_NO") || "Mobile no.", value: aadhaarDetails.mobileNumber || "XXXXXXXXXX" },
|
|
264
347
|
{ label: t("EKYC_EMAIL_ADDRESS") || "Email", value: aadhaarDetails.email || null },
|
|
265
348
|
]}
|
|
@@ -317,8 +400,12 @@ const Review = () => {
|
|
|
317
400
|
{/* Submit (Non-sticky, at form end) */}
|
|
318
401
|
<div style={{ marginTop: "24px" }}>
|
|
319
402
|
<SubmitBar
|
|
320
|
-
label={
|
|
403
|
+
label={isSubmitting
|
|
404
|
+
? (t("EKYC_SUBMITTING") || "Submitting...")
|
|
405
|
+
: (t("ES_COMMON_SUBMIT") || "Submit")
|
|
406
|
+
}
|
|
321
407
|
onSubmit={handleSubmit}
|
|
408
|
+
disabled={isSubmitting}
|
|
322
409
|
/>
|
|
323
410
|
</div>
|
|
324
411
|
|
|
@@ -338,6 +425,17 @@ const Review = () => {
|
|
|
338
425
|
</Card>
|
|
339
426
|
</div>
|
|
340
427
|
</div>
|
|
428
|
+
|
|
429
|
+
{/* Toast notification */}
|
|
430
|
+
{toast && (
|
|
431
|
+
<Toast
|
|
432
|
+
label={toast.message}
|
|
433
|
+
error={toast.type === "error"}
|
|
434
|
+
success={toast.type === "success"}
|
|
435
|
+
onClose={() => setToast(null)}
|
|
436
|
+
/>
|
|
437
|
+
)}
|
|
438
|
+
</Fragment>
|
|
341
439
|
);
|
|
342
440
|
};
|
|
343
441
|
|