From 7742b129fe4333f73cbbd6c660124673adf8aa64 Mon Sep 17 00:00:00 2001 From: Harshjosh361 Date: Thu, 3 Oct 2024 00:42:25 +0530 Subject: [PATCH] added neon gradient behind the cta buttons Signed-off-by: Harshjosh361 --- components/features.tsx | 427 ++++++++++++++-------------- components/hero.tsx | 99 +++---- components/installation.tsx | 5 +- components/magicui/neonGradient.tsx | 95 +++++++ components/ui/header.tsx | 8 +- tailwind.config.js | 5 + 6 files changed, 369 insertions(+), 270 deletions(-) create mode 100644 components/magicui/neonGradient.tsx diff --git a/components/features.tsx b/components/features.tsx index b2985fea..8fa89219 100644 --- a/components/features.tsx +++ b/components/features.tsx @@ -1,227 +1,230 @@ -"use client"; - -import React, {useRef} from "react"; -import testAndStubsGen from "@/public/images/TestGenHighlighted.json"; -import deDuplication from "@/public/images/CaptureAndReplayV2.json"; -import Link from "next/link"; -import gsap from "gsap"; // <-- import GSAP -import { useGSAP } from "@gsap/react"; // <-- import the hook -import { ScrollTrigger } from "gsap/all"; -import _ScrollTrigger from "gsap/ScrollTrigger"; -import FeaturesMobileView from "./FeatureMoblieView"; -import dynamic from "next/dynamic"; -const LottiePlayer = dynamic(() => import("./LottiePlayer"), { ssr: false }); -gsap.registerPlugin(useGSAP); -gsap.registerPlugin(ScrollTrigger); - -const TestAndStubGenerationImage = () => { - return ( -
- {/* Features bg */} -
- -
- -
- ); -}; - -const TestDuplicationImage = () => { - return ( -
- {/* Features bg */} - {/*Element*/} - -
- ); -}; - - - - - // const heightFix = () => { - // if (tabs.current && tabs.current.parentElement) - // tabs.current.parentElement.style.height = `${tabs.current.clientHeight}px`; - // }; - - -const TextSection = ({ - svg, - heading, - description, - btnDescription, - btnLink, -}: { - svg: any; - heading: string; - description: string; - btnDescription?: string; - btnLink?: any; -}) => { - return ( -
-
- {svg} + "use client"; + + import React, {useRef} from "react"; + import testAndStubsGen from "@/public/images/TestGenHighlighted.json"; + import deDuplication from "@/public/images/CaptureAndReplayV2.json"; + import Link from "next/link"; + import gsap from "gsap"; // <-- import GSAP + import { useGSAP } from "@gsap/react"; // <-- import the hook + import { ScrollTrigger } from "gsap/all"; + import _ScrollTrigger from "gsap/ScrollTrigger"; + import FeaturesMobileView from "./FeatureMoblieView"; + import dynamic from "next/dynamic"; + import { NeonButton } from "./magicui/neonGradient"; + const LottiePlayer = dynamic(() => import("./LottiePlayer"), { ssr: false }); + gsap.registerPlugin(useGSAP); + gsap.registerPlugin(ScrollTrigger); + + const TestAndStubGenerationImage = () => { + return ( +
+ {/* Features bg */} +
+ +
+
-
- {heading} + ); + }; + + const TestDuplicationImage = () => { + return ( +
+ {/* Features bg */} + {/*Element*/} +
-
{description}
- {btnDescription && ( -
- - {btnDescription} - + ); + }; + + + + + // const heightFix = () => { + // if (tabs.current && tabs.current.parentElement) + // tabs.current.parentElement.style.height = `${tabs.current.clientHeight}px`; + // }; + + + const TextSection = ({ + svg, + heading, + description, + btnDescription, + btnLink, + }: { + svg: any; + heading: string; + description: string; + btnDescription?: string; + btnLink?: any; + }) => { + return ( +
+
+ {svg}
- )} -
- ); -}; +
+ {heading} +
+
{description}
+ {btnDescription && ( +
+ + + {btnDescription} + + +
+ )} +
+ ); + }; -export default function Features() { - const container = useRef(null); + export default function Features() { + const container = useRef(null); -useGSAP( - () => { - const details: any = gsap.utils.toArray(".detail"); + useGSAP( + () => { + const details: any = gsap.utils.toArray(".detail"); - const images: any = gsap.utils.toArray(".imageToShow"); + const images: any = gsap.utils.toArray(".imageToShow"); - gsap.set(images[1], { opacity: 0 }); + gsap.set(images[1], { opacity: 0 }); - ScrollTrigger.create({ - trigger: ".content-container", - start: "top top", - end: "bottom bottom", - pin: ".right-content", - }); + ScrollTrigger.create({ + trigger: ".content-container", + start: "top top", + end: "bottom bottom", + pin: ".right-content", + }); - ScrollTrigger.create({ - trigger: ".content-container", - start: "top top", - end: "bottom bottom", - pin: ".heading-text", - }); + ScrollTrigger.create({ + trigger: ".content-container", + start: "top top", + end: "bottom bottom", + pin: ".heading-text", + }); - details.forEach((detail: any) => { - gsap.set(detail, { opacity: 1 }); + details.forEach((detail: any) => { + gsap.set(detail, { opacity: 1 }); + + ScrollTrigger.create({ + trigger: detail, + start: "top 20%", + end: "center center", + onEnter: () => gsap.set(detail, { opacity: 0 }), + onLeaveBack: () => gsap.set(detail, { opacity: 1 }), + scrub: 1, + }); + }); - ScrollTrigger.create({ - trigger: detail, - start: "top 20%", - end: "center center", - onEnter: () => gsap.set(detail, { opacity: 0 }), - onLeaveBack: () => gsap.set(detail, { opacity: 1 }), - scrub: 1, + gsap.to(images[0], { + scrollTrigger: { + trigger: details[1], + start: "center center", + end: "center center", + scrub: 1, + }, + opacity: 0, }); - }); - - gsap.to(images[0], { - scrollTrigger: { - trigger: details[1], - start: "center center", - end: "center center", - scrub: 1, - }, - opacity: 0, - }); - gsap.to(images[1], { - scrollTrigger: { - trigger: details[1], - start: "center center", - end: "center center", - scrub: 1, - }, - opacity: 1, - }); - }, - { scope: container } -); - - return ( - <> - -
-
-

- Keploy for Developers -

-

- smart API testing, capture network calls and generate tests with stubs -

-
-
-
-
- - - - } - heading={"Record Replay API Flows"} - description=" Record and replay complex, distributed API flows as mocks and stubs. It's like time machine for tests!" - btnDescription="Explore More" - btnLink="https://keploy.io/docs/keploy-explained/introduction/" - /> -
-
- - - - } - heading={"Find Duplicate Tests"} - description="Find redundant tests that doesn't add to the test coverage. Automatically detect and remove duplicate tests, ideal for big-teams crowd-sourcing tests." - btnDescription="Explore More" - btnLink="https://keploy.io/docs/keploy-cloud/deduplication/" - /> + gsap.to(images[1], { + scrollTrigger: { + trigger: details[1], + start: "center center", + end: "center center", + scrub: 1, + }, + opacity: 1, + }); + }, + { scope: container } + ); + + return ( + <> + +
+
+

+ Keploy for Developers +

+

+ smart API testing, capture network calls and generate tests with stubs +

+
+
+
+
+ + + + } + heading={"Record Replay API Flows"} + description=" Record and replay complex, distributed API flows as mocks and stubs. It's like time machine for tests!" + btnDescription="Explore More" + btnLink="https://keploy.io/docs/keploy-explained/introduction/" + /> +
+
+ + + + } + heading={"Find Duplicate Tests"} + description="Find redundant tests that doesn't add to the test coverage. Automatically detect and remove duplicate tests, ideal for big-teams crowd-sourcing tests." + btnDescription="Explore More" + btnLink="https://keploy.io/docs/keploy-cloud/deduplication/" + /> +
+
+ + + + } + heading={"Works with JUnit, PyTest, Jest, Go-Test in CI/CD"} + description="Merge Keploy tests coverage with unit testing libraries for combined test coverage gating in CI/CD pipelines like Jenkins, Github Actions." + btnDescription="Explore More" + btnLink=" https://keploy.io/docs/server/sdk-installation/go/" + /> +
-
- - - - } - heading={"Works with JUnit, PyTest, Jest, Go-Test in CI/CD"} - description="Merge Keploy tests coverage with unit testing libraries for combined test coverage gating in CI/CD pipelines like Jenkins, Github Actions." - btnDescription="Explore More" - btnLink=" https://keploy.io/docs/server/sdk-installation/go/" - /> +
+ +
-
- - -
-
-
- - ); -} \ No newline at end of file +
+ + ); + } \ No newline at end of file diff --git a/components/hero.tsx b/components/hero.tsx index 5d77ba17..6b05263e 100644 --- a/components/hero.tsx +++ b/components/hero.tsx @@ -1,14 +1,16 @@ /* eslint-disable @typescript-eslint/no-unsafe-call */ -"use client" -import VideoThumb from '@/public/images/demo-thumbnail.png' -import ModalVideo from '@/components/modal-video' +"use client"; +import VideoThumb from '@/public/images/demo-thumbnail.png'; +import ModalVideo from '@/components/modal-video'; import Image from "next/image"; import TestimonialImage from "@/public/images/users/Nutanix_Logo.svg"; import React from "react"; import CopyButton from './utils/copyButton'; import { TrustedBy } from './trustedBy'; import Link from 'next/link'; -import APItext from "@/public/images/apiText.png" +import APItext from "@/public/images/apiText.png"; +import { NeonButton } from './magicui/neonGradient'; // Import NeonButton component + export default function Hero() { return (
@@ -37,32 +39,15 @@ export default function Hero() { {/* Section header */}
-

+

2 minutes to 90% test coverage!

AI Generated Tests - {/**/} - {/* ^*/} - {/* */} - {/* E2E*/} - {/* */} - {/* */}
that actually work! @@ -71,49 +56,53 @@ export default function Hero() {

Open Source Platform for converting API calls to Test Cases with Data Mocks

-
-
- Try Open Source +
+ {/* Wrapping Link with NeonButton */} + + + Try Open Source + +
-
- Join Cloud Waitlist +
+ {/* Wrapping Link with NeonButton */} + + + Join Cloud Waitlist + +
- {/*
-
-                  
-                  
-                  
-                
-
*/}
+ thumb={VideoThumb} + thumbWidth={768} + thumbHeight={432} + thumbAlt="Keploy Demo video" + video="https://www.youtube.com/embed/gvWvpqWM48s" + videoWidth={768} + videoHeight={432} + />

- - {/*Trusted by users section*/} - - +
- ) + ); } diff --git a/components/installation.tsx b/components/installation.tsx index 2d05afa0..1f9d04d7 100644 --- a/components/installation.tsx +++ b/components/installation.tsx @@ -8,6 +8,7 @@ import CopyButton from "@/public/images/icons8-copy-96.png"; import SvgIcon from "@mui/material/SvgIcon"; import { IconButton as MuiButton } from "@mui/material"; import { red } from "@mui/material/colors"; +import { NeonButton } from "./magicui/neonGradient"; import Link from "next/link"; const Installation = () => { @@ -181,12 +182,14 @@ const Installation = () => {
+ Explore on Github +
= ({ + className, + children, + borderSize = 2, + borderRadius = 20, + neonColors = { + firstColor: "#ff00aa", + secondColor: "#00FFF1", + }, + ...props +}) => { + const containerRef = useRef(null); + const [dimensions, setDimensions] = useState({ width: 0, height: 0 }); + + useEffect(() => { + const resizeObserver = new ResizeObserver((entries) => { + for (let entry of entries) { + const { width, height } = entry.contentRect; + setDimensions({ width, height }); + } + }); + + if (containerRef.current) { + resizeObserver.observe(containerRef.current); + } + + return () => { + resizeObserver.disconnect(); + }; + }, []); + + useEffect(() => { + if (containerRef.current) { + const { offsetWidth, offsetHeight } = containerRef.current; + setDimensions({ width: offsetWidth, height: offsetHeight }); + } + }, [children]); + + return ( +
+
+
+ {children} +
+
+ ); +}; + +export { NeonButton }; diff --git a/components/ui/header.tsx b/components/ui/header.tsx index b31cc5b0..93f4c8fd 100644 --- a/components/ui/header.tsx +++ b/components/ui/header.tsx @@ -10,6 +10,7 @@ import { isTypeOfExpression } from "typescript"; import NavItemWithSmallDropdown, {DropdowndataInterface,LinkDatainterface} from "@/components/nav/navItemWithSmallDropdown"; import { PillarPages } from "../utils/resources"; import { StarIcon } from "@heroicons/react/24/solid"; +import { NeonButton } from "../magicui/neonGradient"; export default function Header() { const [top, setTop] = useState(true); const [starsCount, setStarsCount] = useState(1000); @@ -138,17 +139,20 @@ export default function Header() {
- +
+ Join Waitlist {/**/} {/* */} {/**/} + +
diff --git a/tailwind.config.js b/tailwind.config.js index e90698ae..3a89ec0a 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -10,6 +10,7 @@ module.exports = { animation: { marquee: "marquee var(--duration) linear infinite", "marquee-vertical": "marquee-vertical var(--duration) linear infinite", + "background-position-spin": "background-position-spin 3000ms infinite alternate", }, keyframes: { marquee: { @@ -20,6 +21,10 @@ module.exports = { from: { transform: "translateY(0)" }, to: { transform: "translateY(calc(-100% - var(--gap)))" }, }, + "background-position-spin": { + "0%": { backgroundPosition: "top center" }, + "100%": { backgroundPosition: "bottom center" }, + }, }, colors: { // Brand Palette