diff --git a/src/ModalProvider.jsx b/src/ModalProvider.jsx
index 13db2c2c..b9a2dea9 100644
--- a/src/ModalProvider.jsx
+++ b/src/ModalProvider.jsx
@@ -1,12 +1,19 @@
-import React, { useEffect } from 'react'
-import { useOrganizationModal } from './hooks/useOrganization';
-import OrganizationModal from './components/Organization/OrganizationModal';
+import React, { useEffect } from "react";
+import { useOrganizationModal } from "./hooks/useOrganization";
+import OrganizationModal from "./components/Organization/OrganizationModal";
+import { useAuthModal } from "./hooks/useAuth";
+import SwitchTenant from "./pages/authentication/SwitchTenant";
const ModalProvider = () => {
- const { isOpen,onClose } = useOrganizationModal();
-
- return <>{isOpen && }>;
+ const { isOpen, onClose } = useOrganizationModal();
+ const { isOpen: isAuthOpen } = useAuthModal();
+
+ return (
+ <>
+ {isOpen && }
+ {isAuthOpen && }
+ >
+ );
};
-
-export default ModalProvider
\ No newline at end of file
+export default ModalProvider;
\ No newline at end of file
diff --git a/src/components/Layout/Header.jsx b/src/components/Layout/Header.jsx
index 94ec39ac..6e05c1e1 100644
--- a/src/components/Layout/Header.jsx
+++ b/src/components/Layout/Header.jsx
@@ -19,6 +19,7 @@ import { useProjectName } from "../../hooks/useProjects";
import eventBus from "../../services/eventBus";
import { useHasUserPermission } from "../../hooks/useHasUserPermission";
import { MANAGE_PROJECT } from "../../utils/constants";
+import { useAuthModal } from "../../hooks/useAuth";
const Header = () => {
const { profile } = useProfile();
@@ -26,6 +27,7 @@ const Header = () => {
const dispatch = useDispatch();
const { data, loading } = useMaster();
const navigate = useNavigate();
+ const {onOpen} = useAuthModal()
const HasManageProjectPermission = useHasUserPermission(MANAGE_PROJECT);
// {
// console.log(location.pathname);
@@ -455,6 +457,16 @@ const Header = () => {
Change Password
+
+
onOpen()}>
+ {" "}
+
+
+ Switch Tenant
+
+
diff --git a/src/hooks/useAuth.jsx b/src/hooks/useAuth.jsx
index 94b9f2c5..570e0454 100644
--- a/src/hooks/useAuth.jsx
+++ b/src/hooks/useAuth.jsx
@@ -1,39 +1,51 @@
import { useState, useEffect, useCallback } from "react";
+import {
+ Mutation,
+ useMutation,
+ useQuery,
+ useQueryClient,
+} from "@tanstack/react-query";
+import { Link, useNavigate } from "react-router-dom";
+import AuthRepository from "../repositories/AuthRepository.jsx";
+import { useDispatch, useSelector } from "react-redux";
+import {
+ closeAuthModal,
+ openAuthModal,
+} from "../slices/localVariablesSlice.jsx";
-export const useTenantList = ({ autoFetch = true } = {}) => {
- const [data, setData] = useState([]);
- const [loading, setLoading] = useState(false);
- const [error, setError] = useState(null);
-
- const fetchTenantList = useCallback(async () => {
- setLoading(true);
- setError(null);
- try {
- const response = setData(response.data || []);
- } catch (err) {
- setError(err);
- } finally {
- setLoading(false);
- }
- }, []);
-
- useEffect(() => {
- if (autoFetch) fetchTenantList();
- }, [autoFetch, fetchTenantList]);
-
- return {
- data,
- loading,
- error,
- refetch: fetchTenantList, // manual trigger
- };
+export const useTenants = () => {
+ return useQuery({
+ queryKey: ["tenantlist"],
+ queryFn: async () => await AuthRepository.getTenantList(),
+ });
};
+export const useSelectTenant = (onSuccessCallBack) => {
+ const queryClient = useQueryClient();
-export const useTenants =()=>{
- get
- return useQueery({
- queryKey:["tenantlist",localhost.get("orgJwtToken")],
- queryFun:async()=> await AuthRepository.
- })
-}
\ No newline at end of file
+ return useMutation({
+ mutationFn: async (tenantId) => {
+ const res = await AuthRepository.selectTenant(tenantId);
+ return res.data;
+ },
+ onSuccess: (data) => {
+ localStorage.setItem("ltkn", data.token);
+ localStorage.setItem("rtkn", data.refreshToken);
+ if (onSuccessCallBack) onSuccessCallBack();
+ },
+ onError: (error) => {
+ showToast(error.message || "Error while creating project", "error");
+ },
+ });
+};
+
+export const useAuthModal = () => {
+ const dispatch = useDispatch();
+ const { isOpen } = useSelector((state) => state.localVariables.AuthModal);
+
+ return {
+ isOpen,
+ onOpen: () => dispatch(openAuthModal()),
+ onClose: () => dispatch(closeAuthModal()),
+ };
+};
\ No newline at end of file
diff --git a/src/pages/authentication/LoginPage.jsx b/src/pages/authentication/LoginPage.jsx
index 3e331376..363de91f 100644
--- a/src/pages/authentication/LoginPage.jsx
+++ b/src/pages/authentication/LoginPage.jsx
@@ -44,7 +44,7 @@ const LoginPage = () => {
localStorage.setItem("jwtToken", response.data.token);
localStorage.setItem("refreshToken", response.data.refreshToken);
setLoading(false);
- navigate("/dashboard");
+ navigate("/auth/switch/org");
} else {
await AuthRepository.sendOTP({ email: data.username });
showToast("OTP has been sent to your email.", "success");
diff --git a/src/pages/authentication/SwitchTenant.jsx b/src/pages/authentication/SwitchTenant.jsx
new file mode 100644
index 00000000..e36ede07
--- /dev/null
+++ b/src/pages/authentication/SwitchTenant.jsx
@@ -0,0 +1,101 @@
+import React, { useState } from "react";
+import Modal from "../../components/common/Modal";
+import { useAuthModal, useSelectTenant, useTenants } from "../../hooks/useAuth";
+import { useProfile } from "../../hooks/useProfile";
+import { useQueryClient } from "@tanstack/react-query";
+import AuthRepository from "../../repositories/AuthRepository";
+
+const SwitchTenant = () => {
+ const queryClient = useQueryClient();
+ const { profile } = useProfile();
+ const [pendingTenant, setPendingTenant] = useState(null);
+ const { isOpen, onClose, onOpen } = useAuthModal();
+ const { data, isLoading, isError, error } = useTenants();
+ const { mutate: chooseTenant, isPending } = useSelectTenant(() => {
+ onClose();
+ queryClient.clear();
+
+ // 2. Force fetch profile fresh for the new tenant
+ queryClient.fetchQuery({
+ queryKey: ["profile"],
+ queryFn: () => AuthRepository.profile(),
+ });
+ });
+ const currentTenant = localStorage.getItem("ctnt");
+ const handleTenantselection = (tenantId) => {
+ setPendingTenant(tenantId);
+ localStorage.setItem("ctnt", tenantId);
+ chooseTenant(tenantId);
+ };
+ const contentBody = (
+
+
Switch Workplace
+
+ {data?.data.map((tenant) => (
+
+
+
+

+
+
+
+
+ {tenant?.name}
+
+
+
+
Industry:
+
+ {tenant?.industry?.name || "Not Available"}
+
+
+
+ {tenant?.description && (
+
+ {tenant?.description}
+
+ )}
+
+
+
+
+
+ ))}
+
+
+ );
+ return ;
+};
+
+export default SwitchTenant;
\ No newline at end of file
diff --git a/src/pages/authentication/TenantSelectionPage.jsx b/src/pages/authentication/TenantSelectionPage.jsx
new file mode 100644
index 00000000..5e748548
--- /dev/null
+++ b/src/pages/authentication/TenantSelectionPage.jsx
@@ -0,0 +1,102 @@
+import { useEffect, useState } from "react";
+import { useTenants, useSelectTenant } from "../../hooks/useAuth.jsx";
+import { Link, useNavigate } from "react-router-dom";
+import Dashboard from "../../components/Dashboard/Dashboard.jsx";
+
+const TenantSelectionPage = () => {
+ const [pendingTenant, setPendingTenant] = useState(null);
+ const navigate = useNavigate();
+
+ const { data, isLoading, isError, error } = useTenants();
+ const { mutate: chooseTenant, isPending } = useSelectTenant(() => {
+ navigate("/dashboard");
+ });
+ const handleTenantselection = (tenantId) => {
+ setPendingTenant(tenantId);
+ localStorage.setItem("ctnt", tenantId);
+ chooseTenant(tenantId);
+ };
+
+ useEffect(() => {
+ if (localStorage.getItem("ctnt")) {
+ return navigate("/dashboard");
+ }
+ }, []);
+
+ if (isLoading) {
+ return (
+
+
+ Loading tenants...
+
+
+ );
+ }
+
+ return (
+
+ {/* Header */}
+
+
Welcome
+
+ Please select which dashboard you want to explore!!!
+
+
+
+ {/* Card Section */}
+
+ {data?.data.map((tenant) => (
+
+
+ {/* Image */}
+
+

+
+
+ {/* Content */}
+
+
+ {tenant?.name}
+
+
+
+
Industry:
+
+ {tenant?.industry?.name || "Not Available"}
+
+
+
+ {tenant?.description && (
+
+ {tenant?.description}
+
+ )}
+
+
+
+
+
+ ))}
+
+
+ );
+};
+
+export default TenantSelectionPage;
\ No newline at end of file
diff --git a/src/repositories/AuthRepository.jsx b/src/repositories/AuthRepository.jsx
index b1d28940..cf3f6e31 100644
--- a/src/repositories/AuthRepository.jsx
+++ b/src/repositories/AuthRepository.jsx
@@ -15,7 +15,9 @@ const AuthRepository = {
logout: (data) => api.post("/api/auth/logout", data),
profile: () => api.get("/api/user/profile"),
changepassword: (data) => api.post("/api/auth/change-password", data),
- appmenu:()=>api.get('/api/appmenu/get/menu')
+ appmenu: () => api.get('/api/appmenu/get/menu'),
+ selectTenant: (tenantId) => api.post(`/api/Auth/select-tenant/${tenantId}`),
+ getTenantList: () => api.get("/api/Auth/get/user/tenants"),
};
diff --git a/src/router/AppRoutes.jsx b/src/router/AppRoutes.jsx
index 66943fb0..70052cad 100644
--- a/src/router/AppRoutes.jsx
+++ b/src/router/AppRoutes.jsx
@@ -51,6 +51,7 @@ import { Navigate } from "react-router-dom";
import CreateTenant from "../pages/Tenant/CreateTenant";
import OrganizationPage from "../pages/Organization/OrganizationPage";
import LandingPage from "../pages/Home/LandingPage";
+import TenantSelectionPage from "../pages/authentication/TenantSelectionPage";
const router = createBrowserRouter(
[
{
@@ -69,6 +70,7 @@ const router = createBrowserRouter(
{ path: "/auth/changepassword", element: },
],
},
+ { path: "/auth/switch/org", element: },
{
element: ,
errorElement: ,
diff --git a/src/slices/localVariablesSlice.jsx b/src/slices/localVariablesSlice.jsx
index c78e4da7..784100e0 100644
--- a/src/slices/localVariablesSlice.jsx
+++ b/src/slices/localVariablesSlice.jsx
@@ -3,54 +3,56 @@ import { createSlice } from "@reduxjs/toolkit";
const localVariablesSlice = createSlice({
name: "localVariables",
initialState: {
- selectedMaster:"Application Role",
- regularizationCount:0,
- defaultDateRange: {
+ selectedMaster: "Application Role",
+ regularizationCount: 0,
+ defaultDateRange: {
startDate: null,
endDate: null,
},
projectId: null,
- reload:false,
+ reload: false,
- OrganizationModal:{
+ OrganizationModal: {
isOpen: false,
orgData: null,
- prevStep:null,
+ prevStep: null,
startStep: 1,
- flowType: "default",
- }
-
+ flowType: "default",
+ },
+
+ AuthModal: {
+ isOpen: false,
+ },
},
reducers: {
changeMaster: (state, action) => {
- state.selectedMaster = action.payload;
+ state.selectedMaster = action.payload;
},
updateRegularizationCount: (state, action) => {
state.regularizationCount = action.payload;
},
- setProjectId: (state, action) => {
- localStorage.setItem("project",null)
+ setProjectId: (state, action) => {
+ localStorage.setItem("project", null);
state.projectId = action.payload;
- localStorage.setItem("project",state.projectId || null)
+ localStorage.setItem("project", state.projectId || null);
},
- refreshData: ( state, action ) =>
- {
- state.reload = action.payload
+ refreshData: (state, action) => {
+ state.reload = action.payload;
},
setDefaultDateRange: (state, action) => {
state.defaultDateRange = action.payload;
},
-openOrgModal: (state, action) => {
-state.OrganizationModal.isOpen = true;
- state.OrganizationModal.orgData = action.payload?.orgData || null;
+ openOrgModal: (state, action) => {
+ state.OrganizationModal.isOpen = true;
+ state.OrganizationModal.orgData = action.payload?.orgData || null;
- if (state.OrganizationModal.startStep) {
- state.OrganizationModal.prevStep = state.OrganizationModal.startStep;
- }
+ if (state.OrganizationModal.startStep) {
+ state.OrganizationModal.prevStep = state.OrganizationModal.startStep;
+ }
- state.OrganizationModal.startStep = action.payload?.startStep || 1;
- state.OrganizationModal.flowType = action.payload?.flowType || "default";
+ state.OrganizationModal.startStep = action.payload?.startStep || 1;
+ state.OrganizationModal.flowType = action.payload?.flowType || "default";
},
closeOrgModal: (state) => {
state.OrganizationModal.isOpen = false;
@@ -61,8 +63,26 @@ state.OrganizationModal.isOpen = true;
toggleOrgModal: (state) => {
state.OrganizationModal.isOpen = !state.OrganizationModal.isOpen;
},
+
+ openAuthModal: (state, action) => {
+ state.AuthModal.isOpen = true;
+ },
+ closeAuthModal: (state, action) => {
+ state.AuthModal.isOpen = false;
+ },
},
});
-export const { changeMaster ,updateRegularizationCount,setProjectId,refreshData,setDefaultDateRange,openOrgModal,closeOrgModal,toggleOrgModal} = localVariablesSlice.actions;
-export default localVariablesSlice.reducer;
+export const {
+ changeMaster,
+ updateRegularizationCount,
+ setProjectId,
+ refreshData,
+ setDefaultDateRange,
+ openOrgModal,
+ closeOrgModal,
+ toggleOrgModal,
+ openAuthModal,
+ closeAuthModal,
+} = localVariablesSlice.actions;
+export default localVariablesSlice.reducer;
\ No newline at end of file