Skip to content

Commit 1af12f5

Browse files
committed
Revert to state at d6fa552 (encourage wide chart types)
Made-with: Cursor
1 parent 983581b commit 1af12f5

7 files changed

Lines changed: 53 additions & 540 deletions

File tree

frontend/src/app/(dashboard)/app/page.tsx

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,11 @@
22

33
import { Suspense } from "react"
44
import { AppContentRouter } from "@/components/app/AppContentRouter"
5-
import ChatInput from "@/components/app/ChatInput"
65
import { useThemeColors } from "@/context/ThemeContext"
76

87
function SuspenseFallback() {
98
const COLORS = useThemeColors()
10-
return (
11-
<div style={{ flex: 1, minHeight: 0, display: "flex", flexDirection: "column", background: COLORS.bg, position: "relative", overflow: "hidden" }}>
12-
<div style={{ flex: 1, minHeight: 0, background: COLORS.bg }} />
13-
<div style={{ position: "absolute", inset: 0, display: "flex", alignItems: "flex-end", justifyContent: "center", paddingBottom: "6px", pointerEvents: "none", zIndex: 10 }}>
14-
<div style={{ pointerEvents: "auto" }}>
15-
<ChatInput />
16-
</div>
17-
</div>
18-
</div>
19-
)
9+
return <div style={{ flex: 1, minHeight: 0, background: COLORS.bg }} />
2010
}
2111

2212
export default function AppPage() {
Lines changed: 2 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,7 @@
11
"use client"
22

3-
import { useMemo } from "react"
43
import { useThemeColors, useIsDark } from "@/context/ThemeContext"
54
import { FONTS } from "@/lib/constants"
6-
import { readSessionCache } from "@/lib/sessionCache"
7-
import { readLatestSessionUiCache, readSessionUiCache } from "@/lib/sessionUiCache"
8-
9-
function readRouteSessionId(): string {
10-
if (typeof window === "undefined") return ""
11-
try {
12-
return new URLSearchParams(window.location.search).get("id")?.trim() || ""
13-
} catch {
14-
return ""
15-
}
16-
}
175

186
/**
197
* Shown while the session page is loading (Suspense). Keeps TopBar + content area
@@ -22,32 +10,12 @@ function readRouteSessionId(): string {
2210
export function SessionRouteFallback() {
2311
const COLORS = useThemeColors()
2412
const isDark = useIsDark()
25-
const sessionId = useMemo(() => readRouteSessionId(), [])
26-
const cachedUi = useMemo(
27-
() => (sessionId ? readSessionUiCache(sessionId) : null),
28-
[sessionId],
29-
)
30-
const cachedSession = useMemo(
31-
() => (sessionId ? readSessionCache(sessionId) : null),
32-
[sessionId],
33-
)
34-
const latestUi = useMemo(
35-
() => (!cachedUi ? readLatestSessionUiCache() : null),
36-
[cachedUi],
37-
)
38-
const fallbackTitle = (
39-
cachedUi?.title
40-
|| cachedSession?.question
41-
|| latestUi?.entry.title
42-
|| "Session"
43-
).trim() || "Session"
44-
const fallbackDraft = cachedUi?.draft ?? latestUi?.entry.draft ?? ""
4513
const topBarGradient = isDark
4614
? "linear-gradient(180deg, transparent 0%, rgba(255, 255, 255, 0.02) 50%, rgba(255, 255, 255, 0.08) 100%)"
4715
: "linear-gradient(180deg, transparent 0%, rgba(0, 0, 0, 0.02) 50%, rgba(0, 0, 0, 0.06) 100%)"
4816

4917
return (
50-
<div style={{ flex: 1, minHeight: 0, display: "flex", flexDirection: "column", overflow: "hidden", background: COLORS.bg, position: "relative" }}>
18+
<div style={{ flex: 1, minHeight: 0, display: "flex", flexDirection: "column", overflow: "hidden", background: COLORS.bg }}>
5119
<header
5220
style={{
5321
height: "60px",
@@ -59,39 +27,10 @@ export function SessionRouteFallback() {
5927
}}
6028
>
6129
<span style={{ fontFamily: FONTS.sans, fontSize: "16px", fontWeight: 600, color: COLORS.textPrimary }}>
62-
{fallbackTitle}
30+
Untitled
6331
</span>
6432
</header>
6533
<div style={{ flex: 1, minHeight: 0, background: COLORS.bg }} />
66-
<div style={{ position: "absolute", inset: 0, display: "flex", alignItems: "flex-end", justifyContent: "center", paddingBottom: "6px", pointerEvents: "none", zIndex: 10 }}>
67-
<div
68-
style={{
69-
width: "720px",
70-
maxWidth: "85vw",
71-
borderRadius: "24px",
72-
border: `1px solid ${COLORS.border}`,
73-
background: isDark ? "#0A0A0A" : COLORS.modalBg,
74-
padding: "18px 24px",
75-
minHeight: "64px",
76-
display: "flex",
77-
alignItems: "center",
78-
}}
79-
>
80-
<span
81-
style={{
82-
fontFamily: FONTS.sans,
83-
fontSize: "16px",
84-
color: fallbackDraft.trim() ? COLORS.textPrimary : COLORS.textDimmed,
85-
whiteSpace: "nowrap",
86-
overflow: "hidden",
87-
textOverflow: "ellipsis",
88-
width: "100%",
89-
}}
90-
>
91-
{fallbackDraft.trim() ? fallbackDraft : "Add to thread..."}
92-
</span>
93-
</div>
94-
</div>
9534
</div>
9635
)
9736
}

frontend/src/components/app/AppShell.tsx

Lines changed: 28 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
11
"use client"
22

33
import { lazy, Suspense, useCallback, useEffect, useRef, useState } from "react"
4-
5-
/** Delay before showing unauthenticated overlay/redirect so auth persistence can restore (avoids sidebar flash). */
6-
const AUTH_SETTLE_MS = 220
74
import { usePathname } from "next/navigation"
85
import { Sidebar } from "@/components/app/Sidebar"
96
import { ErrorBoundary } from "@/components/app/ErrorBoundary"
@@ -14,7 +11,7 @@ import { ShellLayoutProvider } from "@/context/ShellLayoutContext"
1411
import OnboardingModal from "@/components/app/OnboardingModal"
1512
import { fetchUserMemory, fetchUserStatus, updateUserMemory, type UpdateUserMemoryInput } from "@/lib/api"
1613
import { trackFrontendEvent } from "@/lib/frontendAnalytics"
17-
import { getSettingsCache, setSettingsCache } from "@/lib/settingsCache"
14+
import { setSettingsCache } from "@/lib/settingsCache"
1815

1916
const GoldenGuideModal = lazy(() => import("@/components/app/GoldenGuideModal")) as React.LazyExoticComponent<React.ComponentType<{ COLORS: ThemeColors }>>
2017
const SearchModal = lazy(() => import("@/components/app/SearchModal")) as React.LazyExoticComponent<React.ComponentType<{ COLORS: ThemeColors }>>
@@ -25,78 +22,23 @@ function hasCompletedOnboarding(memory: Record<string, unknown>): boolean {
2522
return typeof completedAt === "string" && completedAt.trim().length > 0
2623
}
2724

28-
function readCachedOnboardingSnapshot(): { required: boolean; memory: Record<string, unknown> } {
29-
const cached = getSettingsCache()
30-
const memory = cached?.memory ?? {}
31-
return {
32-
required: !hasCompletedOnboarding(memory),
33-
memory,
34-
}
35-
}
36-
3725
function AuthGate({ children }: { children: React.ReactNode }) {
3826
const COLORS = useThemeColors()
3927
const { user, loading } = useAuth()
40-
const [showUnauthOverlay, setShowUnauthOverlay] = useState(false)
41-
const settleTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null)
4228

4329
useEffect(() => {
44-
if (loading || user) {
45-
if (settleTimerRef.current) {
46-
clearTimeout(settleTimerRef.current)
47-
settleTimerRef.current = null
48-
}
49-
setShowUnauthOverlay(false)
50-
return
51-
}
52-
settleTimerRef.current = setTimeout(() => {
53-
settleTimerRef.current = null
54-
setShowUnauthOverlay(true)
30+
if (!loading && !user) {
5531
try { sessionStorage.setItem("fp-auth-redirect", window.location.pathname) } catch {}
5632
window.location.href = "/"
57-
}, AUTH_SETTLE_MS)
58-
return () => {
59-
if (settleTimerRef.current) {
60-
clearTimeout(settleTimerRef.current)
61-
settleTimerRef.current = null
62-
}
6333
}
6434
}, [loading, user])
6535

66-
const renderGateStatus = (message: string) => (
67-
<div
68-
style={{
69-
position: "fixed",
70-
inset: 0,
71-
zIndex: 60,
72-
background: COLORS.bg,
73-
display: "flex",
74-
alignItems: "center",
75-
justifyContent: "center",
76-
}}
77-
>
78-
<span
79-
style={{
80-
color: COLORS.textSecondary,
81-
fontSize: "14px",
82-
fontFamily: "var(--font-geist-sans), sans-serif",
83-
letterSpacing: "0.01em",
84-
}}
85-
>
86-
{message}
87-
</span>
88-
</div>
89-
)
90-
91-
// Always render the shell (sidebar, main, topbar, input) so it stays visible and cached.
92-
// Only show redirect overlay after auth has "settled" as unauthenticated (short delay
93-
// so Firebase persistence can restore the session and we don't flash-hide the sidebar).
94-
return (
95-
<>
96-
{children}
97-
{showUnauthOverlay ? renderGateStatus("Redirecting to sign-in...") : null}
98-
</>
99-
)
36+
if (user) return <>{children}</>
37+
// First visit, auth loading
38+
if (loading) return <div style={{ position: "fixed", inset: 0, zIndex: 60, background: COLORS.bg }} />
39+
// Not authenticated
40+
if (!user) return <div style={{ position: "fixed", inset: 0, zIndex: 60, background: COLORS.bg }} />
41+
return <>{children}</>
10042
}
10143

10244
function ShellInner({ children }: { children: React.ReactNode }) {
@@ -105,16 +47,17 @@ function ShellInner({ children }: { children: React.ReactNode }) {
10547
const { user, loading } = useAuth()
10648
const pathname = usePathname()
10749
const { guideOpen, searchOpen } = state
108-
const cachedOnboarding = useRef(readCachedOnboardingSnapshot())
10950
const prefetchedRef = useRef(false)
110-
const [onboardingRequired, setOnboardingRequired] = useState(cachedOnboarding.current.required)
51+
const [onboardingChecking, setOnboardingChecking] = useState(true)
52+
const [onboardingRequired, setOnboardingRequired] = useState(false)
11153
const [onboardingSubmitting, setOnboardingSubmitting] = useState(false)
11254
const [onboardingError, setOnboardingError] = useState<string | null>(null)
113-
const [memorySnapshot, setMemorySnapshot] = useState<Record<string, unknown>>(cachedOnboarding.current.memory)
55+
const [memorySnapshot, setMemorySnapshot] = useState<Record<string, unknown>>({})
11456

11557
useEffect(() => {
11658
if (user) return
11759
prefetchedRef.current = false
60+
setOnboardingChecking(true)
11861
setOnboardingRequired(false)
11962
setOnboardingError(null)
12063
setOnboardingSubmitting(false)
@@ -125,6 +68,7 @@ function ShellInner({ children }: { children: React.ReactNode }) {
12568
if (loading || !user) return
12669
if (prefetchedRef.current) return
12770
prefetchedRef.current = true
71+
setOnboardingChecking(true)
12872
void Promise.all([fetchUserMemory(), fetchUserStatus()])
12973
.then(([memoryRes, statusRes]) => {
13074
setSettingsCache({
@@ -137,6 +81,9 @@ function ShellInner({ children }: { children: React.ReactNode }) {
13781
setOnboardingRequired(!hasCompletedOnboarding(memoryRes.memory))
13882
})
13983
.catch(() => {})
84+
.finally(() => {
85+
setOnboardingChecking(false)
86+
})
14087
}, [loading, user])
14188

14289
const handleOnboardingSubmit = useCallback(async (payload: UpdateUserMemoryInput) => {
@@ -184,7 +131,18 @@ function ShellInner({ children }: { children: React.ReactNode }) {
184131
<DeleteConfirmModal COLORS={COLORS} />
185132
</Suspense>
186133

187-
{!loading && user && onboardingRequired && (
134+
{!loading && user && onboardingChecking && (
135+
<div
136+
style={{
137+
position: "fixed",
138+
inset: 0,
139+
zIndex: 2400,
140+
background: COLORS.bg,
141+
}}
142+
/>
143+
)}
144+
145+
{!loading && user && !onboardingChecking && onboardingRequired && (
188146
<OnboardingModal
189147
mode="onboarding"
190148
initialMemory={memorySnapshot}

0 commit comments

Comments
 (0)