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.
127 lines
4.0 KiB
TypeScript
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>
|
|
);
|
|
}
|