From 4afe43d1163bf9137b2de37ef970bf0b57ec1b62 Mon Sep 17 00:00:00 2001 From: Kartik Sharma Date: Mon, 22 Sep 2025 00:09:34 +0530 Subject: [PATCH] handle one tenant have , directly move to dashboard once logged --- src/components/Dashboard/Attendance.jsx | 169 +++++------- src/components/Dashboard/AttendanceChart.jsx | 2 +- src/components/Dashboard/Projects.jsx | 70 ++--- src/components/Dashboard/Tasks.jsx | 32 ++- src/components/Dashboard/Teams.jsx | 57 ++-- src/components/Project/ProjectNav.jsx | 1 - src/components/Tenant/Profile.jsx | 4 +- src/hooks/useAuth.jsx | 9 +- src/hooks/useDashboard_Data.jsx | 259 +++++++++++------- src/pages/Activities/AttendancePage.jsx | 1 - src/pages/Tenant/SelfTenantDetails.jsx | 4 +- src/pages/Tenant/TenantPage.jsx | 8 +- src/pages/authentication/SwitchTenant.jsx | 7 +- .../authentication/TenantSelectionPage.jsx | 61 +++-- src/pages/employee/EmployeeList.jsx | 4 +- src/utils/authUtils.js | 12 - 16 files changed, 387 insertions(+), 313 deletions(-) diff --git a/src/components/Dashboard/Attendance.jsx b/src/components/Dashboard/Attendance.jsx index 168fb065..5d010acc 100644 --- a/src/components/Dashboard/Attendance.jsx +++ b/src/components/Dashboard/Attendance.jsx @@ -1,21 +1,16 @@ -import React, { useState, useEffect } from "react"; -import LineChart from "../Charts/LineChart"; +import React, { useState, useMemo } from "react"; +import ApexChart from "../Charts/Circle"; import { useProjects } from "../../hooks/useProjects"; import { useDashboard_AttendanceData } from "../../hooks/useDashboard_Data"; -import ApexChart from "../Charts/Circle"; - -const LOCAL_STORAGE_PROJECT_KEY = "selectedAttendanceProjectId"; +import { useSelectedProject } from "../../hooks/useSelectedProject"; // ✅ your custom hook const Attendance = () => { const { projects } = useProjects(); - const today = new Date().toISOString().split("T")[0]; // Format: YYYY-MM-DD + const today = new Date().toISOString().split("T")[0]; // YYYY-MM-DD const [selectedDate, setSelectedDate] = useState(today); - const storedProjectId = localStorage.getItem(LOCAL_STORAGE_PROJECT_KEY); - const initialProjectId = storedProjectId || "all"; - const [selectedProjectId, setSelectedProjectId] = useState(initialProjectId); - const [displayedProjectName, setDisplayedProjectName] = - useState("Select Project"); - const [activeTab, setActiveTab] = useState("Summary"); + + // central project selection hook +const selectedProjectId = useSelectedProject() const { dashboard_Attendancedata: AttendanceData, @@ -23,38 +18,24 @@ const Attendance = () => { error: isError, } = useDashboard_AttendanceData(selectedDate, selectedProjectId); - useEffect(() => { - if (selectedProjectId === "all") { - setDisplayedProjectName("All Projects"); - } else if (projects) { - const foundProject = projects.find((p) => p.id === selectedProjectId); - setDisplayedProjectName( - foundProject ? foundProject.name : "Select Project" - ); - } else { - setDisplayedProjectName("Select Project"); - } - - localStorage.setItem(LOCAL_STORAGE_PROJECT_KEY, selectedProjectId); + // project name derived once + const displayedProjectName = useMemo(() => { + if (selectedProjectId === "all") return "All Projects"; + const found = projects?.find((p) => p.id === selectedProjectId); + return found?.name || "Select Project"; }, [selectedProjectId, projects]); - const handleProjectSelect = (projectId) => { - setSelectedProjectId(projectId); - }; - - const handleDateChange = (e) => { - setSelectedDate(e.target.value); - }; - return (
-
-
+ {/* Header */} +
+
Attendance

Daily Attendance Data

+ {/* Project Dropdown */}
@@ -77,7 +58,7 @@ const Attendance = () => {
  • @@ -88,52 +69,43 @@ const Attendance = () => {
  • -
    - {/* Tabs */} -
    -
      -
    • - -
    • -
    • - -
    • -
    -
    - {/* ✅ Date Picker Aligned Left with Padding */} -
    -
    - -
    + {/* Tabs + Date Picker */} +
    +
      +
    • + +
    • +
    • + +
    • +
    +
    + setSelectedDate(e.target.value)} + />
    + {/* Body */}
    - {activeTab === "Summary" && ( + {/* Summary */} + {AttendanceData?.activeTab === "Summary" && (
    {isLoading ? ( @@ -143,7 +115,7 @@ const Attendance = () => { ) : ( AttendanceData && ( <> -
    +
    Attendance

    @@ -164,11 +136,9 @@ const Attendance = () => {

    )} - {activeTab === "Details" && ( -
    + {/* Details */} + {AttendanceData?.activeTab === "Details" && ( +
    @@ -178,32 +148,17 @@ const Attendance = () => { - {AttendanceData?.attendanceTable && - AttendanceData.attendanceTable.length > 0 ? ( - AttendanceData.attendanceTable.map((record, index) => ( - - - - + {AttendanceData?.attendanceTable?.length ? ( + AttendanceData.attendanceTable.map((r, i) => ( + + + + )) ) : ( - + )} diff --git a/src/components/Dashboard/AttendanceChart.jsx b/src/components/Dashboard/AttendanceChart.jsx index 3879c0e4..67950d9a 100644 --- a/src/components/Dashboard/AttendanceChart.jsx +++ b/src/components/Dashboard/AttendanceChart.jsx @@ -132,7 +132,7 @@ const AttendanceOverview = () => { onClick={() => setView("table")} title="Table View" > - + diff --git a/src/components/Dashboard/Projects.jsx b/src/components/Dashboard/Projects.jsx index 0be20321..86958aa5 100644 --- a/src/components/Dashboard/Projects.jsx +++ b/src/components/Dashboard/Projects.jsx @@ -1,33 +1,28 @@ -import React, { useCallback, useEffect, useState } from "react"; +import React, { useEffect } from "react"; import { useDashboardProjectsCardData } from "../../hooks/useDashboard_Data"; import eventBus from "../../services/eventBus"; -import GlobalRepository from "../../repositories/GlobalRepository"; const Projects = () => { - const { projectsCardData } = useDashboardProjectsCardData(); - const [projectData, setProjectsData] = useState(projectsCardData); + const { + data: projectsCardData, + isLoading, + isError, + error, + refetch, + } = useDashboardProjectsCardData(); useEffect(() => { - setProjectsData(projectsCardData); - }, [projectsCardData]); + // When "project" event happens, just refetch + const handler = () => { + refetch(); + }; - const handler = useCallback( - async (msg) => { - try { - const response = - await GlobalRepository.getDashboardProjectsCardData(); - setProjectsData(response.data); - } catch (err) { - console.error(err); - } - }, - [GlobalRepository] - ); - - useEffect(() => { eventBus.on("project", handler); return () => eventBus.off("project", handler); - }, [handler]); + }, [refetch]); + + const totalProjects = projectsCardData?.totalProjects ?? 0; + const ongoingProjects = projectsCardData?.ongoingProjects ?? 0; return (
    @@ -37,20 +32,29 @@ const Projects = () => { Projects
    -
    -
    -

    - {projectData.totalProjects?.toLocaleString()} -

    - Total + + {isLoading ? ( +
    +
    + Loading... +
    -
    -

    - {projectData.ongoingProjects?.toLocaleString()} -

    - Ongoing + ) : isError ? ( +
    + {error?.message || "Error loading data"}
    -
    + ) : ( +
    +
    +

    {totalProjects.toLocaleString()}

    + Total +
    +
    +

    {ongoingProjects.toLocaleString()}

    + Ongoing +
    +
    + )}
    ); }; diff --git a/src/components/Dashboard/Tasks.jsx b/src/components/Dashboard/Tasks.jsx index 2513e061..56eb00f0 100644 --- a/src/components/Dashboard/Tasks.jsx +++ b/src/components/Dashboard/Tasks.jsx @@ -1,10 +1,16 @@ import React from "react"; -import { useSelector } from "react-redux"; +import { useSelectedProject } from "../../slices/apiDataManager"; import { useDashboardTasksCardData } from "../../hooks/useDashboard_Data"; const TasksCard = () => { - const projectId = useSelector((store) => store.localVariables?.projectId); - const { tasksCardData, loading, error } = useDashboardTasksCardData(projectId); + const projectId = useSelectedProject(); + + const { + data: tasksCardData, + isLoading, + isError, + error, + } = useDashboardTasksCardData(projectId); return (
    @@ -14,28 +20,30 @@ const TasksCard = () => {
    - {loading ? ( - // Loader will be displayed when loading is true + {isLoading ? ( + // Loader while fetching
    Loading...
    - ) : error ? ( - // Error message if there's an error -
    {error}
    + ) : isError ? ( + // Show error +
    + {error?.message || "Error loading data"} +
    ) : ( - // Actual data when loaded successfully + // Show data

    - {tasksCardData?.totalTasks?.toLocaleString()} + {tasksCardData?.totalTasks?.toLocaleString() ?? 0}

    Total

    - {tasksCardData?.completedTasks?.toLocaleString()} + {tasksCardData?.completedTasks?.toLocaleString() ?? 0}

    Completed
    @@ -45,4 +53,4 @@ const TasksCard = () => { ); }; -export default TasksCard; \ No newline at end of file +export default TasksCard; diff --git a/src/components/Dashboard/Teams.jsx b/src/components/Dashboard/Teams.jsx index 00e881f5..9e9d31f9 100644 --- a/src/components/Dashboard/Teams.jsx +++ b/src/components/Dashboard/Teams.jsx @@ -1,33 +1,45 @@ -import React, { useCallback, useEffect, useState } from "react"; +import React, { useCallback, useEffect } from "react"; import { useSelector } from "react-redux"; import { useDashboardTeamsCardData } from "../../hooks/useDashboard_Data"; import eventBus from "../../services/eventBus"; +import { useQueryClient } from "@tanstack/react-query"; +import { useSelectedProject } from "../../slices/apiDataManager"; const Teams = () => { - const projectId = useSelector((store) => store.localVariables?.projectId); - const { teamsCardData, loading, error } = useDashboardTeamsCardData(projectId); + const queryClient = useQueryClient(); + const projectId = useSelectedProject() - const [totalEmployees, setTotalEmployee] = useState(0); - const [inToday, setInToday] = useState(0); - - // Update state when API data arrives - useEffect(() => { - setTotalEmployee(teamsCardData?.totalEmployees || 0); - setInToday(teamsCardData?.inToday || 0); - }, [teamsCardData]); + const { + data: teamsCardData, + isLoading, + isError, + error, + } = useDashboardTeamsCardData(projectId); // Handle real-time updates via eventBus - const handler = useCallback((msg) => { - if (msg.activity === 1) { - setInToday((prev) => prev + 1); - } - }, []); + const handler = useCallback( + (msg) => { + if (msg.activity === 1) { + queryClient.setQueryData(["dashboardTeams", projectId], (old) => { + if (!old) return old; + return { + ...old, + inToday: (old.inToday || 0) + 1, + }; + }); + } + }, + [queryClient, projectId] + ); useEffect(() => { eventBus.on("attendance", handler); return () => eventBus.off("attendance", handler); }, [handler]); + const inToday = teamsCardData?.inToday ?? 0; + const totalEmployees = teamsCardData?.totalEmployees ?? 0; + return (
    @@ -36,18 +48,17 @@ const Teams = () => {
    - {loading ? ( - // Blue spinner loader + {isLoading ? (
    Loading...
    - ) : error ? ( - // Error message if data fetching fails -
    {error}
    + ) : isError ? ( +
    + {error?.message || "Error loading data"} +
    ) : ( - // Display data once loaded

    {totalEmployees.toLocaleString()}

    @@ -63,4 +74,4 @@ const Teams = () => { ); }; -export default Teams; \ No newline at end of file +export default Teams; diff --git a/src/components/Project/ProjectNav.jsx b/src/components/Project/ProjectNav.jsx index 43ba0795..f7c1ad06 100644 --- a/src/components/Project/ProjectNav.jsx +++ b/src/components/Project/ProjectNav.jsx @@ -1,5 +1,4 @@ import React from "react"; -import { hasUserPermission } from "../../utils/authUtils"; import { useHasUserPermission } from "../../hooks/useHasUserPermission"; import { DIRECTORY_ADMIN, diff --git a/src/components/Tenant/Profile.jsx b/src/components/Tenant/Profile.jsx index 50cd99a4..963f6ce3 100644 --- a/src/components/Tenant/Profile.jsx +++ b/src/components/Tenant/Profile.jsx @@ -5,12 +5,12 @@ import GlobalModel from "../common/GlobalModel"; import { useTenantContext } from "../../pages/Tenant/TenantPage"; import { useTenantDetailsContext } from "../../pages/Tenant/TenantDetails"; import IconButton from "../common/IconButton"; -import { hasUserPermission } from "../../utils/authUtils"; import { MANAGE_TENANTS } from "../../utils/constants"; +import { useHasUserPermission } from "../../hooks/useHasUserPermission"; const Profile = ({ data }) => { const {setEditTenant} = useTenantDetailsContext() - const canUpdateTenant = hasUserPermission(MANAGE_TENANTS) + const canUpdateTenant = useHasUserPermission(MANAGE_TENANTS) return ( <>
    diff --git a/src/hooks/useAuth.jsx b/src/hooks/useAuth.jsx index 570e0454..2790558d 100644 --- a/src/hooks/useAuth.jsx +++ b/src/hooks/useAuth.jsx @@ -28,13 +28,18 @@ export const useSelectTenant = (onSuccessCallBack) => { const res = await AuthRepository.selectTenant(tenantId); return res.data; }, + onSuccess: (data) => { - localStorage.setItem("ltkn", data.token); - localStorage.setItem("rtkn", data.refreshToken); + localStorage.setItem("jwtToken", data.token); + localStorage.setItem("refreshToken", data.refreshToken); if (onSuccessCallBack) onSuccessCallBack(); }, + onError: (error) => { showToast(error.message || "Error while creating project", "error"); + localStorage.removeItem("jwtToken"); + localStorage.removeItem("refreshToken") + localStorage.removeItem("ctnt") }, }); }; diff --git a/src/hooks/useDashboard_Data.jsx b/src/hooks/useDashboard_Data.jsx index 0322566a..b9c393b7 100644 --- a/src/hooks/useDashboard_Data.jsx +++ b/src/hooks/useDashboard_Data.jsx @@ -1,7 +1,8 @@ import { useState, useEffect } from "react"; import GlobalRepository from "../repositories/GlobalRepository"; +import { useQuery } from "@tanstack/react-query"; + -// 🔹 Dashboard Progression Data Hook export const useDashboard_Data = ({ days, FromDate, projectId }) => { const [dashboard_data, setDashboard_Data] = useState([]); const [isLineChartLoading, setLoading] = useState(false); @@ -38,120 +39,120 @@ export const useDashboard_Data = ({ days, FromDate, projectId }) => { }; -export const useDashboard_AttendanceData = (date, projectId) => { - const [dashboard_Attendancedata, setDashboard_AttendanceData] = useState([]); - const [isLineChartLoading, setLoading] = useState(false); - const [error, setError] = useState(""); +// export const useDashboard_AttendanceData = (date, projectId) => { +// const [dashboard_Attendancedata, setDashboard_AttendanceData] = useState([]); +// const [isLineChartLoading, setLoading] = useState(false); +// const [error, setError] = useState(""); - useEffect(() => { - const fetchData = async () => { - setLoading(true); - setError(""); +// useEffect(() => { +// const fetchData = async () => { +// setLoading(true); +// setError(""); - try { - const response = await GlobalRepository.getDashboardAttendanceData(date, projectId); // date in 2nd param - setDashboard_AttendanceData(response.data); - } catch (err) { - setError("Failed to fetch dashboard data."); - console.error(err); - } finally { - setLoading(false); - } - }; +// try { +// const response = await GlobalRepository.getDashboardAttendanceData(date, projectId); // date in 2nd param +// setDashboard_AttendanceData(response.data); +// } catch (err) { +// setError("Failed to fetch dashboard data."); +// console.error(err); +// } finally { +// setLoading(false); +// } +// }; - if (date && projectId !== null) { - fetchData(); - } - }, [date, projectId]); +// if (date && projectId !== null) { +// fetchData(); +// } +// }, [date, projectId]); - return { dashboard_Attendancedata, isLineChartLoading: isLineChartLoading, error }; -}; +// return { dashboard_Attendancedata, isLineChartLoading: isLineChartLoading, error }; +// }; // 🔹 Dashboard Projects Card Data Hook -export const useDashboardProjectsCardData = () => { - const [projectsCardData, setProjectsData] = useState([]); - const [loading, setLoading] = useState(false); - const [error, setError] = useState(""); +// export const useDashboardProjectsCardData = () => { +// const [projectsCardData, setProjectsData] = useState([]); +// const [loading, setLoading] = useState(false); +// const [error, setError] = useState(""); - useEffect(() => { - const fetchProjectsData = async () => { - setLoading(true); - setError(""); +// useEffect(() => { +// const fetchProjectsData = async () => { +// setLoading(true); +// setError(""); - try { - const response = await GlobalRepository.getDashboardProjectsCardData(); - setProjectsData(response.data); - } catch (err) { - setError("Failed to fetch projects card data."); - console.error(err); - } finally { - setLoading(false); - } - }; +// try { +// const response = await GlobalRepository.getDashboardProjectsCardData(); +// setProjectsData(response.data); +// } catch (err) { +// setError("Failed to fetch projects card data."); +// console.error(err); +// } finally { +// setLoading(false); +// } +// }; - fetchProjectsData(); - }, []); +// fetchProjectsData(); +// }, []); - return { projectsCardData, loading, error }; -}; +// return { projectsCardData, loading, error }; +// }; // 🔹 Dashboard Teams Card Data Hook -export const useDashboardTeamsCardData = (projectId) => { - const [teamsCardData, setTeamsData] = useState({}); - const [loading, setLoading] = useState(false); - const [error, setError] = useState(""); +// export const useDashboardTeamsCardData = (projectId) => { +// const [teamsCardData, setTeamsData] = useState({}); +// const [loading, setLoading] = useState(false); +// const [error, setError] = useState(""); - useEffect(() => { - const fetchTeamsData = async () => { - setLoading(true); - setError(""); +// useEffect(() => { +// const fetchTeamsData = async () => { +// setLoading(true); +// setError(""); - try { - const response = await GlobalRepository.getDashboardTeamsCardData(projectId); - setTeamsData(response.data || {}); - } catch (err) { - setError("Failed to fetch teams card data."); - console.error("Error fetching teams card data:", err); - setTeamsData({}); - } finally { - setLoading(false); - } - }; +// try { +// const response = await GlobalRepository.getDashboardTeamsCardData(projectId); +// setTeamsData(response.data || {}); +// } catch (err) { +// setError("Failed to fetch teams card data."); +// console.error("Error fetching teams card data:", err); +// setTeamsData({}); +// } finally { +// setLoading(false); +// } +// }; - fetchTeamsData(); - }, [projectId]); +// fetchTeamsData(); +// }, [projectId]); - return { teamsCardData, loading, error }; -}; +// return { teamsCardData, loading, error }; +// }; -export const useDashboardTasksCardData = (projectId) => { - const [tasksCardData, setTasksData] = useState({}); - const [loading, setLoading] = useState(false); - const [error, setError] = useState(""); +// export const useDashboardTasksCardData = (projectId) => { +// const [tasksCardData, setTasksData] = useState({}); +// const [loading, setLoading] = useState(false); +// const [error, setError] = useState(""); - useEffect(() => { - const fetchTasksData = async () => { - setLoading(true); - setError(""); +// useEffect(() => { +// const fetchTasksData = async () => { +// setLoading(true); +// setError(""); - try { - const response = await GlobalRepository.getDashboardTasksCardData(projectId); - setTasksData(response.data); - } catch (err) { - setError("Failed to fetch tasks card data."); - console.error(err); - setTasksData({}); - } finally { - setLoading(false); - } - }; +// try { +// const response = await GlobalRepository.getDashboardTasksCardData(projectId); +// setTasksData(response.data); +// } catch (err) { +// setError("Failed to fetch tasks card data."); +// console.error(err); +// setTasksData({}); +// } finally { +// setLoading(false); +// } +// }; - fetchTasksData(); - }, [projectId]); +// fetchTasksData(); +// }, [projectId]); - return { tasksCardData, loading, error }; -}; +// return { tasksCardData, loading, error }; +// }; export const useAttendanceOverviewData = (projectId, days) => { @@ -180,3 +181,75 @@ export const useAttendanceOverviewData = (projectId, days) => { return { attendanceOverviewData, loading, error }; }; + + +// -------------------Query---------------------------- + +// export const useDashboard_Data = (days, FromDate, projectId)=>{ +// return useQuery({ +// queryKey:["dashboardProjectProgress"], +// queryFn:async()=> { +// const payload = { +// days, +// FromDate: FromDate || '', +// projectId: projectId || null, +// }; +// const resp = await GlobalRepository.getDashboardProgressionData(payload); +// return resp.data; +// } +// }) +// } + +export const useDashboard_AttendanceData = (date,projectId)=>{ + return useQuery({ + queryKey:["dashboardAttendances",date,projectId], + queryFn:async()=> { + + const resp = await await GlobalRepository.getDashboardAttendanceData(date, projectId) + return resp.data; + } + }) +} + +export const useDashboardTeamsCardData =(projectId)=>{ + return useQuery({ + queryKey:["dashboardTeams",projectId], + queryFn:async()=> { + + const resp = await GlobalRepository.getDashboardTeamsCardData(projectId) + return resp.data; + } + }) +} + +export const useDashboardTasksCardData = (projectId) => { + return useQuery({ + queryKey:["dashboardTasks",projectId], + queryFn:async()=> { + + const resp = await GlobalRepository.getDashboardTasksCardData(projectId) + return resp.data; + } + }) +} +// export const useAttendanceOverviewData = (projectId, days) => { +// return useQuery({ +// queryKey:["dashboardAttendanceOverView",projectId], +// queryFn:async()=> { + +// const resp = await GlobalRepository.getAttendanceOverview(projectId, days); +// return resp.data; +// } +// }) +// } + +export const useDashboardProjectsCardData = () => { + return useQuery({ + queryKey:["dashboardProjects"], + queryFn:async()=> { + + const resp = await GlobalRepository.getDashboardProjectsCardData(); + return resp.data; + } + }) +} \ No newline at end of file diff --git a/src/pages/Activities/AttendancePage.jsx b/src/pages/Activities/AttendancePage.jsx index cef91843..5c88d1ee 100644 --- a/src/pages/Activities/AttendancePage.jsx +++ b/src/pages/Activities/AttendancePage.jsx @@ -13,7 +13,6 @@ import Regularization from "../../components/Activities/Regularization"; import { useAttendance } from "../../hooks/useAttendance"; import { useDispatch, useSelector } from "react-redux"; import { setProjectId } from "../../slices/localVariablesSlice"; -import { hasUserPermission } from "../../utils/authUtils"; import { useHasUserPermission } from "../../hooks/useHasUserPermission"; import { REGULARIZE_ATTENDANCE } from "../../utils/constants"; import eventBus from "../../services/eventBus"; diff --git a/src/pages/Tenant/SelfTenantDetails.jsx b/src/pages/Tenant/SelfTenantDetails.jsx index 5375bcc3..ea4b107d 100644 --- a/src/pages/Tenant/SelfTenantDetails.jsx +++ b/src/pages/Tenant/SelfTenantDetails.jsx @@ -1,16 +1,16 @@ import React, { useEffect, useMemo } from "react"; import { useProfile } from "../../hooks/useProfile"; import TenantDetails from "./TenantDetails"; -import { hasUserPermission } from "../../utils/authUtils"; import { VIEW_TENANTS } from "../../utils/constants"; import { useNavigate } from "react-router-dom"; import Loader from "../../components/common/Loader"; +import { useHasUserPermission } from "../../hooks/useHasUserPermission"; const SelfTenantDetails = () => { const { profile, loading } = useProfile(); const tenantId = profile?.employeeInfo?.tenantId; const navigate = useNavigate(); - const isSelfTenantView = hasUserPermission(VIEW_TENANTS); + const isSelfTenantView = useHasUserPermission(VIEW_TENANTS); useEffect(() => { if (!isSelfTenantView) { diff --git a/src/pages/Tenant/TenantPage.jsx b/src/pages/Tenant/TenantPage.jsx index ef33efbf..640c8fc2 100644 --- a/src/pages/Tenant/TenantPage.jsx +++ b/src/pages/Tenant/TenantPage.jsx @@ -20,7 +20,6 @@ import TenantFilterPanel from "../../components/Tenant/TenantFilterPanel"; import { useDebounce } from "../../utils/appUtils"; import { useFab } from "../../Context/FabContext"; import { setCurrentTenant } from "../../slices/globalVariablesSlice"; -import { hasUserPermission } from "../../utils/authUtils"; // ------ Schema ------- import { @@ -35,6 +34,7 @@ import { VIEW_TENANTS, } from "../../utils/constants"; import { useProfile } from "../../hooks/useProfile"; +import { useHasUserPermission } from "../../hooks/useHasUserPermission"; // ---------- Context ---------- export const TenantContext = createContext(); @@ -63,9 +63,9 @@ const TenantPage = () => { const debouncedSearch = useDebounce(searchText, 500); const { setOffcanvasContent, setShowTrigger } = useFab(); - const isSuperTenant = hasUserPermission(SUPPER_TENANT); - const canManageTenants = hasUserPermission(MANAGE_TENANTS); - const isSelfTenant = hasUserPermission(VIEW_TENANTS); + const isSuperTenant = useHasUserPermission(SUPPER_TENANT); + const canManageTenants = useHasUserPermission(MANAGE_TENANTS); + const isSelfTenant = useHasUserPermission(VIEW_TENANTS); const methods = useForm({ resolver: zodResolver(filterSchema), diff --git a/src/pages/authentication/SwitchTenant.jsx b/src/pages/authentication/SwitchTenant.jsx index e36ede07..e07a3416 100644 --- a/src/pages/authentication/SwitchTenant.jsx +++ b/src/pages/authentication/SwitchTenant.jsx @@ -4,6 +4,7 @@ import { useAuthModal, useSelectTenant, useTenants } from "../../hooks/useAuth"; import { useProfile } from "../../hooks/useProfile"; import { useQueryClient } from "@tanstack/react-query"; import AuthRepository from "../../repositories/AuthRepository"; +import Loader from "../../components/common/Loader"; const SwitchTenant = () => { const queryClient = useQueryClient(); @@ -27,6 +28,8 @@ const SwitchTenant = () => { localStorage.setItem("ctnt", tenantId); chooseTenant(tenantId); }; + + const contentBody = (

    Switch Workplace

    @@ -82,7 +85,7 @@ const SwitchTenant = () => {
    ); - return ; + return :contentBody} />; }; export default SwitchTenant; \ No newline at end of file diff --git a/src/pages/authentication/TenantSelectionPage.jsx b/src/pages/authentication/TenantSelectionPage.jsx index 5e748548..39318820 100644 --- a/src/pages/authentication/TenantSelectionPage.jsx +++ b/src/pages/authentication/TenantSelectionPage.jsx @@ -2,6 +2,7 @@ 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"; +import Loader from "../../components/common/Loader.jsx"; const TenantSelectionPage = () => { const [pendingTenant, setPendingTenant] = useState(null); @@ -19,26 +20,48 @@ const TenantSelectionPage = () => { useEffect(() => { if (localStorage.getItem("ctnt")) { - return navigate("/dashboard"); + navigate("/dashboard"); } - }, []); + }, [navigate]); + + useEffect(() => { + if (!isLoading && data?.data?.length === 1) { + const tenant = data.data[0]; + handleTenantselection(tenant.id); + } + }, [isLoading, data]); + + if (isLoading) return ; if (isLoading) { + return ; + } + + if (!data?.data?.length) { return ( -
    -
    - Loading tenants... -
    +
    +

    No tenant assigned to your account.

    ); } + return (
    - {/* Header */} + {/* Logo */} +
    + marco-logo +
    + + {/* Heading */}
    -

    Welcome

    -

    +

    Welcome

    +

    Please select which dashboard you want to explore!!!

    @@ -47,40 +70,45 @@ const TenantSelectionPage = () => {
    {data?.data.map((tenant) => (
    -
    +
    + {/* Image */}
    {tenant.name}
    {/* Content */} -
    -

    +

    + {/* Title */} +

    {tenant?.name}

    + {/* Industry */}

    Industry:

    -

    +

    {tenant?.industry?.name || "Not Available"}

    + {/* Description */} {tenant?.description && ( -

    +

    {tenant?.description}

    )} + {/* Button */}
    + ); }; diff --git a/src/pages/employee/EmployeeList.jsx b/src/pages/employee/EmployeeList.jsx index 648b736b..b0f10a75 100644 --- a/src/pages/employee/EmployeeList.jsx +++ b/src/pages/employee/EmployeeList.jsx @@ -11,7 +11,7 @@ import { } from "../../hooks/useEmployees"; import { useProjectName, useProjects } from "../../hooks/useProjects"; import { useProfile } from "../../hooks/useProfile"; -import { hasUserPermission } from "../../utils/authUtils"; + import { ITEMS_PER_PAGE, MANAGE_EMPLOYEES, @@ -19,7 +19,6 @@ import { VIEW_TEAM_MEMBERS, } from "../../utils/constants"; import { clearCacheKey } from "../../slices/apiDataManager"; -import { useHasUserPermission } from "../../hooks/useHasUserPermission"; import SuspendEmp from "../../components/Employee/SuspendEmp"; // Keep if you use SuspendEmp import { exportToCSV, @@ -36,6 +35,7 @@ import { newlineChars } from "pdf-lib"; import GlobalModel from "../../components/common/GlobalModel"; import usePagination from "../../hooks/usePagination"; import { setProjectId } from "../../slices/localVariablesSlice"; +import { useHasUserPermission } from "../../hooks/useHasUserPermission"; const EmployeeList = () => { const selectedProjectId = useSelector( diff --git a/src/utils/authUtils.js b/src/utils/authUtils.js index 1dd5c055..e69de29b 100644 --- a/src/utils/authUtils.js +++ b/src/utils/authUtils.js @@ -1,12 +0,0 @@ -import { useProfile } from "../hooks/useProfile"; - -export const hasUserPermission = (permission) => { - const { profile } = useProfile(); - if (profile) { - if (!permission || typeof permission !== "string") { - return false; - } - return profile?.featurePermissions.includes(permission); - } - return false; -};
    - {record.firstName} {record.lastName} - - {new Date(record.inTime).toLocaleTimeString([], { - hour: "2-digit", - minute: "2-digit", - })} - - {new Date(record.outTime).toLocaleTimeString([], { - hour: "2-digit", - minute: "2-digit", - })} -
    {r.firstName} {r.lastName}{r.inTime ? new Date(r.inTime).toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" }) : "-"}{r.outTime ? new Date(r.outTime).toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" }) : "-"}
    - No attendance data available - No attendance data available