asset path and iframe setting

This commit is contained in:
sandhiya-hepl
2026-07-16 10:57:25 +05:30
parent ed459d5943
commit 5b27debfa8
13 changed files with 131 additions and 67 deletions
+26 -26
View File
@@ -1,6 +1,6 @@
import React, { useState, useEffect, useRef } from 'react';
const BASE = import.meta.env.BASE_URL;
import { assetUrl } from './lib/assetUrl';
import { motion, useScroll, useTransform, useMotionValueEvent, useReducedMotion } from 'framer-motion';
import { useContent } from './context/ContentContext';
import { usePreviewMode } from './context/PreviewContext';
@@ -566,7 +566,7 @@ export default function App({ previewMode = false }) {
borderBottom: activeSection === 'products' ? '1px solid rgba(15, 23, 42, 0.08)' : '1px solid rgba(255, 255, 255, 0.05)'
}}>
<div style={{ display: 'flex', alignItems: 'center' }}>
<img src={`${BASE}assets/cavin_logo.svg`} alt="Cavin Infotech Logo" style={{ height: isMobile ? '38px' : '50px', display: 'block' }} />
<img src={assetUrl('/assets/cavin_logo.svg')} alt="Cavin Infotech Logo" style={{ height: isMobile ? '38px' : '50px', display: 'block' }} />
</div>
{!isMobile && (
@@ -608,7 +608,7 @@ export default function App({ previewMode = false }) {
);
})}
<div className="btn-sparkle-wrapper">
<img src={`${BASE}assets/button_hover_effect.png`} className="btn-sparkles" alt="" />
<img src={assetUrl('/assets/button_hover_effect.png')} className="btn-sparkles" alt="" />
<button className="btn-talk" onClick={() => setIsStrategyOpen(true)}>
Book a Strategy Call
</button>
@@ -728,7 +728,7 @@ export default function App({ previewMode = false }) {
pointerEvents: 'none'
}}
>
<source src={`${hero.video}?v=2`} type="video/mp4" />
<source src={`${assetUrl(hero.video)}?v=2`} type="video/mp4" />
Your browser does not support the video tag.
</video>
@@ -937,7 +937,7 @@ export default function App({ previewMode = false }) {
{/* Globe Visual */}
<div style={{ position: 'relative', width: '280px', height: '280px', display: 'flex', justifyContent: 'center', alignItems: 'center' }}>
<img
src={`${BASE}assets/GlobeVector.svg`}
src={assetUrl('/assets/GlobeVector.svg')}
alt="Globe Map"
style={{ width: '100%', height: '100%', objectFit: 'contain', opacity: 0.3 }}
/>
@@ -962,7 +962,7 @@ export default function App({ previewMode = false }) {
padding: '0.2rem',
}}>
<img
src={logo.image}
src={assetUrl(logo.image)}
alt={logo.name}
style={{ maxHeight: '100%', maxWidth: '100%', objectFit: 'contain' }}
/>
@@ -982,7 +982,7 @@ export default function App({ previewMode = false }) {
{/* Globe in background - Increased Size & Brightness */}
<img
src={`${BASE}assets/GlobeVector.svg`}
src={assetUrl('/assets/GlobeVector.svg')}
alt="Globe Map"
style={{
position: 'absolute',
@@ -1045,18 +1045,18 @@ export default function App({ previewMode = false }) {
{/* orbital logos with smooth continuous motion in horizontally elongated oval paths - No Skewing */}
{/* Outer Orbit - Increased size further to radiusX=520, radiusY=320 */}
<OrbitalLogo src={`${BASE}assets/Frame 33.svg`} alt="MRF Logo" radiusX={520} radiusY={320} startAngle={0} duration={60} clockwise={true} size={170} />
<OrbitalLogo src={`${BASE}assets/Frame 31.svg`} alt="ACA Global Logo" radiusX={520} radiusY={320} startAngle={78} duration={60} clockwise={true} size={175} />
<OrbitalLogo src={`${BASE}assets/Frame 30.svg`} alt="Polyhose Logo" radiusX={520} radiusY={320} startAngle={144} duration={60} clockwise={true} size={170} />
<OrbitalLogo src={`${BASE}assets/Frame 32.svg`} alt="Dawn Pictures Logo" radiusX={520} radiusY={320} startAngle={216} duration={60} clockwise={true} size={180} />
<OrbitalLogo src={`${BASE}assets/Frame 35.svg`} alt="Hero Logo" radiusX={520} radiusY={320} startAngle={282} duration={60} clockwise={true} size={170} />
<OrbitalLogo src={assetUrl('/assets/Frame 33.svg')} alt="MRF Logo" radiusX={520} radiusY={320} startAngle={0} duration={60} clockwise={true} size={170} />
<OrbitalLogo src={assetUrl('/assets/Frame 31.svg')} alt="ACA Global Logo" radiusX={520} radiusY={320} startAngle={78} duration={60} clockwise={true} size={175} />
<OrbitalLogo src={assetUrl('/assets/Frame 30.svg')} alt="Polyhose Logo" radiusX={520} radiusY={320} startAngle={144} duration={60} clockwise={true} size={170} />
<OrbitalLogo src={assetUrl('/assets/Frame 32.svg')} alt="Dawn Pictures Logo" radiusX={520} radiusY={320} startAngle={216} duration={60} clockwise={true} size={180} />
<OrbitalLogo src={assetUrl('/assets/Frame 35.svg')} alt="Hero Logo" radiusX={520} radiusY={320} startAngle={282} duration={60} clockwise={true} size={170} />
{/* Inner Orbit - Adjusted size to radiusX=360, radiusY=225 */}
<OrbitalLogo src={`${BASE}assets/Frame 28.svg`} alt="Valeo Logo" radiusX={360} radiusY={225} startAngle={36} duration={40} clockwise={false} size={170} />
<OrbitalLogo src={`${BASE}assets/Frame 36.svg`} alt="BorgWarner Logo" radiusX={360} radiusY={225} startAngle={108} duration={40} clockwise={false} size={170} />
<OrbitalLogo src={`${BASE}assets/kone.png`} alt="KONE Logo" radiusX={360} radiusY={225} startAngle={180} duration={40} clockwise={false} size={160} />
<OrbitalLogo src={`${BASE}assets/Frame 34.svg`} alt="Chola MS Logo" radiusX={360} radiusY={225} startAngle={252} duration={40} clockwise={false} size={170} />
<OrbitalLogo src={`${BASE}assets/Frame 27.svg`} alt="CavinKare Logo" radiusX={360} radiusY={225} startAngle={324} duration={40} clockwise={false} size={180} />
<OrbitalLogo src={assetUrl('/assets/Frame 28.svg')} alt="Valeo Logo" radiusX={360} radiusY={225} startAngle={36} duration={40} clockwise={false} size={170} />
<OrbitalLogo src={assetUrl('/assets/Frame 36.svg')} alt="BorgWarner Logo" radiusX={360} radiusY={225} startAngle={108} duration={40} clockwise={false} size={170} />
<OrbitalLogo src={assetUrl('/assets/kone.png')} alt="KONE Logo" radiusX={360} radiusY={225} startAngle={180} duration={40} clockwise={false} size={160} />
<OrbitalLogo src={assetUrl('/assets/Frame 34.svg')} alt="Chola MS Logo" radiusX={360} radiusY={225} startAngle={252} duration={40} clockwise={false} size={170} />
<OrbitalLogo src={assetUrl('/assets/Frame 27.svg')} alt="CavinKare Logo" radiusX={360} radiusY={225} startAngle={324} duration={40} clockwise={false} size={180} />
</div>
)}
@@ -1104,7 +1104,7 @@ export default function App({ previewMode = false }) {
transition: 'all 0.3s ease'
}}>
<img
src={cert.image}
src={assetUrl(cert.image)}
alt={cert.alt}
style={{
height: idx === 0 ? '85%' : idx === 3 ? '55%' : idx === 4 ? '100%' : '80%',
@@ -1369,7 +1369,7 @@ export default function App({ previewMode = false }) {
<div className="glass-card" style={{
padding: '2rem 1.8rem',
borderRadius: '20px',
background: `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)`,
background: `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',
border: '1px solid rgba(255, 255, 255, 0.06)',
@@ -1431,7 +1431,7 @@ export default function App({ previewMode = false }) {
height: '100%'
}}>
<img
src={`${BASE}assets/whyus_arab_meeting.jpg`}
src={assetUrl('/assets/whyus_arab_meeting.jpg')}
alt="Corporate collaboration"
style={{ width: '100%', height: '100%', objectFit: 'cover' }}
/>
@@ -1501,7 +1501,7 @@ export default function App({ previewMode = false }) {
height: '100%'
}}>
<img
src={`${BASE}assets/whyus_vr_man.jpg`}
src={assetUrl('/assets/whyus_vr_man.jpg')}
alt="Sunset boardroom"
style={{ width: '100%', height: '100%', objectFit: 'cover' }}
/>
@@ -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 */}
<img
src={insight.image}
src={assetUrl(insight.image)}
alt={insight.title}
className="blog-card-img"
style={{
@@ -1775,7 +1775,7 @@ export default function App({ previewMode = false }) {
padding: '4rem 0 0 0',
}}>
<img
src={`${BASE}assets/citp_footer_design.png`}
src={assetUrl('/assets/citp_footer_design.png')}
alt="Cavin Infotech Logo Divider"
style={{
width: '100%',
@@ -1851,7 +1851,7 @@ export default function App({ previewMode = false }) {
{/* Phone mockup container on mobile */}
<div style={{ width: '100%', height: '180px', position: 'relative', overflow: 'hidden', borderRadius: '12px' }}>
<img
src={footer.cta.image}
src={assetUrl(footer.cta.image)}
alt="Phone preview"
style={{
position: 'absolute',
@@ -1870,7 +1870,7 @@ export default function App({ previewMode = false }) {
<Reveal>
<div style={{ position: 'relative', width: '100%', marginBottom: '3rem' }}>
<img
src={footer.cta.image}
src={assetUrl(footer.cta.image)}
alt="CTA Banner"
style={{
width: '100%',
+3 -2
View File
@@ -1,6 +1,7 @@
import React, { useState } from 'react';
import { motion, AnimatePresence, useReducedMotion } from 'framer-motion';
import { ArrowRight, Clock } from 'lucide-react';
import { assetUrl } from '../lib/assetUrl';
export default function FeaturedGallery({ gallery }) {
const galleryData = gallery?.items || [];
@@ -82,7 +83,7 @@ function ResponsiveGalleryWrapper({ galleryData, activeIdx, setActiveIdx }) {
border: '1px solid rgba(255, 255, 255, 0.06)',
position: 'relative',
height: isFirst ? '320px' : '240px',
backgroundImage: `linear-gradient(to bottom, rgba(2, 7, 16, 0.3) 0%, rgba(2, 7, 16, 0.95) 100%), url(${item.image})`,
backgroundImage: `linear-gradient(to bottom, rgba(2, 7, 16, 0.3) 0%, rgba(2, 7, 16, 0.95) 100%), url(${assetUrl(item.image)})`,
backgroundSize: 'cover',
backgroundPosition: 'center',
display: 'flex',
@@ -171,7 +172,7 @@ function ResponsiveGalleryWrapper({ galleryData, activeIdx, setActiveIdx }) {
left: 0,
right: 0,
bottom: 0,
backgroundImage: `url(${item.image})`,
backgroundImage: `url(${assetUrl(item.image)})`,
backgroundSize: 'cover',
backgroundPosition: 'center',
zIndex: 1
+2 -1
View File
@@ -1,4 +1,5 @@
import { motion, useReducedMotion } from 'framer-motion';
import { assetUrl } from '../lib/assetUrl';
const ACCENT_GRADIENTS = [
'radial-gradient(circle at top right, rgba(139, 92, 246, 0.08) 0%, transparent 50%), linear-gradient(to bottom, #FAF9FA 0%, #F6F2F5 100%)',
@@ -114,7 +115,7 @@ export default function ProductCard({ product, isMobile, delay = 0, index = 0 })
background: 'transparent',
}}>
<img
src={product.image}
src={assetUrl(product.image)}
alt={`${product.name} dashboard`}
style={{
position: 'absolute',
+15 -17
View File
@@ -1,23 +1,14 @@
import { createContext, useContext, useEffect, useState } from 'react';
import defaultContent from '../../server/seed/default-content.json';
import { API_BASE } from '../lib/apiBase';
import { prefixAssets } from '../lib/assetUrl';
const ContentContext = createContext(null);
const BASE = import.meta.env.BASE_URL;
// Recursively prefix /assets/ paths with the Vite base URL
function prefixAssets(obj) {
if (typeof obj === 'string') {
return obj.startsWith('/assets/') ? `${BASE}${obj.slice(1)}` : 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;
function allowedPreviewOrigins() {
const origins = new Set(['https://demo.cavinkare.in/', 'https://demo.cavinkare.in']);
if (typeof window !== 'undefined') origins.add(window.location.origin);
return origins;
}
export function ContentProvider({ children, previewMode = false }) {
@@ -51,9 +42,10 @@ export function ContentProvider({ children, previewMode = false }) {
if (!previewMode) return;
setLoading(false);
const origins = allowedPreviewOrigins();
const onMessage = (event) => {
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;
}
+62
View File
@@ -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;
}