-

+
@@ -728,7 +728,7 @@ export default function App({ previewMode = false }) {
pointerEvents: 'none'
}}
>
-
+
Your browser does not support the video tag.
@@ -937,7 +937,7 @@ export default function App({ previewMode = false }) {
{/* Globe Visual */}

@@ -962,7 +962,7 @@ export default function App({ previewMode = false }) {
padding: '0.2rem',
}}>

@@ -982,7 +982,7 @@ export default function App({ previewMode = false }) {
{/* Globe in background - Increased Size & Brightness */}

-
-
-
-
+
+
+
+
+
{/* Inner Orbit - Adjusted size to radiusX=360, radiusY=225 */}
-
-
-
-
-
+
+
+
+
+
)}
@@ -1104,7 +1104,7 @@ export default function App({ previewMode = false }) {
transition: 'all 0.3s ease'
}}>

@@ -1501,7 +1501,7 @@ export default function App({ previewMode = false }) {
height: '100%'
}}>

@@ -1515,7 +1515,7 @@ export default function App({ previewMode = false }) {
border: '1px solid rgba(255, 255, 255, 0.06)',
position: 'relative',
overflow: 'hidden',
- backgroundImage: `linear-gradient(to bottom, rgba(2, 7, 16, 0.95) 0%, rgba(2, 7, 16, 0.6) 45%, rgba(2, 7, 16, 0) 85%), url(${BASE}assets/whyus_hologram.jpg)`,
+ backgroundImage: `linear-gradient(to bottom, rgba(2, 7, 16, 0.95) 0%, rgba(2, 7, 16, 0.6) 45%, rgba(2, 7, 16, 0) 85%), url(${assetUrl('/assets/whyus_hologram.jpg')})`,
backgroundSize: 'cover',
backgroundPosition: 'center',
display: 'flex',
@@ -1695,7 +1695,7 @@ export default function App({ previewMode = false }) {
>
{/* Full-bleed image */}

{
- if (event.origin !== window.location.origin) return;
+ if (!origins.has(event.origin)) return;
if (event.data?.type !== 'ADMIN_PREVIEW' || !event.data.fullContent) return;
setContent(prefixAssets(event.data.fullContent));
@@ -68,7 +60,13 @@ export function ContentProvider({ children, previewMode = false }) {
};
window.addEventListener('message', onMessage);
- window.parent?.postMessage({ type: 'PREVIEW_READY' }, window.location.origin);
+ for (const origin of origins) {
+ try {
+ window.parent?.postMessage({ type: 'PREVIEW_READY' }, origin);
+ } catch {
+ /* ignore */
+ }
+ }
return () => window.removeEventListener('message', onMessage);
}, [previewMode]);
@@ -82,6 +80,6 @@ export function ContentProvider({ children, previewMode = false }) {
export function useContent() {
const ctx = useContext(ContentContext);
- if (!ctx) throw new Error('useContent must be used within ContentProvider');
+ if (!ctx) throw new Error('useContent must be used within a ContentProvider');
return ctx;
}
diff --git a/src/lib/assetUrl.js b/src/lib/assetUrl.js
new file mode 100644
index 0000000..68ec8ee
--- /dev/null
+++ b/src/lib/assetUrl.js
@@ -0,0 +1,62 @@
+/**
+ * Vite base, e.g. "/citpl_website/" in production and "/" in local dev.
+ */
+export const ASSET_BASE = (import.meta.env.BASE_URL || '/').endsWith('/')
+ ? (import.meta.env.BASE_URL || '/')
+ : `${import.meta.env.BASE_URL || ''}/`;
+
+/**
+ * Resolve content/seed asset paths for subdirectory deploys.
+ * "/assets/foo.svg" → "/citpl_website/assets/foo.svg" in prod
+ */
+export function assetUrl(path) {
+ if (!path || typeof path !== 'string') return path;
+
+ if (/^(data:|blob:)/i.test(path)) return path;
+
+ // Absolute URL wrongly pointing at domain-root /assets or /uploads
+ if (/^https?:\/\//i.test(path)) {
+ try {
+ const u = new URL(path);
+ if (u.pathname.startsWith('/assets/') || u.pathname.startsWith('/uploads/')) {
+ const prefix = ASSET_BASE.replace(/\/$/, '');
+ if (!u.pathname.startsWith(`${prefix}/`)) {
+ u.pathname = `${prefix}${u.pathname}`;
+ return u.href;
+ }
+ }
+ return path;
+ } catch {
+ return path;
+ }
+ }
+
+ const prefix = ASSET_BASE.replace(/\/$/, '');
+
+ // Already under the site base
+ if (prefix && (path === prefix || path.startsWith(`${prefix}/`))) {
+ return path;
+ }
+
+ if (path.startsWith('/assets/') || path.startsWith('/uploads/')) {
+ return `${prefix}${path}`;
+ }
+
+ if (path.startsWith('assets/') || path.startsWith('uploads/')) {
+ return `${ASSET_BASE}${path}`;
+ }
+
+ return path;
+}
+
+/** Recursively rewrite asset strings inside content JSON. */
+export function prefixAssets(obj) {
+ if (typeof obj === 'string') return assetUrl(obj);
+ if (Array.isArray(obj)) return obj.map(prefixAssets);
+ if (obj && typeof obj === 'object') {
+ const out = {};
+ for (const k in obj) out[k] = prefixAssets(obj[k]);
+ return out;
+ }
+ return obj;
+}