diff --git a/src/components/Tenanat/TenanatSkeleton.jsx b/src/components/Tenanat/TenanatSkeleton.jsx new file mode 100644 index 00000000..9d48529e --- /dev/null +++ b/src/components/Tenanat/TenanatSkeleton.jsx @@ -0,0 +1,97 @@ +import React from "react"; + +const SkeletonCell = ({ width = "100%", height = 20, style = {} }) => ( +
+); + +export const TenantTableSkeleton = ({ columns, rows = 5 }) => { + return ( +
+
+ + + + {columns.map((col) => ( + + ))} + + + + {[...Array(rows)].map((_, rowIdx) => ( + + {columns.map((col, colIdx) => ( + + ))} + + ))} + +
+
{col.label}
+
+ {/* Icon + text skeleton for first few columns */} + {col.key === "name" && ( +
+
+ +
+ )} + {col.key === "domainName" && ( +
+
+ +
+ )} + {col.key === "contactName" && ( +
+
+ +
+ )} + {col.key === "contactNumber" && ( + + )} + {col.key === "status" && ( + + )} +
+
+
+ ); +}; diff --git a/src/components/Tenanat/TenantsList.jsx b/src/components/Tenanat/TenantsList.jsx index aa79c9e1..ed8bafa8 100644 --- a/src/components/Tenanat/TenantsList.jsx +++ b/src/components/Tenanat/TenantsList.jsx @@ -1,31 +1,38 @@ -import React, { useState } from "react"; +import React, { useEffect, useState } from "react"; import { useTenants } from "../../hooks/useTenant"; import { ITEMS_PER_PAGE } from "../../utils/constants"; import { getTenantStatus } from "../../utils/dateUtils"; import IconButton from "../common/IconButton"; import Pagination from "../common/Pagination"; +import { TenantTableSkeleton } from "./TenanatSkeleton"; +import { useTenantContext } from "../../pages/Tenant/TenantPage"; -const TenantsList = ({searchText}) => { +const TenantsList = ({searchText,setIsRefetching, setRefetchFn}) => { const [currentPage, setCurrentPage] = useState(1); - const { data, isLoading, isError, isInitialLoading, error } = useTenants( + const { data, isLoading, isError, isInitialLoading, error,refetch, isFetching } = useTenants( currentPage, {}, searchText, ); + const {setRefetching} = useTenantContext() + const paginate = (page) => { if (page >= 1 && page <= (data?.totalPages ?? 1)) { setCurrentPage(page); } }; - if (isInitialLoading) - return ( -
-

Loading...

-
- ); - if (isError) return
{error.message}
; + + // Pass the refetch function to parent when component mounts + useEffect(() => { + setRefetchFn(() => refetch); // store in parent + }, [setRefetchFn, refetch]); + + // Sync fetching status with parent + useEffect(() => { + setIsRefetching(isFetching); + }, [isFetching, setIsRefetching]); const TenantColumns = [ { @@ -60,7 +67,7 @@ const TenantsList = ({searchText}) => { key: "contactName", label: "Contact Person", getValue: (t) => ( -
+
{t.contactName || "N/A"}
@@ -86,16 +93,21 @@ const TenantsList = ({searchText}) => { {t.tenantStatus?.name || "Unknown"} ), + align:"text-center" }, ]; - + if (isInitialLoading) + return ( + + ); + if (isError) return
{error.message}
; return ( <>
- + {TenantColumns.map((col) => ( diff --git a/src/pages/Tenant/TenantPage.jsx b/src/pages/Tenant/TenantPage.jsx index aecce42f..3ead3600 100644 --- a/src/pages/Tenant/TenantPage.jsx +++ b/src/pages/Tenant/TenantPage.jsx @@ -1,6 +1,6 @@ -import React, { useState, createContext, useEffect } from "react"; +import React, { useState, createContext, useEffect, useContext } from "react"; import { useForm } from "react-hook-form"; -import { zodResolver } from "@hookform/resolvers/zod"; +import { zodResolver } from "@hookform/resolvers/zod"; // ------Components------- import Breadcrumb from "../../components/common/Breadcrumb"; import TenantsList from "../../components/Tenanat/TenantsList"; @@ -9,11 +9,13 @@ import { useDebounce } from "../../utils/appUtils"; import { useFab } from "../../Context/FabContext"; //---------- Schema and defaultValues---- -import { defaultFilterValues, filterSchema } from "../../components/Tenanat/TenantSchema"; +import { + defaultFilterValues, + filterSchema, +} from "../../components/Tenanat/TenantSchema"; import TenantFilterPanel from "../../components/Tenanat/TenantFilterPanel"; - -// This is context that wrapping all components tenant releated , but must pass inside 'TenantContext.Provider' +// This is context that wrapping all components tenant releated , but must pass inside 'TenantContext.Provider' export const TenantContext = createContext(); export const useTenantContext = () => { const context = useContext(TenantContext); @@ -25,22 +27,20 @@ export const useTenantContext = () => { const TenantPage = () => { const [searchText, setSearchText] = useState(""); + const [isRefetching,setRefetching] = useState(false) + const [refetchFn, setRefetchFn] = useState(null); const debouncedSearch = useDebounce(searchText, 500); - const contextValue = {}; + const contextValue = { + }; const navigate = useNavigate(); - const { setOffcanvasContent, setShowTrigger } = useFab(); + // This Hook allow us to right-side bar for filter Tenants - // This Hook allow us to right-side bar for filter Tenants - - useEffect(() => { + useEffect(() => { setShowTrigger(true); - setOffcanvasContent( - "Expense Filters", - - ); + setOffcanvasContent("Tenant Filters", ); return () => { setShowTrigger(false); setOffcanvasContent("", null); @@ -63,13 +63,17 @@ const TenantPage = () => { setSearchText(e.target.value)} + onChange={(e)=>setSearchText(e.target.value)} className="form-control form-control-sm" placeholder="Search..." /> -
+
+ refetchFn && refetchFn()}> + Refresh + +
- + ); diff --git a/src/utils/constants.jsx b/src/utils/constants.jsx index 87fe1719..2364bc8e 100644 --- a/src/utils/constants.jsx +++ b/src/utils/constants.jsx @@ -1,6 +1,6 @@ export const THRESH_HOLD = 48; // hours -export const DURATION_TIME = 20; // minutes -export const ITEMS_PER_PAGE = 10; +export const DURATION_TIME = 10; // minutes +export const ITEMS_PER_PAGE = 20; export const OTP_EXPIRY_SECONDS = 600 // OTP time export const MANAGE_MASTER = "588a8824-f924-4955-82d8-fc51956cf323";
{col.label}
@@ -125,7 +137,7 @@ const TenantsList = ({searchText}) => {
No Tenants Found