feat(landing): port the full marketing site into the CRM (static)
Copies the goutam-pages landing (React marketing home + /page/1..19 + assets) into /public and adds beforeFiles rewrites so '/' serves the marketing home and '/1'..'/19' + '/thanks' serve the static pages — reproducing the landing's vercel.json clean URLs. /portal/* (login/register) is untouched.
This commit is contained in:
@@ -0,0 +1,93 @@
|
||||
/* global React, ReactDOM, Nav, Hero, Manifesto, TrustMarquee, LiveMetrics, SpecSheet, CoreFeatures, ConnectedOps, MobileSection, Analytics, FieldIntelligence, Testimonials, Pricing, FinalCTA, Footer */
|
||||
|
||||
const { useEffect, useRef, useState } = React;
|
||||
|
||||
function App() {
|
||||
const glowRef = useRef(null);
|
||||
const progressRef = useRef(null);
|
||||
|
||||
useEffect(() => {
|
||||
// Cursor glow follower
|
||||
const onMove = (e) => {
|
||||
if (glowRef.current) {
|
||||
glowRef.current.style.left = e.clientX + "px";
|
||||
glowRef.current.style.top = e.clientY + "px";
|
||||
}
|
||||
};
|
||||
window.addEventListener("mousemove", onMove);
|
||||
|
||||
// Scroll progress
|
||||
const onScroll = () => {
|
||||
if (progressRef.current) {
|
||||
const h = document.documentElement.scrollHeight - window.innerHeight;
|
||||
const pct = h > 0 ? (window.scrollY / h) * 100 : 0;
|
||||
progressRef.current.style.width = pct + "%";
|
||||
}
|
||||
};
|
||||
window.addEventListener("scroll", onScroll, { passive: true });
|
||||
|
||||
return () => {
|
||||
window.removeEventListener("mousemove", onMove);
|
||||
window.removeEventListener("scroll", onScroll);
|
||||
};
|
||||
}, []);
|
||||
|
||||
// Build particle set once
|
||||
const particles = React.useMemo(() => {
|
||||
return Array.from({ length: 26 }, (_, i) => ({
|
||||
id: i,
|
||||
left: Math.random() * 100,
|
||||
delay: Math.random() * 18,
|
||||
dur: 18 + Math.random() * 22,
|
||||
size: 1 + Math.random() * 2.5,
|
||||
opacity: 0.3 + Math.random() * 0.6,
|
||||
}));
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div className="app">
|
||||
<div className="bg-layer"/>
|
||||
<div className="bg-grid"/>
|
||||
<div className="particles">
|
||||
{particles.map(p => (
|
||||
<span key={p.id} className="particle" style={{
|
||||
left: `${p.left}%`,
|
||||
bottom: "-10px",
|
||||
width: p.size,
|
||||
height: p.size,
|
||||
animationDuration: `${p.dur}s`,
|
||||
animationDelay: `${p.delay}s`,
|
||||
opacity: p.opacity,
|
||||
}}/>
|
||||
))}
|
||||
</div>
|
||||
<div className="cursor-glow" ref={glowRef}/>
|
||||
<div className="scroll-progress" ref={progressRef}/>
|
||||
|
||||
<Nav/>
|
||||
<Hero/>
|
||||
<TrustMarquee/>
|
||||
<Manifesto/>
|
||||
<LiveMetrics/>
|
||||
<SpecSheet/>
|
||||
<CoreFeatures/>
|
||||
<ConnectedOps/>
|
||||
<MobileSection/>
|
||||
<Analytics/>
|
||||
<FieldIntelligence/>
|
||||
<Testimonials/>
|
||||
<Pricing/>
|
||||
<FinalCTA/>
|
||||
{/* <Footer/> hidden — links were all pointing to Book Demo; revisit later */}
|
||||
|
||||
{/* Sticky system pill */}
|
||||
<div className="sys-pill">
|
||||
<span className="dot"/>
|
||||
<span>SYS · ALL GREEN</span>
|
||||
<span style={{ color: "var(--cyan-2)" }}>| 142 MS</span>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
ReactDOM.createRoot(document.getElementById("root")).render(<App/>);
|
||||
Reference in New Issue
Block a user