Refactor Assets component to streamline category fetching and enhance loading state handling; improve SkeletonUI styles for better asset representation
This commit is contained in:
parent
980d27c91f
commit
59a3cb4704
|
@ -90,24 +90,7 @@ const Assets: React.FC = () => {
|
|||
|
||||
useEffect(() => {
|
||||
setCategoryList([
|
||||
{
|
||||
assetName: "Doors",
|
||||
assetImage: "",
|
||||
category: "Feneration",
|
||||
categoryImage: feneration,
|
||||
},
|
||||
{
|
||||
assetName: "Windows",
|
||||
assetImage: "",
|
||||
category: "Feneration",
|
||||
categoryImage: feneration,
|
||||
},
|
||||
{
|
||||
assetName: "Pillars",
|
||||
assetImage: "",
|
||||
category: "Feneration",
|
||||
categoryImage: feneration,
|
||||
},
|
||||
{ category: "Fenestration", categoryImage: feneration },
|
||||
{ category: "Vehicles", categoryImage: vehicle },
|
||||
{ category: "Workstation", categoryImage: workStation },
|
||||
{ category: "Machines", categoryImage: machines },
|
||||
|
@ -121,44 +104,15 @@ const Assets: React.FC = () => {
|
|||
const fetchCategoryAssets = async (asset: any) => {
|
||||
setisLoading(true);
|
||||
setSelectedCategory(asset);
|
||||
if (asset === "Feneration") {
|
||||
const localAssets: AssetProp[] = [
|
||||
{
|
||||
filename: "arch",
|
||||
category: "Feneration",
|
||||
url: arch,
|
||||
thumbnail: archThumbnail,
|
||||
tags: "arch",
|
||||
},
|
||||
{
|
||||
filename: "door",
|
||||
category: "Feneration",
|
||||
url: door,
|
||||
thumbnail: feneration,
|
||||
tags: "door",
|
||||
},
|
||||
{
|
||||
filename: "window",
|
||||
category: "Feneration",
|
||||
url: window,
|
||||
thumbnail: windowThumbnail,
|
||||
tags: "window",
|
||||
},
|
||||
];
|
||||
setCategoryAssets(localAssets);
|
||||
setFiltereredAssets(localAssets);
|
||||
try {
|
||||
const res = await getCategoryAsset(asset);
|
||||
setCategoryAssets(res);
|
||||
setFiltereredAssets(res);
|
||||
setisLoading(false); // End loading
|
||||
// eslint-disable-next-line
|
||||
} catch (error) {
|
||||
echo.error("failed to fetch assets");
|
||||
setisLoading(false);
|
||||
} else {
|
||||
try {
|
||||
const res = await getCategoryAsset(asset);
|
||||
setCategoryAssets(res);
|
||||
setFiltereredAssets(res);
|
||||
setisLoading(false); // End loading
|
||||
// eslint-disable-next-line
|
||||
} catch (error) {
|
||||
echo.error("failed to fetch assets");
|
||||
setisLoading(false);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -167,62 +121,19 @@ const Assets: React.FC = () => {
|
|||
<Search onChange={handleSearchChange} />
|
||||
<div className="assets-list-section">
|
||||
<section>
|
||||
{isLoading ? (
|
||||
<SkeletonUI type="asset" /> // Show skeleton when loading
|
||||
) : searchValue ? (
|
||||
<div className="assets-result">
|
||||
<div className="assets-wrapper">
|
||||
<div className="searched-content">
|
||||
<p>Results for {searchValue}</p>
|
||||
</div>
|
||||
<div className="assets-container">
|
||||
{categoryAssets?.map((asset: any, index: number) => (
|
||||
<div
|
||||
key={index}
|
||||
className="assets"
|
||||
id={asset.filename}
|
||||
title={asset.filename}
|
||||
>
|
||||
<img
|
||||
src={asset?.thumbnail}
|
||||
alt={asset.filename}
|
||||
className="asset-image"
|
||||
/>
|
||||
|
||||
<div className="asset-name">
|
||||
{asset.filename
|
||||
.split("_")
|
||||
.map(
|
||||
(word: any) =>
|
||||
word.charAt(0).toUpperCase() + word.slice(1)
|
||||
)
|
||||
.join(" ")}
|
||||
</div>
|
||||
{(() => {
|
||||
if (isLoading) {
|
||||
return <SkeletonUI type="asset" />; // Show skeleton when loading
|
||||
}
|
||||
if (searchValue) {
|
||||
return (
|
||||
<div className="assets-result">
|
||||
<div className="assets-wrapper">
|
||||
<div className="searched-content">
|
||||
<p>Results for {searchValue}</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
<>
|
||||
{selectedCategory ? (
|
||||
<div className="assets-wrapper">
|
||||
<h2>
|
||||
{selectedCategory}{" "}
|
||||
<div
|
||||
className="back-button"
|
||||
id="asset-backButtom"
|
||||
onClick={() => {
|
||||
setSelectedCategory(null);
|
||||
setCategoryAssets([]);
|
||||
}}
|
||||
>
|
||||
← Back
|
||||
</div>
|
||||
</h2>
|
||||
<div className="assets-container">
|
||||
{categoryAssets &&
|
||||
categoryAssets?.map((asset: any, index: number) => (
|
||||
<div className="assets-container">
|
||||
{categoryAssets?.map((asset: any, index: number) => (
|
||||
<div
|
||||
key={index}
|
||||
className="assets"
|
||||
|
@ -233,17 +144,8 @@ const Assets: React.FC = () => {
|
|||
src={asset?.thumbnail}
|
||||
alt={asset.filename}
|
||||
className="asset-image"
|
||||
onPointerDown={() => {
|
||||
setSelectedItem({
|
||||
name: asset.filename,
|
||||
id: asset.AssetID,
|
||||
type:
|
||||
asset.type === "undefined"
|
||||
? undefined
|
||||
: asset.type,
|
||||
});
|
||||
}}
|
||||
/>
|
||||
|
||||
<div className="asset-name">
|
||||
{asset.filename
|
||||
.split("_")
|
||||
|
@ -255,40 +157,104 @@ const Assets: React.FC = () => {
|
|||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
);
|
||||
}
|
||||
|
||||
if (selectedCategory) {
|
||||
return (
|
||||
<div className="assets-wrapper">
|
||||
<h2>Categories</h2>
|
||||
<div className="categories-container">
|
||||
{Array.from(
|
||||
new Set(categoryList.map((asset) => asset.category))
|
||||
).map((category, index) => {
|
||||
const categoryInfo = categoryList.find(
|
||||
(asset) => asset.category === category
|
||||
);
|
||||
return (
|
||||
<div
|
||||
key={index}
|
||||
className="category"
|
||||
id={category}
|
||||
onClick={() => fetchCategoryAssets(category)}
|
||||
>
|
||||
<img
|
||||
src={categoryInfo?.categoryImage || ""}
|
||||
alt={category}
|
||||
className="category-image"
|
||||
draggable={false}
|
||||
/>
|
||||
<div className="category-name">{category}</div>
|
||||
<h2>
|
||||
{selectedCategory}
|
||||
<button
|
||||
className="back-button"
|
||||
id="asset-backButtom"
|
||||
onClick={() => {
|
||||
setSelectedCategory(null);
|
||||
setCategoryAssets([]);
|
||||
}}
|
||||
>
|
||||
← Back
|
||||
</button>
|
||||
</h2>
|
||||
<div className="assets-container">
|
||||
{categoryAssets?.map((asset: any, index: number) => (
|
||||
<div
|
||||
key={`${index}-${asset}`}
|
||||
className="assets"
|
||||
id={asset.filename}
|
||||
title={asset.filename}
|
||||
>
|
||||
<img
|
||||
src={asset?.thumbnail}
|
||||
alt={asset.filename}
|
||||
className="asset-image"
|
||||
onPointerDown={() => {
|
||||
setSelectedItem({
|
||||
name: asset.filename,
|
||||
id: asset.AssetID,
|
||||
type:
|
||||
asset.type === "undefined"
|
||||
? undefined
|
||||
: asset.type,
|
||||
});
|
||||
}}
|
||||
/>
|
||||
<div className="asset-name">
|
||||
{asset.filename
|
||||
.split("_")
|
||||
.map(
|
||||
(word: any) =>
|
||||
word.charAt(0).toUpperCase() + word.slice(1)
|
||||
)
|
||||
.join(" ")}
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
))}
|
||||
{categoryAssets.length === 0 && (
|
||||
<div className="no-asset">
|
||||
🚧 The asset shelf is empty. We're working on filling it
|
||||
up!
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="assets-wrapper">
|
||||
<h2>Categories</h2>
|
||||
<div className="categories-container">
|
||||
{Array.from(
|
||||
new Set(categoryList.map((asset) => asset.category))
|
||||
).map((category, index) => {
|
||||
const categoryInfo = categoryList.find(
|
||||
(asset) => asset.category === category
|
||||
);
|
||||
return (
|
||||
<div
|
||||
key={index}
|
||||
className="category"
|
||||
id={category}
|
||||
onClick={() => fetchCategoryAssets(category)}
|
||||
>
|
||||
<img
|
||||
src={categoryInfo?.categoryImage ?? ""}
|
||||
alt={category}
|
||||
className="category-image"
|
||||
draggable={false}
|
||||
/>
|
||||
<div className="category-name">{category}</div>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
})()}
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -7,7 +7,6 @@ interface SkeletonUIProps {
|
|||
|
||||
// Define the SkeletonUI component
|
||||
const SkeletonUI: React.FC<SkeletonUIProps> = ({ type }) => {
|
||||
|
||||
// Function to render skeleton content based on 'type'
|
||||
const renderSkeleton = () => {
|
||||
switch (type) {
|
||||
|
@ -38,17 +37,28 @@ const SkeletonUI: React.FC<SkeletonUIProps> = ({ type }) => {
|
|||
case "asset":
|
||||
return (
|
||||
<>
|
||||
<div className="skeleton-content">
|
||||
<div className="skeleton asset-name"></div>
|
||||
<div className="skeleton asset"></div>
|
||||
</div>
|
||||
<div className="skeleton-content">
|
||||
<div className="skeleton asset-name"></div>
|
||||
<div className="skeleton asset"></div>
|
||||
<div className="skeleton asset-category-title"></div>
|
||||
<div className="skeleton-content-asset">
|
||||
<div className="skeleton-content">
|
||||
<div className="skeleton asset-name"></div>
|
||||
<div className="skeleton asset"></div>
|
||||
</div>
|
||||
<div className="skeleton-content">
|
||||
<div className="skeleton asset-name"></div>
|
||||
<div className="skeleton asset"></div>
|
||||
</div>
|
||||
<div className="skeleton-content">
|
||||
<div className="skeleton asset-name"></div>
|
||||
<div className="skeleton asset"></div>
|
||||
</div>
|
||||
<div className="skeleton-content">
|
||||
<div className="skeleton asset-name"></div>
|
||||
<div className="skeleton asset"></div>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
|
||||
|
||||
default:
|
||||
return (
|
||||
<div className="skeleton-content">
|
||||
|
|
|
@ -1278,7 +1278,7 @@
|
|||
}
|
||||
}
|
||||
.toggle-sidebar-ui-button {
|
||||
svg{
|
||||
svg {
|
||||
transform: scaleX(-1);
|
||||
}
|
||||
.tooltip {
|
||||
|
@ -1455,7 +1455,11 @@
|
|||
height: 100%;
|
||||
gap: 6px;
|
||||
padding: 2px;
|
||||
|
||||
.no-asset {
|
||||
text-align: center;
|
||||
margin: 12px;
|
||||
width: 100%;
|
||||
}
|
||||
.assets {
|
||||
width: 122px;
|
||||
height: 95px;
|
||||
|
|
|
@ -1,18 +1,8 @@
|
|||
.skeleton-wrapper {
|
||||
// max-width: 600px;
|
||||
display: flex;
|
||||
margin: 0 auto;
|
||||
width: 100%;
|
||||
|
||||
.asset-name {
|
||||
width: 40%;
|
||||
height: 10px;
|
||||
}
|
||||
|
||||
.asset {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
// max-width: 600px;
|
||||
margin: 0 auto;
|
||||
width: 100%;
|
||||
|
||||
.skeleton {
|
||||
background: var(--background-color-gray);
|
||||
|
||||
|
@ -31,7 +21,7 @@
|
|||
90deg,
|
||||
rgba(255, 255, 255, 0) 0%,
|
||||
rgba(255, 255, 255, 0.2) 20%,
|
||||
rgba(255, 255, 255, 0.5) 60%,
|
||||
rgba(255, 255, 255, 0.39) 60%,
|
||||
rgba(255, 255, 255, 0) 100%
|
||||
);
|
||||
transform: translateX(-100%);
|
||||
|
@ -66,6 +56,34 @@
|
|||
}
|
||||
}
|
||||
|
||||
.asset-category-title{
|
||||
width: 60%;
|
||||
height: 12px;
|
||||
margin-bottom: 12px;
|
||||
margin-top: 4px;
|
||||
}
|
||||
.skeleton-content-asset{
|
||||
display: flex;
|
||||
height: calc(95px * 2 + 10px);
|
||||
gap: 10px;
|
||||
flex-wrap: wrap;
|
||||
.skeleton-content {
|
||||
gap: 8px;
|
||||
flex-direction: column;
|
||||
min-width: 122px;
|
||||
min-height: 95px;
|
||||
.asset-name {
|
||||
width: 40%;
|
||||
height: 10px;
|
||||
}
|
||||
.asset {
|
||||
flex: 1;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes shimmer {
|
||||
100% {
|
||||
transform: translateX(100%);
|
||||
|
|
Loading…
Reference in New Issue