Adjust navigation flow, clean up JSX markup and defaults in App.jsx
This commit is contained in:
+71
-89
@@ -150,11 +150,11 @@ function ServiceCard({ service, isMobile, index = 0 }) {
|
|||||||
];
|
];
|
||||||
|
|
||||||
const formatTitle = (title) => {
|
const formatTitle = (title) => {
|
||||||
if (title.includes('AI & Data')) return <>AI & Data<br/>Services</>;
|
if (title.includes('AI & Data')) return <>AI & Data<br />Services</>;
|
||||||
if (title.includes('Enterprise')) return <>Enterprise<br/>Software</>;
|
if (title.includes('Enterprise')) return <>Enterprise<br />Software</>;
|
||||||
if (title.includes('SAP')) return <>SAP Managed<br/>Services</>;
|
if (title.includes('SAP')) return <>SAP Managed<br />Services</>;
|
||||||
if (title.includes('Smart')) return <>Smart<br/>Factory</>;
|
if (title.includes('Smart')) return <>Smart<br />Factory</>;
|
||||||
if (title.includes('AR/VR')) return <>AR/VR &<br/>Immersive<br/>Technologies</>;
|
if (title.includes('AR/VR')) return <>AR/VR &<br />Immersive<br />Technologies</>;
|
||||||
return title;
|
return title;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -379,12 +379,7 @@ export default function App({ previewMode = false }) {
|
|||||||
const [isMobile, setIsMobile] = useState(false);
|
const [isMobile, setIsMobile] = useState(false);
|
||||||
const [isCareersOpen, setIsCareersOpen] = useState(false);
|
const [isCareersOpen, setIsCareersOpen] = useState(false);
|
||||||
const [activeSection, setActiveSection] = useState('home');
|
const [activeSection, setActiveSection] = useState('home');
|
||||||
const [currentPage, setCurrentPage] = useState(() => {
|
const [currentPage, setCurrentPage] = useState('home');
|
||||||
const hash = typeof window !== 'undefined' ? window.location.hash : '';
|
|
||||||
if (hash === '#contact' || hash === '#contactus') return 'contact';
|
|
||||||
if (hash === '#about' || hash === '#aboutus') return 'about';
|
|
||||||
return 'home';
|
|
||||||
});
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const syncPageFromHash = () => {
|
const syncPageFromHash = () => {
|
||||||
@@ -550,23 +545,15 @@ export default function App({ previewMode = false }) {
|
|||||||
const NAV_OFFSET = isMobile ? 72 : 88;
|
const NAV_OFFSET = isMobile ? 72 : 88;
|
||||||
|
|
||||||
const scrollToSection = (sectionId) => {
|
const scrollToSection = (sectionId) => {
|
||||||
if (sectionId === 'contactus') {
|
|
||||||
const footer = document.getElementById('contactus');
|
|
||||||
if (footer) {
|
|
||||||
const top = footer.getBoundingClientRect().top + window.scrollY - NAV_OFFSET;
|
|
||||||
window.scrollTo({ top: Math.max(0, top), behavior: 'smooth' });
|
|
||||||
} else {
|
|
||||||
window.scrollTo({ top: document.documentElement.scrollHeight, behavior: 'smooth' });
|
|
||||||
}
|
|
||||||
setActiveSection('contactus');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const el = document.getElementById(sectionId);
|
const el = document.getElementById(sectionId);
|
||||||
if (!el) return;
|
if (el) {
|
||||||
const top = el.getBoundingClientRect().top + window.scrollY - NAV_OFFSET;
|
const top = el.getBoundingClientRect().top + window.scrollY - NAV_OFFSET;
|
||||||
window.scrollTo({ top: Math.max(0, top), behavior: 'smooth' });
|
window.scrollTo({ top, behavior: 'smooth' });
|
||||||
setActiveSection(sectionId);
|
setActiveSection(sectionId);
|
||||||
|
} else if (sectionId === 'contactus') {
|
||||||
|
window.scrollTo({ top: document.documentElement.scrollHeight, behavior: 'smooth' });
|
||||||
|
setActiveSection('contactus');
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleNavClick = (item) => {
|
const handleNavClick = (item) => {
|
||||||
@@ -594,28 +581,33 @@ export default function App({ previewMode = false }) {
|
|||||||
|
|
||||||
const sectionMap = {
|
const sectionMap = {
|
||||||
Home: 'home',
|
Home: 'home',
|
||||||
'About Us': 'aboutus',
|
|
||||||
Products: 'products',
|
Products: 'products',
|
||||||
};
|
};
|
||||||
const id = sectionMap[item];
|
const id = sectionMap[item];
|
||||||
|
|
||||||
|
const doScroll = (sectionId) => {
|
||||||
|
if (!sectionId || sectionId === 'home') {
|
||||||
|
window.scrollTo({ top: 0, behavior: 'smooth' });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
requestAnimationFrame(() => {
|
||||||
|
const el = document.getElementById(sectionId);
|
||||||
|
if (el) {
|
||||||
|
const top = el.getBoundingClientRect().top + window.scrollY - NAV_OFFSET;
|
||||||
|
window.scrollTo({ top, behavior: 'smooth' });
|
||||||
|
setActiveSection(sectionId);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
if (currentPage !== 'home') {
|
if (currentPage !== 'home') {
|
||||||
setCurrentPage('home');
|
setCurrentPage('home');
|
||||||
setActiveSection(id || 'home');
|
setActiveSection(id || 'home');
|
||||||
window.location.hash = id || 'home';
|
setTimeout(() => doScroll(id), 350);
|
||||||
setTimeout(() => {
|
|
||||||
if (id && id !== 'home') {
|
|
||||||
scrollToSection(id);
|
|
||||||
} else {
|
|
||||||
window.scrollTo({ top: 0, behavior: 'smooth' });
|
|
||||||
}
|
|
||||||
}, 100);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!id) return;
|
doScroll(id);
|
||||||
window.location.hash = id;
|
|
||||||
setTimeout(() => scrollToSection(id), isMobile ? 150 : 0);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -738,7 +730,7 @@ export default function App({ previewMode = false }) {
|
|||||||
return (
|
return (
|
||||||
<a
|
<a
|
||||||
key={item}
|
key={item}
|
||||||
href={item === 'Careers' ? undefined : `#${item.toLowerCase().replace(' ', '')}`}
|
href={(item === 'Careers' || item === 'Products') ? undefined : `#${item.toLowerCase().replace(' ', '')}`}
|
||||||
onClick={(e) => {
|
onClick={(e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
handleNavClick(item);
|
handleNavClick(item);
|
||||||
@@ -1385,7 +1377,8 @@ export default function App({ previewMode = false }) {
|
|||||||
backgroundColor: '#070d18',
|
backgroundColor: '#070d18',
|
||||||
position: 'relative',
|
position: 'relative',
|
||||||
overflow: 'hidden',
|
overflow: 'hidden',
|
||||||
borderBottom: '1px solid rgba(255, 255, 255, 0.04)'
|
borderBottom: '1px solid rgba(255, 255, 255, 0.04)',
|
||||||
|
scrollMarginTop: `${NAV_OFFSET}px`
|
||||||
}}>
|
}}>
|
||||||
{/* Background Ambient Glow matching screenshot */}
|
{/* Background Ambient Glow matching screenshot */}
|
||||||
<div style={{
|
<div style={{
|
||||||
@@ -1824,7 +1817,8 @@ export default function App({ previewMode = false }) {
|
|||||||
padding: isMobile ? '4rem 1.25rem' : '6rem 4rem',
|
padding: isMobile ? '4rem 1.25rem' : '6rem 4rem',
|
||||||
background: 'linear-gradient(180deg, #2791a5 0%, #0f4652 35%, #020710 100%)',
|
background: 'linear-gradient(180deg, #2791a5 0%, #0f4652 35%, #020710 100%)',
|
||||||
position: 'relative',
|
position: 'relative',
|
||||||
overflow: 'hidden'
|
overflow: 'hidden',
|
||||||
|
scrollMarginTop: `${NAV_OFFSET}px`
|
||||||
}}>
|
}}>
|
||||||
{/* Wave Pattern Overlay */}
|
{/* Wave Pattern Overlay */}
|
||||||
<img
|
<img
|
||||||
@@ -1891,42 +1885,7 @@ export default function App({ previewMode = false }) {
|
|||||||
Plus many more specialized solutions: LiveWire, Nucleus, Digital Meeting Agenda, SEC, XR Workbench, TMS, and others - purpose-built for manufacturing and enterprise excellence.
|
Plus many more specialized solutions: LiveWire, Nucleus, Digital Meeting Agenda, SEC, XR Workbench, TMS, and others - purpose-built for manufacturing and enterprise excellence.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
{/* Bottom CTA Button */}
|
|
||||||
<div style={{ display: 'flex', justifyContent: 'center' }}>
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
onClick={() => scrollToSection('contactus')}
|
|
||||||
style={{
|
|
||||||
display: 'inline-flex',
|
|
||||||
alignItems: 'center',
|
|
||||||
gap: '0.6rem',
|
|
||||||
background: 'rgba(255, 255, 255, 0.05)',
|
|
||||||
border: '1.5px solid rgba(255, 255, 255, 0.35)',
|
|
||||||
boxShadow: '0 8px 25px rgba(0, 0, 0, 0.3)',
|
|
||||||
borderRadius: '50px',
|
|
||||||
color: '#ffffff',
|
|
||||||
padding: '0.75rem 2rem',
|
|
||||||
fontSize: '0.92rem',
|
|
||||||
fontWeight: 600,
|
|
||||||
cursor: 'pointer',
|
|
||||||
transition: 'all 0.25s ease',
|
|
||||||
backdropFilter: 'blur(10px)'
|
|
||||||
}}
|
|
||||||
onMouseEnter={(e) => {
|
|
||||||
e.currentTarget.style.background = 'rgba(255, 255, 255, 0.12)';
|
|
||||||
e.currentTarget.style.borderColor = 'rgba(255, 255, 255, 0.6)';
|
|
||||||
e.currentTarget.style.transform = 'translateY(-2px)';
|
|
||||||
}}
|
|
||||||
onMouseLeave={(e) => {
|
|
||||||
e.currentTarget.style.background = 'rgba(255, 255, 255, 0.05)';
|
|
||||||
e.currentTarget.style.borderColor = 'rgba(255, 255, 255, 0.35)';
|
|
||||||
e.currentTarget.style.transform = 'translateY(0)';
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<span>Explore Our Full Product Suite</span>
|
|
||||||
<ArrowRight size={16} />
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
@@ -2110,6 +2069,7 @@ export default function App({ previewMode = false }) {
|
|||||||
</Reveal>
|
</Reveal>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
@@ -2169,7 +2129,7 @@ export default function App({ previewMode = false }) {
|
|||||||
}}>
|
}}>
|
||||||
<div>
|
<div>
|
||||||
<h2 style={{ fontSize: '1.65rem', fontWeight: 600, color: '#ffffff', lineHeight: 1.25, marginBottom: '0.8rem', letterSpacing: '-0.02em' }}>
|
<h2 style={{ fontSize: '1.65rem', fontWeight: 600, color: '#ffffff', lineHeight: 1.25, marginBottom: '0.8rem', letterSpacing: '-0.02em' }}>
|
||||||
Let's Build What's Next -<br/>Together.
|
Let's Build What's Next -<br />Together.
|
||||||
</h2>
|
</h2>
|
||||||
<p style={{ fontSize: '0.82rem', fontWeight: 500, lineHeight: 1.55, color: '#cbd5e1', marginBottom: '1.8rem', textTransform: 'uppercase', letterSpacing: '0.06em' }}>
|
<p style={{ fontSize: '0.82rem', fontWeight: 500, lineHeight: 1.55, color: '#cbd5e1', marginBottom: '1.8rem', textTransform: 'uppercase', letterSpacing: '0.06em' }}>
|
||||||
{footer.cta.body}
|
{footer.cta.body}
|
||||||
@@ -2227,7 +2187,7 @@ export default function App({ previewMode = false }) {
|
|||||||
marginBottom: '1rem',
|
marginBottom: '1rem',
|
||||||
letterSpacing: '-0.02em'
|
letterSpacing: '-0.02em'
|
||||||
}}>
|
}}>
|
||||||
Let's Build What's Next -<br/>Together.
|
Let's Build What's Next -<br />Together.
|
||||||
</h2>
|
</h2>
|
||||||
<p style={{
|
<p style={{
|
||||||
fontSize: 'clamp(0.72rem, 1vw, 0.9rem)',
|
fontSize: 'clamp(0.72rem, 1vw, 0.9rem)',
|
||||||
@@ -2295,9 +2255,9 @@ export default function App({ previewMode = false }) {
|
|||||||
onMouseLeave={e => e.currentTarget.style.color = '#475569'}>Home</a>
|
onMouseLeave={e => e.currentTarget.style.color = '#475569'}>Home</a>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<a href="#certifications" onClick={e => {
|
<a href="#aboutus" onClick={e => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
scrollToSection('certifications');
|
handleNavClick('About Us');
|
||||||
}} style={{ color: '#475569', textDecoration: 'none', fontSize: '0.85rem', transition: 'color 0.2s' }}
|
}} style={{ color: '#475569', textDecoration: 'none', fontSize: '0.85rem', transition: 'color 0.2s' }}
|
||||||
onMouseEnter={e => e.currentTarget.style.color = '#1e40af'}
|
onMouseEnter={e => e.currentTarget.style.color = '#1e40af'}
|
||||||
onMouseLeave={e => e.currentTarget.style.color = '#475569'}>About Us</a>
|
onMouseLeave={e => e.currentTarget.style.color = '#475569'}>About Us</a>
|
||||||
@@ -2305,11 +2265,24 @@ export default function App({ previewMode = false }) {
|
|||||||
<li>
|
<li>
|
||||||
<a href="#services" onClick={e => {
|
<a href="#services" onClick={e => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
if (currentPage !== 'home') {
|
||||||
|
setCurrentPage('home');
|
||||||
|
setTimeout(() => scrollToSection('services'), 300);
|
||||||
|
} else {
|
||||||
scrollToSection('services');
|
scrollToSection('services');
|
||||||
|
}
|
||||||
}} style={{ color: '#475569', textDecoration: 'none', fontSize: '0.85rem', transition: 'color 0.2s' }}
|
}} style={{ color: '#475569', textDecoration: 'none', fontSize: '0.85rem', transition: 'color 0.2s' }}
|
||||||
onMouseEnter={e => e.currentTarget.style.color = '#1e40af'}
|
onMouseEnter={e => e.currentTarget.style.color = '#1e40af'}
|
||||||
onMouseLeave={e => e.currentTarget.style.color = '#475569'}>Our Services</a>
|
onMouseLeave={e => e.currentTarget.style.color = '#475569'}>Our Services</a>
|
||||||
</li>
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="#contactus" onClick={e => {
|
||||||
|
e.preventDefault();
|
||||||
|
handleNavClick('Contact Us');
|
||||||
|
}} style={{ color: '#475569', textDecoration: 'none', fontSize: '0.85rem', transition: 'color 0.2s' }}
|
||||||
|
onMouseEnter={e => e.currentTarget.style.color = '#1e40af'}
|
||||||
|
onMouseLeave={e => e.currentTarget.style.color = '#475569'}>Contact Us</a>
|
||||||
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -2317,10 +2290,15 @@ export default function App({ previewMode = false }) {
|
|||||||
<div>
|
<div>
|
||||||
<h5 style={{ fontSize: '0.75rem', fontWeight: 800, letterSpacing: '0.12em', textTransform: 'uppercase', color: '#1e293b', marginBottom: '1rem' }}>Products</h5>
|
<h5 style={{ fontSize: '0.75rem', fontWeight: 800, letterSpacing: '0.12em', textTransform: 'uppercase', color: '#1e293b', marginBottom: '1rem' }}>Products</h5>
|
||||||
<ul style={{ listStyle: 'none', display: 'flex', flexDirection: 'column', gap: '0.45rem', padding: 0, margin: 0 }}>
|
<ul style={{ listStyle: 'none', display: 'flex', flexDirection: 'column', gap: '0.45rem', padding: 0, margin: 0 }}>
|
||||||
{(footer.productLinks && footer.productLinks.length ? footer.productLinks.map(p => p.label) : ['Nebula AI platform', 'Prodmax', 'Budgie']).map(l => (
|
{(footer.productLinks && footer.productLinks.length ? footer.productLinks.map(p => p.label) : ['Nebula AI Platform', 'Prodmax', 'Budgie']).map(l => (
|
||||||
<li key={l}><a href="#products" onClick={e => {
|
<li key={l}><a href="#products" onClick={e => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
if (currentPage !== 'home') {
|
||||||
|
setCurrentPage('home');
|
||||||
|
setTimeout(() => scrollToSection('products'), 300);
|
||||||
|
} else {
|
||||||
scrollToSection('products');
|
scrollToSection('products');
|
||||||
|
}
|
||||||
}} style={{ color: '#475569', textDecoration: 'none', fontSize: '0.85rem', transition: 'color 0.2s' }}
|
}} style={{ color: '#475569', textDecoration: 'none', fontSize: '0.85rem', transition: 'color 0.2s' }}
|
||||||
onMouseEnter={e => e.currentTarget.style.color = '#1e40af'}
|
onMouseEnter={e => e.currentTarget.style.color = '#1e40af'}
|
||||||
onMouseLeave={e => e.currentTarget.style.color = '#475569'}>{l}</a></li>
|
onMouseLeave={e => e.currentTarget.style.color = '#475569'}>{l}</a></li>
|
||||||
@@ -2393,10 +2371,11 @@ export default function App({ previewMode = false }) {
|
|||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer >
|
||||||
|
|
||||||
{/* Careers Modal Popup */}
|
{/* Careers Modal Popup */ }
|
||||||
{isCareersOpen && !previewMode && (
|
{
|
||||||
|
isCareersOpen && !previewMode && (
|
||||||
<div style={{
|
<div style={{
|
||||||
position: 'fixed',
|
position: 'fixed',
|
||||||
inset: 0,
|
inset: 0,
|
||||||
@@ -2863,10 +2842,12 @@ export default function App({ previewMode = false }) {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)
|
||||||
|
}
|
||||||
|
|
||||||
{/* Book a Strategy Call Modal Popup */}
|
{/* Book a Strategy Call Modal Popup */ }
|
||||||
{isStrategyOpen && !previewMode && (
|
{
|
||||||
|
isStrategyOpen && !previewMode && (
|
||||||
<div style={{
|
<div style={{
|
||||||
position: 'fixed',
|
position: 'fixed',
|
||||||
inset: 0,
|
inset: 0,
|
||||||
@@ -3425,7 +3406,8 @@ export default function App({ previewMode = false }) {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)
|
||||||
</div>
|
}
|
||||||
|
</div >
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -52,47 +52,7 @@ export default function FeaturedGallery({ gallery }) {
|
|||||||
setActiveIdx={setActiveGalleryIndex}
|
setActiveIdx={setActiveGalleryIndex}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
{/* Bottom CTA Button matching design screenshot */}
|
|
||||||
<div style={{ display: 'flex', justifyContent: 'center', marginTop: '3rem' }}>
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
onClick={() => {
|
|
||||||
const footer = document.getElementById('contactus');
|
|
||||||
if (footer) {
|
|
||||||
footer.scrollIntoView({ behavior: 'smooth' });
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
style={{
|
|
||||||
display: 'inline-flex',
|
|
||||||
alignItems: 'center',
|
|
||||||
gap: '0.6rem',
|
|
||||||
background: 'rgba(255, 255, 255, 0.05)',
|
|
||||||
border: '1.5px solid rgba(255, 255, 255, 0.35)',
|
|
||||||
boxShadow: '0 8px 25px rgba(0, 0, 0, 0.3)',
|
|
||||||
borderRadius: '50px',
|
|
||||||
color: '#ffffff',
|
|
||||||
padding: '0.75rem 2rem',
|
|
||||||
fontSize: '0.92rem',
|
|
||||||
fontWeight: 600,
|
|
||||||
cursor: 'pointer',
|
|
||||||
transition: 'all 0.25s ease',
|
|
||||||
backdropFilter: 'blur(10px)'
|
|
||||||
}}
|
|
||||||
onMouseEnter={(e) => {
|
|
||||||
e.currentTarget.style.background = 'rgba(255, 255, 255, 0.12)';
|
|
||||||
e.currentTarget.style.borderColor = 'rgba(255, 255, 255, 0.6)';
|
|
||||||
e.currentTarget.style.transform = 'translateY(-2px)';
|
|
||||||
}}
|
|
||||||
onMouseLeave={(e) => {
|
|
||||||
e.currentTarget.style.background = 'rgba(255, 255, 255, 0.05)';
|
|
||||||
e.currentTarget.style.borderColor = 'rgba(255, 255, 255, 0.35)';
|
|
||||||
e.currentTarget.style.transform = 'translateY(0)';
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<span>Explore Success Stories</span>
|
|
||||||
<ArrowRight size={16} />
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user