@djb25/digit-ui-module-ekyc 1.0.3 → 1.0.4

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,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,
@@ -12,7 +11,6 @@ import {
12
11
  InfoBannerIcon,
13
12
  PropertyHouse,
14
13
  LocationIcon,
15
- RemoveableTag,
16
14
  HomeIcon,
17
15
  ConnectingCheckPoints,
18
16
  CheckPoint,
@@ -20,26 +18,148 @@ import {
20
18
  import { useTranslation } from "react-i18next";
21
19
  import { useHistory, useLocation } from "react-router-dom";
22
20
 
21
+ // ─── Icons ────────────────────────────────────────────────────────────────────
22
+
23
+ const FlagIcon = ({ size = 20 }) => (
24
+ <svg width={size} height={size} viewBox="0 0 24 24" fill="none">
25
+ <path d="M14.4 6L13.6 4H5V21H7V14H12.6L13.4 16H20V6H14.4Z" fill="#0F6E56" />
26
+ </svg>
27
+ );
28
+
29
+ const IdCardIcon = ({ size = 20 }) => (
30
+ <svg width={size} height={size} viewBox="0 0 24 24" fill="none">
31
+ <path
32
+ d="M2 7V17C2 18.1 2.9 19 4 19H20C21.1 19 22 18.1 22 17V7C22 5.9 21.1 5 20 5H4C2.9 5 2 5.9 2 7ZM12 11H14V13H12V11ZM12 7H14V9H12V7ZM16 11H20V13H16V11ZM16 7H20V9H16V7ZM4 7H10V15H4V7ZM20 17H4V16H20V17Z"
33
+ fill="#185FA5"
34
+ />
35
+ </svg>
36
+ );
37
+
38
+ const CameraIcon = ({ size = 28 }) => (
39
+ <svg width={size} height={size} viewBox="0 0 24 24" fill="none">
40
+ <path
41
+ d="M9 2L7.17 4H4C2.9 4 2 4.9 2 6V18C2 19.1 2.9 20 4 20H20C21.1 20 22 19.1 22 18V6C22 4.9 21.1 4 20 4H16.83L15 2H9ZM12 17C9.24 17 7 14.76 7 12C7 9.24 9.24 7 12 7C14.76 7 17 9.24 17 12C17 14.76 14.76 17 12 17ZM12 9C10.34 9 9 10.34 9 12C9 13.66 10.34 15 12 15C13.66 15 15 13.66 15 12C15 10.34 13.66 9 12 9Z"
42
+ fill="#185FA5"
43
+ />
44
+ </svg>
45
+ );
46
+
47
+ const TargetIcon = ({ size = 20 }) => (
48
+ <svg width={size} height={size} viewBox="0 0 24 24" fill="none">
49
+ <path
50
+ d="M12 8C9.79 8 8 9.79 8 12C8 14.21 9.79 16 12 16C14.21 16 16 14.21 16 12C16 9.79 14.21 8 12 8ZM20.94 11C20.48 6.83 17.17 3.52 13 3.06V1H11V3.06C6.83 3.52 3.52 6.83 3.06 11H1V13H3.06C3.52 17.17 6.83 20.48 11 20.94V23H13V20.94C17.17 20.48 20.48 17.17 20.94 13H23V11H20.94ZM12 19C8.13 19 5 15.87 5 12C5 8.13 8.13 5 12 5C15.87 5 19 8.13 19 12C19 15.87 15.87 19 12 19Z"
51
+ fill="#185FA5"
52
+ />
53
+ </svg>
54
+ );
55
+
56
+ const PincodeIcon = ({ size = 18 }) => (
57
+ <svg width={size} height={size} viewBox="0 0 24 24" fill="none">
58
+ <path
59
+ d="M13 13V11H15V13H13ZM13 9V7H15V9H13ZM17 13V11H19V13H17ZM17 9V7H19V9H17ZM11 13V11H9V13H11ZM11 9V7H9V9H11ZM7 13V11H5V13H7ZM7 9V7H5V9H7ZM21 3H3C1.9 3 1 3.9 1 5V19C1 20.1 1.9 21 3 21H21C22.1 21 23 20.1 23 19V5C23 3.9 22.1 3 21 3ZM21 19H3V5H21V19Z"
60
+ fill="currentColor"
61
+ />
62
+ </svg>
63
+ );
64
+
65
+ const TrashIcon = ({ size = 16 }) => (
66
+ <svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="#D92D20" strokeWidth="2" strokeLinecap="round">
67
+ <polyline points="3 6 5 6 21 6" />
68
+ <path d="M19 6l-1 14a2 2 0 0 1-2 2H8a2 2 0 0 1-2-2L5 6" />
69
+ <path d="M10 11v6M14 11v6" />
70
+ <path d="M9 6V4a1 1 0 0 1 1-1h4a1 1 0 0 1 1 1v2" />
71
+ </svg>
72
+ );
73
+
74
+ const CheckIcon = ({ size = 11, color = "#fff" }) => (
75
+ <svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke={color} strokeWidth="3" strokeLinecap="round">
76
+ <polyline points="20 6 9 17 4 12" />
77
+ </svg>
78
+ );
79
+
80
+ // ─── Reusable: Icon-prefixed input ────────────────────────────────────────────
81
+
82
+ const IconInput = ({ icon, topAligned = false, inputStyle = {}, ...props }) => (
83
+ <div style={{ position: "relative", width: "100%" }}>
84
+ <div style={{
85
+ position: "absolute",
86
+ left: "10px",
87
+ ...(topAligned ? { top: "14px" } : { top: "50%", transform: "translateY(-50%)" }),
88
+ zIndex: 1,
89
+ opacity: 0.45,
90
+ display: "flex",
91
+ pointerEvents: "none",
92
+ }}>
93
+ {icon}
94
+ </div>
95
+ <TextInput
96
+ textInputStyle={{ paddingLeft: "36px", paddingRight: "12px", ...inputStyle }}
97
+ {...props}
98
+ />
99
+ </div>
100
+ );
101
+
102
+ // ─── Reusable: Section heading with inline rule ───────────────────────────────
103
+
104
+ const SectionHead = ({ icon, label }) => (
105
+ <div style={{
106
+ display: "flex", alignItems: "center", gap: "8px",
107
+ marginBottom: "16px", marginTop: "4px",
108
+ }}>
109
+ <div style={{ opacity: 0.5, display: "flex" }}>{icon}</div>
110
+ <span style={{ fontSize: "15px", fontWeight: "600", color: "#0B0C0C", whiteSpace: "nowrap" }}>
111
+ {label}
112
+ </span>
113
+ <div style={{ flex: 1, height: "1px", background: "#EAECF0" }} />
114
+ </div>
115
+ );
116
+
117
+ // ─── Reusable: Admin info card ────────────────────────────────────────────────
118
+
119
+ const AdminCard = ({ bgColor, iconBg, icon, labelColor, label, value }) => (
120
+ <div style={{
121
+ backgroundColor: bgColor,
122
+ padding: "14px 16px",
123
+ borderRadius: "8px",
124
+ display: "flex",
125
+ alignItems: "center",
126
+ gap: "14px",
127
+ border: "0.5px solid #EAECF0",
128
+ }}>
129
+ <div style={{ backgroundColor: iconBg, padding: "8px", borderRadius: "8px", display: "flex", flexShrink: 0 }}>
130
+ {icon}
131
+ </div>
132
+ <div>
133
+ <div style={{ color: labelColor, fontSize: "10px", fontWeight: "600", textTransform: "uppercase", letterSpacing: "0.05em", marginBottom: "3px" }}>
134
+ {label}
135
+ </div>
136
+ <div style={{ fontSize: "14px", fontWeight: "600", color: "#101828" }}>{value}</div>
137
+ </div>
138
+ </div>
139
+ );
140
+
141
+ // ─── Main Component ───────────────────────────────────────────────────────────
142
+
23
143
  const AddressDetails = ({ isSection = false, onComplete, parentState }) => {
24
144
  const { t } = useTranslation();
25
145
  const history = useHistory();
26
146
  const location = useLocation();
27
147
 
28
- // Use parent state if provided, otherwise fallback to location state or defaults
29
- const flowState = parentState ||
30
- location.state || {
31
- kNumber: "EKYC-1234567890",
32
- selectedOption: { code: "SELF", name: "EKYC_SELF" },
33
- connectionDetails: null,
34
- };
148
+ const flowState = parentState || location.state || {
149
+ kNumber: "EKYC-1234567890",
150
+ selectedOption: { code: "SELF", name: "EKYC_SELF" },
151
+ connectionDetails: null,
152
+ };
153
+
154
+ const addrDetails = flowState.connectionDetails?.addressDetails || {};
35
155
 
36
156
  const [addressType, setAddressType] = useState({ code: "AADHAAR", name: "EKYC_AADHAAR_ADDRESS" });
37
157
  const [correctAddress, setCorrectAddress] = useState({ code: "NO", name: "CORE_COMMON_NO" });
38
- const [fullAddress, setFullAddress] = useState("");
39
- const [flatNo, setFlatNo] = useState("");
40
- const [building, setBuilding] = useState("");
41
- const [landmark, setLandmark] = useState("");
42
- const [pincode, setPincode] = useState("");
158
+ const [fullAddress, setFullAddress] = useState(addrDetails.fullAddress || "");
159
+ const [flatNo, setFlatNo] = useState(addrDetails.flatHouseNumber || "");
160
+ const [building, setBuilding] = useState(addrDetails.buildingTower || "");
161
+ const [landmark, setLandmark] = useState(addrDetails.landmark || "");
162
+ const [pincode, setPincode] = useState(addrDetails.pinCode || "");
43
163
  const [doorPhoto, setDoorPhoto] = useState(null);
44
164
  const [isLocationFetching, setIsLocationFetching] = useState(false);
45
165
  const fileInputRef = useRef(null);
@@ -55,32 +175,23 @@ const AddressDetails = ({ isSection = false, onComplete, parentState }) => {
55
175
  ];
56
176
 
57
177
  const handleCompleteVerification = () => {
178
+ const payload = { addressType, fullAddress, flatNo, building, landmark, pincode, doorPhoto };
58
179
  if (onComplete) {
59
- onComplete({ addressType, fullAddress, flatNo, building, landmark, pincode, doorPhoto });
180
+ onComplete(payload);
60
181
  } else {
61
182
  const { kNumber, selectedOption, connectionDetails } = flowState;
62
183
  history.push("/digit-ui/employee/ekyc/property-info", {
63
- kNumber,
64
- selectedOption,
65
- connectionDetails,
66
- addressDetails: { addressType, fullAddress, flatNo, building, landmark, pincode, doorPhoto },
184
+ kNumber, selectedOption, connectionDetails, addressDetails: payload,
67
185
  });
68
186
  }
69
187
  };
70
188
 
71
189
  const handleCapture = (e) => {
72
190
  const file = e.target.files[0];
73
- if (file) {
74
- const reader = new FileReader();
75
- reader.onloadend = () => {
76
- setDoorPhoto(reader.result);
77
- };
78
- reader.readAsDataURL(file);
79
- }
80
- };
81
-
82
- const openGallery = () => {
83
- fileInputRef.current.click();
191
+ if (!file) return;
192
+ const reader = new FileReader();
193
+ reader.onloadend = () => setDoorPhoto(reader.result);
194
+ reader.readAsDataURL(file);
84
195
  };
85
196
 
86
197
  const removePhoto = () => {
@@ -93,98 +204,47 @@ const AddressDetails = ({ isSection = false, onComplete, parentState }) => {
93
204
  alert(t("GEOLOCATION_NOT_SUPPORTED") || "Geolocation is not supported by your browser");
94
205
  return;
95
206
  }
96
-
97
207
  setIsLocationFetching(true);
98
208
  navigator.geolocation.getCurrentPosition(
99
- async (position) => {
100
- const { latitude, longitude } = position.coords;
209
+ async ({ coords: { latitude, longitude } }) => {
101
210
  try {
102
- const response = await fetch(
211
+ const res = await fetch(
103
212
  `https://nominatim.openstreetmap.org/reverse?format=json&lat=${latitude}&lon=${longitude}&zoom=18&addressdetails=1`
104
213
  );
105
- if (!response.ok) throw new Error("Failed to fetch address");
106
- const data = await response.json();
107
-
108
- if (data && data.address) {
109
- const addr = [
110
- data.address?.amenity,
111
- data.address?.road,
112
- data.address?.neighbourhood,
113
- data.address?.suburb,
114
- data.address?.city,
115
- data.address?.state,
116
- data.address?.postcode,
117
- ]
118
- .filter(Boolean)
119
- .join(", ");
120
-
121
- setFullAddress(addr || "");
122
- setPincode(data.address?.postcode || "");
123
- setLandmark(data.address?.suburb || data.address?.neighbourhood || "");
124
- setFlatNo(data.address?.amenity || "");
214
+ if (!res.ok) throw new Error("Geocode failed");
215
+ const data = await res.json();
216
+ if (data?.address) {
217
+ const a = data.address;
218
+ setFullAddress([a.amenity, a.road, a.neighbourhood, a.suburb, a.city, a.state, a.postcode].filter(Boolean).join(", "));
219
+ setPincode(a.postcode || "");
220
+ setLandmark(a.suburb || a.neighbourhood || "");
221
+ setFlatNo(a.amenity || "");
125
222
  }
126
- } catch (error) {
127
- console.error("Error reverse geocoding:", error);
223
+ } catch (err) {
224
+ console.error("Reverse geocode error:", err);
128
225
  } finally {
129
226
  setIsLocationFetching(false);
130
227
  }
131
228
  },
132
- (error) => {
133
- console.error("Error getting location:", error);
229
+ (err) => {
230
+ console.error("Geolocation error:", err);
134
231
  setIsLocationFetching(false);
135
- alert(t("LOCATION_FETCH_FAILED") || "Failed to fetch your current location. Please ensure location permissions are granted.");
232
+ alert(t("LOCATION_FETCH_FAILED") || "Failed to fetch location. Please grant location permissions.");
136
233
  },
137
234
  { enableHighAccuracy: true, timeout: 10000, maximumAge: 0 }
138
235
  );
139
236
  };
140
237
 
141
- const FlagIcon = () => (
142
- <svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
143
- <path d="M14.4 6L13.6 4H5V21H7V14H12.6L13.4 16H20V6H14.4Z" fill="#2E9E8F" />
144
- </svg>
145
- );
146
-
147
- const IdCardIcon = () => (
148
- <svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
149
- <path
150
- d="M2 7V17C2 18.1 2.9 19 4 19H20C21.1 19 22 18.1 22 17V7C22 5.9 21.1 5 20 5H4C2.9 5 2 5.9 2 7ZM12 11H14V13H12V11ZM12 7H14V9H12V7ZM16 11H20V13H16V11ZM16 7H20V9H16V7ZM4 7H10V15H4V7ZM20 17H4V16H20V17Z"
151
- fill="#3D51B0"
152
- />
153
- </svg>
154
- );
155
-
156
- const CameraIcon = () => (
157
- <svg width="32" height="32" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
158
- <path
159
- d="M9 2L7.17 4H4C2.9 4 2 4.9 2 6V18C2 19.1 2.9 20 4 20H20C21.1 20 22 19.1 22 18V6C22 4.9 21.1 4 20 4H16.83L15 2H9ZM12 17C9.24 17 7 14.76 7 12C7 9.24 9.24 7 12 7C14.76 7 17 9.24 17 12C17 14.76 14.76 17 12 17ZM12 9C10.34 9 9 10.34 9 12C9 13.66 10.34 15 12 15C13.66 15 15 13.66 15 12C15 10.34 13.66 9 12 9Z"
160
- fill="#0068faff"
161
- />
162
- </svg>
163
- );
164
-
165
- const TargetIcon = () => (
166
- <svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
167
- <path
168
- d="M12 8C9.79 8 8 9.79 8 12C8 14.21 9.79 16 12 16C14.21 16 16 14.21 16 12C16 9.79 14.21 8 12 8ZM20.94 11C20.48 6.83 17.17 3.52 13 3.06V1H11V3.06C6.83 3.52 3.52 6.83 3.06 11H1V13H3.06C3.52 17.17 6.83 20.48 11 20.94V23H13V20.94C17.17 20.48 20.48 17.17 20.94 13H23V11H20.94ZM12 19C8.13 19 5 15.87 5 12C5 8.13 8.13 5 12 5C15.87 5 19 8.13 19 12C19 15.87 15.87 19 12 19Z"
169
- fill="#0068faff"
170
- />
171
- </svg>
172
- );
238
+ const renderContent = () => (
239
+ <div style={{ animation: "fadeSlideIn 0.3s ease" }}>
173
240
 
174
- const PincodeIcon = () => (
175
- <svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
176
- <path
177
- d="M13 13V11H15V13H13ZM13 9V7H15V9H13ZM17 13V11H19V13H17ZM17 9V7H19V9H17ZM11 13V11H9V13H11ZM11 9V7H9V9H11ZM7 13V11H5V13H7ZM7 9V7H5V9H7ZM21 3H3C1.9 3 1 3.9 1 5V19C1 20.1 1.9 21 3 21H21C22.1 21 23 20.1 23 19V5C23 3.9 22.1 3 21 3ZM21 19H3V5H21V19Z"
178
- fill="#0068faff"
241
+ {/* ── Address Type Toggle ── */}
242
+ <SectionHead
243
+ icon={<LocationIcon className="icon" styles={{ fill: "#0B0C0C", width: "16px", height: "16px" }} />}
244
+ label={t("EKYC_ADDRESS_DETAILS_HEADER") || "Address Details"}
179
245
  />
180
- </svg>
181
- );
182
246
 
183
- const renderContent = () => (
184
- <div style={{ animation: "fadeSlideIn 0.3s ease" }}>
185
- {isSection && <hr style={{ margin: "40px 0", border: "0", borderTop: "2px solid #EAECF0" }} />}
186
- <Header style={{ marginBottom: "24px" }}>{t("EKYC_ADDRESS_DETAILS_HEADER") || "Address Details"}</Header>
187
- <div style={{ marginBottom: "32px" }}>
247
+ <div style={{ marginBottom: "20px" }}>
188
248
  <RadioButtons
189
249
  options={addressOptions}
190
250
  optionsKey="name"
@@ -192,40 +252,40 @@ const AddressDetails = ({ isSection = false, onComplete, parentState }) => {
192
252
  onSelect={setAddressType}
193
253
  t={t}
194
254
  innerStyles={{ display: "flex", alignItems: "center" }}
195
- style={{ display: "flex", gap: "50px", justifyContent: "flex-start" }}
255
+ style={{ display: "flex", gap: "40px" }}
196
256
  />
197
257
  </div>
198
258
 
259
+ {/* ── Aadhaar Address display ── */}
199
260
  {addressType.code === "AADHAAR" && (
200
- <div
201
- style={{
202
- backgroundColor: "#F9FAFB",
203
- padding: "16px",
204
- borderRadius: "12px",
205
- marginBottom: "24px",
206
- border: "1px solid #EAECF0",
207
- display: "flex",
208
- alignItems: "flex-start",
209
- gap: "12px",
210
- animation: "fadeSlideIn 0.3s ease",
211
- }}
212
- >
213
- <div style={{ backgroundColor: "#E7F4EE", padding: "8px", borderRadius: "8px" }}>
214
- <LocationIcon className="icon" styles={{ fill: "#2E9E8F", width: "20px", height: "20px" }} />
261
+ <div style={{
262
+ backgroundColor: "#E1F5EE",
263
+ border: "0.5px solid #5DCAA5",
264
+ borderRadius: "8px",
265
+ padding: "14px 16px",
266
+ display: "flex",
267
+ alignItems: "flex-start",
268
+ gap: "12px",
269
+ marginBottom: "20px",
270
+ animation: "fadeSlideIn 0.3s ease",
271
+ }}>
272
+ <div style={{ backgroundColor: "#9FE1CB", padding: "6px", borderRadius: "6px", display: "flex", flexShrink: 0 }}>
273
+ <LocationIcon className="icon" styles={{ fill: "#085041", width: "16px", height: "16px" }} />
215
274
  </div>
216
- <div style={{ fontSize: "16px", lineHeight: "1.6", color: "#344054", fontWeight: "500" }}>
217
- H.No. 123, Sector 15, Rohini
218
- <br />
219
- Delhi - 110085
275
+ <div style={{ fontSize: "14px", lineHeight: "1.6", color: "#04342C", fontWeight: "500" }}>
276
+ {addrDetails.fullAddress || "H.No. 123, Sector 15, Rohini, Delhi – 110085"}
220
277
  </div>
221
278
  </div>
222
279
  )}
223
280
 
281
+ {/* ── Old / Custom Address ── */}
224
282
  {addressType.code === "OLD" && (
225
283
  <div style={{ animation: "fadeSlideIn 0.3s ease" }}>
226
- <div style={{ marginBottom: "24px" }}>
227
- <CardLabel style={{ marginBottom: "12px", fontWeight: "600", color: "#344054" }}>
228
- {t("EKYC_ADDRESS_CORRECTION_PROMPT") || "Do you want to correct the address?"}
284
+
285
+ {/* Correction toggle */}
286
+ <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between", marginBottom: "14px" }}>
287
+ <CardLabel style={{ fontWeight: "500", marginBottom: 0, fontSize: "13px", color: "#505A5F" }}>
288
+ {t("EKYC_ADDRESS_CORRECTION_PROMPT") || "Correct the address?"}
229
289
  </CardLabel>
230
290
  <RadioButtons
231
291
  options={yesNoOptions}
@@ -233,352 +293,361 @@ const AddressDetails = ({ isSection = false, onComplete, parentState }) => {
233
293
  selectedOption={correctAddress}
234
294
  onSelect={setCorrectAddress}
235
295
  t={t}
236
- innerStyles={{ display: "flex", alignItems: "center" }}
237
- style={{ display: "flex", gap: "50px", justifyContent: "flex-start" }}
296
+ innerStyles={{ display: "flex", gap: "20px" }}
297
+ style={{ marginBottom: 0 }}
238
298
  />
239
299
  </div>
240
300
 
301
+ {/* Use Current Location */}
241
302
  <div
303
+ onClick={!isLocationFetching ? handleUseCurrentLocation : undefined}
242
304
  style={{
243
- border: "1px solid #D0D5DD",
244
- borderRadius: "12px",
245
- padding: "14px 16px",
305
+ border: "0.5px solid #D0D5DD",
306
+ borderRadius: "8px",
307
+ padding: "12px 16px",
246
308
  display: "flex",
247
309
  alignItems: "center",
248
310
  justifyContent: "space-between",
249
- marginBottom: "24px",
311
+ marginBottom: "20px",
250
312
  cursor: isLocationFetching ? "not-allowed" : "pointer",
251
- backgroundColor: isLocationFetching ? "#F2F4F7" : "#FFFFFF",
252
- transition: "all 0.2s ease",
313
+ backgroundColor: isLocationFetching ? "#F9FAFB" : "#fff",
314
+ transition: "background 0.15s",
253
315
  opacity: isLocationFetching ? 0.7 : 1,
254
- boxShadow: "0px 1px 2px rgba(16, 24, 40, 0.05)",
255
316
  }}
256
- onClick={!isLocationFetching ? handleUseCurrentLocation : undefined}
257
- onMouseOver={(e) => (!isLocationFetching ? (e.currentTarget.style.backgroundColor = "#F9FAFB") : null)}
258
- onMouseOut={(e) => (!isLocationFetching ? (e.currentTarget.style.backgroundColor = "#FFFFFF") : null)}
317
+ onMouseOver={(e) => { if (!isLocationFetching) e.currentTarget.style.background = "#F9FAFB"; }}
318
+ onMouseOut={(e) => { if (!isLocationFetching) e.currentTarget.style.background = "#fff"; }}
259
319
  >
260
320
  <div style={{ display: "flex", alignItems: "center", gap: "12px" }}>
261
- <div style={{ backgroundColor: "#EEF4FF", padding: "8px", borderRadius: "8px" }}>
321
+ <div style={{ backgroundColor: "#E6F1FB", padding: "7px", borderRadius: "7px", display: "flex" }}>
262
322
  {isLocationFetching ? (
263
- <div
264
- className="location-loader"
265
- style={{
266
- width: "20px",
267
- height: "20px",
268
- border: "2px solid #0068faff",
269
- borderTopColor: "transparent",
270
- borderRadius: "50%",
271
- animation: "spin 1s linear infinite",
272
- }}
273
- ></div>
323
+ <div style={{
324
+ width: "18px", height: "18px", border: "2px solid #185FA5",
325
+ borderTopColor: "transparent", borderRadius: "50%",
326
+ animation: "spin 1s linear infinite",
327
+ }} />
274
328
  ) : (
275
- <TargetIcon />
329
+ <TargetIcon size={18} />
276
330
  )}
277
331
  </div>
278
- <span style={{ fontWeight: "600", color: "#344054" }}>
332
+ <span style={{ fontWeight: "500", fontSize: "14px", color: "#344054" }}>
279
333
  {isLocationFetching
280
- ? t("EKYC_FETCHING_LOCATION") || "Fetching Location..."
281
- : t("EKYC_USE_CURRENT_LOCATION") || "Use Current Location"}
334
+ ? t("EKYC_FETCHING_LOCATION") || "Fetching location..."
335
+ : t("EKYC_USE_CURRENT_LOCATION") || "Use current location"}
282
336
  </span>
283
337
  </div>
284
- {!isLocationFetching && <span style={{ fontSize: "20px", color: "#98A2B3" }}>›</span>}
338
+ {!isLocationFetching && (
339
+ <span style={{ fontSize: "18px", color: "#98A2B3", lineHeight: 1 }}>›</span>
340
+ )}
341
+ </div>
342
+
343
+ {/* Full Address (textarea-style) */}
344
+ <div style={{ marginBottom: "14px" }}>
345
+ <div style={{ fontSize: "11px", fontWeight: "600", color: "#667085", textTransform: "uppercase", letterSpacing: "0.04em", marginBottom: "6px" }}>
346
+ {t("EKYC_FULL_ADDRESS") || "Full address"}
347
+ </div>
348
+ <IconInput
349
+ icon={<PropertyHouse styles={{ fill: "#0068fa", width: "15px", height: "15px" }} />}
350
+ topAligned
351
+ value={fullAddress}
352
+ onChange={(e) => setFullAddress(e.target.value)}
353
+ placeholder={t("EKYC_ENTER_FULL_ADDRESS") || "Enter full address"}
354
+ inputStyle={{ minHeight: "72px" }}
355
+ />
285
356
  </div>
286
357
 
287
- <LabelFieldPair>
288
- <CardLabel style={{ fontWeight: "600" }}>{t("EKYC_FULL_ADDRESS") || "Full Address"}</CardLabel>
289
- <div className="field" style={{ position: "relative" }}>
290
- <div style={{ position: "absolute", left: "12px", top: "16px", zIndex: 1, opacity: 0.6 }}>
291
- <PropertyHouse styles={{ fill: "#0068faff", width: "20px", height: "20px" }} />
358
+ {/* Flat + Building */}
359
+ <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: "14px", marginBottom: "14px" }}>
360
+ <div>
361
+ <div style={{ fontSize: "11px", fontWeight: "600", color: "#667085", textTransform: "uppercase", letterSpacing: "0.04em", marginBottom: "6px" }}>
362
+ {t("EKYC_FLAT_HOUSE_NUMBER") || "Flat / House no."}
292
363
  </div>
293
- <TextInput
294
- value={fullAddress}
295
- onChange={(e) => setFullAddress(e.target.value)}
296
- placeholder={t("EKYC_ENTER_FULL_ADDRESS") || "Enter Full Address"}
297
- textInputStyle={{ paddingLeft: "40px", minHeight: "80px" }}
364
+ <IconInput
365
+ icon={<PropertyHouse styles={{ fill: "#0068fa", width: "15px", height: "15px" }} />}
366
+ value={flatNo}
367
+ onChange={(e) => setFlatNo(e.target.value)}
368
+ placeholder={t("EKYC_ENTER_FLAT_NO") || "e.g. 45-B"}
298
369
  />
299
370
  </div>
300
- </LabelFieldPair>
301
-
302
- <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: "24px" }}>
303
- <LabelFieldPair>
304
- <CardLabel style={{ fontWeight: "600" }}>{t("EKYC_FLAT_HOUSE_NUMBER") || "Flat/House Number"}</CardLabel>
305
- <div className="field" style={{ position: "relative" }}>
306
- <div style={{ position: "absolute", left: "12px", top: "50%", transform: "translateY(-50%)", zIndex: 1, opacity: 0.6 }}>
307
- <PropertyHouse styles={{ fill: "#0068faff", width: "20px", height: "20px" }} />
308
- </div>
309
- <TextInput
310
- value={flatNo}
311
- onChange={(e) => setFlatNo(e.target.value)}
312
- placeholder={t("EKYC_ENTER_FLAT_NO") || "e.g. 45-B"}
313
- textInputStyle={{ paddingLeft: "40px" }}
314
- />
315
- </div>
316
- </LabelFieldPair>
317
- <LabelFieldPair>
318
- <CardLabel style={{ fontWeight: "600" }}>{t("EKYC_BUILDING_TOWER") || "Building/Tower"}</CardLabel>
319
- <div className="field" style={{ position: "relative" }}>
320
- <div style={{ position: "absolute", left: "12px", top: "50%", transform: "translateY(-50%)", zIndex: 1, opacity: 0.6 }}>
321
- <PropertyHouse styles={{ fill: "#0068faff", width: "20px", height: "20px" }} />
322
- </div>
323
- <TextInput
324
- value={building}
325
- onChange={(e) => setBuilding(e.target.value)}
326
- placeholder={t("EKYC_ENTER_BUILDING") || "e.g. Tower 4"}
327
- textInputStyle={{ paddingLeft: "40px" }}
328
- />
371
+ <div>
372
+ <div style={{ fontSize: "11px", fontWeight: "600", color: "#667085", textTransform: "uppercase", letterSpacing: "0.04em", marginBottom: "6px" }}>
373
+ {t("EKYC_BUILDING_TOWER") || "Building / Tower"}
329
374
  </div>
330
- </LabelFieldPair>
375
+ <IconInput
376
+ icon={<PropertyHouse styles={{ fill: "#0068fa", width: "15px", height: "15px" }} />}
377
+ value={building}
378
+ onChange={(e) => setBuilding(e.target.value)}
379
+ placeholder={t("EKYC_ENTER_BUILDING") || "e.g. Tower 4"}
380
+ />
381
+ </div>
331
382
  </div>
332
383
 
333
- <LabelFieldPair>
334
- <CardLabel style={{ fontWeight: "600" }}>{t("EKYC_LANDMARK") || "Landmark"}</CardLabel>
335
- <div className="field" style={{ position: "relative" }}>
336
- <div style={{ position: "absolute", left: "12px", top: "50%", transform: "translateY(-50%)", zIndex: 1, opacity: 0.6 }}>
337
- <LocationIcon className="icon" styles={{ fill: "#0068faff", width: "20px", height: "20px" }} />
384
+ {/* Landmark + Pincode */}
385
+ <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: "14px", marginBottom: "4px" }}>
386
+ <div>
387
+ <div style={{ fontSize: "11px", fontWeight: "600", color: "#667085", textTransform: "uppercase", letterSpacing: "0.04em", marginBottom: "6px" }}>
388
+ {t("EKYC_LANDMARK") || "Landmark"}
338
389
  </div>
339
- <TextInput
390
+ <IconInput
391
+ icon={<LocationIcon className="icon" styles={{ fill: "#0068fa", width: "15px", height: "15px" }} />}
340
392
  value={landmark}
341
393
  onChange={(e) => setLandmark(e.target.value)}
342
394
  placeholder={t("EKYC_ENTER_LANDMARK") || "Near Central Park"}
343
- textInputStyle={{ paddingLeft: "40px" }}
344
395
  />
345
396
  </div>
346
- </LabelFieldPair>
347
-
348
- <LabelFieldPair>
349
- <CardLabel style={{ fontWeight: "600" }}>{t("EKYC_PINCODE") || "Pincode"}</CardLabel>
350
- <div className="field" style={{ position: "relative" }}>
351
- <div style={{ position: "absolute", left: "12px", top: "50%", transform: "translateY(-50%)", zIndex: 1, opacity: 0.6 }}>
352
- <PincodeIcon />
397
+ <div>
398
+ <div style={{ fontSize: "11px", fontWeight: "600", color: "#667085", textTransform: "uppercase", letterSpacing: "0.04em", marginBottom: "6px" }}>
399
+ {t("EKYC_PINCODE") || "Pincode"}
353
400
  </div>
354
- <TextInput
401
+ <IconInput
402
+ icon={<PincodeIcon size={15} />}
355
403
  value={pincode}
356
- onChange={(e) => setPincode(e.target.value)}
404
+ onChange={(e) => { if (/^\d*$/.test(e.target.value)) setPincode(e.target.value); }}
357
405
  placeholder={t("EKYC_ENTER_PINCODE") || "6-digit pincode"}
358
- textInputStyle={{ paddingLeft: "40px" }}
359
406
  maxLength={6}
360
407
  />
361
408
  </div>
362
- </LabelFieldPair>
409
+ </div>
363
410
  </div>
364
411
  )}
365
412
 
366
- <hr style={{ margin: "32px 0", border: "0", borderTop: "1px solid #EAECF0" }} />
413
+ <hr style={{ margin: "24px 0", border: 0, borderTop: "1px solid #EAECF0" }} />
367
414
 
368
- <div style={{ display: "flex", alignItems: "center", gap: "10px", marginBottom: "20px" }}>
369
- <div style={{ backgroundColor: "#EEF4FF", padding: "8px", borderRadius: "8px" }}>
370
- <PropertyHouse styles={{ fill: "#0068faff", width: "24px", height: "24px" }} />
371
- </div>
372
- <CardHeader style={{ margin: 0, fontSize: "20px" }}>{t("EKYC_ADMINISTRATIVE_DIVISION") || "Administrative Division"}</CardHeader>
373
- </div>
415
+ {/* ── Administrative Division ── */}
416
+ <SectionHead
417
+ icon={<PropertyHouse styles={{ fill: "#0B0C0C", width: "16px", height: "16px" }} />}
418
+ label={t("EKYC_ADMINISTRATIVE_DIVISION") || "Administrative Division"}
419
+ />
374
420
 
375
- <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: "24px", marginBottom: "32px" }}>
376
- <div
377
- style={{
378
- backgroundColor: "#F9FAFB",
379
- padding: "16px",
380
- borderRadius: "12px",
381
- display: "flex",
382
- alignItems: "center",
383
- gap: "16px",
384
- border: "1px solid #EAECF0",
385
- }}
386
- >
387
- <div style={{ backgroundColor: "#E7F4EE", padding: "10px", borderRadius: "10px", display: "flex" }}>
388
- <FlagIcon />
389
- </div>
390
- <div>
391
- <div style={{ color: "#2E9E8F", fontSize: "12px", fontWeight: "700", textTransform: "uppercase", letterSpacing: "0.5px" }}>
392
- {t("EKYC_ASSEMBLY") || "ASSEMBLY"}
393
- </div>
394
- <div style={{ fontSize: "15px", fontWeight: "700", color: "#101828", marginTop: "2px" }}>AC-12 Chandni Chowk</div>
395
- </div>
396
- </div>
397
- <div
398
- style={{
399
- backgroundColor: "#F9FAFB",
400
- padding: "16px",
401
- borderRadius: "12px",
402
- display: "flex",
403
- alignItems: "center",
404
- gap: "16px",
405
- border: "1px solid #EAECF0",
406
- }}
407
- >
408
- <div style={{ backgroundColor: "#EEF4FF", padding: "10px", borderRadius: "10px", display: "flex" }}>
409
- <IdCardIcon />
410
- </div>
411
- <div>
412
- <div style={{ color: "#0068faff", fontSize: "12px", fontWeight: "700", textTransform: "uppercase", letterSpacing: "0.5px" }}>
413
- {t("EKYC_WARD") || "WARD"}
414
- </div>
415
- <div style={{ fontSize: "15px", fontWeight: "700", color: "#101828", marginTop: "2px" }}>WARD-45 Civil Lines</div>
416
- </div>
417
- </div>
421
+ <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: "14px", marginBottom: "24px" }}>
422
+ <AdminCard
423
+ bgColor="#E1F5EE"
424
+ iconBg="#9FE1CB"
425
+ icon={<FlagIcon size={18} />}
426
+ labelColor="#0F6E56"
427
+ label={t("EKYC_ASSEMBLY") || "Assembly"}
428
+ value={addrDetails.assembly || "AC-12 Chandni Chowk"}
429
+ />
430
+ <AdminCard
431
+ bgColor="#E6F1FB"
432
+ iconBg="#B5D4F4"
433
+ icon={<IdCardIcon size={18} />}
434
+ labelColor="#185FA5"
435
+ label={t("EKYC_WARD") || "Ward"}
436
+ value={addrDetails.ward || "WARD-45 Civil Lines"}
437
+ />
418
438
  </div>
419
439
 
420
- <CardHeader style={{ fontSize: "18px", color: "#101828", marginBottom: "4px" }}>
421
- {t("EKYC_DOOR_PHOTO_HEADER") || "Door Photo with GPS Stamp"}
422
- </CardHeader>
423
- <div style={{ color: "#667085", fontSize: "14px", marginBottom: "16px" }}>
440
+ <hr style={{ margin: "24px 0", border: 0, borderTop: "1px solid #EAECF0" }} />
441
+
442
+ {/* ── Door Photo ── */}
443
+ <SectionHead
444
+ icon={<CameraIcon size={16} />}
445
+ label={t("EKYC_DOOR_PHOTO_HEADER") || "Door photo with GPS stamp"}
446
+ />
447
+
448
+ <div style={{ fontSize: "12px", color: "#667085", marginBottom: "12px" }}>
424
449
  {t("EKYC_REQUIRED_FOR_VERIFICATION") || "Required for verification"}
425
450
  </div>
426
451
 
427
- <div
428
- style={{
429
- backgroundColor: "#FFFAEB",
430
- padding: "14px",
431
- borderRadius: "12px",
432
- display: "flex",
433
- alignItems: "center",
434
- gap: "12px",
435
- marginBottom: "20px",
436
- border: "1px solid #FEDF89",
437
- }}
438
- >
439
- <InfoBannerIcon fill="#B54708" />
452
+ {/* Warning banner */}
453
+ <div style={{
454
+ backgroundColor: "#FFFAEB",
455
+ border: "0.5px solid #FEDF89",
456
+ borderRadius: "8px",
457
+ padding: "12px 14px",
458
+ display: "flex",
459
+ alignItems: "flex-start",
460
+ gap: "10px",
461
+ marginBottom: "16px",
462
+ }}>
463
+ <div style={{ flexShrink: 0, marginTop: "1px" }}>
464
+ <InfoBannerIcon fill="#B54708" />
465
+ </div>
440
466
  <div>
441
- <div style={{ fontWeight: "700", color: "#B54708", fontSize: "14px" }}>{t("EKYC_IMPORTANT") || "Important"}</div>
442
- <div style={{ fontSize: "13px", color: "#B54708", marginTop: "2px" }}>
467
+ <div style={{ fontWeight: "600", color: "#B54708", fontSize: "13px", marginBottom: "2px" }}>
468
+ {t("EKYC_IMPORTANT") || "Important"}
469
+ </div>
470
+ <div style={{ fontSize: "12px", color: "#92400E" }}>
443
471
  {t("EKYC_CAPTURE_LIVE_CAMERA") || "Capture with live camera for GPS metadata"}
444
472
  </div>
445
473
  </div>
446
474
  </div>
447
475
 
476
+ {/* Drop zone */}
477
+ <input
478
+ type="file"
479
+ ref={fileInputRef}
480
+ onChange={handleCapture}
481
+ accept="image/*"
482
+ style={{ display: "none" }}
483
+ />
448
484
  <div
485
+ onClick={!doorPhoto ? () => fileInputRef.current.click() : undefined}
486
+ onMouseOver={(e) => { if (!doorPhoto) e.currentTarget.style.borderColor = "#185FA5"; }}
487
+ onMouseOut={(e) => { if (!doorPhoto) e.currentTarget.style.borderColor = "#D0D5DD"; }}
449
488
  style={{
450
- border: "2px dashed #D0D5DD",
451
- borderRadius: "16px",
452
- padding: doorPhoto ? "12px" : "40px 24px",
453
- textAlign: "center",
454
- cursor: "pointer",
455
- position: "relative",
456
- overflow: "hidden",
457
- minHeight: "180px",
489
+ border: "1.5px dashed #D0D5DD",
490
+ borderRadius: "10px",
491
+ minHeight: "160px",
458
492
  display: "flex",
459
493
  flexDirection: "column",
460
494
  alignItems: "center",
461
495
  justifyContent: "center",
462
496
  backgroundColor: "#F9FAFB",
463
- transition: "all 0.2s ease",
464
- boxShadow: "inset 0px 2px 4px rgba(0, 0, 0, 0.02)",
497
+ cursor: doorPhoto ? "default" : "pointer",
498
+ overflow: "hidden",
499
+ transition: "border-color 0.15s",
500
+ position: "relative",
501
+ padding: doorPhoto ? "0" : "32px 24px",
465
502
  }}
466
- onClick={!doorPhoto ? openGallery : undefined}
467
- onMouseOver={(e) => (!doorPhoto ? (e.currentTarget.style.borderColor = "#0068faff") : null)}
468
- onMouseOut={(e) => (!doorPhoto ? (e.currentTarget.style.borderColor = "#D0D5DD") : null)}
469
503
  >
470
- <input type="file" ref={fileInputRef} onChange={handleCapture} accept="image/*" style={{ display: "none" }} />
471
504
  {!doorPhoto ? (
472
505
  <>
473
- <div
474
- style={{
475
- backgroundColor: "#FFFFFF",
476
- width: "64px",
477
- height: "64px",
478
- borderRadius: "50%",
479
- display: "flex",
480
- alignItems: "center",
481
- justifyContent: "center",
482
- margin: "0 auto 16px",
483
- boxShadow: "0px 1px 3px rgba(16, 24, 40, 0.1)",
484
- }}
485
- >
486
- <CameraIcon />
506
+ <div style={{
507
+ width: "52px", height: "52px", borderRadius: "50%",
508
+ background: "#E6F1FB", display: "flex",
509
+ alignItems: "center", justifyContent: "center", marginBottom: "12px",
510
+ }}>
511
+ <CameraIcon size={26} />
512
+ </div>
513
+ <div style={{ fontWeight: "600", fontSize: "14px", color: "#101828", marginBottom: "4px" }}>
514
+ {t("EKYC_TAP_TO_CAPTURE") || "Tap to capture"}
487
515
  </div>
488
- <div style={{ fontWeight: "700", fontSize: "16px", marginBottom: "4px", color: "#101828" }}>
489
- {t("EKYC_TAP_TO_CAPTURE") || "Tap to Capture"}
516
+ <div style={{ fontSize: "12px", color: "#667085" }}>
517
+ {t("EKYC_CAPTURE_DOOR_IMAGE") || "Capture door image"}
490
518
  </div>
491
- <div style={{ color: "#667085", fontSize: "14px" }}>{t("EKYC_CAPTURE_DOOR_IMAGE") || "Capture Door Image"}</div>
492
519
  </>
493
520
  ) : (
494
- <div style={{ position: "relative", width: "100%", height: "100%", display: "flex", justifyContent: "center" }}>
521
+ <>
495
522
  <img
496
523
  src={doorPhoto}
497
524
  alt="Door"
498
- style={{ width: "100%", maxHeight: "300px", objectFit: "cover", borderRadius: "12px", display: "block" }}
525
+ style={{ width: "100%", maxHeight: "280px", objectFit: "cover", display: "block" }}
499
526
  />
500
- <div style={{ position: "absolute", top: "12px", right: "12px" }}>
501
- <button
502
- onClick={(e) => {
503
- e.stopPropagation();
504
- removePhoto();
505
- }}
506
- style={{
507
- background: "#FFFFFF",
508
- border: "1px solid #EAECF0",
509
- borderRadius: "8px",
510
- padding: "8px",
511
- display: "flex",
512
- boxShadow: "0px 1px 2px rgba(16, 24, 40, 0.05)",
513
- cursor: "pointer",
514
- }}
515
- >
516
- <RemoveableTag text="" onClick={() => {}} extraStyles={{ tagStyles: { margin: 0, padding: 0 } }} />
517
- </button>
518
- </div>
519
- </div>
527
+ <button
528
+ onClick={(e) => { e.stopPropagation(); removePhoto(); }}
529
+ style={{
530
+ position: "absolute", top: "10px", right: "10px",
531
+ background: "#fff", border: "0.5px solid #EAECF0",
532
+ borderRadius: "7px", padding: "6px 10px",
533
+ display: "flex", alignItems: "center", gap: "5px",
534
+ cursor: "pointer", fontSize: "12px", color: "#D92D20", fontWeight: "500",
535
+ }}
536
+ >
537
+ <TrashIcon size={13} /> {t("EKYC_REMOVE") || "Remove"}
538
+ </button>
539
+ </>
520
540
  )}
521
541
  </div>
522
542
 
523
- <ActionBar>
524
- <SubmitBar
525
- label={
526
- isSection
527
- ? t("EKYC_COMPLETE_VERIFICATION_AND_PROCEED") || "Complete & Proceed"
528
- : t("EKYC_COMPLETE_VERIFICATION") || "Complete Verification"
529
- }
530
- onSubmit={handleCompleteVerification}
531
- />
532
- </ActionBar>
543
+ {/* Submit */}
544
+ {isSection ? (
545
+ <div style={{ marginTop: "24px" }}>
546
+ <SubmitBar
547
+ label={t("EKYC_COMPLETE_VERIFICATION_AND_PROCEED") || "Complete & Proceed"}
548
+ onSubmit={handleCompleteVerification}
549
+ />
550
+ </div>
551
+ ) : (
552
+ <ActionBar>
553
+ <SubmitBar
554
+ label={t("EKYC_COMPLETE_VERIFICATION") || "Complete Verification"}
555
+ onSubmit={handleCompleteVerification}
556
+ />
557
+ </ActionBar>
558
+ )}
559
+
560
+ {/* Secure notice */}
561
+ <div style={{
562
+ display: "flex", alignItems: "center", justifyContent: "center",
563
+ gap: "5px", marginTop: "16px",
564
+ fontSize: "11px", color: "#98A2B3",
565
+ }}>
566
+ <svg width="11" height="11" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round">
567
+ <rect x="3" y="11" width="18" height="11" rx="2" />
568
+ <path d="M7 11V7a5 5 0 0 1 10 0v4" />
569
+ </svg>
570
+ {t("EKYC_SECURE_DATA_NOTICE") || "Your data is encrypted and secure"}
571
+ </div>
533
572
  </div>
534
573
  );
535
574
 
536
- if (isSection) return renderContent();
575
+ // ── When rendered as inline section inside AadhaarVerification ──
576
+ if (isSection) {
577
+ return (
578
+ <Fragment>
579
+ <hr style={{ margin: "32px 0", border: 0, borderTop: "2px solid #EAECF0" }} />
580
+ {renderContent()}
581
+ </Fragment>
582
+ );
583
+ }
537
584
 
585
+ // ── When rendered as a standalone page ──
538
586
  return (
539
587
  <div className="inbox-container">
540
588
  <style>{`
541
- @keyframes spin { to { transform: rotate(360deg); } }
542
- @keyframes fadeSlideIn { from { opacity:0; transform:translateY(10px); } to { opacity:1; transform:translateY(0); } }
543
- `}</style>
589
+ @keyframes spin { to { transform: rotate(360deg); } }
590
+ @keyframes fadeSlideIn { from { opacity:0; transform:translateY(8px); } to { opacity:1; transform:translateY(0); } }
591
+ `}</style>
544
592
 
593
+ {/* Sidebar */}
545
594
  <div className="filters-container">
546
- {/* Sidebar Title Card */}
547
- <Card
548
- className="sidebar-title-card"
549
- style={{ display: "flex", alignItems: "center", padding: "16px", marginBottom: "16px", borderRadius: "4px" }}
550
- >
551
- <div className="icon-container" style={{ color: "#0068faff", marginRight: "12px" }}>
552
- <HomeIcon style={{ width: "24px", height: "24px" }} />
595
+ <Card style={{ display: "flex", alignItems: "center", padding: "12px 16px", marginBottom: "12px", borderRadius: "8px" }}>
596
+ <div style={{ color: "#185FA5", marginRight: "10px", display: "flex" }}>
597
+ <HomeIcon style={{ width: "20px", height: "20px" }} />
598
+ </div>
599
+ <div style={{ fontWeight: "600", fontSize: "15px", color: "#0B0C0C" }}>
600
+ {t("EKYC_PROCESS") || "eKYC Process"}
553
601
  </div>
554
- <div style={{ fontWeight: "700", fontSize: "18px", color: "#0B0C0C" }}>{t("EKYC_PROCESS")}</div>
555
602
  </Card>
556
603
 
557
- {/* Progress Steps Sidebar */}
558
- <div
559
- style={{
560
- backgroundColor: "#FFFFFF",
561
- padding: "16px",
562
- borderRadius: "8px",
563
- border: "1px solid #EAECF0",
564
- boxShadow: "0 2px 4px rgba(0,0,0,0.02)",
565
- }}
566
- >
567
- <ConnectingCheckPoints>
568
- <CheckPoint label={t("EKYC_STEP_AADHAAR") || "Aadhaar"} isCompleted={true} />
569
- <CheckPoint label={t("EKYC_STEP_ADDRESS") || "Address"} isCompleted={true} />
570
- <CheckPoint label={t("EKYC_STEP_PROPERTY") || "Property"} isCompleted={false} />
571
- <CheckPoint label={t("EKYC_STEP_REVIEW") || "Review"} />
572
- </ConnectingCheckPoints>
604
+ <div style={{ background: "#fff", padding: "16px 14px", borderRadius: "8px", border: "1px solid #EAECF0" }}>
605
+ {[
606
+ { label: t("EKYC_STEP_AADHAAR") || "Aadhaar", done: true, active: false },
607
+ { label: t("EKYC_STEP_ADDRESS") || "Address", done: false, active: true },
608
+ { label: t("EKYC_STEP_PROPERTY") || "Property", done: false, active: false },
609
+ { label: t("EKYC_STEP_REVIEW") || "Review", done: false, active: false },
610
+ ].map((step, i) => (
611
+ <div key={i} style={{ display: "flex", gap: "10px", alignItems: "flex-start", position: "relative", paddingBottom: i < 3 ? "18px" : 0 }}>
612
+ {i < 3 && (
613
+ <div style={{ position: "absolute", left: "10px", top: "22px", width: "1px", height: "calc(100% - 10px)", background: "#EAECF0" }} />
614
+ )}
615
+ <div style={{
616
+ width: "20px", height: "20px", borderRadius: "50%", flexShrink: 0, marginTop: "1px",
617
+ border: step.done ? "none" : step.active ? "1.5px solid #185FA5" : "1.5px solid #D0D5DD",
618
+ background: step.done ? "#0F6E56" : step.active ? "#E6F1FB" : "#fff",
619
+ display: "flex", alignItems: "center", justifyContent: "center",
620
+ fontSize: "10px", fontWeight: "500",
621
+ color: step.done ? "#fff" : step.active ? "#185FA5" : "#98A2B3",
622
+ }}>
623
+ {step.done ? <CheckIcon size={11} color="#fff" /> : i + 1}
624
+ </div>
625
+ <div style={{
626
+ fontSize: "12px", paddingTop: "2px",
627
+ color: step.done ? "#0F6E56" : step.active ? "#0B0C0C" : "#667085",
628
+ fontWeight: step.done || step.active ? "600" : "400",
629
+ }}>
630
+ {step.label}
631
+ </div>
632
+ </div>
633
+ ))}
573
634
  </div>
574
635
  </div>
575
636
 
637
+ {/* Main */}
576
638
  <div style={{ flex: 1, marginLeft: "16px" }}>
577
639
  <Card>
578
- <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", marginBottom: "24px" }}>
579
- <Header>{t("EKYC_ADDRESS_DETAILS_HEADER") || "Address Details"}</Header>
580
- <div style={{ fontSize: "14px", fontWeight: "700", color: "#505A5F" }}>
581
- {t("EKYC_K_NUMBER")}: <span style={{ color: "#0B0C0C" }}>{flowState?.kNumber}</span>
640
+ <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", marginBottom: "20px" }}>
641
+ <CardHeader style={{ margin: 0, fontSize: "18px" }}>
642
+ {t("EKYC_ADDRESS_DETAILS_HEADER") || "Address Details"}
643
+ </CardHeader>
644
+ <div style={{
645
+ background: "#F9FAFB", border: "0.5px solid #EAECF0",
646
+ borderRadius: "20px", padding: "4px 14px",
647
+ fontSize: "12px", color: "#667085",
648
+ }}>
649
+ {t("EKYC_K_NUMBER") || "K Number"}:{" "}
650
+ <span style={{ color: "#0B0C0C", fontWeight: "600" }}>{flowState?.kNumber}</span>
582
651
  </div>
583
652
  </div>
584
653
  {renderContent()}
@@ -588,4 +657,4 @@ const AddressDetails = ({ isSection = false, onComplete, parentState }) => {
588
657
  );
589
658
  };
590
659
 
591
- export default AddressDetails;
660
+ export default AddressDetails;