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