feat: add descriptive loading overlays to Spark Plug wizard
Build and Deploy / build-and-push (push) Successful in 40s
Build and Deploy / build-and-push (push) Successful in 40s
This commit is contained in:
+20
-3
@@ -14,6 +14,7 @@ export default function SparkPlug() {
|
||||
const navigate = useNavigate();
|
||||
const [currentStep, setCurrentStep] = useState(1);
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
const [loadingMessage, setLoadingMessage] = useState('');
|
||||
|
||||
// Step 1: PDF File
|
||||
const [pdfFile, setPdfFile] = useState<File | null>(null);
|
||||
@@ -35,6 +36,7 @@ export default function SparkPlug() {
|
||||
|
||||
const processStep1 = async () => {
|
||||
if (!pdfFile) return;
|
||||
setLoadingMessage('Extracting details with Gemini AI...');
|
||||
setIsLoading(true);
|
||||
|
||||
try {
|
||||
@@ -63,6 +65,7 @@ export default function SparkPlug() {
|
||||
|
||||
const processStep2 = async () => {
|
||||
if (!extractedPrompt) return;
|
||||
setLoadingMessage('Generating multi-view concepts with Nano Banana...');
|
||||
setIsLoading(true);
|
||||
|
||||
try {
|
||||
@@ -95,6 +98,7 @@ export default function SparkPlug() {
|
||||
|
||||
const processStep3 = async () => {
|
||||
if (generatedImages.length === 0) return;
|
||||
setLoadingMessage('Constructing 3D Model with Meshy API...');
|
||||
setIsLoading(true);
|
||||
|
||||
try {
|
||||
@@ -121,6 +125,7 @@ export default function SparkPlug() {
|
||||
};
|
||||
|
||||
const processStep4 = async () => {
|
||||
setLoadingMessage('Saving project to your workspace...');
|
||||
setIsLoading(true);
|
||||
try {
|
||||
// Mock generated GLB URL from Meshy
|
||||
@@ -200,7 +205,17 @@ export default function SparkPlug() {
|
||||
</div>
|
||||
|
||||
{/* Content Area */}
|
||||
<div className="w-full max-w-3xl bg-zinc-900 border border-zinc-800 rounded-2xl p-8 shadow-2xl min-h-[400px] flex flex-col">
|
||||
<div className="w-full max-w-3xl bg-zinc-900 border border-zinc-800 rounded-2xl p-8 shadow-2xl min-h-[400px] flex flex-col relative overflow-hidden">
|
||||
|
||||
{isLoading && (
|
||||
<div className="absolute inset-0 z-50 bg-zinc-900/80 backdrop-blur-sm flex flex-col items-center justify-center animate-in fade-in duration-300">
|
||||
<div className="w-16 h-16 rounded-full border-4 border-zinc-800 border-t-amber-500 animate-spin mb-6 flex items-center justify-center">
|
||||
<Sparkles className="text-amber-500 animate-pulse" size={24} />
|
||||
</div>
|
||||
<h3 className="text-lg font-bold text-white mb-2">{loadingMessage}</h3>
|
||||
<p className="text-sm text-zinc-400">This might take a few moments...</p>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{currentStep === 1 && (
|
||||
<div className="flex-1 flex flex-col items-center justify-center gap-6 animate-in fade-in zoom-in duration-300">
|
||||
@@ -258,7 +273,8 @@ export default function SparkPlug() {
|
||||
<div className="flex items-center justify-between mt-4">
|
||||
<button
|
||||
onClick={() => processStep1()} // re-run extraction
|
||||
className="flex items-center gap-2 text-zinc-400 hover:text-white px-4 py-2 rounded-lg hover:bg-zinc-800 transition-colors"
|
||||
disabled={isLoading}
|
||||
className="flex items-center gap-2 text-zinc-400 hover:text-white px-4 py-2 rounded-lg hover:bg-zinc-800 transition-colors disabled:opacity-50"
|
||||
>
|
||||
<RefreshCw size={16} /> Regenerate Extraction
|
||||
</button>
|
||||
@@ -303,7 +319,8 @@ export default function SparkPlug() {
|
||||
<div className="flex items-center justify-between mt-4">
|
||||
<button
|
||||
onClick={() => processStep2()} // re-run generation
|
||||
className="flex items-center gap-2 text-zinc-400 hover:text-white px-4 py-2 rounded-lg hover:bg-zinc-800 transition-colors"
|
||||
disabled={isLoading}
|
||||
className="flex items-center gap-2 text-zinc-400 hover:text-white px-4 py-2 rounded-lg hover:bg-zinc-800 transition-colors disabled:opacity-50"
|
||||
>
|
||||
<RefreshCw size={16} /> Regenerate Images
|
||||
</button>
|
||||
|
||||
Reference in New Issue
Block a user