diff --git a/src/app/globals.css b/src/app/globals.css index dc0cf2bf..f18000e7 100644 --- a/src/app/globals.css +++ b/src/app/globals.css @@ -150,16 +150,6 @@ text-decoration: none; } - /* Removed macOS day/night mode detection to use our app's theme setting exclusively */ -} - -/* Custom styling for AppKit button text */ -:root:not(.dark) appkit-button wui-text[variant="paragraph-600"] { - color: #333333 !important; -} - -:root:not(.dark) appkit-button { - --wui-color-inherit: #333333 !important; } @layer base { diff --git a/src/app/page.tsx b/src/app/page.tsx index 2005cee8..15bb4bd3 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -5,11 +5,9 @@ import * as React from "react"; import { useAccount } from "wagmi"; import { RootLayout } from "@/components/chat/RootLayout"; -import { DisconnectedMessage } from "@/components/shared/DIsconnectedMessage"; +import { DisconnectedCard } from "@/components/shared/DisconnectedCard"; import MatrixCanvas from "@/components/shared/MatrixCanvas"; -import { useDisconnectedDarkMode } from "@/hooks/useDisconnectedDarkMode"; - import { useChat } from "@/contexts/chat-context"; export default function HomePage() { @@ -20,8 +18,6 @@ export default function HomePage() { handleNavigateToRoot(); }, []); - useDisconnectedDarkMode(isConnected); - return ( <>
@@ -29,7 +25,7 @@ export default function HomePage() { {!isConnected && ( <> - + )} diff --git a/src/components/chat/ChatLayout.tsx b/src/components/chat/ChatLayout.tsx index c78d8f9d..fd12fc90 100644 --- a/src/components/chat/ChatLayout.tsx +++ b/src/components/chat/ChatLayout.tsx @@ -9,7 +9,7 @@ import { Loader2 } from "lucide-react"; import ChatInput from "@/components/chat/chat-input"; import { Messages } from "@/components/chat/messages"; -import { ChatDisconnectedMessage } from "@/components/shared/DIsconnectedMessage"; +import { ChatDisconnectedCard } from "@/components/shared/DisconnectedCard"; import { useLayoutState } from "@/hooks/useLayoutState"; @@ -68,7 +68,7 @@ export function ChatLayout() { {showDisconnected && (
- +
)} diff --git a/src/components/chat/RootLayout.tsx b/src/components/chat/RootLayout.tsx index ee05ddd3..ec62be8b 100644 --- a/src/components/chat/RootLayout.tsx +++ b/src/components/chat/RootLayout.tsx @@ -7,7 +7,7 @@ import { useAccount } from "wagmi"; import RootChatInput from "@/components/chat/chat-input-root"; import { ExampleQueries } from "@/components/chat/example-queries"; -import { ChatDisconnectedMessage } from "@/components/shared/DIsconnectedMessage"; +import { ChatDisconnectedCard } from "@/components/shared/DisconnectedCard"; import { useChat } from "@/contexts/chat-context"; @@ -47,7 +47,7 @@ export function RootLayout() {
- +
diff --git a/src/components/header/theme-toggle.tsx b/src/components/header/theme-toggle.tsx index f9f88e45..197207de 100644 --- a/src/components/header/theme-toggle.tsx +++ b/src/components/header/theme-toggle.tsx @@ -10,7 +10,8 @@ const ThemeToggle = () => { const { theme, setTheme } = useTheme(); const toggleTheme = () => { - setTheme(theme === "light" ? "dark" : "light"); + const newTheme = theme === "light" ? "dark" : "light"; + setTheme(newTheme); }; return ( diff --git a/src/components/shared/DIsconnectedMessage.tsx b/src/components/shared/DisconnectedCard.tsx similarity index 85% rename from src/components/shared/DIsconnectedMessage.tsx rename to src/components/shared/DisconnectedCard.tsx index c3a32f57..58c98cdb 100644 --- a/src/components/shared/DIsconnectedMessage.tsx +++ b/src/components/shared/DisconnectedCard.tsx @@ -3,7 +3,7 @@ import Link from "next/link"; import { ConnectKitButton } from "connectkit"; import { RefreshCw, Shield, Sparkles } from "lucide-react"; -export function ChatDisconnectedMessage() { +export function ChatDisconnectedCard() { return (
@@ -41,9 +41,9 @@ export function ChatDisconnectedMessage() { ); } -export function DisconnectedMessage() { +export function DisconnectedCard() { return ( -
+
{[...Array(30)].map((_, i) => (
@@ -109,25 +109,27 @@ export function DisconnectedMessage() {
-

+

Connect your Wallet to access the Terminal. Sign in via Signature to unlock the Matrix.

-
+
- + Secure Connection
-
+
- Premium Access + + Premium Access +
-

+

This signature does not give anyone access to your funds and will not be shared with any third parties. Signing your blockchain address is anonymous and does not compromise your @@ -152,8 +154,8 @@ export function DisconnectedMessage() { Return to Home diff --git a/src/components/shared/MatrixCanvas.tsx b/src/components/shared/MatrixCanvas.tsx index 8bf6b663..ecf9e674 100644 --- a/src/components/shared/MatrixCanvas.tsx +++ b/src/components/shared/MatrixCanvas.tsx @@ -6,10 +6,6 @@ const MatrixCanvas = () => { const canvasRef = useRef(null); useEffect(() => { - // Enforce dark mode on client-side - document.documentElement.classList.add("dark"); - document.body.classList.add("dark"); - const canvas = canvasRef.current; if (!canvas) return; @@ -42,6 +38,7 @@ const MatrixCanvas = () => { } const isDarkMode = document.documentElement.classList.contains("dark"); + console.log("isDarkMode", isDarkMode); ctx.fillStyle = isDarkMode ? "rgba(0, 0, 0, 1)" : "rgba(255, 255, 255, 1)"; ctx.fillRect(0, 0, canvas.width, canvas.height); @@ -49,7 +46,7 @@ const MatrixCanvas = () => { const draw = () => { // Black BG for the canvas with opacity to create trail effect const isDarkMode = document.documentElement.classList.contains("dark"); - + // Theme-aware background - dark in dark mode, white in light mode if (isDarkMode) { ctx.fillStyle = "rgba(0, 0, 0, 0.06)"; // Dark mode: black with opacity diff --git a/src/components/shared/WalletGuard.tsx b/src/components/shared/WalletGuard.tsx index 43c31eb4..010ce8ec 100644 --- a/src/components/shared/WalletGuard.tsx +++ b/src/components/shared/WalletGuard.tsx @@ -6,7 +6,8 @@ import { usePathname, useRouter } from "next/navigation"; import { useAccount } from "wagmi"; -// Allow root path and chat paths to be accessed without redirecting +import { useTheme } from "@/contexts/theme-context"; + const isPublicPath = (path: string) => path === "/" || path.startsWith("/chat/"); @@ -14,12 +15,11 @@ export function WalletGuard({ children }: { children: React.ReactNode }) { const { isConnecting, isConnected } = useAccount(); const router = useRouter(); const pathname = usePathname(); + const { setTheme } = useTheme(); const [isInitialized, setIsInitialized] = useState(false); - // Wait for wallet state to be fully determined useEffect(() => { if (!isConnecting && !isInitialized) { - // Add a small delay to ensure state is fully rehydrated const timer = setTimeout(() => { setIsInitialized(true); }, 500); @@ -28,24 +28,26 @@ export function WalletGuard({ children }: { children: React.ReactNode }) { } }, [isConnecting, isInitialized]); - // Handle redirects useEffect(() => { if ( - isInitialized && // Only after initialization - !isConnecting && // Not in the process of connecting - !isConnected && // Definitely not connected - !isPublicPath(pathname) // Not on a public path + isInitialized && + !isConnecting && + !isConnected && + !isPublicPath(pathname) ) { router.push("/"); } - }, [isConnected, isConnecting, pathname, router, isInitialized]); - // During initialization, render children + if (isConnected) { + const savedTheme = localStorage.getItem("theme") || "dark"; + setTheme(savedTheme === "dark" ? "dark" : "light"); + } + }, [isConnected, isConnecting, pathname, router, isInitialized, setTheme]); + if (!isInitialized || isConnecting) { return <>{children}; } - // After initialization, block if definitely not connected and not on a public path if (!isConnected && !isPublicPath(pathname)) { return null; } diff --git a/src/components/shared/Web3Provider.tsx b/src/components/shared/Web3Provider.tsx index e0731289..75ec8033 100644 --- a/src/components/shared/Web3Provider.tsx +++ b/src/components/shared/Web3Provider.tsx @@ -5,6 +5,8 @@ import { ConnectKitProvider, getDefaultConfig } from "connectkit"; import { WagmiProvider, createConfig, http } from "wagmi"; import { arbitrum, base, mainnet, optimism } from "wagmi/chains"; +import { useTheme } from "@/contexts/theme-context"; + // Define custom chains that aren't in wagmi directly const mode = { id: 34443, @@ -90,23 +92,43 @@ const queryClient = new QueryClient(); // Web3 Provider component export const Web3Provider = ({ children }: { children: React.ReactNode }) => { + const { theme } = useTheme(); + const isDarkMode = theme === "dark"; + return ( {children} diff --git a/src/contexts/theme-context.tsx b/src/contexts/theme-context.tsx index 043644bc..26dd7803 100644 --- a/src/contexts/theme-context.tsx +++ b/src/contexts/theme-context.tsx @@ -21,7 +21,6 @@ export const useTheme = () => useContext(ThemeContext); export const ThemeProvider: React.FC<{ children: React.ReactNode; }> = ({ children }) => { - // Start with undefined to avoid hydration mismatch const [theme, setThemeState] = useState(undefined); // Initialize theme from localStorage on mount @@ -31,44 +30,17 @@ export const ThemeProvider: React.FC<{ const savedTheme = (localStorage.getItem("theme") as Theme) || defaultTheme; setThemeState(savedTheme); - - // Apply the theme to the HTML element applyTheme(savedTheme); - - // Update the AppKit theme (if it exists) - try { - // @ts-expect-error - AppKit may not be fully typed - if (window.AppKit && window.AppKit.setThemeMode) { - // @ts-expect-error - AppKit may not be fully typed - window.AppKit.setThemeMode(savedTheme); - } - } catch (error) { - console.error("Failed to update AppKit theme:", error); - } } }, []); - // Apply theme changes const setTheme = (newTheme: Theme) => { setThemeState(newTheme); localStorage.setItem("theme", newTheme); applyTheme(newTheme); - - // Update AppKit theme if available - try { - // @ts-expect-error - AppKit may not be fully typed - if (window.AppKit && window.AppKit.setThemeMode) { - // @ts-expect-error - AppKit may not be fully typed - window.AppKit.setThemeMode(newTheme); - } - } catch (error) { - console.error("Failed to update AppKit theme:", error); - } }; - // Apply theme to document const applyTheme = (theme: Theme) => { - // Skip server-side rendering if (typeof window === "undefined" || typeof document === "undefined") return; @@ -81,37 +53,6 @@ export const ThemeProvider: React.FC<{ } }; - // Add script to apply theme immediately before React hydration - useEffect(() => { - // Skip server-side rendering - if (typeof window === "undefined" || typeof document === "undefined") - return; - - const existingScript = document.getElementById("theme-script"); - if (!existingScript) { - const script = document.createElement("script"); - script.id = "theme-script"; - script.innerHTML = ` - (function() { - try { - const savedTheme = localStorage.getItem('theme') || '${defaultTheme}'; - if (savedTheme === 'dark') { - document.documentElement.classList.add('dark'); - document.documentElement.style.colorScheme = 'dark'; - } else { - document.documentElement.classList.remove('dark'); - document.documentElement.style.colorScheme = 'light'; - } - } catch (e) { - console.error('Error setting initial theme:', e); - } - })(); - `; - document.head.appendChild(script); - } - }, []); - - // Don't render until we have a theme to avoid hydration issues if (theme === undefined) { return <>{children}; } diff --git a/src/contexts/user-context.tsx b/src/contexts/user-context.tsx index 93c648fb..cfa482c1 100644 --- a/src/contexts/user-context.tsx +++ b/src/contexts/user-context.tsx @@ -13,7 +13,6 @@ import { useAccount } from "wagmi"; import { supabaseReadOnly } from "@/lib/supabaseClient"; import { UserQuota, getUserProfile } from "@/lib/userManager"; -// Define the shape of the user context interface UserContextType { address: string | undefined; isConnected: boolean; @@ -26,9 +25,9 @@ interface UserContextType { }) | null; isProfileLoading: boolean; + fetchUserProfile: () => Promise; } -// Create context with default values const UserContext = createContext({ address: undefined, isConnected: false, @@ -37,9 +36,9 @@ const UserContext = createContext({ isLoading: true, userProfile: null, isProfileLoading: true, + fetchUserProfile: async () => {}, }); -// Custom hook to use the user context export const useUser = () => useContext(UserContext); interface UserProviderProps { diff --git a/src/hooks/useDisconnectedDarkMode.ts b/src/hooks/useDisconnectedDarkMode.ts deleted file mode 100644 index 8feb3fba..00000000 --- a/src/hooks/useDisconnectedDarkMode.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { useEffect } from "react"; - -/** - * Force dark mode when the user is disconnected from wallet - * Restores original theme preference when reconnected - */ -export function useDisconnectedDarkMode(isConnected: boolean) { - useEffect(() => { - // Only enforce dark mode when disconnected - if (!isConnected) { - // Save the current theme preference - const savedTheme = localStorage.getItem("theme"); - - // Add dark class for disconnected state - document.documentElement.classList.add("dark"); - document.documentElement.style.colorScheme = "dark"; - - // Return cleanup function to restore original theme when connected - return () => { - if (savedTheme === "light") { - document.documentElement.classList.remove("dark"); - document.documentElement.style.colorScheme = "light"; - } - }; - } - }, [isConnected]); -}