clean placeholder

This commit is contained in:
MFCo
2025-08-26 15:26:36 +02:00
parent b18d935294
commit de42b26e32
+21 -17
View File
@@ -1,33 +1,24 @@
import { useState, useEffect } from 'react'; import { useState } from 'react';
import { Loader2, ExternalLink, RefreshCw, Terminal } from 'lucide-react'; import { Loader2, ExternalLink, RefreshCw, Terminal } from 'lucide-react';
interface SandboxPreviewProps { interface SandboxPreviewProps {
sandboxId: string;
port: number;
type: 'vite' | 'nextjs' | 'console'; type: 'vite' | 'nextjs' | 'console';
output?: string; output?: string;
isLoading?: boolean; isLoading?: boolean;
sandboxUrl?: string; // Real URL from Vercel Sandbox API
} }
export default function SandboxPreview({ export default function SandboxPreview({
sandboxId,
port,
type, type,
output, output,
isLoading = false isLoading = false,
sandboxUrl
}: SandboxPreviewProps) { }: SandboxPreviewProps) {
const [previewUrl, setPreviewUrl] = useState<string>('');
const [showConsole, setShowConsole] = useState(false); const [showConsole, setShowConsole] = useState(false);
const [iframeKey, setIframeKey] = useState(0); const [iframeKey, setIframeKey] = useState(0);
useEffect(() => { // Use the real sandbox URL passed from the API
if (sandboxId && type !== 'console') { const previewUrl = sandboxUrl || '';
// For Vercel Sandbox, we'll receive the full URL from the API
// The URL format is determined by Vercel Sandbox's domain() method
// This is just a fallback format - actual URL comes from sandbox.domain(port)
setPreviewUrl(`https://${sandboxId}.vercel-sandbox.dev`);
}
}, [sandboxId, port, type]);
const handleRefresh = () => { const handleRefresh = () => {
setIframeKey(prev => prev + 1); setIframeKey(prev => prev + 1);
@@ -51,9 +42,13 @@ export default function SandboxPreview({
<span className="text-sm text-gray-400"> <span className="text-sm text-gray-400">
{type === 'vite' ? '⚡ Vite' : '▲ Next.js'} Preview {type === 'vite' ? '⚡ Vite' : '▲ Next.js'} Preview
</span> </span>
{previewUrl ? (
<code className="text-xs bg-gray-900 px-2 py-1 rounded text-blue-400"> <code className="text-xs bg-gray-900 px-2 py-1 rounded text-blue-400">
{previewUrl} {previewUrl}
</code> </code>
) : (
<span className="text-xs text-gray-500">Waiting for sandbox URL...</span>
)}
</div> </div>
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
<button <button
@@ -70,6 +65,7 @@ export default function SandboxPreview({
> >
<RefreshCw className="w-4 h-4" /> <RefreshCw className="w-4 h-4" />
</button> </button>
{previewUrl && (
<a <a
href={previewUrl} href={previewUrl}
target="_blank" target="_blank"
@@ -79,22 +75,29 @@ export default function SandboxPreview({
> >
<ExternalLink className="w-4 h-4" /> <ExternalLink className="w-4 h-4" />
</a> </a>
)}
</div> </div>
</div> </div>
{/* Main Preview */} {/* Main Preview */}
<div className="relative bg-gray-900 rounded-lg overflow-hidden border border-gray-700"> <div className="relative bg-gray-900 rounded-lg overflow-hidden border border-gray-700">
{isLoading && ( {(isLoading || !previewUrl) && (
<div className="absolute inset-0 bg-gray-900/80 flex items-center justify-center z-10"> <div className="absolute inset-0 bg-gray-900/80 flex items-center justify-center z-10">
<div className="text-center"> <div className="text-center">
<Loader2 className="w-8 h-8 animate-spin mx-auto mb-2" /> <Loader2 className="w-8 h-8 animate-spin mx-auto mb-2" />
<p className="text-sm text-gray-400"> <p className="text-sm text-gray-400">
{type === 'vite' ? 'Starting Vite dev server...' : 'Starting Next.js dev server...'} {!previewUrl
? 'Setting up sandbox environment...'
: type === 'vite'
? 'Starting Vite dev server...'
: 'Starting Next.js dev server...'
}
</p> </p>
</div> </div>
</div> </div>
)} )}
{previewUrl && (
<iframe <iframe
key={iframeKey} key={iframeKey}
src={previewUrl} src={previewUrl}
@@ -102,6 +105,7 @@ export default function SandboxPreview({
title={`${type} preview`} title={`${type} preview`}
sandbox="allow-scripts allow-same-origin allow-forms" sandbox="allow-scripts allow-same-origin allow-forms"
/> />
)}
</div> </div>
{/* Console Output (Toggle) */} {/* Console Output (Toggle) */}