clean placeholder
This commit is contained in:
@@ -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) */}
|
||||||
|
|||||||
Reference in New Issue
Block a user