@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.
- package/dist/index.js +8911 -1
- package/dist/index.js.map +1 -1
- package/dist/index.modern.js +3295 -2039
- package/dist/index.modern.js.map +1 -1
- package/package.json +4 -1
- package/dist/index.css +0 -54
- package/src/Module.js +0 -78
- package/src/components/AadhaarVerification.js +0 -315
- package/src/components/AssignEkyc.js +0 -236
- package/src/components/AssignEkycModal.js +0 -446
- package/src/components/CeoDashboard.js +0 -264
- package/src/components/CeoDashboard.jsx +0 -334
- package/src/components/ConnectionDetailsView.js +0 -241
- package/src/components/Dashboard.js +0 -43
- package/src/components/DesktopInbox.js +0 -176
- package/src/components/EKYCCard.js +0 -53
- package/src/components/Filter.js +0 -55
- package/src/components/MeterDetails.js +0 -336
- package/src/components/MobileInbox.js +0 -73
- package/src/components/PropertyInfo.js +0 -264
- package/src/components/Review.js +0 -696
- package/src/components/SearchConsumer.js +0 -142
- package/src/components/SearchFormFieldsComponent.js +0 -67
- package/src/components/SelectEkycZones.js +0 -71
- package/src/components/StatusCards.js +0 -148
- package/src/components/SurveyorDetailsCard.js +0 -512
- package/src/components/VendorDetails.jsx +0 -230
- package/src/components/analytics/charts/ClusterHeatmap.js +0 -88
- package/src/components/analytics/charts/ExecutiveBarChart.jsx +0 -30
- package/src/components/analytics/charts/ExecutiveLineChart.jsx +0 -159
- package/src/components/analytics/charts/ExecutivePieChart.jsx +0 -24
- package/src/components/analytics/charts/TaskStatusChart.js +0 -90
- package/src/components/analytics/components/AnalyticsTable.js +0 -106
- package/src/components/analytics/components/DashboardLayout.js +0 -52
- package/src/components/analytics/components/EmptyState.js +0 -27
- package/src/components/analytics/components/ErrorBoundary.js +0 -27
- package/src/components/analytics/components/FilterBar.js +0 -73
- package/src/components/analytics/components/NotificationPanel.js +0 -77
- package/src/components/analytics/components/SLAWidget.js +0 -56
- package/src/components/analytics/components/SkeletonLoader.js +0 -53
- package/src/components/analytics/components/SummaryCard.js +0 -74
- package/src/components/analytics/components/WorkflowTimeline.js +0 -55
- package/src/components/analytics/utils/exportUtils.js +0 -64
- package/src/components/analytics/utils/filterSerializer.js +0 -50
- package/src/components/mockData.js +0 -772
- package/src/config/AadhaarVerificationConfig.js +0 -367
- package/src/config/MeterDetailsConfig.js +0 -297
- package/src/config/PropertyInfoConfig.js +0 -145
- package/src/config/config.js +0 -70
- package/src/hook/SupervisorInboxTableConfig.js +0 -80
- package/src/hook/useInboxTableConfig.js +0 -131
- package/src/pages/citizen/Home.js +0 -54
- package/src/pages/citizen/Inbox.js +0 -265
- package/src/pages/citizen/index.js +0 -199
- package/src/pages/employee/ConsumerDetails.js +0 -299
- package/src/pages/employee/Create.js +0 -94
- package/src/pages/employee/EKYCForm.js +0 -118
- package/src/pages/employee/Inbox.js +0 -266
- package/src/pages/employee/Mapping.js +0 -358
- package/src/pages/employee/Update.js +0 -9
- package/src/pages/employee/index.js +0 -184
- package/src/utils/index.js +0 -46
- package/src/utils/reportDownloader.js +0 -90
|
@@ -1,334 +0,0 @@
|
|
|
1
|
-
import React, { useMemo, useState } from "react";
|
|
2
|
-
import { useHistory, useLocation } from "react-router-dom";
|
|
3
|
-
import {
|
|
4
|
-
FaChartLine,
|
|
5
|
-
FaUsers,
|
|
6
|
-
FaCheckCircle,
|
|
7
|
-
FaClock,
|
|
8
|
-
FaExclamationTriangle,
|
|
9
|
-
FaUserTie,
|
|
10
|
-
FaMapMarkedAlt,
|
|
11
|
-
FaSearch,
|
|
12
|
-
FaArrowRight,
|
|
13
|
-
} from "react-icons/fa";
|
|
14
|
-
import { ekycMockData } from "./mockData";
|
|
15
|
-
import ExecutiveLineChart from "./analytics/charts/ExecutiveLineChart";
|
|
16
|
-
import ExecutiveBarChart from "./analytics/charts/ExecutiveBarChart";
|
|
17
|
-
import ExecutivePieChart from "./analytics/charts/ExecutivePieChart";
|
|
18
|
-
|
|
19
|
-
const CeoDashboard = () => {
|
|
20
|
-
const history = useHistory();
|
|
21
|
-
const location = useLocation();
|
|
22
|
-
const [query, setQuery] = useState("");
|
|
23
|
-
const [statusFilter, setStatusFilter] = useState("All");
|
|
24
|
-
|
|
25
|
-
const basePath = location.pathname.replace(/\/ceo-dashboard$/, "");
|
|
26
|
-
const filters = ["All", "High Priority", "Stable", "Watchlist"];
|
|
27
|
-
|
|
28
|
-
const vendors = useMemo(() => ekycMockData.vendors || [], []);
|
|
29
|
-
const topKpis = useMemo(() => ekycMockData.topKpis || {}, []);
|
|
30
|
-
const dailyTrend = useMemo(() => ekycMockData.dailyTrend || [], []);
|
|
31
|
-
const selfVsAgency = useMemo(() => ekycMockData.selfVsAgency || [], []);
|
|
32
|
-
const pendingVsCompleted = useMemo(() => ekycMockData.pendingVsCompleted || [], []);
|
|
33
|
-
// const rejectionAnalysis = ekycMockData.rejectionAnalysis || [];
|
|
34
|
-
|
|
35
|
-
const filteredVendors = useMemo(() => {
|
|
36
|
-
return vendors
|
|
37
|
-
.filter((vendor) => {
|
|
38
|
-
if (statusFilter === "High Priority") return vendor.successRate < 70;
|
|
39
|
-
if (statusFilter === "Watchlist") return vendor.pending > 35000;
|
|
40
|
-
if (statusFilter === "Stable") return vendor.successRate >= 70;
|
|
41
|
-
return true;
|
|
42
|
-
})
|
|
43
|
-
.filter((vendor) => {
|
|
44
|
-
if (!query) return true;
|
|
45
|
-
const keyword = query.toLowerCase();
|
|
46
|
-
return (
|
|
47
|
-
vendor.name.toLowerCase().includes(keyword) ||
|
|
48
|
-
vendor.jurisdictions.some((zone) => zone.toLowerCase().includes(keyword)) ||
|
|
49
|
-
vendor.zones.some((zone) => zone.location?.toLowerCase().includes(keyword))
|
|
50
|
-
);
|
|
51
|
-
});
|
|
52
|
-
}, [vendors, query, statusFilter]);
|
|
53
|
-
|
|
54
|
-
const zoneRows = useMemo(() => {
|
|
55
|
-
return vendors
|
|
56
|
-
.flatMap((vendor) => vendor.zones.map((zone) => ({ ...zone, agency: vendor.name })))
|
|
57
|
-
.filter((row) => row.location)
|
|
58
|
-
.sort((a, b) => (b.activeDemand || 0) - (a.activeDemand || 0));
|
|
59
|
-
}, [vendors]);
|
|
60
|
-
|
|
61
|
-
const alerts = [
|
|
62
|
-
"North East District has 22% more pending accounts than last week",
|
|
63
|
-
"Agency 2 has a 12% improvement opportunity in Self eKYC adoption",
|
|
64
|
-
"Urgent: 18 supervisor escalations raised for NWS Bhera Enclave",
|
|
65
|
-
"Risk alert: Rejection trends are rising in Outer North clusters",
|
|
66
|
-
];
|
|
67
|
-
|
|
68
|
-
const routeToVendor = (vendorId) => {
|
|
69
|
-
history.push(`${basePath}/vendors/${vendorId}`);
|
|
70
|
-
};
|
|
71
|
-
|
|
72
|
-
return (
|
|
73
|
-
<div className="ekyc-dashboard-wrapper">
|
|
74
|
-
<div className="dashboard-shell">
|
|
75
|
-
<section className="kpi-grid">
|
|
76
|
-
{[
|
|
77
|
-
{
|
|
78
|
-
title: "Total Water Connections",
|
|
79
|
-
value: topKpis.totalWaterConnections,
|
|
80
|
-
icon: <FaUsers />,
|
|
81
|
-
variant: "primary",
|
|
82
|
-
},
|
|
83
|
-
{
|
|
84
|
-
title: "Total eKYC Completed",
|
|
85
|
-
value: topKpis.totalEkycCompleted,
|
|
86
|
-
icon: <FaCheckCircle />,
|
|
87
|
-
variant: "success",
|
|
88
|
-
},
|
|
89
|
-
{
|
|
90
|
-
title: "Total Pending",
|
|
91
|
-
value: topKpis.totalPending,
|
|
92
|
-
icon: <FaClock />,
|
|
93
|
-
variant: "warning",
|
|
94
|
-
},
|
|
95
|
-
{
|
|
96
|
-
title: "Total Rejected",
|
|
97
|
-
value: topKpis.totalRejected,
|
|
98
|
-
icon: <FaExclamationTriangle />,
|
|
99
|
-
variant: "danger",
|
|
100
|
-
},
|
|
101
|
-
{
|
|
102
|
-
title: "Agency eKYC Completed",
|
|
103
|
-
value: topKpis.agencyEkycCompleted,
|
|
104
|
-
icon: <FaUserTie />,
|
|
105
|
-
variant: "info",
|
|
106
|
-
},
|
|
107
|
-
{
|
|
108
|
-
title: "Citizen Self eKYC Completed",
|
|
109
|
-
value: topKpis.citizenSelfEkycCompleted,
|
|
110
|
-
icon: <FaUsers />,
|
|
111
|
-
variant: "secondary",
|
|
112
|
-
},
|
|
113
|
-
{
|
|
114
|
-
title: "Today's eKYC",
|
|
115
|
-
value: topKpis.todaysEkyc,
|
|
116
|
-
icon: <FaChartLine />,
|
|
117
|
-
variant: "muted",
|
|
118
|
-
},
|
|
119
|
-
{
|
|
120
|
-
title: "Success Rate",
|
|
121
|
-
value: `${topKpis.successRate}%`,
|
|
122
|
-
icon: <FaCheckCircle />,
|
|
123
|
-
variant: "success",
|
|
124
|
-
},
|
|
125
|
-
{
|
|
126
|
-
title: "Rejection Percentage",
|
|
127
|
-
value: `${topKpis.rejectionPercentage}%`,
|
|
128
|
-
icon: <FaExclamationTriangle />,
|
|
129
|
-
variant: "danger",
|
|
130
|
-
},
|
|
131
|
-
].map((card) => (
|
|
132
|
-
<article key={card.title} className={`kpi-card card-${card.variant}`}>
|
|
133
|
-
<div className="kpi-icon">{card.icon}</div>
|
|
134
|
-
<div>
|
|
135
|
-
<p className="kpi-title">{card.title}</p>
|
|
136
|
-
<h2>{card.value?.toLocaleString?.() ?? card.value}</h2>
|
|
137
|
-
</div>
|
|
138
|
-
</article>
|
|
139
|
-
))}
|
|
140
|
-
</section>
|
|
141
|
-
|
|
142
|
-
<section className="vendor-section">
|
|
143
|
-
<div className="section-top">
|
|
144
|
-
<div>
|
|
145
|
-
<h2>Agency Performance Snapshot</h2>
|
|
146
|
-
<p>Search, filter, and navigate into detailed analytics for every assigned vendor.</p>
|
|
147
|
-
</div>
|
|
148
|
-
<div className="vendor-filters">
|
|
149
|
-
<div className="search-box">
|
|
150
|
-
<FaSearch />
|
|
151
|
-
<input type="text" placeholder="Search agency, jurisdiction, location" value={query} onChange={(e) => setQuery(e.target.value)} />
|
|
152
|
-
</div>
|
|
153
|
-
<div className="status-pill-group">
|
|
154
|
-
{filters.map((status) => (
|
|
155
|
-
<button key={status} className={`status-pill ${statusFilter === status ? "active" : ""}`} onClick={() => setStatusFilter(status)}>
|
|
156
|
-
{status}
|
|
157
|
-
</button>
|
|
158
|
-
))}
|
|
159
|
-
</div>
|
|
160
|
-
</div>
|
|
161
|
-
</div>
|
|
162
|
-
|
|
163
|
-
<div className="vendor-grid">
|
|
164
|
-
{filteredVendors.map((vendor) => (
|
|
165
|
-
<div key={vendor.id} className="vendor-card glass-card" onClick={() => routeToVendor(vendor.id)}>
|
|
166
|
-
<div className="vendor-card-top">
|
|
167
|
-
<div>
|
|
168
|
-
<p className="vendor-chip">{vendor.name}</p>
|
|
169
|
-
<h3>{vendor.assignedConnections.toLocaleString()}</h3>
|
|
170
|
-
<p className="vendor-subtitle">Assigned connections across {vendor.jurisdictions.length} jurisdiction(s)</p>
|
|
171
|
-
</div>
|
|
172
|
-
<div className="vendor-progress-value">{vendor.progress}%</div>
|
|
173
|
-
</div>
|
|
174
|
-
<div className="progress-bar">
|
|
175
|
-
<div className="progress-fill" style={{ width: `${vendor.progress}%` }} />
|
|
176
|
-
</div>
|
|
177
|
-
<div className="vendor-stats-grid">
|
|
178
|
-
<div>
|
|
179
|
-
<strong>{vendor.completedEkyc.toLocaleString()}</strong>
|
|
180
|
-
<span>Agency eKYC</span>
|
|
181
|
-
</div>
|
|
182
|
-
<div>
|
|
183
|
-
<strong>{vendor.selfEkyc.toLocaleString()}</strong>
|
|
184
|
-
<span>Self eKYC</span>
|
|
185
|
-
</div>
|
|
186
|
-
<div>
|
|
187
|
-
<strong>{vendor.pending.toLocaleString()}</strong>
|
|
188
|
-
<span>Pending</span>
|
|
189
|
-
</div>
|
|
190
|
-
<div>
|
|
191
|
-
<strong>{vendor.rejected.toLocaleString()}</strong>
|
|
192
|
-
<span>Rejected</span>
|
|
193
|
-
</div>
|
|
194
|
-
</div>
|
|
195
|
-
<div className="vendor-card-footer">
|
|
196
|
-
<span>{vendor.activeSurveyors} Surveyors</span>
|
|
197
|
-
<span>{vendor.supervisors} Supervisors</span>
|
|
198
|
-
<span>{vendor.jurisdictions.join(", ")}</span>
|
|
199
|
-
</div>
|
|
200
|
-
<div className="vendor-card-action">
|
|
201
|
-
<span>Explore analytics</span>
|
|
202
|
-
<FaArrowRight />
|
|
203
|
-
</div>
|
|
204
|
-
</div>
|
|
205
|
-
))}
|
|
206
|
-
</div>
|
|
207
|
-
</section>
|
|
208
|
-
|
|
209
|
-
<section className="analytics-grid">
|
|
210
|
-
<div className="analytics-panel glass-card">
|
|
211
|
-
<div className="section-header">
|
|
212
|
-
<h2>Daily eKYC Trend</h2>
|
|
213
|
-
<span className="badge success">Live index</span>
|
|
214
|
-
</div>
|
|
215
|
-
<ExecutiveLineChart data={dailyTrend} dataKey="completed" name="Completed" />
|
|
216
|
-
</div>
|
|
217
|
-
|
|
218
|
-
<div className="analytics-panel glass-card">
|
|
219
|
-
<div className="section-header">
|
|
220
|
-
<h2>Self vs Agency eKYC</h2>
|
|
221
|
-
<span className="badge info">Adoption</span>
|
|
222
|
-
</div>
|
|
223
|
-
<ExecutiveBarChart
|
|
224
|
-
data={selfVsAgency}
|
|
225
|
-
categories={[
|
|
226
|
-
{ key: "agency", name: "Agency" },
|
|
227
|
-
{ key: "citizen", name: "Citizen" },
|
|
228
|
-
]}
|
|
229
|
-
/>
|
|
230
|
-
</div>
|
|
231
|
-
|
|
232
|
-
<div className="analytics-panel glass-card">
|
|
233
|
-
<div className="section-header">
|
|
234
|
-
<h2>Pending vs Completed</h2>
|
|
235
|
-
<span className="badge warning">Operational pulse</span>
|
|
236
|
-
</div>
|
|
237
|
-
<ExecutivePieChart data={pendingVsCompleted} dataKey="completed" labelKey="label" />
|
|
238
|
-
</div>
|
|
239
|
-
</section>
|
|
240
|
-
|
|
241
|
-
<section className="zone-section">
|
|
242
|
-
<div className="section-header">
|
|
243
|
-
<div>
|
|
244
|
-
<h2>
|
|
245
|
-
<FaMapMarkedAlt /> Jurisdiction Performance
|
|
246
|
-
</h2>
|
|
247
|
-
<p>Top zones evaluated from the full agency dataset.</p>
|
|
248
|
-
</div>
|
|
249
|
-
<button className="secondary-button">Export Zone Data</button>
|
|
250
|
-
</div>
|
|
251
|
-
|
|
252
|
-
<div className="table-wrapper glass-card">
|
|
253
|
-
<table>
|
|
254
|
-
<thead>
|
|
255
|
-
<tr>
|
|
256
|
-
<th>Agency</th>
|
|
257
|
-
<th>Location</th>
|
|
258
|
-
<th>District</th>
|
|
259
|
-
<th>Assigned</th>
|
|
260
|
-
<th>Agency eKYC</th>
|
|
261
|
-
<th>Pending</th>
|
|
262
|
-
<th>Progress</th>
|
|
263
|
-
</tr>
|
|
264
|
-
</thead>
|
|
265
|
-
<tbody>
|
|
266
|
-
{zoneRows.slice(0, 10).map((zone, index) => (
|
|
267
|
-
<tr key={`${zone.agency}-${zone.location}-${index}`}>
|
|
268
|
-
<td>{zone.agency}</td>
|
|
269
|
-
<td>{zone.location}</td>
|
|
270
|
-
<td>{zone.district || zone.cluster}</td>
|
|
271
|
-
<td>{zone.activeDemand?.toLocaleString() ?? "—"}</td>
|
|
272
|
-
<td>{zone.pppZones?.toLocaleString() ?? "—"}</td>
|
|
273
|
-
<td>{zone.inactiveDemand?.toLocaleString() ?? "—"}</td>
|
|
274
|
-
<td>
|
|
275
|
-
<span className="status-badge success">
|
|
276
|
-
{Math.min(100, Math.round(((zone.pppZones || 0) / Math.max(zone.activeDemand || 1, 1)) * 100))}%
|
|
277
|
-
</span>
|
|
278
|
-
</td>
|
|
279
|
-
</tr>
|
|
280
|
-
))}
|
|
281
|
-
</tbody>
|
|
282
|
-
</table>
|
|
283
|
-
</div>
|
|
284
|
-
</section>
|
|
285
|
-
|
|
286
|
-
<section className="bottom-grid">
|
|
287
|
-
<div className="alerts-panel glass-card">
|
|
288
|
-
<div className="section-header">
|
|
289
|
-
<h2>
|
|
290
|
-
<FaExclamationTriangle /> Critical Alerts
|
|
291
|
-
</h2>
|
|
292
|
-
</div>
|
|
293
|
-
<div className="alerts-list">
|
|
294
|
-
{alerts.map((alert) => (
|
|
295
|
-
<div key={alert} className="alert-card">
|
|
296
|
-
<FaExclamationTriangle />
|
|
297
|
-
<p>{alert}</p>
|
|
298
|
-
</div>
|
|
299
|
-
))}
|
|
300
|
-
</div>
|
|
301
|
-
</div>
|
|
302
|
-
|
|
303
|
-
<div className="efficiency-panel glass-card">
|
|
304
|
-
<div className="section-header">
|
|
305
|
-
<h2>
|
|
306
|
-
<FaUserTie /> Workforce & Efficiency
|
|
307
|
-
</h2>
|
|
308
|
-
</div>
|
|
309
|
-
<div className="efficiency-grid">
|
|
310
|
-
<div className="efficiency-box">
|
|
311
|
-
<h3>48</h3>
|
|
312
|
-
<p>Supervisors Online</p>
|
|
313
|
-
</div>
|
|
314
|
-
<div className="efficiency-box">
|
|
315
|
-
<h3>168</h3>
|
|
316
|
-
<p>Surveyors Active</p>
|
|
317
|
-
</div>
|
|
318
|
-
<div className="efficiency-box">
|
|
319
|
-
<h3>{topKpis.todayEkyc?.toLocaleString()}</h3>
|
|
320
|
-
<p>eKYC Completed Today</p>
|
|
321
|
-
</div>
|
|
322
|
-
<div className="efficiency-box">
|
|
323
|
-
<h3>{topKpis.successRate}%</h3>
|
|
324
|
-
<p>Operational Efficiency</p>
|
|
325
|
-
</div>
|
|
326
|
-
</div>
|
|
327
|
-
</div>
|
|
328
|
-
</section>
|
|
329
|
-
</div>
|
|
330
|
-
</div>
|
|
331
|
-
);
|
|
332
|
-
};
|
|
333
|
-
|
|
334
|
-
export default CeoDashboard;
|
|
@@ -1,241 +0,0 @@
|
|
|
1
|
-
import React, { useState } from "react";
|
|
2
|
-
import { Loader, Modal, RadioButtons } from "@djb25/digit-ui-react-components";
|
|
3
|
-
import { useTranslation } from "react-i18next";
|
|
4
|
-
import { useHistory, useRouteMatch } from "react-router-dom";
|
|
5
|
-
|
|
6
|
-
const ConnectionDetailsView = ({ kNumber, kName, connectionDetails, isLoading }) => {
|
|
7
|
-
const { t } = useTranslation();
|
|
8
|
-
const history = useHistory();
|
|
9
|
-
const { path } = useRouteMatch();
|
|
10
|
-
|
|
11
|
-
const [showModal, setShowModal] = useState(false);
|
|
12
|
-
const [selectedOption, setSelectedOption] = useState({ code: "SELF", name: "EKYC_SELF" });
|
|
13
|
-
|
|
14
|
-
const options = [
|
|
15
|
-
{ code: "SELF", name: "EKYC_SELF" },
|
|
16
|
-
{ code: "OTHER", name: "EKYC_OTHER" },
|
|
17
|
-
];
|
|
18
|
-
|
|
19
|
-
const handleStartVerification = () => setShowModal(true);
|
|
20
|
-
|
|
21
|
-
const onModalConfirm = () => {
|
|
22
|
-
const parentPath = path.includes("/create-kyc")
|
|
23
|
-
? path.replace("/create-kyc", "")
|
|
24
|
-
: path.replace("/k-details", "");
|
|
25
|
-
history.push(`${parentPath}/consumer-details`, { kNumber, selectedOption, connectionDetails });
|
|
26
|
-
setShowModal(false);
|
|
27
|
-
};
|
|
28
|
-
|
|
29
|
-
if (isLoading) return <Loader />;
|
|
30
|
-
if (!connectionDetails) return null;
|
|
31
|
-
|
|
32
|
-
const details = connectionDetails?.connectionDetails || {};
|
|
33
|
-
const statusFlag = details.statusflag || "";
|
|
34
|
-
const isActive = statusFlag?.toLowerCase() === "active" || statusFlag === "A";
|
|
35
|
-
|
|
36
|
-
return (
|
|
37
|
-
<React.Fragment>
|
|
38
|
-
<div className="ekyc-employee-container">
|
|
39
|
-
{/* Main Card */}
|
|
40
|
-
<div className="connection-details-card">
|
|
41
|
-
{/* Card Header */}
|
|
42
|
-
<div className="details-card-header">
|
|
43
|
-
<div className="header-title-wrapper">
|
|
44
|
-
<div className="header-icon-bg">
|
|
45
|
-
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="#3A7BD5" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
|
|
46
|
-
<path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2" />
|
|
47
|
-
<circle cx="12" cy="7" r="4" />
|
|
48
|
-
</svg>
|
|
49
|
-
</div>
|
|
50
|
-
<span className="header-title-text">
|
|
51
|
-
{t("EKYC_K_NUMBER_DETAILS") || "Consumer Identity Details"}
|
|
52
|
-
</span>
|
|
53
|
-
</div>
|
|
54
|
-
|
|
55
|
-
{/* Status Badge */}
|
|
56
|
-
<span className={`status-badge ${isActive ? "active" : "inactive"}`}>
|
|
57
|
-
{isActive ? (t("EKYC_ACTIVE_CONNECTION") || "Active Connection") : (statusFlag || t("CS_NA"))}
|
|
58
|
-
</span>
|
|
59
|
-
</div>
|
|
60
|
-
|
|
61
|
-
{/* Card Body */}
|
|
62
|
-
<div className="details-card-body">
|
|
63
|
-
<div className="body-content-row">
|
|
64
|
-
{/* Left: Verification Parameters */}
|
|
65
|
-
<div className="detail-section">
|
|
66
|
-
<div className="section-title">
|
|
67
|
-
{t("EKYC_VERIFICATION_PARAMETERS") || "Verification Parameters"}
|
|
68
|
-
</div>
|
|
69
|
-
|
|
70
|
-
<div className="data-grid">
|
|
71
|
-
{/* Consumer Name */}
|
|
72
|
-
<div className="data-item">
|
|
73
|
-
<div className="data-label">
|
|
74
|
-
{t("EKYC_CONSUMER_NAME") || "Consumer Name"}
|
|
75
|
-
</div>
|
|
76
|
-
<div className="data-value">
|
|
77
|
-
{details.consumerName || kName || t("CS_NA")}
|
|
78
|
-
</div>
|
|
79
|
-
</div>
|
|
80
|
-
|
|
81
|
-
{/* K Number */}
|
|
82
|
-
<div className="data-item">
|
|
83
|
-
<div className="data-label">
|
|
84
|
-
{t("EKYC_K_NUMBER") || "K Number"}
|
|
85
|
-
</div>
|
|
86
|
-
<div className="data-value blue">
|
|
87
|
-
{kNumber || t("CS_NA")}
|
|
88
|
-
</div>
|
|
89
|
-
</div>
|
|
90
|
-
|
|
91
|
-
{/* Meter Serial No */}
|
|
92
|
-
<div className="data-item">
|
|
93
|
-
<div className="data-label">
|
|
94
|
-
{t("EKYC_METER_NO") || "Meter Serial No."}
|
|
95
|
-
</div>
|
|
96
|
-
<div className="data-value">
|
|
97
|
-
{details.meterNumber || t("CS_NA")}
|
|
98
|
-
</div>
|
|
99
|
-
</div>
|
|
100
|
-
|
|
101
|
-
{/* Connection Type */}
|
|
102
|
-
<div className="data-item">
|
|
103
|
-
<div className="data-label">
|
|
104
|
-
{t("EKYC_CONNECTION_TYPE") || "Connection Type"}
|
|
105
|
-
</div>
|
|
106
|
-
<div className="data-value">
|
|
107
|
-
{details.connectionType || t("CS_NA")}
|
|
108
|
-
</div>
|
|
109
|
-
</div>
|
|
110
|
-
</div>
|
|
111
|
-
</div>
|
|
112
|
-
|
|
113
|
-
{/* Divider */}
|
|
114
|
-
<div className="vertical-divider" />
|
|
115
|
-
|
|
116
|
-
{/* Right: Address & Contact */}
|
|
117
|
-
<div className="detail-section">
|
|
118
|
-
<div className="section-title">
|
|
119
|
-
{t("EKYC_ADDRESS_AND_CONTACT") || "Address & Contact"}
|
|
120
|
-
</div>
|
|
121
|
-
|
|
122
|
-
{/* Service Address */}
|
|
123
|
-
<div className="address-block">
|
|
124
|
-
<div className="icon-wrapper-small">
|
|
125
|
-
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="#6B7B8E" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
|
|
126
|
-
<path d="M21 10c0 7-9 13-9 13S3 17 3 10a9 9 0 0 1 18 0z" />
|
|
127
|
-
<circle cx="12" cy="10" r="3" />
|
|
128
|
-
</svg>
|
|
129
|
-
</div>
|
|
130
|
-
<div>
|
|
131
|
-
<div className="data-label">
|
|
132
|
-
{t("EKYC_ADDRESS") || "Service Address"}
|
|
133
|
-
</div>
|
|
134
|
-
<div className="address-text">
|
|
135
|
-
{details.address || t("CS_NA")}
|
|
136
|
-
</div>
|
|
137
|
-
</div>
|
|
138
|
-
</div>
|
|
139
|
-
|
|
140
|
-
{/* Contact + Email row */}
|
|
141
|
-
<div className="contact-row">
|
|
142
|
-
{/* Contact */}
|
|
143
|
-
<div className="contact-item">
|
|
144
|
-
<div className="icon-wrapper-small">
|
|
145
|
-
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="#6B7B8E" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
|
|
146
|
-
<rect x="5" y="2" width="14" height="20" rx="2" ry="2" />
|
|
147
|
-
<line x1="12" y1="18" x2="12.01" y2="18" />
|
|
148
|
-
</svg>
|
|
149
|
-
</div>
|
|
150
|
-
<div>
|
|
151
|
-
<div className="data-label">
|
|
152
|
-
{t("EKYC_PHONE_NO") || "Contact"}
|
|
153
|
-
</div>
|
|
154
|
-
<div className="address-text">
|
|
155
|
-
{details.phoneNumber || t("CS_NA")}
|
|
156
|
-
</div>
|
|
157
|
-
</div>
|
|
158
|
-
</div>
|
|
159
|
-
|
|
160
|
-
{/* Email */}
|
|
161
|
-
<div className="contact-item">
|
|
162
|
-
<div className="icon-wrapper-small">
|
|
163
|
-
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="#6B7B8E" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
|
|
164
|
-
<circle cx="12" cy="12" r="4" />
|
|
165
|
-
<path d="M16 8v5a3 3 0 0 0 6 0v-1a10 10 0 1 0-3.92 7.94" />
|
|
166
|
-
</svg>
|
|
167
|
-
</div>
|
|
168
|
-
<div>
|
|
169
|
-
<div className="data-label">
|
|
170
|
-
{t("EKYC_EMAIL") || "Email Address"}
|
|
171
|
-
</div>
|
|
172
|
-
<div className="address-text">
|
|
173
|
-
{details.email || t("CS_NA")}
|
|
174
|
-
</div>
|
|
175
|
-
</div>
|
|
176
|
-
</div>
|
|
177
|
-
</div>
|
|
178
|
-
</div>
|
|
179
|
-
</div>
|
|
180
|
-
</div>
|
|
181
|
-
|
|
182
|
-
{/* Card Footer */}
|
|
183
|
-
<div className="details-card-footer">
|
|
184
|
-
{/* Last Verified */}
|
|
185
|
-
<div className="footer-meta-text">
|
|
186
|
-
{connectionDetails?.lastVerified
|
|
187
|
-
? `${t("EKYC_LAST_VERIFIED") || "Last verified:"} ${connectionDetails.lastVerified}`
|
|
188
|
-
: ""}
|
|
189
|
-
</div>
|
|
190
|
-
|
|
191
|
-
{/* Action Buttons */}
|
|
192
|
-
<div className="action-btns-container" style={{ fontSize: "12px" }}>
|
|
193
|
-
<button
|
|
194
|
-
onClick={handleStartVerification}
|
|
195
|
-
className="primary-action-btn"
|
|
196
|
-
style={{ fontSize: "12px" }}
|
|
197
|
-
>
|
|
198
|
-
{t("EKYC_START_REVIEW") || "Start Review"}
|
|
199
|
-
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round">
|
|
200
|
-
<line x1="5" y1="12" x2="19" y2="12" />
|
|
201
|
-
<polyline points="12 5 19 12 12 19" />
|
|
202
|
-
</svg>
|
|
203
|
-
</button>
|
|
204
|
-
</div>
|
|
205
|
-
</div>
|
|
206
|
-
</div>
|
|
207
|
-
</div>
|
|
208
|
-
|
|
209
|
-
{/* Modal */}
|
|
210
|
-
{showModal && (
|
|
211
|
-
<Modal
|
|
212
|
-
headerBarMain={t("EKYC_SELECT_VERIFICATION_TYPE")}
|
|
213
|
-
headerBarEnd={
|
|
214
|
-
<span onClick={() => setShowModal(false)} style={{ cursor: "pointer", padding: "8px" }}>
|
|
215
|
-
X
|
|
216
|
-
</span>
|
|
217
|
-
}
|
|
218
|
-
actionSaveLabel={t("ES_COMMON_CONFIRM")}
|
|
219
|
-
actionSaveOnSubmit={onModalConfirm}
|
|
220
|
-
actionCancelLabel={t("ES_COMMON_CANCEL")}
|
|
221
|
-
actionCancelOnSubmit={() => setShowModal(false)}
|
|
222
|
-
style={{ borderRadius: "12px" }}
|
|
223
|
-
>
|
|
224
|
-
<div style={{ padding: "24px" }}>
|
|
225
|
-
<RadioButtons
|
|
226
|
-
name="verificationType"
|
|
227
|
-
options={options}
|
|
228
|
-
optionsKey="name"
|
|
229
|
-
selectedOption={selectedOption}
|
|
230
|
-
onSelect={setSelectedOption}
|
|
231
|
-
style={{ display: "flex", flexDirection: "column", gap: "12px", buttonStyle: { borderRadius: "5px" } }}
|
|
232
|
-
t={t}
|
|
233
|
-
/>
|
|
234
|
-
</div>
|
|
235
|
-
</Modal>
|
|
236
|
-
)}
|
|
237
|
-
</React.Fragment>
|
|
238
|
-
);
|
|
239
|
-
};
|
|
240
|
-
|
|
241
|
-
export default ConnectionDetailsView;
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
import React, { useMemo } from "react";
|
|
2
|
-
import StatusCards from "./StatusCards";
|
|
3
|
-
import { Card, Loader } from "@djb25/digit-ui-react-components";
|
|
4
|
-
|
|
5
|
-
// Mock data removed in favor of API integration
|
|
6
|
-
|
|
7
|
-
const Dashboard = () => {
|
|
8
|
-
const tenantId = Digit.ULBService.getCurrentTenantId();
|
|
9
|
-
|
|
10
|
-
// 2. API Data Fetching
|
|
11
|
-
const { isLoading, data: dashboardData } = Digit.Hooks.ekyc.useEkycSurveyorDashboard(
|
|
12
|
-
{},
|
|
13
|
-
{
|
|
14
|
-
tenantId,
|
|
15
|
-
offset: 0,
|
|
16
|
-
limit: 10,
|
|
17
|
-
},
|
|
18
|
-
{
|
|
19
|
-
enabled: !!tenantId,
|
|
20
|
-
}
|
|
21
|
-
);
|
|
22
|
-
|
|
23
|
-
const countData = useMemo(() => {
|
|
24
|
-
const info = dashboardData?.dashboardInfo || {};
|
|
25
|
-
return {
|
|
26
|
-
total: info.total || 0,
|
|
27
|
-
completed: info.completed || 0,
|
|
28
|
-
pending: info.pending || 0,
|
|
29
|
-
rejected: info.rejected || 0,
|
|
30
|
-
active: info.active || 0,
|
|
31
|
-
};
|
|
32
|
-
}, [dashboardData]);
|
|
33
|
-
|
|
34
|
-
return isLoading ? (
|
|
35
|
-
<Loader />
|
|
36
|
-
) : (
|
|
37
|
-
<Card className="min-width-full">
|
|
38
|
-
<StatusCards countData={countData} />
|
|
39
|
-
</Card>
|
|
40
|
-
);
|
|
41
|
-
};
|
|
42
|
-
|
|
43
|
-
export default Dashboard;
|