diff --git a/src/hooks/useAuth.jsx b/src/hooks/useAuth.jsx
new file mode 100644
index 00000000..94b9f2c5
--- /dev/null
+++ b/src/hooks/useAuth.jsx
@@ -0,0 +1,39 @@
+import { useState, useEffect, useCallback } from "react";
+
+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 =()=>{
+ get
+ return useQueery({
+ queryKey:["tenantlist",localhost.get("orgJwtToken")],
+ queryFun:async()=> await AuthRepository.
+ })
+}
\ No newline at end of file
diff --git a/src/pages/authentication/LoginPage.jsx b/src/pages/authentication/LoginPage.jsx
index 3e331376..e75b9f0c 100644
--- a/src/pages/authentication/LoginPage.jsx
+++ b/src/pages/authentication/LoginPage.jsx
@@ -6,7 +6,7 @@ import { useForm } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import { z } from "zod";
import { AuthWrapper } from "./AuthWrapper";
-
+import { setOrgToken } from "../../services/tenantService";
const LoginPage = () => {
const navigate = useNavigate();
const [loading, setLoading] = useState(false);
@@ -16,13 +16,13 @@ const LoginPage = () => {
const loginSchema = IsLoginWithOTP
? z.object({
- username: z.string().trim().email({ message: "Valid email required" }),
- })
+ username: z.string().trim().email({ message: "Valid email required" }),
+ })
: z.object({
- username: z.string().trim().email({ message: "Valid email required" }),
- password: z.string().trim().min(1, { message: "Password required" }),
- rememberMe: z.boolean(),
- });
+ username: z.string().trim().email({ message: "Valid email required" }),
+ password: z.string().trim().min(1, { message: "Password required" }),
+ rememberMe: z.boolean(),
+ });
const {
register,
@@ -41,10 +41,11 @@ const LoginPage = () => {
password: data.password,
};
const response = await AuthRepository.login(userCredential);
- localStorage.setItem("jwtToken", response.data.token);
- localStorage.setItem("refreshToken", response.data.refreshToken);
+ // localStorage.setItem("jwtToken", response.data.token);
+ // localStorage.setItem("refreshToken", response.data.refreshToken);
setLoading(false);
- navigate("/dashboard");
+ setOrgToken(response.data.token, response.data.refreshToken);
+ navigate("/auth/user");
} else {
await AuthRepository.sendOTP({ email: data.username });
showToast("OTP has been sent to your email.", "success");
@@ -146,8 +147,9 @@ const LoginPage = () => {
type={hidepass ? "password" : "text"}
autoComplete="new-password"
id="password"
- className={`form-control form-control-xl shadow-none ${errors.password ? "is-invalid" : ""
- }`}
+ className={`form-control form-control-xl shadow-none ${
+ errors.password ? "is-invalid" : ""
+ }`}
name="password"
{...register("password")}
placeholder="••••••••••••"
@@ -170,13 +172,15 @@ const LoginPage = () => {
{/* ✅ Error message */}
{errors.password && (
-
@@ -209,8 +213,8 @@ const LoginPage = () => {
{loading
? "Please Wait..."
: IsLoginWithOTP
- ? "Send OTP"
- : "Sign In"}
+ ? "Send OTP"
+ : "Sign In"}
{/* Login With OTP Button */}
@@ -254,4 +258,4 @@ const LoginPage = () => {
);
};
-export default LoginPage;
\ No newline at end of file
+export default LoginPage;
diff --git a/src/repositories/AttendanceRepository.jsx b/src/repositories/AttendanceRepository.jsx
index 679001f8..a8f1a0b1 100644
--- a/src/repositories/AttendanceRepository.jsx
+++ b/src/repositories/AttendanceRepository.jsx
@@ -1,13 +1,10 @@
import { api } from "../utils/axiosClient";
-
-const AttendanceRepository = {
- markAttendance:(data)=>api.post("/api/attendance/record",data),
- getAttendance:(id)=>api.get(`api/attendance/project/team?projectId=${id}`),
- getAttendanceFilteredByDate: ( projectId, fromDate, toDate ) =>
- {
-
- let url = `api/Attendance/project/log?projectId=${ projectId }`
+const AttendanceRepository = {
+ markAttendance: (data) => api.post("/api/attendance/record", data),
+ getAttendance: (id) => api.get(`api/attendance/project/team?projectId=${id}`),
+ getAttendanceFilteredByDate: (projectId, fromDate, toDate) => {
+ let url = `api/Attendance/project/log?projectId=${projectId}`;
if (fromDate) {
url += `&dateFrom=${fromDate}`;
}
@@ -15,27 +12,24 @@ const AttendanceRepository = {
if (toDate) {
url += `&dateTo=${toDate}`;
}
- return api.get(url)
+ return api.get(url);
},
-
- getAttendanceLogs: ( id ) => api.get( `api/attendance/log/attendance/${ id }` ),
- getRegularizeList: ( id ) => api.get( `api/attendance/regularize?projectId=${ id }` ),
-
- getAttendanceByEmployee: ( employeeId, fromDate, toDate ) =>
- {
-
- let url = `api/Attendance/log/employee/${ employeeId }?`
- if (fromDate) {
- url += `&dateFrom=${fromDate}`;
- }
-
- if (toDate) {
- url += `&dateTo=${toDate}`;
- }
- return api.get(url)
- },
-}
+ getAttendanceLogs: (id) => api.get(`api/attendance/log/attendance/${id}`),
+ getRegularizeList: (id) =>
+ api.get(`api/attendance/regularize?projectId=${id}`),
+
+ getAttendanceByEmployee: (employeeId, fromDate, toDate) => {
+ let url = `api/Attendance/log/employee/${employeeId}?`;
+ if (fromDate) {
+ url += `&dateFrom=${fromDate}`;
+ }
+
+ if (toDate) {
+ url += `&dateTo=${toDate}`;
+ }
+ return api.get(url);
+ },
+};
export default AttendanceRepository;
-
diff --git a/src/repositories/AuthRepository.jsx b/src/repositories/AuthRepository.jsx
index 5004c7ec..e6c6411a 100644
--- a/src/repositories/AuthRepository.jsx
+++ b/src/repositories/AuthRepository.jsx
@@ -16,6 +16,22 @@ const AuthRepository = {
profile: () => api.get("/api/user/profile"),
changepassword: (data) => api.post("/api/auth/change-password", data),
appmenu: () => api.get("/api/appmenu/get/menu"),
+ // getTenantList: () =>
+ // api.get("/api/Auth/get/user/tenants", {}, { useTenantToken: false }),
+ // selectTenant: (tenantId) =>
+ // api.post(`/api/Auth/select-tenant/${tenantId}`),
+
+ // ---------------- Org-level routes (use org token) ---------------
+ // Note: pass `orgToken: true` (4th arg) so axios interceptor uses orgJwtToken.
+ getTenantList: () => api.get("/api/Auth/get/user/tenants", {}, {}, true),
+
+ // Exchange tenantId (with org token) -> server returns tenant JWT
+ // Using POST with body { tenantId } (adjust if your API expects path param).
+ selectTenant: (tenantId) =>
+ api.post("/api/Auth/select-tenant", { tenantId }, {}, true),
+
+ // If your backend expects tenantId in URL instead of body, use this variant:
+ // selectTenant: (tenantId) => api.post(`/api/Auth/select-tenant/${tenantId}`, {}, {}, true),
};
export default AuthRepository;
diff --git a/src/router/AppRoutes.jsx b/src/router/AppRoutes.jsx
index 8e32e0e1..66943fb0 100644
--- a/src/router/AppRoutes.jsx
+++ b/src/router/AppRoutes.jsx
@@ -49,7 +49,6 @@ import MainResetPasswordPage from "../pages/authentication/MainResetPasswordPage
import TenantPage from "../pages/Tenant/TenantPage";
import { Navigate } from "react-router-dom";
import CreateTenant from "../pages/Tenant/CreateTenant";
-;
import OrganizationPage from "../pages/Organization/OrganizationPage";
import LandingPage from "../pages/Home/LandingPage";
const router = createBrowserRouter(
diff --git a/src/router/ProtectedRoute.jsx b/src/router/ProtectedRoute.jsx
index a1879e85..68dd847f 100644
--- a/src/router/ProtectedRoute.jsx
+++ b/src/router/ProtectedRoute.jsx
@@ -8,7 +8,7 @@ const ProtectedRoute = () => {
// // const isAuthenticated = true;
// isTokenValid();
// return isAuthenticated ? :
-
+
const [isAuthenticated, setIsAuthenticated] = useState(null);
useEffect(() => {
@@ -66,7 +66,7 @@ const attemptTokenRefresh = async (storedRefreshToken) => {
localStorage.setItem("jwtToken", response.data.token);
localStorage.setItem("refreshToken", response.data.refreshToken);
return true;
- // api
+ // api
// .post("/api/auth/refresh-token", {
// token: localStorage.getItem("jwtToken"),
// refreshToken: refreshToken,
diff --git a/src/slices/globalVariablesSlice.jsx b/src/slices/globalVariablesSlice.jsx
index 7bdadd51..8e656000 100644
--- a/src/slices/globalVariablesSlice.jsx
+++ b/src/slices/globalVariablesSlice.jsx
@@ -3,23 +3,23 @@ import { createSlice } from "@reduxjs/toolkit";
const globalVariablesSlice = createSlice({
name: "globalVariables",
initialState: {
- loginUser:null,
- currentTenant:null
+ loginUser: null,
+ currentTenant: null,
},
reducers: {
setGlobalVariable: (state, action) => {
const { key, value } = action.payload;
state[key] = value;
},
- setLoginUserPermmisions: ( state, action ) =>
- {
- state.loginUser = action.payload
+ setLoginUserPermmisions: (state, action) => {
+ state.loginUser = action.payload;
+ },
+ setCurrentTenant: (state, action) => {
+ state.currentTenant = action.payload;
},
- setCurrentTenant:(state,action)=>{
- state.currentTenant = action.payload
- }
},
});
-export const { setGlobalVariable,setLoginUserPermmisions,setCurrentTenant } = globalVariablesSlice.actions;
+export const { setGlobalVariable, setLoginUserPermmisions, setCurrentTenant } =
+ globalVariablesSlice.actions;
export default globalVariablesSlice.reducer;
diff --git a/src/utils/axiosClient.jsx b/src/utils/axiosClient.jsx
index 9c4bd3ae..62e9b3bb 100644
--- a/src/utils/axiosClient.jsx
+++ b/src/utils/axiosClient.jsx
@@ -4,7 +4,7 @@ import axiosRetry from "axios-retry";
import showToast from "../services/toastService";
import { startSignalR, stopSignalR } from "../services/signalRService";
import { BASE_URL } from "./constants";
-const base_Url = BASE_URL
+const base_Url = BASE_URL;
export const axiosClient = axios.create({
baseURL: base_Url,
@@ -44,7 +44,10 @@ axiosClient.interceptors.response.use(
const originalRequest = error.config;
// Skip retry for public requests or already retried ones
- if (!originalRequest && originalRequest._retry || originalRequest.authRequired === false) {
+ if (
+ (!originalRequest && originalRequest._retry) ||
+ originalRequest.authRequired === false
+ ) {
return Promise.reject(error);
}
@@ -53,7 +56,10 @@ axiosClient.interceptors.response.use(
originalRequest._toastShown = true;
if (error.code === "ERR_CONNECTION_REFUSED") {
- showToast("Unable to connect to the server. Please try again later.", "error");
+ showToast(
+ "Unable to connect to the server. Please try again later.",
+ "error"
+ );
} else if (error.code === "ERR_NETWORK") {
showToast("Network error. Please check your connection.", "error");
redirectToLogin();
@@ -68,7 +74,10 @@ axiosClient.interceptors.response.use(
const refreshToken = localStorage.getItem("refreshToken");
- if (!refreshToken || error.response.data?.errors === "Invalid or expired refresh token.") {
+ if (
+ !refreshToken ||
+ error.response.data?.errors === "Invalid or expired refresh token."
+ ) {
redirectToLogin();
return Promise.reject(error);
}
@@ -88,7 +97,7 @@ axiosClient.interceptors.response.use(
localStorage.setItem("jwtToken", token);
localStorage.setItem("refreshToken", newRefreshToken);
- startSignalR()
+ startSignalR();
// Set Authorization header
originalRequest.headers["Authorization"] = `Bearer ${token}`;
return axiosClient(originalRequest);
@@ -160,4 +169,4 @@ export const api = {
// Redirect helper
function redirectToLogin() {
window.location.href = "/auth/login";
-}
\ No newline at end of file
+}