@djb25/digit-ui-module-ekyc 1.0.3 → 1.0.5
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 +2164 -1535
- package/dist/index.modern.js.map +1 -1
- package/package.json +1 -1
- package/src/components/ConnectionDetailsView.js +8 -8
- package/src/components/DesktopInbox.js +5 -5
- package/src/components/SearchConsumer.js +11 -2
- package/src/pages/employee/AadhaarVerification.js +367 -251
- package/src/pages/employee/AddressDetails.js +530 -373
- package/src/pages/employee/Create.js +5 -19
- package/src/pages/employee/Inbox.js +40 -34
- package/src/pages/employee/PropertyInfo.js +409 -316
- package/src/pages/employee/Review.js +290 -89
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import React, { useState, useRef, Fragment } from "react";
|
|
2
2
|
import {
|
|
3
|
-
Header,
|
|
4
3
|
Card,
|
|
5
4
|
LabelFieldPair,
|
|
6
5
|
CardLabel,
|
|
@@ -9,10 +8,7 @@ import {
|
|
|
9
8
|
CardHeader,
|
|
10
9
|
RadioButtons,
|
|
11
10
|
ActionBar,
|
|
12
|
-
TickMark,
|
|
13
11
|
HomeIcon,
|
|
14
|
-
StatusTable,
|
|
15
|
-
Row,
|
|
16
12
|
ConnectingCheckPoints,
|
|
17
13
|
CheckPoint,
|
|
18
14
|
} from "@djb25/digit-ui-react-components";
|
|
@@ -20,67 +16,127 @@ import { useTranslation } from "react-i18next";
|
|
|
20
16
|
import { useLocation, useHistory } from "react-router-dom";
|
|
21
17
|
import AddressDetails from "./AddressDetails";
|
|
22
18
|
|
|
23
|
-
// ─── Icons
|
|
19
|
+
// ─── Icons ───────────────────────────────────────────────────────────────────
|
|
24
20
|
|
|
25
|
-
const
|
|
26
|
-
<svg width={size} height={size} viewBox="0 0 24 24" fill="none">
|
|
27
|
-
<
|
|
28
|
-
|
|
29
|
-
fill={color}
|
|
30
|
-
/>
|
|
31
|
-
<path d="M12 11c-.55 0-1-.45-1-1s.45-1 1-1 1 .45 1 1-.45 1-1 1z" fill={color} />
|
|
21
|
+
const LockIcon = ({ size = 16 }) => (
|
|
22
|
+
<svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round">
|
|
23
|
+
<rect x="3" y="11" width="18" height="11" rx="2" />
|
|
24
|
+
<path d="M7 11V7a5 5 0 0 1 10 0v4" />
|
|
32
25
|
</svg>
|
|
33
26
|
);
|
|
34
27
|
|
|
35
|
-
const UserIcon = ({ size = 16, color = "
|
|
36
|
-
<svg width={size} height={size} viewBox="0 0 24 24" fill="none">
|
|
37
|
-
<path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2"
|
|
38
|
-
<circle cx="12" cy="7" r="4"
|
|
28
|
+
const UserIcon = ({ size = 16, color = "currentColor" }) => (
|
|
29
|
+
<svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke={color} strokeWidth="1.8" strokeLinecap="round">
|
|
30
|
+
<path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2" />
|
|
31
|
+
<circle cx="12" cy="7" r="4" />
|
|
39
32
|
</svg>
|
|
40
33
|
);
|
|
41
34
|
|
|
42
|
-
const PhoneIcon = ({ size = 16, color = "
|
|
43
|
-
<svg width={size} height={size} viewBox="0 0 24 24" fill="none">
|
|
44
|
-
<path
|
|
45
|
-
d="M22 16.92v3a2 2 0 01-2.18 2 19.79 19.79 0 01-8.63-3.07A19.5 19.5 0 013.07 10.6 19.79 19.79 0 0 0 3 1.82C3 .72 3.72 0 4.82 0h3a2 2 0 012 1.72c.127.96.361 1.903.7 2.81a2 2 0 01-.45 2.11L8.91 7.91a16 16 0 006.16 6.16l1.27-1.27a2 2 0 012.11-.45c.907.339 1.85.573 2.81.7A2 2 0 0122 16.92z"
|
|
46
|
-
stroke={color}
|
|
47
|
-
strokeWidth="2"
|
|
48
|
-
strokeLinecap="round"
|
|
49
|
-
/>
|
|
35
|
+
const PhoneIcon = ({ size = 16, color = "currentColor" }) => (
|
|
36
|
+
<svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke={color} strokeWidth="1.8" strokeLinecap="round">
|
|
37
|
+
<path d="M22 16.92v3a2 2 0 01-2.18 2 19.79 19.79 0 01-8.63-3.07 19.5 19.5 0 01-5.37-5.37 19.79 19.79 0 01-3.07-8.63A2 2 0 014.82 0h3a2 2 0 012 1.72c.127.96.361 1.903.7 2.81a2 2 0 01-.45 2.11L8.91 7.91a16 16 0 006.16 6.16l1.27-1.27a2 2 0 012.11-.45c.907.339 1.85.573 2.81.7A2 2 0 0122 16.92z" />
|
|
50
38
|
</svg>
|
|
51
39
|
);
|
|
52
40
|
|
|
53
41
|
const WhatsappIcon = ({ size = 16 }) => (
|
|
54
42
|
<svg width={size} height={size} viewBox="0 0 24 24" fill="none">
|
|
55
43
|
<path
|
|
56
|
-
d="M17.472 14.382c-.297-.149-1.758-.867-2.03-.967-.273-.099-.471-.148-.67.15-.197.297-.767.966-.94 1.164-.173.199-.347.223-.644.075-.297-.15-1.255-.463-2.39-1.475-.883-.788-1.48-1.761-1.653-2.059-.173-.297-.018-.458.13-.606.134-.133.298-.347.446-.52.149-.174.198-.298.298-.497.099-.198.05-.371-.025-.52-.075-.149-.669-1.612-.916-2.207-.242-.579-.487-.5-.669-.51-.173-.008-.371-.01-.57-.01-.198 0-.52.074-.792.372-.272.297-1.04 1.016-1.04 2.479 0 1.462 1.065 2.875 1.213 3.074.149.198 2.096 3.2 5.077 4.487.709.306 1.262.489 1.694.625.712.227 1.36.195 1.871.118.571-.085 1.758-.719 2.006-1.413.248-.694.248-1.289.173-1.
|
|
44
|
+
d="M17.472 14.382c-.297-.149-1.758-.867-2.03-.967-.273-.099-.471-.148-.67.15-.197.297-.767.966-.94 1.164-.173.199-.347.223-.644.075-.297-.15-1.255-.463-2.39-1.475-.883-.788-1.48-1.761-1.653-2.059-.173-.297-.018-.458.13-.606.134-.133.298-.347.446-.52.149-.174.198-.298.298-.497.099-.198.05-.371-.025-.52-.075-.149-.669-1.612-.916-2.207-.242-.579-.487-.5-.669-.51-.173-.008-.371-.01-.57-.01-.198 0-.52.074-.792.372-.272.297-1.04 1.016-1.04 2.479 0 1.462 1.065 2.875 1.213 3.074.149.198 2.096 3.2 5.077 4.487.709.306 1.262.489 1.694.625.712.227 1.36.195 1.871.118.571-.085 1.758-.719 2.006-1.413.248-.694.248-1.289.173-1.413z"
|
|
57
45
|
fill="#25D366"
|
|
58
46
|
/>
|
|
59
47
|
<path
|
|
60
48
|
d="M12 2C6.477 2 2 6.477 2 12c0 1.89.525 3.66 1.438 5.168L2 22l4.832-1.438A9.96 9.96 0 0012 22c5.523 0 10-4.477 10-10S17.523 2 12 2z"
|
|
61
|
-
stroke="#25D366"
|
|
62
|
-
strokeWidth="2"
|
|
63
|
-
strokeLinecap="round"
|
|
49
|
+
stroke="#25D366" strokeWidth="1.8" strokeLinecap="round"
|
|
64
50
|
/>
|
|
65
51
|
</svg>
|
|
66
52
|
);
|
|
67
53
|
|
|
68
|
-
const MailIcon = ({ size = 16, color = "
|
|
69
|
-
<svg width={size} height={size} viewBox="0 0 24 24" fill="none">
|
|
70
|
-
<path d="M4 4h16c1.1 0 2 .9 2 2v12c0 1.1-.9 2-2 2H4c-1.1 0-2-.9-2-2V6c0-1.1.9-2 2-2z"
|
|
71
|
-
<path d="M22 6l-10 7L2 6"
|
|
54
|
+
const MailIcon = ({ size = 16, color = "currentColor" }) => (
|
|
55
|
+
<svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke={color} strokeWidth="1.8" strokeLinecap="round">
|
|
56
|
+
<path d="M4 4h16c1.1 0 2 .9 2 2v12c0 1.1-.9 2-2 2H4c-1.1 0-2-.9-2-2V6c0-1.1.9-2 2-2z" />
|
|
57
|
+
<path d="M22 6l-10 7L2 6" />
|
|
72
58
|
</svg>
|
|
73
59
|
);
|
|
74
60
|
|
|
75
|
-
const UsersIcon = ({ size = 16, color = "
|
|
76
|
-
<svg width={size} height={size} viewBox="0 0 24 24" fill="none">
|
|
77
|
-
<path d="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"
|
|
78
|
-
<circle cx="9" cy="7" r="4"
|
|
79
|
-
<path d="M23 21v-2a4 4 0 0 0-3-3.
|
|
80
|
-
<path d="M16 3.13a4 4 0 0 1 0 7.75" stroke={color} strokeWidth="2" strokeLinecap="round" />
|
|
61
|
+
const UsersIcon = ({ size = 16, color = "currentColor" }) => (
|
|
62
|
+
<svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke={color} strokeWidth="1.8" strokeLinecap="round">
|
|
63
|
+
<path d="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2" />
|
|
64
|
+
<circle cx="9" cy="7" r="4" />
|
|
65
|
+
<path d="M23 21v-2a4 4 0 0 0-3-3.87M16 3.13a4 4 0 0 1 0 7.75" />
|
|
81
66
|
</svg>
|
|
82
67
|
);
|
|
83
68
|
|
|
69
|
+
const CheckIcon = ({ size = 15, color = "#1D9E75" }) => (
|
|
70
|
+
<svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke={color} strokeWidth="2.8" strokeLinecap="round">
|
|
71
|
+
<polyline points="20 6 9 17 4 12" />
|
|
72
|
+
</svg>
|
|
73
|
+
);
|
|
74
|
+
|
|
75
|
+
// ─── Reusable: Icon-prefixed input wrapper ────────────────────────────────────
|
|
76
|
+
|
|
77
|
+
const IconInput = ({ icon, rightIcon, inputStyle = {}, ...props }) => (
|
|
78
|
+
<div style={{ position: "relative", width: "100%" }}>
|
|
79
|
+
<div style={{
|
|
80
|
+
position: "absolute", left: "10px", top: "50%",
|
|
81
|
+
transform: "translateY(-50%)", zIndex: 1, opacity: 0.45,
|
|
82
|
+
display: "flex", pointerEvents: "none",
|
|
83
|
+
}}>
|
|
84
|
+
{icon}
|
|
85
|
+
</div>
|
|
86
|
+
<TextInput
|
|
87
|
+
textInputStyle={{ paddingLeft: "36px", paddingRight: rightIcon ? "36px" : "12px", ...inputStyle }}
|
|
88
|
+
{...props}
|
|
89
|
+
/>
|
|
90
|
+
{rightIcon && (
|
|
91
|
+
<div style={{
|
|
92
|
+
position: "absolute", right: "10px", top: "50%",
|
|
93
|
+
transform: "translateY(-50%)", display: "flex",
|
|
94
|
+
}}>
|
|
95
|
+
{rightIcon}
|
|
96
|
+
</div>
|
|
97
|
+
)}
|
|
98
|
+
</div>
|
|
99
|
+
);
|
|
100
|
+
|
|
101
|
+
// ─── Reusable: Section heading with inline rule ───────────────────────────────
|
|
102
|
+
|
|
103
|
+
const SectionHead = ({ icon, label }) => (
|
|
104
|
+
<div style={{
|
|
105
|
+
display: "flex", alignItems: "center", gap: "8px",
|
|
106
|
+
marginBottom: "16px", marginTop: "4px",
|
|
107
|
+
}}>
|
|
108
|
+
<div style={{ opacity: 0.5, display: "flex" }}>{icon}</div>
|
|
109
|
+
<span style={{ fontSize: "15px", fontWeight: "600", color: "#0B0C0C", whiteSpace: "nowrap" }}>
|
|
110
|
+
{label}
|
|
111
|
+
</span>
|
|
112
|
+
<div style={{ flex: 1, height: "1px", background: "#EAECF0" }} />
|
|
113
|
+
</div>
|
|
114
|
+
);
|
|
115
|
+
|
|
116
|
+
// ─── Reusable: Radio toggle row ───────────────────────────────────────────────
|
|
117
|
+
|
|
118
|
+
const RadioToggleRow = ({ label, selected, onSelect, t, options }) => (
|
|
119
|
+
<div style={{
|
|
120
|
+
display: "flex", alignItems: "center",
|
|
121
|
+
justifyContent: "space-between", marginBottom: "8px",
|
|
122
|
+
}}>
|
|
123
|
+
<CardLabel style={{ fontWeight: "500", marginBottom: 0, fontSize: "13px", color: "#505A5F" }}>
|
|
124
|
+
{label}
|
|
125
|
+
</CardLabel>
|
|
126
|
+
<RadioButtons
|
|
127
|
+
options={options}
|
|
128
|
+
optionsKey="name"
|
|
129
|
+
selectedOption={selected}
|
|
130
|
+
onSelect={onSelect}
|
|
131
|
+
t={t}
|
|
132
|
+
innerStyles={{ display: "flex", gap: "20px", alignItems: "center" }}
|
|
133
|
+
style={{ display: "flex", gap: "20px", marginBottom: 0 }}
|
|
134
|
+
/>
|
|
135
|
+
</div>
|
|
136
|
+
);
|
|
137
|
+
|
|
138
|
+
// ─── Main Component ───────────────────────────────────────────────────────────
|
|
139
|
+
|
|
84
140
|
const AadhaarVerification = () => {
|
|
85
141
|
const { t } = useTranslation();
|
|
86
142
|
const location = useLocation();
|
|
@@ -99,18 +155,27 @@ const AadhaarVerification = () => {
|
|
|
99
155
|
},
|
|
100
156
|
};
|
|
101
157
|
|
|
158
|
+
// Normalize the nested data shape (API returns .connectionDetails, fallback uses .connectionDetailsInfo)
|
|
159
|
+
const details =
|
|
160
|
+
connectionDetails?.connectionDetails ||
|
|
161
|
+
connectionDetails?.connectionDetailsInfo ||
|
|
162
|
+
{};
|
|
163
|
+
|
|
164
|
+
// ── State ──
|
|
102
165
|
const [aadhaarLastFour, setAadhaarLastFour] = useState("");
|
|
103
166
|
const [isAadhaarVerified, setIsAadhaarVerified] = useState(false);
|
|
104
167
|
const [isVerifying, setIsVerifying] = useState(false);
|
|
105
168
|
const [nameCorrect, setNameCorrect] = useState({ code: "NO", name: "CORE_COMMON_NO" });
|
|
106
|
-
const [userName, setUserName] = useState(
|
|
169
|
+
const [userName, setUserName] = useState(details.consumerName || "");
|
|
170
|
+
|
|
107
171
|
const [mobileChange, setMobileChange] = useState({ code: "NO", name: "CORE_COMMON_NO" });
|
|
108
|
-
const [mobileNumber, setMobileNumber] = useState(
|
|
109
|
-
const [whatsappNumber, setWhatsappNumber] = useState(connectionDetails?.connectionDetailsInfo?.phoneNumber || "");
|
|
110
|
-
const [email, setEmail] = useState(connectionDetails?.connectionDetailsInfo?.email || "");
|
|
111
|
-
const [noOfPersons, setNoOfPersons] = useState("");
|
|
172
|
+
const [mobileNumber, setMobileNumber] = useState(details.phoneNumber || "");
|
|
112
173
|
|
|
113
|
-
|
|
174
|
+
const [whatsappNumber, setWhatsappNumber] = useState(details.phoneNumber || "");
|
|
175
|
+
const [email, setEmail] = useState(details.email || "");
|
|
176
|
+
const [noOfPersons, setNoOfPersons] = useState(
|
|
177
|
+
connectionDetails?.addressDetails?.noOfPerson || ""
|
|
178
|
+
);
|
|
114
179
|
const [showAddressSection, setShowAddressSection] = useState(false);
|
|
115
180
|
const [addressData, setAddressData] = useState(null);
|
|
116
181
|
|
|
@@ -119,17 +184,22 @@ const AadhaarVerification = () => {
|
|
|
119
184
|
{ code: "NO", name: "CORE_COMMON_NO" },
|
|
120
185
|
];
|
|
121
186
|
|
|
187
|
+
// ── Handlers ──
|
|
122
188
|
const handleVerifyAadhaar = () => {
|
|
123
|
-
if (aadhaarLastFour.length
|
|
124
|
-
|
|
189
|
+
if (aadhaarLastFour.length !== 4 || isVerifying) return;
|
|
190
|
+
setIsVerifying(true);
|
|
191
|
+
setTimeout(() => {
|
|
192
|
+
setIsVerifying(false);
|
|
193
|
+
setIsAadhaarVerified(true);
|
|
194
|
+
// Auto-expand address section upon verification
|
|
195
|
+
setShowAddressSection(true);
|
|
125
196
|
setTimeout(() => {
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
}
|
|
197
|
+
addressSectionRef.current?.scrollIntoView({ behavior: "smooth", block: "start" });
|
|
198
|
+
}, 100);
|
|
199
|
+
}, 1200);
|
|
130
200
|
};
|
|
131
201
|
|
|
132
|
-
const
|
|
202
|
+
const handleSaveAndContinue = () => {
|
|
133
203
|
setShowAddressSection(true);
|
|
134
204
|
setTimeout(() => {
|
|
135
205
|
addressSectionRef.current?.scrollIntoView({ behavior: "smooth", block: "start" });
|
|
@@ -142,299 +212,345 @@ const AadhaarVerification = () => {
|
|
|
142
212
|
kNumber,
|
|
143
213
|
selectedOption,
|
|
144
214
|
connectionDetails,
|
|
145
|
-
aadhaarDetails: {
|
|
215
|
+
aadhaarDetails: {
|
|
216
|
+
aadhaarLastFour,
|
|
217
|
+
isAadhaarVerified,
|
|
218
|
+
userName,
|
|
219
|
+
mobileNumber,
|
|
220
|
+
whatsappNumber,
|
|
221
|
+
email,
|
|
222
|
+
noOfPersons,
|
|
223
|
+
},
|
|
146
224
|
addressDetails,
|
|
147
225
|
});
|
|
148
226
|
};
|
|
149
227
|
|
|
228
|
+
// ── Styles ──
|
|
229
|
+
const styles = {
|
|
230
|
+
verifiedInput: {
|
|
231
|
+
borderColor: "#1D9E75",
|
|
232
|
+
backgroundColor: "#E1F5EE",
|
|
233
|
+
},
|
|
234
|
+
verifiedCard: {
|
|
235
|
+
backgroundColor: "#E1F5EE",
|
|
236
|
+
border: "0.5px solid #5DCAA5",
|
|
237
|
+
borderRadius: "8px",
|
|
238
|
+
padding: "16px",
|
|
239
|
+
marginTop: "14px",
|
|
240
|
+
marginBottom: "4px",
|
|
241
|
+
animation: "fadeSlideIn 0.35s ease",
|
|
242
|
+
},
|
|
243
|
+
infoLabel: {
|
|
244
|
+
fontSize: "11px",
|
|
245
|
+
fontWeight: "600",
|
|
246
|
+
color: "#1D9E75",
|
|
247
|
+
textTransform: "uppercase",
|
|
248
|
+
letterSpacing: "0.05em",
|
|
249
|
+
marginBottom: "3px",
|
|
250
|
+
},
|
|
251
|
+
infoValue: {
|
|
252
|
+
fontSize: "14px",
|
|
253
|
+
fontWeight: "500",
|
|
254
|
+
color: "#04342C",
|
|
255
|
+
},
|
|
256
|
+
twoCol: {
|
|
257
|
+
display: "grid",
|
|
258
|
+
gridTemplateColumns: "1fr 1fr",
|
|
259
|
+
gap: "14px",
|
|
260
|
+
marginBottom: "20px",
|
|
261
|
+
},
|
|
262
|
+
optionalTag: {
|
|
263
|
+
display: "inline-block",
|
|
264
|
+
fontSize: "10px",
|
|
265
|
+
background: "#F1EFE8",
|
|
266
|
+
color: "#5F5E5A",
|
|
267
|
+
border: "0.5px solid #D3D1C7",
|
|
268
|
+
borderRadius: "10px",
|
|
269
|
+
padding: "1px 7px",
|
|
270
|
+
marginLeft: "6px",
|
|
271
|
+
fontWeight: "400",
|
|
272
|
+
},
|
|
273
|
+
};
|
|
274
|
+
|
|
150
275
|
return (
|
|
151
276
|
<div className="inbox-container">
|
|
152
277
|
<style>{`
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
278
|
+
@keyframes fadeSlideIn {
|
|
279
|
+
from { opacity: 0; transform: translateY(6px); }
|
|
280
|
+
to { opacity: 1; transform: translateY(0); }
|
|
281
|
+
}
|
|
282
|
+
@keyframes pulseGreen {
|
|
283
|
+
0%, 100% { box-shadow: 0 0 0 0 rgba(29,158,117,0.35); }
|
|
284
|
+
50% { box-shadow: 0 0 0 6px rgba(29,158,117,0); }
|
|
285
|
+
}
|
|
286
|
+
.ekyc-sidebar-step { display: flex; gap: 10px; align-items: flex-start; position: relative; padding-bottom: 18px; }
|
|
287
|
+
.ekyc-sidebar-step:last-child { padding-bottom: 0; }
|
|
288
|
+
.ekyc-step-line { position: absolute; left: 10px; top: 22px; width: 1px; height: calc(100% - 10px); background: #EAECF0; }
|
|
289
|
+
.ekyc-step-dot { width: 20px; height: 20px; border-radius: 50%; border: 1.5px solid #D0D5DD; display: flex; align-items: center; justify-content: center; font-size: 10px; font-weight: 500; color: #98A2B3; background: #fff; flex-shrink: 0; margin-top: 1px; }
|
|
290
|
+
.ekyc-step-dot.active { border-color: #185FA5; color: #185FA5; background: #E6F1FB; }
|
|
291
|
+
.ekyc-step-dot.done { border-color: #0F6E56; background: #0F6E56; color: #fff; }
|
|
292
|
+
.ekyc-step-label { font-size: 12px; color: #667085; padding-top: 2px; }
|
|
293
|
+
.ekyc-step-label.active { color: #0B0C0C; font-weight: 600; }
|
|
294
|
+
.ekyc-step-label.done { color: #0F6E56; }
|
|
295
|
+
.ekyc-field-label { font-size: 11px; font-weight: 600; color: #667085; text-transform: uppercase; letter-spacing: 0.04em; margin-bottom: 6px; }
|
|
296
|
+
`}</style>
|
|
297
|
+
|
|
298
|
+
{/* ── Sidebar ── */}
|
|
158
299
|
<div className="filters-container">
|
|
159
|
-
{
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
<HomeIcon style={{ width: "24px", height: "24px" }} />
|
|
300
|
+
<Card style={{ display: "flex", alignItems: "center", padding: "12px 16px", marginBottom: "12px", borderRadius: "8px" }}>
|
|
301
|
+
<div style={{ color: "#185FA5", marginRight: "10px", display: "flex" }}>
|
|
302
|
+
<HomeIcon style={{ width: "20px", height: "20px" }} />
|
|
303
|
+
</div>
|
|
304
|
+
<div style={{ fontWeight: "600", fontSize: "15px", color: "#0B0C0C" }}>
|
|
305
|
+
{t("EKYC_PROCESS") || "eKYC Process"}
|
|
166
306
|
</div>
|
|
167
|
-
<div style={{ fontWeight: "700", fontSize: "18px", color: "#0B0C0C" }}>{t("EKYC_PROCESS")}</div>
|
|
168
307
|
</Card>
|
|
169
308
|
|
|
170
|
-
{
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
309
|
+
<div style={{ background: "#fff", padding: "16px 14px", borderRadius: "8px", border: "1px solid #EAECF0" }}>
|
|
310
|
+
{[
|
|
311
|
+
{ label: t("EKYC_STEP_AADHAAR") || "Aadhaar", done: showAddressSection, active: !showAddressSection },
|
|
312
|
+
{ label: t("EKYC_STEP_ADDRESS") || "Address", done: addressData !== null, active: showAddressSection && addressData === null },
|
|
313
|
+
{ label: t("EKYC_STEP_PROPERTY") || "Property", done: false, active: false },
|
|
314
|
+
{ label: t("EKYC_STEP_REVIEW") || "Review", done: false, active: false },
|
|
315
|
+
].map((step, i) => (
|
|
316
|
+
<div className="ekyc-sidebar-step" key={i}>
|
|
317
|
+
<div className={`ekyc-step-dot${step.done ? " done" : step.active ? " active" : ""}`}>
|
|
318
|
+
{step.done
|
|
319
|
+
? <CheckIcon size={11} color="#fff" />
|
|
320
|
+
: i + 1}
|
|
321
|
+
</div>
|
|
322
|
+
{i < 3 && <div className="ekyc-step-line" />}
|
|
323
|
+
<div className={`ekyc-step-label${step.done ? " done" : step.active ? " active" : ""}`}>
|
|
324
|
+
{step.label}
|
|
325
|
+
</div>
|
|
326
|
+
</div>
|
|
327
|
+
))}
|
|
186
328
|
</div>
|
|
187
329
|
</div>
|
|
188
330
|
|
|
331
|
+
{/* ── Main content ── */}
|
|
189
332
|
<div style={{ flex: 1, marginLeft: "16px" }}>
|
|
190
333
|
<Card>
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
334
|
+
|
|
335
|
+
{/* K-Number badge */}
|
|
336
|
+
<div style={{ display: "flex", justifyContent: "flex-end", marginBottom: "20px" }}>
|
|
337
|
+
<div style={{
|
|
338
|
+
background: "#F9FAFB", border: "0.5px solid #EAECF0",
|
|
339
|
+
borderRadius: "20px", padding: "4px 14px",
|
|
340
|
+
fontSize: "12px", color: "#667085",
|
|
341
|
+
}}>
|
|
342
|
+
{t("EKYC_K_NUMBER") || "K Number"}:{" "}
|
|
343
|
+
<span style={{ color: "#0B0C0C", fontWeight: "600" }}>{kNumber}</span>
|
|
195
344
|
</div>
|
|
196
345
|
</div>
|
|
197
346
|
|
|
198
|
-
{/* Section 1: Aadhaar
|
|
199
|
-
<
|
|
347
|
+
{/* ── Section 1: Aadhaar ── */}
|
|
348
|
+
<SectionHead
|
|
349
|
+
icon={<LockIcon size={16} />}
|
|
350
|
+
label={t("EKYC_AADHAAR_NUMBER_HEADER") || "Aadhaar Number"}
|
|
351
|
+
/>
|
|
200
352
|
|
|
353
|
+
<div className="ekyc-field-label">
|
|
354
|
+
{t("EKYC_LAST_4_DIGIT_AADHAAR") || "Enter 12 digits of Aadhaar"}
|
|
355
|
+
</div>
|
|
201
356
|
<LabelFieldPair>
|
|
202
|
-
<
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
<
|
|
206
|
-
</div>
|
|
207
|
-
<TextInput
|
|
357
|
+
<div className="field">
|
|
358
|
+
<IconInput
|
|
359
|
+
icon={<LockIcon size={15} />}
|
|
360
|
+
rightIcon={isAadhaarVerified ? <CheckIcon size={15} /> : null}
|
|
208
361
|
value={aadhaarLastFour}
|
|
209
362
|
onChange={(e) => {
|
|
210
363
|
const val = e.target.value;
|
|
211
|
-
if (val.length <=
|
|
364
|
+
if (val.length <= 12 && /^\d*$/.test(val)) setAadhaarLastFour(val);
|
|
212
365
|
}}
|
|
213
|
-
placeholder={t("EKYC_ENTER_LAST_4_DIGIT") || "Enter
|
|
214
|
-
|
|
215
|
-
|
|
366
|
+
placeholder={t("EKYC_ENTER_LAST_4_DIGIT") || "Enter 12 digits"}
|
|
367
|
+
maxLength={12}
|
|
368
|
+
disabled={isAadhaarVerified}
|
|
369
|
+
inputStyle={isAadhaarVerified ? styles.verifiedInput : {}}
|
|
216
370
|
/>
|
|
217
|
-
{isAadhaarVerified && (
|
|
218
|
-
<div style={{ position: "absolute", right: "12px", top: "50%", transform: "translateY(-50%)" }}>
|
|
219
|
-
<TickMark fillColor="#2E9E8F" />
|
|
220
|
-
</div>
|
|
221
|
-
)}
|
|
222
371
|
</div>
|
|
223
372
|
</LabelFieldPair>
|
|
224
373
|
|
|
225
374
|
{!isAadhaarVerified && (
|
|
226
375
|
<SubmitBar
|
|
227
|
-
label={isVerifying
|
|
376
|
+
label={isVerifying
|
|
377
|
+
? t("EKYC_VERIFYING") || "Verifying..."
|
|
378
|
+
: t("EKYC_VERIFY_AADHAAR_BTN") || "Verify Aadhaar"}
|
|
228
379
|
onSubmit={handleVerifyAadhaar}
|
|
229
380
|
disabled={aadhaarLastFour.length !== 4 || isVerifying}
|
|
230
|
-
style={{ marginTop: "
|
|
381
|
+
style={{ marginTop: "12px" }}
|
|
231
382
|
/>
|
|
232
383
|
)}
|
|
233
384
|
|
|
234
385
|
{isAadhaarVerified && (
|
|
235
|
-
<div
|
|
236
|
-
style={{
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
}}
|
|
245
|
-
>
|
|
246
|
-
<div style={{ display: "flex", alignItems: "center", gap: "10px", marginBottom: "16px" }}>
|
|
247
|
-
<div
|
|
248
|
-
style={{
|
|
249
|
-
backgroundColor: "#D1E9DB",
|
|
250
|
-
padding: "4px",
|
|
251
|
-
borderRadius: "50%",
|
|
252
|
-
display: "flex",
|
|
253
|
-
animation: "pulseGreen 2s ease infinite",
|
|
254
|
-
}}
|
|
255
|
-
>
|
|
256
|
-
<TickMark fillColor="#2E9E8F" />
|
|
386
|
+
<div style={styles.verifiedCard}>
|
|
387
|
+
<div style={{ display: "flex", alignItems: "center", gap: "8px", marginBottom: "14px" }}>
|
|
388
|
+
<div style={{
|
|
389
|
+
width: "24px", height: "24px", borderRadius: "50%",
|
|
390
|
+
background: "#9FE1CB", display: "flex", alignItems: "center",
|
|
391
|
+
justifyContent: "center", animation: "pulseGreen 2s ease infinite",
|
|
392
|
+
flexShrink: 0,
|
|
393
|
+
}}>
|
|
394
|
+
<CheckIcon size={13} color="#085041" />
|
|
257
395
|
</div>
|
|
258
|
-
<span style={{ fontWeight: "
|
|
396
|
+
<span style={{ fontWeight: "600", color: "#085041", fontSize: "14px" }}>
|
|
259
397
|
{t("EKYC_AADHAAR_VERIFIED_SUCCESS") || "Aadhaar Verified Successfully"}
|
|
260
398
|
</span>
|
|
261
399
|
</div>
|
|
262
|
-
<div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: "
|
|
263
|
-
<div
|
|
264
|
-
<
|
|
265
|
-
<
|
|
400
|
+
<div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: "12px" }}>
|
|
401
|
+
<div>
|
|
402
|
+
<div style={styles.infoLabel}>{t("EKYC_NAME") || "Name"}</div>
|
|
403
|
+
<div style={styles.infoValue}>{details.consumerName}</div>
|
|
266
404
|
</div>
|
|
267
|
-
<div
|
|
268
|
-
<
|
|
269
|
-
<
|
|
405
|
+
<div>
|
|
406
|
+
<div style={styles.infoLabel}>{t("EKYC_AADHAAR") || "Aadhaar"}</div>
|
|
407
|
+
<div style={styles.infoValue}>XXXX XXXX {aadhaarLastFour}</div>
|
|
270
408
|
</div>
|
|
271
|
-
<div style={{
|
|
272
|
-
<
|
|
273
|
-
<
|
|
409
|
+
<div style={{ gridColumn: "span 2" }}>
|
|
410
|
+
<div style={styles.infoLabel}>{t("EKYC_ADDRESS") || "Address"}</div>
|
|
411
|
+
<div style={{ ...styles.infoValue, fontSize: "13px" }}>{details.address}</div>
|
|
274
412
|
</div>
|
|
275
413
|
</div>
|
|
276
414
|
</div>
|
|
277
415
|
)}
|
|
278
416
|
|
|
279
|
-
<hr style={{ margin: "
|
|
280
|
-
|
|
281
|
-
{/* Section 2: Contact Details */}
|
|
282
|
-
<
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
<div className="field"
|
|
298
|
-
<
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
left: "12px",
|
|
302
|
-
top: "50%",
|
|
303
|
-
transform: "translateY(-50%)",
|
|
304
|
-
zIndex: 1,
|
|
305
|
-
opacity: nameCorrect.code === "YES" ? 0.6 : 0.3,
|
|
306
|
-
}}
|
|
307
|
-
>
|
|
308
|
-
<UserIcon size={18} color={nameCorrect.code === "YES" ? "#64748b" : "#94a3b8"} />
|
|
309
|
-
</div>
|
|
310
|
-
<TextInput
|
|
417
|
+
<hr style={{ margin: "24px 0", border: 0, borderTop: "1px solid #EAECF0" }} />
|
|
418
|
+
|
|
419
|
+
{/* ── Section 2: Contact Details ── */}
|
|
420
|
+
<SectionHead
|
|
421
|
+
icon={<UserIcon size={16} />}
|
|
422
|
+
label={t("EKYC_CONTACT_DETAILS_HEADER") || "Contact Details"}
|
|
423
|
+
/>
|
|
424
|
+
|
|
425
|
+
{/* Name */}
|
|
426
|
+
<RadioToggleRow
|
|
427
|
+
label={`${t("EKYC_USER_NAME")} (${t("EKYC_NAME_CORRECT_HINT")})`}
|
|
428
|
+
selected={nameCorrect}
|
|
429
|
+
onSelect={setNameCorrect}
|
|
430
|
+
options={yesNoOptions}
|
|
431
|
+
sty
|
|
432
|
+
t={t}
|
|
433
|
+
/>
|
|
434
|
+
<LabelFieldPair>
|
|
435
|
+
<div className="field">
|
|
436
|
+
<IconInput
|
|
437
|
+
icon={<UserIcon size={15} color={nameCorrect.code === "YES" ? "#64748b" : "#94a3b8"} />}
|
|
438
|
+
style={{ marginBottom: "12px" }}
|
|
311
439
|
value={userName}
|
|
312
440
|
onChange={(e) => setUserName(e.target.value)}
|
|
313
441
|
placeholder={t("EKYC_ENTER_NAME_PLACEHOLDER") || "Enter full name"}
|
|
314
|
-
textInputStyle={{ paddingLeft: "40px" }}
|
|
315
442
|
disabled={nameCorrect.code !== "YES"}
|
|
316
443
|
/>
|
|
317
444
|
</div>
|
|
318
445
|
</LabelFieldPair>
|
|
319
446
|
|
|
447
|
+
{/* Mobile */}
|
|
448
|
+
<RadioToggleRow
|
|
449
|
+
label={`${t("EKYC_USER_MOBILE_NUMBER")} (${t("EKYC_UPDATE_MOBILE_HINT")})`}
|
|
450
|
+
selected={mobileChange}
|
|
451
|
+
onSelect={setMobileChange}
|
|
452
|
+
options={yesNoOptions}
|
|
453
|
+
t={t}
|
|
454
|
+
/>
|
|
320
455
|
<LabelFieldPair>
|
|
321
|
-
<div
|
|
322
|
-
<
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
options={yesNoOptions}
|
|
326
|
-
optionsKey="name"
|
|
327
|
-
selectedOption={mobileChange}
|
|
328
|
-
onSelect={setMobileChange}
|
|
329
|
-
t={t}
|
|
330
|
-
innerStyles={{ display: "flex", gap: "24px" }}
|
|
331
|
-
style={{ display: "flex", gap: "50px", marginBottom: "0" }}
|
|
332
|
-
/>
|
|
333
|
-
</div>
|
|
334
|
-
<div className="field" style={{ position: "relative" }}>
|
|
335
|
-
<div
|
|
336
|
-
style={{
|
|
337
|
-
position: "absolute",
|
|
338
|
-
left: "12px",
|
|
339
|
-
top: "50%",
|
|
340
|
-
transform: "translateY(-50%)",
|
|
341
|
-
zIndex: 1,
|
|
342
|
-
opacity: mobileChange.code === "YES" ? 0.6 : 0.3,
|
|
343
|
-
}}
|
|
344
|
-
>
|
|
345
|
-
<PhoneIcon size={18} color={mobileChange.code === "YES" ? "#64748b" : "#94a3b8"} />
|
|
346
|
-
</div>
|
|
347
|
-
<TextInput
|
|
456
|
+
<div className="field">
|
|
457
|
+
<IconInput
|
|
458
|
+
icon={<PhoneIcon size={15} color={mobileChange.code === "YES" ? "#64748b" : "#94a3b8"} />}
|
|
459
|
+
style={{ marginBottom: "12px" }}
|
|
348
460
|
value={mobileNumber}
|
|
349
461
|
onChange={(e) => setMobileNumber(e.target.value)}
|
|
350
462
|
placeholder="+91 XXXXX XXXXX"
|
|
351
|
-
textInputStyle={{ paddingLeft: "40px" }}
|
|
352
463
|
disabled={mobileChange.code !== "YES"}
|
|
353
464
|
/>
|
|
354
465
|
</div>
|
|
355
466
|
</LabelFieldPair>
|
|
356
467
|
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
<div className="field"
|
|
361
|
-
|
|
362
|
-
<WhatsappIcon size={18} />
|
|
363
|
-
</div>
|
|
364
|
-
<TextInput
|
|
365
|
-
value={whatsappNumber}
|
|
366
|
-
onChange={(e) => setWhatsappNumber(e.target.value)}
|
|
367
|
-
placeholder="+91 XXXXX XXXXX"
|
|
368
|
-
textInputStyle={{ paddingLeft: "40px" }}
|
|
369
|
-
/>
|
|
468
|
+
{/* WhatsApp + Email */}
|
|
469
|
+
<div style={styles.twoCol}>
|
|
470
|
+
<div>
|
|
471
|
+
<div className="ekyc-field-label">
|
|
472
|
+
{t("EKYC_WHATSAPP_NUMBER") || "WhatsApp Number"}
|
|
370
473
|
</div>
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
{
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
<
|
|
382
|
-
value={email}
|
|
383
|
-
onChange={(e) => setEmail(e.target.value)}
|
|
384
|
-
placeholder={t("EKYC_EMAIL_ADDRESS_PLACEHOLDER") || "example@email.com"}
|
|
385
|
-
textInputStyle={{ paddingLeft: "40px" }}
|
|
386
|
-
/>
|
|
474
|
+
<IconInput
|
|
475
|
+
icon={<WhatsappIcon size={15} />}
|
|
476
|
+
value={whatsappNumber}
|
|
477
|
+
onChange={(e) => setWhatsappNumber(e.target.value)}
|
|
478
|
+
placeholder="+91 XXXXX XXXXX"
|
|
479
|
+
/>
|
|
480
|
+
</div>
|
|
481
|
+
<div>
|
|
482
|
+
<div className="ekyc-field-label">
|
|
483
|
+
{t("EKYC_EMAIL_ADDRESS") || "Email Address"}
|
|
484
|
+
<span style={styles.optionalTag}>{t("EKYC_OPTIONAL") || "Optional"}</span>
|
|
387
485
|
</div>
|
|
388
|
-
|
|
486
|
+
<IconInput
|
|
487
|
+
icon={<MailIcon size={15} />}
|
|
488
|
+
value={email}
|
|
489
|
+
onChange={(e) => setEmail(e.target.value)}
|
|
490
|
+
placeholder={t("EKYC_EMAIL_ADDRESS_PLACEHOLDER") || "example@email.com"}
|
|
491
|
+
/>
|
|
492
|
+
</div>
|
|
389
493
|
</div>
|
|
390
494
|
|
|
391
|
-
<hr style={{ margin: "
|
|
495
|
+
<hr style={{ margin: "24px 0", border: 0, borderTop: "1px solid #EAECF0" }} />
|
|
392
496
|
|
|
393
|
-
{/* Section 3: Family Details */}
|
|
394
|
-
<
|
|
497
|
+
{/* ── Section 3: Family Details ── */}
|
|
498
|
+
<SectionHead
|
|
499
|
+
icon={<UsersIcon size={16} />}
|
|
500
|
+
label={t("EKYC_FAMILY_DETAILS_HEADER") || "Family Details"}
|
|
501
|
+
/>
|
|
395
502
|
|
|
503
|
+
<div className="ekyc-field-label">
|
|
504
|
+
{t("EKYC_NO_OF_PERSONS") || "Number of Family Members"}
|
|
505
|
+
</div>
|
|
396
506
|
<LabelFieldPair>
|
|
397
|
-
<
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
<UsersIcon size={18} />
|
|
401
|
-
</div>
|
|
402
|
-
<TextInput
|
|
507
|
+
<div className="field">
|
|
508
|
+
<IconInput
|
|
509
|
+
icon={<UsersIcon size={15} />}
|
|
403
510
|
value={noOfPersons}
|
|
404
511
|
onChange={(e) => {
|
|
405
512
|
if (/^\d*$/.test(e.target.value)) setNoOfPersons(e.target.value);
|
|
406
513
|
}}
|
|
407
514
|
placeholder={t("EKYC_ENTER_NO_OF_PERSONS") || "Enter total number of persons"}
|
|
408
|
-
textInputStyle={{ paddingLeft: "40px" }}
|
|
409
515
|
/>
|
|
410
516
|
</div>
|
|
411
517
|
</LabelFieldPair>
|
|
412
518
|
|
|
519
|
+
{/* Save & Continue (Non-sticky, at form end) */}
|
|
413
520
|
{!showAddressSection && (
|
|
414
|
-
<
|
|
415
|
-
<SubmitBar
|
|
416
|
-
|
|
521
|
+
<div style={{ marginTop: "24px" }}>
|
|
522
|
+
<SubmitBar
|
|
523
|
+
label={t("ES_COMMON_SAVE_CONTINUE") || "Save & Continue"}
|
|
524
|
+
onSubmit={handleSaveAndContinue}
|
|
525
|
+
/>
|
|
526
|
+
</div>
|
|
417
527
|
)}
|
|
418
528
|
|
|
529
|
+
{/* Address section (injected inline) */}
|
|
419
530
|
{showAddressSection && (
|
|
420
531
|
<div ref={addressSectionRef}>
|
|
421
|
-
<AddressDetails
|
|
532
|
+
<AddressDetails
|
|
533
|
+
isSection={true}
|
|
534
|
+
onComplete={handleCompleteAll}
|
|
535
|
+
parentState={{ kNumber, selectedOption, connectionDetails }}
|
|
536
|
+
/>
|
|
422
537
|
</div>
|
|
423
538
|
)}
|
|
424
539
|
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
540
|
+
{/* Secure notice */}
|
|
541
|
+
<div style={{
|
|
542
|
+
display: "flex", alignItems: "center", justifyContent: "center",
|
|
543
|
+
gap: "5px", marginTop: "20px",
|
|
544
|
+
fontSize: "11px", color: "#98A2B3",
|
|
545
|
+
}}>
|
|
546
|
+
<LockIcon size={11} />
|
|
547
|
+
{t("EKYC_SECURE_DATA_NOTICE") || "Your data is encrypted and secure"}
|
|
433
548
|
</div>
|
|
549
|
+
|
|
434
550
|
</Card>
|
|
435
551
|
</div>
|
|
436
552
|
</div>
|
|
437
553
|
);
|
|
438
554
|
};
|
|
439
555
|
|
|
440
|
-
export default AadhaarVerification;
|
|
556
|
+
export default AadhaarVerification;
|