@djb25/digit-ui-module-ekyc 1.0.9 → 1.0.10

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,6 +1,6 @@
1
1
  {
2
2
  "name": "@djb25/digit-ui-module-ekyc",
3
- "version": "1.0.9",
3
+ "version": "1.0.10",
4
4
  "description": "Digit UI Module for Ekyc",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.modern.js",
package/src/Module.js CHANGED
@@ -3,7 +3,7 @@ import { useTranslation } from "react-i18next";
3
3
  import { useRouteMatch } from "react-router-dom";
4
4
  import { CitizenHomeCard, DocumentIcon } from "@djb25/digit-ui-react-components";
5
5
  import EKYCCard from "./components/EKYCCard";
6
- import Inbox from "./pages/employee/Dashboard";
6
+ import Inbox from "./components/Dashboard";
7
7
  import DesktopInbox from "./components/DesktopInbox";
8
8
  import MobileInbox from "./components/MobileInbox";
9
9
  import Filter from "./components/Filter";
@@ -13,16 +13,11 @@ import AadhaarVerification from "./pages/employee/AadhaarVerification";
13
13
  import AddressDetails from "./pages/employee/AddressDetails";
14
14
  import PropertyInfo from "./pages/employee/PropertyInfo";
15
15
  import MeterDetails from "./pages/employee/MeterDetails";
16
- export const EkycModule = ({ stateCode, userType, tenants }) => {
16
+ export const EkycModule = ({ userType, tenants }) => {
17
17
  const { path, url } = useRouteMatch();
18
- const moduleCode = "EKYC";
19
- const language = Digit.StoreData.getCurrentLanguage();
20
- const { isLoading, data: store } = Digit.Services.useStore({ stateCode, moduleCode, language });
18
+
21
19
  Digit.SessionStorage.set("EKYC_TENANTS", tenants);
22
20
 
23
- if (isLoading) {
24
- return null;
25
- }
26
21
  if (userType === "employee") {
27
22
  return <EmployeeApp path={path} url={url} userType={userType} tenants={tenants} />;
28
23
  } else return <CitizenApp />;
@@ -1,10 +1,10 @@
1
1
  import React, { useMemo } from "react";
2
- import StatusCards from "../../components/StatusCards";
2
+ import StatusCards from "./StatusCards";
3
3
  import { Card, Loader } from "@djb25/digit-ui-react-components";
4
4
 
5
5
  // Mock data removed in favor of API integration
6
6
 
7
- const Dashboard = ({ parentRoute, businessService = "EKYC", initialStates = {}, filterComponent, isInbox }) => {
7
+ const Dashboard = () => {
8
8
  const tenantId = Digit.ULBService.getCurrentTenantId();
9
9
 
10
10
  // 2. API Data Fetching
@@ -34,7 +34,7 @@ const Dashboard = ({ parentRoute, businessService = "EKYC", initialStates = {},
34
34
  return isLoading ? (
35
35
  <Loader />
36
36
  ) : (
37
- <Card>
37
+ <Card className="min-width-full">
38
38
  <StatusCards countData={countData} />
39
39
  </Card>
40
40
  );
@@ -0,0 +1,41 @@
1
+ import React from "react";
2
+ import { useTranslation } from "react-i18next";
3
+ import { ModuleLinksView } from "@djb25/digit-ui-react-components";
4
+ const Home = () => {
5
+ const { t } = useTranslation();
6
+ const propsForModuleCard = {
7
+ moduleName: t("ACTION_TEST_EKYC"),
8
+ kpis: [
9
+ {
10
+ count: "-",
11
+ label: t("TOTAL_EKYC"),
12
+ link: `/digit-ui/citizen/ekyc/dashboard`,
13
+ },
14
+ ],
15
+ links: [
16
+ {
17
+ label: t("EKYC_DASHBOARD"),
18
+ link: `/digit-ui/citizen/ekyc/dashboard`,
19
+ },
20
+ {
21
+ label: t("EKYC_INBOX"),
22
+ link: `/digit-ui/citizen/ekyc/inbox`,
23
+ },
24
+ // {
25
+ // label: t("EKYC_CREATE_KYC"),
26
+ // link: `/digit-ui/citizen/ekyc/create-kyc`
27
+ // },
28
+ // {
29
+ // label: t("EKYC_UPDATE_KYC"),
30
+ // link: `/digit-ui/citizen/ekyc/update-kyc`
31
+ // },
32
+ {
33
+ label: t("EKYC_MAPPING"),
34
+ link: `/digit-ui/citizen/ekyc/mapping`,
35
+ },
36
+ ],
37
+ };
38
+ return <ModuleLinksView links={propsForModuleCard.links} />;
39
+ };
40
+
41
+ export default Home;
@@ -0,0 +1,255 @@
1
+ import React, { useMemo, useCallback, useReducer } from "react";
2
+ import { useLocation } from "react-router-dom";
3
+ import { InboxComposer } from "@djb25/digit-ui-react-components";
4
+ import useInboxTableConfig from "../../hook/useInboxTableConfig";
5
+ import SearchFormFieldsComponents from "../../components/SearchFormFieldsComponent";
6
+
7
+ // Mock data removed in favor of API integration
8
+
9
+ const Inbox = ({ parentRoute }) => {
10
+ const tenantId = Digit.ULBService.getCurrentTenantId();
11
+ const location = useLocation();
12
+
13
+ const formInitValue = {
14
+ filterForm: {},
15
+ searchForm: {},
16
+ tableForm: {
17
+ limit: 10,
18
+ offset: 0,
19
+ sortBy: "createdTime",
20
+ sortOrder: "DESC",
21
+ },
22
+ };
23
+
24
+ const [formState, dispatch] = useReducer(formReducer, formInitValue);
25
+
26
+ const queryParams = useMemo(() => {
27
+ return {
28
+ tenantId,
29
+ offset: formState?.tableForm?.offset || 0,
30
+ limit: formState?.tableForm?.limit || 10,
31
+ search: formState?.searchForm || {},
32
+ };
33
+ }, [tenantId, formState?.tableForm?.offset, formState?.tableForm?.limit, formState?.searchForm]);
34
+
35
+ const { isLoading, data: dashboardData = {} } = Digit.Hooks.ekyc.useEkycSurveyorDashboard({}, queryParams, {
36
+ enabled: !!tenantId,
37
+ keepPreviousData: true,
38
+ });
39
+
40
+ const searchDetails = useMemo(
41
+ () => ({
42
+ kno: formState?.searchForm?.kNumber || "",
43
+ name: formState?.searchForm?.kName || "",
44
+ }),
45
+ [formState?.searchForm?.kNumber, formState?.searchForm?.kName]
46
+ );
47
+
48
+ const isSearchActive = !!(searchDetails.kno || searchDetails.name);
49
+
50
+ const { isLoading: isSearchLoading, data: searchData } = Digit.Hooks.ekyc.useSearchConnection(
51
+ {
52
+ tenantId,
53
+ details: searchDetails,
54
+ },
55
+ {
56
+ enabled: !!tenantId && !!searchDetails.kno, // 🔥 important
57
+ keepPreviousData: true,
58
+ }
59
+ );
60
+
61
+ const sourceData = useMemo(() => {
62
+ if (isSearchActive) {
63
+ if (!searchData) return [];
64
+ return [searchData];
65
+ }
66
+
67
+ return dashboardData?.dashboardInfo?.consumerList || [];
68
+ }, [isSearchActive, searchData, dashboardData]);
69
+
70
+ const filteredData = useMemo(() => {
71
+ return (sourceData || []).map((item) => {
72
+ // ✅ detect search response
73
+ const isSearchItem = !!item.connectionDetails;
74
+
75
+ if (isSearchItem) {
76
+ return {
77
+ applicationNo: item.propertyInfo?.kno || "",
78
+ connectionNo: item.propertyInfo?.kno || "",
79
+ owner: item.connectionDetails?.consumerName || "",
80
+ applicationNumber: item.propertyInfo?.kno || "",
81
+ citizenName: item.connectionDetails?.consumerName || "",
82
+ status: item.connectionDetails?.statusflag || "",
83
+ sla: 0,
84
+ };
85
+ }
86
+
87
+ // ✅ dashboard mapping
88
+ return {
89
+ ...item,
90
+ applicationNo: item.kno || item.applicationNumber || "",
91
+ connectionNo: item.connectionNo || "",
92
+ owner: item.consumerName || item.citizenName || "",
93
+ applicationNumber: item.kno || item.applicationNumber || "",
94
+ citizenName: item.consumerName || item.citizenName || "",
95
+ status: item.status || "",
96
+ sla: item.sla ?? 0,
97
+ };
98
+ });
99
+ }, [sourceData]);
100
+
101
+ const totalRecords = dashboardData?.dashboardInfo?.totalRecords || dashboardData?.totalCount || 0;
102
+
103
+ const checkPathName = location.pathname.includes("ekyc/inbox");
104
+ const PropsForInboxLinks = {
105
+ headerText: checkPathName ? "MODULE_WATER" : "MODULE_SW",
106
+ };
107
+
108
+ const SearchFormFields = useCallback(
109
+ ({ registerRef, searchFormState, controlSearchForm }) => (
110
+ <SearchFormFieldsComponents {...{ registerRef, searchFormState, controlSearchForm }} className="search" />
111
+ ),
112
+ []
113
+ );
114
+
115
+ const tableOrderFormDefaultValues = {
116
+ sortBy: "createdTime",
117
+ limit: window.Digit.Utils.browser.isMobile() ? 50 : 10,
118
+ offset: 0,
119
+ sortOrder: "DESC",
120
+ };
121
+
122
+ const onSearchFormSubmit = (data) => {
123
+ data.hasOwnProperty("") && delete data?.[""];
124
+ dispatch({ action: "mutateTableForm", data: { ...tableOrderFormDefaultValues }, checkPathName });
125
+ dispatch({ action: "mutateSearchForm", data, checkPathName });
126
+ };
127
+
128
+ const searchFormDefaultValues = {
129
+ mobileNumber: "",
130
+ applicationNumber: "",
131
+ consumerNo: "",
132
+ };
133
+
134
+ const onSearchFormReset = (setSearchFormValue) => {
135
+ setSearchFormValue("mobileNumber", null);
136
+ setSearchFormValue("applicationNumber", null);
137
+ setSearchFormValue("consumerNo", null);
138
+ dispatch({ action: "mutateSearchForm", data: searchFormDefaultValues });
139
+ };
140
+
141
+ const propsForSearchForm = {
142
+ SearchFormFields,
143
+ onSearchFormSubmit,
144
+ searchFormDefaultValues: formState?.searchForm,
145
+ resetSearchFormDefaultValues: searchFormDefaultValues,
146
+ onSearchFormReset,
147
+ className: "search-form-wns-inbox",
148
+ };
149
+
150
+ const FilterFormFields = useCallback(
151
+ ({ registerRef, controlFilterForm, setFilterFormValue, getFilterFormValue }) => <React.Fragment></React.Fragment>,
152
+ []
153
+ );
154
+
155
+ const propsForFilterForm = {
156
+ FilterFormFields,
157
+ onFilterFormSubmit: () => {},
158
+ filterFormDefaultValues: "",
159
+ resetFilterFormDefaultValues: "",
160
+ onFilterFormReset: () => {},
161
+ };
162
+
163
+ function formReducer(state, payload) {
164
+ const storageKey = payload.checkPathName ? "EKYC.INBOX" : "EKYC.SW.INBOX";
165
+
166
+ // ✅ safety for SLA
167
+ switch (payload.action) {
168
+ case "mutateSearchForm":
169
+ Digit.SessionStorage.set(storageKey, { ...state, searchForm: payload.data });
170
+ return { ...state, searchForm: payload.data };
171
+
172
+ case "mutateFilterForm":
173
+ Digit.SessionStorage.set(storageKey, { ...state, filterForm: payload.data });
174
+ return { ...state, filterForm: payload.data };
175
+
176
+ case "mutateTableForm":
177
+ Digit.SessionStorage.set(storageKey, { ...state, tableForm: payload.data });
178
+ return { ...state, tableForm: payload.data };
179
+
180
+ default:
181
+ return state; // ✅ IMPORTANT
182
+ }
183
+ }
184
+
185
+ const onPageSizeChange = (e) => {
186
+ const newLimit = Number(e.target.value);
187
+
188
+ dispatch({
189
+ action: "mutateTableForm",
190
+ data: {
191
+ ...formState.tableForm,
192
+ limit: newLimit,
193
+ offset: 0, // reset page
194
+ },
195
+ checkPathName,
196
+ });
197
+ };
198
+
199
+ const onSortingByData = (e) => {
200
+ if (e.length > 0) {
201
+ const [{ id, desc }] = e;
202
+ const sortOrder = desc ? "DESC" : "ASC";
203
+ const sortBy = id;
204
+
205
+ if (!(formState.tableForm.sortBy === sortBy && formState.tableForm.sortOrder === sortOrder)) {
206
+ dispatch({
207
+ action: "mutateTableForm",
208
+ data: {
209
+ ...formState.tableForm,
210
+ sortBy: id,
211
+ sortOrder: desc ? "DESC" : "ASC",
212
+ },
213
+ checkPathName,
214
+ });
215
+ }
216
+ }
217
+ };
218
+
219
+ const propsForInboxTable = useInboxTableConfig({
220
+ ...{
221
+ parentRoute,
222
+ onPageSizeChange,
223
+ formState,
224
+ totalCount: totalRecords,
225
+ table: filteredData,
226
+ dispatch,
227
+ onSortingByData,
228
+ tenantId,
229
+ checkPathName,
230
+ inboxStyles: { overflowX: "scroll", overflowY: "hidden" },
231
+ tableStyle: { width: "70%" },
232
+ },
233
+ });
234
+
235
+ const isInboxLoading = isLoading || isSearchLoading;
236
+
237
+ return (
238
+ <div className="app-container">
239
+ <InboxComposer
240
+ {...{
241
+ isInboxLoading,
242
+ PropsForInboxLinks,
243
+ ...propsForSearchForm,
244
+ ...propsForFilterForm,
245
+ // ...propsForMobileSortForm,
246
+ propsForInboxTable,
247
+ // propsForInboxMobileCards,
248
+ formState,
249
+ }}
250
+ />
251
+ </div>
252
+ );
253
+ };
254
+
255
+ export default Inbox;
@@ -8,83 +8,62 @@ import AddressDetails from "../employee/AddressDetails";
8
8
  import PropertyInfo from "../employee/PropertyInfo";
9
9
  import MeterDetails from "../employee/MeterDetails";
10
10
  import Review from "../employee/Review";
11
+ import Home from "./Home";
12
+ import Dashboard from "../../components/Dashboard";
13
+ import Inbox from "./Inbox";
11
14
 
12
15
  const CitizenApp = () => {
13
- const { t } = useTranslation();
14
- const location = useLocation();
15
- const { path } = useRouteMatch();
16
+ const { t } = useTranslation();
17
+ const location = useLocation();
18
+ const { path } = useRouteMatch();
16
19
 
17
- sessionStorage.removeItem("revalidateddone");
20
+ sessionStorage.removeItem("revalidateddone");
18
21
 
19
- const getBreadcrumbLabel = () => {
20
- const pathname = location.pathname;
21
- if (pathname.includes("/create-kyc")) return "EKYC_CREATE_KYC";
22
- if (pathname.includes("/aadhaar-verification")) return "EKYC_AADHAAR_VERIFICATION";
23
- if (pathname.includes("/address-details")) return "EKYC_ADDRESS_DETAILS";
24
- if (pathname.includes("/property-info")) return "EKYC_PROPERTY_INFO";
25
- if (pathname.includes("/meter-details")) return "EKYC_METER_DETAILS";
26
- if (pathname.includes("/review")) return "EKYC_REVIEW";
27
- return "EKYC_HOME";
28
- };
22
+ const getBreadcrumbLabel = () => {
23
+ const pathname = location.pathname;
24
+ if (pathname.includes("/create-kyc")) return "EKYC_CREATE_KYC";
25
+ if (pathname.includes("/aadhaar-verification")) return "EKYC_AADHAAR_VERIFICATION";
26
+ if (pathname.includes("/address-details")) return "EKYC_ADDRESS_DETAILS";
27
+ if (pathname.includes("/property-info")) return "EKYC_PROPERTY_INFO";
28
+ if (pathname.includes("/meter-details")) return "EKYC_METER_DETAILS";
29
+ if (pathname.includes("/review")) return "EKYC_REVIEW";
30
+ return "EKYC_HOME";
31
+ };
29
32
 
30
- const breadcrumbs = [
31
- { icon: HomeIcon, path: "/digit-ui/citizen" },
32
- { label: t(getBreadcrumbLabel()) }
33
- ];
33
+ const breadcrumbs = [{ icon: HomeIcon, path: "/digit-ui/citizen" }, { label: t(getBreadcrumbLabel()) }];
34
34
 
35
- return (
36
- <AppContainer>
37
- <div className="ground-container employee-app-container form-container">
38
- <ModuleHeader
39
- leftContent={
40
- <React.Fragment>
41
- <ArrowLeft className="icon" />
42
- {t("CS_COMMON_BACK")}
43
- </React.Fragment>
44
- }
45
- onLeftClick={() => window.history.back()}
46
- breadcrumbs={breadcrumbs}
47
- />
35
+ return (
36
+ <AppContainer>
37
+ <div className="ground-container employee-app-container form-container">
38
+ <ModuleHeader
39
+ leftContent={
40
+ <React.Fragment>
41
+ <ArrowLeft className="icon" />
42
+ {t("CS_COMMON_BACK")}
43
+ </React.Fragment>
44
+ }
45
+ onLeftClick={() => window.history.back()}
46
+ breadcrumbs={breadcrumbs}
47
+ />
48
48
 
49
- <Switch>
50
- <PrivateRoute
51
- path={`${path}/create-kyc`}
52
- component={() => <Create />}
53
- />
49
+ <Switch>
50
+ <PrivateRoute exact path={`${path}`} component={() => <Home />} />
51
+ <PrivateRoute path={`${path}/dashboard`} component={() => <Dashboard />} />
52
+ <PrivateRoute path={`${path}/inbox`} component={() => <Inbox />} />
54
53
 
55
- <PrivateRoute
56
- path={`${path}/aadhaar-verification`}
57
- component={() => <AadhaarVerification />}
58
- />
54
+ <PrivateRoute path={`${path}/aadhaar-verification`} component={() => <AadhaarVerification />} />
59
55
 
60
- <PrivateRoute
61
- path={`${path}/address-details`}
62
- component={() => <AddressDetails />}
63
- />
56
+ <PrivateRoute path={`${path}/address-details`} component={() => <AddressDetails />} />
64
57
 
65
- <PrivateRoute
66
- path={`${path}/property-info`}
67
- component={() => <PropertyInfo />}
68
- />
58
+ <PrivateRoute path={`${path}/property-info`} component={() => <PropertyInfo />} />
69
59
 
70
- <PrivateRoute
71
- path={`${path}/meter-details`}
72
- component={() => <MeterDetails />}
73
- />
60
+ <PrivateRoute path={`${path}/meter-details`} component={() => <MeterDetails />} />
74
61
 
75
- <PrivateRoute
76
- path={`${path}/review`}
77
- component={() => <Review />}
78
- />
79
-
80
- <PrivateRoute
81
- path={`${path}/`}
82
- component={() => <Create />}
83
- />
84
- </Switch>
85
- </div>
86
- </AppContainer>
87
- );
62
+ <PrivateRoute path={`${path}/review`} component={() => <Review />} />
63
+ </Switch>
64
+ </div>
65
+ </AppContainer>
66
+ );
88
67
  };
89
68
 
90
69
  export default CitizenApp;
@@ -2,7 +2,7 @@ import { AppContainer, PrivateRoute, ModuleHeader, ArrowLeft, HomeIcon } from "@
2
2
  import React from "react";
3
3
  import { useTranslation } from "react-i18next";
4
4
  import { Switch, useLocation } from "react-router-dom";
5
- import Dashboard from "./Dashboard";
5
+ import Dashboard from "../../components/Dashboard";
6
6
  import Inbox from "./Inbox";
7
7
  import Mapping from "./Mapping";
8
8
  import Create from "./Create";