111 lines
3.5 KiB
JavaScript
111 lines
3.5 KiB
JavaScript
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>
|
|
</>
|
|
);
|
|
};
|
|
|
|
export const TeamsSkeleton = () => {
|
|
return (
|
|
<>
|
|
<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="bx bx-group text-warning"></i> Teams
|
|
</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="90px" className="mx-auto" />
|
|
</div>
|
|
<div className="text-center">
|
|
<SkeletonLine height={28} width="60px" className="mx-auto mb-2" />
|
|
<SkeletonLine height={14} width="70px" className="mx-auto" />
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</>
|
|
);
|
|
};
|
|
export const TasksSkeleton = () => {
|
|
return (
|
|
<>
|
|
<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="bx bx-task text-success"></i> Tasks
|
|
</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="70px" className="mx-auto" />
|
|
</div>
|
|
<div className="text-center">
|
|
<SkeletonLine height={28} width="60px" className="mx-auto mb-2" />
|
|
<SkeletonLine height={14} width="90px" className="mx-auto" />
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</>
|
|
);
|
|
};
|