@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,176 +0,0 @@
1
- import React, { useMemo, useState } from "react";
2
- import { useTranslation } from "react-i18next";
3
- import { Table, Card, Loader, InboxLinks } from "@djb25/digit-ui-react-components";
4
- import { useHistory } from "react-router-dom";
5
- import StatusCards from "./StatusCards";
6
-
7
- const DesktopInbox = ({ tableConfig, filterComponent, ...props }) => {
8
- const {
9
- data,
10
- isLoading,
11
- onSort,
12
- onNextPage,
13
- onPrevPage,
14
- currentPage,
15
- pageSizeLimit,
16
- onPageSizeChange,
17
- parentRoute,
18
- searchParams,
19
- sortParams,
20
- totalRecords,
21
- countData,
22
- } = props;
23
- const { t } = useTranslation();
24
- const history = useHistory();
25
- const tenantId = Digit.ULBService.getCurrentTenantId();
26
- const FilterComponent = Digit.ComponentRegistryService?.getComponent(filterComponent);
27
-
28
- // State for Review Modal
29
- const [selectedKno, setSelectedKno] = useState("");
30
- const { data: reviewData, getReview } = Digit.Hooks.ekyc.useEkycAPI("review", tenantId);
31
- const handleReview = (kno) => {
32
- setSelectedKno(kno);
33
- getReview({ kno });
34
- };
35
-
36
- React.useEffect(() => {
37
- if (reviewData) {
38
- history.push("/digit-ui/employee/ekyc/review", { kNumber: selectedKno, aadhaarData: reviewData?.aadhaarData, reviewData });
39
- }
40
- // eslint-disable-next-line react-hooks/exhaustive-deps
41
- }, [reviewData]);
42
-
43
- const columns = useMemo(
44
- () => [
45
- {
46
- Header: t("EKYC_APPLICATION_NO"),
47
- accessor: "applicationNumber",
48
- Cell: ({ row }) => {
49
- const kno = row.original?.kno || row.original?.applicationNumber || "NA";
50
- return (
51
- <span
52
- className="ekyc-application-link"
53
- style={{ color: "#add8f7", cursor: "pointer", fontWeight: "bold" }}
54
- onClick={() => handleReview(kno)}
55
- >
56
- {kno}
57
- </span>
58
- );
59
- },
60
- },
61
- {
62
- Header: t("EKYC_CITIZEN_NAME"),
63
- accessor: "citizenName",
64
- Cell: ({ row }) => <span>{row.original?.citizenName || "NA"}</span>,
65
- },
66
- // {
67
- // Header: t("EKYC_MOBILE_NO"),
68
- // accessor: "mobileNumber",
69
- // Cell: ({ row }) => <span>{row.original?.mobileNumber || "NA"}</span>,
70
- // },
71
- {
72
- Header: t("EKYC_STATUS"),
73
- accessor: "actionStatus",
74
- Cell: ({ row }) => {
75
- const status = row.original?.status || "DEFAULT";
76
- return <span className={`ekyc-status-tag ${status}`}>{t(`${status}`)}</span>;
77
- },
78
- },
79
- {
80
- Header: t("EKYC_EKYC_STATUS"),
81
- accessor: "ekycStatus",
82
- Cell: ({ row }) => {
83
- const ekycStatus = (row.original?.ekycStatus || row.original?.ekycstatus || "NA").toUpperCase();
84
- return <span className={`ekyc-status-tag ${ekycStatus}`}>{t(`${ekycStatus}`)}</span>
85
- }
86
- },
87
- {
88
- Header: t("EKYC_ACTION"),
89
- accessor: "status",
90
- Cell: ({ row }) => {
91
- const kno = row.original?.kno || row.original?.applicationNumber || "NA";
92
- return (
93
- <span
94
- className="ekyc-application-link"
95
- style={{ color: "#add8f7", cursor: "pointer", fontWeight: "bold" }}
96
- onClick={() => handleReview(kno)}
97
- >
98
- {t("EKYC_REVIEW")}
99
- </span>
100
- );
101
- },
102
- },
103
- ],
104
- // eslint-disable-next-line react-hooks/exhaustive-deps
105
- [t, parentRoute]
106
- );
107
-
108
- const tableData = useMemo(() => {
109
- return data?.items || (Array.isArray(data) ? data : []);
110
- }, [data]);
111
-
112
- return (
113
- <div className="app-container">
114
- <div className="inbox-container">
115
- {isLoading && <Loader />}
116
- <div className="side-panel-item">
117
- {/* Sidebar Title Card */}
118
-
119
- <InboxLinks headerText={props.moduleCode} />
120
-
121
- {FilterComponent && (
122
- <FilterComponent
123
- defaultSearchParams={props.defaultSearchParams}
124
- onFilterChange={props.onSearch}
125
- searchParams={searchParams}
126
- type="desktop"
127
- moduleCode="EKYC"
128
- />
129
- )}
130
- </div>
131
-
132
- <div className="employee-form-content" style={{ flex: 1 }}>
133
- {/* Header Section (retaining for context/actions) */}
134
- {/* <div className="ekyc-header-container module-header" style={{ marginBottom: "16px", display: "flex", justifyContent: "space-between", alignItems: "center" }}>
135
- <Header className="title" style={{ margin: 0 }}>{t("EKYC_INBOX_HEADER")}</Header>
136
- <Link to={`${parentRoute}/create-kyc`}>
137
- <SubmitBar label={t("EKYC_CREATE_KYC")} style={{ borderRadius: "8px" }} />
138
- </Link>
139
- </div> */}
140
-
141
- {/* Metrics Section (The Card) */}
142
- <Card className="ekyc-metrics-card">
143
- <StatusCards countData={countData} />
144
- </Card>
145
-
146
- {/* Table Section */}
147
- <div className="result" style={{ flex: 1 }}>
148
- <Card className="ekyc-table-card" style={{ padding: 0 }}>
149
- <Table
150
- t={t}
151
- data={tableData}
152
- columns={columns}
153
- isLoading={isLoading}
154
- onSort={onSort}
155
- sortParams={sortParams}
156
- totalRecords={totalRecords}
157
- onNextPage={onNextPage}
158
- onPrevPage={onPrevPage}
159
- currentPage={currentPage}
160
- pageSizeLimit={pageSizeLimit}
161
- onPageSizeChange={onPageSizeChange}
162
- getCellProps={(cellInfo) => {
163
- return {
164
- className: "ekyc-table-cell",
165
- };
166
- }}
167
- />
168
- </Card>
169
- </div>
170
- </div>
171
- </div>
172
- </div>
173
- );
174
- };
175
-
176
- export default DesktopInbox;
@@ -1,53 +0,0 @@
1
- import { PersonIcon, EmployeeModuleCard } from "@djb25/digit-ui-react-components";
2
- import React from "react";
3
- import { useTranslation } from "react-i18next";
4
-
5
- const EKYCCard = () => {
6
- const { t } = useTranslation();
7
-
8
- const propsForModuleCard = {
9
- Icon: <PersonIcon />,
10
- moduleName: t("ACTION_TEST_EKYC"),
11
- kpis: [
12
- {
13
- count: "-",
14
- label: t("TOTAL_EKYC"),
15
- link: `/digit-ui/employee/ekyc/dashboard`,
16
- },
17
- ],
18
- links: [
19
- {
20
- label: t("CEO_M.F_DOR_FINANCE_VIEW"),
21
- link: `/digit-ui/employee/ekyc/ceo-dashboard`,
22
- },
23
- // {
24
- // label: t("EKYC_DASHBOARD"),
25
- // link: `/digit-ui/employee/ekyc/dashboard`,
26
- // },
27
- {
28
- label: t("EKYC_INBOX"),
29
- link: `/digit-ui/employee/ekyc/inbox`,
30
- },
31
- // {
32
- // label: t("EKYC_CREATE_KYC"),
33
- // link: `/digit-ui/employee/ekyc/create-kyc`
34
- // },
35
- // {
36
- // label: t("EKYC_UPDATE_KYC"),
37
- // link: `/digit-ui/employee/ekyc/update-kyc`
38
- // },
39
- // {
40
- // label: t("EKYC_MAPPING"),
41
- // link: `/digit-ui/employee/ekyc/mapping`,
42
- // },
43
- {
44
- label: t("EKYC_ASSIGN"),
45
- link: `/digit-ui/employee/ekyc/assign`,
46
- },
47
- ],
48
- };
49
-
50
- return <EmployeeModuleCard {...propsForModuleCard} />;
51
- };
52
-
53
- export default EKYCCard;
@@ -1,55 +0,0 @@
1
- import React, { useState } from "react";
2
- import { Dropdown, FilterForm, FilterFormField } from "@djb25/digit-ui-react-components";
3
- import { useTranslation } from "react-i18next";
4
-
5
- const Filter = ({ searchParams, onFilterChange, defaultSearchParams, statusMap, moduleCode, ...props }) => {
6
- const { t } = useTranslation();
7
-
8
- const [_searchParams, setSearchParams] = useState(() => ({ ...searchParams }));
9
-
10
- const applyLocalFilters = () => {
11
- onFilterChange(_searchParams);
12
- };
13
-
14
- const clearAll = () => {
15
- setSearchParams({ ...defaultSearchParams });
16
- onFilterChange({ ...defaultSearchParams });
17
- };
18
-
19
- const onStatusChange = (value) => {
20
- const newParams = { ..._searchParams, status: value };
21
- setSearchParams(newParams);
22
- onFilterChange(newParams);
23
- };
24
-
25
- return (
26
- <FilterForm
27
- onSubmit={applyLocalFilters}
28
- handleSubmit={(fn) => (e) => {
29
- e && e.preventDefault();
30
- fn();
31
- }}
32
- onResetFilterForm={clearAll}
33
- id="ekyc-filter-form"
34
- onMobileExclusiveFilterPopupFormClose={props.onClose}
35
- >
36
- <FilterFormField>
37
- <div className="filter-label" style={{ fontWeight: "normal" }}>
38
- {t("EKYC_STATUS")}:
39
- </div>
40
- <Dropdown
41
- option={[
42
- { label: t("EKYC_STATUS_ALL"), value: "" },
43
- { label: t("EKYC_STATUS_ACTIVE"), value: "ACTIVE" },
44
- { label: t("EKYC_STATUS_PENDING"), value: "PENDING START" },
45
- ]}
46
- optionKey="label"
47
- select={onStatusChange}
48
- selected={_searchParams?.status || { label: t("EKYC_STATUS_ALL"), value: "" }}
49
- />
50
- </FilterFormField>
51
- </FilterForm>
52
- );
53
- };
54
-
55
- export default Filter;
@@ -1,336 +0,0 @@
1
- import React, { useState, Fragment, useEffect } from "react";
2
- import { useLocation } from "react-router-dom";
3
- import { Toast, Loader, FormComposer } from "@djb25/digit-ui-react-components";
4
- import { useTranslation } from "react-i18next";
5
- import MeterDetailsConfig from "../config/MeterDetailsConfig";
6
-
7
- const MeterDetails = ({ config, onSelect, formData }) => {
8
- const { t } = useTranslation();
9
- const location = useLocation();
10
- const flowState = location.state || {};
11
- const tenantId = Digit.ULBService.getCurrentTenantId();
12
-
13
- const queryParams = new URLSearchParams(location.search);
14
- const urlKno = queryParams.get("kno");
15
- const searchKno =
16
- urlKno ||
17
- flowState?.kNumber ||
18
- flowState?.kno ||
19
- formData?.kNumber ||
20
- formData?.kno ||
21
- sessionStorage.getItem("EKYC_K_NUMBER");
22
-
23
- const { isLoading, data: searchData } = Digit.Hooks.ekyc.useSearchConnection(
24
- { tenantId, details: { kno: searchKno, fetchType: "METER" } },
25
- { enabled: !!searchKno, cacheTime: 0 }
26
- );
27
-
28
- const updateMutation = Digit.Hooks.ekyc.useEkycUpdate(tenantId);
29
-
30
- const savedData = formData?.meterDetails || {};
31
-
32
- // 🔹 STATES
33
- const [meterPhoto, setMeterPhoto] = useState(null);
34
- const [meterPhotoId, setMeterPhotoId] = useState(savedData.meterPhotoId || null);
35
- const [toast, setToast] = useState(null);
36
- const [isDataLoaded, setIsDataLoaded] = useState(false);
37
- const [canSubmit, setCanSubmit] = useState(false);
38
-
39
- const [defaultValues, setDefaultValues] = useState(() => ({
40
- connectionCategory: savedData.connectionCategory || "",
41
- saType: savedData.saType || "",
42
- status: savedData.status || "",
43
- mrCode: savedData.mrCode || "",
44
- areaCode: savedData.areaCode || "",
45
- mrKey: savedData.mrKey || "",
46
- meterNumber: savedData.meterNumber || "",
47
- meterMaker: savedData.meterMaker || "",
48
- meterStatus: savedData.meterStatus ? { name: savedData.meterStatus } : null,
49
- meterCondition: savedData.meterCondition ? { name: savedData.meterCondition } : null,
50
- meterLocation: savedData.meterLocation ? { name: savedData.meterLocation } : null,
51
- lastBillReceived: savedData.lastBillReceived ? { name: savedData.lastBillReceived } : null,
52
- billMonthYear: savedData.billMonthYear ? { name: savedData.billMonthYear } : null,
53
- reason: savedData.reason || "",
54
- accessToMeter: savedData.accessToMeter ? { name: savedData.accessToMeter } : null,
55
- sewerConnection: savedData.sewerConnection ? { name: savedData.sewerConnection } : null,
56
- septicTank: savedData.septicTank ? { name: savedData.septicTank } : null,
57
- meterPhoto: savedData.meterPhotoId ? "Uploaded" : null,
58
- }));
59
-
60
- const [localFormData, setLocalFormData] = useState(defaultValues);
61
-
62
- const extractApplicationData = (searchData) => {
63
- if (!searchData) return null;
64
- const reviewWrapper =
65
- searchData?.applicationReviewInfo || searchData?.applicationReview || searchData;
66
- const applicationData = (Array.isArray(reviewWrapper) ? reviewWrapper[0] : reviewWrapper) || {};
67
- return applicationData?.newData || applicationData;
68
- };
69
-
70
- useEffect(() => {
71
- const appData = extractApplicationData(searchData);
72
- const rawData = appData || formData?.connectionDetails;
73
- const apiMeter = rawData?.meterDetails || rawData || {};
74
-
75
- if (apiMeter && Object.keys(apiMeter).length > 0 && !isDataLoaded) {
76
- let mStatus = null;
77
- let mCondition = null;
78
- let mLoc = null;
79
- let billRec = null;
80
- let billMonYr = null;
81
- let accToMeter = null;
82
- let sewerConn = null;
83
- let sepTank = null;
84
-
85
- if (apiMeter.meterStatus) {
86
- const matchingStatus = [
87
- { name: "Metered" },
88
- { name: "Unmetered" },
89
- { name: "Can not be identified" },
90
- ].find((o) => o.name.toLowerCase() === apiMeter.meterStatus.toLowerCase());
91
- if (matchingStatus) mStatus = matchingStatus;
92
- else mStatus = { name: apiMeter.meterStatus };
93
- } else if (apiMeter.metered !== undefined) {
94
- mStatus = { name: apiMeter.metered ? "Metered" : "Unmetered" };
95
- }
96
-
97
- if (apiMeter.meterCondition) {
98
- const matchingCond = [{ name: "Damaged" }, { name: "Not-Damaged" }].find(
99
- (o) => o.name.toLowerCase() === apiMeter.meterCondition.toLowerCase()
100
- );
101
- if (matchingCond) mCondition = matchingCond;
102
- else mCondition = { name: apiMeter.meterCondition };
103
- }
104
-
105
- if (apiMeter.meterLocation) {
106
- const matchingLoc = [{ name: "Inside" }, { name: "Outside" }].find(
107
- (o) =>
108
- o.name.toLowerCase() === apiMeter.meterLocation.toLowerCase() ||
109
- apiMeter.meterLocation.toLowerCase().includes(o.name.toLowerCase())
110
- );
111
- if (matchingLoc) mLoc = matchingLoc;
112
- else mLoc = { name: apiMeter.meterLocation };
113
- }
114
-
115
- if (apiMeter.lastBillRaised !== undefined && apiMeter.lastBillRaised !== null) {
116
- const strVal = String(apiMeter.lastBillRaised).toLowerCase();
117
- if (strVal === "true" || strVal === "yes") billRec = { name: "Yes" };
118
- else billRec = { name: "No" };
119
- }
120
-
121
- if (apiMeter.lastBillReceivedDate) {
122
- const formatted = apiMeter.lastBillReceivedDate.replace("-", "/");
123
- const parsedParts = formatted.split("/");
124
- if (parsedParts.length === 2) {
125
- const mon = parseInt(parsedParts[0], 10);
126
- const yr = parseInt(parsedParts[1], 10);
127
- billMonYr = { name: `${mon}/${yr}` };
128
- } else {
129
- billMonYr = { name: apiMeter.lastBillReceivedDate };
130
- }
131
- }
132
-
133
- if (apiMeter.accessToMeter !== undefined && apiMeter.accessToMeter !== null) {
134
- const strVal = String(apiMeter.accessToMeter).toLowerCase();
135
- if (strVal === "true" || strVal === "yes") accToMeter = { name: "Yes" };
136
- else accToMeter = { name: "No" };
137
- }
138
-
139
- if (apiMeter.sewerConnection !== undefined && apiMeter.sewerConnection !== null) {
140
- const strVal = String(apiMeter.sewerConnection).toLowerCase();
141
- if (strVal === "true" || strVal === "yes") sewerConn = { name: "Yes" };
142
- else sewerConn = { name: "No" };
143
- }
144
-
145
- if (apiMeter.septicTank !== undefined && apiMeter.septicTank !== null) {
146
- const strVal = String(apiMeter.septicTank).toLowerCase();
147
- if (strVal === "true" || strVal === "yes") sepTank = { name: "Yes" };
148
- else sepTank = { name: "No" };
149
- }
150
-
151
- const updatedDefaults = {
152
- connectionCategory: savedData.connectionCategory || apiMeter.connectionCategory || "",
153
- saType: savedData.saType || apiMeter.saType || "",
154
- status: savedData.status || apiMeter.statusFlag || "",
155
- mrCode: savedData.mrCode || (apiMeter.mrcode ? String(apiMeter.mrcode) : ""),
156
- areaCode: savedData.areaCode || (apiMeter.areacode ? String(apiMeter.areacode) : ""),
157
- mrKey: savedData.mrKey || (apiMeter.mrkey ? String(apiMeter.mrkey) : ""),
158
- meterNumber: savedData.meterNumber || apiMeter.meterNumber || "",
159
- meterMaker: savedData.meterMaker || apiMeter.meterMake || "",
160
- meterStatus: savedData.meterStatus ? { name: savedData.meterStatus } : mStatus,
161
- meterCondition: savedData.meterCondition ? { name: savedData.meterCondition } : mCondition,
162
- meterLocation: savedData.meterLocation ? { name: savedData.meterLocation } : mLoc,
163
- lastBillReceived: savedData.lastBillReceived ? { name: savedData.lastBillReceived } : billRec,
164
- billMonthYear: savedData.billMonthYear ? { name: savedData.billMonthYear } : billMonYr,
165
- reason: savedData.reason || apiMeter.lastBillNotRaisedReason || "",
166
- accessToMeter: savedData.accessToMeter ? { name: savedData.accessToMeter } : accToMeter,
167
- sewerConnection: savedData.sewerConnection ? { name: savedData.sewerConnection } : sewerConn,
168
- septicTank: savedData.septicTank ? { name: savedData.septicTank } : sepTank,
169
- meterPhoto: savedData.meterPhotoId || apiMeter.meterPhotoFileStoreId || null,
170
- };
171
-
172
- setDefaultValues(updatedDefaults);
173
- setLocalFormData(updatedDefaults);
174
- if (updatedDefaults.meterPhoto) {
175
- setMeterPhotoId(updatedDefaults.meterPhoto);
176
- }
177
- setIsDataLoaded(true);
178
- }
179
- }, [searchData, formData?.connectionDetails, isDataLoaded]);
180
-
181
- // 🔹 FILE UPLOAD
182
- const handleUpload = async (e, onChange) => {
183
- const file = e.target.files[0];
184
- if (!file) return;
185
-
186
- if (file.size > 2000000) {
187
- setToast({ type: "error", message: t("Max size 2MB exceeded") });
188
- return;
189
- }
190
-
191
- try {
192
- const res = await Digit.UploadServices.Filestorage("EKYC", file, tenantId);
193
- const fileStoreId = res?.data?.files?.[0]?.fileStoreId;
194
-
195
- if (fileStoreId) {
196
- onChange(file.name);
197
- setMeterPhotoId(fileStoreId);
198
-
199
- const reader = new FileReader();
200
- reader.onloadend = () => setMeterPhoto(reader.result);
201
- reader.readAsDataURL(file);
202
-
203
- setToast({ type: "success", message: t("Upload successful") });
204
- }
205
- } catch {
206
- setToast({ type: "error", message: t("Upload failed") });
207
- }
208
- };
209
-
210
- const onFormValueChange = (setValue, data) => {
211
- const meterStatusChanged =
212
- (data?.meterStatus?.name || data?.meterStatus) !==
213
- (localFormData?.meterStatus?.name || localFormData?.meterStatus);
214
-
215
- const lastBillReceivedChanged =
216
- (data?.lastBillReceived?.name || data?.lastBillReceived) !==
217
- (localFormData?.lastBillReceived?.name || localFormData?.lastBillReceived);
218
-
219
- const sewerConnectionChanged =
220
- (data?.sewerConnection?.name || data?.sewerConnection) !==
221
- (localFormData?.sewerConnection?.name || localFormData?.sewerConnection);
222
-
223
- if (meterStatusChanged || lastBillReceivedChanged || sewerConnectionChanged) {
224
- setLocalFormData((prev) => ({
225
- ...prev,
226
- ...data,
227
- }));
228
- }
229
-
230
- // Determine validation
231
- const connCatVal = data?.connectionCategory;
232
- const mStatusVal = data?.meterStatus;
233
- const mLocVal = data?.meterLocation;
234
- const billRecVal = data?.lastBillReceived;
235
- const sewerConnVal = data?.sewerConnection;
236
- const mPhotoId = meterPhotoId || data?.meterPhoto;
237
- const reasonVal = data?.reason;
238
- const billMonYrVal = data?.billMonthYear;
239
- const sepTankVal = data?.septicTank;
240
-
241
- let valid = true;
242
- if (!connCatVal) valid = false;
243
- if (!mStatusVal) valid = false;
244
- if (!mLocVal) valid = false;
245
- if (!billRecVal) valid = false;
246
- if (!sewerConnVal) valid = false;
247
-
248
- if (mStatusVal?.name === "Metered" && !mPhotoId) valid = false;
249
- if (billRecVal?.name === "No" && !reasonVal) valid = false;
250
- if (billRecVal?.name === "Yes" && !billMonYrVal) valid = false;
251
- if (sewerConnVal?.name === "No" && !sepTankVal) valid = false;
252
-
253
- if (valid !== canSubmit) {
254
- setCanSubmit(valid);
255
- }
256
- };
257
-
258
- const onSubmit = async (data) => {
259
- const submitData = {
260
- connectionCategory: data.connectionCategory,
261
- saType: data.saType,
262
- status: data.status,
263
- mrCode: data.mrCode,
264
- areaCode: data.areaCode,
265
- mrKey: data.mrKey,
266
- meterNumber: data.meterNumber,
267
- meterMaker: data.meterMaker,
268
- meterStatus: data.meterStatus?.name || data.meterStatus,
269
- meterCondition: data.meterCondition?.name || data.meterCondition,
270
- meterLocation: data.meterLocation?.name || data.meterLocation,
271
- lastBillReceived: data.lastBillReceived?.name || data.lastBillReceived,
272
- billMonthYear: data.billMonthYear?.name || data.billMonthYear,
273
- reason: data.reason,
274
- accessToMeter: data.accessToMeter?.name || data.accessToMeter,
275
- sewerConnection: data.sewerConnection?.name || data.sewerConnection,
276
- septicTank: data.septicTank?.name || data.septicTank,
277
- meterPhotoId: meterPhotoId,
278
- };
279
-
280
- try {
281
- await updateMutation.mutateAsync({
282
- RequestInfo: {},
283
- updateType: "METER",
284
- kno: searchKno,
285
- ...submitData,
286
- });
287
- setToast({ type: "success", message: t("Meter details updated successfully!") });
288
- onSelect(config.key, submitData);
289
- } catch (error) {
290
- setToast({ type: "error", message: t("Failed to update meter details") });
291
- }
292
- };
293
-
294
- if (isLoading) {
295
- return <Loader />;
296
- }
297
-
298
- const Config = MeterDetailsConfig(
299
- t,
300
- localFormData,
301
- handleUpload,
302
- meterPhoto,
303
- meterPhotoId,
304
- setMeterPhoto,
305
- setMeterPhotoId
306
- );
307
-
308
- return (
309
- <Fragment>
310
- <FormComposer
311
- key={isDataLoaded ? "loaded" : "loading"}
312
- isDisabled={!canSubmit}
313
- label={t("ES_COMMON_CONTINUE")}
314
- config={Config.map((item) => ({
315
- ...item,
316
- isCollapsible: true,
317
- isDefaultOpen: true,
318
- }))}
319
- onSubmit={onSubmit}
320
- defaultValues={defaultValues}
321
- onFormValueChange={onFormValueChange}
322
- noCard={false}
323
- submitInForm={true}
324
- />
325
- {toast && (
326
- <Toast
327
- error={toast.type === "error"}
328
- label={toast.message}
329
- onClose={() => setToast(null)}
330
- />
331
- )}
332
- </Fragment>
333
- );
334
- };
335
-
336
- export default MeterDetails;
@@ -1,73 +0,0 @@
1
- import React from "react";
2
- import { useTranslation } from "react-i18next";
3
- import { Header, Card, SubmitBar, DetailsCard, Loader } from "@djb25/digit-ui-react-components";
4
- import { Link } from "react-router-dom";
5
- import SearchConsumer from "./SearchConsumer";
6
- import StatusCards from "./StatusCards";
7
-
8
- const MobileInbox = ({
9
- data,
10
- isLoading,
11
- onSearch,
12
- searchParams,
13
- parentRoute,
14
- countData,
15
- }) => {
16
- const { t } = useTranslation();
17
-
18
- const mobileData = data?.items?.map((item) => ({
19
- [t("EKYC_APPLICATION_NO")]: item.applicationNumber,
20
- [t("EKYC_CITIZEN_NAME")]: item.citizenName,
21
- [t("EKYC_MOBILE_NO")]: item.mobileNumber,
22
- [t("EKYC_STATUS")]: (
23
- <span className={`ekyc-status-tag ${item.status}`}>
24
- {t(`EKYC_STATUS_${item.status}`)}
25
- </span>
26
- ),
27
- })) || [];
28
-
29
- return (
30
- <div className="inbox-wrapper">
31
- <div className="ekyc-header-container module-header">
32
- <Header className="title">{t("EKYC_INBOX_HEADER")}</Header>
33
- <Link to={`${parentRoute}/create-kyc`}>
34
- <SubmitBar label={t("EKYC_CREATE_KYC")} />
35
- </Link>
36
- </div>
37
-
38
- <div className="ekyc-metrics-section">
39
- <StatusCards countData={countData} />
40
- </div>
41
-
42
- <SearchConsumer
43
- onSearch={onSearch}
44
- searchParams={searchParams}
45
- />
46
-
47
- <div className="mobile-data-container">
48
- {isLoading ? (
49
- <Loader />
50
- ) : mobileData?.length > 0 ? (
51
- <DetailsCard
52
- data={mobileData}
53
- t={t}
54
- serviceRequestIdKey={t("EKYC_APPLICATION_NO")}
55
- linkPrefix={`${parentRoute}/application-details/`}
56
- />
57
- ) : (
58
- <Card>
59
- {t("ES_COMMON_NO_DATA")
60
- .split("\\n")
61
- .map((text, index) => (
62
- <p key={index} style={{ textAlign: "center" }}>
63
- {text}
64
- </p>
65
- ))}
66
- </Card>
67
- )}
68
- </div>
69
- </div>
70
- );
71
- };
72
-
73
- export default MobileInbox;