Skip to content

Commit ca1bafb

Browse files
Enhance "Why We Built" section with smooth scrolling and updated content for better engagement (#64)
1 parent 97dc1c3 commit ca1bafb

File tree

1 file changed

+68
-11
lines changed

1 file changed

+68
-11
lines changed

jaseci-org/layouts/components/landing/WhyWeBuilt.js

Lines changed: 68 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,43 @@ const useIntersectionObserver = (ref, options) => {
3333

3434
const WhyWeBuilt = () => {
3535
const hl = "text-white font-medium";
36+
const [showScrollTop, setShowScrollTop] = useState(false);
37+
38+
// Smooth scroll handler
39+
const handleCardClick = (e, link) => {
40+
e.preventDefault();
41+
const targetId = link.replace('#', '');
42+
const targetElement = document.getElementById(targetId);
43+
if (targetElement) {
44+
targetElement.scrollIntoView({ behavior: 'smooth', block: 'start' });
45+
}
46+
};
47+
48+
// Scroll to top handler
49+
const scrollToTop = () => {
50+
window.scrollTo({ top: 0, behavior: 'smooth' });
51+
};
52+
53+
// Show/hide scroll to top button
54+
useEffect(() => {
55+
const handleScroll = () => {
56+
if (window.scrollY > 400) {
57+
setShowScrollTop(true);
58+
} else {
59+
setShowScrollTop(false);
60+
}
61+
};
62+
63+
window.addEventListener('scroll', handleScroll);
64+
return () => window.removeEventListener('scroll', handleScroll);
65+
}, []);
66+
3667
const cards = [
3768
{
3869
title: "Full Stack in One File",
39-
subtitle: (<>A <span className={hl}>superset of Python</span> with full access to both <span className={hl}>PyPI and npm</span> — backend, frontend, and AI in one language.</>),
40-
subtext: (<>Jac supersets Python the way <span className={hl}>TypeScript supersets JavaScript</span>. All your existing Python code and libraries just work. But now you can also write <span className={hl}>React components</span>, call <span className={hl}>npm packages</span>, and integrate AI: all in the same file. No more juggling three languages across three codebases.</>),
70+
link: "#jac-client",
71+
subtitle: (<>A superset of Python with full access to both PyPI and npm — backend, frontend, and AI in one language.</>),
72+
subtext: (<>Jac supersets Python the way TypeScript supersets JavaScript. All your existing Python code and libraries just work. But now you can also write React components, call npm packages, and integrate AI: all in the same file. No more juggling three languages across three codebases.</>),
4173
gradient: "from-orange-400 to-orange-500",
4274
borderColor: "border-orange-400/30",
4375
hoverBorder: "hover:border-orange-400/50",
@@ -52,8 +84,9 @@ const WhyWeBuilt = () => {
5284
},
5385
{
5486
title: "Kill the Glue Code",
55-
subtitle: (<>No REST endpoints. No HTTP clients. No CORS. <span className={hl}>Frontend calls backend directly</span>.</>),
56-
subtext: (<>In traditional stacks, half your code is just connecting things: writing API routes, serializing data, configuring fetch calls. In Jac, your frontend invokes backend walkers directly with <span className={hl}>spawn</span>. Authentication, type safety, and serialization are handled for you.</>),
87+
link: "#jac-client",
88+
subtitle: (<>No REST endpoints. No HTTP clients. No CORS. Frontend calls backend directly.</>),
89+
subtext: (<>In traditional stacks, half your code is just connecting things: writing API routes, serializing data, configuring fetch calls. In Jac, your frontend invokes backend walkers directly with spawn. Authentication, type safety, and serialization are handled for you.</>),
5790
gradient: "from-orange-500 to-orange-600",
5891
borderColor: "border-orange-500/30",
5992
hoverBorder: "hover:border-orange-500/50",
@@ -68,8 +101,9 @@ const WhyWeBuilt = () => {
68101
},
69102
{
70103
title: "AI with No Manual Prompts",
71-
subtitle: (<><span className={hl}>by llm()</span> turns your function signature into the prompt. <span className={hl}>No prompt engineering required</span>.</>),
72-
subtext: (<>Declare what you want, not how to ask for it. Jac{"'"}s <span className={hl}>Meaning Typed Programming</span> extracts the semantics from your code: function names, types, docstrings, and generates the right prompt automatically. Research shows developers complete tasks <span className={hl}>3.2x faster</span> with <span className={hl}>45% fewer lines of code</span>.</>),
104+
link: "#what-is-jac",
105+
subtitle: (<>by llm() turns your function signature into the prompt. No prompt engineering required.</>),
106+
subtext: (<>Declare what you want, not how to ask for it. Jac{"'"}s Meaning Typed Programming extracts the semantics from your code: function names, types, docstrings, and generates the right prompt automatically. Research shows developers complete tasks 3.2x faster with 45% fewer lines of code.</>),
73107
gradient: "from-orange-600 to-orange-700",
74108
borderColor: "border-orange-600/30",
75109
hoverBorder: "hover:border-orange-600/50",
@@ -83,8 +117,9 @@ const WhyWeBuilt = () => {
83117
},
84118
{
85119
title: "Deploy Without DevOps",
86-
subtitle: (<>Same code, <span className={hl}>laptop to Kubernetes</span>. Databases, auth, and API docs <span className={hl}>auto-provisioned</span>.</>),
87-
subtext: (<><span className={hl}>jac start app.jac</span> runs locally. Add <span className={hl}>--scale</span> and you get Kubernetes deployments with MongoDB, Redis, JWT auth, and Swagger docs: all auto-configured. <span className={hl}>No Dockerfile</span>, no manifests, no infrastructure setup.</>),
120+
link: "#jac-scale",
121+
subtitle: (<>Same code, laptop to Kubernetes. Databases, auth, and API docs auto-provisioned.</>),
122+
subtext: (<>jac start app.jac runs locally. Add --scale and you get Kubernetes deployments with MongoDB, Redis, JWT auth, and Swagger docs: all auto-configured. No Dockerfile, no manifests, no infrastructure setup.</>),
88123
gradient: "from-orange-700 to-orange-800",
89124
borderColor: "border-orange-700/30",
90125
hoverBorder: "hover:border-orange-700/50",
@@ -103,6 +138,7 @@ const WhyWeBuilt = () => {
103138
const headerInView = useIntersectionObserver(headerRef, { threshold: 0.1 });
104139

105140
return (
141+
<>
106142
<section id="why-jaseci" className="py-16 sm:py-20 lg:py-24 bg-gradient-to-b from-medium-bg via-dark-bg to-dark-bg relative overflow-hidden">
107143
{/* Background decorative elements */}
108144
<div className="absolute inset-0 opacity-[0.06] overflow-hidden">
@@ -136,11 +172,13 @@ const WhyWeBuilt = () => {
136172
const cardInView = useIntersectionObserver(cardRef, { threshold: 0.1 });
137173

138174
return (
139-
<div
175+
<a
176+
href={card.link}
177+
onClick={(e) => handleCardClick(e, card.link)}
140178
key={index}
141179
ref={cardRef} // Attach ref for observation
142180
className={`
143-
bg-gradient-to-br from-dark-bg/90 via-medium-bg/80 to-dark-bg/90 backdrop-blur-md rounded-2xl border ${card.borderColor} ${card.hoverBorder} p-7 sm:p-8 shadow-card hover:shadow-card-hover transition-all duration-700 ease-out group mx-2 sm:mx-0
181+
block bg-gradient-to-br from-dark-bg/90 via-medium-bg/80 to-dark-bg/90 backdrop-blur-md rounded-2xl border ${card.borderColor} ${card.hoverBorder} p-7 sm:p-8 shadow-card hover:shadow-card-hover transition-all duration-700 ease-out group mx-2 sm:mx-0 cursor-pointer
144182
// Scroll animation classes
145183
${cardInView ? 'opacity-100 translate-y-0' : 'opacity-0 translate-y-10'}
146184
// Hover effects
@@ -171,13 +209,32 @@ const WhyWeBuilt = () => {
171209
{card.subtext}
172210
</p>
173211
</div>
174-
</div>
212+
</a>
175213
);
176214
})}
177215
</div>
178216
</div>
179217

180218
</section>
219+
220+
{/* Scroll to Top Button */}
221+
<button
222+
onClick={scrollToTop}
223+
className={`fixed bottom-8 right-8 z-50 w-12 h-12 bg-gradient-to-r from-primary-orange to-amber-500 rounded-full shadow-lg hover:shadow-xl transition-all duration-300 flex items-center justify-center group hover:scale-110 ${
224+
showScrollTop ? 'opacity-100 translate-y-0' : 'opacity-0 translate-y-16 pointer-events-none'
225+
}`}
226+
aria-label="Scroll to top"
227+
>
228+
<svg
229+
className="w-6 h-6 text-white group-hover:translate-y-[-2px] transition-transform duration-300"
230+
fill="none"
231+
stroke="currentColor"
232+
viewBox="0 0 24 24"
233+
>
234+
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2.5} d="M5 10l7-7m0 0l7 7m-7-7v18" />
235+
</svg>
236+
</button>
237+
</>
181238
);
182239
};
183240

0 commit comments

Comments
 (0)