Skip to content

Commit 917244f

Browse files
committed
optimistic UI update after betting; UI improvements for mobile; remove animal number from the interface; remove duplicated scroll on GameDetailsModal; fix bet card image;
1 parent cf35c5b commit 917244f

4 files changed

Lines changed: 41 additions & 16 deletions

File tree

packages/nextjs/app/jodobix/_components/AnimalSelector.tsx

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ export const AnimalSelector: React.FC<AnimalSelectorProps> = ({
1616
drawnNumber,
1717
}) => {
1818
return (
19-
<div className="grid grid-cols-5 gap-1 md:gap-2 flex-1">
19+
<div className="flex flex-wrap gap-1 md:gap-2 flex-1">
2020
{[...Array(25)].map((_, index) => {
2121
const number = index + 1;
2222
const betAmount = betsPerNumber[index] || 0n;
@@ -40,9 +40,8 @@ export const AnimalSelector: React.FC<AnimalSelectorProps> = ({
4040
/>
4141
</svg>
4242
)}
43-
<div className="flex items-center justify-between w-[86px] -mt-12 h-12 flex-col md:flex-row">
44-
<span className="text-sm text-accent">#{number}</span>
45-
<span className="text-xs text-black">{formatEther(betAmount)} ETH</span>
43+
<div className="w-[86px] -mt-10 h-10 text-sm leading-8 text-end font-bold text-black">
44+
{formatEther(betAmount)} ETH
4645
</div>
4746
</button>
4847
);

packages/nextjs/app/jodobix/_components/BetCard.tsx

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,15 @@ export const BetCard: React.FC<BetCardProps> = ({ betId, drawnNumber }) => {
4141

4242
return (
4343
<div className="flex items-center gap-4">
44-
<div className="relative w-16 h-16">
45-
<Image src={`/animals/${bet?.number}.webp`} alt={`Animal ${bet?.number}`} width={228} height={325} />
44+
<div className="relative w-16 h-[68px] overflow-hidden">
45+
<Image
46+
src={`/animals/${bet?.number}.webp`}
47+
alt={`Animal ${bet?.number}`}
48+
width={228}
49+
height={325}
50+
className="object-contain object-top"
51+
style={{ width: "100%", height: "auto" }}
52+
/>
4653

4754
{won && (
4855
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 86 66" className="h-14 -ml-1 mt-1">
@@ -58,7 +65,6 @@ export const BetCard: React.FC<BetCardProps> = ({ betId, drawnNumber }) => {
5865

5966
<div className="flex flex-col">
6067
<span className="text-sm font-semibold">Bet #{betId.toString()}</span>
61-
<span className="text-sm">Number: #{bet?.number}</span>
6268
<span className="text-sm">{formatEther(bet?.value || 0n)} ETH</span>
6369
</div>
6470

packages/nextjs/app/jodobix/_components/BetForm.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { useDeployedContractInfo, useScaffoldWriteContract } from "~~/hooks/scaf
66
interface BetFormProps {
77
gameId?: bigint;
88
selectedNumber: number | null;
9-
onBetPlaced?: (betId: bigint) => void;
9+
onBetPlaced?: (betId: bigint, gameId: bigint, number: number) => void;
1010
betAmount: string;
1111
setBetAmount: (value: string) => void;
1212
}
@@ -35,7 +35,7 @@ export const BetForm: React.FC<BetFormProps> = ({ gameId, selectedNumber, onBetP
3535

3636
if (betPlacedEvent && "betId" in betPlacedEvent.args) {
3737
const betId = betPlacedEvent.args.betId as bigint;
38-
onBetPlaced?.(betId);
38+
onBetPlaced?.(betId, gameId!, Number(selectedNumber));
3939
}
4040
},
4141
},

packages/nextjs/app/jodobix/_components/GameDetailsModal.tsx

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,10 @@ import { useCloseGame } from "../_hooks/useCloseGame";
55
import { AnimalSelector } from "./AnimalSelector";
66
import { BetCard } from "./BetCard";
77
import { BetForm } from "./BetForm";
8+
import { useQueryClient } from "@tanstack/react-query";
89
import { toast } from "react-hot-toast";
910
import { formatEther, parseEther } from "viem";
10-
import { useAccount } from "wagmi";
11+
import { useAccount, useChainId } from "wagmi";
1112
import { ArrowPathIcon, InformationCircleIcon, ShareIcon } from "@heroicons/react/24/outline";
1213
import { Address } from "~~/components/scaffold-eth";
1314
import { HoverCard, HoverCardContent, HoverCardTrigger } from "~~/components/ui/hover-card";
@@ -24,9 +25,11 @@ export const GameDetailsModal: React.FC<GameDetailsModalProps> = ({ gameId, onCl
2425
const [selectedNumber, setSelectedNumber] = useState<number | null>(null);
2526
const [betAmount, setBetAmount] = useState("");
2627
const { address, connector, chainId } = useAccount();
28+
const queryClient = useQueryClient();
2729
const { data: balance } = useWatchBalance({
2830
address,
2931
});
32+
const defaultChainId = useChainId();
3033

3134
const { data: game, refetch: refetchGame } = useScaffoldReadContract({
3235
contractName: "Jodobix",
@@ -43,7 +46,6 @@ export const GameDetailsModal: React.FC<GameDetailsModalProps> = ({ gameId, onCl
4346

4447
const {
4548
data: myBets,
46-
refetch: refetchMyBets,
4749
isLoading: isLoadingMyBets,
4850
error: errorMyBets,
4951
} = useBetsPlaced({
@@ -100,9 +102,27 @@ export const GameDetailsModal: React.FC<GameDetailsModalProps> = ({ gameId, onCl
100102
setSelectedNumber(number);
101103
};
102104

103-
const handleBetPlaced = (betId: bigint) => {
105+
const handleBetPlaced = (betId: bigint, gameId: bigint, number: number) => {
106+
// Optimistic UI update
107+
queryClient.setQueryData(
108+
["betPlaceds", defaultChainId, gameId?.toString(), undefined, address],
109+
[
110+
...(myBets ?? []),
111+
{
112+
betId: betId.toString(),
113+
gameId: gameId.toString(),
114+
number,
115+
bettor: address,
116+
value: parseEther(betAmount).toString(),
117+
timestamp: Date.now().toString(),
118+
blockNumber: "0",
119+
blockTimestamp: "0",
120+
transactionHash: "0x",
121+
},
122+
],
123+
);
124+
104125
resetBetForm();
105-
refetchMyBets();
106126
onBetPlaced?.(betId);
107127
};
108128

@@ -151,7 +171,7 @@ export const GameDetailsModal: React.FC<GameDetailsModalProps> = ({ gameId, onCl
151171

152172
return (
153173
<div className="modal modal-open">
154-
<div className="modal-box w-11/12 max-w-5xl h-full flex flex-col dark:bg-">
174+
<div className="modal-box w-11/12 max-w-5xl h-full flex flex-col">
155175
<div className="flex justify-between items-center mb-4">
156176
<h3 className="font-bold text-lg">
157177
Game #{gameId.toString()}
@@ -179,15 +199,15 @@ export const GameDetailsModal: React.FC<GameDetailsModalProps> = ({ gameId, onCl
179199
</button>
180200
</div>
181201

182-
<div className="flex gap-8 md:h-[calc(100%-3.3rem)] items-start flex-col md:flex-row">
202+
<div className="flex gap-8 items-start flex-col md:flex-row pb-8">
183203
<AnimalSelector
184204
selectedNumber={selectedNumber}
185205
onSelectNumber={handleSelectNumber}
186206
betsPerNumber={Array.from(game?.betsPerNumber || [])}
187207
drawnNumber={game?.bettingPeriodEnded ? game?.drawnNumber : undefined}
188208
/>
189209

190-
<div className="flex flex-col gap-2 h-full overflow-y-auto overflow-x-hidden self-center">
210+
<div className="flex flex-col gap-2 h-full self-center">
191211
<div>
192212
Total Value: {formatEther(game?.totalValue || 0n)} ETH ({game?.numberOfBets.toString()} bets)
193213
</div>

0 commit comments

Comments
 (0)