11'use client' ;
22
3- import { useRef , useState } from 'react' ;
3+ import { useEffect , useRef , useState } from 'react' ;
44import { useInView , motion , AnimatePresence } from 'framer-motion' ;
55import {
66 Check ,
@@ -21,6 +21,7 @@ import {
2121 TrendingUp ,
2222} from 'lucide-react' ;
2323import Link from 'next/link' ;
24+ import { createClient } from '@/lib/supabase/client' ;
2425
2526/* ─────────────────────────────────────────────────────────
2627 ANIMATION PRIMITIVES
@@ -600,6 +601,28 @@ const proPlanFeatures = [
600601 ═════════════════════════════════════════════════════════ */
601602
602603export default function LandingPage ( ) {
604+ useEffect ( ( ) => {
605+ const url = new URL ( window . location . href ) ;
606+ const code = url . searchParams . get ( 'code' ) ;
607+ const tokenHash = url . searchParams . get ( 'token_hash' ) ;
608+
609+ // If auth params accidentally land on "/", forward to callback to complete session exchange.
610+ if ( code || tokenHash ) {
611+ window . location . replace ( `/auth/callback${ url . search } ` ) ;
612+ return ;
613+ }
614+
615+ // Keep logged-in users inside the app instead of showing marketing landing.
616+ const supabase = createClient ( ) ;
617+ void supabase . auth . getUser ( ) . then ( ( { data : { user } } ) => {
618+ if ( user ) {
619+ window . location . replace ( '/app/today' ) ;
620+ }
621+ } ) . catch ( ( ) => {
622+ // Ignore errors here; unauthenticated users should still see the landing page.
623+ } ) ;
624+ } , [ ] ) ;
625+
603626 return (
604627 < div className = "min-h-screen bg-bg-primary font-sans relative" >
605628 { /* Noise texture */ }
0 commit comments