changed ui for org

This commit is contained in:
pramod.mahajan 2025-10-24 17:29:38 +05:30
parent 1372f9870a
commit 32f16092db
11 changed files with 147 additions and 67 deletions

View File

@ -19,7 +19,6 @@ import ExpenseStatus from "./ExpenseStatus";
import ExpenseByProject from "./ExpenseByProject";
const Dashboard = () => {
const { projectsCardData } = useDashboardProjectsCardData();
const { teamsCardData } = useDashboardTeamsCardData();
const { tasksCardData } = useDashboardTasksCardData();
@ -32,7 +31,7 @@ const Dashboard = () => {
<div className="row gy-4">
{isAllProjectsSelected && (
<div className="col-sm-6 col-lg-4">
<Projects projectsCardData={projectsCardData} />
<Projects />
</div>
)}

View File

@ -0,0 +1,54 @@
import React from "react";
const SkeletonLine = ({ height = 20, width = "100%", className = "" }) => (
<div
className={`skeleton ${className}`}
style={{
height,
width,
borderRadius: "4px",
background: "linear-gradient(90deg, #eee, #f5f5f5, #eee)",
backgroundSize: "200% 100%",
animation: "skeleton-loading 1.5s infinite",
}}
></div>
);
const skeletonStyle = `
@keyframes skeleton-loading {
0% { background-position: 200% 0; }
100% { background-position: -200% 0; }
}
`;
export const ProjectCardSkeleton = () => {
return (
<>
{/* Inject animation CSS once */}
<style>{skeletonStyle}</style>
<div className="card p-3 h-100 text-center d-flex justify-content-between">
{/* Header */}
<div className="d-flex justify-content-start align-items-center mb-3">
<h5 className="fw-bold mb-0 ms-2">
<i className="rounded-circle bx bx-building-house text-primary"></i>{" "}
Projects
</h5>
</div>
{/* Skeleton body */}
<div className="d-flex justify-content-around align-items-start mt-n2 w-100">
<div className="text-center">
<SkeletonLine height={28} width="60px" className="mx-auto mb-2" />
<SkeletonLine height={14} width="40px" className="mx-auto" />
</div>
<div className="text-center">
<SkeletonLine height={28} width="60px" className="mx-auto mb-2" />
<SkeletonLine height={14} width="40px" className="mx-auto" />
</div>
</div>
</div>
</>
);
};

View File

@ -1,6 +1,8 @@
import React, { useEffect } from "react";
import { useDashboardProjectsCardData } from "../../hooks/useDashboard_Data";
import eventBus from "../../services/eventBus";
import ProjectInfra from "../Project/ProjectInfra";
import { ProjectCardSkeleton } from "./DashboardSkeleton";
const Projects = () => {
const {
@ -23,7 +25,7 @@ const Projects = () => {
const totalProjects = projectsCardData?.totalProjects ?? 0;
const ongoingProjects = projectsCardData?.ongoingProjects ?? 0;
if(isLoading) return <ProjectCardSkeleton/>
return (
<div className="card p-3 h-100 text-center d-flex justify-content-between">
<div className="d-flex justify-content-start align-items-center mb-3">

View File

@ -93,10 +93,12 @@ const OrganizationsList = ({searchText}) => {
if (isError) return <div>{error?.message || "Something went wrong"}</div>;
return (
<div className="card px-0 px-sm-4 pb-12 pt-5">
<div className="card-datatable table-responsive" id="horizontal-example">
<div className="dataTables_wrapper no-footer px-2">
<table className="table border-top dataTable text-nowrap">
<div
className="card-datatable table-responsive overflow-auto"
id="horizontal-example"
>
<div className="dataTables_wrapper no-footer px-2 ">
<table className="table border-top dataTable text-nowrap">
<thead>
<tr className="table_header_border">
{organizationsColumns.map((col) => (
@ -157,7 +159,6 @@ const OrganizationsList = ({searchText}) => {
)}
</div>
</div>
</div>
);
};

View File

@ -136,7 +136,7 @@ const TenantsList = ({
);
return (
<>
<div className="p-2 mt-3">
<div className=" mt-3">
<div className=" text-nowrap table-responsive">
<table className="table border-top dataTable text-nowrap">
<thead>

View File

@ -151,7 +151,7 @@ const CollectionList = ({ fromDate, toDate, isPending, searchString }) => {
if (isError) return <p>{error.message}</p>;
return (
<div className="card ">
<div className="card px-sm-4 px-0">
<div
className="card-datatable table-responsive page-min-h"
id="horizontal-example"

View File

@ -4,7 +4,6 @@ import { formatUTCToLocalTime } from "../../utils/dateUtils";
const ViewGallery = ({ batch, index }) => {
const [loading, setLoading] = useState(true);
const [currentIndex, setCurrentIndex] = useState(index);
console.log(batch);
useEffect(() => {
setCurrentIndex(index);
}, [index, batch]);

View File

@ -13,7 +13,7 @@ const OrganizationPage = () => {
<Breadcrumb
data={[{ label: "Home", link: "/" }, { label: "Organizations" }]}
/>
<div className="card my-3 px-sm-2 px-0">
<div className="card my-3 px-sm-4 px-0">
<div className="card-body py-2 px-3">
<div className="row align-items-center">
<div className="col-6 d-flex ">
@ -42,9 +42,13 @@ const OrganizationPage = () => {
</button>
</div>
</div>
</div>
</div>
<OrganizationsList searchText={searchText} />
<div className="card page-min-h px-sm-4">
<OrganizationsList searchText={searchText} />
</div>
</div>
);

View File

@ -121,7 +121,7 @@ const TenantPage = () => {
{ label: "Tenant", link: null },
]}
/>
<div className="card text-center my-4 p-5 pb-10">
<div className="card text-center my-4 p-md-5 px-1 py-3 pb-10">
{/* Super Tenant Actions */}
{isSuperTenant && (
<div className="p-0">

View File

@ -8,35 +8,43 @@ const TenantSelectionPage = () => {
const [pendingTenant, setPendingTenant] = useState(null);
const navigate = useNavigate();
const { data, isLoading, isError, error } = useTenants();
const { data, isLoading, isError } = useTenants();
const { mutate: chooseTenant, isPending } = useSelectTenant(() => {
navigate("/dashboard");
});
const handleTenantselection = (tenantId) => {
const { mutate: handleLogout, isPending: isLogouting } = useLogout();
const handleTenantSelection = (tenantId) => {
setPendingTenant(tenantId);
localStorage.setItem("ctnt", tenantId);
chooseTenant(tenantId);
};
const {mutate:handleLogout,isPending:isLogouting} = useLogout()
// Auto-select if already stored
useEffect(() => {
if (localStorage.getItem("ctnt")) {
chooseTenant(localStorage.getItem("ctnt"))
const storedTenant = localStorage.getItem("ctnt");
if (storedTenant) {
chooseTenant(storedTenant);
}
}, [navigate]);
}, []);
// Auto-select if only one tenant
useEffect(() => {
if (!isLoading && data?.data?.length === 1) {
const tenant = data.data[0];
handleTenantselection(tenant.id);
handleTenantSelection(tenant.id);
}
}, [isLoading, data]);
if (isLoading) return <Loader />;
if (isLoading) {
// Show loader if:
// - initial loading
// - only one tenant (auto-selecting)
// - user manually selecting
if (
isLoading ||
isPending ||
(data?.data?.length === 1 && pendingTenant !== null)
) {
return <Loader />;
}
@ -48,7 +56,6 @@ const TenantSelectionPage = () => {
);
}
return (
<div className="container-fluid">
{/* Logo */}
@ -65,20 +72,24 @@ const TenantSelectionPage = () => {
<div className="text-center mb-4">
<p className="fs-4 fw-bold mb-1">Welcome</p>
<p className="fs-6 fs-md-5">
Please select which dashboard you want to explore!!!
Please select which dashboard you want to explore!
</p>
<div onClick={()=>handleLogout()}>
{isLogouting ? "Please Wait...":<span className="fs-6 fw-semibold cursor-pointer text-decoration-underline"><i className='bx bx-log-out'></i>SignOut</span>}
<div onClick={() => handleLogout()}>
{isLogouting ? (
"Please Wait..."
) : (
<span className="fs-6 fw-semibold cursor-pointer text-decoration-underline">
<i className="bx bx-log-out"></i> Sign Out
</span>
)}
</div>
</div>
{/* Card Section */}
<div className="row justify-content-center g-4 ">
{/* Tenant Cards */}
<div className="row justify-content-center g-4">
{data?.data.map((tenant) => (
<div key={tenant.id} className="col-12 col-md-10 col-lg-8">
<div className="d-flex flex-column flex-md-row gap-4 align-items-center align-items-md-start p-3 border rounded shadow-sm bg-white h-100">
{/* Image */}
<div className="flex-shrink-0 text-center">
<img
@ -95,12 +106,10 @@ const TenantSelectionPage = () => {
{/* Content */}
<div className="d-flex flex-column text-start gap-2 w-100">
{/* Title */}
<p className="fs-5 fs-md-4 text-dark fw-semibold mb-1">
{tenant?.name}
</p>
{/* Industry */}
<div className="d-flex flex-wrap gap-2 align-items-center">
<p className="fw-semibold m-0">Industry:</p>
<p className="m-0 text-muted">
@ -108,21 +117,19 @@ const TenantSelectionPage = () => {
</p>
</div>
{/* Description */}
{tenant?.description && (
<p className="text-start text-wrap text-muted small m-0">
{tenant?.description}
</p>
)}
{/* Button */}
<button
className="btn btn-primary btn-sm mt-2 align-self-start"
onClick={() => handleTenantselection(tenant?.id)}
onClick={() => handleTenantSelection(tenant?.id)}
disabled={pendingTenant === tenant.id && isPending}
>
{isPending && pendingTenant === tenant.id
? "Please Wait.."
{pendingTenant === tenant.id && isPending
? "Please Wait..."
: "Go To Dashboard"}
</button>
</div>
@ -131,8 +138,8 @@ const TenantSelectionPage = () => {
))}
</div>
</div>
);
};
export default TenantSelectionPage;
export default TenantSelectionPage;

View File

@ -82,18 +82,29 @@ const CollectionPage = () => {
const handleMarkedPayment = (payload) => {
MarkedReceived(payload);
};
if (isAdmin === undefined ||
canAddPayment === undefined ||
canEditCollection === undefined ||
canViewCollection === undefined ||
if (
isAdmin === undefined ||
canAddPayment === undefined ||
canEditCollection === undefined ||
canViewCollection === undefined ||
canCreate === undefined
) {
return <div className="text-center py-5">Checking access...</div>;
}
) {
return <div className="text-center py-5">Checking access...</div>;
}
if (!isAdmin && !canAddPayment && !canEditCollection && !canViewCollection && !canCreate) {
return <AccessDenied data={[{ label: "Home", link: "/" }, { label: "Collection" }]} />;
}
if (
!isAdmin &&
!canAddPayment &&
!canEditCollection &&
!canViewCollection &&
!canCreate
) {
return (
<AccessDenied
data={[{ label: "Home", link: "/" }, { label: "Collection" }]}
/>
);
}
return (
<CollectionContext.Provider value={contextMassager}>
<div className="container-fluid">
@ -127,28 +138,31 @@ if (!isAdmin && !canAddPayment && !canEditCollection && !canViewCollection && !c
</div>
</div>
<div className="col-12 col-md-6 d-flex justify-content-end gap-4">
<div className=" w-md-auto">
<div className="col-12 col-md-6 d-flex justify-content-between justify-content-md-end gap-4">
<div className="w-md-auto">
{" "}
<input
type="search"
value={searchText}
onChange={(e) => setSearchText(e.target.value)}
placeholder="search Collection"
placeholder="Search Collection"
className="form-control form-control-sm"
/>
</div>
{ (canCreate || isAdmin) && (
<button
className="btn btn-sm btn-primary"
type="button"
onClick={() => setCollection({ isOpen: true, invoiceId: null })}
>
<i className="bx bx-plus-circle me-2"></i>
<span className="d-none d-md-inline-block">Add New Collection</span>
</button>
)}
{(canCreate || isAdmin) && (
<button
className="btn btn-sm btn-primary"
type="button"
onClick={() =>
setCollection({ isOpen: true, invoiceId: null })
}
>
<i className="bx bx-plus-circle me-2"></i>
<span className="d-none d-md-inline-block">
Add New Collection
</span>
</button>
)}
</div>
</div>
</div>