import React, { useState, useContext, useEffect } from "react"; import { motion, AnimatePresence } from "framer-motion"; import { Activity, BarChart2, Shield, Calendar, Zap, LogIn, Settings, X, } from "lucide-react"; import { Analytics } from "@vercel/analytics/react"; import { SpeedInsights } from "@vercel/speed-insights/react"; import { LandingPage } from "./components/LandingPage"; import ProjectionsTable from "./components/ProjectionsTable"; import AccuracyDashboard from "./components/AccuracyDashboard"; import TeamRatings from "./components/TeamRatings"; import Fixtures from "./components/Fixtures"; import Solver from "./components/Solver"; import LoginModal from "./components/LoginModal"; import { PlayerProvider, PlayerContext } from "./PlayerContext"; const tabs = [ { id: "solver", label: "Solver", icon: Zap }, { id: "projections", label: "Projections", icon: Activity }, { id: "accuracy", label: "Accuracy", icon: BarChart2 }, { id: "ratings", label: "Team Ratings", icon: Shield }, { id: "fixtures", label: "Fixtures", icon: Calendar }, ]; function AppContent() { const [activeTab, setActiveTab] = useState(() => { if (typeof window !== 'undefined') { const params = new URLSearchParams(window.location.search); return params.get("tab") || tabs[0].id; } return tabs[0].id; }); useEffect(() => { if (typeof window !== 'undefined') { const url = new URL(window.location); url.searchParams.set("tab", activeTab); window.history.replaceState({}, "", url); } }, [activeTab]); const [showLoginModal, setShowLoginModal] = useState(false); const [showSettings, setShowSettings] = useState(false); const { isLoggedIn, setIsLoggedIn, userProfile, setUserProfile, hasGuestMadeEdits, setHasGuestMadeEdits, isCheckingAuth, // <-- Pull in the new state isLoadingDB, } = useContext(PlayerContext); const [newDefaultId, setNewDefaultId] = useState(""); const [isSaved, setIsSaved] = useState(false); // Sync local input with context profile useEffect(() => { if (userProfile?.defaultTeamId) { setNewDefaultId(userProfile.defaultTeamId); } }, [userProfile]); const handleUpdateDefaultId = () => { const parsedId = parseInt(newDefaultId); if (!parsedId) return; const token = localStorage.getItem('fpl_token'); if (token) { fetch('https://anayshukla-fpl-solver.hf.space/api/auth/save_session', { method: 'POST', headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${token}` }, body: JSON.stringify({ default_team_id: parsedId }) }).then(() => { setUserProfile(prev => ({ ...prev, defaultTeamId: parsedId })); setIsSaved(true); setTimeout(() => setIsSaved(false), 2000); }); } }; // --- THE NEW LOADING INTERCEPTOR --- // If we are actively checking the token, show a sleek loading screen instead of the landing page if (isCheckingAuth || isLoadingDB) { return (

Entering Mansion...

{isLoadingDB &&

Loading database...

} {isCheckingAuth && !isLoadingDB &&

Verifying access...

}
); } if (!isLoggedIn) { return ; } const handleLogout = () => { localStorage.removeItem("fpl_token"); setIsLoggedIn(false); setUserProfile({ username: "Guest", defaultTeamId: null, isAdmin: false }); setShowSettings(false); setActiveTab("solver"); }; return (
Skip to main content
{/* THE RESTORED TITLE */}
setActiveTab("solver")} className="flex items-center gap-3 cursor-pointer hover:opacity-80 transition-opacity" > Luigi's Mansion Logo

Luigi's Mansion

{isLoggedIn ? (
{/* Desktop: username left of button. Mobile: hidden here, shown below button */}
{userProfile.isAdmin && ( )} {userProfile.username}
{/* Mobile only: username under the button */}
{userProfile.isAdmin && ( )} {userProfile.username}
{showSettings && (
{/* Default ID Setting */}

Default FPL ID

setNewDefaultId(e.target.value)} placeholder="e.g. 123456" className="bg-slate-950 border border-slate-700 rounded py-1.5 px-3 text-xs font-bold text-slate-200 outline-none focus:border-luigi-500 flex-1 shadow-inner" />
)}
) : (
{hasGuestMadeEdits && (
💡

You've made custom adjustments!{" "} setShowLoginModal(true)} > Log in {" "} to save your session.

)}
)}
{/* closes Row 1 */} {/* Row 2 — nav tabs */}
{isLoggedIn ? (
{/* Desktop: username left of button. Mobile: hidden here, shown below button */}
{userProfile.isAdmin && ( )} {userProfile.username}
{/* Mobile only: username under the button */}
{userProfile.isAdmin && ( )} {userProfile.username}
{showSettings && (
{/* Default ID Setting */}

Default FPL ID

setNewDefaultId(e.target.value)} placeholder="e.g. 123456" className="bg-slate-950 border border-slate-700 rounded py-1.5 px-3 text-xs font-bold text-slate-200 outline-none focus:border-luigi-500 flex-1 shadow-inner" />
)}
) : (
{hasGuestMadeEdits && (
💡

You've made custom adjustments!{" "} setShowLoginModal(true)} > Log in {" "} to save your session.

)}
)}
{/* closes outer flex-col */}
{/* Solver is always mounted so local state (snapshot, pairs, highlights) survives tab switches */}
{/* Every other tab is animated and only rendered when active */} {activeTab !== "solver" && ( {activeTab === "projections" && } {activeTab === "accuracy" && } {activeTab === "ratings" && } {activeTab === "fixtures" && } )}
setShowLoginModal(false)} />
); } export default function App() { return ( ); }