Files
SatsFaucet/frontend/src/App.tsx
T
SatsFaucet e7daa57ab4 Redesign frontend with Sats Flow theme and restore homepage sidebars.
Apply the glassmorphic Bitcoin-orange design system across the claim flow and all pages, add the eligibility draw animation, and flank the claim wizard with deposit and stats panels again.
2026-06-09 05:23:29 +02:00

127 lines
4.0 KiB
TypeScript

import { useState, useEffect, useCallback } from "react";
import { BrowserRouter, Routes, Route } from "react-router-dom";
import { getToken, getAuthMe, clearToken, type LoginMethod } from "./api";
import { Header } from "./components/Header";
import { Footer } from "./components/Footer";
import { ClaimWizard } from "./components/ClaimWizard";
import { StatsSection } from "./components/StatsSection";
import { DepositSection } from "./components/DepositSection";
import { TransactionsPage } from "./pages/TransactionsPage";
import { SponsorsPage } from "./pages/SponsorsPage";
import { MyAdsPage } from "./pages/MyAdsPage";
import { SponsorsSection } from "./components/SponsorsSection";
export default function App() {
const [pubkey, setPubkey] = useState<string | null>(null);
const [loginMethod, setLoginMethod] = useState<LoginMethod | null>(null);
const [statsRefetchTrigger, setStatsRefetchTrigger] = useState(0);
const refreshAuth = useCallback(() => {
const token = getToken();
if (!token) {
setPubkey(null);
setLoginMethod(null);
return;
}
getAuthMe()
.then((r) => {
setPubkey(r.pubkey);
setLoginMethod(r.method ?? "nip98");
})
.catch(() => {
clearToken();
setPubkey(null);
setLoginMethod(null);
});
}, []);
useEffect(() => {
refreshAuth();
const onAuthChanged = () => refreshAuth();
window.addEventListener("auth-changed", onAuthChanged);
return () => window.removeEventListener("auth-changed", onAuthChanged);
}, [refreshAuth]);
const handlePubkeyChange = useCallback((pk: string | null, method?: LoginMethod) => {
setPubkey(pk);
setLoginMethod(pk ? (method ?? "nip98") : null);
}, []);
const handleLogout = useCallback(() => {
clearToken();
setPubkey(null);
setLoginMethod(null);
}, []);
const handleClaimSuccess = useCallback(() => {
setStatsRefetchTrigger((t) => t + 1);
}, []);
return (
<BrowserRouter>
<div className="app sats-flow">
<Header pubkey={pubkey} onLogout={handleLogout} onLoginSuccess={handlePubkeyChange} />
<div className="topbar" />
<div className="app-body">
<Routes>
<Route
path="/"
element={
<>
<section className="claim-flow-page claim-flow-page--grid">
<div className="sf-ambient-glow" aria-hidden />
<div className="claim-flow-grid">
<aside className="sidebar sidebar-left">
<div className="funding-panel">
<DepositSection />
</div>
</aside>
<main className="claim-flow-main">
<ClaimWizard
pubkey={pubkey}
loginMethod={loginMethod}
onPubkeyChange={handlePubkeyChange}
onClaimSuccess={handleClaimSuccess}
/>
</main>
<aside className="sidebar sidebar-right">
<StatsSection refetchTrigger={statsRefetchTrigger} />
</aside>
</div>
</section>
<SponsorsSection />
</>
}
/>
<Route
path="/transactions"
element={
<div className="sf-page">
<TransactionsPage />
</div>
}
/>
<Route
path="/sponsors"
element={
<div className="sponsors-route sf-page">
<SponsorsPage />
</div>
}
/>
<Route
path="/my-ads"
element={
<div className="sf-page">
<MyAdsPage />
</div>
}
/>
</Routes>
</div>
<Footer />
</div>
</BrowserRouter>
);
}