Session G (night2): Phase 6 — landing first-paint + content engine + OG
6.1 FIRST-PAINT ROOT CAUSE: the landing blocked its ENTIRE render on
Supabase auth init ('loading || user') — anonymous visitors stared at
'LOADING THE SLATE' for the whole auth roundtrip (~3-4s). Now a
synchronous localStorage session check gates the suppression: only
visitors who actually hold a session (and will redirect) wait;
anonymous traffic paints the hero immediately. Full RSC conversion of
the hero is deferred and logged — the blocker itself is dead.
Proof Strip rules: top-3 by grade whatever they are; 'TONIGHT'S TOP
SIGNALS' only with >=1 A-tier, else 'TONIGHT'S BOARD'; nothing graded
yet → yesterday's SETTLED reads with outcome chips (misses included).
6.2 Content routes: /api/content/top-signals/:sport,
/streak-watch/:sport (the zero-grade daily format off the aggregator),
/daily-report/:sport — built but self-flagging do_not_post until the
record clears n>=20. Flag, don't fake.
6.3 Per-player OG images: app/player/[name]/opengraph-image.tsx (Node
runtime per the S53 rule) + server layout generateMetadata — every
shared player link unfurls as an intelligence card.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
+22
-4
@@ -1,6 +1,6 @@
|
||||
'use client';
|
||||
|
||||
import { useEffect } from 'react';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { useRouter } from 'next/navigation';
|
||||
import { useAuth } from '@/contexts/AuthContext';
|
||||
import Hero from '@/components/Hero';
|
||||
@@ -25,17 +25,35 @@ import Pricing from '@/components/Pricing';
|
||||
import FAQ from '@/components/FAQ';
|
||||
// Footer is mounted globally in the root layout (Session 34) — no per-page import.
|
||||
|
||||
// Session 60 (6.1) — the 3–4s "LOADING THE SLATE" first paint was THIS
|
||||
// page blocking its entire render on Supabase auth initialization
|
||||
// (`loading || user`), even for anonymous visitors who were never going to
|
||||
// redirect. Synchronous localStorage check instead: only a visitor who
|
||||
// actually HAS a stored session (and will redirect to /dashboard) sees the
|
||||
// suppressed render; anonymous traffic paints the hero immediately.
|
||||
function hasStoredSession(): boolean {
|
||||
if (typeof window === 'undefined') return false;
|
||||
try {
|
||||
for (let i = 0; i < window.localStorage.length; i += 1) {
|
||||
const k = window.localStorage.key(i) || '';
|
||||
if (/^sb-.*-auth-token$/.test(k) || k === 'sb-token') return true;
|
||||
}
|
||||
} catch { /* storage blocked → treat as anonymous */ }
|
||||
return false;
|
||||
}
|
||||
|
||||
export default function Home() {
|
||||
const { user, loading } = useAuth();
|
||||
const router = useRouter();
|
||||
const [maybeSignedIn] = useState<boolean>(() => hasStoredSession());
|
||||
|
||||
useEffect(() => {
|
||||
if (!loading && user) router.replace('/dashboard');
|
||||
}, [user, loading, router]);
|
||||
|
||||
// While we know the user is signed in we suppress the marketing
|
||||
// render to avoid a flicker before the redirect lands.
|
||||
if (loading || user) {
|
||||
// Suppress the marketing render ONLY for visitors with a stored session
|
||||
// (they're about to redirect) — anonymous first paint is instant.
|
||||
if (user || (loading && maybeSignedIn)) {
|
||||
return (
|
||||
<section style={{ minHeight: '80vh', display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
|
||||
<p className="mono" style={{ color: 'var(--text-tertiary)', fontSize: 13, letterSpacing: '0.08em', textTransform: 'uppercase' }}>
|
||||
|
||||
Reference in New Issue
Block a user