From 4939c19c129b485f3001b52cb9b46215c1d3bd41 Mon Sep 17 00:00:00 2001 From: Vishnu Date: Tue, 13 May 2025 15:18:15 +0530 Subject: [PATCH] Refactor asset management components to enhance structure and improve data handling; update styles for better UI consistency --- app/src/modules/market/AssetPreview.tsx | 39 ++++++------ app/src/modules/market/Card.tsx | 30 ++++++---- app/src/modules/market/CardsContainer.tsx | 13 +++- app/src/modules/market/FilterSearch.tsx | 7 ++- app/src/modules/market/GltfLoader.tsx | 6 +- app/src/modules/market/MarketPlace.tsx | 1 + app/src/services/marketplace/fetchGltfUrl.ts | 29 +++++++-- .../components/marketPlace/marketPlace.scss | 60 +++++++------------ 8 files changed, 102 insertions(+), 83 deletions(-) diff --git a/app/src/modules/market/AssetPreview.tsx b/app/src/modules/market/AssetPreview.tsx index a53a60d..aa037e2 100644 --- a/app/src/modules/market/AssetPreview.tsx +++ b/app/src/modules/market/AssetPreview.tsx @@ -1,7 +1,6 @@ -import React, { Suspense, useEffect } from "react"; -import assetImage from "../../assets/image/image.png"; +import React, { Suspense } from "react"; import { FilledStarsIconSmall } from "../../components/icons/marketPlaceIcons"; -import { Canvas, useThree } from "@react-three/fiber"; +import { Canvas } from "@react-three/fiber"; import { ContactShadows, OrbitControls, Text } from "@react-three/drei"; import GltfLoader from "./GltfLoader"; import * as THREE from "three"; @@ -14,17 +13,26 @@ interface SelectedCard { rating: number; views: number; description: string; + AssetID: string; } // Define the props type for AssetPreview interface AssetPreviewProps { selectedCard: SelectedCard; + modelUrl: string; setSelectedCard: React.Dispatch>; // Type for setter function } +const savedTheme: string | null = localStorage.getItem("theme"); + function Ui() { return ( - + Loading preview... ); @@ -33,16 +41,8 @@ function Ui() { const AssetPreview: React.FC = ({ selectedCard, setSelectedCard, + modelUrl, }) => { - // Ensure rating is a valid number between 0 and 5 - const rating = Math.max( - 0, - Math.min(5, isNaN(selectedCard.rating) ? 0 : selectedCard.rating) - ); - - // Ensure that the rating is a valid positive integer for array length - const starsArray = Array.from({ length: rating }, (_, index) => index); - return (
@@ -53,18 +53,19 @@ const AssetPreview: React.FC = ({ { - scene.background = new THREE.Color(0xffffff); + scene.background = new THREE.Color( + savedTheme === "dark" ? 0x19191d : 0xfcfdfd + ); }} > }> - {selectedCard.assetName && ( - + {selectedCard.assetName && modelUrl && ( + )} = ({
{/* close button */} -
setSelectedCard(null)}> +
+
diff --git a/app/src/modules/market/Card.tsx b/app/src/modules/market/Card.tsx index a7010cc..e192c17 100644 --- a/app/src/modules/market/Card.tsx +++ b/app/src/modules/market/Card.tsx @@ -1,15 +1,12 @@ -import React, { useEffect } from "react"; +import React from "react"; import { CommentsIcon, - DownloadIcon, EyeIconBig, FilledStarsIconSmall, StarsIconSmall, VerifiedIcon, } from "../../components/icons/marketPlaceIcons"; -import assetImage from "../../assets/image/image.png"; -import { getAssetDownload } from "../../services/marketplace/getAssetDownload"; interface CardProps { assetName: string; @@ -19,6 +16,7 @@ interface CardProps { views: number; image: string; description: string; + AssetID: string; onSelectCard: (cardData: { assetName: string; uploadedOn: number; @@ -26,6 +24,7 @@ interface CardProps { rating: number; views: number; description: string; + AssetID: string; }) => void; } @@ -38,9 +37,18 @@ const Card: React.FC = ({ image, description, onSelectCard, + AssetID, }) => { const handleCardSelect = () => { - onSelectCard({ assetName, uploadedOn, price, rating, views, description }); + onSelectCard({ + assetName, + uploadedOn, + price, + rating, + views, + description, + AssetID, + }); }; return ( @@ -81,22 +89,22 @@ const Card: React.FC = ({
{[...Array(5)].map((_, index) => ( - <> + {index < 3 ? ( - + ) : ( - + )} - + ))}
₹ {price}/unit
-
+
+ ); }; diff --git a/app/src/modules/market/CardsContainer.tsx b/app/src/modules/market/CardsContainer.tsx index 62b905b..684fc1d 100644 --- a/app/src/modules/market/CardsContainer.tsx +++ b/app/src/modules/market/CardsContainer.tsx @@ -1,6 +1,7 @@ import React, { useState } from "react"; import Card from "./Card"; import AssetPreview from "./AssetPreview"; +import { fetchGltfUrl } from "../../services/marketplace/fetchGltfUrl"; interface ModelData { CreatedBy: string; @@ -15,12 +16,14 @@ interface ModelData { uploadDate: number; _id: string; price: number; + AssetID: string; } interface ModelsProps { models: ModelData[]; } const CardsContainer: React.FC = ({ models }) => { + const [modelUrl, setModelUrl] = useState(""); const [selectedCard, setSelectedCard] = useState<{ assetName: string; uploadedOn: number; @@ -28,19 +31,23 @@ const CardsContainer: React.FC = ({ models }) => { rating: number; views: number; description: string; + AssetID: string; } | null>(null); - const handleCardSelect = (cardData: { + const handleCardSelect = async (cardData: { assetName: string; uploadedOn: number; price: number; rating: number; views: number; description: string; + AssetID: string; }) => { setSelectedCard(cardData); + const res = await fetchGltfUrl(cardData.assetName, cardData.AssetID); + console.log("res: ", res); + setModelUrl(res.url); }; - return (
@@ -56,6 +63,7 @@ const CardsContainer: React.FC = ({ models }) => { rating={4.5} views={800} onSelectCard={handleCardSelect} + AssetID={assetDetail.AssetID} image={assetDetail.thumbnail} description={assetDetail.description} /> @@ -66,6 +74,7 @@ const CardsContainer: React.FC = ({ models }) => { )} {/* */} diff --git a/app/src/modules/market/FilterSearch.tsx b/app/src/modules/market/FilterSearch.tsx index 20882c9..e860b44 100644 --- a/app/src/modules/market/FilterSearch.tsx +++ b/app/src/modules/market/FilterSearch.tsx @@ -16,6 +16,7 @@ interface ModelData { uploadDate: number; _id: string; price: number; + AssetID: string; } interface ModelsProps { @@ -44,7 +45,7 @@ const FilterSearch: React.FC = ({ const descending = [...models].sort((a, b) => b.filename.localeCompare(a.filename)); setModels(descending); } - }, [activeOption]); + }, [activeOption, models, setModels]); const handleSearch = (val: string) => { const filteredModel = filteredModels.filter((model) => @@ -73,13 +74,13 @@ const FilterSearch: React.FC = ({
Rating
{[0, 1, 2, 3, 4].map((i) => ( -
handleStarClick(i)} className={`star-wrapper ${i < rating ? "filled" : "empty"}`} > -
+ ))}
diff --git a/app/src/modules/market/GltfLoader.tsx b/app/src/modules/market/GltfLoader.tsx index 2431af2..cfec06d 100644 --- a/app/src/modules/market/GltfLoader.tsx +++ b/app/src/modules/market/GltfLoader.tsx @@ -3,7 +3,6 @@ import { useFrame } from "@react-three/fiber"; import { Stage, useGLTF } from "@react-three/drei"; import { AnimationMixer, AnimationAction, Object3D } from "three"; import * as THREE from "three"; -import { fetchGltfUrl } from "../../services/marketplace/fetchGltfUrl"; interface GltfLoaderProps { glbdata?: boolean; @@ -13,7 +12,6 @@ interface GltfLoaderProps { setSelectedAnimation?: (animation: string) => void; } -// const getGLTFUrl = (url: string) => url; // Placeholder for your actual function const GltfLoader: React.FC = ({ glbdata, @@ -21,12 +19,10 @@ const GltfLoader: React.FC = ({ setAnimations, selectedAnimation, }) => { - const modelUrl: any = fromServer ? fetchGltfUrl(fromServer) : glbdata; - const { scene, animations } = useGLTF(modelUrl ?? "") as { + const { scene, animations } = useGLTF(fromServer ?? "") as { scene: Object3D; animations: THREE.AnimationClip[]; }; - const mixer = useRef( scene ? new AnimationMixer(scene) : null ); diff --git a/app/src/modules/market/MarketPlace.tsx b/app/src/modules/market/MarketPlace.tsx index 6de3fea..c76baa3 100644 --- a/app/src/modules/market/MarketPlace.tsx +++ b/app/src/modules/market/MarketPlace.tsx @@ -16,6 +16,7 @@ interface ModelData { uploadDate: number; _id: string; price: number; + AssetID: string; } const MarketPlace = () => { const [models, setModels] = useState([]); diff --git a/app/src/services/marketplace/fetchGltfUrl.ts b/app/src/services/marketplace/fetchGltfUrl.ts index 3916c9e..2f52887 100644 --- a/app/src/services/marketplace/fetchGltfUrl.ts +++ b/app/src/services/marketplace/fetchGltfUrl.ts @@ -1,7 +1,26 @@ let BackEnd_url = `http://${process.env.REACT_APP_SERVER_MARKETPLACE_URL}`; -export const fetchGltfUrl = (filename: string) => { - if (filename) { - return `${BackEnd_url}/api/v1/getAssetFile/${filename}`; +export const fetchGltfUrl = async (filename: string, AssetID: string) => { + try { + const response = await fetch( + `${BackEnd_url}/api/v2/assetDetails/${filename}/${AssetID}`, + { + method: "GET", + headers: { + "Content-Type": "application/json", + }, + // body: JSON.stringify(assetData), + } + ); + + if (!response.ok) { + throw new Error("Failed to fetch asset details"); + } + + const result = await response.json(); + + return result; + } catch (error: any) { + // + throw new Error(error.message); } - return null; // or handle the case when filename is not provided -}; +} \ No newline at end of file diff --git a/app/src/styles/components/marketPlace/marketPlace.scss b/app/src/styles/components/marketPlace/marketPlace.scss index b4237f2..6e39da6 100644 --- a/app/src/styles/components/marketPlace/marketPlace.scss +++ b/app/src/styles/components/marketPlace/marketPlace.scss @@ -2,9 +2,6 @@ @use "../../abstracts/mixins.scss" as *; .marketplace-wrapper { - // transform: scale(0.65); - /* Start at 90% width */ - height: 100vh; width: 100vw; z-index: #{$z-index-marketplace}; @@ -14,7 +11,6 @@ top: 0; padding: 10px; padding-top: 100px; - // animation: growWidth 0.4s ease-in-out 0.5s forwards; .marketplace-container { position: relative; @@ -43,8 +39,6 @@ width: 100%; .skeleton-content { - - width: calc(25% - 14px) !important; height: 100%; border-radius: #{$border-radius-xlarge}; @@ -79,7 +73,6 @@ } .button { - width: 100%; height: 35px; border-radius: 20px; @@ -143,8 +136,7 @@ .star-wrapper.filled { svg { - - fill: #F3A50C; + fill: #f3a50c; } } } @@ -190,10 +182,6 @@ justify-content: center; gap: 6px; - .assets-container { - height: auto; - } - .icon { position: absolute; top: 12px; @@ -208,7 +196,7 @@ .image-container { width: 100%; display: flex; - max-height: 180px; + height: 180px; justify-content: center; border-radius: #{$border-radius-medium}; overflow: hidden; @@ -224,7 +212,7 @@ display: flex; justify-content: space-between; padding: 0; - + height: auto; .name-container { display: flex; flex-direction: column; @@ -299,7 +287,6 @@ } } - .assetPreview-wrapper { width: 100%; height: 100%; @@ -307,15 +294,18 @@ top: 0; left: 0; z-index: 3; + padding: 0 10px; .assetPreview { width: 100%; height: 100%; background: var(--background-color); + backdrop-filter: blur(18px); display: flex; gap: 12px; overflow: hidden; border-radius: #{$border-radius-extra-large}; + outline: 1px solid var(--border-color); } // Image Preview Section @@ -352,8 +342,8 @@ min-width: 26px; border-radius: #{$border-radius-circle}; font-weight: var(--font-weight-bold); - color: var(--background-color); - background: var(--accent-color); + color: var(--text-button-color); + background: var(--background-color-button); } .organization-details { @@ -361,9 +351,7 @@ flex-direction: column; .organization-name { - font-weight: bold; margin-bottom: 5px; - font-weight: #{$bold-weight}; font-size: $regular; } @@ -380,35 +368,31 @@ margin-top: 20px; .asset-name { - font-size: 1.5em; - font-weight: bold; margin-bottom: 10px; font-weight: #{$bold-weight}; - font-size: $large; + font-size: var(--font-size-large); } .asset-description { margin-bottom: 20px; - color: #666; + color: var(--input-text-color); } .asset-review { width: fit-content; - padding: 5px 10px; + padding: 5px 14px; display: flex; align-items: center; margin-bottom: 20px; - outline: 1px solid #909090cc; - border-radius: #{$border-radius-small}; + outline: 1px solid var(--border-color); + border-radius: #{$border-radius-large}; .asset-rating { display: flex; align-items: center; gap: 4px; margin-right: 10px; - font-weight: bold; position: relative; - font-weight: #{$bold-weight}; font-size: $regular; @@ -442,25 +426,25 @@ } .button { - color: white; - padding: 10px 20px; - border-radius: #{$border-radius-small}; + color: var(--text-button-color); + padding: 8px 26px; + border-radius: #{$border-radius-extra-large}; cursor: pointer; text-align: center; &:first-child { - outline: 1px solid var(--accent-color); - color: var(--accent-color); + outline: 1px solid var(--background-color-button); + color: var(--highlight-text-color); } &:last-child { - background: var(--accent-color); - color: var(--background-color); + background: var(--background-color-button); + color: var(--text-button-color); } } .closeButton { - color: var(--accent-color); + color: var(--highlight-text-color); position: absolute; top: 18px; left: 18px; @@ -468,4 +452,4 @@ cursor: pointer; font-size: var(--font-size-large); } -} \ No newline at end of file +}