diff --git a/micro-ui/web/.env b/micro-ui/web/.env
index 3174de8ec10..b696bf04eba 100644
--- a/micro-ui/web/.env
+++ b/micro-ui/web/.env
@@ -8,4 +8,4 @@ REACT_APP_PROXY_API=https://unified-dev.digit.org
REACT_APP_PROXY_ASSETS=https://unified-dev.digit.org
REACT_APP_GLOBAL=https://s3.ap-south-1.amazonaws.com/egov-dev-assets/globalConfigsWorkbench.js
NODE_TLS_REJECT_UNAUTHORIZED=0;
-REACT_APP_PORT=8000
\ No newline at end of file
+REACT_APP_PORT=8000
diff --git a/micro-ui/web/lerna.json b/micro-ui/web/lerna.json
index 17c7a0f8604..e0472965252 100644
--- a/micro-ui/web/lerna.json
+++ b/micro-ui/web/lerna.json
@@ -5,6 +5,7 @@
"packages/core",
"packages/common",
"packages/workbench",
+ "packages/pgr",
"packages/ui-core",
"packages/app1"
],
diff --git a/micro-ui/web/package.json b/micro-ui/web/package.json
index a26212b0e20..2dd955ac0bd 100644
--- a/micro-ui/web/package.json
+++ b/micro-ui/web/package.json
@@ -18,9 +18,10 @@
"workspaces": [
"packages/core",
"packages/workbench",
- "packages/common",
+ "packages/pgr",
"packages/ui-core",
"packages/app1"
+ "packages/common"
],
"scripts": {
"build": "yarn lerna run build",
@@ -30,12 +31,14 @@
"build:hrms": "cd packages/hrms && yarn build",
"build:workbench": "cd packages/workbench && yarn build",
"build:dss": "cd packages/dss && yarn build",
+ "build:pgr": "cd packages/pgr && yarn build",
"start:core": "cd packages/core && yarn start",
+ "start:workbench": "cd packages/workbench && yarn start",
+ "start:pgr": "cd packages/pgr && yarn start"
"start:common": "cd packages/common && yarn start",
- "start:workbench": "cd packages/workbench && yarn start"
},
"dependencies": {
"dotenv": "^16.3.1",
"yarn": "^1.22.21"
}
-}
+}
\ No newline at end of file
diff --git a/micro-ui/web/packages/core/src/App.js b/micro-ui/web/packages/core/src/App.js
index cb86c2bce2b..c1076cd6ce3 100644
--- a/micro-ui/web/packages/core/src/App.js
+++ b/micro-ui/web/packages/core/src/App.js
@@ -7,7 +7,7 @@ import useRouter from "./hooks/useRouter";
import { DigitUI } from "./Module";
import { initLibraries } from "@digit-ui/digit-ui-libraries-mfe";
import { QueryClient, QueryClientProvider } from "react-query";
-import registerRemotes from "./modules/registerRemotes"
+import registerRemotes from "./modules/registerRemotes";
//import { initHRMSComponents } from "@digit-ui/digit-ui-module-hrms-mfe";
// const LandingLazy = lazy(() => import("./modules/Landing"));
@@ -23,6 +23,7 @@ initLibraries().then(() => {
initDigitUI();
});
+//registering remote apps
const queryClient = new QueryClient({
defaultOptions: {
queries: {
@@ -44,10 +45,10 @@ registerRemotes(queryClient)
const App = () => {
const { login, history, isSignedIn$, logout } = useAuth();
const { navigate } = useRouter();
- const enabledModules=["PT","HRMS","Workbench","DSS","Measurement"]
+ const enabledModules = ["PT", "HRMS", "Workbench", "DSS", "Measurement", "PGR"];
const moduleReducers = (initData) => initData;
-
+
const stateCode = window?.globalConfigs?.getConfig("STATE_LEVEL_TENANT_ID") || "pb";
@@ -67,7 +68,6 @@ const App = () => {
-
}>
{/*
@@ -89,9 +89,9 @@ const App = () => {
*/}
- {
-
- }
+
+ {}
+
@@ -99,21 +99,17 @@ const App = () => {
);
};
-
-
const initDigitUI = () => {
window.contextPath = window?.globalConfigs?.getConfig("CONTEXT_PATH") || "digit-ui";
- window.Digit.Customizations = {
-
- };
+ window.Digit.Customizations = {};
window?.Digit.ComponentRegistryService.setupRegistry({
// PaymentModule,
// ...paymentConfigs,
// PaymentLinks,
});
- // initHRMSComponents();
- const enabledModules=["PT"];
+ // initHRMSComponents();
+ const enabledModules = ["PT"];
const moduleReducers = (initData) => initData;
@@ -123,7 +119,4 @@ const initDigitUI = () => {
// return ();
};
-
-
export default App;
-
diff --git a/micro-ui/web/packages/core/src/modules/registerRemotes.js b/micro-ui/web/packages/core/src/modules/registerRemotes.js
index 5a3c83fbf29..e96c6b86163 100644
--- a/micro-ui/web/packages/core/src/modules/registerRemotes.js
+++ b/micro-ui/web/packages/core/src/modules/registerRemotes.js
@@ -15,7 +15,17 @@ export default (queryClient) => {
queryClient,
},
});
-
+
+ registerApplication({
+ name: "PGR",
+ app: () => import("pgr/PGRModule"),
+ activeWhen: "/workbench-ui/employee/pgr",
+ customProps: {
+ title: "PGR is running on host",
+ queryClient,
+ },
+ });
+
registerApplication({
name: "Common",
app: () => import("common/CommonModule"),
diff --git a/micro-ui/web/packages/core/webpack.dev.js b/micro-ui/web/packages/core/webpack.dev.js
index 604e8a3a332..5fbc36cfd5f 100644
--- a/micro-ui/web/packages/core/webpack.dev.js
+++ b/micro-ui/web/packages/core/webpack.dev.js
@@ -44,6 +44,7 @@ module.exports = () => {
// auth: "auth@http://localhost:8082/remoteEntry.js",
// header: "header@http://localhost:8083/remoteEntry.js",
// dashboard: "dashboard@http://localhost:8084/remoteEntry.js",
+ pgr: "pgr@https://localhost:8087/remoteEntry.js",
// hrms: "hrms@https://localhost:8085/remoteEntry.js",
workbench: "workbench@https://localhost:8086/remoteEntry.js",
common:"common@https://localhost:8090/remoteEntry.js"
diff --git a/micro-ui/web/packages/core/webpack.prod.js b/micro-ui/web/packages/core/webpack.prod.js
index ae3ef4c63cb..ad7456ec973 100644
--- a/micro-ui/web/packages/core/webpack.prod.js
+++ b/micro-ui/web/packages/core/webpack.prod.js
@@ -19,6 +19,7 @@ module.exports = () => {
// auth: `auth@${domain}/auth/remoteEntry.js`,
// header: `header@${domain}/header/remoteEntry.js`,
// dashboard: `dashboard@${domain}/dashboard/remoteEntry.js`,
+ pgr : `pgr@${domain}/pgr/remoteEntry.js`,
// hrms: `hrms@${domain}/hrms/remoteEntry.js`,
common: `common-ui@${domain}/common/remoteEntry.js`,
workbench : `workbench_web@${domain}/workbench/remoteEntry.js`,
diff --git a/micro-ui/web/packages/pgr/package.json b/micro-ui/web/packages/pgr/package.json
new file mode 100644
index 00000000000..be4e93b9c2c
--- /dev/null
+++ b/micro-ui/web/packages/pgr/package.json
@@ -0,0 +1,50 @@
+{
+ "name": "@digit-ui/digit-ui-module-pgr-mfe",
+ "version": "1.0.6",
+ "description": "",
+ "main": "module.js",
+ "scripts": {
+ "predeploy": "yarn build",
+ "deploy": "gh-pages -d dist",
+ "start": "webpack serve --config webpack.dev.js",
+ "build": "webpack --config webpack.prod.js"
+ },
+ "homepage": "http://design-egov.github.io/auth",
+ "keywords": [],
+ "author": "",
+ "license": "ISC",
+ "devDependencies": {
+ "@babel/core": "7.12.10",
+ "@babel/preset-react": "7.12.10",
+ "babel-loader": "8.2.2",
+ "gh-pages": "^5.0.0",
+ "html-webpack-plugin": "^5.5.0",
+ "babel-plugin-react-html-attrs": "^3.0.5",
+ "@babel/preset-env": "7.23.9"
+ },
+ "dependencies": {
+ "single-spa-react": "^4.6.1",
+ "@digit-ui/digit-ui-libraries-mfe": "1.0.6",
+ "@digit-ui/digit-ui-module-core-base": "1.0.8",
+ "@egovernments/digit-ui-react-components": "1.4.107",
+ "@egovernments/digit-ui-svg-components": "0.0.8",
+ "@rjsf/core": "5.10.0",
+ "@rjsf/utils": "5.10.0",
+ "@rjsf/validator-ajv8": "5.10.0",
+ "react": "17.0.1",
+ "react-date-range": "1.4.0",
+ "react-dom": "17.0.1",
+ "react-hook-form": "6.15.8",
+ "react-i18next": "11.16.2",
+ "react-query": "3.6.1",
+ "react-router-dom": "5.2.0",
+ "react-select": "5.7.4",
+ "webpack": "^5.68.0",
+ "webpack-cli": "^4.9.2",
+ "webpack-dev-server": "^4.8.1",
+ "react-redux": "7.2.8",
+ "redux": "4.1.2",
+ "redux-thunk": "2.4.1",
+ "webpack-merge": "5.7.3"
+ }
+}
diff --git a/micro-ui/web/packages/pgr/public/index.html b/micro-ui/web/packages/pgr/public/index.html
new file mode 100644
index 00000000000..ce70aaede68
--- /dev/null
+++ b/micro-ui/web/packages/pgr/public/index.html
@@ -0,0 +1,34 @@
+
+
+
+
+ PGR Page
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/micro-ui/web/packages/pgr/src/EmployeeApp.js b/micro-ui/web/packages/pgr/src/EmployeeApp.js
new file mode 100644
index 00000000000..f0747117c18
--- /dev/null
+++ b/micro-ui/web/packages/pgr/src/EmployeeApp.js
@@ -0,0 +1,23 @@
+import React from "react";
+import { AppContainer, EmployeeAppContainer } from "@egovernments/digit-ui-react-components";
+import Complaint from "./pages/employee/index";
+import { Provider } from "react-redux";
+import getStore from "./redux/store";
+import { PGRReducers } from "./Module";
+
+const App = () => {
+ const { isLoading, data: initData } = Digit.Hooks.useInitStore("pg", ["PT", "HRMS", "Workbench", "DSS", "Measurement", "PGR"]);
+ const moduleReducers = (initData) => ({
+ pgr: PGRReducers(initData),
+ });
+
+ return (
+
+
+
+
+
+ );
+};
+
+export default App;
diff --git a/micro-ui/web/packages/pgr/src/Icons.js b/micro-ui/web/packages/pgr/src/Icons.js
new file mode 100644
index 00000000000..c932e7ad466
--- /dev/null
+++ b/micro-ui/web/packages/pgr/src/Icons.js
@@ -0,0 +1,8 @@
+import React from "react";
+
+export const Close = () => (
+
+);
diff --git a/micro-ui/web/packages/pgr/src/Module.js b/micro-ui/web/packages/pgr/src/Module.js
new file mode 100644
index 00000000000..df775c3222a
--- /dev/null
+++ b/micro-ui/web/packages/pgr/src/Module.js
@@ -0,0 +1,87 @@
+import React, { useEffect } from "react";
+import PGRCard from "./components/PGRCard";
+
+import getRootReducer from "./redux/reducers";
+import CitizenApp from "./pages/citizen";
+
+import EmployeeApp from "./EmployeeApp";
+import { ComplaintIcon, CitizenHomeCard, Loader } from "@egovernments/digit-ui-react-components";
+import { PGR_CITIZEN_CREATE_COMPLAINT } from "./constants/Citizen";
+import { useTranslation } from "react-i18next";
+import { LOCALE } from "./constants/Localization";
+import { ComplaintDetails } from "./pages/employee/ComplaintDetails";
+import { CreateComplaint as CreateComplaintEmp } from "./pages/employee/CreateComplaint";
+import Inbox from "./pages/employee/Inbox";
+import ResponseEmp from "./pages/employee/Response";
+
+import { CreateComplaint as CreateComplaintCitizen } from "./pages/citizen/Create";
+import { ComplaintsList } from "./pages/citizen/ComplaintsList";
+import ComplaintDetailsPage from "./pages/citizen/ComplaintDetails";
+import SelectRating from "./pages/citizen/Rating/SelectRating";
+import ResponseCitizen from "./pages/citizen/Response";
+import InboxV2 from "./pages/employee/InboxV2";
+
+
+export const PGRReducers = getRootReducer;
+
+const PGRModule = ({ stateCode, userType, tenants }) => {
+ const moduleCode = "PGR";
+ const language = Digit.StoreData.getCurrentLanguage();
+ const { isLoading, data: store } = Digit.Services.useStore({ stateCode, moduleCode, language });
+
+ if (isLoading) {
+ return ;
+ }
+
+ Digit.SessionStorage.set("PGR_TENANTS", tenants);
+
+ if (userType === "citizen") {
+ return ;
+ } else {
+ return ;
+ }
+};
+
+const PGRLinks = ({ matchPath }) => {
+ const { t } = useTranslation();
+ const [params, setParams, clearParams] = Digit.Hooks.useSessionStorage(PGR_CITIZEN_CREATE_COMPLAINT, {});
+
+ useEffect(() => {
+ clearParams();
+ }, []);
+
+ const links = [
+ {
+ link: `${matchPath}/create-complaint/complaint-type`,
+ i18nKey: t("CS_COMMON_FILE_A_COMPLAINT"),
+ },
+ {
+ link: `${matchPath}/complaints`,
+ i18nKey: t(LOCALE.MY_COMPLAINTS),
+ },
+ ];
+
+ return ;
+};
+
+const componentsToRegister = {
+ PGRModule,
+ PGRLinks,
+ PGRCard,
+ PGRComplaintDetails : ComplaintDetails,
+ PGRCreateComplaintEmp : CreateComplaintEmp,
+ PGRInbox : Inbox,
+ PGRInboxV2 : InboxV2,
+ PGRResponseEmp : ResponseEmp,
+ PGRCreateComplaintCitizen : CreateComplaintCitizen,
+ PGRComplaintsList : ComplaintsList,
+ PGRComplaintDetailsPage : ComplaintDetailsPage,
+ PGRSelectRating : SelectRating,
+ PGRResponseCitzen : ResponseCitizen
+};
+
+export const initPGRComponents = () => {
+ Object.entries(componentsToRegister).forEach(([key, value]) => {
+ Digit.ComponentRegistryService.setComponent(key, value);
+ });
+};
diff --git a/micro-ui/web/packages/pgr/src/PGRWrapper.js b/micro-ui/web/packages/pgr/src/PGRWrapper.js
new file mode 100644
index 00000000000..1c466976b89
--- /dev/null
+++ b/micro-ui/web/packages/pgr/src/PGRWrapper.js
@@ -0,0 +1,20 @@
+import React from 'react';
+import { initPGRComponents } from './Module';
+import { QueryClientProvider } from 'react-query';
+import EmployeeApp from './EmployeeApp';
+import { Switch, useLocation, BrowserRouter as Router } from 'react-router-dom';
+
+const App = ({ queryClient, title }) => {
+ initPGRComponents();
+ //make way to do this job in container while registering remotes
+
+ return (
+
+
+
+
+
+ );
+};
+
+export default App;
diff --git a/micro-ui/web/packages/pgr/src/SingleSpaEntry.js b/micro-ui/web/packages/pgr/src/SingleSpaEntry.js
new file mode 100644
index 00000000000..194c089d506
--- /dev/null
+++ b/micro-ui/web/packages/pgr/src/SingleSpaEntry.js
@@ -0,0 +1,26 @@
+import React from "react";
+import ReactDOM from "react-dom";
+import singleSpaReact from "single-spa-react";
+import App from "./PGRWrapper";
+
+const appLifeCycles = singleSpaReact({
+ React,
+ ReactDOM,
+ rootComponent: App,
+ errorBoundary() {
+ // https://reactjs.org/docs/error-boundaries.html
+ return This renders when a catastrophic error occurs
;
+ },
+});
+
+export function bootstrap(props) {
+ return appLifeCycles.bootstrap(props);
+}
+
+export function mount(props) {
+ return appLifeCycles.mount(props);
+}
+
+export function unmount(props) {
+ return appLifeCycles.unmount(props);
+}
\ No newline at end of file
diff --git a/micro-ui/web/packages/pgr/src/components/Complaint.js b/micro-ui/web/packages/pgr/src/components/Complaint.js
new file mode 100644
index 00000000000..3583fa17aad
--- /dev/null
+++ b/micro-ui/web/packages/pgr/src/components/Complaint.js
@@ -0,0 +1,41 @@
+import React from "react";
+import { useTranslation } from "react-i18next";
+import { useHistory } from "react-router-dom";
+import { Card, DateWrap, KeyNote } from "@egovernments/digit-ui-react-components";
+import { CardSubHeader } from "@egovernments/digit-ui-react-components";
+import { LOCALIZATION_KEY } from "../constants/Localization";
+
+// import { ConvertTimestampToDate } from "../@egovernments/digit-utils/services/date";
+
+const Complaint = ({ data, path }) => {
+ let { serviceCode, serviceRequestId, applicationStatus } = data;
+
+ const history = useHistory();
+ const { t } = useTranslation();
+
+ const handleClick = () => {
+ history.push(`${path}/${serviceRequestId}`);
+ };
+
+ const closedStatus = ["RESOLVED", "REJECTED", "CLOSEDAFTERREJECTION", "CLOSEDAFTERRESOLUTION"];
+
+ return (
+
+
+ {t(`SERVICEDEFS.${serviceCode.toUpperCase()}`)}
+
+
+
+
+
+
+
{(closedStatus.includes(applicationStatus) ? t("CS_COMMON_CLOSED") : t("CS_COMMON_OPEN")).toUpperCase()}
+
+
+ {t(`${LOCALIZATION_KEY.CS_COMMON}_${applicationStatus}`)}
+
+
+ );
+};
+
+export default Complaint;
diff --git a/micro-ui/web/packages/pgr/src/components/DesktopInbox.js b/micro-ui/web/packages/pgr/src/components/DesktopInbox.js
new file mode 100644
index 00000000000..a81aba6a4c8
--- /dev/null
+++ b/micro-ui/web/packages/pgr/src/components/DesktopInbox.js
@@ -0,0 +1,143 @@
+import React from "react";
+import { useTranslation } from "react-i18next";
+import { Link } from "react-router-dom";
+import { Card, Loader } from "@egovernments/digit-ui-react-components";
+import ComplaintsLink from "./inbox/ComplaintLinks";
+import ComplaintTable from "./inbox/ComplaintTable";
+import Filter from "./inbox/Filter";
+import SearchComplaint from "./inbox/search";
+import { LOCALE } from "../constants/Localization";
+
+const DesktopInbox = ({
+ data,
+ onFilterChange,
+ onSearch,
+ isLoading,
+ searchParams,
+ onNextPage,
+ onPrevPage,
+ currentPage,
+ pageSizeLimit,
+ onPageSizeChange,
+ totalRecords,
+}) => {
+ const { t } = useTranslation();
+ const GetCell = (value) => {value};
+ const GetSlaCell = (value) => {
+ return value < 0 ? {value || ""} : {value || ""};
+ };
+
+ const columns = React.useMemo(
+ () => [
+ {
+ Header: t("CS_COMMON_COMPLAINT_NO"),
+ Cell: ({ row }) => {
+ return (
+
+ );
+ },
+ },
+ {
+ Header: t("WF_INBOX_HEADER_LOCALITY"),
+ Cell: ({ row }) => {
+ return GetCell(t(Digit.Utils.locale.getLocalityCode(row.original["locality"], row.original["tenantId"])));
+ },
+ },
+ {
+ Header: t("CS_COMPLAINT_DETAILS_CURRENT_STATUS"),
+ Cell: ({ row }) => {
+ return GetCell(t(`CS_COMMON_${row.original["status"]}`));
+ },
+ },
+ {
+ Header: t("WF_INBOX_HEADER_CURRENT_OWNER"),
+ Cell: ({ row }) => {
+ return GetCell(row.original["taskOwner"]);
+ },
+ },
+ {
+ Header: t("WF_INBOX_HEADER_SLA_DAYS_REMAINING"),
+ Cell: ({ row }) => {
+ return GetSlaCell(row.original["sla"]);
+ },
+ },
+ ],
+ [t]
+ );
+
+ let result;
+ if (isLoading) {
+ result = ;
+ } else if (data && data.length === 0) {
+ result = (
+
+ {t(LOCALE.NO_COMPLAINTS_EMPLOYEE)
+ .split("\\n")
+ .map((text, index) => (
+
+ {text}
+
+ ))}
+
+ );
+ } else if (data.length > 0) {
+ result = (
+ {
+ return {
+ style: {
+ minWidth: cellInfo.column.Header === t("CS_COMMON_COMPLAINT_NO") ? "240px" : "",
+ padding: "20px 18px",
+ fontSize: "16px",
+ },
+ };
+ }}
+ onNextPage={onNextPage}
+ onPrevPage={onPrevPage}
+ totalRecords={totalRecords}
+ onPageSizeChagne={onPageSizeChange}
+ currentPage={currentPage}
+ pageSizeLimit={pageSizeLimit}
+ />
+ );
+ } else {
+ result = (
+
+ {t(LOCALE.ERROR_LOADING_RESULTS)
+ .split("\\n")
+ .map((text, index) => (
+
+ {text}
+
+ ))}
+
+ );
+ }
+
+ return (
+
+ );
+};
+
+export default DesktopInbox;
diff --git a/micro-ui/web/packages/pgr/src/components/FormComposer.js b/micro-ui/web/packages/pgr/src/components/FormComposer.js
new file mode 100644
index 00000000000..785f9cde039
--- /dev/null
+++ b/micro-ui/web/packages/pgr/src/components/FormComposer.js
@@ -0,0 +1,86 @@
+import React, { useMemo } from "react";
+import { useForm } from "react-hook-form";
+import {
+ BreakLine,
+ Card,
+ CardLabel,
+ CardLabelError,
+ CardSubHeader,
+ CardSectionHeader,
+ TextArea,
+ TextInput,
+ ActionBar,
+ SubmitBar,
+ LabelFieldPair,
+} from "@egovernments/digit-ui-react-components";
+
+import { useTranslation } from "react-i18next";
+
+export const FormComposer = (props) => {
+ const { register, handleSubmit, errors } = useForm();
+ const { t } = useTranslation();
+
+ function onSubmit(data) {
+ props.onSubmit(data);
+ }
+
+ const fieldSelector = (type, populators) => {
+ switch (type) {
+ case "text":
+ return (
+
+ {populators.componentInFront ? populators.componentInFront : null}
+
+
+ );
+ case "textarea":
+ return ;
+ default:
+ return populators.dependency !== false ? populators : null;
+ }
+ };
+
+ const formFields = useMemo(
+ () =>
+ props.config?.map((section, index, array) => {
+ return (
+
+ {section.head}
+ {section.body.map((field, index) => {
+ return (
+
+ {errors[field.populators.name] && (field.populators?.validate ? errors[field.populators.validate] : true) && (
+ {field.populators.error}
+ )}
+
+
+ {field.label}
+ {field.isMandatory ? " * " : null}
+
+ {fieldSelector(field.type, field.populators)}
+
+
+ );
+ })}
+ {array.length - 1 === index ? null : }
+
+ );
+ }),
+ [props.config, errors]
+ );
+
+ const isDisabled = props.isDisabled || false;
+
+ return (
+
+ );
+};
diff --git a/micro-ui/web/packages/pgr/src/components/MobileInbox.js b/micro-ui/web/packages/pgr/src/components/MobileInbox.js
new file mode 100644
index 00000000000..34e8f9eadbf
--- /dev/null
+++ b/micro-ui/web/packages/pgr/src/components/MobileInbox.js
@@ -0,0 +1,64 @@
+import React from "react";
+import { useTranslation } from "react-i18next";
+import { Loader, Card } from "@egovernments/digit-ui-react-components";
+import { ComplaintCard } from "./inbox/ComplaintCard";
+import ComplaintsLink from "./inbox/ComplaintLinks";
+import { LOCALE } from "../constants/Localization";
+import PropTypes from "prop-types";
+
+const GetSlaCell = (value) => {
+ return value < 0 ? {value} : {value};
+};
+
+const MobileInbox = ({ data, onFilterChange, onSearch, isLoading, searchParams }) => {
+ const { t } = useTranslation();
+ const localizedData = data?.map(({ locality, tenantId, serviceRequestId, complaintSubType, sla, status, taskOwner }) => ({
+ [t("CS_COMMON_COMPLAINT_NO")]: serviceRequestId,
+ [t("CS_ADDCOMPLAINT_COMPLAINT_SUB_TYPE")]: t(`SERVICEDEFS.${complaintSubType.toUpperCase()}`),
+ [t("WF_INBOX_HEADER_LOCALITY")]: t(Digit.Utils.locale.getLocalityCode(locality, tenantId)),
+ [t("CS_COMPLAINT_DETAILS_CURRENT_STATUS")]: t(`CS_COMMON_${status}`),
+ [t("WF_INBOX_HEADER_CURRENT_OWNER")]: taskOwner,
+ [t("WF_INBOX_HEADER_SLA_DAYS_REMAINING")]: GetSlaCell(sla),
+ // status,
+ }));
+
+ let result;
+ if (isLoading) {
+ result = ;
+ } else {
+ result = (
+
+ );
+ }
+
+ return (
+
+ );
+};
+MobileInbox.propTypes = {
+ data: PropTypes.any,
+ onFilterChange: PropTypes.func,
+ onSearch: PropTypes.func,
+ isLoading: PropTypes.bool,
+ searchParams: PropTypes.any,
+};
+
+MobileInbox.defaultProps = {
+ onFilterChange: () => {},
+ searchParams: {},
+};
+
+export default MobileInbox;
diff --git a/micro-ui/web/packages/pgr/src/components/PGRCard.js b/micro-ui/web/packages/pgr/src/components/PGRCard.js
new file mode 100644
index 00000000000..11e56ae8293
--- /dev/null
+++ b/micro-ui/web/packages/pgr/src/components/PGRCard.js
@@ -0,0 +1,58 @@
+import React, { useEffect, useState } from "react";
+import { Link } from "react-router-dom";
+import { useTranslation } from "react-i18next";
+import { EmployeeModuleCard } from "@egovernments/digit-ui-react-components";
+
+
+const PGRCard = () => {
+ const { t } = useTranslation();
+
+ const allLinks = [
+ { text: t("ES_PGR_INBOX"), link: "/digit-ui/employee/pgr/inbox" },
+ { text: t("ES_PGR_NEW_COMPLAINT"), link: "/digit-ui/employee/pgr/complaint/create", accessTo: ["CSR"] },
+ ];
+
+ if (!Digit.Utils.pgrAccess()) {
+ return null;
+ }
+
+ const Icon = () =>
+
+ let propsForCSR =[
+ {
+ label: t("ES_PGR_NEW_COMPLAINT"),
+ link: `/digit-ui/employee/pgr/complaint/create`,
+ role: "CSR"
+ }
+ ]
+
+ propsForCSR = propsForCSR.filter(link => link.role && Digit.Utils.didEmployeeHasRole(link.role) );
+
+ const propsForModuleCard = {
+ Icon: ,
+ moduleName: t("ES_PGR_HEADER_COMPLAINT"),
+ kpis: [
+ {
+ label: t("TOTAL_PGR"),
+ link: `/digit-ui/employee/pgr/inbox`
+ },
+ {
+ label: t("TOTAL_NEARING_SLA"),
+ link: `/digit-ui/employee/pgr/inbox`
+ }
+ ],
+ links: [
+ {
+ label: t("ES_PGR_INBOX"),
+ link: `/digit-ui/employee/pgr/inbox`
+ },
+ ...propsForCSR
+ ]
+}
+
+ return
+};
+export default PGRCard;
diff --git a/micro-ui/web/packages/pgr/src/components/TimeLine.js b/micro-ui/web/packages/pgr/src/components/TimeLine.js
new file mode 100644
index 00000000000..a9cee1246ce
--- /dev/null
+++ b/micro-ui/web/packages/pgr/src/components/TimeLine.js
@@ -0,0 +1,162 @@
+import { Card, CardSubHeader, CheckPoint, ConnectingCheckPoints, GreyOutText, Loader, DisplayPhotos } from "@egovernments/digit-ui-react-components";
+import React, {Fragment, useEffect, useMemo } from "react";
+import { useTranslation } from "react-i18next";
+import { LOCALIZATION_KEY } from "../constants/Localization";
+import PendingAtLME from "./timelineInstances/pendingAtLme";
+import PendingForAssignment from "./timelineInstances/PendingForAssignment";
+import PendingForReassignment from "./timelineInstances/PendingForReassignment";
+import Reopen from "./timelineInstances/reopen";
+import Resolved from "./timelineInstances/resolved";
+import Rejected from "./timelineInstances/rejected";
+import StarRated from "./timelineInstances/StarRated";
+
+const TLCaption = ({ data , comments}) => {
+ const { t } = useTranslation()
+ return (
+
+ {data?.date &&
{data?.date}
}
+
{data?.name}
+
{data?.mobileNumber}
+ {data?.source &&
{t("ES_COMMON_FILED_VIA_" + data?.source.toUpperCase())}
}
+
+ );
+};
+
+const TimeLine = ({ isLoading, data, serviceRequestId, complaintWorkflow, rating, zoomImage, complaintDetails, ComplainMaxIdleTime }) => {
+ const { t } = useTranslation();
+
+ function zoomImageWrapper(imageSource, index,thumbnailsToShow){
+ let newIndex=thumbnailsToShow.thumbs?.findIndex(link=>link===imageSource);
+ zoomImage((newIndex>-1&&thumbnailsToShow?.fullImage?.[newIndex])||imageSource);
+ }
+
+ let { timeline } = data;
+ const totalTimelineLength = useMemo(()=> timeline?.length ,[timeline])
+
+ useEffect(() => {
+ let filteredTimeline = timeline?.filter((status, index, array) => {
+ if (index === array.length - 1 && status.status === "PENDINGFORASSIGNMENT") {
+ return true;
+ } else {
+ return false;
+ }
+ });
+ const [{auditDetails}] = filteredTimeline?.length>0 ? filteredTimeline : [{}];
+
+ const onlyPendingForAssignmentStatusArray = timeline?.filter( e => e?.status === "PENDINGFORASSIGNMENT")
+ const duplicateCheckpointOfPendingForAssignment = onlyPendingForAssignmentStatusArray.at(-1)
+ timeline?.push({
+ ...duplicateCheckpointOfPendingForAssignment,
+ performedAction: "FILED",
+ status: "COMPLAINT_FILED",
+ });
+ }, [timeline]);
+
+ const getCommentsInCustomChildComponent = ({comment, thumbnailsToShow, auditDetails, assigner, status}) => {
+ const captionDetails = {
+ date: auditDetails?.lastModified,
+ name: assigner?.name,
+ mobileNumber: assigner?.mobileNumber,
+ source: status == "COMPLAINT_FILED" ? complaintDetails?.audit.source : ""
+ }
+ return <>
+ {comment ? {comment?.map( e =>
+
+
{t("WF_COMMON_COMMENTS")}
+
{e}
+
+ )}
: null}
+ {thumbnailsToShow?.thumbs?.length > 0 ?
+
{t("CS_COMMON_ATTACHMENTS")}
+ {zoomImageWrapper(src, index,thumbnailsToShow)}} />
+ : null}
+ {captionDetails?.date ? : null}
+ >
+ }
+
+ const getCheckPoint = ({ status, caption, auditDetails, timeLineActions, index, array, performedAction, comment, thumbnailsToShow, assigner, totalTimelineLength }) => {
+ const isCurrent = 0 === index;
+ switch (status) {
+ case "PENDINGFORREASSIGNMENT":
+ return ;
+
+ case "PENDINGFORASSIGNMENT":
+ const isFirstPendingForAssignment = totalTimelineLength - (index + 1) === 0 ? true : false
+ return ;
+
+ case "PENDINGFORASSIGNMENT_AFTERREOPEN":
+ return ;
+
+ case "PENDINGATLME":
+ let { name, mobileNumber } = caption && caption.length > 0 ? caption[0] : { name: "", mobileNumber: "" };
+ const assignedTo = `${t(`CS_COMMON_${status}`)}`;
+ return ;
+
+ case "RESOLVED":
+ return (
+
+ );
+ case "REJECTED":
+ return (
+
+ );
+ case "CLOSEDAFTERRESOLUTION":
+ return {getCommentsInCustomChildComponent({comment, thumbnailsToShow, auditDetails, assigner})}{rating ? : null}} />;
+
+ // case "RESOLVE":
+ // return (
+ //
+ // );
+ case "COMPLAINT_FILED":
+ return ;
+
+ default:
+ return ;
+ }
+ };
+
+ return (
+
+ {t(`${LOCALIZATION_KEY.CS_COMPLAINT_DETAILS}_COMPLAINT_TIMELINE`)}
+ {timeline && totalTimelineLength > 0 ? (
+
+ {timeline.map(({ status, caption, auditDetails, timeLineActions, performedAction, wfComment: comment, thumbnailsToShow, assigner }, index, array) => {
+ return getCheckPoint({ status, caption, auditDetails, timeLineActions, index, array, performedAction, comment, thumbnailsToShow, assigner, totalTimelineLength });
+ })}
+
+ ) : (
+
+ )}
+
+ );
+};
+
+export default TimeLine;
\ No newline at end of file
diff --git a/micro-ui/web/packages/pgr/src/components/inbox/ComplaintCard.js b/micro-ui/web/packages/pgr/src/components/inbox/ComplaintCard.js
new file mode 100644
index 00000000000..13a625a7c3e
--- /dev/null
+++ b/micro-ui/web/packages/pgr/src/components/inbox/ComplaintCard.js
@@ -0,0 +1,75 @@
+import React, { useState } from "react";
+
+import { FilterAction, Card, DetailsCard, PopUp, SearchAction } from "@egovernments/digit-ui-react-components";
+import { useTranslation } from "react-i18next";
+import Filter from "./Filter";
+import SearchComplaint from "./search";
+import { LOCALE } from "../../constants/Localization";
+
+export const ComplaintCard = ({ data, onFilterChange, onSearch, serviceRequestIdKey, searchParams }) => {
+ const { t } = useTranslation();
+ const [popup, setPopup] = useState(false);
+ const [selectedComponent, setSelectedComponent] = useState(null);
+ const [filterCount, setFilterCount] = useState(Digit.inboxFilterCount || 1);
+
+ const handlePopupAction = (type) => {
+ if (type === "SEARCH") {
+ setSelectedComponent();
+ } else if (type === "FILTER") {
+ setSelectedComponent(
+
+ );
+ }
+ setPopup(true);
+ };
+
+ const handlePopupClose = () => {
+ setPopup(false);
+ setSelectedComponent(null);
+ };
+
+ let result;
+ if (data && data?.length === 0) {
+ result = (
+
+ {t(LOCALE.NO_COMPLAINTS_EMPLOYEE)
+ .split("\\n")
+ .map((text, index) => (
+
+ {text}
+
+ ))}
+
+ );
+ } else if (data && data?.length > 0) {
+ result = ;
+ } else {
+ result = (
+
+ {t(LOCALE.ERROR_LOADING_RESULTS)
+ .split("\\n")
+ .map((text, index) => (
+
+ {text}
+
+ ))}
+
+ );
+ }
+
+ return (
+
+
+ handlePopupAction("SEARCH")} />
+ handlePopupAction("FILTER")} />
+ {/* */}
+
+ {result}
+ {popup && (
+
+ {selectedComponent}
+
+ )}
+
+ );
+};
diff --git a/micro-ui/web/packages/pgr/src/components/inbox/ComplaintLinks.js b/micro-ui/web/packages/pgr/src/components/inbox/ComplaintLinks.js
new file mode 100644
index 00000000000..59a47b833c0
--- /dev/null
+++ b/micro-ui/web/packages/pgr/src/components/inbox/ComplaintLinks.js
@@ -0,0 +1,68 @@
+import { Card } from "@egovernments/digit-ui-react-components";
+import React, { useEffect, useState } from "react";
+import { Link } from "react-router-dom";
+import { useTranslation } from "react-i18next";
+
+const ComplaintsLink = ({ isMobile, data }) => {
+ const { t } = useTranslation();
+
+ const allLinks = [
+ { text: "ES_PGR_NEW_COMPLAINT", link: "/digit-ui/employee/pgr/complaint/create", accessTo: ["CSR"] },
+ // { text: "Reports", link: "/employee" },
+ // { text: "Dashboard", link: "/employee" },
+ ];
+
+ const [links, setLinks] = useState([]);
+
+ useEffect(() => {
+ let linksToShow = [];
+ allLinks.forEach((link) => {
+ if (link.accessTo) {
+ if (Digit.UserService.hasAccess(link.accessTo)) {
+ linksToShow.push(link);
+ }
+ } else {
+ linksToShow.push(link);
+ }
+ });
+ setLinks(linksToShow);
+ }, []);
+
+ // useEffect(() => {
+ // if (isMobile) {
+ // const mobileLinks = links.filter((link) => {
+ // return link.text !== "Dashboard";
+ // });
+ // setLinks(mobileLinks);
+ // }
+ // }, []);
+
+ const GetLogo = () => (
+
+
+
+ {" "}
+
{t("ES_PGR_HEADER_COMPLAINT")}
+
+ );
+
+ return (
+
+
+ {GetLogo()}
+
+ {links.map(({ link, text }, index) => (
+
+ {t(text)}
+
+ ))}
+
+
+
+ );
+};
+
+export default ComplaintsLink;
diff --git a/micro-ui/web/packages/pgr/src/components/inbox/ComplaintTable.js b/micro-ui/web/packages/pgr/src/components/inbox/ComplaintTable.js
new file mode 100644
index 00000000000..7facec2f239
--- /dev/null
+++ b/micro-ui/web/packages/pgr/src/components/inbox/ComplaintTable.js
@@ -0,0 +1,19 @@
+import React from "react";
+import { Table } from "@egovernments/digit-ui-react-components";
+
+const ComplaintTable = ({ t, columns, data, getCellProps, onNextPage, onPrevPage, currentPage, totalRecords, pageSizeLimit, onPageSizeChange }) => (
+
+);
+
+export default ComplaintTable;
diff --git a/micro-ui/web/packages/pgr/src/components/inbox/Filter.js b/micro-ui/web/packages/pgr/src/components/inbox/Filter.js
new file mode 100644
index 00000000000..02e4bd19636
--- /dev/null
+++ b/micro-ui/web/packages/pgr/src/components/inbox/Filter.js
@@ -0,0 +1,227 @@
+import React, { useEffect, useMemo, useState } from "react";
+import { Dropdown, RadioButtons, ActionBar, RemoveableTag, RoundedLabel } from "@egovernments/digit-ui-react-components";
+import { ApplyFilterBar, CloseSvg } from "@egovernments/digit-ui-react-components";
+import { useTranslation } from "react-i18next";
+import Status from "./Status";
+
+let pgrQuery = {};
+let wfQuery = {};
+
+const Filter = (props) => {
+ let { uuid } = Digit.UserService.getUser().info;
+ const { searchParams } = props;
+ const { t } = useTranslation();
+ const isAssignedToMe = searchParams?.filters?.wfFilters?.assignee && searchParams?.filters?.wfFilters?.assignee[0]?.code ? true : false;
+
+ const assignedToOptions = useMemo(
+ () => [
+ { code: "ASSIGNED_TO_ME", name: t("ASSIGNED_TO_ME") },
+ { code: "ASSIGNED_TO_ALL", name: t("ASSIGNED_TO_ALL") },
+ ],
+ [t]
+ );
+
+ const [selectAssigned, setSelectedAssigned] = useState(isAssignedToMe ? assignedToOptions[0] : assignedToOptions[1]);
+
+ // useEffect(() => setSelectedAssigned(isAssignedToMe ? assignedToOptions[0] : assignedToOptions[1]), [t]);
+
+ const [selectedComplaintType, setSelectedComplaintType] = useState(null);
+ const [selectedLocality, setSelectedLocality] = useState(null);
+ const [pgrfilters, setPgrFilters] = useState(
+ searchParams?.filters?.pgrfilters || {
+ serviceCode: [],
+ locality: [],
+ applicationStatus: [],
+ }
+ );
+
+ const [wfFilters, setWfFilters] = useState(
+ searchParams?.filters?.wfFilters || {
+ assignee: [{ code: uuid }],
+ }
+ );
+
+ const tenantId = Digit.ULBService.getCurrentTenantId();
+ // let localities = Digit.Hooks.pgr.useLocalities({ city: tenantId });
+ const { data: localities } = Digit.Hooks.useBoundaryLocalities(tenantId, "admin", {}, t);
+ let serviceDefs = Digit.Hooks.pgr.useServiceDefs(tenantId, "PGR");
+
+ const onRadioChange = (value) => {
+ setSelectedAssigned(value);
+ uuid = value.code === "ASSIGNED_TO_ME" ? uuid : "";
+ setWfFilters({ ...wfFilters, assignee: [{ code: uuid }] });
+ };
+
+ useEffect(() => {
+ let count = 0;
+ for (const property in pgrfilters) {
+ if (Array.isArray(pgrfilters[property])) {
+ count += pgrfilters[property].length;
+ let params = pgrfilters[property].map((prop) => prop.code).join();
+ if (params) {
+ pgrQuery[property] = params;
+ }
+ else{
+ delete pgrQuery?.[property]
+ }
+ }
+ }
+ for (const property in wfFilters) {
+ if (Array.isArray(wfFilters[property])) {
+ let params = wfFilters[property].map((prop) => prop.code).join();
+ if (params) {
+ wfQuery[property] = params;
+ } else {
+ wfQuery = {};
+ }
+ }
+ }
+ count += wfFilters?.assignee?.length || 0;
+
+ if (props.type !== "mobile") {
+ handleFilterSubmit();
+ }
+
+ Digit.inboxFilterCount = count;
+ }, [pgrfilters, wfFilters]);
+
+ const ifExists = (list, key) => {
+ return list.filter((object) => object.code === key.code).length;
+ };
+ function applyFiltersAndClose() {
+ handleFilterSubmit();
+ props.onClose();
+ }
+ function complaintType(_type) {
+ const type = { i18nKey: t("SERVICEDEFS." + _type.serviceCode.toUpperCase()), code: _type.serviceCode };
+ if (!ifExists(pgrfilters.serviceCode, type)) {
+ setPgrFilters({ ...pgrfilters, serviceCode: [...pgrfilters.serviceCode, type] });
+ }
+ }
+
+ function onSelectLocality(value, type) {
+ if (!ifExists(pgrfilters.locality, value)) {
+ setPgrFilters({ ...pgrfilters, locality: [...pgrfilters.locality, value] });
+ }
+ }
+
+ useEffect(() => {
+ if (pgrfilters.serviceCode.length > 1) {
+ setSelectedComplaintType({ i18nKey: `${pgrfilters.serviceCode.length} selected` });
+ } else {
+ setSelectedComplaintType(pgrfilters.serviceCode[0]);
+ }
+ }, [pgrfilters.serviceCode]);
+
+ useEffect(() => {
+ if (pgrfilters.locality.length > 1) {
+ setSelectedLocality({ name: `${pgrfilters.locality.length} selected` });
+ } else {
+ setSelectedLocality(pgrfilters.locality[0]);
+ }
+ }, [pgrfilters.locality]);
+
+ const onRemove = (index, key) => {
+ let afterRemove = pgrfilters[key].filter((value, i) => {
+ return i !== index;
+ });
+ setPgrFilters({ ...pgrfilters, [key]: afterRemove });
+ };
+
+ const handleAssignmentChange = (e, type) => {
+ if (e.target.checked) {
+ setPgrFilters({ ...pgrfilters, applicationStatus: [...pgrfilters.applicationStatus, { code: type.code }] });
+ } else {
+ const filteredStatus = pgrfilters.applicationStatus.filter((value) => {
+ return value.code !== type.code;
+ });
+ setPgrFilters({ ...pgrfilters, applicationStatus: filteredStatus });
+ }
+ };
+
+ function clearAll() {
+ let pgrReset = { serviceCode: [], locality: [], applicationStatus: [] };
+ let wfRest = { assigned: [{ code: [] }] };
+ setPgrFilters(pgrReset);
+ setWfFilters(wfRest);
+ pgrQuery = {};
+ wfQuery = {};
+ setSelectedAssigned("");
+ setSelectedComplaintType(null);
+ setSelectedLocality(null);
+ }
+
+ const handleFilterSubmit = () => {
+ props.onFilterChange({ pgrQuery: pgrQuery, wfQuery: wfQuery, wfFilters, pgrfilters });
+ };
+
+ const GetSelectOptions = (lable, options, selected = null, select, optionKey, onRemove, key) => {
+ selected = selected || { [optionKey]: " ", code: "" };
+ return (
+
+
{lable}
+ {
select(value, key)} optionKey={optionKey} />}
+
+
+ {pgrfilters[key].length > 0 &&
+ pgrfilters[key].map((value, index) => {
+ return onRemove(index, key)} />;
+ })}
+
+
+ );
+ };
+
+ return (
+
+
+
+
+
{t("ES_COMMON_FILTER_BY")}:
+
+ {t("ES_COMMON_CLEAR_ALL")}
+
+ {props.type === "desktop" && (
+
+ {t("ES_COMMON_CLEAR_ALL")}
+
+ )}
+ {props.type === "mobile" && (
+
+
+
+ )}
+
+
+
+
+ {GetSelectOptions(
+ t("CS_COMPLAINT_DETAILS_COMPLAINT_SUBTYPE"),
+ serviceDefs,
+ selectedComplaintType,
+ complaintType,
+ "i18nKey",
+ onRemove,
+ "serviceCode"
+ )}
+
+
{GetSelectOptions(t("CS_PGR_LOCALITY"), localities, selectedLocality, onSelectLocality, "i18nkey", onRemove, "locality")}
+ {
}
+
+
+
+
+ {props.type === "mobile" && (
+
+ )}
+
+
+ );
+};
+
+export default Filter;
diff --git a/micro-ui/web/packages/pgr/src/components/inbox/Status.js b/micro-ui/web/packages/pgr/src/components/inbox/Status.js
new file mode 100644
index 00000000000..1980ab00ae3
--- /dev/null
+++ b/micro-ui/web/packages/pgr/src/components/inbox/Status.js
@@ -0,0 +1,27 @@
+import React from "react";
+import { CheckBox, Loader } from "@egovernments/digit-ui-react-components";
+import { useTranslation } from "react-i18next";
+
+const Status = ({ complaints, onAssignmentChange, pgrfilters }) => {
+ const { t } = useTranslation();
+ const complaintsWithCount = Digit.Hooks.pgr.useComplaintStatusCount(complaints);
+ let hasFilters = pgrfilters?.applicationStatus?.length;
+ return (
+
+
{t("ES_PGR_FILTER_STATUS")}
+ {complaintsWithCount.length === 0 &&
}
+ {complaintsWithCount.map((option, index) => {
+ return (
+
onAssignmentChange(e, option)}
+ checked={hasFilters ? (pgrfilters.applicationStatus.filter((e) => e.code === option.code).length !== 0 ? true : false) : false}
+ label={`${option.name} (${option.count || 0})`}
+ />
+ );
+ })}
+
+ );
+};
+
+export default Status;
diff --git a/micro-ui/web/packages/pgr/src/components/inbox/search.js b/micro-ui/web/packages/pgr/src/components/inbox/search.js
new file mode 100644
index 00000000000..3bbcc4213e1
--- /dev/null
+++ b/micro-ui/web/packages/pgr/src/components/inbox/search.js
@@ -0,0 +1,110 @@
+import React, { useState } from "react";
+import { useForm } from "react-hook-form";
+import { useTranslation } from "react-i18next";
+import { TextInput, Label, SubmitBar, LinkLabel, ActionBar, CloseSvg } from "@egovernments/digit-ui-react-components";
+
+const SearchComplaint = ({ onSearch, type, onClose, searchParams }) => {
+ const [complaintNo, setComplaintNo] = useState(searchParams?.search?.serviceRequestId || "");
+ const [mobileNo, setMobileNo] = useState(searchParams?.search?.mobileNumber || "");
+ const { register, errors, handleSubmit, reset } = useForm();
+ const { t } = useTranslation();
+
+ const onSubmitInput = (data) => {
+ if (!Object.keys(errors).filter((i) => errors[i]).length) {
+ if (data.serviceRequestId !== "") {
+ onSearch({ serviceRequestId: data.serviceRequestId });
+ } else if (data.mobileNumber !== "") {
+ onSearch({ mobileNumber: data.mobileNumber });
+ } else {
+ onSearch({});
+ }
+
+ if (type === "mobile") {
+ onClose();
+ }
+ }
+ };
+
+ function clearSearch() {
+ reset();
+ onSearch({});
+ setComplaintNo("");
+ setMobileNo("");
+ }
+
+ const clearAll = () => {
+ return (
+
+ {t("ES_COMMON_CLEAR_SEARCH")}
+
+ );
+ };
+
+ function setComplaint(e) {
+ setComplaintNo(e.target.value);
+ }
+
+ function setMobile(e) {
+ setMobileNo(e.target.value);
+ }
+
+ return (
+
+ );
+};
+
+export default SearchComplaint;
diff --git a/micro-ui/web/packages/pgr/src/components/timelineInstances/PendingForAssignment.js b/micro-ui/web/packages/pgr/src/components/timelineInstances/PendingForAssignment.js
new file mode 100644
index 00000000000..489c1de0f38
--- /dev/null
+++ b/micro-ui/web/packages/pgr/src/components/timelineInstances/PendingForAssignment.js
@@ -0,0 +1,8 @@
+import React from "react";
+import { CheckPoint } from "@egovernments/digit-ui-react-components";
+
+const PendingForAssignment = ({ isCompleted, text, complaintFiledDate, customChild }) => {
+ return ;
+};
+
+export default PendingForAssignment;
diff --git a/micro-ui/web/packages/pgr/src/components/timelineInstances/PendingForReassignment.js b/micro-ui/web/packages/pgr/src/components/timelineInstances/PendingForReassignment.js
new file mode 100644
index 00000000000..ba50b8aa136
--- /dev/null
+++ b/micro-ui/web/packages/pgr/src/components/timelineInstances/PendingForReassignment.js
@@ -0,0 +1,5 @@
+import React from "react";
+
+const PendingForReassignment = ({ text }) => {text};
+
+export default PendingForReassignment;
diff --git a/micro-ui/web/packages/pgr/src/components/timelineInstances/StarRated.js b/micro-ui/web/packages/pgr/src/components/timelineInstances/StarRated.js
new file mode 100644
index 00000000000..23efde2d31a
--- /dev/null
+++ b/micro-ui/web/packages/pgr/src/components/timelineInstances/StarRated.js
@@ -0,0 +1,6 @@
+import React from "react";
+import { Rating } from "@egovernments/digit-ui-react-components";
+
+const StarRated = ({ text, rating }) => {}} />;
+
+export default StarRated;
diff --git a/micro-ui/web/packages/pgr/src/components/timelineInstances/pendingAtLme.js b/micro-ui/web/packages/pgr/src/components/timelineInstances/pendingAtLme.js
new file mode 100644
index 00000000000..e55ddac2c11
--- /dev/null
+++ b/micro-ui/web/packages/pgr/src/components/timelineInstances/pendingAtLme.js
@@ -0,0 +1,15 @@
+import { TelePhone, CheckPoint } from "@egovernments/digit-ui-react-components";
+import React from "react";
+import { useTranslation } from "react-i18next";
+
+const PendingAtLME = ({ name, isCompleted, mobile, text, customChild }) => {
+ let { t } = useTranslation();
+ return
+ {name && mobile ? : null }
+ {customChild}
+
+ } />
+};
+
+export default PendingAtLME;
diff --git a/micro-ui/web/packages/pgr/src/components/timelineInstances/rejected.js b/micro-ui/web/packages/pgr/src/components/timelineInstances/rejected.js
new file mode 100644
index 00000000000..07606d1a8d6
--- /dev/null
+++ b/micro-ui/web/packages/pgr/src/components/timelineInstances/rejected.js
@@ -0,0 +1,55 @@
+import React from "react";
+import { ActionLinks, CheckPoint } from "@egovernments/digit-ui-react-components";
+import { Link } from "react-router-dom";
+import StarRated from "./StarRated";
+import { useTranslation } from "react-i18next";
+import Reopen from "./reopen";
+//const GetTranslatedAction = (action, t) => t(`CS_COMMON_${action}`);
+
+const Rejected = ({ action, nextActions, complaintDetails, ComplainMaxIdleTime=3600000, rating, serviceRequestId, reopenDate, isCompleted }) => {
+ const { t } = useTranslation();
+
+ if (action === "REJECTED") {
+ let actions =
+ nextActions &&
+ nextActions.map((action, index) => {
+ if (action && action !== "COMMENT") {
+ return (
+
+ {t(`CS_COMMON_${action}`)}
+
+ );
+ }
+ });
+ return {actions}} />;
+ } else if (action === "RATE" && rating) {
+ return (
+
+ {rating ? : null}
+ {customChild}
+ }
+ />
+ );
+ } else if (action === "REOPEN") {
+ return ;
+ } else {
+ let actions =
+ nextActions &&
+ nextActions.map((action, index) => {
+ if (action && (action !== "COMMENT") ) {
+ if((action!== "REOPEN" || (action === "REOPEN" && (Date?.now() - complaintDetails?.service?.auditDetails?.lastModifiedTime) < ComplainMaxIdleTime)))
+ return (
+
+ {t(`CS_COMMON_${action}`)}
+
+ );
+ }
+ });
+ return {actions}} />;
+ }
+};
+
+export default Rejected;
diff --git a/micro-ui/web/packages/pgr/src/components/timelineInstances/reopen.js b/micro-ui/web/packages/pgr/src/components/timelineInstances/reopen.js
new file mode 100644
index 00000000000..59b1bd8681e
--- /dev/null
+++ b/micro-ui/web/packages/pgr/src/components/timelineInstances/reopen.js
@@ -0,0 +1,14 @@
+import { GreyOutText } from "@egovernments/digit-ui-react-components";
+import React from "react";
+const Reopen = ({ text, reopenDate }) => {
+ // let { t } = useTranslation();
+ // let reopenDate = ConvertTimestampToDate(obj.auditDetails.createdTime);
+ return (
+
+ {text}
+ {reopenDate}
+
+ );
+};
+
+export default Reopen;
diff --git a/micro-ui/web/packages/pgr/src/components/timelineInstances/resolved.js b/micro-ui/web/packages/pgr/src/components/timelineInstances/resolved.js
new file mode 100644
index 00000000000..7d51132ba3b
--- /dev/null
+++ b/micro-ui/web/packages/pgr/src/components/timelineInstances/resolved.js
@@ -0,0 +1,55 @@
+import React from "react";
+import { ActionLinks, CheckPoint } from "@egovernments/digit-ui-react-components";
+import { Link } from "react-router-dom";
+import StarRated from "./StarRated";
+import { useTranslation } from "react-i18next";
+import Reopen from "./reopen";
+//const GetTranslatedAction = (action, t) => t(`CS_COMMON_${action}`);
+
+const Resolved = ({ action, nextActions,complaintDetails, ComplainMaxIdleTime=3600000, rating, serviceRequestId, reopenDate, isCompleted, customChild }) => {
+ const { t } = useTranslation();
+
+ if (action === "RESOLVE") {
+ let actions =
+ nextActions &&
+ nextActions.map((action, index) => {
+ if (action && action !== "COMMENT") {
+ return (
+
+ {t(`CS_COMMON_${action}`)}
+
+ );
+ }
+ });
+ return {actions}{customChild}} />;
+ } else if (action === "RATE") {
+ return (
+
+ {/* {rating ? : null} */}
+ {customChild}
+ }
+ />
+ );
+ } else if (action === "REOPEN") {
+ return ;
+ } else {
+ let actions =
+ nextActions &&
+ nextActions.map((action, index) => {
+ if (action && action !== "COMMENT") {
+ if((action!== "REOPEN" || (action === "REOPEN" && (Date?.now() - complaintDetails?.service?.auditDetails?.lastModifiedTime) < ComplainMaxIdleTime)))
+ return (
+
+ {t(`CS_COMMON_${action}`)}
+
+ );
+ }
+ });
+ return {actions}{customChild}} />;
+ }
+};
+
+export default Resolved;
diff --git a/micro-ui/web/packages/pgr/src/constants/Citizen.js b/micro-ui/web/packages/pgr/src/constants/Citizen.js
new file mode 100644
index 00000000000..2c550d45bc5
--- /dev/null
+++ b/micro-ui/web/packages/pgr/src/constants/Citizen.js
@@ -0,0 +1,3 @@
+// Session Storage Keys
+export const PGR_CITIZEN_CREATE_COMPLAINT = "PGR_CITIZEN_CREATE_COMPLAINT";
+export const PGR_CITIZEN_COMPLAINT_CONFIG = "PGR_CITIZEN_COMPLAINT_CONFIG";
diff --git a/micro-ui/web/packages/pgr/src/constants/Employee.js b/micro-ui/web/packages/pgr/src/constants/Employee.js
new file mode 100644
index 00000000000..46173a9a280
--- /dev/null
+++ b/micro-ui/web/packages/pgr/src/constants/Employee.js
@@ -0,0 +1,2 @@
+export const PGR_EMPLOYEE_COMPLAINT_DETAILS = "/complaint/details/";
+export const PGR_EMPLOYEE_CREATE_COMPLAINT = "/complaint/create";
diff --git a/micro-ui/web/packages/pgr/src/constants/Localization.js b/micro-ui/web/packages/pgr/src/constants/Localization.js
new file mode 100644
index 00000000000..91e8479942a
--- /dev/null
+++ b/micro-ui/web/packages/pgr/src/constants/Localization.js
@@ -0,0 +1,20 @@
+export const LOCALIZATION_KEY = {
+ CS_COMPLAINT_DETAILS: "CS_COMPLAINT_DETAILS",
+ CS_COMMON: "CS_COMMON",
+ CS_COMPLAINT: "CS_COMPLAINT",
+ CS_FEEDBACK: "CS_FEEDBACK",
+ CS_HEADER: "CS_HEADER",
+ CS_HOME: "CS_HOME",
+ CS_ADDCOMPLAINT: "CS_ADDCOMPLAINT",
+ CS_REOPEN: "CS_REOPEN",
+ CS_CREATECOMPLAINT: "CS_CREATECOMPLAINT",
+ PT_COMMONS: "PT_COMMONS",
+ CORE_COMMON: "CORE_COMMON",
+};
+
+export const LOCALE = {
+ MY_COMPLAINTS: "CS_HOME_MY_COMPLAINTS",
+ NO_COMPLAINTS: "CS_MYCOMPLAINTS_NO_COMPLAINTS",
+ NO_COMPLAINTS_EMPLOYEE: "CS_MYCOMPLAINTS_NO_COMPLAINTS_EMPLOYEE",
+ ERROR_LOADING_RESULTS: "CS_COMMON_ERROR_LOADING_RESULTS",
+};
diff --git a/micro-ui/web/packages/pgr/src/constants/Routes.js b/micro-ui/web/packages/pgr/src/constants/Routes.js
new file mode 100644
index 00000000000..e60b7e6a27e
--- /dev/null
+++ b/micro-ui/web/packages/pgr/src/constants/Routes.js
@@ -0,0 +1,38 @@
+export const PGR_BASE = "/digit-ui/pgr/citizen/";
+
+const CREATE_COMPLAINT_PATH = "/create-complaint/";
+const REOPEN_COMPLAINT_PATH = "/reopen/";
+import { PGR_EMPLOYEE_COMPLAINT_DETAILS, PGR_EMPLOYEE_CREATE_COMPLAINT } from "./Employee";
+
+export const PgrRoutes = {
+ ComplaintsPage: "/complaints",
+ RatingAndFeedBack: "/rate/:id*",
+ ComplaintDetailsPage: "/complaint/details/:id",
+ ReasonPage: `/:id`,
+ UploadPhoto: `/upload-photo/:id`,
+ AddtionalDetails: `/addional-details/:id`,
+ CreateComplaint: "/create-complaint",
+ ReopenComplaint: "/reopen",
+ Response: "/response",
+
+ CreateComplaintStart: "",
+ SubType: `/subtype`,
+ LocationSearch: `/location`,
+ Pincode: `/pincode`,
+ Address: `/address`,
+ Landmark: `/landmark`,
+ UploadPhotos: `/upload-photos`,
+ Details: `/details`,
+ CreateComplaintResponse: `/response`,
+};
+
+export const Employee = {
+ Inbox: "/inbox",
+ InboxV2: "/inbox/v2",
+ ComplaintDetails: PGR_EMPLOYEE_COMPLAINT_DETAILS,
+ CreateComplaint: PGR_EMPLOYEE_CREATE_COMPLAINT,
+ Response: "/response",
+ Home: "/digit-ui/employee",
+};
+
+export const getRoute = (match, route) => `${match.path}${route}`;
diff --git a/micro-ui/web/packages/pgr/src/pages/citizen/ComplaintDetails.js b/micro-ui/web/packages/pgr/src/pages/citizen/ComplaintDetails.js
new file mode 100644
index 00000000000..c4fd9bc9b65
--- /dev/null
+++ b/micro-ui/web/packages/pgr/src/pages/citizen/ComplaintDetails.js
@@ -0,0 +1,186 @@
+import React, { useEffect, useState } from "react";
+import { useParams } from "react-router-dom";
+import { useTranslation } from "react-i18next";
+
+import { LOCALIZATION_KEY } from "../../constants/Localization";
+
+import {
+ Card,
+ Header,
+ CardSubHeader,
+ StatusTable,
+ Row,
+ TextArea,
+ SubmitBar,
+ DisplayPhotos,
+ ImageViewer,
+ Loader,
+ Toast,
+} from "@egovernments/digit-ui-react-components";
+
+import TimeLine from "../../components/TimeLine";
+
+const WorkflowComponent = ({ complaintDetails, id, getWorkFlow, zoomImage }) => {
+ const tenantId = Digit.SessionStorage.get("CITIZEN.COMMON.HOME.CITY")?.code || complaintDetails.service.tenantId;
+ let workFlowDetails = Digit.Hooks.useWorkflowDetails({ tenantId: tenantId, id, moduleCode: "PGR" });
+ const { data: ComplainMaxIdleTime, isLoading: ComplainMaxIdleTimeLoading } = Digit.Hooks.pgr.useMDMS.ComplainClosingTime(tenantId?.split(".")[0]);
+
+ useEffect(() => {
+ getWorkFlow(workFlowDetails.data);
+ }, [workFlowDetails.data]);
+
+ useEffect(() => {
+ workFlowDetails.revalidate();
+ }, []);
+
+ return (
+ !workFlowDetails.isLoading && (
+
+ )
+ );
+};
+
+const ComplaintDetailsPage = (props) => {
+ let { t } = useTranslation();
+ let { id } = useParams();
+
+ let tenantId = Digit.SessionStorage.get("CITIZEN.COMMON.HOME.CITY")?.code || Digit.ULBService.getCurrentTenantId(); // ToDo: fetch from state
+ const { isLoading, error, isError, complaintDetails, revalidate } = Digit.Hooks.pgr.useComplaintDetails({ tenantId, id });
+
+ const [imageShownBelowComplaintDetails, setImageToShowBelowComplaintDetails] = useState({});
+
+ const [imageZoom, setImageZoom] = useState(null);
+
+ const [comment, setComment] = useState("");
+
+ const [toast, setToast] = useState(false);
+
+ const [commentError, setCommentError] = useState(null);
+
+ const [disableComment, setDisableComment] = useState(true);
+
+ const [loader, setLoader] = useState(false);
+
+ useEffect(() => {
+ (async () => {
+ if (complaintDetails) {
+ setLoader(true);
+ await revalidate();
+ setLoader(false);
+ }
+ })();
+ }, []);
+
+ function zoomImage(imageSource, index) {
+ setImageZoom(imageSource);
+ }
+ function zoomImageWrapper(imageSource, index) {
+ zoomImage(imageShownBelowComplaintDetails?.fullImage[index]);
+ }
+
+ function onCloseImageZoom() {
+ setImageZoom(null);
+ }
+
+ const onWorkFlowChange = (data) => {
+ let timeline = data?.timeline;
+ timeline && timeline[0].timeLineActions?.filter((e) => e === "COMMENT").length ? setDisableComment(false) : setDisableComment(true);
+ if (timeline) {
+ const actionByCitizenOnComplaintCreation = timeline.find((e) => e?.performedAction === "APPLY");
+ const { thumbnailsToShow } = actionByCitizenOnComplaintCreation;
+ setImageToShowBelowComplaintDetails(thumbnailsToShow);
+ }
+ };
+
+ const submitComment = async () => {
+ let detailsToSend = { ...complaintDetails };
+ delete detailsToSend.audit;
+ delete detailsToSend.details;
+ detailsToSend.workflow = { action: "COMMENT", comments: comment };
+ let tenantId = Digit.ULBService.getCurrentTenantId();
+ try {
+ setCommentError(null);
+ const res = await Digit.PGRService.update(detailsToSend, tenantId);
+ if (res.ServiceWrappers.length) setComment("");
+ else throw true;
+ } catch (er) {
+ setCommentError(true);
+ }
+ setToast(true);
+ setTimeout(() => {
+ setToast(false);
+ }, 30000);
+ };
+
+ if (isLoading || loader) {
+ return ;
+ }
+
+ if (isError) {
+ return Error
;
+ }
+
+ return (
+
+
+ {t(`${LOCALIZATION_KEY.CS_HEADER}_COMPLAINT_SUMMARY`)}
+
+ {Object.keys(complaintDetails).length > 0 ? (
+
+
+ {t(`SERVICEDEFS.${complaintDetails.audit.serviceCode.toUpperCase()}`)}
+
+ {Object.keys(complaintDetails.details).map((flag, index, arr) => (
+ (typeof val === "object" ? t(val?.code) : t(val)))
+ : t(complaintDetails.details[flag]) || "N/A"
+ }
+ last={index === arr.length - 1}
+ />
+ ))}
+
+ {imageShownBelowComplaintDetails?.thumbs ? (
+ zoomImageWrapper(source, index)} />
+ ) : null}
+ {imageZoom ? : null}
+
+
+ {complaintDetails?.service && (
+
+ )}
+
+ {/*
+ {t(`${LOCALIZATION_KEY.CS_COMMON}_COMMENTS`)}
+ */}
+ {toast && (
+ setToast(false)}
+ />
+ )}{" "}
+
+ ) : (
+
+ )}
+
+
+ );
+};
+
+export default ComplaintDetailsPage;
\ No newline at end of file
diff --git a/micro-ui/web/packages/pgr/src/pages/citizen/ComplaintsList.js b/micro-ui/web/packages/pgr/src/pages/citizen/ComplaintsList.js
new file mode 100644
index 00000000000..805ebb5941b
--- /dev/null
+++ b/micro-ui/web/packages/pgr/src/pages/citizen/ComplaintsList.js
@@ -0,0 +1,68 @@
+import React, { useEffect } from "react";
+import { useTranslation } from "react-i18next";
+import { useRouteMatch } from "react-router-dom";
+
+import { Card, Header, Loader } from "@egovernments/digit-ui-react-components";
+import { LOCALE } from "../../constants/Localization";
+import Complaint from "../../components/Complaint";
+
+export const ComplaintsList = (props) => {
+ const User = Digit.UserService.getUser();
+ const mobileNumber = User.mobileNumber || User?.info?.mobileNumber || User?.info?.userInfo?.mobileNumber;
+ const tenantId = Digit.SessionStorage.get("CITIZEN.COMMON.HOME.CITY")?.code || Digit.ULBService.getCurrentTenantId();
+ const { t } = useTranslation();
+ const { path, url } = useRouteMatch();
+ let { isLoading, error, data, revalidate } = Digit.Hooks.pgr.useComplaintsListByMobile(tenantId, mobileNumber);
+
+ useEffect(() => {
+ revalidate();
+ }, []);
+
+ if (isLoading) {
+ return (
+
+ {t(LOCALE.MY_COMPLAINTS)}
+
+
+ );
+ }
+
+ let complaints = data?.ServiceWrappers;
+ let complaintsList;
+ if (error) {
+ complaintsList = (
+
+ {t(LOCALE.ERROR_LOADING_RESULTS)
+ .split("\\n")
+ .map((text, index) => (
+
+ {text}
+
+ ))}
+
+ );
+ } else if (complaints.length === 0) {
+ complaintsList = (
+
+ {t(LOCALE.NO_COMPLAINTS)
+ .split("\\n")
+ .map((text, index) => (
+
+ {text}
+
+ ))}
+
+ );
+ } else {
+ complaintsList = complaints.map(({ service }, index) => );
+ }
+
+ return (
+
+
+ {t(LOCALE.MY_COMPLAINTS)}
+ {complaintsList}
+
+
+ );
+};
diff --git a/micro-ui/web/packages/pgr/src/pages/citizen/Create/Response.js b/micro-ui/web/packages/pgr/src/pages/citizen/Create/Response.js
new file mode 100644
index 00000000000..6173f2c4e03
--- /dev/null
+++ b/micro-ui/web/packages/pgr/src/pages/citizen/Create/Response.js
@@ -0,0 +1,51 @@
+import React from "react";
+import { Card, Banner, CardText, SubmitBar } from "@egovernments/digit-ui-react-components";
+import { Link } from "react-router-dom";
+import { useSelector } from "react-redux";
+import { PgrRoutes, getRoute } from "../../../constants/Routes";
+import { useTranslation } from "react-i18next";
+
+const GetActionMessage = ({ action }) => {
+ const { t } = useTranslation();
+ switch (action) {
+ case "REOPEN":
+ return t(`CS_COMMON_COMPLAINT_REOPENED`);
+ case "RATE":
+ return t("CS_COMMON_THANK_YOU");
+ default:
+ return t(`CS_COMMON_COMPLAINT_SUBMITTED`);
+ }
+};
+
+const BannerPicker = ({ response }) => {
+ const { complaints } = response;
+
+ if (complaints && complaints.response && complaints.response.responseInfo) {
+ return (
+
+ );
+ } else {
+ return ;
+ }
+};
+
+const Response = (props) => {
+ const { t } = useTranslation();
+ const appState = useSelector((state) => state)["pgr"];
+
+ return (
+
+ {appState.complaints.response && }
+ {t("CS_COMMON_TRACK_COMPLAINT_TEXT")}
+
+
+
+
+ );
+};
+
+export default Response;
diff --git a/micro-ui/web/packages/pgr/src/pages/citizen/Create/Steps/Response.js b/micro-ui/web/packages/pgr/src/pages/citizen/Create/Steps/Response.js
new file mode 100644
index 00000000000..9e14b599eab
--- /dev/null
+++ b/micro-ui/web/packages/pgr/src/pages/citizen/Create/Steps/Response.js
@@ -0,0 +1,39 @@
+import React from "react";
+import { FormStep, Banner } from "@egovernments/digit-ui-react-components";
+import { useSelector } from "react-redux";
+import { useTranslation } from "react-i18next";
+
+const GetActionMessage = ({ action }) => {
+ const { t } = useTranslation();
+ if (action === "REOPEN") {
+ return t(`CS_COMMON_COMPLAINT_REOPENED`);
+ } else {
+ return t(`CS_COMMON_COMPLAINT_SUBMITTED`);
+ }
+};
+
+const BannerPicker = ({ complaints }) => {
+ const { t } = useTranslation();
+ if (complaints && complaints.response && complaints.response.responseInfo) {
+ return (
+
+ );
+ } else {
+ return ;
+ }
+};
+
+const Response = ({ t, config, onSelect }) => {
+ const complaints = useSelector((state) => state["pgr"].complaints);
+ return (
+
+ {complaints.response ? : null}
+
+ );
+};
+
+export default Response;
diff --git a/micro-ui/web/packages/pgr/src/pages/citizen/Create/Steps/SelectAddress.js b/micro-ui/web/packages/pgr/src/pages/citizen/Create/Steps/SelectAddress.js
new file mode 100644
index 00000000000..9741b1bd34b
--- /dev/null
+++ b/micro-ui/web/packages/pgr/src/pages/citizen/Create/Steps/SelectAddress.js
@@ -0,0 +1,74 @@
+import React, { useEffect, useState, useRef } from "react";
+import { CardLabel, Dropdown, FormStep, RadioButtons } from "@egovernments/digit-ui-react-components";
+
+const SelectAddress = ({ t, config, onSelect, value }) => {
+ const allCities = Digit.Hooks.pgr.useTenants();
+ const cities = value?.pincode ? allCities.filter((city) => city?.pincode?.some((pin) => pin == value["pincode"])) : allCities;
+
+ const [selectedCity, setSelectedCity] = useState(() => {
+ const { city_complaint } = value;
+ return city_complaint ? city_complaint : null;
+ });
+ const { data: fetchedLocalities } = Digit.Hooks.useBoundaryLocalities(
+ selectedCity?.code,
+ "admin",
+ {
+ enabled: !!selectedCity,
+ },
+ t
+ );
+ const [localities, setLocalities] = useState(null);
+
+ const [selectedLocality, setSelectedLocality] = useState(() => {
+ const { locality_complaint } = value;
+ return locality_complaint ? locality_complaint : null;
+ });
+
+ useEffect(() => {
+ if (selectedCity && fetchedLocalities) {
+ const { pincode } = value;
+ let __localityList = pincode ? fetchedLocalities.filter((city) => city["pincode"] == pincode) : fetchedLocalities;
+ setLocalities(__localityList);
+ }
+ }, [selectedCity, fetchedLocalities]);
+
+ function selectCity(city) {
+ setSelectedLocality(null);
+ setLocalities(null);
+ setSelectedCity(city);
+ // Digit.SessionStorage.set("city_complaint", city);
+ }
+
+ function selectLocality(locality) {
+ setSelectedLocality(locality);
+ // Digit.SessionStorage.set("locality_complaint", locality);
+ }
+
+ function onSubmit() {
+ onSelect({ city_complaint: selectedCity, locality_complaint: selectedLocality });
+ }
+ return (
+
+
+ {t("MYCITY_CODE_LABEL")}
+ {cities?.length < 5 ? (
+
+ ) : (
+
+ )}
+ {selectedCity && localities && {t("CS_CREATECOMPLAINT_MOHALLA")}}
+ {selectedCity && localities && (
+
+ {localities?.length < 5 ? (
+
+ ) : (
+
+ )}
+
+ )}
+
+
+ );
+};
+
+export default SelectAddress;
diff --git a/micro-ui/web/packages/pgr/src/pages/citizen/Create/Steps/SelectComplaintType.js b/micro-ui/web/packages/pgr/src/pages/citizen/Create/Steps/SelectComplaintType.js
new file mode 100644
index 00000000000..bacaeb161a5
--- /dev/null
+++ b/micro-ui/web/packages/pgr/src/pages/citizen/Create/Steps/SelectComplaintType.js
@@ -0,0 +1,37 @@
+import React, { useState } from "react";
+import { useForm } from "react-hook-form";
+import { TypeSelectCard } from "@egovernments/digit-ui-react-components";
+
+const SelectComplaintType = ({ t, config, onSelect, value }) => {
+ const [complaintType, setComplaintType] = useState(() => {
+ const { complaintType } = value;
+ return complaintType ? complaintType : {};
+ });
+
+ const goNext = () => {
+ onSelect({ complaintType });
+ };
+
+ const textParams = config.texts;
+
+ const menu = Digit.Hooks.pgr.useComplaintTypes({ stateCode: Digit.ULBService.getCurrentTenantId() });
+
+ function selectedValue(value) {
+ setComplaintType(value);
+ // SessionStorage.set("complaintType", value);
+ }
+ return (
+
+ );
+};
+
+export default SelectComplaintType;
diff --git a/micro-ui/web/packages/pgr/src/pages/citizen/Create/Steps/SelectDetails.js b/micro-ui/web/packages/pgr/src/pages/citizen/Create/Steps/SelectDetails.js
new file mode 100644
index 00000000000..377ca2cb4f2
--- /dev/null
+++ b/micro-ui/web/packages/pgr/src/pages/citizen/Create/Steps/SelectDetails.js
@@ -0,0 +1,18 @@
+import React, { useState } from "react";
+import { FormStep } from "@egovernments/digit-ui-react-components";
+
+const SelectDetails = ({ t, config, onSelect, value }) => {
+ const [details, setDetails] = useState(() => {
+ const { details } = value;
+ return details ? details : "";
+ });
+
+ const onChange = (event) => {
+ const { value } = event.target;
+ setDetails(value);
+ };
+
+ return onSelect({ details })} value={details} t={t} />;
+};
+
+export default SelectDetails;
diff --git a/micro-ui/web/packages/pgr/src/pages/citizen/Create/Steps/SelectGeolocation.js b/micro-ui/web/packages/pgr/src/pages/citizen/Create/Steps/SelectGeolocation.js
new file mode 100644
index 00000000000..d16efff8e6b
--- /dev/null
+++ b/micro-ui/web/packages/pgr/src/pages/citizen/Create/Steps/SelectGeolocation.js
@@ -0,0 +1,19 @@
+import React from "react";
+import { LocationSearchCard } from "@egovernments/digit-ui-react-components";
+
+const SelectGeolocation = ({ onSelect, onSkip, value, t }) => {
+ let pincode = "";
+ return (
+ onSelect()}
+ onSave={() => onSelect({ pincode })}
+ onChange={(code) => (pincode = code)}
+ />
+ );
+};
+
+export default SelectGeolocation;
diff --git a/micro-ui/web/packages/pgr/src/pages/citizen/Create/Steps/SelectImages.js b/micro-ui/web/packages/pgr/src/pages/citizen/Create/Steps/SelectImages.js
new file mode 100644
index 00000000000..1cc1fd67d0b
--- /dev/null
+++ b/micro-ui/web/packages/pgr/src/pages/citizen/Create/Steps/SelectImages.js
@@ -0,0 +1,36 @@
+import React, { useState } from "react";
+import { FormStep, ImageUploadHandler, Loader } from "@egovernments/digit-ui-react-components";
+
+const SelectImages = ({ t, config, onSelect, onSkip, value }) => {
+ // const __initImages = Digit.SessionStorage.get("PGR_CREATE_IMAGES");
+ const [uploadedImages, setUploadedImagesIds] = useState(() => {
+ // __initImages ? __initImages : null
+ const { uploadedImages } = value;
+ return uploadedImages ? uploadedImages : null;
+ });
+
+ const handleUpload = (ids) => {
+ setUploadedImagesIds(ids);
+ // Digit.SessionStorage.set("PGR_CREATE_IMAGES", ids);
+ };
+
+ // const onSkip = () => onSelect();
+ const handleSubmit = () => {
+ if (!uploadedImages || uploadedImages.length === 0) return onSkip();
+ // const _uploadImages = uploadedImages.map((url) => ({
+ // documentType: "PHOTO",
+ // fileStore: url,
+ // documentUid: "",
+ // additionalDetails: {},
+ // }));
+ onSelect({ uploadedImages });
+ };
+
+ return (
+
+
+
+ );
+};
+
+export default SelectImages;
diff --git a/micro-ui/web/packages/pgr/src/pages/citizen/Create/Steps/SelectLandmark.js b/micro-ui/web/packages/pgr/src/pages/citizen/Create/Steps/SelectLandmark.js
new file mode 100644
index 00000000000..ae293bc7dfb
--- /dev/null
+++ b/micro-ui/web/packages/pgr/src/pages/citizen/Create/Steps/SelectLandmark.js
@@ -0,0 +1,19 @@
+import React, { useState } from "react";
+import { FormStep } from "@egovernments/digit-ui-react-components";
+
+const SelectLandmark = ({ t, config, onSelect, value }) => {
+ const [landmark, setLandmark] = useState(() => {
+ const { landmark } = value;
+ return landmark ? landmark : "";
+ });
+
+ function onChange(e) {
+ setLandmark(e.target.value);
+ }
+
+ const onSkip = () => onSelect();
+
+ return onSelect(data)} onSkip={onSkip} t={t}>;
+};
+
+export default SelectLandmark;
diff --git a/micro-ui/web/packages/pgr/src/pages/citizen/Create/Steps/SelectPincode.js b/micro-ui/web/packages/pgr/src/pages/citizen/Create/Steps/SelectPincode.js
new file mode 100644
index 00000000000..a4d94e68bc5
--- /dev/null
+++ b/micro-ui/web/packages/pgr/src/pages/citizen/Create/Steps/SelectPincode.js
@@ -0,0 +1,56 @@
+import { FormStep } from "@egovernments/digit-ui-react-components";
+import React, { useState } from "react";
+
+const SelectPincode = ({ t, config, onSelect, value }) => {
+ const tenants = Digit.Hooks.pgr.useTenants();
+ // const __initPincode = Digit.SessionStorage.get("PGR_CREATE_PINCODE");
+ const [pincode, setPincode] = useState(() => {
+ const { pincode } = value;
+ return pincode;
+ });
+ let isNextDisabled = pincode ? false : true;
+ const [pincodeServicability, setPincodeServicability] = useState(null);
+
+ function onChange(e) {
+ setPincode(e.target.value);
+
+ if (!e.target.value) {
+ isNextDisabled = true;
+ } else {
+ isNextDisabled = false;
+ }
+ // Digit.SessionStorage.set("PGR_CREATE_PINCODE", e.target.value);
+ setPincodeServicability(null);
+ }
+
+ const goNext = async (data) => {
+ var foundValue = tenants.find((obj) => obj.pincode?.find((item) => item == data?.pincode));
+ if (foundValue) {
+ Digit.SessionStorage.set("city_complaint", foundValue);
+ let response = await Digit.LocationService.getLocalities(foundValue.code);
+ let __localityList = Digit.LocalityService.get(response.TenantBoundary[0]);
+ const filteredLocalities = __localityList.filter((obj) => obj.pincode?.find((item) => item == data.pincode));
+ onSelect({ ...data, city_complaint: foundValue });
+ } else {
+ Digit.SessionStorage.set("city_complaint", undefined);
+ Digit.SessionStorage.set("selected_localities", undefined);
+ setPincodeServicability("CS_COMMON_PINCODE_NOT_SERVICABLE");
+ }
+ };
+
+ const onSkip = () => onSelect();
+ return (
+
+ );
+};
+
+export default SelectPincode;
diff --git a/micro-ui/web/packages/pgr/src/pages/citizen/Create/Steps/SelectSubType.js b/micro-ui/web/packages/pgr/src/pages/citizen/Create/Steps/SelectSubType.js
new file mode 100644
index 00000000000..9b6d34fa77c
--- /dev/null
+++ b/micro-ui/web/packages/pgr/src/pages/citizen/Create/Steps/SelectSubType.js
@@ -0,0 +1,34 @@
+import { TypeSelectCard } from "@egovernments/digit-ui-react-components";
+import React, { useState } from "react";
+
+const SelectSubType = ({ t, config, onSelect, value }) => {
+ const [subType, setSubType] = useState(() => {
+ const { subType } = value;
+ return subType ? subType : {};
+ });
+ const { complaintType } = value;
+ const menu = Digit.Hooks.pgr.useComplaintSubType(complaintType, t);
+
+
+ const goNext = () => {
+ // const serviceCode = subType.key;
+ onSelect({ subType });
+ };
+
+ function selectedValue(value) {
+ setSubType(value);
+ }
+
+ const configNew = {
+ ...config.texts,
+ ...{ headerCaption: t(`SERVICEDEFS.${complaintType.key.toUpperCase()}`) },
+ ...{ menu: menu },
+ ...{ optionsKey: "name" },
+ ...{ selected: selectedValue },
+ ...{ selectedOption: subType },
+ ...{ onSave: goNext },
+ };
+
+ return ;
+};
+export default SelectSubType;
diff --git a/micro-ui/web/packages/pgr/src/pages/citizen/Create/config.js b/micro-ui/web/packages/pgr/src/pages/citizen/Create/config.js
new file mode 100644
index 00000000000..2571cdfa849
--- /dev/null
+++ b/micro-ui/web/packages/pgr/src/pages/citizen/Create/config.js
@@ -0,0 +1,98 @@
+export const newComplaintSteps = [
+ {
+ path: "/complaint-type",
+ texts: {
+ headerCaption: "",
+ header: "CS_ADDCOMPLAINT_COMPLAINT_TYPE_PLACEHOLDER",
+ cardText: "CS_COMPLAINT_TYPE_TEXT",
+ submitBarLabel: "PT_COMMONS_NEXT",
+ },
+ },
+ {
+ path: "/sub-type",
+ texts: {
+ header: "CS_ADDCOMPLAINT_COMPLAINT_SUBTYPE_PLACEHOLDER",
+ cardText: "CS_COMPLAINT_SUBTYPE_TEXT",
+ submitBarLabel: "PT_COMMONS_NEXT",
+ },
+ },
+ {
+ path: "/pincode",
+ texts: {
+ headerCaption: "CS_ADDCOMPLAINT_COMPLAINT_LOCATION",
+ header: "CS_FILE_APPLICATION_PINCODE_LABEL",
+ cardText: "CS_ADDCOMPLAINT_CHANGE_PINCODE_TEXT",
+ nextText: "PT_COMMONS_NEXT",
+ skipText: "CORE_COMMON_SKIP_CONTINUE",
+ },
+ inputs: [
+ {
+ label: "CORE_COMMON_PINCODE",
+ type: "text",
+ name: "pincode",
+ validation: {
+ minLength: 6,
+ maxLength: 7,
+ },
+ error: "CORE_COMMON_PINCODE_INVALID",
+ },
+ ],
+ },
+ {
+ path: "/address",
+ texts: {
+ headerCaption: "CS_ADDCOMPLAINT_COMPLAINT_LOCATION",
+ header: "CS_ADDCOMPLAINT_PROVIDE_COMPLAINT_ADDRESS",
+ cardText: "CS_ADDCOMPLAINT_CITY_MOHALLA_TEXT",
+ nextText: "PT_COMMONS_NEXT",
+ },
+ },
+ {
+ path: "/landmark",
+ texts: {
+ headerCaption: "CS_ADDCOMPLAINT_COMPLAINT_LOCATION",
+ header: "CS_FILE_APPLICATION_PROPERTY_LOCATION_PROVIDE_LANDMARK_TITLE",
+ cardText: "CS_FILE_APPLICATION_PROPERTY_LOCATION_PROVIDE_LANDMARK_TITLE_TEXT",
+ nextText: "PT_COMMONS_NEXT",
+ skipText: "CORE_COMMON_SKIP_CONTINUE",
+ },
+ inputs: [
+ {
+ label: "CS_ADDCOMPLAINT_LANDMARK",
+ type: "textarea",
+ name: "landmark",
+ },
+ ],
+ },
+ {
+ path: "/upload-photos",
+ texts: {
+ header: "CS_ADDCOMPLAINT_UPLOAD_PHOTO",
+ cardText: "CS_ADDCOMPLAINT_UPLOAD_PHOTO_TEXT",
+ nextText: "PT_COMMONS_NEXT",
+ skipText: "CORE_COMMON_SKIP_CONTINUE",
+ },
+ },
+ {
+ path: "/additional-details",
+ texts: {
+ header: "CS_ADDCOMPLAINT_PROVIDE_ADDITIONAL_DETAILS",
+ cardText: "CS_ADDCOMPLAINT_ADDITIONAL_DETAILS_TEXT",
+ nextText: "PT_COMMONS_NEXT",
+ },
+ inputs: [
+ {
+ label: "CS_ADDCOMPLAINT_ADDITIONAL_DETAILS",
+ type: "textarea",
+ name: "details",
+ },
+ ],
+ },
+ {
+ path: "/response",
+ texts: {
+ cardText: "CS_COMMON_TRACK_COMPLAINT_TEXT",
+ nextText: "CORE_COMMON_GO_TO_HOME",
+ },
+ },
+];
diff --git a/micro-ui/web/packages/pgr/src/pages/citizen/Create/defaultConfig.js b/micro-ui/web/packages/pgr/src/pages/citizen/Create/defaultConfig.js
new file mode 100644
index 00000000000..0dc0fbda572
--- /dev/null
+++ b/micro-ui/web/packages/pgr/src/pages/citizen/Create/defaultConfig.js
@@ -0,0 +1,114 @@
+import SelectAddress from "./Steps/SelectAddress";
+import SelectComplaintType from "./Steps/SelectComplaintType";
+import SelectDetails from "./Steps/SelectDetails";
+import SelectImages from "./Steps/SelectImages";
+import SelectLandmark from "./Steps/SelectLandmark";
+import SelectPincode from "./Steps/SelectPincode";
+import SelectSubType from "./Steps/SelectSubType";
+import SelectGeolocation from "./Steps/SelectGeolocation";
+
+export const config = {
+ routes: {
+ "complaint-type": {
+ component: SelectComplaintType,
+ texts: {
+ headerCaption: "",
+ header: "CS_ADDCOMPLAINT_COMPLAINT_TYPE_PLACEHOLDER",
+ cardText: "CS_COMPLAINT_TYPE_TEXT",
+ submitBarLabel: "CS_COMMON_NEXT",
+ },
+ nextStep: "sub-type",
+ },
+ "sub-type": {
+ component: SelectSubType,
+ texts: {
+ header: "CS_ADDCOMPLAINT_COMPLAINT_SUBTYPE_PLACEHOLDER",
+ cardText: "CS_COMPLAINT_SUBTYPE_TEXT",
+ submitBarLabel: "CS_COMMON_NEXT",
+ },
+ nextStep: "map",
+ },
+ map: {
+ component: SelectGeolocation,
+ nextStep: "pincode",
+ },
+ pincode: {
+ component: SelectPincode,
+ texts: {
+ headerCaption: "CS_ADDCOMPLAINT_COMPLAINT_LOCATION",
+ header: "CS_FILE_APPLICATION_PINCODE_LABEL",
+ cardText: "CS_ADDCOMPLAINT_CHANGE_PINCODE_TEXT",
+ submitBarLabel: "CS_COMMON_NEXT",
+ skipText: "CORE_COMMON_SKIP_CONTINUE",
+ },
+ inputs: [
+ {
+ label: "CORE_COMMON_PINCODE",
+ type: "text",
+ name: "pincode",
+ validation: {
+ minLength: 6,
+ maxLength: 7,
+ },
+ error: "CORE_COMMON_PINCODE_INVALID",
+ },
+ ],
+ nextStep: "address",
+ },
+ address: {
+ component: SelectAddress,
+ texts: {
+ headerCaption: "CS_ADDCOMPLAINT_COMPLAINT_LOCATION",
+ header: "CS_ADDCOMPLAINT_PROVIDE_COMPLAINT_ADDRESS",
+ cardText: "CS_ADDCOMPLAINT_CITY_MOHALLA_TEXT",
+ submitBarLabel: "CS_COMMON_NEXT",
+ },
+ nextStep: "landmark",
+ },
+ landmark: {
+ component: SelectLandmark,
+ texts: {
+ headerCaption: "CS_ADDCOMPLAINT_COMPLAINT_LOCATION",
+ header: "CS_FILE_APPLICATION_PROPERTY_LOCATION_PROVIDE_LANDMARK_TITLE",
+ cardText: "CS_FILE_APPLICATION_PROPERTY_LOCATION_PROVIDE_LANDMARK_TITLE_TEXT",
+ submitBarLabel: "CS_COMMON_NEXT",
+ skipText: "CORE_COMMON_SKIP_CONTINUE",
+ },
+ inputs: [
+ {
+ label: "CS_ADDCOMPLAINT_LANDMARK",
+ type: "textarea",
+ name: "landmark",
+ },
+ ],
+ nextStep: "upload-photos",
+ },
+ "upload-photos": {
+ component: SelectImages,
+ texts: {
+ header: "CS_ADDCOMPLAINT_UPLOAD_PHOTO",
+ cardText: "CS_ADDCOMPLAINT_UPLOAD_PHOTO_TEXT",
+ submitBarLabel: "CS_COMMON_NEXT",
+ skipText: "CORE_COMMON_SKIP_CONTINUE",
+ },
+ nextStep: "additional-details",
+ },
+ "additional-details": {
+ component: SelectDetails,
+ texts: {
+ header: "CS_ADDCOMPLAINT_PROVIDE_ADDITIONAL_DETAILS",
+ cardText: "CS_ADDCOMPLAINT_ADDITIONAL_DETAILS_TEXT",
+ submitBarLabel: "CS_COMMON_NEXT",
+ },
+ inputs: [
+ {
+ label: "CS_ADDCOMPLAINT_ADDITIONAL_DETAILS",
+ type: "textarea",
+ name: "details",
+ },
+ ],
+ nextStep: null,
+ },
+ },
+ indexRoute: "complaint-type",
+};
diff --git a/micro-ui/web/packages/pgr/src/pages/citizen/Create/index.js b/micro-ui/web/packages/pgr/src/pages/citizen/Create/index.js
new file mode 100644
index 00000000000..740de4a682f
--- /dev/null
+++ b/micro-ui/web/packages/pgr/src/pages/citizen/Create/index.js
@@ -0,0 +1,129 @@
+import React, { useContext, useEffect, useMemo, useState } from "react";
+import { useTranslation } from "react-i18next";
+import merge from "lodash.merge";
+import { useDispatch } from "react-redux";
+import { createComplaint } from "../../../redux/actions/index";
+import { PGR_CITIZEN_COMPLAINT_CONFIG, PGR_CITIZEN_CREATE_COMPLAINT } from "../../../constants/Citizen";
+import Response from "./Response";
+
+import { config as defaultConfig } from "./defaultConfig";
+import { Redirect, Route, Switch, useHistory, useRouteMatch, useLocation } from "react-router-dom";
+import { useQueryClient } from "react-query";
+
+export const CreateComplaint = () => {
+ const ComponentProvider = Digit.Contexts.ComponentProvider;
+ const { t } = useTranslation();
+ const { pathname } = useLocation();
+ const match = useRouteMatch();
+ const history = useHistory();
+ const registry = useContext(ComponentProvider);
+ const dispatch = useDispatch();
+ const { data: storeData, isLoading } = Digit.Hooks.useStore.getInitData();
+ const { stateInfo } = storeData || {};
+ const [params, setParams, clearParams] = Digit.Hooks.useSessionStorage(PGR_CITIZEN_CREATE_COMPLAINT, {});
+ // const [customConfig, setConfig] = Digit.Hooks.useSessionStorage(PGR_CITIZEN_COMPLAINT_CONFIG, {});
+ const config = useMemo(() => merge(defaultConfig, Digit.Customizations.PGR.complaintConfig), [Digit.Customizations.PGR.complaintConfig]);
+ const [paramState, setParamState] = useState(params);
+ const [nextStep, setNextStep] = useState("");
+ const [canSubmit, setCanSubmit] = useState(false);
+
+ const [rerender, setRerender] = useState(0);
+ const client = useQueryClient();
+ useEffect(() => {
+ setCanSubmit(false);
+ }, []);
+
+ useEffect(() => {
+ setParamState(params);
+ if (nextStep === null) {
+ wrapperSubmit();
+ } else {
+ history.push(`${match.path}/${nextStep}`);
+ }
+ }, [params, nextStep]);
+
+ const goNext = () => {
+ const currentPath = pathname.split("/").pop();
+
+ let { nextStep } = config.routes[currentPath];
+ let compType = Digit.SessionStorage.get(PGR_CITIZEN_CREATE_COMPLAINT);
+ if (nextStep === "sub-type" && compType.complaintType.key === "Others") {
+ setParams({
+ ...params,
+ complaintType: { key: "Others", name: t("SERVICEDEFS.OTHERS") },
+ subType: { key: "Others", name: t("SERVICEDEFS.OTHERS") },
+ });
+ nextStep = config.routes[nextStep].nextStep;
+ }
+ setNextStep(nextStep);
+ };
+
+ const wrapperSubmit = () => {
+ if (!canSubmit) {
+ setCanSubmit(true);
+ submitComplaint();
+ }
+ };
+ const submitComplaint = async () => {
+ if (paramState?.complaintType) {
+ const { city_complaint, locality_complaint, uploadedImages, complaintType, subType, details, ...values } = paramState;
+ const { code: cityCode, name: city } = city_complaint;
+ const { code: localityCode, name: localityName } = locality_complaint;
+ const _uploadImages = uploadedImages?.map((url) => ({
+ documentType: "PHOTO",
+ fileStoreId: url,
+ documentUid: "",
+ additionalDetails: {},
+ }));
+
+ const data = {
+ ...values,
+ complaintType: subType.key,
+ cityCode,
+ city,
+ description: details,
+ district: city,
+ region: city,
+ localityCode,
+ localityName,
+ state: stateInfo.name,
+ uploadedImages: _uploadImages,
+ };
+
+ await dispatch(createComplaint(data));
+ await client.refetchQueries(["complaintsList"]);
+ history.push(`${match.path}/response`);
+ }
+ };
+
+ const handleSelect = (data) => {
+ setParams({ ...params, ...data });
+ goNext();
+ };
+
+ const handleSkip = () => {
+ goNext();
+ };
+
+ if (isLoading) return null;
+
+ return (
+
+ {Object.keys(config.routes).map((route, index) => {
+ const { component, texts, inputs } = config.routes[route];
+ const Component = typeof component === "string" ? Digit.ComponentRegistryService.getComponent(component) : component;
+ return (
+
+
+
+ );
+ })}
+
+
+
+
+
+
+
+ );
+};
diff --git a/micro-ui/web/packages/pgr/src/pages/citizen/Rating/Rating.js b/micro-ui/web/packages/pgr/src/pages/citizen/Rating/Rating.js
new file mode 100644
index 00000000000..6516c89b1ab
--- /dev/null
+++ b/micro-ui/web/packages/pgr/src/pages/citizen/Rating/Rating.js
@@ -0,0 +1,76 @@
+import React, { useCallback, useState } from "react";
+import { useParams } from "react-router-dom";
+import { useForm } from "react-hook-form";
+import { useDispatch } from "react-redux";
+import { useTranslation } from "react-i18next";
+
+import { Card, CardHeader, CardLabel, Rating, CheckBox, TextArea, SubmitBar } from "@egovernments/digit-ui-react-components";
+import { updateComplaints } from "../../../redux/actions/index";
+
+import { LOCALIZATION_KEY } from "../../../constants/Localization";
+//import { Storage } from "../../@egovernments/digit-utils/services/Storage";
+
+const RatingAndFeedBack = () => {
+ const { id } = useParams();
+ const { handleSubmit } = useForm();
+ const { t } = useTranslation();
+
+ const dispatch = useDispatch();
+
+ const [selection, setSelection] = useState([]);
+ const [comment, setComment] = useState("");
+ const [rating, setRating] = useState(0);
+
+ let complaintDetails = Digit.SessionStorage.get(`complaint.${id}`);
+
+ const onSelect = (e) => {
+ setSelection([...selection, e.target.value]);
+ };
+
+ const onComments = (e) => {
+ setComment(e.target.value);
+ };
+
+ const feedback = (e, ref, index) => {
+ setRating(index);
+ };
+
+ const onSubmit = () => {
+ let complaintDetails = Digit.SessionStorage.get(`complaint.${id}`);
+ complaintDetails.service.rating = rating;
+ complaintDetails.service.additionalDetail = selection;
+ complaintDetails.workflow = {
+ action: "RATE",
+ comments: comment,
+ verificationDocuments: [],
+ };
+ updateComplaint(complaintDetails);
+ };
+
+ const updateComplaint = useCallback((complaintDetails) => dispatch(updateComplaints(complaintDetails)), [dispatch]);
+
+ let lables = ["_SERVICES", "_RESOLUTION_TIME", "_QUALITY_OF_WORK", "_OTHERS"];
+
+ return (
+
+
+
+ );
+};
+
+export default RatingAndFeedBack;
diff --git a/micro-ui/web/packages/pgr/src/pages/citizen/Rating/SelectRating.js b/micro-ui/web/packages/pgr/src/pages/citizen/Rating/SelectRating.js
new file mode 100644
index 00000000000..c24bce32f20
--- /dev/null
+++ b/micro-ui/web/packages/pgr/src/pages/citizen/Rating/SelectRating.js
@@ -0,0 +1,62 @@
+import React, { useCallback, useState } from "react";
+import { useDispatch } from "react-redux";
+import { RatingCard, CardLabelError } from "@egovernments/digit-ui-react-components";
+import { useParams, Redirect, useHistory } from "react-router-dom";
+import { useTranslation } from "react-i18next";
+import { updateComplaints } from "../../../redux/actions/index";
+
+const SelectRating = ({ parentRoute }) => {
+ const { t } = useTranslation();
+ const { id } = useParams();
+ const dispatch = useDispatch();
+ const history = useHistory();
+
+ let tenantId = Digit.SessionStorage.get("CITIZEN.COMMON.HOME.CITY")?.code || Digit.ULBService.getCurrentTenantId();
+ const complaintDetails = Digit.Hooks.pgr.useComplaintDetails({ tenantId: tenantId, id: id }).complaintDetails;
+ const updateComplaint = useCallback((complaintDetails) => dispatch(updateComplaints(complaintDetails)), [dispatch]);
+ const [submitError, setError] = useState(false)
+
+ function log(data) {
+ if (complaintDetails && data.rating > 0 ) {
+ complaintDetails.service.rating = data.rating;
+ complaintDetails.service.additionalDetail = data.CS_FEEDBACK_WHAT_WAS_GOOD.join(",");
+ complaintDetails.workflow = {
+ action: "RATE",
+ comments: data.comments,
+ verificationDocuments: [],
+ };
+ updateComplaint({ service: complaintDetails.service, workflow: complaintDetails.workflow });
+ history.push(`${parentRoute}/response`);
+ }
+ else{
+ setError(true)
+ }
+ }
+
+ const config = {
+ texts: {
+ header: "CS_COMPLAINT_RATE_HELP_TEXT",
+ submitBarLabel: "CS_COMMONS_NEXT",
+ },
+ inputs: [
+ {
+ type: "rate",
+ maxRating: 5,
+ label: t("CS_COMPLAINT_RATE_TEXT"),
+ error: submitError ? {t("CS_FEEDBACK_ENTER_RATING_ERROR")} : null
+ },
+ {
+ type: "checkbox",
+ label: "CS_FEEDBACK_WHAT_WAS_GOOD",
+ checkLabels: [t("CS_FEEDBACK_SERVICES"), t("CS_FEEDBACK_RESOLUTION_TIME"), t("CS_FEEDBACK_QUALITY_OF_WORK"), t("CS_FEEDBACK_OTHERS")],
+ },
+ {
+ type: "textarea",
+ label: t("CS_COMMON_COMMENTS"),
+ name: "comments",
+ },
+ ],
+ };
+ return ;
+};
+export default SelectRating;
diff --git a/micro-ui/web/packages/pgr/src/pages/citizen/ReopenComplaint/AddtionalDetails.js b/micro-ui/web/packages/pgr/src/pages/citizen/ReopenComplaint/AddtionalDetails.js
new file mode 100644
index 00000000000..7c9ae3f20ac
--- /dev/null
+++ b/micro-ui/web/packages/pgr/src/pages/citizen/ReopenComplaint/AddtionalDetails.js
@@ -0,0 +1,97 @@
+import React, { useCallback, useEffect } from "react";
+import { useTranslation } from "react-i18next";
+import { useDispatch, useSelector } from "react-redux";
+import { useParams, useHistory, Redirect } from "react-router-dom";
+
+import { BackButton, Card, CardHeader, CardText, TextArea, SubmitBar } from "@egovernments/digit-ui-react-components";
+
+import { updateComplaints } from "../../../redux/actions/index";
+import { LOCALIZATION_KEY } from "../../../constants/Localization";
+
+const AddtionalDetails = (props) => {
+ // const [details, setDetails] = useState(null);
+ const history = useHistory();
+ let { id } = useParams();
+ const dispatch = useDispatch();
+ const appState = useSelector((state) => state)["common"];
+ let { t } = useTranslation();
+
+ const {complaintDetails} = props
+ useEffect(() => {
+ if (appState.complaints) {
+ const { response } = appState.complaints;
+ if (response && response.responseInfo.status === "successful") {
+ history.push(`${props.match.path}/response/:${id}`);
+ }
+ }
+ }, [appState.complaints, props.history]);
+
+ const updateComplaint = useCallback(
+ async (complaintDetails) => {
+ await dispatch(updateComplaints(complaintDetails));
+ history.push(`${props.match.path}/response/${id}`);
+ },
+ [dispatch]
+ );
+
+ const getUpdatedWorkflow = (reopenDetails, type) => {
+ switch (type) {
+ case "REOPEN":
+ return {
+ action: "REOPEN",
+ comments: reopenDetails.addtionalDetail,
+ assignes: [],
+ verificationDocuments: reopenDetails.verificationDocuments,
+ };
+ default:
+ return "";
+ }
+ };
+
+ function reopenComplaint() {
+ let reopenDetails = Digit.SessionStorage.get(`reopen.${id}`);
+ if (complaintDetails) {
+ complaintDetails.workflow = getUpdatedWorkflow(
+ reopenDetails,
+ // complaintDetails,
+ "REOPEN"
+ );
+ complaintDetails.service.additionalDetail = {
+ REOPEN_REASON: reopenDetails.reason,
+ };
+ updateComplaint({ service: complaintDetails.service, workflow: complaintDetails.workflow });
+ }
+ return (
+
+ );
+ }
+
+ function textInput(e) {
+ // setDetails(e.target.value);
+ let reopenDetails = Digit.SessionStorage.get(`reopen.${id}`);
+ Digit.SessionStorage.set(`reopen.${id}`, {
+ ...reopenDetails,
+ addtionalDetail: e.target.value,
+ });
+ }
+
+ return (
+
+
+ {t(`${LOCALIZATION_KEY.CS_ADDCOMPLAINT}_PROVIDE_ADDITIONAL_DETAILS`)}
+ {t(`${LOCALIZATION_KEY.CS_ADDCOMPLAINT}_ADDITIONAL_DETAILS_TEXT`)}
+
+
+
+
+
+
+ );
+};
+
+export default AddtionalDetails;
diff --git a/micro-ui/web/packages/pgr/src/pages/citizen/ReopenComplaint/Reason.js b/micro-ui/web/packages/pgr/src/pages/citizen/ReopenComplaint/Reason.js
new file mode 100644
index 00000000000..a67b9b52c1c
--- /dev/null
+++ b/micro-ui/web/packages/pgr/src/pages/citizen/ReopenComplaint/Reason.js
@@ -0,0 +1,57 @@
+import React, { useState } from "react";
+import { useTranslation } from "react-i18next";
+import { Link, useHistory, useParams } from "react-router-dom";
+import { BackButton, Card, CardHeader, CardLabelError, CardText, RadioButtons, SubmitBar } from "@egovernments/digit-ui-react-components";
+
+import { LOCALIZATION_KEY } from "../../../constants/Localization";
+import { getRoute, PgrRoutes, PGR_BASE } from "../../../constants/Routes";
+
+const ReasonPage = (props) => {
+ const history = useHistory();
+ const { t } = useTranslation();
+ const { id } = useParams();
+ const [selected, setSelected] = useState(null);
+ const [valid, setValid] = useState(true);
+
+ const onRadioChange = (value) => {
+ let reopenDetails = Digit.SessionStorage.get(`reopen.${id}`);
+ Digit.SessionStorage.set(`reopen.${id}`, { ...reopenDetails, reason: value });
+ setSelected(value);
+ };
+
+ function onSave() {
+ if (selected === null) {
+ setValid(false);
+ } else {
+ history.push(`${props.match.path}/upload-photo/${id}`);
+ }
+ }
+
+ return (
+
+ {t(`${LOCALIZATION_KEY.CS_REOPEN}_COMPLAINT`)}
+
+ {/* Select the option related to your complaint from the list given below.
+ If the complaint type you are looking for is not listed select others.{" "} */}
+ {/* {t(`${TRANSLATION_KEY}_OPTION_ONE`)} */}
+
+ {valid ? null : {t(`${LOCALIZATION_KEY.CS_ADDCOMPLAINT}_ERROR_REOPEN_REASON`)}}
+ setSelected(value)}
+ options={[
+ t(`${LOCALIZATION_KEY.CS_REOPEN}_OPTION_ONE`),
+ t(`${LOCALIZATION_KEY.CS_REOPEN}_OPTION_TWO`),
+ t(`${LOCALIZATION_KEY.CS_REOPEN}_OPTION_THREE`),
+ t(`${LOCALIZATION_KEY.CS_REOPEN}_OPTION_FOUR`),
+ ]}
+ />
+
+
+
+ );
+};
+
+export default ReasonPage;
diff --git a/micro-ui/web/packages/pgr/src/pages/citizen/ReopenComplaint/UploadPhoto.js b/micro-ui/web/packages/pgr/src/pages/citizen/ReopenComplaint/UploadPhoto.js
new file mode 100644
index 00000000000..a50ae8af67f
--- /dev/null
+++ b/micro-ui/web/packages/pgr/src/pages/citizen/ReopenComplaint/UploadPhoto.js
@@ -0,0 +1,71 @@
+import React, { useEffect, useState } from "react";
+import { Link, useHistory, useParams } from "react-router-dom";
+import { useTranslation } from "react-i18next";
+
+import { Card, SubmitBar, BackButton, ImageUploadHandler, CardLabelError, LinkButton } from "@egovernments/digit-ui-react-components";
+
+import { LOCALIZATION_KEY } from "../../../constants/Localization";
+
+const UploadPhoto = (props) => {
+ const { t } = useTranslation();
+ const history = useHistory();
+ let { id } = useParams();
+ const [verificationDocuments, setVerificationDocuments] = useState(null);
+ const [valid, setValid] = useState(true);
+
+ const handleUpload = (ids) => {
+ setDocState(ids);
+ };
+
+ const setDocState = (ids) => {
+ if (ids?.length) {
+ const documents = ids.map((id) => ({
+ documentType: "PHOTO",
+ fileStoreId: id,
+ documentUid: "",
+ additionalDetails: {},
+ }));
+ setVerificationDocuments(documents);
+ }
+ };
+
+ function save() {
+ if (verificationDocuments === null) {
+ setValid(false);
+ } else {
+ history.push(`${props.match.path}/addional-details/${id}`);
+ }
+ }
+
+ function skip() {
+ history.push(`${props.match.path}/addional-details/${id}`);
+ }
+
+ useEffect(() => {
+ let reopenDetails = Digit.SessionStorage.get(`reopen.${id}`);
+ Digit.SessionStorage.set(`reopen.${id}`, { ...reopenDetails, verificationDocuments });
+ }, [verificationDocuments, id]);
+
+ return (
+
+
+
+ {/*
+
+ */}
+
+ {valid ? null : {t(`${LOCALIZATION_KEY.CS_ADDCOMPLAINT}_UPLOAD_ERROR_MESSAGE`)}}
+
+ {props.skip ? : null}
+
+
+ );
+};
+
+export default UploadPhoto;
diff --git a/micro-ui/web/packages/pgr/src/pages/citizen/ReopenComplaint/index.js b/micro-ui/web/packages/pgr/src/pages/citizen/ReopenComplaint/index.js
new file mode 100644
index 00000000000..ddd9dab9acd
--- /dev/null
+++ b/micro-ui/web/packages/pgr/src/pages/citizen/ReopenComplaint/index.js
@@ -0,0 +1,28 @@
+import React, { useMemo } from "react";
+
+import { Route, Switch, useRouteMatch } from "react-router-dom";
+// import UserOnboarding from "../UserOnboarding/index";
+import { PgrRoutes, getRoute } from "../../../constants/Routes";
+import ReasonPage from "./Reason";
+import UploadPhoto from "./UploadPhoto";
+import AddtionalDetails from "./AddtionalDetails";
+import Response from "../Response";
+
+const ReopenComplaint = ({ match, history, parentRoute }) => {
+
+ const allParams = window.location.pathname.split("/")
+ const id = allParams[allParams.length - 1]
+ const tenantId = Digit.SessionStorage.get("CITIZEN.COMMON.HOME.CITY")?.code || Digit.ULBService.getCurrentTenantId();
+
+ const complaintDetails = Digit.Hooks.pgr.useComplaintDetails({ tenantId: tenantId, id: id }).complaintDetails;
+ return (
+
+ } />
+ } />
+ } />
+ } />
+
+ );
+};
+
+export { ReopenComplaint };
diff --git a/micro-ui/web/packages/pgr/src/pages/citizen/Response.js b/micro-ui/web/packages/pgr/src/pages/citizen/Response.js
new file mode 100644
index 00000000000..28b77b73e40
--- /dev/null
+++ b/micro-ui/web/packages/pgr/src/pages/citizen/Response.js
@@ -0,0 +1,59 @@
+import React from "react";
+import { Card, Banner, CardText, SubmitBar } from "@egovernments/digit-ui-react-components";
+import { Link } from "react-router-dom";
+import { useSelector } from "react-redux";
+import { PgrRoutes, getRoute } from "../../constants/Routes";
+import { useTranslation } from "react-i18next";
+
+const GetActionMessage = ({ action }) => {
+ const { t } = useTranslation();
+ switch (action) {
+ case "REOPEN":
+ return t(`CS_COMMON_COMPLAINT_REOPENED`);
+ case "RATE":
+ return t("CS_COMMON_THANK_YOU");
+ default:
+ return t(`CS_COMMON_COMPLAINT_SUBMITTED`);
+ }
+};
+
+const BannerPicker = ({ response }) => {
+ const { complaints } = response;
+ const { t } = useTranslation();
+ if (complaints && complaints.response && complaints.response.responseInfo) {
+ return (
+
+ );
+ } else {
+ return ;
+ }
+};
+
+const TextPicker = ({ response }) => {
+ const { complaints } = response;
+ const { t } = useTranslation();
+ if (complaints && complaints.response && complaints.response.responseInfo) {
+ const { action } = complaints.response.ServiceWrappers[0].workflow;
+ return action === "RATE" ? {t("CS_COMMON_RATING_SUBMIT_TEXT")} : {t("CS_COMMON_TRACK_COMPLAINT_TEXT")};
+ }
+};
+
+const Response = (props) => {
+ const { t } = useTranslation();
+ const appState = useSelector((state) => state)["pgr"];
+ return (
+
+ {appState.complaints.response && }
+ {appState.complaints.response && }
+
+
+
+
+ );
+};
+
+export default Response;
diff --git a/micro-ui/web/packages/pgr/src/pages/citizen/index.js b/micro-ui/web/packages/pgr/src/pages/citizen/index.js
new file mode 100644
index 00000000000..9319f81beb7
--- /dev/null
+++ b/micro-ui/web/packages/pgr/src/pages/citizen/index.js
@@ -0,0 +1,48 @@
+import React from "react";
+import { ReopenComplaint } from "./ReopenComplaint/index";
+import SelectRating from "./Rating/SelectRating";
+import { PgrRoutes, getRoute } from "../../constants/Routes";
+import { useRouteMatch, Switch, useLocation } from "react-router-dom";
+import { AppContainer, BackButton, PrivateRoute } from "@egovernments/digit-ui-react-components";
+
+import { CreateComplaint } from "./Create";
+import { ComplaintsList } from "./ComplaintsList";
+import ComplaintDetailsPage from "./ComplaintDetails";
+import Response from "./Response";
+import { useTranslation } from "react-i18next";
+
+const App = () => {
+ const { t } = useTranslation();
+ const { path, url, ...match } = useRouteMatch();
+ const location = useLocation();
+
+ const CreateComplaint = Digit?.ComponentRegistryService?.getComponent("PGRCreateComplaintCitizen");
+ const ComplaintsList = Digit?.ComponentRegistryService?.getComponent("PGRComplaintsList");
+ const ComplaintDetailsPage = Digit?.ComponentRegistryService?.getComponent("PGRComplaintDetailsPage");
+ const SelectRating = Digit?.ComponentRegistryService?.getComponent("PGRSelectRating");
+ const Response = Digit?.ComponentRegistryService?.getComponent("PGRResponseCitzen");
+
+ return (
+
+
+ {!location.pathname.includes("/response") &&
{t("CS_COMMON_BACK")}}
+
+ {/* */}
+
+
+
+ }
+ />
+ } />
+ } />
+
+ {/* */}
+
+
+
+ );
+};
+
+export default App;
diff --git a/micro-ui/web/packages/pgr/src/pages/employee/ComplaintDetails.js b/micro-ui/web/packages/pgr/src/pages/employee/ComplaintDetails.js
new file mode 100644
index 00000000000..b76bdeed77f
--- /dev/null
+++ b/micro-ui/web/packages/pgr/src/pages/employee/ComplaintDetails.js
@@ -0,0 +1,505 @@
+import React, { useState, useEffect, Fragment } from "react";
+import { useParams } from "react-router-dom";
+import {
+ BreakLine,
+ Card,
+ CardLabel,
+ CardLabelDesc,
+ CardSubHeader,
+ ConnectingCheckPoints,
+ CheckPoint,
+ DisplayPhotos,
+ MediaRow,
+ LastRow,
+ Row,
+ StatusTable,
+ PopUp,
+ HeaderBar,
+ ImageViewer,
+ TextInput,
+ TextArea,
+ UploadFile,
+ ButtonSelector,
+ Toast,
+ ActionBar,
+ Menu,
+ SubmitBar,
+ Dropdown,
+ Loader,
+ Modal,
+ SectionalDropdown,
+} from "@egovernments/digit-ui-react-components";
+
+import { Close } from "../../Icons";
+import { useTranslation } from "react-i18next";
+import { isError, useQueryClient } from "react-query";
+import StarRated from "../../components/timelineInstances/StarRated";
+
+const MapView = (props) => {
+ return (
+
+
![](https://via.placeholder.com/640x280)
+
+ );
+};
+
+const Heading = (props) => {
+ return {props.label}
;
+};
+
+const CloseBtn = (props) => {
+ return (
+
+
+
+ );
+};
+
+const TLCaption = ({ data, comments }) => {
+ const { t } = useTranslation()
+ return (
+
+ {data?.date &&
{data?.date}
}
+
{data?.name}
+
{data?.mobileNumber}
+ {data?.source &&
{t("ES_COMMON_FILED_VIA_" + data?.source.toUpperCase())}
}
+ {comments?.map( e =>
+
+
{t("WF_COMMON_COMMENTS")}
+
{e}
+
+ )}
+
+ );
+};
+
+const ComplaintDetailsModal = ({ workflowDetails, complaintDetails, close, popup, selectedAction, onAssign, tenantId, t }) => {
+
+ // RAIN-5692 PGR : GRO is assigning complaint, Selecting employee and assign. Its not getting assigned.
+ // Fix for next action assignee dropdown issue
+ const stateArray = workflowDetails?.data?.initialActionState?.nextActions?.filter( ele => ele?.action == selectedAction );
+ const useEmployeeData = Digit.Hooks.pgr.useEmployeeFilter(
+ tenantId,
+ stateArray?.[0]?.assigneeRoles?.length > 0 ? stateArray?.[0]?.assigneeRoles?.join(",") : "",
+ complaintDetails
+ );
+ const employeeData = useEmployeeData
+ ? useEmployeeData.map((departmentData) => {
+ return { heading: departmentData.department, options: departmentData.employees };
+ })
+ : null;
+
+ const [selectedEmployee, setSelectedEmployee] = useState(null);
+ const [comments, setComments] = useState("");
+ const [file, setFile] = useState(null);
+ const [uploadedFile, setUploadedFile] = useState(null);
+ const [error, setError] = useState(null);
+ const cityDetails = Digit.ULBService.getCurrentUlb();
+ const [selectedReopenReason, setSelectedReopenReason] = useState(null);
+
+ useEffect(() => {
+ (async () => {
+ setError(null);
+ if (file) {
+ if (file.size >= 5242880) {
+ setError(t("CS_MAXIMUM_UPLOAD_SIZE_EXCEEDED"));
+ } else {
+ try {
+ // TODO: change module in file storage
+ const response = await Digit.UploadServices.Filestorage("property-upload", file, cityDetails.code);
+ if (response?.data?.files?.length > 0) {
+ setUploadedFile(response?.data?.files[0]?.fileStoreId);
+ } else {
+ setError(t("CS_FILE_UPLOAD_ERROR"));
+ }
+ } catch (err) {
+ setError(t("CS_FILE_UPLOAD_ERROR"));
+ }
+ }
+ }
+ })();
+ }, [file]);
+
+ const reopenReasonMenu = [t(`CS_REOPEN_OPTION_ONE`), t(`CS_REOPEN_OPTION_TWO`), t(`CS_REOPEN_OPTION_THREE`), t(`CS_REOPEN_OPTION_FOUR`)];
+ // const uploadFile = useCallback( () => {
+
+ // }, [file]);
+
+ function onSelectEmployee(employee) {
+ setSelectedEmployee(employee);
+ }
+
+ function addComment(e) {
+ setError(null);
+ setComments(e.target.value);
+ }
+
+ function selectfile(e) {
+ setFile(e.target.files[0]);
+ }
+
+ function onSelectReopenReason(reason) {
+ setSelectedReopenReason(reason);
+ }
+
+ return (
+
+ }
+ headerBarEnd={ close(popup)} />}
+ actionCancelLabel={t("CS_COMMON_CANCEL")}
+ actionCancelOnSubmit={() => close(popup)}
+ actionSaveLabel={
+ selectedAction === "ASSIGN" || selectedAction === "REASSIGN"
+ ? t("CS_COMMON_ASSIGN")
+ : selectedAction === "REJECT"
+ ? t("CS_COMMON_REJECT")
+ : selectedAction === "REOPEN"
+ ? t("CS_COMMON_REOPEN")
+ : t("CS_COMMON_RESOLVE")
+ }
+ actionSaveOnSubmit={() => {
+ if(selectedAction === "REJECT" && !comments)
+ setError(t("CS_MANDATORY_COMMENTS"));
+ else
+ onAssign(selectedEmployee, comments, uploadedFile);
+ }}
+ error={error}
+ setError={setError}
+ >
+
+ {selectedAction === "REJECT" || selectedAction === "RESOLVE" || selectedAction === "REOPEN" ? null : (
+
+ {t("CS_COMMON_EMPLOYEE_NAME")}
+ {employeeData && }
+
+ )}
+ {selectedAction === "REOPEN" ? (
+
+ {t("CS_REOPEN_COMPLAINT")}
+
+
+ ) : null}
+ {t("CS_COMMON_EMPLOYEE_COMMENTS")}
+
+ {t("CS_ACTION_SUPPORTING_DOCUMENTS")}
+ {t(`CS_UPLOAD_RESTRICTIONS`)}
+ {
+ setUploadedFile(null);
+ }}
+ uploadedFiles={[]}
+ message={uploadedFile ? `1 ${t(`CS_ACTION_FILEUPLOADED`)}` : t(`CS_ACTION_NO_FILEUPLOADED`)}
+ />
+
+
+ );
+};
+
+export const ComplaintDetails = (props) => {
+ let { id } = useParams();
+ const { t } = useTranslation();
+ const [fullscreen, setFullscreen] = useState(false);
+ const [imageZoom, setImageZoom] = useState(null);
+ // const [actionCalled, setActionCalled] = useState(false);
+ const [toast, setToast] = useState(false);
+ const tenantId = Digit.ULBService.getCurrentTenantId();
+ const { isLoading, complaintDetails, revalidate: revalidateComplaintDetails } = Digit.Hooks.pgr.useComplaintDetails({ tenantId, id });
+ const workflowDetails = Digit.Hooks.useWorkflowDetails({ tenantId, id, moduleCode: "PGR", role: "EMPLOYEE" });
+ const [imagesToShowBelowComplaintDetails, setImagesToShowBelowComplaintDetails] = useState([])
+
+ // RAIN-5692 PGR : GRO is assigning complaint, Selecting employee and assign. Its not getting assigned.
+ // Fix for next action assignee dropdown issue
+ if (workflowDetails && workflowDetails?.data){
+ workflowDetails.data.initialActionState=workflowDetails?.data?.initialActionState || {...workflowDetails?.data?.actionState } || {} ;
+ workflowDetails.data.actionState = { ...workflowDetails.data };
+ }
+
+ useEffect(()=>{
+ if(workflowDetails){
+ const {data:{timeline: complaintTimelineData}={}} = workflowDetails
+ if(complaintTimelineData){
+ const actionByCitizenOnComplaintCreation = complaintTimelineData?.find( e => e?.performedAction === "APPLY")
+ const { thumbnailsToShow } = actionByCitizenOnComplaintCreation
+ thumbnailsToShow ? setImagesToShowBelowComplaintDetails(thumbnailsToShow) : null
+ }
+ }
+ },[workflowDetails])
+ const [displayMenu, setDisplayMenu] = useState(false);
+ const [popup, setPopup] = useState(false);
+ const [selectedAction, setSelectedAction] = useState(null);
+ const [assignResponse, setAssignResponse] = useState(null);
+ const [loader, setLoader] = useState(false);
+ const [rerender, setRerender] = useState(1);
+ const client = useQueryClient();
+ function popupCall(option) {
+ setDisplayMenu(false);
+ setPopup(true);
+ }
+
+ useEffect(() => {
+ (async () => {
+ const assignWorkflow = await Digit?.WorkflowService?.getByBusinessId(tenantId, id);
+ })();
+ }, [complaintDetails]);
+
+ const refreshData = async () => {
+ await client.refetchQueries(["fetchInboxData"]);
+ await workflowDetails.revalidate();
+ await revalidateComplaintDetails();
+ };
+
+ useEffect(() => {
+ (async () => {
+ if (complaintDetails) {
+ setLoader(true);
+ await refreshData();
+ setLoader(false);
+ }
+ })();
+ }, []);
+
+ function zoomView() {
+ setFullscreen(!fullscreen);
+ }
+
+ function close(state) {
+ switch (state) {
+ case fullscreen:
+ setFullscreen(!fullscreen);
+ break;
+ case popup:
+ setPopup(!popup);
+ break;
+ default:
+ break;
+ }
+ }
+
+ function zoomImage(imageSource, index) {
+ setImageZoom(imageSource);
+ }
+ function zoomImageWrapper(imageSource, index){
+ zoomImage(imagesToShowBelowComplaintDetails?.fullImage[index]);
+ }
+ function onCloseImageZoom() {
+ setImageZoom(null);
+ }
+
+ function onActionSelect(action) {
+ setSelectedAction(action);
+ switch (action) {
+ case "ASSIGN":
+ setPopup(true);
+ setDisplayMenu(false);
+ break;
+ case "REASSIGN":
+ setPopup(true);
+ setDisplayMenu(false);
+ break;
+ case "RESOLVE":
+ setPopup(true);
+ setDisplayMenu(false);
+ break;
+ case "REJECT":
+ setPopup(true);
+ setDisplayMenu(false);
+ break;
+ case "REOPEN":
+ setPopup(true);
+ setDisplayMenu(false);
+ break;
+ default:
+ setDisplayMenu(false);
+ }
+ }
+
+ async function onAssign(selectedEmployee, comments, uploadedFile) {
+ setPopup(false);
+ const response = await Digit.Complaint.assign(complaintDetails, selectedAction, selectedEmployee, comments, uploadedFile, tenantId);
+ setAssignResponse(response);
+ setToast(true);
+ setLoader(true);
+ await refreshData();
+ setLoader(false);
+ setRerender(rerender + 1);
+ setTimeout(() => setToast(false), 10000);
+ }
+
+ function closeToast() {
+ setToast(false);
+ }
+
+ if (isLoading || workflowDetails.isLoading || loader) {
+ return ;
+ }
+
+ if (workflowDetails.isError) return {workflowDetails.error};
+
+ const getTimelineCaptions = (checkpoint, index, arr) => {
+ const {wfComment: comment, thumbnailsToShow} = checkpoint;
+ function zoomImageTimeLineWrapper(imageSource, index,thumbnailsToShow){
+ let newIndex=thumbnailsToShow.thumbs?.findIndex(link=>link===imageSource);
+ zoomImage((newIndex>-1&&thumbnailsToShow?.fullImage?.[newIndex])||imageSource);
+ }
+ const captionForOtherCheckpointsInTL = {
+ date: checkpoint?.auditDetails?.lastModified,
+ name: checkpoint?.assigner?.name,
+ mobileNumber: checkpoint?.assigner?.mobileNumber,
+ ...checkpoint.status === "COMPLAINT_FILED" && complaintDetails?.audit ? {
+ source: complaintDetails.audit.source,
+ } : {}
+ }
+ const isFirstPendingForAssignment = arr.length - (index + 1) === 1 ? true : false
+ if (checkpoint.status === "PENDINGFORASSIGNMENT" && complaintDetails?.audit) {
+ if(isFirstPendingForAssignment){
+ const caption = {
+ date: Digit.DateUtils.ConvertTimestampToDate(complaintDetails.audit.details.createdTime),
+ };
+ return ;
+ } else {
+ const caption = {
+ date: Digit.DateUtils.ConvertTimestampToDate(complaintDetails.audit.details.createdTime),
+ };
+ return <>
+ {checkpoint?.wfComment ? {checkpoint?.wfComment?.map( e =>
+
+
{t("WF_COMMON_COMMENTS")}
+
{e}
+
+ )}
: null}
+ {checkpoint.status !== "COMPLAINT_FILED" && thumbnailsToShow?.thumbs?.length > 0 ?
+
{t("CS_COMMON_ATTACHMENTS")}
+ zoomImageTimeLineWrapper(src, index,thumbnailsToShow)} />
+ : null}
+ {caption?.date ? : null}
+ >
+ }
+ }
+ // return (checkpoint.caption && checkpoint.caption.length !== 0) || checkpoint?.wfComment?.length > 0 ? : null;
+ return <>
+ {comment ? {comment?.map( e =>
+
+
{t("WF_COMMON_COMMENTS")}
+
{e}
+
+ )}
: null}
+ {checkpoint.status !== "COMPLAINT_FILED" && thumbnailsToShow?.thumbs?.length > 0 ?
+
{t("CS_COMMON_ATTACHMENTS")}
+ zoomImageTimeLineWrapper(src, index,thumbnailsToShow)} />
+ : null}
+ {captionForOtherCheckpointsInTL?.date ? : null}
+ {(checkpoint.status == "CLOSEDAFTERRESOLUTION" && complaintDetails.workflow.action == "RATE" && index <= 1) && complaintDetails.audit.rating ? : null}
+ >
+ }
+
+ return (
+
+
+ {t(`CS_HEADER_COMPLAINT_SUMMARY`)}
+ {t(`CS_COMPLAINT_DETAILS_COMPLAINT_DETAILS`)}
+ {isLoading ? (
+
+ ) : (
+
+ {complaintDetails &&
+ Object.keys(complaintDetails?.details).map((k, i, arr) => (
+ (typeof val === "object" ? t(val?.code) : t(val)))
+ : t(complaintDetails?.details[k]) || "N/A"
+ }
+ last={arr.length - 1 === i}
+ />
+ ))}
+
+ {1 === 1 ? null : (
+
+
+
+ )}
+
+ )}
+ {imagesToShowBelowComplaintDetails?.thumbs ? (
+ zoomImageWrapper(source, index)} />
+ ) : null}
+
+ {workflowDetails?.isLoading && }
+ {!workflowDetails?.isLoading && (
+
+ {t(`CS_COMPLAINT_DETAILS_COMPLAINT_TIMELINE`)}
+
+ {workflowDetails?.data?.timeline && workflowDetails?.data?.timeline?.length === 1 ? (
+
+ ) : (
+
+ {workflowDetails?.data?.timeline &&
+ workflowDetails?.data?.timeline.map((checkpoint, index, arr) => {
+ return (
+
+
+
+ );
+ })}
+
+ )}
+
+ )}
+
+ {fullscreen ? (
+
+
+
} end={
close(fullscreen)} />} />
+
+
![](https://via.placeholder.com/912x568)
+
+
+
+ ) : null}
+ {imageZoom ? : null}
+ {popup ? (
+
+ ) : null}
+ {toast && }
+ {!workflowDetails?.isLoading && workflowDetails?.data?.nextActions?.length > 0 && (
+
+ {displayMenu && workflowDetails?.data?.nextActions ? (
+
+ )}
+
+ );
+};
diff --git a/micro-ui/web/packages/pgr/src/pages/employee/CreateComplaint/index.js b/micro-ui/web/packages/pgr/src/pages/employee/CreateComplaint/index.js
new file mode 100644
index 00000000000..889a2d6694a
--- /dev/null
+++ b/micro-ui/web/packages/pgr/src/pages/employee/CreateComplaint/index.js
@@ -0,0 +1,261 @@
+import React, { useState, useEffect, useMemo } from "react";
+import { useTranslation } from "react-i18next";
+import { useDispatch } from "react-redux";
+import { Dropdown } from "@egovernments/digit-ui-react-components";
+import { useRouteMatch, useHistory } from "react-router-dom";
+import { useQueryClient } from "react-query";
+
+import { FormComposer } from "../../../components/FormComposer";
+import { createComplaint } from "../../../redux/actions/index";
+
+export const CreateComplaint = ({ parentUrl }) => {
+ const cities = Digit.Hooks.pgr.useTenants();
+ const { t } = useTranslation();
+
+ const getCities = () => cities?.filter((e) => e.code === Digit.ULBService.getCurrentTenantId()) || [];
+
+ const [complaintType, setComplaintType] = useState({});
+ const [subTypeMenu, setSubTypeMenu] = useState([]);
+ const [subType, setSubType] = useState({});
+ const [pincode, setPincode] = useState("");
+ const [selectedCity, setSelectedCity] = useState(getCities()[0] ? getCities()[0] : null);
+
+ const { data: fetchedLocalities } = Digit.Hooks.useBoundaryLocalities(
+ getCities()[0]?.code,
+ "admin",
+ {
+ enabled: !!getCities()[0],
+ },
+ t
+ );
+
+ const [localities, setLocalities] = useState(fetchedLocalities);
+ const [selectedLocality, setSelectedLocality] = useState(null);
+ const [canSubmit, setSubmitValve] = useState(false);
+ const [submitted, setSubmitted] = useState(false);
+
+ const [pincodeNotValid, setPincodeNotValid] = useState(false);
+ const [params, setParams] = useState({});
+ const tenantId = window.Digit.SessionStorage.get("Employee.tenantId");
+ const menu = Digit.Hooks.pgr.useComplaintTypes({ stateCode: tenantId });
+ const dispatch = useDispatch();
+ const match = useRouteMatch();
+ const history = useHistory();
+ const serviceDefinitions = Digit.GetServiceDefinitions;
+ const client = useQueryClient();
+
+ useEffect(() => {
+ if (complaintType?.key && subType?.key && selectedCity?.code && selectedLocality?.code) {
+ setSubmitValve(true);
+ } else {
+ setSubmitValve(false);
+ }
+ }, [complaintType, subType, selectedCity, selectedLocality]);
+
+ useEffect(() => {
+ setLocalities(fetchedLocalities);
+ }, [fetchedLocalities]);
+
+ useEffect(() => {
+ const city = cities.find((obj) => obj.pincode?.find((item) => item == pincode));
+ if (city?.code === getCities()[0]?.code) {
+ setPincodeNotValid(false);
+ setSelectedCity(city);
+ setSelectedLocality(null);
+ const __localityList = fetchedLocalities;
+ const __filteredLocalities = __localityList.filter((city) => city["pincode"] == pincode);
+ setLocalities(__filteredLocalities);
+ } else if (pincode === "" || pincode === null) {
+ setPincodeNotValid(false);
+ setLocalities(fetchedLocalities);
+ } else {
+ setPincodeNotValid(true);
+ }
+ }, [pincode]);
+
+ async function selectedType(value) {
+ if (value.key !== complaintType.key) {
+ if (value.key === "Others") {
+ setSubType({ name: "" });
+ setComplaintType(value);
+ setSubTypeMenu([{ key: "Others", name: t("SERVICEDEFS.OTHERS") }]);
+ } else {
+ setSubType({ name: "" });
+ setComplaintType(value);
+ setSubTypeMenu(await serviceDefinitions.getSubMenu(tenantId, value, t));
+ }
+ }
+ }
+
+ function selectedSubType(value) {
+ setSubType(value);
+ }
+
+ // city locality logic
+ const selectCity = async (city) => {
+ // if (selectedCity?.code !== city.code) {}
+ return;
+ };
+
+ function selectLocality(locality) {
+ setSelectedLocality(locality);
+ }
+
+ const wrapperSubmit = (data) => {
+ if (!canSubmit) return;
+ setSubmitted(true);
+ !submitted && onSubmit(data);
+ };
+
+ //On SUbmit
+ const onSubmit = async (data) => {
+ if (!canSubmit) return;
+ const cityCode = selectedCity.code;
+ const city = selectedCity.city.name;
+ const district = selectedCity.city.name;
+ const region = selectedCity.city.name;
+ const localityCode = selectedLocality.code;
+ const localityName = selectedLocality.name;
+ const landmark = data.landmark;
+ const { key } = subType;
+ const complaintType = key;
+ const mobileNumber = data.mobileNumber;
+ const name = data.name;
+ const formData = { ...data, cityCode, city, district, region, localityCode, localityName, landmark, complaintType, mobileNumber, name };
+ await dispatch(createComplaint(formData));
+ await client.refetchQueries(["fetchInboxData"]);
+ history.push(parentUrl + "/response");
+ };
+
+ const handlePincode = (event) => {
+ const { value } = event.target;
+ setPincode(value);
+ if (!value) {
+ setPincodeNotValid(false);
+ }
+ };
+
+ const isPincodeValid = () => !pincodeNotValid;
+
+ const config = [
+ {
+ head: t("ES_CREATECOMPLAINT_PROVIDE_COMPLAINANT_DETAILS"),
+ body: [
+ {
+ label: t("ES_CREATECOMPLAINT_MOBILE_NUMBER"),
+ isMandatory: true,
+ type: "text",
+ populators: {
+ name: "mobileNumber",
+ validation: {
+ required: true,
+ pattern: /^[6-9]\d{9}$/,
+ },
+ componentInFront: +91
,
+ error: t("CORE_COMMON_MOBILE_ERROR"),
+ },
+ },
+ {
+ label: t("ES_CREATECOMPLAINT_COMPLAINT_NAME"),
+ isMandatory: true,
+ type: "text",
+ populators: {
+ name: "name",
+ validation: {
+ required: true,
+ pattern: /^[A-Za-z]/,
+ },
+ error: t("CS_ADDCOMPLAINT_NAME_ERROR"),
+ },
+ },
+ ],
+ },
+ {
+ head: t("CS_COMPLAINT_DETAILS_COMPLAINT_DETAILS"),
+ body: [
+ {
+ label: t("CS_COMPLAINT_DETAILS_COMPLAINT_TYPE"),
+ isMandatory: true,
+ type: "dropdown",
+ populators: ,
+ },
+ {
+ label: t("CS_COMPLAINT_DETAILS_COMPLAINT_SUBTYPE"),
+ isMandatory: true,
+ type: "dropdown",
+ menu: { ...subTypeMenu },
+ populators: ,
+ },
+ ],
+ },
+ {
+ head: t("CS_ADDCOMPLAINT_LOCATION"),
+ body: [
+ {
+ label: t("CORE_COMMON_PINCODE"),
+ type: "text",
+ populators: {
+ name: "pincode",
+ validation: { pattern: /^[1-9][0-9]{5}$/, validate: isPincodeValid },
+ error: t("CORE_COMMON_PINCODE_INVALID"),
+ onChange: handlePincode,
+ },
+ },
+ {
+ label: t("CS_COMPLAINT_DETAILS_CITY"),
+ isMandatory: true,
+ type: "dropdown",
+ populators: (
+
+ ),
+ },
+ {
+ label: t("CS_CREATECOMPLAINT_MOHALLA"),
+ type: "dropdown",
+ isMandatory: true,
+ dependency: selectedCity && localities ? true : false,
+ populators: (
+
+ ),
+ },
+ {
+ label: t("CS_COMPLAINT_DETAILS_LANDMARK"),
+ type: "textarea",
+ populators: {
+ name: "landmark",
+ },
+ },
+ ],
+ },
+ {
+ head: t("CS_COMPLAINT_DETAILS_ADDITIONAL_DETAILS"),
+ body: [
+ {
+ label: t("CS_COMPLAINT_DETAILS_ADDITIONAL_DETAILS"),
+ type: "textarea",
+ populators: {
+ name: "description",
+ },
+ },
+ ],
+ },
+ ];
+ return (
+
+ );
+};
diff --git a/micro-ui/web/packages/pgr/src/pages/employee/Inbox.js b/micro-ui/web/packages/pgr/src/pages/employee/Inbox.js
new file mode 100644
index 00000000000..a9be8e207da
--- /dev/null
+++ b/micro-ui/web/packages/pgr/src/pages/employee/Inbox.js
@@ -0,0 +1,82 @@
+import React, { useCallback, useEffect, useState } from "react";
+import { useTranslation } from "react-i18next";
+import { Loader, Header } from "@egovernments/digit-ui-react-components";
+
+import DesktopInbox from "../../components/DesktopInbox";
+import MobileInbox from "../../components/MobileInbox";
+
+const Inbox = () => {
+ const { t } = useTranslation();
+ const tenantId = Digit.ULBService.getCurrentTenantId();
+ const { uuid } = Digit.UserService.getUser().info;
+ const [pageOffset, setPageOffset] = useState(0);
+ const [pageSize, setPageSize] = useState(10);
+ const [totalRecords, setTotalRecords] = useState(0);
+ const [searchParams, setSearchParams] = useState({ filters: { wfFilters: { assignee: [{ code: uuid }] } }, search: "", sort: {} });
+
+ useEffect(() => {
+ (async () => {
+ const applicationStatus = searchParams?.filters?.pgrfilters?.applicationStatus?.map(e => e.code).join(",")
+ let response = await Digit.PGRService.count(tenantId, applicationStatus?.length > 0 ? {applicationStatus} : {} );
+ if (response?.count) {
+ setTotalRecords(response.count);
+ }
+ })();
+ }, [searchParams]);
+
+ const fetchNextPage = () => {
+ setPageOffset((prevState) => prevState + 10);
+ };
+
+ const fetchPrevPage = () => {
+ setPageOffset((prevState) => prevState - 10);
+ };
+
+ const handlePageSizeChange = (e) => {
+ setPageSize(Number(e.target.value));
+ };
+
+ const handleFilterChange = (filterParam) => {
+ setSearchParams({ ...searchParams, filters: filterParam });
+ };
+
+ const onSearch = (params = "") => {
+ setSearchParams({ ...searchParams, search: params });
+ };
+
+ // let complaints = Digit.Hooks.pgr.useInboxData(searchParams) || [];
+ let { data: complaints, isLoading } = Digit.Hooks.pgr.useInboxData({ ...searchParams, offset: pageOffset, limit: pageSize }) ;
+
+ let isMobile = Digit.Utils.browser.isMobile();
+
+ if (complaints?.length !== null) {
+ if (isMobile) {
+ return (
+
+ );
+ } else {
+ return (
+
+
+
+
+ );
+ }
+ } else {
+ return ;
+ }
+};
+
+export default Inbox;
diff --git a/micro-ui/web/packages/pgr/src/pages/employee/InboxV2.js b/micro-ui/web/packages/pgr/src/pages/employee/InboxV2.js
new file mode 100644
index 00000000000..bbd9fa55373
--- /dev/null
+++ b/micro-ui/web/packages/pgr/src/pages/employee/InboxV2.js
@@ -0,0 +1,84 @@
+import React, { useCallback, useEffect, useState } from "react";
+import { useTranslation } from "react-i18next";
+import { Loader, Header, InboxSearchComposer } from "@egovernments/digit-ui-react-components";
+
+import DesktopInbox from "../../components/DesktopInbox";
+import MobileInbox from "../../components/MobileInbox";
+import { configs } from "./config";
+
+const InboxV2 = () => {
+ const { t } = useTranslation();
+ const tenantId = Digit.ULBService.getCurrentTenantId();
+ const { uuid } = Digit.UserService.getUser().info;
+ const [pageOffset, setPageOffset] = useState(0);
+ const [pageSize, setPageSize] = useState(10);
+ const [config, setConfig] = useState(configs);
+ const [totalRecords, setTotalRecords] = useState(0);
+ const [searchParams, setSearchParams] = useState({ filters: { wfFilters: { assignee: [{ code: uuid }] } }, search: "", sort: {} });
+
+ useEffect(() => {
+ (async () => {
+ const applicationStatus = searchParams?.filters?.pgrfilters?.applicationStatus?.map((e) => e.code).join(",");
+ let response = await Digit.PGRService.count(tenantId, applicationStatus?.length > 0 ? { applicationStatus } : {});
+ if (response?.count) {
+ setTotalRecords(response.count);
+ }
+ })();
+ }, [searchParams]);
+
+ const fetchNextPage = () => {
+ setPageOffset((prevState) => prevState + 10);
+ };
+
+ const fetchPrevPage = () => {
+ setPageOffset((prevState) => prevState - 10);
+ };
+
+ const handlePageSizeChange = (e) => {
+ setPageSize(Number(e.target.value));
+ };
+
+ const handleFilterChange = (filterParam) => {
+ setSearchParams({ ...searchParams, filters: filterParam });
+ };
+
+ const onSearch = (params = "") => {
+ setSearchParams({ ...searchParams, search: params });
+ };
+
+ // let complaints = Digit.Hooks.pgr.useInboxData(searchParams) || [];
+ // let { data: complaints, isLoading } = Digit.Hooks.pgr.useInboxData({ ...searchParams, offset: pageOffset, limit: pageSize });
+
+ let isMobile = Digit.Utils.browser.isMobile();
+
+ // if (complaints?.length !== null) {
+ // return (
+ //
+ //
+ //
+ //
+ // );
+ // }
+ return (
+
+
+
+
+
+
+ );
+};
+
+export default InboxV2;
diff --git a/micro-ui/web/packages/pgr/src/pages/employee/Response.js b/micro-ui/web/packages/pgr/src/pages/employee/Response.js
new file mode 100644
index 00000000000..3ce17817589
--- /dev/null
+++ b/micro-ui/web/packages/pgr/src/pages/employee/Response.js
@@ -0,0 +1,48 @@
+import React from "react";
+import { Card, Banner, CardText, SubmitBar } from "@egovernments/digit-ui-react-components";
+import { Link, useRouteMatch } from "react-router-dom";
+import { useSelector } from "react-redux";
+import { PgrRoutes, getRoute } from "../../constants/Routes";
+import { useTranslation } from "react-i18next";
+
+const GetActionMessage = ({ action }) => {
+ const { t } = useTranslation();
+ if (action === "REOPEN") {
+ return t(`CS_COMMON_COMPLAINT_REOPENED`);
+ } else {
+ return t(`CS_COMMON_COMPLAINT_SUBMITTED`);
+ }
+};
+
+const BannerPicker = ({ response }) => {
+ const { complaints } = response;
+
+ if (complaints && complaints.response && complaints.response.responseInfo) {
+ return (
+
+ );
+ } else {
+ return ;
+ }
+};
+
+const Response = (props) => {
+ const { t } = useTranslation();
+ const { match } = useRouteMatch();
+ const appState = useSelector((state) => state)["pgr"];
+ return (
+
+ {appState.complaints.response && }
+ {t("ES_COMMON_TRACK_COMPLAINT_TEXT")}
+
+
+
+
+ );
+};
+
+export default Response;
diff --git a/micro-ui/web/packages/pgr/src/pages/employee/config.js b/micro-ui/web/packages/pgr/src/pages/employee/config.js
new file mode 100644
index 00000000000..97f92850166
--- /dev/null
+++ b/micro-ui/web/packages/pgr/src/pages/employee/config.js
@@ -0,0 +1,219 @@
+export const configs = {
+ label: "ACTION_TEST_ESTIMATE_INBOX_V2",
+ type: "inbox",
+ apiDetails: {
+ serviceName: "/inbox/v2/_search",
+ requestParam: {},
+ requestBody: {
+ inbox: {
+ processSearchCriteria: {
+ businessService: ["PGR"],
+ moduleName: "RAINMAKER-PGR",
+ },
+
+ moduleSearchCriteria: {
+ sortOrder: "ASC",
+ },
+ },
+ },
+ minParametersForSearchForm: 0,
+ minParametersForFilterForm: 0,
+ masterName: "commonUiConfig",
+ moduleName: "EstimateInboxConfig",
+ tableFormJsonPath: "requestBody.inbox",
+ filterFormJsonPath: "requestBody.inbox.moduleSearchCriteria",
+ searchFormJsonPath: "requestBody.inbox.moduleSearchCriteria",
+ },
+ sections: {
+ search: {
+ uiConfig: {
+ headerStyle: null,
+ primaryLabel: "Search",
+ secondaryLabel: "Clear Search",
+ minReqFields: 1,
+ defaultValues: {
+ complaintNumber: "",
+ mobileNumber: "",
+ },
+ fields: [
+ {
+ label: "CS_COMMON_COMPLAINT_NO",
+ type: "text",
+ isMandatory: false,
+ disable: false,
+ preProcess: {
+ convertStringToRegEx: ["populators.validation.pattern"],
+ },
+ populators: {
+ name: "complaintNumber",
+ error: "ESTIMATE_PATTERN_ERR_MSG",
+ validation: {
+ minlength: 2,
+ },
+ },
+ },
+ {
+ label: "CS_COMMON_MOBILE_NO",
+ type: "text",
+ isMandatory: false,
+ disable: false,
+ preProcess: {
+ convertStringToRegEx: ["populators.validation.pattern"],
+ },
+ populators: {
+ name: "mobileNumber",
+ error: "PROJECT_PATTERN_ERR_MSG",
+ validation: {
+ pattern: "PJ\\/[0-9]+-[0-9]+\\/[0-9]+\\/[0-9]+",
+ minlength: 2,
+ },
+ },
+ },
+ ],
+ },
+ label: "",
+ children: {},
+ show: true,
+ },
+ searchResult: {
+ label: "",
+ estimateNumber: "",
+ projectId: "",
+ department: "",
+ estimateStatus: "",
+ fromProposalDate: "",
+ toProposalDate: "",
+ uiConfig: {
+ columns: [
+ {
+ label: "CS_COMMON_COMPLAINT_NO",
+ jsonPath: "businessObject.service.serviceRequestId",
+ key: "complaintNumber",
+ additionalCustomization: true,
+ },
+ {
+ label: "WF_INBOX_HEADER_LOCALITY",
+ jsonPath: "businessObject.service.address.locality.code",
+ additionalCustomization: false,
+ },
+ {
+ label: "CS_COMPLAINT_DETAILS_CURRENT_STATUS",
+ jsonPath: "businessObject.service.applicationStatus",
+ },
+ {
+ label: "WF_INBOX_HEADER_CURRENT_OWNER",
+ jsonPath: "ProcessInstance.assignes",
+ additionalCustomization: true,
+ key: "assignee",
+ },
+ {
+ label: "WF_INBOX_HEADER_SLA_DAYS_REMAINING",
+ jsonPath: "businessObject.service.auditDetails.createdTime",
+ additionalCustomization: false,
+ key: "state",
+ },
+ ],
+ enableGlobalSearch: false,
+ enableColumnSort: true,
+ resultsJsonPath: "items",
+ },
+ children: {},
+ show: true,
+ },
+ links: {
+ uiConfig: {
+ links: [
+ {
+ text: "ES_PGR_NEW_COMPLAINT",
+ url: "/employee/pgr/complaint/create",
+ roles: ["SYSTEM_ADMINISTRATOR"],
+ },
+ ],
+ label: "PGR",
+ logoIcon: {
+ component: "PropertyHouse",
+ customClass: "inbox-search-icon--projects",
+ },
+ },
+ children: {},
+ show: true,
+ },
+ filter: {
+ uiConfig: {
+ type: "filter",
+ headerStyle: null,
+ primaryLabel: "Filter",
+ secondaryLabel: "",
+ minReqFields: 0,
+ defaultValues: {
+ state: "",
+ locality: [],
+ assignee: {
+ code: "ASSIGNED_TO_ME",
+ name: "ASSIGNED_TO_ME",
+ },
+ },
+ fields: [
+ {
+ label: "",
+ type: "radio",
+ isMandatory: false,
+ disable: false,
+ populators: {
+ name: "assignee",
+ options: [
+ {
+ code: "ASSIGNED_TO_ME",
+ name: "ASSIGNED_TO_ME",
+ },
+ {
+ code: "ASSIGNED_TO_ALL",
+ name: "ASSIGNED_TO_ALL",
+ },
+ ],
+ optionsKey: "name",
+ styles: {
+ gap: "1rem",
+ flexDirection: "column",
+ },
+ innerStyles: {
+ display: "flex",
+ },
+ },
+ },
+ {
+ label: "COMMON_ORG_NAME",
+ type: "apidropdown",
+ isMandatory: false,
+ disable: false,
+ populators: {
+ name: "locality",
+ optionsKey: "name",
+ allowMultiSelect: false,
+ masterName: "commonUiConfig",
+ moduleName: "EstimateInboxConfig",
+ customfn: "populateReqCriteria",
+ },
+ },
+ {
+ label: "COMMON_ORG_NAME",
+ type: "apidropdown",
+ isMandatory: false,
+ disable: false,
+ populators: {
+ name: "status",
+ optionsKey: "applicationStatus",
+ allowMultiSelect: true,
+ masterName: "commonUiConfig",
+ moduleName: "EstimateInboxConfig",
+ customfn: "populateStatusList",
+ },
+ },
+ ],
+ },
+ label: "Filter",
+ show: true,
+ },
+ },
+ additionalSections: {},
+};
diff --git a/micro-ui/web/packages/pgr/src/pages/employee/index.js b/micro-ui/web/packages/pgr/src/pages/employee/index.js
new file mode 100644
index 00000000000..908eb427782
--- /dev/null
+++ b/micro-ui/web/packages/pgr/src/pages/employee/index.js
@@ -0,0 +1,83 @@
+import React, { useState } from "react";
+import { Switch, Route, useRouteMatch, useLocation } from "react-router-dom";
+import { ActionBar, Menu, SubmitBar, BreadCrumb } from "@egovernments/digit-ui-react-components";
+import { useTranslation } from "react-i18next";
+
+// import { ComplaintDetails } from "./ComplaintDetails";
+// import { CreateComplaint } from "./CreateComplaint";
+// import Inbox from "./Inbox";
+import { Employee } from "../../constants/Routes";
+// import Response from "./Response";
+
+const Complaint = () => {
+ const [displayMenu, setDisplayMenu] = useState(false);
+ const [popup, setPopup] = useState(false);
+ const match = useRouteMatch();
+ const { t } = useTranslation();
+
+ const breadcrumConfig = {
+ home: {
+ content: t("CS_COMMON_HOME"),
+ path: Employee.Home,
+ },
+ inbox: {
+ content: t("CS_COMMON_INBOX"),
+ path: match.url + Employee.Inbox,
+ },
+ createComplaint: {
+ content: t("CS_PGR_CREATE_COMPLAINT"),
+ path: match.url + Employee.CreateComplaint,
+ },
+ complaintDetails: {
+ content: t("CS_PGR_COMPLAINT_DETAILS"),
+ path: match.url + Employee.ComplaintDetails + ":id",
+ },
+ response: {
+ content: t("CS_PGR_RESPONSE"),
+ path: match.url + Employee.Response,
+ },
+ };
+ function popupCall(option) {
+ setDisplayMenu(false);
+ setPopup(true);
+ }
+
+ let location = useLocation().pathname;
+
+ const CreateComplaint = Digit?.ComponentRegistryService?.getComponent("PGRCreateComplaintEmp");
+ const ComplaintDetails = Digit?.ComponentRegistryService?.getComponent("PGRComplaintDetails");
+ const Inbox = Digit?.ComponentRegistryService?.getComponent("PGRInbox");
+ const InboxV2 = Digit?.ComponentRegistryService?.getComponent("PGRInboxV2");
+ const Response = Digit?.ComponentRegistryService?.getComponent("PGRResponseEmp");
+
+ return (
+
+
+ {!location.includes(Employee.Response) && (
+
+ } />
+ }
+ />
+ } />
+ } />
+
+ )}
+
+ } />
+ } />
+
+
+
+
+
+ {/*
+ {displayMenu ? : null}
+ setDisplayMenu(!displayMenu)} />
+ */}
+
+ );
+};
+
+export default Complaint;
diff --git a/micro-ui/web/packages/pgr/src/redux/actions/complaint.js b/micro-ui/web/packages/pgr/src/redux/actions/complaint.js
new file mode 100644
index 00000000000..c41760b87c5
--- /dev/null
+++ b/micro-ui/web/packages/pgr/src/redux/actions/complaint.js
@@ -0,0 +1,41 @@
+import { CREATE_COMPLAINT } from "./types";
+
+const createComplaint = ({
+ cityCode,
+ complaintType,
+ description,
+ landmark,
+ city,
+ district,
+ region,
+ state,
+ pincode,
+ localityCode,
+ localityName,
+ uploadedImages,
+ mobileNumber,
+ name,
+}) => async (dispatch, getState) => {
+ const response = await Digit.Complaint.create({
+ cityCode,
+ complaintType,
+ description,
+ landmark,
+ city,
+ district,
+ region,
+ state,
+ pincode,
+ localityCode,
+ localityName,
+ uploadedImages,
+ mobileNumber,
+ name,
+ });
+ dispatch({
+ type: CREATE_COMPLAINT,
+ payload: response,
+ });
+};
+
+export default createComplaint;
diff --git a/micro-ui/web/packages/pgr/src/redux/actions/index.js b/micro-ui/web/packages/pgr/src/redux/actions/index.js
new file mode 100644
index 00000000000..805c84dc097
--- /dev/null
+++ b/micro-ui/web/packages/pgr/src/redux/actions/index.js
@@ -0,0 +1,52 @@
+import {
+ APPLY_FILTER,
+ APPLY_INBOX_FILTER,
+ FETCH_BUSINESS_SERVICE_BY_ID,
+ FETCH_COMPLAINTS,
+ FETCH_LOCALITIES,
+ UPDATE_COMPLAINT,
+ FETCH_ALL_BUSINESSS_SERVICES,
+} from "./types";
+//import { LocalizationService } from "../../@egovernments/digit-utils/services/Localization/service";
+//import { LocationService } from "../../@egovernments/digit-utils/services/Location";
+//import { LocalityService } from "../../@egovernments/digit-utils/services/Localities";
+import createComplaint from "./complaint";
+
+export const fetchLocalities = (city) => async (dispatch, getState) => {
+ city = city.toLowerCase();
+ const { stateInfo } = getState();
+ let response = await Digit.LocationService.getLocalities(`${stateInfo.code}.${city}`);
+ let localityList = Digit.LocalityService.get(response.TenantBoundary[0]);
+ dispatch({
+ type: FETCH_LOCALITIES,
+ payload: { localityList },
+ });
+};
+
+export const updateComplaints = (data) => async (dispatch) => {
+ let ServiceWrappers = await Digit.PGRService.update(data);
+
+ dispatch({
+ type: UPDATE_COMPLAINT,
+ payload: ServiceWrappers,
+ });
+};
+
+export const fetchBusinessServiceByTenant = (tenantId, businessServices) => async (dispatch) => {
+ const businessServiceResponse = await Digit.WorkflowService.init(tenantId, businessServices);
+ const businessService = businessServiceResponse.BusinessServices;
+ dispatch({
+ type: FETCH_ALL_BUSINESSS_SERVICES,
+ payload: { businessService },
+ });
+};
+
+export const applyInboxFilters = (filters) => async (dispatch) => {
+ let response = await Digit.PGRService.inboxFilter(filters);
+ dispatch({
+ type: APPLY_INBOX_FILTER,
+ payload: { response },
+ });
+};
+
+export { createComplaint };
diff --git a/micro-ui/web/packages/pgr/src/redux/actions/types.js b/micro-ui/web/packages/pgr/src/redux/actions/types.js
new file mode 100644
index 00000000000..0b706733621
--- /dev/null
+++ b/micro-ui/web/packages/pgr/src/redux/actions/types.js
@@ -0,0 +1,16 @@
+//TODO: Make these immutable
+export const FETCH_CITIES = "FETCH_CITIES";
+export const FETCH_LOCALITIES = "FETCH_LOCALITIES";
+export const FETCH_LOCALIZATION_KEYS_PGR = "FETCH_LOCALIZATION_KEYS_PGR";
+export const UPDATE_I18NSTORE_CITY_PGR = "UPDATE_I18nStore_CITY_PGR";
+export const FETCH_LOCALITY_LOCALIZATION_KEYS_PGR = "FETCH_LOCALITY_LOCALIZATION_KEYS_PGR";
+export const CREATE_LOCALITY_DROPDOWN = "CREATE_LOCALITY_DROPDOWN";
+export const UPDATE_I18nStore_LOCALITY_PGR = "UPDATE_I18nStore_LOCALITY_PGR";
+export const CHANGE_LANGUAGE = "CHANGE_LANGUAGE";
+export const FETCH_LANGUAGES = "FETCH_LANGUAGES";
+export const FETCH_COMPLAINTS = "FETCH_COMPLAINTS";
+export const FETCH_ALL_BUSINESSS_SERVICES = "FETCH_ALL_BUSINESSS_SERVICES";
+export const FETCH_BUSINESS_SERVICE_BY_ID = "FETCH_BUSINESS_SERVICE_BY_ID";
+export const UPDATE_COMPLAINT = "UPDATE_COMPLAINT";
+export const CREATE_COMPLAINT = "CREATE_COMPLAINT";
+export const APPLY_INBOX_FILTER = "APPLY_INBOX_FILTER";
diff --git a/micro-ui/web/packages/pgr/src/redux/reducers/complaintReducer.js b/micro-ui/web/packages/pgr/src/redux/reducers/complaintReducer.js
new file mode 100644
index 00000000000..92bffc66a43
--- /dev/null
+++ b/micro-ui/web/packages/pgr/src/redux/reducers/complaintReducer.js
@@ -0,0 +1,18 @@
+import { APPLY_INBOX_FILTER, CREATE_COMPLAINT, FETCH_COMPLAINTS, UPDATE_COMPLAINT } from "../actions/types";
+
+function complaintReducer(state = {}, action) {
+ switch (action.type) {
+ case CREATE_COMPLAINT:
+ return { ...state, response: action.payload };
+ case FETCH_COMPLAINTS:
+ return { ...state, list: action.payload.complaints };
+ case UPDATE_COMPLAINT:
+ return { ...state, response: action.payload };
+ case APPLY_INBOX_FILTER:
+ return { ...state, response: action.payload.response.instances };
+ default:
+ return state;
+ }
+}
+
+export default complaintReducer;
diff --git a/micro-ui/web/packages/pgr/src/redux/reducers/index.js b/micro-ui/web/packages/pgr/src/redux/reducers/index.js
new file mode 100644
index 00000000000..40f634f19c8
--- /dev/null
+++ b/micro-ui/web/packages/pgr/src/redux/reducers/index.js
@@ -0,0 +1,9 @@
+import { combineReducers } from "redux";
+import complaintReducer from "./complaintReducer";
+
+const getRootReducer = () =>
+ combineReducers({
+ complaints: complaintReducer,
+ });
+
+export default getRootReducer;
diff --git a/micro-ui/web/packages/pgr/src/redux/store.js b/micro-ui/web/packages/pgr/src/redux/store.js
new file mode 100644
index 00000000000..57eb63e5a60
--- /dev/null
+++ b/micro-ui/web/packages/pgr/src/redux/store.js
@@ -0,0 +1,14 @@
+import { createStore, compose, applyMiddleware } from "redux";
+// import { composeWithDevTools } from "redux-devtools-extension";
+import thunk from "redux-thunk";
+import getRootReducer from "./reducers";
+
+const middleware = [thunk];
+const getStore = (defaultStore) => {
+ return createStore(
+ getRootReducer(defaultStore),
+ // composeWithDevTools(applyMiddleware(...middleware)) // :
+ compose(applyMiddleware(...middleware))
+ );
+};
+export default getStore;
diff --git a/micro-ui/web/packages/pgr/src/selectors/complaint.js b/micro-ui/web/packages/pgr/src/selectors/complaint.js
new file mode 100644
index 00000000000..cc3decc505e
--- /dev/null
+++ b/micro-ui/web/packages/pgr/src/selectors/complaint.js
@@ -0,0 +1,3 @@
+export const selectComplaints = (state) => state.pgr.complaints.list || [];
+
+export const selectComplaintById = (state, id) => state.pgr.complaints.list.filter((complaint) => complaint.service.serviceRequestId === id);
diff --git a/micro-ui/web/packages/pgr/src/selectors/processInstance.js b/micro-ui/web/packages/pgr/src/selectors/processInstance.js
new file mode 100644
index 00000000000..d58cc569e48
--- /dev/null
+++ b/micro-ui/web/packages/pgr/src/selectors/processInstance.js
@@ -0,0 +1 @@
+export const selectWorkflow = (state) => (state.businessService && state.businessService.businessService) || {};
diff --git a/micro-ui/web/packages/pgr/webpack.common.js b/micro-ui/web/packages/pgr/webpack.common.js
new file mode 100644
index 00000000000..6fe7bf190f7
--- /dev/null
+++ b/micro-ui/web/packages/pgr/webpack.common.js
@@ -0,0 +1,22 @@
+const path = require("path");
+
+module.exports = {
+ entry: "./src/SingleSpaEntry.js",
+ resolve: {
+ extensions: [ ".js", ".jsx"],
+ modules: [path.resolve(__dirname, "src"), "node_modules"],
+ },
+ module: {
+ rules: [
+ {
+ test: /\.js?$/,
+ loader: "babel-loader",
+ exclude: /node_modules/,
+ options: {
+ presets: ["@babel/preset-react"],
+ },
+ },
+ ],
+ },
+ plugins: [],
+};
diff --git a/micro-ui/web/packages/pgr/webpack.dev.js b/micro-ui/web/packages/pgr/webpack.dev.js
new file mode 100644
index 00000000000..6ca344ebf14
--- /dev/null
+++ b/micro-ui/web/packages/pgr/webpack.dev.js
@@ -0,0 +1,55 @@
+const { merge } = require("webpack-merge");
+const ModuleFederationPlugin = require("webpack/lib/container/ModuleFederationPlugin");
+const HtmlWebpackPlugin = require("html-webpack-plugin");
+const commonConfig = require("./webpack.common");
+const packageJson = require("./package.json");
+
+module.exports = () => {
+ const devConfig = {
+ mode: "development",
+ output: {
+ publicPath: "https://localhost:8087/",
+ filename: "[name].[contenthash].js",
+ },
+ devServer: {
+ port: 8087,
+ proxy: [
+ {
+ context: () => true,
+ target: 'https://unified-dev.digit.org',
+ secure: true,
+ changeOrigin: true,
+ bypass: function (req, res, proxyOptions){
+ if(req.headers.accept.indexOf('html') !== -1){
+ console.log('Skipping proxy for browser request.');
+ return '/index.html';
+ }
+ },
+ headers:{
+ "Connection" : "keep-alive"
+ },
+ },
+
+ ],
+ historyApiFallback: {
+ index: "/",
+ },
+ server:"https", //Enable HTTPS
+ },
+ plugins: [
+ new ModuleFederationPlugin({
+ name: "pgr",
+ filename: "remoteEntry.js",
+ exposes: {
+ "./PGRModule": "./src/SingleSpaEntry",
+ },
+ shared: packageJson.dependencies,
+ }),
+ new HtmlWebpackPlugin({
+ template: "./public/index.html",
+ }),
+ ],
+ };
+
+ return merge(commonConfig, devConfig);
+};
diff --git a/micro-ui/web/packages/pgr/webpack.prod.js b/micro-ui/web/packages/pgr/webpack.prod.js
new file mode 100644
index 00000000000..99965c434cf
--- /dev/null
+++ b/micro-ui/web/packages/pgr/webpack.prod.js
@@ -0,0 +1,27 @@
+const { merge } = require("webpack-merge");
+const ModuleFederationPlugin = require("webpack/lib/container/ModuleFederationPlugin");
+const commonConfig = require("./webpack.common");
+const packageJson = require("./package.json");
+
+module.exports = () => {
+ const prodConfig = {
+ mode: "production",
+ output: {
+ publicPath: "/pgr/",
+ filename: "[name].[contenthash].js",
+ },
+ plugins: [
+ new ModuleFederationPlugin({
+ name: "pgr",
+ filename: "remoteEntry.js",
+ exposes: {
+ "./PGRModule": "./src/SingleSpaEntry",
+ },
+ // shared: packageJson.dependencies,
+ shared: packageJson.dependencies
+ }),
+ ],
+ };
+
+ return merge(commonConfig, prodConfig);
+};
diff --git a/micro-ui/web/packages/workbench/src/bootstrap.js b/micro-ui/web/packages/workbench/src/bootstrap.js
index 54858a8dcdd..d7a5660d942 100644
--- a/micro-ui/web/packages/workbench/src/bootstrap.js
+++ b/micro-ui/web/packages/workbench/src/bootstrap.js
@@ -14,7 +14,7 @@ initWorkbenchComponents();
const mount = (el, { history, login }) => {
const moduleReducers = (initData) => {
};
- const enabledModules=["PT","Workbench"]
+ const enabledModules=["PT","Workbench", "PGR"]
const stateCode = window?.globalConfigs?.getConfig("STATE_LEVEL_TENANT_ID") || "pb";
//console.log(stateCode,'ststcode');