asset path and iframe setting
This commit is contained in:
Vendored
+8
-7
@@ -1,4 +1,4 @@
|
|||||||
# Deployed under /citpl_website/ — Apache must proxy API to the Node server.
|
# Deployed under /citpl_website/ - Apache must proxy API to the Node server.
|
||||||
# Requires: mod_rewrite, mod_proxy, mod_proxy_http, mod_headers
|
# Requires: mod_rewrite, mod_proxy, mod_proxy_http, mod_headers
|
||||||
# Start Node on the host: npm run server (or pm2 start server/index.js)
|
# Start Node on the host: npm run server (or pm2 start server/index.js)
|
||||||
|
|
||||||
@@ -11,17 +11,18 @@
|
|||||||
RewriteRule ^uploads/(.*)$ http://127.0.0.1:3001/uploads/$1 [P,L]
|
RewriteRule ^uploads/(.*)$ http://127.0.0.1:3001/uploads/$1 [P,L]
|
||||||
</IfModule>
|
</IfModule>
|
||||||
|
|
||||||
# Allow admin login preview iframe (same origin)
|
# Allow embedding from this site and https://demo.cavinkare.in/
|
||||||
|
# X-Frame-Options cannot allow a third origin - unset it and use CSP only.
|
||||||
<IfModule mod_headers.c>
|
<IfModule mod_headers.c>
|
||||||
Header always edit Content-Security-Policy "frame-ancestors 'none'" "frame-ancestors 'self'"
|
Header always unset X-Frame-Options
|
||||||
Header always edit X-Frame-Options "DENY" "SAMEORIGIN"
|
Header unset X-Frame-Options
|
||||||
|
Header always edit Content-Security-Policy "frame-ancestors 'none'" "frame-ancestors 'self' https://demo.cavinkare.in/"
|
||||||
|
|
||||||
<FilesMatch "^(preview\.html|index\.html)$">
|
<FilesMatch "^(preview\.html|index\.html|admin\.html)$">
|
||||||
Header unset X-Frame-Options
|
Header unset X-Frame-Options
|
||||||
Header always unset X-Frame-Options
|
Header always unset X-Frame-Options
|
||||||
Header unset Content-Security-Policy
|
Header unset Content-Security-Policy
|
||||||
Header always unset Content-Security-Policy
|
Header always unset Content-Security-Policy
|
||||||
Header always set X-Frame-Options "SAMEORIGIN"
|
Header always set Content-Security-Policy "frame-ancestors 'self' https://demo.cavinkare.in/"
|
||||||
Header always set Content-Security-Policy "frame-ancestors 'self'"
|
|
||||||
</FilesMatch>
|
</FilesMatch>
|
||||||
</IfModule>
|
</IfModule>
|
||||||
|
|||||||
Vendored
-1
File diff suppressed because one or more lines are too long
Vendored
+1
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
|
|||||||
import{c as e,l as t,m as n,u as r}from"./x-DnG5sti3.js";import{r as i,t as a}from"./App-CuujNhcz.js";var o=n(r(),1),s=t(),c=e();(0,s.createRoot)(document.getElementById(`root`)).render((0,c.jsx)(o.StrictMode,{children:(0,c.jsx)(i,{children:(0,c.jsx)(a,{})})}));
|
import{c as e,l as t,m as n,u as r}from"./x-DnG5sti3.js";import{r as i,t as a}from"./App-g0Gkzm_v.js";var o=n(r(),1),s=t(),c=e();(0,s.createRoot)(document.getElementById(`root`)).render((0,c.jsx)(o.StrictMode,{children:(0,c.jsx)(i,{children:(0,c.jsx)(a,{})})}));
|
||||||
@@ -1 +1 @@
|
|||||||
import{c as e,l as t,m as n,u as r}from"./x-DnG5sti3.js";import{n as i,r as a,t as o}from"./App-CuujNhcz.js";var s=n(r(),1),c=t(),l=e();function u(){return(0,s.useEffect)(()=>(document.body.classList.add(`admin-preview-embed`),()=>document.body.classList.remove(`admin-preview-embed`)),[]),(0,l.jsx)(o,{previewMode:!0})}(0,c.createRoot)(document.getElementById(`root`)).render((0,l.jsx)(s.StrictMode,{children:(0,l.jsx)(i.Provider,{value:!0,children:(0,l.jsx)(a,{previewMode:!0,children:(0,l.jsx)(u,{})})})}));
|
import{c as e,l as t,m as n,u as r}from"./x-DnG5sti3.js";import{n as i,r as a,t as o}from"./App-g0Gkzm_v.js";var s=n(r(),1),c=t(),l=e();function u(){return(0,s.useEffect)(()=>(document.body.classList.add(`admin-preview-embed`),()=>document.body.classList.remove(`admin-preview-embed`)),[]),(0,l.jsx)(o,{previewMode:!0})}(0,c.createRoot)(document.getElementById(`root`)).render((0,l.jsx)(s.StrictMode,{children:(0,l.jsx)(i.Provider,{value:!0,children:(0,l.jsx)(a,{previewMode:!0,children:(0,l.jsx)(u,{})})})}));
|
||||||
Vendored
+2
-2
@@ -5,9 +5,9 @@
|
|||||||
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<title>Cavin Infotech | One Trusted Technology Partner</title>
|
<title>Cavin Infotech | One Trusted Technology Partner</title>
|
||||||
<script type="module" crossorigin src="/citpl_website/assets/main-oTwpSzcd.js"></script>
|
<script type="module" crossorigin src="/citpl_website/assets/main-BxILBfZ3.js"></script>
|
||||||
<link rel="modulepreload" crossorigin href="/citpl_website/assets/x-DnG5sti3.js">
|
<link rel="modulepreload" crossorigin href="/citpl_website/assets/x-DnG5sti3.js">
|
||||||
<link rel="modulepreload" crossorigin href="/citpl_website/assets/App-CuujNhcz.js">
|
<link rel="modulepreload" crossorigin href="/citpl_website/assets/App-g0Gkzm_v.js">
|
||||||
<link rel="stylesheet" crossorigin href="/citpl_website/assets/App-DpUt8oMg.css">
|
<link rel="stylesheet" crossorigin href="/citpl_website/assets/App-DpUt8oMg.css">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|||||||
Vendored
+2
-2
@@ -4,9 +4,9 @@
|
|||||||
<meta charset="UTF-8" />
|
<meta charset="UTF-8" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<title>CITPL Preview</title>
|
<title>CITPL Preview</title>
|
||||||
<script type="module" crossorigin src="/citpl_website/assets/preview-C0prGlYe.js"></script>
|
<script type="module" crossorigin src="/citpl_website/assets/preview-wEp9RUMD.js"></script>
|
||||||
<link rel="modulepreload" crossorigin href="/citpl_website/assets/x-DnG5sti3.js">
|
<link rel="modulepreload" crossorigin href="/citpl_website/assets/x-DnG5sti3.js">
|
||||||
<link rel="modulepreload" crossorigin href="/citpl_website/assets/App-CuujNhcz.js">
|
<link rel="modulepreload" crossorigin href="/citpl_website/assets/App-g0Gkzm_v.js">
|
||||||
<link rel="stylesheet" crossorigin href="/citpl_website/assets/App-DpUt8oMg.css">
|
<link rel="stylesheet" crossorigin href="/citpl_website/assets/App-DpUt8oMg.css">
|
||||||
<link rel="stylesheet" crossorigin href="/citpl_website/assets/preview-DknkzKsF.css">
|
<link rel="stylesheet" crossorigin href="/citpl_website/assets/preview-DknkzKsF.css">
|
||||||
</head>
|
</head>
|
||||||
|
|||||||
+8
-7
@@ -1,4 +1,4 @@
|
|||||||
# Deployed under /citpl_website/ — Apache must proxy API to the Node server.
|
# Deployed under /citpl_website/ - Apache must proxy API to the Node server.
|
||||||
# Requires: mod_rewrite, mod_proxy, mod_proxy_http, mod_headers
|
# Requires: mod_rewrite, mod_proxy, mod_proxy_http, mod_headers
|
||||||
# Start Node on the host: npm run server (or pm2 start server/index.js)
|
# Start Node on the host: npm run server (or pm2 start server/index.js)
|
||||||
|
|
||||||
@@ -11,17 +11,18 @@
|
|||||||
RewriteRule ^uploads/(.*)$ http://127.0.0.1:3001/uploads/$1 [P,L]
|
RewriteRule ^uploads/(.*)$ http://127.0.0.1:3001/uploads/$1 [P,L]
|
||||||
</IfModule>
|
</IfModule>
|
||||||
|
|
||||||
# Allow admin login preview iframe (same origin)
|
# Allow embedding from this site and https://demo.cavinkare.in/
|
||||||
|
# X-Frame-Options cannot allow a third origin - unset it and use CSP only.
|
||||||
<IfModule mod_headers.c>
|
<IfModule mod_headers.c>
|
||||||
Header always edit Content-Security-Policy "frame-ancestors 'none'" "frame-ancestors 'self'"
|
Header always unset X-Frame-Options
|
||||||
Header always edit X-Frame-Options "DENY" "SAMEORIGIN"
|
Header unset X-Frame-Options
|
||||||
|
Header always edit Content-Security-Policy "frame-ancestors 'none'" "frame-ancestors 'self' https://demo.cavinkare.in/"
|
||||||
|
|
||||||
<FilesMatch "^(preview\.html|index\.html)$">
|
<FilesMatch "^(preview\.html|index\.html|admin\.html)$">
|
||||||
Header unset X-Frame-Options
|
Header unset X-Frame-Options
|
||||||
Header always unset X-Frame-Options
|
Header always unset X-Frame-Options
|
||||||
Header unset Content-Security-Policy
|
Header unset Content-Security-Policy
|
||||||
Header always unset Content-Security-Policy
|
Header always unset Content-Security-Policy
|
||||||
Header always set X-Frame-Options "SAMEORIGIN"
|
Header always set Content-Security-Policy "frame-ancestors 'self' https://demo.cavinkare.in/"
|
||||||
Header always set Content-Security-Policy "frame-ancestors 'self'"
|
|
||||||
</FilesMatch>
|
</FilesMatch>
|
||||||
</IfModule>
|
</IfModule>
|
||||||
|
|||||||
+26
-26
@@ -1,6 +1,6 @@
|
|||||||
import React, { useState, useEffect, useRef } from 'react';
|
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 { motion, useScroll, useTransform, useMotionValueEvent, useReducedMotion } from 'framer-motion';
|
||||||
import { useContent } from './context/ContentContext';
|
import { useContent } from './context/ContentContext';
|
||||||
import { usePreviewMode } from './context/PreviewContext';
|
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)'
|
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' }}>
|
<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>
|
</div>
|
||||||
|
|
||||||
{!isMobile && (
|
{!isMobile && (
|
||||||
@@ -608,7 +608,7 @@ export default function App({ previewMode = false }) {
|
|||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
<div className="btn-sparkle-wrapper">
|
<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)}>
|
<button className="btn-talk" onClick={() => setIsStrategyOpen(true)}>
|
||||||
Book a Strategy Call
|
Book a Strategy Call
|
||||||
</button>
|
</button>
|
||||||
@@ -728,7 +728,7 @@ export default function App({ previewMode = false }) {
|
|||||||
pointerEvents: 'none'
|
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.
|
Your browser does not support the video tag.
|
||||||
</video>
|
</video>
|
||||||
|
|
||||||
@@ -937,7 +937,7 @@ export default function App({ previewMode = false }) {
|
|||||||
{/* Globe Visual */}
|
{/* Globe Visual */}
|
||||||
<div style={{ position: 'relative', width: '280px', height: '280px', display: 'flex', justifyContent: 'center', alignItems: 'center' }}>
|
<div style={{ position: 'relative', width: '280px', height: '280px', display: 'flex', justifyContent: 'center', alignItems: 'center' }}>
|
||||||
<img
|
<img
|
||||||
src={`${BASE}assets/GlobeVector.svg`}
|
src={assetUrl('/assets/GlobeVector.svg')}
|
||||||
alt="Globe Map"
|
alt="Globe Map"
|
||||||
style={{ width: '100%', height: '100%', objectFit: 'contain', opacity: 0.3 }}
|
style={{ width: '100%', height: '100%', objectFit: 'contain', opacity: 0.3 }}
|
||||||
/>
|
/>
|
||||||
@@ -962,7 +962,7 @@ export default function App({ previewMode = false }) {
|
|||||||
padding: '0.2rem',
|
padding: '0.2rem',
|
||||||
}}>
|
}}>
|
||||||
<img
|
<img
|
||||||
src={logo.image}
|
src={assetUrl(logo.image)}
|
||||||
alt={logo.name}
|
alt={logo.name}
|
||||||
style={{ maxHeight: '100%', maxWidth: '100%', objectFit: 'contain' }}
|
style={{ maxHeight: '100%', maxWidth: '100%', objectFit: 'contain' }}
|
||||||
/>
|
/>
|
||||||
@@ -982,7 +982,7 @@ export default function App({ previewMode = false }) {
|
|||||||
|
|
||||||
{/* Globe in background - Increased Size & Brightness */}
|
{/* Globe in background - Increased Size & Brightness */}
|
||||||
<img
|
<img
|
||||||
src={`${BASE}assets/GlobeVector.svg`}
|
src={assetUrl('/assets/GlobeVector.svg')}
|
||||||
alt="Globe Map"
|
alt="Globe Map"
|
||||||
style={{
|
style={{
|
||||||
position: 'absolute',
|
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 */}
|
{/* orbital logos with smooth continuous motion in horizontally elongated oval paths - No Skewing */}
|
||||||
{/* Outer Orbit - Increased size further to radiusX=520, radiusY=320 */}
|
{/* 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={assetUrl('/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={assetUrl('/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={assetUrl('/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={assetUrl('/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 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 */}
|
{/* 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={assetUrl('/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={assetUrl('/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={assetUrl('/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={assetUrl('/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 27.svg')} alt="CavinKare Logo" radiusX={360} radiusY={225} startAngle={324} duration={40} clockwise={false} size={180} />
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
@@ -1104,7 +1104,7 @@ export default function App({ previewMode = false }) {
|
|||||||
transition: 'all 0.3s ease'
|
transition: 'all 0.3s ease'
|
||||||
}}>
|
}}>
|
||||||
<img
|
<img
|
||||||
src={cert.image}
|
src={assetUrl(cert.image)}
|
||||||
alt={cert.alt}
|
alt={cert.alt}
|
||||||
style={{
|
style={{
|
||||||
height: idx === 0 ? '85%' : idx === 3 ? '55%' : idx === 4 ? '100%' : '80%',
|
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={{
|
<div className="glass-card" style={{
|
||||||
padding: '2rem 1.8rem',
|
padding: '2rem 1.8rem',
|
||||||
borderRadius: '20px',
|
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',
|
backgroundSize: 'cover',
|
||||||
backgroundPosition: 'center',
|
backgroundPosition: 'center',
|
||||||
border: '1px solid rgba(255, 255, 255, 0.06)',
|
border: '1px solid rgba(255, 255, 255, 0.06)',
|
||||||
@@ -1431,7 +1431,7 @@ export default function App({ previewMode = false }) {
|
|||||||
height: '100%'
|
height: '100%'
|
||||||
}}>
|
}}>
|
||||||
<img
|
<img
|
||||||
src={`${BASE}assets/whyus_arab_meeting.jpg`}
|
src={assetUrl('/assets/whyus_arab_meeting.jpg')}
|
||||||
alt="Corporate collaboration"
|
alt="Corporate collaboration"
|
||||||
style={{ width: '100%', height: '100%', objectFit: 'cover' }}
|
style={{ width: '100%', height: '100%', objectFit: 'cover' }}
|
||||||
/>
|
/>
|
||||||
@@ -1501,7 +1501,7 @@ export default function App({ previewMode = false }) {
|
|||||||
height: '100%'
|
height: '100%'
|
||||||
}}>
|
}}>
|
||||||
<img
|
<img
|
||||||
src={`${BASE}assets/whyus_vr_man.jpg`}
|
src={assetUrl('/assets/whyus_vr_man.jpg')}
|
||||||
alt="Sunset boardroom"
|
alt="Sunset boardroom"
|
||||||
style={{ width: '100%', height: '100%', objectFit: 'cover' }}
|
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)',
|
border: '1px solid rgba(255, 255, 255, 0.06)',
|
||||||
position: 'relative',
|
position: 'relative',
|
||||||
overflow: 'hidden',
|
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',
|
backgroundSize: 'cover',
|
||||||
backgroundPosition: 'center',
|
backgroundPosition: 'center',
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
@@ -1695,7 +1695,7 @@ export default function App({ previewMode = false }) {
|
|||||||
>
|
>
|
||||||
{/* Full-bleed image */}
|
{/* Full-bleed image */}
|
||||||
<img
|
<img
|
||||||
src={insight.image}
|
src={assetUrl(insight.image)}
|
||||||
alt={insight.title}
|
alt={insight.title}
|
||||||
className="blog-card-img"
|
className="blog-card-img"
|
||||||
style={{
|
style={{
|
||||||
@@ -1775,7 +1775,7 @@ export default function App({ previewMode = false }) {
|
|||||||
padding: '4rem 0 0 0',
|
padding: '4rem 0 0 0',
|
||||||
}}>
|
}}>
|
||||||
<img
|
<img
|
||||||
src={`${BASE}assets/citp_footer_design.png`}
|
src={assetUrl('/assets/citp_footer_design.png')}
|
||||||
alt="Cavin Infotech Logo Divider"
|
alt="Cavin Infotech Logo Divider"
|
||||||
style={{
|
style={{
|
||||||
width: '100%',
|
width: '100%',
|
||||||
@@ -1851,7 +1851,7 @@ export default function App({ previewMode = false }) {
|
|||||||
{/* Phone mockup container on mobile */}
|
{/* Phone mockup container on mobile */}
|
||||||
<div style={{ width: '100%', height: '180px', position: 'relative', overflow: 'hidden', borderRadius: '12px' }}>
|
<div style={{ width: '100%', height: '180px', position: 'relative', overflow: 'hidden', borderRadius: '12px' }}>
|
||||||
<img
|
<img
|
||||||
src={footer.cta.image}
|
src={assetUrl(footer.cta.image)}
|
||||||
alt="Phone preview"
|
alt="Phone preview"
|
||||||
style={{
|
style={{
|
||||||
position: 'absolute',
|
position: 'absolute',
|
||||||
@@ -1870,7 +1870,7 @@ export default function App({ previewMode = false }) {
|
|||||||
<Reveal>
|
<Reveal>
|
||||||
<div style={{ position: 'relative', width: '100%', marginBottom: '3rem' }}>
|
<div style={{ position: 'relative', width: '100%', marginBottom: '3rem' }}>
|
||||||
<img
|
<img
|
||||||
src={footer.cta.image}
|
src={assetUrl(footer.cta.image)}
|
||||||
alt="CTA Banner"
|
alt="CTA Banner"
|
||||||
style={{
|
style={{
|
||||||
width: '100%',
|
width: '100%',
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import React, { useState } from 'react';
|
import React, { useState } from 'react';
|
||||||
import { motion, AnimatePresence, useReducedMotion } from 'framer-motion';
|
import { motion, AnimatePresence, useReducedMotion } from 'framer-motion';
|
||||||
import { ArrowRight, Clock } from 'lucide-react';
|
import { ArrowRight, Clock } from 'lucide-react';
|
||||||
|
import { assetUrl } from '../lib/assetUrl';
|
||||||
|
|
||||||
export default function FeaturedGallery({ gallery }) {
|
export default function FeaturedGallery({ gallery }) {
|
||||||
const galleryData = gallery?.items || [];
|
const galleryData = gallery?.items || [];
|
||||||
@@ -82,7 +83,7 @@ function ResponsiveGalleryWrapper({ galleryData, activeIdx, setActiveIdx }) {
|
|||||||
border: '1px solid rgba(255, 255, 255, 0.06)',
|
border: '1px solid rgba(255, 255, 255, 0.06)',
|
||||||
position: 'relative',
|
position: 'relative',
|
||||||
height: isFirst ? '320px' : '240px',
|
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',
|
backgroundSize: 'cover',
|
||||||
backgroundPosition: 'center',
|
backgroundPosition: 'center',
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
@@ -171,7 +172,7 @@ function ResponsiveGalleryWrapper({ galleryData, activeIdx, setActiveIdx }) {
|
|||||||
left: 0,
|
left: 0,
|
||||||
right: 0,
|
right: 0,
|
||||||
bottom: 0,
|
bottom: 0,
|
||||||
backgroundImage: `url(${item.image})`,
|
backgroundImage: `url(${assetUrl(item.image)})`,
|
||||||
backgroundSize: 'cover',
|
backgroundSize: 'cover',
|
||||||
backgroundPosition: 'center',
|
backgroundPosition: 'center',
|
||||||
zIndex: 1
|
zIndex: 1
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { motion, useReducedMotion } from 'framer-motion';
|
import { motion, useReducedMotion } from 'framer-motion';
|
||||||
|
import { assetUrl } from '../lib/assetUrl';
|
||||||
|
|
||||||
const ACCENT_GRADIENTS = [
|
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%)',
|
'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',
|
background: 'transparent',
|
||||||
}}>
|
}}>
|
||||||
<img
|
<img
|
||||||
src={product.image}
|
src={assetUrl(product.image)}
|
||||||
alt={`${product.name} dashboard`}
|
alt={`${product.name} dashboard`}
|
||||||
style={{
|
style={{
|
||||||
position: 'absolute',
|
position: 'absolute',
|
||||||
|
|||||||
@@ -1,23 +1,14 @@
|
|||||||
import { createContext, useContext, useEffect, useState } from 'react';
|
import { createContext, useContext, useEffect, useState } from 'react';
|
||||||
import defaultContent from '../../server/seed/default-content.json';
|
import defaultContent from '../../server/seed/default-content.json';
|
||||||
import { API_BASE } from '../lib/apiBase';
|
import { API_BASE } from '../lib/apiBase';
|
||||||
|
import { prefixAssets } from '../lib/assetUrl';
|
||||||
|
|
||||||
const ContentContext = createContext(null);
|
const ContentContext = createContext(null);
|
||||||
|
|
||||||
const BASE = import.meta.env.BASE_URL;
|
function allowedPreviewOrigins() {
|
||||||
|
const origins = new Set(['https://demo.cavinkare.in/', 'https://demo.cavinkare.in']);
|
||||||
// Recursively prefix /assets/ paths with the Vite base URL
|
if (typeof window !== 'undefined') origins.add(window.location.origin);
|
||||||
function prefixAssets(obj) {
|
return origins;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function ContentProvider({ children, previewMode = false }) {
|
export function ContentProvider({ children, previewMode = false }) {
|
||||||
@@ -51,9 +42,10 @@ export function ContentProvider({ children, previewMode = false }) {
|
|||||||
if (!previewMode) return;
|
if (!previewMode) return;
|
||||||
|
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
|
const origins = allowedPreviewOrigins();
|
||||||
|
|
||||||
const onMessage = (event) => {
|
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;
|
if (event.data?.type !== 'ADMIN_PREVIEW' || !event.data.fullContent) return;
|
||||||
|
|
||||||
setContent(prefixAssets(event.data.fullContent));
|
setContent(prefixAssets(event.data.fullContent));
|
||||||
@@ -68,7 +60,13 @@ export function ContentProvider({ children, previewMode = false }) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
window.addEventListener('message', onMessage);
|
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);
|
return () => window.removeEventListener('message', onMessage);
|
||||||
}, [previewMode]);
|
}, [previewMode]);
|
||||||
@@ -82,6 +80,6 @@ export function ContentProvider({ children, previewMode = false }) {
|
|||||||
|
|
||||||
export function useContent() {
|
export function useContent() {
|
||||||
const ctx = useContext(ContentContext);
|
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;
|
return ctx;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user