Skip to content

Commit 62c2476

Browse files
committed
replace useEffects. Fix animation
1 parent aacd26d commit 62c2476

19 files changed

Lines changed: 804 additions & 576 deletions

‎apps/codebility/app/(marketing)/_components/MarketingCalendly.tsx‎

Lines changed: 65 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,62 @@
11
"use client";
22

3-
import React from "react";
43
import { Clock, Lightbulb, Rocket } from "lucide-react";
4+
import { motion } from "framer-motion";
55
import { InlineWidget } from "react-calendly";
66

77
import Container from "./MarketingContainer";
88
import Section from "./MarketingSection";
99

10+
const VIEWPORT = { once: true, amount: 0.2 } as const;
11+
12+
const containerVariants = {
13+
hidden: { opacity: 0 },
14+
visible: {
15+
opacity: 1,
16+
transition: {
17+
staggerChildren: 0.12,
18+
delayChildren: 0.05,
19+
},
20+
},
21+
};
22+
23+
const itemVariants = {
24+
hidden: { opacity: 0, y: 24 },
25+
visible: {
26+
opacity: 1,
27+
y: 0,
28+
transition: {
29+
duration: 0.55,
30+
ease: [0.25, 0.46, 0.45, 0.94],
31+
},
32+
},
33+
};
34+
1035
const Calendly = () => {
1136
return (
12-
<Section id="book" className="relative w-full pt-10 2xl:pt-24 text-white overflow-hidden">
37+
<Section
38+
id="book"
39+
className="relative w-full overflow-hidden pt-10 text-white 2xl:pt-24"
40+
>
1341
<Container className="relative z-10 flex flex-col gap-6 text-white lg:flex-row lg:gap-10">
14-
<div className="flex w-full flex-1 flex-col justify-start gap-2 text-center lg:text-left">
15-
<h2 className="text-3xl font-bold md:text-5xl bg-gradient-to-r from-white via-purple-200 to-cyan-200 bg-clip-text text-transparent">
42+
<motion.div
43+
className="flex w-full flex-1 flex-col justify-start gap-2 text-center lg:text-left"
44+
initial="hidden"
45+
whileInView="visible"
46+
viewport={VIEWPORT}
47+
variants={containerVariants}
48+
>
49+
<motion.h2
50+
variants={itemVariants}
51+
className="bg-gradient-to-r from-white via-purple-200 to-cyan-200 bg-clip-text text-3xl font-bold text-transparent md:text-5xl"
52+
>
1653
Let&apos;s Connect
17-
</h2>
18-
<p className="text-md lg:text-lg text-gray-300">
19-
Schedule a meeting with us to discuss your needs and have solutions.
20-
</p>
21-
22-
{/* Enhanced CTA elements */}
23-
<div className="flex flex-col gap-4 mt-6">
24-
{/* Feature highlights */}
54+
</motion.h2>
55+
<motion.p variants={itemVariants} className="text-md text-gray-300 lg:text-lg">
56+
Schedule a meeting with us to discuss your needs and have solutions.
57+
</motion.p>
58+
59+
<motion.div variants={itemVariants} className="mt-6 flex flex-col gap-4">
2560
<div className="flex flex-col gap-3 text-sm lg:text-base">
2661
{[
2762
{ icon: Clock, text: "Free 30-minute consultation" },
@@ -34,25 +69,29 @@ const Calendly = () => {
3469
</div>
3570
))}
3671
</div>
37-
</div>
38-
</div>
72+
</motion.div>
73+
</motion.div>
3974

40-
<div className="calendly-widget-container w-full flex-1 justify-center lg:w-1/2 relative overflow-hidden">
41-
{/* Widget wrapper with enhanced styling */}
42-
<div className="relative rounded-xl overflow-hidden">
43-
{/* Calendar widget */}
75+
<motion.div
76+
className="calendly-widget-container relative w-full flex-1 justify-center overflow-hidden lg:w-1/2"
77+
initial={{ opacity: 0, y: 32 }}
78+
whileInView={{ opacity: 1, y: 0 }}
79+
viewport={VIEWPORT}
80+
transition={{ duration: 0.6, delay: 0.15 }}
81+
>
82+
<div className="relative overflow-hidden rounded-xl">
4483
<div className="relative z-10">
45-
<InlineWidget
46-
styles={{
47-
borderRadius: '0.75rem',
48-
border: 'none',
49-
height: '600px',
50-
}}
51-
url="https://calendly.com/codebility-dev/30min"
84+
<InlineWidget
85+
styles={{
86+
borderRadius: "0.75rem",
87+
border: "none",
88+
height: "600px",
89+
}}
90+
url="https://calendly.com/codebility-dev/30min"
5291
/>
5392
</div>
5493
</div>
55-
</div>
94+
</motion.div>
5695
</Container>
5796
</Section>
5897
);
Lines changed: 25 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
"use client";
22

3-
import { useEffect, useState } from "react";
43
import Link from "next/link";
5-
import ScrollToHash from "@/app/(marketing)/_components/landing/LandingScrollToHash";
6-
4+
import { useSyncExternalStore } from "react";
75
import { Briefcase, Info, Phone, CodeXml, Search, Rocket } from "lucide-react";
86

97
const links = [
@@ -13,27 +11,34 @@ const links = [
1311
{ href: "/codevs", label: "Be a Codev", icon: CodeXml },
1412
{ href: "/hire-a-codev", label: "Hire Codevs", icon: Search },
1513
{ href: "/careers", label: "Careers", icon: Rocket },
16-
]
14+
];
1715

18-
const SideNavMenu = () => {
19-
const [isScrolling, setIsScrolling] = useState(false);
16+
const SCROLL_SHRINK_Y = 200;
2017

21-
// Handle scroll animation - shrink links when scrolling
22-
const handleNav = () => {
23-
if (window.scrollY >= 200) {
24-
setIsScrolling(true);
25-
} else {
26-
setIsScrolling(false);
27-
}
18+
function subscribeScrollShrink(onStoreChange: () => void) {
19+
window.addEventListener("scroll", onStoreChange, { passive: true });
20+
return () => {
21+
window.removeEventListener("scroll", onStoreChange);
2822
};
23+
}
24+
25+
function getScrollShrinkSnapshot() {
26+
return window.scrollY >= SCROLL_SHRINK_Y;
27+
}
2928

30-
useEffect(() => {
31-
window.addEventListener("scroll", handleNav);
32-
}, []);
29+
function getServerScrollShrinkSnapshot() {
30+
return false;
31+
}
32+
33+
const SideNavMenu = () => {
34+
const isScrolling = useSyncExternalStore(
35+
subscribeScrollShrink,
36+
getScrollShrinkSnapshot,
37+
getServerScrollShrinkSnapshot,
38+
);
3339

3440
return (
3541
<div className="fixed left-0 top-20 z-50 hidden w-60 flex-col gap-4 ps-5 pt-24 text-sm lg:flex xl:text-base">
36-
{/* <ScrollToHash /> */}
3742
{links.map((link, index) => (
3843
<Link
3944
key={index}
@@ -44,9 +49,9 @@ const SideNavMenu = () => {
4449
<div
4550
className={`relative flex h-8 ${
4651
isScrolling ? "w-[52px] text-xs" : "w-36 text-base"
47-
} border-light-900/5 bg-light-700/10 group items-center gap-2 rounded-md border-2 ps-4 text-white backdrop-blur-lg duration-300 hover:ml-4 hover:w-36 hover:bg-customViolet-100 hover:text-base hover:text-opacity-100 hover:opacity-100 xl:h-10`}
52+
} border-light-900/5 bg-light-700/10 group items-center gap-2 rounded-md border-2 ps-4 text-white backdrop-blur-lg duration-300 hover:ml-4 hover:w-36 hover:bg-customViolet-100 hover:text-base hover:text-opacity-100 hover:opacity-100 xl:h-10`}
4853
>
49-
<link.icon className="size-4 shrink-0"/>
54+
<link.icon className="size-4 shrink-0" />
5055
<p
5156
className={`text-nowrap transition-opacity duration-300 ${
5257
isScrolling ? "opacity-0" : "opacity-100"
@@ -61,4 +66,4 @@ const SideNavMenu = () => {
6166
);
6267
};
6368

64-
export default SideNavMenu;
69+
export default SideNavMenu;

‎apps/codebility/app/(marketing)/_components/landing/AnimatedAdminsSection.tsx‎

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ interface AnimatedAdminsSectionProps {
1313
sectionId: string;
1414
}
1515

16+
const VIEWPORT = { once: true, amount: 0.15 } as const;
17+
1618
const containerVariants = {
1719
hidden: { opacity: 0 },
1820
visible: {
@@ -47,11 +49,12 @@ const AnimatedAdminsSection = ({
4749
className="w-full"
4850
variants={containerVariants}
4951
initial="hidden"
50-
animate="visible"
52+
whileInView="visible"
53+
viewport={VIEWPORT}
5154
data-section={sectionId}
5255
>
5356
<motion.h1
54-
className="text-center text-3xl font-bold bg-gradient-to-r from-white via-purple-200 to-cyan-200 bg-clip-text text-transparent"
57+
className="bg-gradient-to-r from-white via-purple-200 to-cyan-200 bg-clip-text text-center text-3xl font-bold text-transparent"
5558
variants={itemVariants}
5659
>
5760
{title}
@@ -60,7 +63,7 @@ const AnimatedAdminsSection = ({
6063
<div className="flex flex-col items-center justify-center">
6164
<div className="max-w-[1100px] px-4">
6265
<motion.p
63-
className="pt-8 text-center md:px-44 text-gray-300"
66+
className="pt-8 text-center text-gray-300 md:px-44"
6467
variants={itemVariants}
6568
>
6669
{description}
@@ -74,7 +77,7 @@ const AnimatedAdminsSection = ({
7477
{members.map((member: Codev) => (
7578
<motion.div
7679
key={member.id}
77-
className="h-full relative"
80+
className="relative h-full"
7881
variants={itemVariants}
7982
>
8083
<AdminCard admin={member} />
@@ -87,4 +90,4 @@ const AnimatedAdminsSection = ({
8790
);
8891
};
8992

90-
export default AnimatedAdminsSection;
93+
export default AnimatedAdminsSection;

‎apps/codebility/app/(marketing)/_components/landing/AnimatedMetrics.tsx‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ type AnimatedMetricsProps = {
1212
variant?: "hero" | "stat";
1313
};
1414

15-
const VIEWPORT = { once: true, amount: 0.5 } as const;
15+
const VIEWPORT = { once: true, amount: 0.2 } as const;
1616

1717
const VARIANT_CONFIG = {
1818
hero: {

0 commit comments

Comments
 (0)