added search functionality for decals

This commit is contained in:
2025-08-29 12:46:34 +05:30
parent 98be35bf5f
commit 363906aa12
2 changed files with 156 additions and 70 deletions

View File

@@ -49,39 +49,54 @@ const Assets: React.FC = () => {
const [searchValue, setSearchValue] = useState<string>("");
const [selectedCategory, setSelectedCategory] = useState<string | null>(null);
const [categoryAssets, setCategoryAssets] = useState<AssetProp[]>([]);
const [filtereredAssets, setFiltereredAssets] = useState<AssetProp[]>([]);
const [decalAsset, setDecalAsset] = useState<any>();
const [filtereredAssets, setFiltereredAssets] = useState<AssetProp[] | []>(
[]
);
const [categoryList, setCategoryList] = useState<CategoryListProp[]>([]);
const [isLoading, setisLoading] = useState<boolean>(false); // Loading state for assets
const { selectedSubCategory, setSelectedSubCategory } = useDecalStore();
const handleSearchChange = (value: string) => {
const searchTerm = value.toLowerCase();
const searchTerm = searchValue
? searchValue.toLowerCase()
: value.toLowerCase();
setSearchValue(value);
if (searchTerm.trim() === "" && !selectedCategory) {
setCategoryAssets([]);
return;
}
const filteredModels = filtereredAssets?.filter((model) => {
if (!model?.tags || !model?.filename || !model?.category) return false;
if (searchTerm.startsWith(":") && searchTerm.length > 1) {
const tagSearchTerm = searchTerm.slice(1);
return model.tags.toLowerCase().includes(tagSearchTerm);
} else if (selectedCategory) {
return (
model.category
.toLowerCase()
.includes(selectedCategory.toLowerCase()) &&
model.filename.toLowerCase().includes(searchTerm)
);
} else {
return model.filename.toLowerCase().includes(searchTerm);
}
});
if (selectedCategory === "Decals" || selectedSubCategory) {
const filteredModels = decalAsset?.filter((model: any) =>
model.decalName?.toLowerCase().includes(searchTerm.toLowerCase())
);
setCategoryAssets(filteredModels);
} else {
const filteredModels = filtereredAssets?.filter((model) => {
if (!model?.tags || !model?.filename || !model?.category) return false;
if (searchTerm.startsWith(":") && searchTerm.length > 1) {
const tagSearchTerm = searchTerm.slice(1);
return model.tags.toLowerCase().includes(tagSearchTerm);
} else if (selectedCategory) {
return (
model.category
.toLowerCase()
.includes(selectedCategory.toLowerCase()) &&
model.filename.toLowerCase().includes(searchTerm)
);
} else {
return model.filename.toLowerCase().includes(searchTerm);
}
});
setCategoryAssets(filteredModels);
setCategoryAssets(filteredModels);
}
};
useEffect(() => {
if (selectedCategory === "Decals") return;
const filteredAssets = async () => {
try {
const filt = await fetchAssets();
@@ -91,7 +106,18 @@ const Assets: React.FC = () => {
}
};
filteredAssets();
}, [categoryAssets]);
}, [categoryAssets, selectedCategory]);
useEffect(() => {
if (
(searchValue.trim() === "" && selectedCategory === "Decals") ||
selectedSubCategory
) {
const filteredModels = decalAsset?.filter((model: any) =>
model.decalName?.toLowerCase().includes(searchValue.toLowerCase())
);
setCategoryAssets(filteredModels);
}
}, [selectedSubCategory, decalAsset, searchValue]);
useEffect(() => {
setCategoryList([
@@ -126,8 +152,10 @@ const Assets: React.FC = () => {
// setSelectedCategory(asset);
try {
const res = await getCategoryDecals(asset);
setCategoryAssets(res);
setFiltereredAssets(res);
setDecalAsset(res);
setisLoading(false); // End loading
// eslint-disable-next-line
} catch (error) {
@@ -143,11 +171,9 @@ const Assets: React.FC = () => {
{ name: "Informational", icon: <DecalInfoIcon /> },
];
const { selectedSubCategory, setSelectedSubCategory } = useDecalStore();
return (
<div className="assets-container-main">
<Search onChange={handleSearchChange} />
<Search onChange={handleSearchChange} value={searchValue} />
<div className="assets-list-section">
<section>
{(() => {
@@ -162,40 +188,100 @@ const Assets: React.FC = () => {
<p>Results for {searchValue}</p>
</div>
<div className="assets-container">
{categoryAssets?.map((asset: any, index: number) => (
<div
key={`${index}-${asset.filename}`}
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(" ")}
{selectedCategory == "Decals" ? (
<>
<div className="catogory-asset-filter">
{activeSubcategories.map((cat, index) => (
<div
key={index}
className={`catogory-asset-filter-wrapper ${
selectedSubCategory === cat.name
? "active"
: ""
}`}
onClick={() => {
fetchCategoryDecals(cat.name);
setSelectedSubCategory(cat.name);
}}
>
<div className="sub-catagory">{cat.icon}</div>
<div className="sub-catagory">{cat.name}</div>
</div>
))}
</div>
</div>
))}
{categoryAssets?.map((asset: any, index: number) => (
<div
key={`${index}-${asset}`}
className="assets"
id={asset.decalName}
title={asset.decalName}
>
<img
src={asset?.decalImage}
alt={asset.decalName}
className="asset-image"
onPointerDown={() => {
setSelectedItem({
name: asset.decalName,
id: asset.id,
type:
asset.type === "undefined"
? undefined
: asset.type,
category: asset.category,
// subType: asset.subType,
});
}}
/>
<div className="asset-name">
{asset.decalName
.split("_")
.map(
(word: any) =>
word.charAt(0).toUpperCase() +
word.slice(1)
)
.join(" ")}
</div>
</div>
))}
</>
) : (
categoryAssets?.map((asset: any, index: number) => (
<div
key={`${index}-${asset.filename}`}
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>
))
)}
</div>
</div>
</div>

View File

@@ -5,20 +5,20 @@ import { useSceneContext } from "../../../scene/sceneContext";
import { useViewSceneStore } from "../../../../store/builder/store";
function VehicleInstances() {
const { vehicleStore } = useSceneContext();
const { vehicles } = vehicleStore();
const { viewSceneLabels } = useViewSceneStore();
const { vehicleStore } = useSceneContext();
const { vehicles } = vehicleStore();
const { viewSceneLabels } = useViewSceneStore();
return (
<>
{vehicles.map((vehicle: VehicleStatus) => (
<React.Fragment key={vehicle.modelUuid}>
<VehicleInstance agvDetail={vehicle} />
{viewSceneLabels && <VehicleContentUi vehicle={vehicle} />}
</React.Fragment>
))}
</>
);
return (
<>
{vehicles.map((vehicle: VehicleStatus) => (
<React.Fragment key={vehicle.modelUuid}>
<VehicleInstance agvDetail={vehicle} />
{viewSceneLabels && <VehicleContentUi vehicle={vehicle} />}
</React.Fragment>
))}
</>
);
}
export default VehicleInstances;