feat: update Spark Plug UI to handle 4 multi-view images and save generated GLB URL
Build and Deploy / build-and-push (push) Successful in 51s

This commit is contained in:
AI Bot
2026-09-02 12:03:45 +05:30
parent 9fe22f9210
commit 40d3e686b5
+45 -13
View File
@@ -21,8 +21,8 @@ export default function SparkPlug() {
// Step 2: Extracted Text // Step 2: Extracted Text
const [extractedPrompt, setExtractedPrompt] = useState<string>(''); const [extractedPrompt, setExtractedPrompt] = useState<string>('');
// Step 3: Generated Image // Step 3: Generated Images (Multi-view)
const [generatedImage, setGeneratedImage] = useState<string | null>(null); const [generatedImages, setGeneratedImages] = useState<string[]>([]);
// Step 4: 3D Model // Step 4: 3D Model
const [modelProgress, setModelProgress] = useState(0); const [modelProgress, setModelProgress] = useState(0);
@@ -76,8 +76,13 @@ export default function SparkPlug() {
// Mocking the image generation with Nano Banana // Mocking the image generation with Nano Banana
await new Promise(r => setTimeout(r, 3000)); await new Promise(r => setTimeout(r, 3000));
// Placeholder image for the shampoo sachet // Placeholder images for the 4 views (front, back, left, right)
setGeneratedImage("https://images.unsplash.com/photo-1629198688000-71f23e745b6e?w=800&q=80"); // Generic beauty product placeholder setGeneratedImages([
"https://images.unsplash.com/photo-1629198688000-71f23e745b6e?w=400&q=80", // front
"https://images.unsplash.com/photo-1629198725848-18e55e975cc3?w=400&q=80", // back
"https://images.unsplash.com/photo-1629198725838-511bb7405234?w=400&q=80", // left
"https://images.unsplash.com/photo-1629198688000-71f23e745b6e?w=400&q=80", // right
]);
setCurrentStep(3); setCurrentStep(3);
} catch (err) { } catch (err) {
@@ -89,7 +94,7 @@ export default function SparkPlug() {
}; };
const processStep3 = async () => { const processStep3 = async () => {
if (!generatedImage) return; if (generatedImages.length === 0) return;
setIsLoading(true); setIsLoading(true);
try { try {
@@ -118,10 +123,26 @@ export default function SparkPlug() {
const processStep4 = async () => { const processStep4 = async () => {
setIsLoading(true); setIsLoading(true);
try { try {
// Create project and save // Mock generated GLB URL from Meshy
const mockGlbUrl = "https://raw.githubusercontent.com/KhronosGroup/glTF-Sample-Models/master/2.0/BoxTextured/glTF-Binary/BoxTextured.glb";
// Create project and save with model injected into scene_data
const res = await api.saveProject({ const res = await api.saveProject({
name: "Spark Plug Output - Sachet", name: "Spark Plug Output",
scene_data: {} // We would normally attach the generated GLB URL here scene_data: {
objects: [
{
id: "model_" + Date.now(),
type: "model",
name: "Generated Product Model",
visible: true,
position: [0, 0, 0],
rotation: [0, 0, 0],
scale: [1, 1, 1],
url: mockGlbUrl
}
]
}
}); });
if (res.id) { if (res.id) {
navigate(`/editor/${res.id}`); navigate(`/editor/${res.id}`);
@@ -257,14 +278,25 @@ export default function SparkPlug() {
<div className="flex-1 flex flex-col gap-4 animate-in fade-in slide-in-from-right-8 duration-300"> <div className="flex-1 flex flex-col gap-4 animate-in fade-in slide-in-from-right-8 duration-300">
<h2 className="text-xl font-bold">Concept Art generated by Nano Banana</h2> <h2 className="text-xl font-bold">Concept Art generated by Nano Banana</h2>
<p className="text-sm text-zinc-400"> <p className="text-sm text-zinc-400">
Review the generated product imagery. These images will be used by Meshy to construct the final 3D model. Review the 4-sided product imagery (front, back, left, right). These images will be used by Meshy's Multi-Image API to construct the final 3D model.
</p> </p>
<div className="flex-1 bg-zinc-950 border border-zinc-800 rounded-xl flex items-center justify-center overflow-hidden p-4 relative"> <div className="flex-1 bg-zinc-950 border border-zinc-800 rounded-xl p-4">
{generatedImage ? ( {generatedImages.length > 0 ? (
<img src={generatedImage} alt="Generated Concept" className="max-w-full max-h-[300px] object-contain rounded-lg shadow-xl" /> <div className="grid grid-cols-2 gap-4 h-full">
{generatedImages.map((img, idx) => (
<div key={idx} className="relative bg-zinc-900 rounded-lg overflow-hidden border border-zinc-800 flex items-center justify-center">
<img src={img} alt={`View ${idx + 1}`} className="max-w-full max-h-[150px] object-contain" />
<div className="absolute top-2 left-2 bg-black/50 backdrop-blur-sm px-2 py-1 rounded text-[10px] font-bold text-zinc-300">
{['FRONT', 'BACK', 'LEFT', 'RIGHT'][idx]}
</div>
</div>
))}
</div>
) : ( ) : (
<ImageIcon size={48} className="text-zinc-800" /> <div className="flex h-full items-center justify-center">
<ImageIcon size={48} className="text-zinc-800" />
</div>
)} )}
</div> </div>