Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

141 changes: 88 additions & 53 deletions packages/app/src/app/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,30 +12,38 @@ import { ChainRaceStatus } from "@/hooks/useChainRace";
import dynamic from "next/dynamic";

// Dynamic import for LeaderboardPanel (only loaded when racing/finished)
const LeaderboardPanel = dynamic(() => import("@/components/LeaderboardPanel").then(mod => ({ default: mod.LeaderboardPanel })), {
loading: () => (
<Card className="w-full">
<div className="flex items-center justify-center h-48">
<div className="animate-spin rounded-full h-8 w-8 border-b-2 border-primary"></div>
</div>
</Card>
),
ssr: false // Since this only shows during racing, no need for SSR
});
const LeaderboardPanel = dynamic(
() =>
import("@/components/LeaderboardPanel").then((mod) => ({
default: mod.LeaderboardPanel,
})),
{
loading: () => (
<Card className="w-full">
<div className="flex items-center justify-center h-48">
<div className="animate-spin rounded-full h-8 w-8 border-b-2 border-primary"></div>
</div>
</Card>
),
ssr: false, // Since this only shows during racing, no need for SSR
}
);

export default function Home() {
const { status } = useChainRaceContext();
// Create a stabilized status to prevent flickering
const [stableStatus, setStableStatus] = useState<ChainRaceStatus>(status);

useEffect(() => {
const isRacingOrFinished = (s: ChainRaceStatus) => s === "racing" || s === "finished";
const isInitialState = (s: ChainRaceStatus) => s === "idle" || s === "funding" || s === "ready";

const isRacingOrFinished = (s: ChainRaceStatus) =>
s === "racing" || s === "finished";
const isInitialState = (s: ChainRaceStatus) =>
s === "idle" || s === "funding" || s === "ready";

// For transitions to racing or finished, update immediately
if (isRacingOrFinished(status)) {
setStableStatus(status);
}
}
// For transitions from racing/finished to other states, add a delay
else if (isRacingOrFinished(stableStatus) && !isRacingOrFinished(status)) {
// Only allow transition away from racing/finished if it's a deliberate action (like reset)
Expand All @@ -47,59 +55,86 @@ export default function Home() {
}
// Otherwise ignore the status change - keep showing race UI
// This prevents balance checks from affecting the UI
}
}
// For initial states (idle, funding, ready)
else if (isInitialState(status)) {
setStableStatus(status);
}
}, [status, stableStatus]);

return (
<div className="min-h-screen bg-gradient-to-b from-background to-accent/30">
<div className="h-full p-4 md:p-8 flex justify-center">
<Card className="h-full overflow-x-hidden p-4 md:p-7 w-full max-w-6xl shadow-xl border border-accent/50 rounded-xl">
<ChainRace />
<ChainRace />
<div className="w-full">
<div className="grid gap-8">
{/* Chain Derby Visualization (shown when racing or finished) */}
{(stableStatus === "racing" || stableStatus === "finished") && (
<LeaderboardPanel />
)}

<div className="grid md:grid-cols-2 gap-6">
{/* Wallet Information */}
<EmbeddedWallet />
{/* Race Controller */}
<FundingPhase />
</div>

<div className="flex justify-between items-center text-sm text-muted-foreground">
<div className="flex items-center gap-3">
<DisclaimersButton />
<Button
variant="outline"
size="sm"
asChild
className="flex items-center gap-2"
>
<a
href="https://github.com/SmoothBot/chain-derby"
target="_blank"
rel="noopener noreferrer"
<div className="grid gap-8">
{/* Chain Derby Visualization (shown when racing or finished) */}
{(stableStatus === "racing" || stableStatus === "finished") && (
<LeaderboardPanel />
)}

<div className="grid md:grid-cols-2 gap-6">
{/* Wallet Information */}
<EmbeddedWallet />
{/* Race Controller */}
<FundingPhase />
</div>

<div className="flex justify-between items-center text-sm text-muted-foreground">
<div className="flex items-center gap-3">
<DisclaimersButton />
<Button
variant="outline"
size="sm"
asChild
className="flex items-center gap-2"
>
<a
href="https://github.com/SmoothBot/chain-derby"
target="_blank"
rel="noopener noreferrer"
>
<svg
className="h-4 w-4"
fill="currentColor"
viewBox="0 0 24 24"
>
<path d="M12 0c-6.626 0-12 5.373-12 12 0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23.957-.266 1.983-.399 3.003-.404 1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576 4.765-1.589 8.199-6.086 8.199-11.386 0-6.627-5.373-12-12-12z" />
</svg>
Contribute
</a>
</Button>
<Button
variant="outline"
size="sm"
asChild
className="flex items-center gap-2"
>
<svg className="h-4 w-4" fill="currentColor" viewBox="0 0 24 24">
<path d="M12 0c-6.626 0-12 5.373-12 12 0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23.957-.266 1.983-.399 3.003-.404 1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576 4.765-1.589 8.199-6.086 8.199-11.386 0-6.627-5.373-12-12-12z"/>
</svg>
Contribute
</a>
</Button>
<a
href="https://x.com/ChainDerby"
target="_blank"
rel="noopener noreferrer"
>
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
fill="currentColor"
viewBox="0 0 24 24"
>
<path d="M4.25 3h5.4l4.08 5.76L18.8 3h.95l-4.68 6.2L20.75 21h-5.4l-4.18-5.9L5.3 21h-.95l4.88-6.43L3.25 3h1ZM6.03 3.74l6.52 9.23 1.33 1.88 4.1 5.83h2.26L14.6 13.5l-.98-1.37-4.5-6.42-1.8-2.57H6.03Zm11.94 16.52L11.1 10.9 9.77 9.02 5.3 3.74h-2.3l6.24 8.3 1.05 1.44 4.6 6.3 1.73 2.48h2.3Z" />
</svg>
Follow Us
</a>
</Button>
</div>
<DarkModeToggle />
</div>
<DarkModeToggle />
</div>
</div>
</div>
</Card>
</div>
</div>
);
}
}