@djb25/digit-ui-module-ekyc 1.0.30 → 1.0.32

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.
Files changed (63) hide show
  1. package/dist/index.js +8911 -1
  2. package/dist/index.js.map +1 -1
  3. package/dist/index.modern.js +3295 -2039
  4. package/dist/index.modern.js.map +1 -1
  5. package/package.json +4 -1
  6. package/dist/index.css +0 -54
  7. package/src/Module.js +0 -78
  8. package/src/components/AadhaarVerification.js +0 -315
  9. package/src/components/AssignEkyc.js +0 -236
  10. package/src/components/AssignEkycModal.js +0 -446
  11. package/src/components/CeoDashboard.js +0 -264
  12. package/src/components/CeoDashboard.jsx +0 -334
  13. package/src/components/ConnectionDetailsView.js +0 -241
  14. package/src/components/Dashboard.js +0 -43
  15. package/src/components/DesktopInbox.js +0 -176
  16. package/src/components/EKYCCard.js +0 -53
  17. package/src/components/Filter.js +0 -55
  18. package/src/components/MeterDetails.js +0 -336
  19. package/src/components/MobileInbox.js +0 -73
  20. package/src/components/PropertyInfo.js +0 -264
  21. package/src/components/Review.js +0 -696
  22. package/src/components/SearchConsumer.js +0 -142
  23. package/src/components/SearchFormFieldsComponent.js +0 -67
  24. package/src/components/SelectEkycZones.js +0 -71
  25. package/src/components/StatusCards.js +0 -148
  26. package/src/components/SurveyorDetailsCard.js +0 -512
  27. package/src/components/VendorDetails.jsx +0 -230
  28. package/src/components/analytics/charts/ClusterHeatmap.js +0 -88
  29. package/src/components/analytics/charts/ExecutiveBarChart.jsx +0 -30
  30. package/src/components/analytics/charts/ExecutiveLineChart.jsx +0 -159
  31. package/src/components/analytics/charts/ExecutivePieChart.jsx +0 -24
  32. package/src/components/analytics/charts/TaskStatusChart.js +0 -90
  33. package/src/components/analytics/components/AnalyticsTable.js +0 -106
  34. package/src/components/analytics/components/DashboardLayout.js +0 -52
  35. package/src/components/analytics/components/EmptyState.js +0 -27
  36. package/src/components/analytics/components/ErrorBoundary.js +0 -27
  37. package/src/components/analytics/components/FilterBar.js +0 -73
  38. package/src/components/analytics/components/NotificationPanel.js +0 -77
  39. package/src/components/analytics/components/SLAWidget.js +0 -56
  40. package/src/components/analytics/components/SkeletonLoader.js +0 -53
  41. package/src/components/analytics/components/SummaryCard.js +0 -74
  42. package/src/components/analytics/components/WorkflowTimeline.js +0 -55
  43. package/src/components/analytics/utils/exportUtils.js +0 -64
  44. package/src/components/analytics/utils/filterSerializer.js +0 -50
  45. package/src/components/mockData.js +0 -772
  46. package/src/config/AadhaarVerificationConfig.js +0 -367
  47. package/src/config/MeterDetailsConfig.js +0 -297
  48. package/src/config/PropertyInfoConfig.js +0 -145
  49. package/src/config/config.js +0 -70
  50. package/src/hook/SupervisorInboxTableConfig.js +0 -80
  51. package/src/hook/useInboxTableConfig.js +0 -131
  52. package/src/pages/citizen/Home.js +0 -54
  53. package/src/pages/citizen/Inbox.js +0 -265
  54. package/src/pages/citizen/index.js +0 -199
  55. package/src/pages/employee/ConsumerDetails.js +0 -299
  56. package/src/pages/employee/Create.js +0 -94
  57. package/src/pages/employee/EKYCForm.js +0 -118
  58. package/src/pages/employee/Inbox.js +0 -266
  59. package/src/pages/employee/Mapping.js +0 -358
  60. package/src/pages/employee/Update.js +0 -9
  61. package/src/pages/employee/index.js +0 -184
  62. package/src/utils/index.js +0 -46
  63. package/src/utils/reportDownloader.js +0 -90
@@ -1,446 +0,0 @@
1
- import React, { useMemo, useState, useEffect } from "react";
2
- import { Modal, Close, Table, Toast } from "@djb25/digit-ui-react-components";
3
- import { useTranslation } from "react-i18next";
4
-
5
- const AssignEkycModal = ({ surveyor, closeModal, refetchDashboard }) => {
6
- const { t } = useTranslation();
7
- const [selectedKnos, setSelectedKnos] = useState([]);
8
- const [isBulkSelection, setIsBulkSelection] = useState(false);
9
- const [currentPage, setCurrentPage] = useState(0);
10
- const [pageSize, setPageSize] = useState(10);
11
- const [showToast, setShowToast] = useState(false);
12
- const [toastData, setToastData] = useState({
13
- error: false,
14
- label: "",
15
- });
16
- const [filters, setFilters] = useState({
17
- kno: "", // search value
18
- pincode: "",
19
- zoneCode: "",
20
- zoneName: "",
21
- ward: "",
22
- assembly: "",
23
- mrkey: "",
24
- ekycStatus: "",
25
- });
26
-
27
- const [debouncedFilters, setDebouncedFilters] = useState(filters);
28
-
29
- const { data: zroLocationsData, isLoading: isZroLoading } = Digit.Hooks.ws.useWSConfigMDMS.ZROLocation("dl.djb");
30
- const mappedZROLocation = useMemo(() => {
31
- return (zroLocationsData || []).map((item) => ({
32
- code: item.code,
33
- name: item.name,
34
- }));
35
- }, [zroLocationsData]);
36
-
37
- const { data: egovLocationData } = Digit.Hooks.useCommonMDMS("dl.djb", "egov-location", ["TenantBoundary"]);
38
-
39
- const boundaryData = useMemo(() => {
40
- const tenantBoundary = egovLocationData?.["egov-location"]?.TenantBoundary || [];
41
- const revenueData = tenantBoundary.find((item) => item?.hierarchyType?.code === "REVENUE");
42
- const boundary = revenueData?.boundary || [];
43
- return Array.isArray(boundary) ? boundary : [boundary];
44
- }, [egovLocationData]);
45
-
46
- const { assemblyOptions, wardOptions } = useMemo(() => {
47
- const assemblies = new Map();
48
- const wards = new Map();
49
-
50
- const boundaries = Array.isArray(boundaryData) ? boundaryData : boundaryData ? [boundaryData] : [];
51
-
52
- const traverse = (node) => {
53
- if (!node) return;
54
- if (node.label === "Ward" || node.label === "WARD" || node.label === "Block" || node.label === "BLOCK") {
55
- const code = node.code || node.localname || node.name;
56
- const name = node.name || node.localname || code;
57
- if (code) wards.set(code, { code, name: name });
58
- }
59
- if (node.label === "Assembly Constituency" || node.label === "ASSEMBLY_CONSTITUENCY") {
60
- const code = node.code || node.localname || node.name;
61
- const name = node.name || node.localname || code;
62
- if (code) assemblies.set(code, { code, name: name });
63
- }
64
- if (node.children && node.children.length > 0) {
65
- node.children.forEach(traverse);
66
- }
67
- };
68
-
69
- boundaries.forEach(traverse);
70
-
71
- return {
72
- assemblyOptions: Array.from(assemblies.values()).sort((a, b) => a.name.localeCompare(b.name)),
73
- wardOptions: Array.from(wards.values()).sort((a, b) => a.name.localeCompare(b.name)),
74
- };
75
- }, [boundaryData]);
76
-
77
- const structuredLocalityData = useMemo(() => {
78
- let localities = [];
79
- const boundaries = Array.isArray(boundaryData) ? boundaryData : boundaryData ? [boundaryData] : [];
80
-
81
- const extractLocalities = (node) => {
82
- if (!node) return;
83
-
84
- if (node.label === "Locality" || node.label === "LOCALITY") {
85
- localities.push({
86
- ...node,
87
- name: node.localname || node.name || node.code,
88
- });
89
- }
90
- if (node.children && node.children.length > 0) {
91
- node.children.forEach((child) => extractLocalities(child));
92
- }
93
- };
94
-
95
- boundaries.forEach((rootNode) => extractLocalities(rootNode));
96
-
97
- return localities;
98
- }, [boundaryData]);
99
-
100
- const fetchedPincodes = useMemo(() => {
101
- const pinSet = new Set();
102
-
103
- structuredLocalityData.forEach((loc) => {
104
- if (loc.pincode) {
105
- const pins = Array.isArray(loc.pincode) ? loc.pincode : [loc.pincode];
106
- pins.forEach((p) => {
107
- if (p) {
108
- const sanitizedPin = p.toString().split(".")[0];
109
- pinSet.add(sanitizedPin);
110
- }
111
- });
112
- }
113
- });
114
-
115
- return Array.from(pinSet).sort();
116
- }, [structuredLocalityData]);
117
-
118
- useEffect(() => {
119
- const timer = setTimeout(() => {
120
- setDebouncedFilters(filters);
121
- }, 500);
122
-
123
- return () => clearTimeout(timer);
124
- }, [filters]);
125
-
126
- useEffect(() => {
127
- setCurrentPage(0);
128
- }, [debouncedFilters, filters.kno]);
129
-
130
- const { data: applicationData, isFetching: isLoading } = Digit.Hooks.ekyc.useEkycApplicationList(
131
- {
132
- /*
133
- ...(debouncedFilters.kno && {
134
- kno: debouncedFilters.kno,
135
- }),
136
- */
137
- ...(filters.kno && {
138
- kno: filters.kno,
139
- }),
140
-
141
- ...(debouncedFilters.ekycStatus && {
142
- ekycStatus: debouncedFilters.ekycStatus,
143
- }),
144
-
145
- ...(debouncedFilters.zoneName && {
146
- zoneName: debouncedFilters.zoneName,
147
- }),
148
-
149
- ...(debouncedFilters.assembly && {
150
- assembly: debouncedFilters.assembly,
151
- }),
152
-
153
- ...(debouncedFilters.ward && {
154
- ward: debouncedFilters.ward,
155
- }),
156
-
157
- ...(debouncedFilters.mrkey && {
158
- mrkey: debouncedFilters.mrkey,
159
- }),
160
-
161
- ...(debouncedFilters.pincode && {
162
- pincode: debouncedFilters.pincode,
163
- }),
164
- },
165
- {
166
- tenantId: "dl.djb",
167
- offset: currentPage * pageSize,
168
- limit: pageSize,
169
- },
170
- {
171
- keepPreviousData: true,
172
- }
173
- );
174
-
175
- const assignmentMutation = Digit.Hooks.ekyc.useEkycAssignmentCreate({
176
- onSuccess: (response) => {
177
- if (response?.error) {
178
- setToastData({
179
- error: true,
180
- label: response?.data?.message || "Something went wrong",
181
- });
182
-
183
- setShowToast(true);
184
- return;
185
- }
186
-
187
- setToastData({
188
- error: false,
189
- label: "Assignment successful",
190
- });
191
-
192
- setShowToast(true);
193
-
194
- // optional delay so user can see the success toast
195
- setTimeout(async () => {
196
- await refetchDashboard();
197
- closeModal();
198
- }, 1000);
199
- },
200
-
201
- onError: (error) => {
202
- setToastData({
203
- error: true,
204
- label: error?.data?.message || error?.response?.data?.message || "Something went wrong",
205
- });
206
-
207
- setShowToast(true);
208
- },
209
- });
210
-
211
- const tableData = applicationData?.consumerList || [];
212
-
213
- const getAssignmentPayload = () => {
214
- if (isBulkSelection) {
215
- const filterMappings = [
216
- { key: "ekycStatus", type: "EKYCSTATUS" },
217
- { key: "zoneName", type: "ZONENAME" },
218
- { key: "assembly", type: "ASSEMBLY" },
219
- { key: "ward", type: "WARD" },
220
- { key: "mrkey", type: "MRKEY" },
221
- { key: "pincode", type: "PINCODE" },
222
- ];
223
-
224
- const appliedFilter = filterMappings.find(({ key }) => debouncedFilters[key]);
225
-
226
- if (appliedFilter) {
227
- return {
228
- assignmentType: appliedFilter.type,
229
- assignmentValue: debouncedFilters[appliedFilter.key],
230
- };
231
- }
232
- }
233
-
234
- return {
235
- assignmentType: "KNO",
236
- assignmentValue: selectedKnos,
237
- };
238
- };
239
-
240
- const handleAssign = () => {
241
- const { assignmentType, assignmentValue } = getAssignmentPayload();
242
-
243
- assignmentMutation.mutate({
244
- tenantId: "dl.djb",
245
- surveyorId: surveyor?.owner?.uuid,
246
- assignmentType,
247
- assignmentValue,
248
- });
249
- };
250
-
251
- const handleSelectAll = () => {
252
- setIsBulkSelection(true);
253
-
254
- const pageKnos = tableData.map((item) => item.kno);
255
-
256
- const allSelected = pageKnos.length > 0 && pageKnos.every((kno) => selectedKnos.includes(kno));
257
-
258
- setSelectedKnos((prev) => (allSelected ? prev.filter((kno) => !pageKnos.includes(kno)) : [...new Set([...prev, ...pageKnos])]));
259
- };
260
-
261
- const handleFilterChange = (key, value) => {
262
- setFilters((prev) => ({
263
- ...prev,
264
- [key]: value,
265
- }));
266
- };
267
-
268
- const columns = useMemo(
269
- () => [
270
- {
271
- Header: () => (
272
- <input
273
- type="checkbox"
274
- checked={tableData.length > 0 && tableData.every((item) => selectedKnos.includes(item.kno))}
275
- onChange={handleSelectAll}
276
- />
277
- ),
278
- id: "selection",
279
- Cell: ({ row }) => {
280
- const kno = row.original.kno;
281
-
282
- return <input type="checkbox" checked={selectedKnos.includes(kno)} onChange={() => handleSelect(kno)} />;
283
- },
284
- },
285
- {
286
- Header: "KNO",
287
- accessor: "kno",
288
- },
289
- {
290
- Header: "Consumer Name",
291
- accessor: (row) => `${row.firstName || ""} ${row.middleName || ""} ${row.lastName || ""}`.trim(),
292
- id: "consumerName",
293
- },
294
- {
295
- Header: "Zone",
296
- accessor: "zoneName",
297
- },
298
- {
299
- Header: "Pincode",
300
- accessor: "pincode",
301
- },
302
- {
303
- Header: "Status",
304
- accessor: "status",
305
- Cell: ({ value }) => (
306
- <span className={`status-badge ${value === "ACTIVE" ? "verified" : value === "PENDING" ? "pending" : "assigned"}`}>{value}</span>
307
- ),
308
- },
309
- {
310
- Header: "eKYC Status",
311
- accessor: "ekycStatus",
312
- Cell: ({ value }) => value || "-",
313
- },
314
- ],
315
- // eslint-disable-next-line react-hooks/exhaustive-deps
316
- [selectedKnos, tableData]
317
- );
318
-
319
- const handleSelect = (kno) => {
320
- setSelectedKnos((prev) => (prev.includes(kno) ? prev.filter((item) => item !== kno) : [...prev, kno]));
321
- };
322
-
323
- return (
324
- <Modal
325
- headerBarMain={`Assign KNOs to ${surveyor?.name}`}
326
- headerBarEnd={<Close onClick={closeModal} />}
327
- actionCancelLabel="Cancel"
328
- actionCancelOnSubmit={closeModal}
329
- actionSaveLabel={`Assign ${selectedKnos.length} KNOs`}
330
- actionSaveOnSubmit={handleAssign}
331
- >
332
- <div className="assign-knos-modal">
333
- {/* Filters */}
334
- <div className="filters-grid">
335
- <input className="form-control" placeholder="KNO" value={filters.kno} onChange={(e) => handleFilterChange("kno", e.target.value)} />
336
-
337
- <select
338
- className="form-control"
339
- value={filters.pincode}
340
- onChange={(e) => handleFilterChange("pincode", e.target.value)}
341
- >
342
- <option value="">Select Pincode</option>
343
- {fetchedPincodes.map((pin) => (
344
- <option key={pin} value={pin}>
345
- {pin}
346
- </option>
347
- ))}
348
- </select>
349
-
350
- <select
351
- className="form-control"
352
- value={filters.zoneName}
353
- onChange={(e) => {
354
- const val = e.target.value;
355
- setFilters((prev) => ({
356
- ...prev,
357
- zoneCode: val,
358
- zoneName: val,
359
- }));
360
- }}
361
- disabled={isZroLoading}
362
- >
363
- <option value="">{isZroLoading ? "Loading ZRO Locations..." : "Select ZRO Location"}</option>
364
- {mappedZROLocation.map((loc) => (
365
- <option key={loc.code} value={loc.name}>
366
- {loc.name}
367
- </option>
368
- ))}http://localhost:3000/digit-ui/employee/ekyc/assign
369
- </select>
370
-
371
- <select
372
- className="form-control"
373
- value={filters.ward}
374
- onChange={(e) => handleFilterChange("ward", e.target.value)}
375
- >
376
- <option value="">Select Ward</option>
377
- {wardOptions.map((ward) => (
378
- <option key={ward.code} value={ward.name}>
379
- {ward.name}
380
- </option>
381
- ))}
382
- </select>
383
-
384
- <select
385
- className="form-control"
386
- value={filters.assembly}
387
- onChange={(e) => handleFilterChange("assembly", e.target.value)}
388
- >
389
- <option value="">Select Assembly</option>
390
- {assemblyOptions.map((assembly) => (
391
- <option key={assembly.code} value={assembly.name}>
392
- {assembly.name}
393
- </option>
394
- ))}
395
- </select>
396
-
397
- <input className="form-control" placeholder="MR Key" value={filters.mrkey} onChange={(e) => handleFilterChange("mrkey", e.target.value)} />
398
-
399
- <select className="form-control" value={filters.ekycStatus} onChange={(e) => handleFilterChange("ekycStatus", e.target.value)}>
400
- <option value="">All eKYC Status</option>
401
- <option value="PENDING">Pending</option>
402
- <option value="APPROVED">Approved</option>
403
- <option value="REJECTED">Rejected</option>
404
- </select>
405
- </div>
406
-
407
- {/* Table */}
408
- <Table
409
- tableTitle="eKYC Applications"
410
- tableClass="ekycTable"
411
- data={tableData}
412
- columns={columns}
413
- isLoading={isLoading}
414
- totalRecords={applicationData?.totalCount || 0}
415
- currentPage={currentPage}
416
- pageSizeLimit={pageSize}
417
- manualPagination={true}
418
- isPaginationRequired={true}
419
- onNextPage={() => {
420
- if (currentPage < (applicationData?.totalPages || 1) - 1) {
421
- setCurrentPage((prev) => prev + 1);
422
- }
423
- }}
424
- onPrevPage={() => {
425
- if (currentPage > 0) {
426
- setCurrentPage((prev) => prev - 1);
427
- }
428
- }}
429
- onFirstPage={() => {
430
- setCurrentPage(0);
431
- }}
432
- onLastPage={() => {
433
- setCurrentPage(Math.max((applicationData?.totalPages || 1) - 1, 0));
434
- }}
435
- onPageSizeChange={(e) => {
436
- setPageSize(Number(e.target.value));
437
- setCurrentPage(0);
438
- }}
439
- />
440
- </div>
441
- {showToast && <Toast error={toastData.error} label={toastData.label} onClose={() => setShowToast(false)} />}
442
- </Modal>
443
- );
444
- };
445
-
446
- export default AssignEkycModal;
@@ -1,264 +0,0 @@
1
- import React from "react";
2
- import { FaUsers, FaUserTie, FaMapMarkedAlt, FaCheckCircle, FaClock, FaExclamationTriangle, FaChartLine } from "react-icons/fa";
3
-
4
- const vendors = [
5
- {
6
- id: 1,
7
- name: "Vendor Alpha",
8
- progress: 78,
9
- supervisors: 12,
10
- surveyors: 148,
11
- completed: 154200,
12
- pending: 43200,
13
- rejected: 3200,
14
- },
15
- {
16
- id: 2,
17
- name: "Vendor Beta",
18
- progress: 64,
19
- supervisors: 10,
20
- surveyors: 122,
21
- completed: 121000,
22
- pending: 68500,
23
- rejected: 2800,
24
- },
25
- {
26
- id: 3,
27
- name: "Vendor Gamma",
28
- progress: 91,
29
- supervisors: 15,
30
- surveyors: 182,
31
- completed: 201500,
32
- pending: 19800,
33
- rejected: 1800,
34
- },
35
- ];
36
-
37
- const zones = [
38
- {
39
- zone: "North Delhi",
40
- totalConnections: 220000,
41
- ekycDone: 172000,
42
- liveSurveyors: 58,
43
- todayCompleted: 2800,
44
- },
45
- {
46
- zone: "South Delhi",
47
- totalConnections: 198000,
48
- ekycDone: 154500,
49
- liveSurveyors: 42,
50
- todayCompleted: 2100,
51
- },
52
- {
53
- zone: "East Delhi",
54
- totalConnections: 175000,
55
- ekycDone: 132800,
56
- liveSurveyors: 37,
57
- todayCompleted: 1740,
58
- },
59
- {
60
- zone: "West Delhi",
61
- totalConnections: 212000,
62
- ekycDone: 188300,
63
- liveSurveyors: 48,
64
- todayCompleted: 2560,
65
- },
66
- ];
67
-
68
- const alerts = [
69
- "15 Surveyors inactive for more than 2 hours",
70
- "Vendor Beta completion dropped by 12% this week",
71
- "North Delhi has highest pending backlog",
72
- "2,843 eKYC applications rejected today",
73
- ];
74
-
75
- const CeoDashboard = () => {
76
- return (
77
- <div className="ekyc-dashboard-wrapper">
78
- <div className="ceo-dashboard">
79
- <main className="main-content">
80
- <div className="kpi-grid">
81
- <div className="kpi-card primary">
82
- <div className="icon-box">
83
- <FaUsers />
84
- </div>
85
- <div>
86
- <h3>7,85,000</h3>
87
- <p>Total Water Connections</p>
88
- </div>
89
- </div>
90
-
91
- <div className="kpi-card success">
92
- <div className="icon-box">
93
- <FaCheckCircle />
94
- </div>
95
- <div>
96
- <h3>6,47,300</h3>
97
- <p>eKYC Completed</p>
98
- </div>
99
- </div>
100
-
101
- <div className="kpi-card warning">
102
- <div className="icon-box">
103
- <FaClock />
104
- </div>
105
- <div>
106
- <h3>1,31,500</h3>
107
- <p>Pending eKYC</p>
108
- </div>
109
- </div>
110
-
111
- <div className="kpi-card danger">
112
- <div className="icon-box">
113
- <FaExclamationTriangle />
114
- </div>
115
- <div>
116
- <h3>7,200</h3>
117
- <p>Rejected Applications</p>
118
- </div>
119
- </div>
120
- </div>
121
- <section className="dashboard-section">
122
- <div className="section-header">
123
- <h2>
124
- <FaChartLine /> Vendor Performance Overview
125
- </h2>
126
- <button>View All</button>
127
- </div>
128
-
129
- <div className="vendor-grid">
130
- {vendors.map((vendor) => (
131
- <div className="vendor-card" key={vendor.id}>
132
- <div className="vendor-top">
133
- <div>
134
- <h3>{vendor.name}</h3>
135
- <p>Jurisdiction Assigned Vendor</p>
136
- </div>
137
-
138
- <span>{vendor.progress}%</span>
139
- </div>
140
-
141
- <div className="progress-bar">
142
- <div className="progress-fill" style={{ width: `${vendor.progress}%` }}></div>
143
- </div>
144
-
145
- <div className="vendor-stats">
146
- <div>
147
- <h4>{vendor.supervisors}</h4>
148
- <p>Supervisors</p>
149
- </div>
150
-
151
- <div>
152
- <h4>{vendor.surveyors}</h4>
153
- <p>Surveyors</p>
154
- </div>
155
-
156
- <div>
157
- <h4>{vendor.completed}</h4>
158
- <p>Completed</p>
159
- </div>
160
- </div>
161
-
162
- <div className="vendor-footer">
163
- <span>Pending: {vendor.pending}</span>
164
- <span>Rejected: {vendor.rejected}</span>
165
- </div>
166
- </div>
167
- ))}
168
- </div>
169
- </section>
170
-
171
- <section className="dashboard-section">
172
- <div className="section-header">
173
- <h2>
174
- <FaMapMarkedAlt /> Jurisdiction Monitoring
175
- </h2>
176
- <button>Export Data</button>
177
- </div>
178
-
179
- <div className="table-wrapper">
180
- <table>
181
- <thead>
182
- <tr>
183
- <th>Zone</th>
184
- <th>Total Connections</th>
185
- <th>eKYC Done</th>
186
- <th>Live Surveyors</th>
187
- <th>Today's Completion</th>
188
- <th>Status</th>
189
- </tr>
190
- </thead>
191
-
192
- <tbody>
193
- {zones.map((item, index) => (
194
- <tr key={index}>
195
- <td>{item.zone}</td>
196
- <td>{item.totalConnections}</td>
197
- <td>{item.ekycDone}</td>
198
- <td>{item.liveSurveyors}</td>
199
- <td>{item.todayCompleted}</td>
200
- <td>
201
- <span className="status-badge success">Active</span>
202
- </td>
203
- </tr>
204
- ))}
205
- </tbody>
206
- </table>
207
- </div>
208
- </section>
209
-
210
- <div className="bottom-grid">
211
- <section className="dashboard-section alerts-section">
212
- <div className="section-header">
213
- <h2>
214
- <FaExclamationTriangle /> Critical Alerts
215
- </h2>
216
- </div>
217
-
218
- <div className="alerts-list">
219
- {alerts.map((alert, index) => (
220
- <div className="alert-card" key={index}>
221
- <FaExclamationTriangle />
222
- <p>{alert}</p>
223
- </div>
224
- ))}
225
- </div>
226
- </section>
227
-
228
- <section className="dashboard-section team-section">
229
- <div className="section-header">
230
- <h2>
231
- <FaUserTie /> Workforce Monitoring
232
- </h2>
233
- </div>
234
-
235
- <div className="team-stats-grid">
236
- <div className="team-box">
237
- <h3>37</h3>
238
- <p>Total Supervisors Online</p>
239
- </div>
240
-
241
- <div className="team-box">
242
- <h3>154</h3>
243
- <p>Surveyors Active</p>
244
- </div>
245
-
246
- <div className="team-box">
247
- <h3>12,430</h3>
248
- <p>Today's eKYC Completed</p>
249
- </div>
250
-
251
- <div className="team-box">
252
- <h3>92%</h3>
253
- <p>Operational Efficiency</p>
254
- </div>
255
- </div>
256
- </section>
257
- </div>
258
- </main>
259
- </div>
260
- </div>
261
- );
262
- };
263
-
264
- export default CeoDashboard;