path correction

This commit is contained in:
sandhiya-hepl
2026-07-15 18:22:52 +05:30
parent e84c1adac4
commit abb35c0e03
15 changed files with 518 additions and 42 deletions
+45 -15
View File
@@ -73,9 +73,12 @@ function Toast({ message, type }) {
function LoginPreview() {
const viewportRef = useRef(null);
const iframeRef = useRef(null);
const [scale, setScale] = useState(0.5);
const [frameBlocked, setFrameBlocked] = useState(false);
const previewWidth = 1280;
const previewHeight = 800;
const previewSrc = `${BASE}preview.html`;
useEffect(() => {
const el = viewportRef.current;
@@ -91,6 +94,22 @@ function LoginPreview() {
observer.observe(el);
return () => observer.disconnect();
}, []);
// Host CSP (frame-ancestors 'none' / XFO DENY) can block the embed — show a fallback.
useEffect(() => {
const timer = setTimeout(() => {
try {
const doc = iframeRef.current?.contentDocument;
if (!doc?.body || doc.body.childElementCount === 0) {
setFrameBlocked(true);
}
} catch {
setFrameBlocked(true);
}
}, 2000);
return () => clearTimeout(timer);
}, []);
return (
<div className="login-preview">
<div className="login-preview-intro">
@@ -116,21 +135,32 @@ function LoginPreview() {
ref={viewportRef}
style={{ height: previewHeight * scale }}
>
<div
className="login-preview-stage"
style={{ width: previewWidth * scale, height: previewHeight * scale }}
>
<iframe
src={`${BASE}preview.html`}
title="Website preview"
className="login-preview-iframe"
style={{
width: previewWidth,
height: previewHeight,
transform: `scale(${scale})`,
}}
/>
</div>
{frameBlocked ? (
<div className="login-preview-fallback">
<p>Inline preview is blocked by the server&apos;s frame policy.</p>
<a href={previewSrc} target="_blank" rel="noopener noreferrer" className="login-preview-link">
<ExternalLink size={14} />
Open preview
</a>
</div>
) : (
<div
className="login-preview-stage"
style={{ width: previewWidth * scale, height: previewHeight * scale }}
>
<iframe
ref={iframeRef}
src={previewSrc}
title="Website preview"
className="login-preview-iframe"
style={{
width: previewWidth,
height: previewHeight,
transform: `scale(${scale})`,
}}
/>
</div>
)}
</div>
</div>
</div>
+22
View File
@@ -893,6 +893,28 @@ body {
isolation: isolate;
}
.login-preview-fallback {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 12px;
height: 100%;
min-height: 220px;
padding: 24px;
text-align: center;
color: #64748b;
background: linear-gradient(160deg, #0f172a 0%, #1e293b 55%, #0f172a 100%);
}
.login-preview-fallback p {
margin: 0;
max-width: 280px;
font-size: 0.9rem;
line-height: 1.45;
color: #94a3b8;
}
.login-preview-iframe {
position: absolute;
top: 0;
+9 -1
View File
@@ -22,7 +22,15 @@ async function apiFetch(path, options = {}) {
const res = await fetch(`${API_BASE}${path}`, { ...options, headers });
const data = await res.json().catch(() => ({}));
if (!res.ok) throw new Error(data.error || 'Request failed');
if (!res.ok) {
const fallback =
res.status === 404
? 'API not found. Deploy server/ and run: npm run server (port 3001)'
: res.status === 502
? 'API server unreachable. Start Node on the host (port 3001).'
: 'Request failed';
throw new Error(data.error || fallback);
}
return data;
}