@djb25/digit-ui-module-ekyc 1.0.12 → 1.0.14

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/package.json CHANGED
@@ -1,30 +1,35 @@
1
1
  {
2
- "name": "@djb25/digit-ui-module-ekyc",
3
- "version": "1.0.12",
4
- "description": "Digit UI Module for Ekyc",
5
- "main": "dist/index.js",
6
- "module": "dist/index.modern.js",
7
- "source": "src/Module.js",
8
- "scripts": {
9
- "start": "microbundle-crl watch --no-compress --format modern,cjs",
10
- "build": "microbundle-crl --compress --no-sourcemap --format cjs",
11
- "prepublish": "yarn build"
12
- },
13
- "keywords": [
14
- "digit-ui",
15
- "module",
16
- "ekyc"
17
- ],
18
- "author": "Shivam Nishad",
19
- "license": "ISC",
20
- "dependencies": {
21
- "@djb25/digit-ui-react-components": "1.0.0",
22
- "microbundle-crl": "^0.13.11",
23
- "react": "17.0.2",
24
- "react-dom": "17.0.2",
25
- "react-i18next": "11.16.2",
26
- "react-icons": "^5.6.0",
27
- "react-router-dom": "5.3.0",
28
- "chart.js": "^4.4.1"
29
- }
30
- }
2
+ "name": "@djb25/digit-ui-module-ekyc",
3
+ "version": "1.0.14",
4
+ "description": "Digit UI Module for Ekyc",
5
+ "main": "dist/index.js",
6
+ "module": "dist/index.modern.js",
7
+ "source": "src/Module.js",
8
+ "scripts": {
9
+ "start": "microbundle-crl watch --no-compress --format modern,cjs",
10
+ "build": "microbundle-crl --compress --no-sourcemap --format cjs",
11
+ "prepublish": "yarn build"
12
+ },
13
+ "keywords": [
14
+ "digit-ui",
15
+ "module",
16
+ "ekyc"
17
+ ],
18
+ "author": "Shivam Nishad",
19
+ "license": "ISC",
20
+ "dependencies": {
21
+ "@djb25/digit-ui-react-components": "1.0.0",
22
+ "chart.js": "^4.4.1",
23
+ "microbundle-crl": "^0.13.11",
24
+ "react": "17.0.2",
25
+ "react-dom": "17.0.2",
26
+ "react-i18next": "11.16.2",
27
+ "react-icons": "^5.6.0",
28
+ "react-router-dom": "5.3.0",
29
+ "recharts": "^2.1.13",
30
+ "react-smooth": "2.0.1"
31
+ },
32
+ "resolutions": {
33
+ "fast-equals": "2.0.4"
34
+ }
35
+ }
package/src/Module.js CHANGED
@@ -13,12 +13,12 @@ import PropertyInfo from "./components/PropertyInfo";
13
13
  import MeterDetails from "./components/MeterDetails";
14
14
  import AadhaarVerification from "./components/AadhaarVerification";
15
15
  import AddressDetails from "./components/AddressDetails";
16
- export const EkycModule = ({ stateCode, userType, tenants }) => {
17
16
 
17
+ export const EkycModule = ({ stateCode, userType, tenants }) => {
18
18
  const { path, url } = useRouteMatch();
19
19
  const moduleCode = "EKYC";
20
20
  const language = Digit.StoreData.getCurrentLanguage();
21
- const { isLoading, data: store } = Digit.Services.useStore({ stateCode, moduleCode, language });
21
+ const { isLoading } = Digit.Services.useStore({ stateCode, moduleCode, language });
22
22
 
23
23
  Digit.SessionStorage.set("EKYC_TENANTS", tenants);
24
24
 
@@ -1,205 +1,264 @@
1
- import React, { useState, useMemo } from "react";
2
- import { useTranslation } from "react-i18next";
3
- import "./analytics/styles/Dashboard.css";
4
-
5
-
6
- // Hooks
7
- import useInboxRouting from "./analytics/hooks/useInboxRouting";
8
-
9
- // Components
10
- import DashboardLayout from "./analytics/components/DashboardLayout";
11
- import FilterBar from "./analytics/components/FilterBar";
12
- import SummaryCard from "./analytics/components/SummaryCard";
13
- import TaskStatusChart from "./analytics/charts/TaskStatusChart";
14
- import ClusterHeatmap from "./analytics/charts/ClusterHeatmap";
15
- import AnalyticsTable from "./analytics/components/AnalyticsTable";
16
- import SLAWidget from "./analytics/components/SLAWidget";
17
- import WorkflowTimeline from "./analytics/components/WorkflowTimeline";
18
- import NotificationPanel from "./analytics/components/NotificationPanel";
19
- import SkeletonLoader from "./analytics/components/SkeletonLoader";
20
- import ErrorBoundary from "./analytics/components/ErrorBoundary";
21
- import EmptyState from "./analytics/components/EmptyState";
1
+ import React from "react";
2
+ import { FaUsers, FaUserTie, FaMapMarkedAlt, FaCheckCircle, FaClock, FaExclamationTriangle, FaChartLine } from "react-icons/fa";
22
3
 
23
- const CeoDashboard = () => {
24
- const { t } = useTranslation();
25
- const { routeToInbox } = useInboxRouting();
26
-
27
- // 1. Dashboard State
28
- const [activeRole, setActiveRole] = useState("CEO");
29
- const [isNotificationOpen, setIsNotificationOpen] = useState(false);
30
- const [filters, setFilters] = useState({
31
- financialYear: "2025-26",
32
- clusterId: "ALL",
33
- agencyId: "ALL"
34
- });
35
-
36
- // 2. Fetch Config & Data
37
- const { config, tenantId } = Digit.Hooks.ekyc.useEkycDashboardConfigs(activeRole);
38
- const {
39
- summary: kpiData, agencies: agencyData, heatmap: clusterData, workflow: workflowData,
40
- isLoading, isError
41
- } = Digit.Hooks.ekyc.useEkycDashboardData(activeRole, filters);
42
-
43
- // 3. Handlers
44
- const handleFilterChange = (id, value) => {
45
- setFilters(prev => ({ ...prev, [id]: value }));
46
- };
47
-
48
- const handleReset = () => {
49
- setFilters({ financialYear: "2025-26", clusterId: "ALL", agencyId: "ALL" });
50
- };
51
-
52
- const handleKpiClick = (kpi) => {
53
- routeToInbox(kpi.targetRoute, { ...filters, status: kpi.status });
54
- };
55
-
56
- // Mock Notifications
57
- const notifications = [
58
- { title: "EKYC_SLA_BREACH_ALERT", message: "EKYC_ALERT_DESC_1", priority: "HIGH", time: "10m ago" },
59
- { title: "EKYC_SYSTEM_UPDATE", message: "EKYC_ALERT_DESC_3", priority: "NORMAL", time: "5h ago" }
60
- ];
61
-
62
- // 4. Render Logic
63
- if (isError) return <EmptyState message="EKYC_ERROR_FETCHING_DATA" />;
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
+ ];
64
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 = () => {
65
76
  return (
66
- <DashboardLayout
67
- header={config.title}
68
- activeRole={activeRole}
69
- onRoleChange={(role) => {
70
- setActiveRole(role);
71
- handleReset();
72
- }}
73
- onNotificationClick={() => setIsNotificationOpen(true)}
74
- filters={
75
- <FilterBar
76
- filters={filters}
77
- config={config.globalFilters}
78
- onFilterChange={handleFilterChange}
79
- onReset={handleReset}
80
- />
81
- }
82
- >
83
- <NotificationPanel
84
- isOpen={isNotificationOpen}
85
- onClose={() => setIsNotificationOpen(false)}
86
- notifications={notifications}
87
- />
88
-
89
- {/* KPI Section */}
90
- <section style={{ marginBottom: "32px" }}>
91
- {isLoading ? (
92
- <SkeletonLoader type="card" count={4} />
93
- ) : (
94
- <div style={{ display: "grid", gridTemplateColumns: "repeat(auto-fill, minmax(280px, 1fr))", gap: "24px" }}>
95
- {config?.widgets?.summary?.map((kpiKey, idx) => {
96
- const kpiMeta = config?.kpis?.[kpiKey];
97
- if (!kpiMeta) return null;
98
-
99
- const value = kpiData?.[kpiKey] || 0;
100
- return (
101
- <ErrorBoundary key={kpiKey}>
102
- <div className="animate-fade-in" style={{ animationDelay: `${idx * 0.1}s` }}>
103
- <SummaryCard
104
- label={kpiMeta.label}
105
- value={value}
106
- color={kpiMeta.color}
107
- icon={kpiMeta.icon}
108
- trend={kpiData?.[`${kpiKey}Trend`]}
109
- onClick={() => handleKpiClick(kpiMeta)}
110
- />
111
- </div>
112
- </ErrorBoundary>
113
- );
114
- })}
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>
115
120
  </div>
116
- )}
117
- </section>
118
-
119
- {/* Main Analytics Grid */}
120
- <div style={{ display: "grid", gridTemplateColumns: "repeat(12, 1fr)", gap: "24px" }}>
121
-
122
-
123
-
124
- {/* Workflow Distribution */}
125
- <div style={{ gridColumn: "span 12", background: "#FFF", padding: "24px", borderRadius: "16px", boxShadow: "0 1px 3px rgba(0,0,0,0.1)" }}>
126
- {isLoading ? (
127
- <SkeletonLoader type="chart" />
128
- ) : (
129
- <ErrorBoundary>
130
- <TaskStatusChart
131
- title="EKYC_APPLICATION_STATUS"
132
- data={workflowData?.stageBreakdown || []}
133
- />
134
- </ErrorBoundary>
135
- )}
136
- </div>
137
-
138
- {/* SLA & Timeline Bottlenecks */}
139
- <div style={{ gridColumn: "span 4" }}>
140
- {isLoading ? (
141
- <SkeletonLoader type="chart" />
142
- ) : (
143
- <ErrorBoundary>
144
- <SLAWidget
145
- slaPercentage={workflowData?.slaCompliance || 0}
146
- avgTime={workflowData?.avgProcessingTimeHours || 0}
147
- breachedCount={workflowData?.breachCount || 0}
148
- />
149
- </ErrorBoundary>
150
- )}
151
- </div>
152
-
153
- <div style={{ gridColumn: "span 8" }}>
154
- {isLoading ? (
155
- <SkeletonLoader type="chart" />
156
- ) : (
157
- <ErrorBoundary>
158
- <WorkflowTimeline stages={workflowData?.stageBreakdown || []} />
159
- </ErrorBoundary>
160
- )}
161
- </div>
162
-
163
- {/* Spatial Cluster Analysis */}
164
- <div style={{ gridColumn: "span 12", background: "#FFF", padding: "24px", borderRadius: "16px", boxShadow: "0 1px 3px rgba(0,0,0,0.1)" }}>
165
- {isLoading ? (
166
- <SkeletonLoader type="chart" />
167
- ) : (
168
- <ErrorBoundary>
169
- <ClusterHeatmap
170
- title="EKYC_CLUSTER_WORKLOAD_HEATMAP"
171
- data={clusterData || []}
172
- onDrillDown={(cluster) => handleFilterChange("clusterId", cluster.clusterId)}
173
- />
174
- </ErrorBoundary>
175
- )}
176
- </div>
177
-
178
- {/* Agency Performance Table */}
179
- <div style={{ gridColumn: "span 12" }}>
180
- {isLoading ? (
181
- <SkeletonLoader type="table" />
182
- ) : (
183
- <ErrorBoundary>
184
- <AnalyticsTable
185
- title="EKYC_AGENCY_PERFORMANCE_METRICS"
186
- filename="agency_performance_report.csv"
187
- data={agencyData || []}
188
- columns={[
189
- { id: "agencyName", label: "EKYC_AGENCY_NAME" },
190
- { id: "totalAssigned", label: "EKYC_TOTAL_ASSIGNED" },
191
- { id: "totalCompleted", label: "EKYC_TOTAL_COMPLETED" },
192
- { id: "pendingCount", label: "EKYC_PENDING" },
193
- { id: "slaCompliance", label: "EKYC_SLA_COMPLIANCE", isPercentage: true }
194
- ]}
195
- />
196
- </ErrorBoundary>
197
- )}
198
- </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>
199
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>
200
259
  </div>
201
- </DashboardLayout>
260
+ </div>
202
261
  );
203
262
  };
204
263
 
205
- export default CeoDashboard;
264
+ export default CeoDashboard;