Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion app/auth/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ NEXT_PUBLIC_SUPABASE_ANON_KEY=your_key`}
try {
await signInWithGitHub();
} catch (error) {
errorLogger.error(ErrorCategory.AUTH, 'GitHub auth failed:', error);
errorLogger.error(ErrorCategory.AUTH, 'GitHub auth failed', error);
setError('GitHub authentication failed. Please try again.');
setIsLoading(false);
}
Expand Down
6 changes: 3 additions & 3 deletions app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import type { Metadata, Viewport } from 'next';
import { Inter } from 'next/font/google';
import { ThemeProvider } from '@/components/theme-provider';

import { AuthProvider } from '@/providers/AuthProvider';
import SupabaseProvider from '@/components/SupabaseProvider';
import { RealtimeProvider } from '@/providers/RealtimeProvider';
import { SentryProvider } from '@/components/sentry-provider';
import { VersionCheck } from '@/components/version-check';
Expand Down Expand Up @@ -124,15 +124,15 @@ export default function RootLayout({
disableTransitionOnChange
>
<SentryProvider>
<AuthProvider>
<SupabaseProvider>
<RealtimeProvider>
<main className="w-full flex-1">{children}</main>
<VersionCheck />
<Toaster />
<CookieConsentBanner />
<Analytics />
</RealtimeProvider>
</AuthProvider>
</SupabaseProvider>
</SentryProvider>
</ThemeProvider>
</QueryProvider>
Expand Down
237 changes: 153 additions & 84 deletions app/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,10 @@ import { useEffect, useState } from 'react';
import Hero from '@/components/hero';
import FinalCTA from '@/components/final-cta';
import Pricing from '@/components/pricing';
import PublicPlayground from '@/components/public-playground';
import ExampleGallery from '@/components/example-gallery';
import CompetitiveEdge from '@/components/competitive-edge';
import { useSupabase } from '@/components/SupabaseProvider';
import { AuthButtons } from '@/components/auth-buttons';
import { CrossBrowserButton } from '@/components/ui/cross-browser-button';

const FeaturesShowcase = dynamic(() => import('@/components/features-showcase'), {
loading: () => (
Expand Down Expand Up @@ -56,6 +57,7 @@ export default function Home() {
const [showFloatingCTA, setShowFloatingCTA] = useState(false);
const [mounted, setMounted] = useState(false);
const { scrollY } = useScroll();
const { user, loading } = useSupabase();

// Ensure component is mounted before complex interactions
useEffect(() => {
Expand Down Expand Up @@ -89,6 +91,101 @@ export default function Home() {
return () => unsubscribe();
}, [scrollY, showFloatingCTA, mounted]);

// Simple auth buttons that don't cause re-renders
const AuthButtons = () => {
if (loading) {
return (
<div className="flex items-center gap-4">
<div className="h-8 w-20 animate-pulse rounded-lg bg-white/10 px-4 py-2"></div>
<div className="h-8 w-16 animate-pulse rounded-lg bg-white/10 px-4 py-2"></div>
</div>
);
}

if (user) {
return (
<div className="flex items-center gap-4">
<motion.button
onClick={goToChat}
className="rounded-lg bg-gradient-to-r from-[#6C52A0] to-[#A0527C] px-4 py-2 text-sm font-medium text-white transition-all hover:from-[#7C62B0] hover:to-[#B0627C]"
whileHover={{ scale: 1.05 }}
whileTap={{ scale: 0.95 }}
>
Chat
</motion.button>
<motion.button
onClick={goToPricingPage}
className="rounded-lg bg-gradient-to-r from-[#A0527C] to-[#6C52A0] px-4 py-2 text-sm font-medium text-white transition-all hover:from-[#B0627C] hover:to-[#7C62B0]"
whileHover={{ scale: 1.05 }}
whileTap={{ scale: 0.95 }}
>
Subscribe
</motion.button>
</div>
);
}

return (
<div className="flex items-center gap-4">
<motion.button
onClick={goToAuth}
className="rounded-lg bg-gradient-to-r from-[#6C52A0] to-[#A0527C] px-4 py-2 text-sm font-medium text-white transition-all hover:from-[#7C62B0] hover:to-[#B0627C]"
whileHover={{ scale: 1.05 }}
whileTap={{ scale: 0.95 }}
>
Sign In
</motion.button>
<motion.button
onClick={goToAuth}
className="rounded-lg bg-gradient-to-r from-[#A0527C] to-[#6C52A0] px-4 py-2 text-sm font-medium text-white transition-all hover:from-[#B0627C] hover:to-[#7C62B0]"
whileHover={{ scale: 1.05 }}
whileTap={{ scale: 0.95 }}
>
Sign Up
</motion.button>
</div>
);
};

// Simplified floating CTA
const FloatingCTA = () => {
const buttonText = user ? 'Go to Chat' : 'Sign In';
const targetRoute = user ? '/chat' : '/auth';

return (
<motion.button
onClick={() => router.push(targetRoute)}
className="flex items-center gap-2 rounded-full bg-gradient-to-r from-[#6C52A0] to-[#A0527C] px-6 py-3 font-medium text-white shadow-lg shadow-purple-900/20 hover:from-[#7C62B0] hover:to-[#B0627C]"
whileHover={{ scale: 1.05 }}
whileTap={{ scale: 0.95 }}
>
<span>{buttonText}</span>
<svg
width="16"
height="16"
viewBox="0 0 16 16"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M3.33337 8H12.6667"
stroke="currentColor"
strokeWidth="1.5"
strokeLinecap="round"
strokeLinejoin="round"
/>
<path
d="M8.66663 4L12.6666 8L8.66663 12"
stroke="currentColor"
strokeWidth="1.5"
strokeLinecap="round"
strokeLinejoin="round"
/>
</svg>
</motion.button>
);
};

// Don't render complex interactions until mounted
if (!mounted) {
return (
Expand All @@ -99,103 +196,75 @@ export default function Home() {
}

return (
<div className="w-full bg-[#0D0D10] text-[#EAEAEA]">
<motion.header
initial={{ y: -100, opacity: 0 }}
animate={{ y: 0, opacity: 1 }}
variants={{ visible: { opacity: 1, y: 0 }, hidden: { opacity: 0, y: -20 } }}
transition={{ duration: 0.5 }}
<div className="min-h-screen bg-[#0D0D10] text-white">
{/* Auth buttons */}
<motion.div
className="fixed right-4 top-4 z-50 flex gap-4"
initial={{ opacity: 0, y: -20 }}
animate={{ opacity: 1, y: 0 }}
transition={{ delay: 0.3 }}
>
<motion.div
initial={{ opacity: 0, y: -20 }}
animate={{ opacity: 1, y: 0 }}
transition={{ delay: 0.3 }}
className="flex items-center gap-4"
>
{/* Debug: Simple static buttons to confirm they show */}
<div className="flex items-center gap-4 rounded-lg bg-black/20 px-4 py-2 backdrop-blur-sm border border-white/10">
<button
onClick={() => router.push('/auth')}
className="gradient-button-primary rounded-lg px-4 py-2 text-sm font-medium text-white"
>
Sign In
</button>
<button
onClick={() => router.push('/auth')}
className="gradient-button-secondary rounded-lg px-4 py-2 text-sm font-medium text-white"
>
Sign Up
</button>
</div>
{/* Uncomment this after we confirm the basic buttons work */}
{/* <AuthButtons /> */}
</motion.div>
</motion.header>
<AuthButtons />
</motion.div>

{/* Floating CTA */}
{/* Main CTA button */}
<motion.div
initial={{ y: 100, opacity: 0 }}
animate={{ y: showFloatingCTA ? 0 : 100, opacity: showFloatingCTA ? 1 : 0 }}
transition={{ type: 'spring', stiffness: 200, damping: 30 }}
className="fixed bottom-8 left-1/2 z-50 -translate-x-1/2"
className="fixed bottom-8 right-8 z-50"
initial={{ opacity: 0, scale: 0.9 }}
animate={{ opacity: 1, scale: 1 }}
transition={{ delay: 0.5 }}
>
<FloatingCTA />
</motion.div>

<main className="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8">
{/* Floating CTA for subscribing */}
{showFloatingCTA && (
<motion.div
className="fixed bottom-8 left-8 z-50"
initial={{ opacity: 0, x: -50 }}
animate={{ opacity: 1, x: 0 }}
exit={{ opacity: 0, x: -50 }}
transition={{ duration: 0.3 }}
>
<motion.button
onClick={user ? goToPricingPage : goToAuth}
className="flex items-center gap-2 rounded-full bg-gradient-to-r from-[#A0527C] to-[#6C52A0] px-6 py-3 font-medium text-white shadow-lg shadow-purple-900/20 hover:from-[#B0627C] hover:to-[#7C62B0]"
whileHover={{ scale: 1.05 }}
whileTap={{ scale: 0.95 }}
>
<span>{user ? 'Subscribe' : 'Sign Up'}</span>
<svg
width="16"
height="16"
viewBox="0 0 16 16"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M8 3v10M3 8h10"
stroke="currentColor"
strokeWidth="1.5"
strokeLinecap="round"
/>
</svg>
</motion.button>
</motion.div>
)}

{/* Main content */}
<main>
<Hero />
<PublicPlayground />
<ExampleGallery />
<CompetitiveEdge />
<FeaturesShowcase />
<VisualShowcase />
<VibeToReality />
<Audience />
<Pricing />
<Testimonials />
<Pricing />
<FinalCTA />
</main>
<FinalCTA />
</div>
);
}

// Simplified floating CTA
const FloatingCTA = () => {
const router = useRouter();
const { user } = useSupabase();
const buttonText = user ? 'Go to Chat' : 'Sign In';
const targetRoute = user ? '/chat' : '/auth';

return (
<CrossBrowserButton
onClick={() => router.push(targetRoute)}
className="cross-browser-button gradient-button-primary flex items-center gap-2 rounded-full px-6 py-3 font-medium text-white shadow-lg shadow-purple-900/20"
motionProps={{
whileHover: { scale: 1.05 },
whileTap: { scale: 0.95 },
}}
>
<span>{buttonText}</span>
<svg
width="16"
height="16"
viewBox="0 0 16 16"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M3.33337 8H12.6667"
stroke="currentColor"
strokeWidth="1.5"
strokeLinecap="round"
strokeLinejoin="round"
/>
<path
d="M8.66663 4L12.6666 8L8.66663 12"
stroke="currentColor"
strokeWidth="1.5"
strokeLinecap="round"
strokeLinejoin="round"
/>
</svg>
</CrossBrowserButton>
);
};
Loading