diff --git a/apps/web/src/App.tsx b/apps/web/src/App.tsx index 22e04762..e4959295 100644 --- a/apps/web/src/App.tsx +++ b/apps/web/src/App.tsx @@ -1,18 +1,19 @@ import { useCallback, useEffect } from "react"; import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; -import { VaultPanel } from "./components/dashboard/VaultPanel"; -import { WalletConnect } from "./components/onboarding/WalletConnect"; -import { Toasts } from "./components/ui/Toasts"; -import { ErrorBoundary } from "./components/ui/ErrorBoundary"; -import { useWalletStore } from "./store/wallet"; +import { VaultPanel } from "./components/dashboard/VaultPanel"; // FIX 1:./ +import { WalletConnect } from "./components/onboarding/WalletConnect"; // FIX 1:./ +import { Toasts } from "./components/ui/Toasts"; // FIX 1:./ +import { ErrorBoundary } from "./components/ui/ErrorBoundary"; // FIX 1:./ +import { useWalletStore } from "./store/wallet"; // FIX 1:./ import { useTranslation } from "react-i18next"; +import AdminLogin from "./pages/AdminLogin"; const queryClient = new QueryClient(); function Dashboard() { const { t, i18n } = useTranslation(); const toggleLanguage = useCallback(() => { - const newLang = i18n.language === "en" ? "fr" : "en"; + const newLang = i18n.language === "en"? "fr" : "en"; i18n.changeLanguage(newLang); localStorage.setItem("language", newLang); }, [i18n]); @@ -28,14 +29,13 @@ function Dashboard() { -
@@ -49,17 +49,15 @@ export default function App() { useEffect(() => { const revalidate = () => void useWalletStore.getState().revalidate(); revalidate(); - // Re-check authorization when the window regains focus. Freighter opens - // as an extension popup (separate window), so the page loses focus while - // the popup is open and regains it when it closes — this catches revoked - // site access without requiring a page reload. window.addEventListener("focus", revalidate); return () => window.removeEventListener("focus", revalidate); }, []); + const isAdminRoute = window.location.pathname === '/admin'; + return ( - + {isAdminRoute? : } ); diff --git a/apps/web/src/pages/AdminLogin.tsx b/apps/web/src/pages/AdminLogin.tsx new file mode 100644 index 00000000..7eef9b00 --- /dev/null +++ b/apps/web/src/pages/AdminLogin.tsx @@ -0,0 +1,38 @@ +// apps/web/src/pages/AdminLogin.tsx +import { useState, useEffect } from 'react' +import { readVaultAdmin } from '@stellar-sdk-helpers/coordinator' // daidaita path +import { useWalletStore } from '../store/useWalletStore' +import { connectWallet } from '../lib/wallet' + +export function AdminLogin() { + const { publicKey, connected } = useWalletStore() + const [status, setStatus] = useState<'loading' | 'blocked' | 'allowed'>('loading') + + useEffect(() => { + if (!connected) return + readVaultAdmin(import.meta.env.VITE_VAULT_CONTRACT_ID).then(admin => { + setStatus(admin === publicKey ? 'allowed' : 'blocked') + }).catch(() => setStatus('blocked')) + }, [connected, publicKey]) + + if (!connected) { + return ( +
+ +
+ ) + } + + if (status === 'blocked') { + return
Not authorized: {publicKey}
+ } + if (status === 'allowed') { + return
Admin Dashboard
+ } + return
Loading...
+}