From 2dda2711e8d138f8fb4a69636fbb1dcc9d2da2a0 Mon Sep 17 00:00:00 2001 From: chaitanyakole Date: Tue, 28 Jan 2025 14:55:55 +0530 Subject: [PATCH] Task #234200 Implement the Remaining APIs After Keycloak Authentication for Tenant Page --- src/components/FormControl.tsx | 6 +-- src/components/HeaderComponent.tsx | 20 ++++---- src/components/layouts/header/Profile.tsx | 24 +++++---- src/pages/_app.tsx | 60 +++++++++++++++++------ src/pages/cohorts.tsx | 6 +-- src/pages/tenant.tsx | 15 +++--- src/utils/keycloak.ts | 18 +++---- 7 files changed, 90 insertions(+), 59 deletions(-) diff --git a/src/components/FormControl.tsx b/src/components/FormControl.tsx index ef489d4..8da7d85 100644 --- a/src/components/FormControl.tsx +++ b/src/components/FormControl.tsx @@ -76,11 +76,11 @@ const MultipleSelectCheckmarks: React.FC = ({ value={ // If no categories are selected (empty or invalid selection), show default value or the first name from 'names' selectedCategories?.length <= 0 || selectedCategories[0] === "" - ? names?.length > 1 - ? [names[0]] // If there are multiple tenants, default to the first one + ? names?.length >= 1 + ? [names[0]] : defaultValue ? [defaultValue] - : [] // Else, use defaultValue or empty array + : [] : selectedCategories // If categories are selected, use selectedCategories } onChange={handleChange} // Handle the change event for the selection diff --git a/src/components/HeaderComponent.tsx b/src/components/HeaderComponent.tsx index f8cb4dd..e80046c 100644 --- a/src/components/HeaderComponent.tsx +++ b/src/components/HeaderComponent.tsx @@ -283,23 +283,23 @@ const HeaderComponent = ({ if (stateField?.value?.includes(",")) { setStateDefaultValue(t("COMMON.ALL_STATES")); } else { - setStateDefaultValue(stateField.value); + setStateDefaultValue(stateField?.value); const response = await queryClient.fetchQuery({ queryKey: [ QueryKeys.FIELD_OPTION_READ, - stateField.code, + stateField?.code, "districts", ], queryFn: () => getStateBlockDistrictList({ - controllingfieldfk: stateField.code, + controllingfieldfk: stateField?.code, fieldName: "districts", }), }); // const object = { - // controllingfieldfk: stateField.code, + // controllingfieldfk: stateField?.code, // fieldName: "districts", // }; @@ -334,7 +334,7 @@ const HeaderComponent = ({ pathname: router.pathname, query: { ...router.query, - state: stateField.code, + state: stateField?.code, district: districtResult[0]?.value, }, }); @@ -358,7 +358,7 @@ const HeaderComponent = ({ pathname: router.pathname, // query: { // ...router.query, - // state: stateField.code, + // state: stateField?.code, // district: districtResult[0]?.value, // block: blockResult[0]?.value, // }, @@ -372,7 +372,7 @@ const HeaderComponent = ({ filters: { // "type":"COHORT", status: ["active"], - // states: stateField.code, + // states: stateField?.code, // districts: districtResult[0]?.value, // blocks: blockResult[0]?.value, // "name": selected[0] @@ -416,7 +416,7 @@ const HeaderComponent = ({ pathname: router.pathname, // query: { // ...router.query, - // state: stateField.code, + // state: stateField?.code, // district: districtResult[0]?.value, // block: blockResult[0]?.value, // // center: cohortInfo[0]?.cohortId @@ -427,8 +427,8 @@ const HeaderComponent = ({ const object = [ { - value: stateField.code, - label: stateField.value, + value: stateField?.code, + label: stateField?.value, }, ]; setStates(object); diff --git a/src/components/layouts/header/Profile.tsx b/src/components/layouts/header/Profile.tsx index 8b59ec0..3eb4595 100644 --- a/src/components/layouts/header/Profile.tsx +++ b/src/components/layouts/header/Profile.tsx @@ -36,7 +36,18 @@ const Profile = () => { (state: any) => state.setAdminInformation ); const router = useRouter(); - + useEffect(() => { + const intervalId = setInterval(() => { + const admin = localStorage.getItem("adminInfo"); + if (admin) { + setAdminInfo(JSON.parse(admin)); + clearInterval(intervalId); + } + }, 100); + return () => { + clearInterval(intervalId); + }; + }, []); const handleClick4 = (event: React.MouseEvent) => { setAnchorEl4(event.currentTarget); setProfileClick(true); @@ -169,13 +180,6 @@ const Profile = () => { getUserName(); }, [formdata]); - useEffect(() => { - if (typeof window !== "undefined" && window.localStorage) { - const admin = localStorage.getItem("adminInfo"); - if (admin) setAdminInfo(JSON.parse(admin)); - } - }, []); - const handleModalSubmit = (value: boolean) => { submitValue ? setSubmitValue(false) : setSubmitValue(true); }; @@ -223,7 +227,9 @@ const Profile = () => { whiteSpace: "nowrap", }} > - {t("COMMON.HI", { name: firstLetterInUpperCase(userName ?? "") })} + {t("COMMON.HI", { + name: firstLetterInUpperCase(adminInfo?.name ?? ""), + })} diff --git a/src/pages/_app.tsx b/src/pages/_app.tsx index aef0967..034c349 100644 --- a/src/pages/_app.tsx +++ b/src/pages/_app.tsx @@ -3,7 +3,7 @@ import "@/styles/globals.css"; import type { AppProps } from "next/app"; import { appWithTranslation } from "next-i18next"; import { initGA } from "../utils/googleAnalytics"; -import { useEffect, useState } from "react"; +import { useEffect, useRef, useState } from "react"; import { AuthProvider } from "../context/AuthContext"; import { ToastContainer } from "react-toastify"; import "react-toastify/dist/ReactToastify.css"; @@ -16,8 +16,13 @@ import keycloak from "../utils/keycloak"; import { QueryClientProvider, QueryClient } from "@tanstack/react-query"; import { ReactQueryDevtools } from "@tanstack/react-query-devtools"; import "react-circular-progressbar/dist/styles.css"; +import { getUserId } from "@/services/LoginService"; +import { getUserDetailsInfo } from "@/services/UserList"; function App({ Component, pageProps }: AppProps) { + const [isAuthenticated, setIsAuthenticated] = useState(false); + const hasFetchedUserDetails = useRef(false); + // Analytics initialization useEffect(() => { telemetryFactory.init(); @@ -34,21 +39,18 @@ function App({ Component, pageProps }: AppProps) { useEffect(() => { const initializeKeycloak = async () => { try { - if (keycloak != null && !keycloak.authenticated) { - const authenticated = await keycloak.init({ - onLoad: "login-required", - redirectUri: window.location.origin + "/tenant", - }); - - if (authenticated) { - if (keycloak.token) { - localStorage.setItem("token", keycloak.token); - } - if (keycloak.refreshToken) { - localStorage.setItem("refreshToken", keycloak.refreshToken); - } - } - } + if (!keycloak || keycloak.authenticated) return; + + const authenticated = await keycloak.init({ + onLoad: "login-required", + redirectUri: `${window.location.origin}/tenant`, + }); + + if (!authenticated) return; + setIsAuthenticated(true); + if (keycloak.token) localStorage.setItem("token", keycloak.token); + if (keycloak.refreshToken) + localStorage.setItem("refreshToken", keycloak.refreshToken); } catch (error) { console.error("Failed to initialize Keycloak:", error); } @@ -56,6 +58,32 @@ function App({ Component, pageProps }: AppProps) { initializeKeycloak(); }, []); + useEffect(() => { + if (!isAuthenticated || hasFetchedUserDetails.current) return; + + const fetchUserDetails = async () => { + try { + const userResponse = await getUserId(); + if (!userResponse) return; + localStorage.setItem("userId", userResponse.userId || ""); + localStorage.setItem("name", userResponse.name || ""); + + const tenantId = userResponse.tenantData?.[0]?.tenantId || ""; + localStorage.setItem("tenantId", tenantId); + + if (userResponse?.userId) { + const response = await getUserDetailsInfo(userResponse.userId, true); + localStorage.setItem("adminInfo", JSON.stringify(response?.userData)); + } + + hasFetchedUserDetails.current = true; + } catch (error) { + console.error("Error fetching user details:", error); + } + }; + + fetchUserDetails(); + }, [isAuthenticated]); const renderComponent = () => { if (pageProps.noLayout) { diff --git a/src/pages/cohorts.tsx b/src/pages/cohorts.tsx index b075520..1ec86e2 100644 --- a/src/pages/cohorts.tsx +++ b/src/pages/cohorts.tsx @@ -327,9 +327,9 @@ const Center: React.FC = () => { if (typeof window !== "undefined" && window.localStorage) { const admin = localStorage.getItem("adminInfo"); if (admin) { - const stateField: any = JSON.parse(admin).customFields.find( - (field: any) => field.label === "STATES" - ); + // const stateField: any = JSON.parse(admin).customFields.find( + // (field: any) => field.label === "STATES" + // ); // const object = [ // { // value: stateField.code, diff --git a/src/pages/tenant.tsx b/src/pages/tenant.tsx index a532fe0..6b7ef8b 100644 --- a/src/pages/tenant.tsx +++ b/src/pages/tenant.tsx @@ -291,6 +291,7 @@ const Tenant: React.FC = () => { status: [statusValue], districts: "", }); + const handleCloseAddLearnerModal = () => { setUpdateBtnDisabled(true); setOpenAddNewCohort(false); @@ -303,9 +304,9 @@ const Tenant: React.FC = () => { if (typeof window !== "undefined" && window?.localStorage) { const admin = localStorage.getItem("adminInfo"); if (admin) { - const stateField: any = JSON.parse(admin).customFields.find( - (field: any) => field.label === "STATES" - ); + // const stateField: any = JSON.parse(admin).customFields.find( + // (field: any) => field.label === "STATES" + // ); // const object = [ // { // value: stateField.code, @@ -1025,12 +1026,12 @@ const Tenant: React.FC = () => { if (typeof window !== "undefined" && window.localStorage) { const admin = localStorage.getItem("adminInfo"); if (admin) { - const stateField = JSON.parse(admin).customFields.find( - (field: any) => field.label === "STATES" + const stateField = JSON.parse(admin).customFields?.find( + (field: any) => field?.label === "STATES" ); - if (!stateField.value.includes(",")) { + if (!stateField?.value?.includes(",")) { // setSelectedState([stateField.value]); - setSelectedStateCode(stateField.code); + setSelectedStateCode(stateField?.code); if ( selectedDistrictCode && selectedDistrict.length !== 0 && diff --git a/src/utils/keycloak.ts b/src/utils/keycloak.ts index bb70d4b..94b4647 100644 --- a/src/utils/keycloak.ts +++ b/src/utils/keycloak.ts @@ -14,16 +14,12 @@ export const logout = async () => { console.error("Logout failed:", error); } }; - -const keycloakConfig = { - url: process.env.NEXT_PUBLIC_KEYCLOAK_URL || " ", - realm: process.env.NEXT_PUBLIC_KEYCLOAK_REALM || " ", - clientId: process.env.NEXT_PUBLIC_KEYCLOAK_CLIENT_ID || "", -}; - -// Initialize Keycloak instance - const keycloakInstance = - typeof window !== "undefined" ? new Keycloak(keycloakConfig) : null; - + typeof window !== "undefined" + ? new Keycloak({ + url: process.env.NEXT_PUBLIC_KEYCLOAK_URL || "", + realm: process.env.NEXT_PUBLIC_KEYCLOAK_REALM || "", + clientId: process.env.NEXT_PUBLIC_KEYCLOAK_CLIENT_ID || "", + }) + : null; export default keycloakInstance;