Merge pull request #748 from elammertsma/dev

feat: Implemented hero A/B test, added Contact Sales button
This commit is contained in:
Rohan Verma 2026-01-27 16:03:02 -08:00 committed by GitHub
commit 114ac59c0e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 61 additions and 16 deletions

View file

@ -1,4 +1,5 @@
"use client"; "use client";
import { useFeatureFlagVariantKey } from "@posthog/react";
import { AnimatePresence, motion } from "motion/react"; import { AnimatePresence, motion } from "motion/react";
import Image from "next/image"; import Image from "next/image";
import Link from "next/link"; import Link from "next/link";
@ -33,6 +34,8 @@ const GoogleLogo = ({ className }: { className?: string }) => (
export function HeroSection() { export function HeroSection() {
const containerRef = useRef<HTMLDivElement>(null); const containerRef = useRef<HTMLDivElement>(null);
const parentRef = useRef<HTMLDivElement>(null); const parentRef = useRef<HTMLDivElement>(null);
const heroVariant = useFeatureFlagVariantKey("notebooklm_flag");
const isNotebookLMVariant = heroVariant === "notebooklm";
return ( return (
<div <div
@ -83,12 +86,22 @@ export function HeroSection() {
<h2 className="relative z-50 mx-auto mb-4 mt-4 max-w-4xl text-balance text-center text-3xl font-semibold tracking-tight text-gray-700 md:text-7xl dark:text-neutral-300"> <h2 className="relative z-50 mx-auto mb-4 mt-4 max-w-4xl text-balance text-center text-3xl font-semibold tracking-tight text-gray-700 md:text-7xl dark:text-neutral-300">
<Balancer> <Balancer>
{isNotebookLMVariant ? (
<div className="relative mx-auto inline-block w-max filter-[drop-shadow(0px_1px_3px_rgba(27,37,80,0.14))]">
<div className="text-black [text-shadow:0_0_rgba(0,0,0,0.1)] dark:text-white">
<span className="">NotebookLM for Teams</span>
</div>
</div>
) : (
<>
The AI Workspace{" "} The AI Workspace{" "}
<div className="relative mx-auto inline-block w-max filter-[drop-shadow(0px_1px_3px_rgba(27,37,80,0.14))]"> <div className="relative mx-auto inline-block w-max filter-[drop-shadow(0px_1px_3px_rgba(27,37,80,0.14))]">
<div className="text-black [text-shadow:0_0_rgba(0,0,0,0.1)] dark:text-white"> <div className="text-black [text-shadow:0_0_rgba(0,0,0,0.1)] dark:text-white">
<span className="">Built for Teams</span> <span className="">Built for Teams</span>
</div> </div>
</div> </div>
</>
)}
</Balancer> </Balancer>
</h2> </h2>
{/* // TODO:aCTUAL DESCRITION */} {/* // TODO:aCTUAL DESCRITION */}
@ -98,12 +111,7 @@ export function HeroSection() {
</p> </p>
<div className="mb-10 mt-8 flex w-full flex-col items-center justify-center gap-4 px-8 sm:flex-row md:mb-20"> <div className="mb-10 mt-8 flex w-full flex-col items-center justify-center gap-4 px-8 sm:flex-row md:mb-20">
<GetStartedButton /> <GetStartedButton />
{/* <Link <ContactSalesButton />
href="/pricing"
className="shadow-input group relative z-20 flex h-10 w-full cursor-pointer items-center justify-center space-x-2 rounded-lg bg-white p-px px-4 py-2 text-sm font-semibold leading-6 text-black no-underline transition duration-200 hover:-translate-y-0.5 sm:w-52 dark:bg-neutral-800 dark:text-white"
>
Start Free Trial
</Link> */}
</div> </div>
<div <div
ref={containerRef} ref={containerRef}
@ -193,6 +201,21 @@ function GetStartedButton() {
); );
} }
function ContactSalesButton() {
return (
<motion.div whileHover={{ scale: 1.02, y: -2 }} whileTap={{ scale: 0.98 }}>
<Link
href="https://calendly.com/eric-surfsense/surfsense-meeting"
target="_blank"
rel="noopener noreferrer"
className="group relative z-20 flex h-11 w-full cursor-pointer items-center justify-center gap-2 rounded-xl bg-white px-6 py-2.5 text-sm font-semibold text-neutral-700 shadow-lg ring-1 ring-neutral-200/50 transition-shadow duration-300 hover:shadow-xl sm:w-56 dark:bg-neutral-900 dark:text-neutral-200 dark:ring-neutral-700/50"
>
Contact Sales
</Link>
</motion.div>
);
}
const BackgroundGrids = () => { const BackgroundGrids = () => {
return ( return (
<div className="pointer-events-none absolute inset-0 z-0 grid h-full w-full -rotate-45 transform select-none grid-cols-2 gap-10 md:grid-cols-4"> <div className="pointer-events-none absolute inset-0 z-0 grid h-full w-full -rotate-45 transform select-none grid-cols-2 gap-10 md:grid-cols-4">

View file

@ -3,6 +3,7 @@
import { PostHogProvider as PHProvider } from "@posthog/react"; import { PostHogProvider as PHProvider } from "@posthog/react";
import posthog from "posthog-js"; import posthog from "posthog-js";
import type { ReactNode } from "react"; import type { ReactNode } from "react";
import "../../instrumentation-client";
import { PostHogIdentify } from "./PostHogIdentify"; import { PostHogIdentify } from "./PostHogIdentify";
interface PostHogProviderProps { interface PostHogProviderProps {
@ -10,8 +11,8 @@ interface PostHogProviderProps {
} }
export function PostHogProvider({ children }: PostHogProviderProps) { export function PostHogProvider({ children }: PostHogProviderProps) {
// posthog-js is already initialized in instrumentation-client.ts // posthog-js is initialized by importing instrumentation-client.ts above
// We just need to wrap the app with the PostHogProvider for hook access // We wrap the app with the PostHogProvider for hook access
return ( return (
<PHProvider client={posthog}> <PHProvider client={posthog}>
<PostHogIdentify /> <PostHogIdentify />

View file

@ -12,5 +12,17 @@ if (process.env.NEXT_PUBLIC_POSTHOG_KEY) {
capture_pageview: "history_change", capture_pageview: "history_change",
// Enable session recording // Enable session recording
capture_pageleave: true, capture_pageleave: true,
loaded: (posthog) => {
// Expose PostHog to window for console access and toolbar
if (typeof window !== "undefined") {
window.posthog = posthog;
}
},
}); });
} }
// Always expose posthog to window for debugging/toolbar access
// This allows testing feature flags even without POSTHOG_KEY configured
if (typeof window !== "undefined") {
window.posthog = posthog;
}

9
surfsense_web/types/window.d.ts vendored Normal file
View file

@ -0,0 +1,9 @@
import type { PostHog } from "posthog-js";
declare global {
interface Window {
posthog?: PostHog;
}
}
export {};