Skip to content

Commit ba5d241

Browse files
feat: UI/UX improvements
1 parent 1408e7d commit ba5d241

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+1071
-566
lines changed

app/layout.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@ import './globals.css';
1010
export const metadata: Metadata = {
1111
title: 'Hathor Dice - Provably Fair Betting',
1212
description: 'Decentralized dice game on Hathor Network',
13+
icons: {
14+
icon: '/images/icon.png',
15+
},
1316
};
1417

1518
export default function RootLayout({

app/page.tsx

Lines changed: 123 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import { useState, useEffect } from 'react';
44
import { useWallet } from '@/contexts/WalletContext';
55
import { useHathor } from '@/contexts/HathorContext';
6+
import { useUnifiedWallet } from '@/contexts/UnifiedWalletContext';
67
import Header from '@/components/Header';
78
import BalanceCard from '@/components/BalanceCard';
89
import RecentBetsTable from '@/components/RecentBetsTable';
@@ -17,13 +18,16 @@ import { ContractInfoCompact } from '@/components/ContractInfoCompact';
1718
import { NetworkSelector } from '@/components/NetworkSelector';
1819
import { UIModeSwitcher, type UIMode } from '@/components/UIModeSwitcher';
1920
import HelpIcon from '@/components/HelpIcon';
20-
import { formatBalance } from '@/lib/utils';
21+
import { WalletConnectionModal } from '@/components/WalletConnectionModal';
22+
import { IntroVideo } from '@/components/IntroVideo';
23+
import { formatBalance, formatBalanceWithCommas, formatAddress } from '@/lib/utils';
2124
import { toast } from '@/lib/toast';
2225
import { APP_VERSION } from '@/lib/version';
2326

2427
export default function Home() {
25-
const { connected, balance, address, claimBalance, refreshBalance, contractBalance, setContractBalance } = useWallet();
26-
const { network, getContractStateForToken, getContractIdForToken, switchNetwork, isConnected, coreAPI } = useHathor();
28+
const { connected, balance, address, claimBalance, refreshBalance, contractBalance, setContractBalance, balanceVerified, isLoadingBalance } = useWallet();
29+
const { network, getContractStateForToken, getContractIdForToken, switchNetwork, isConnected, coreAPI, disconnectWallet } = useHathor();
30+
const { walletType } = useUnifiedWallet();
2731
const [selectedToken, setSelectedToken] = useState('HTR');
2832
const [expandedCard, setExpandedCard] = useState<string | null>('placeBet');
2933
const [isLoadingClaimable, setIsLoadingClaimable] = useState(false);
@@ -33,7 +37,10 @@ export default function Home() {
3337
const [isRefreshingContract, setIsRefreshingContract] = useState(false);
3438
const [showWithdrawModal, setShowWithdrawModal] = useState(false);
3539
const [withdrawAmount, setWithdrawAmount] = useState('');
36-
const [uiMode, setUIMode] = useState<UIMode>('classic');
40+
const [uiMode, setUIMode] = useState<UIMode>('fortune-tiger');
41+
const [showWalletModal, setShowWalletModal] = useState(false);
42+
const [showDisconnectMenu, setShowDisconnectMenu] = useState(false);
43+
const [showIntro, setShowIntro] = useState(true);
3744

3845
// Load UI mode preference from localStorage
3946
useEffect(() => {
@@ -178,10 +185,76 @@ export default function Home() {
178185

179186
// If in Fortune Tiger mode, render full-screen slot machine
180187
if (uiMode === 'fortune-tiger') {
188+
const totalBalance = BigInt(balance) + BigInt(contractBalance);
189+
const formattedBalance = isConnected && balanceVerified && totalBalance > 0n
190+
? `${formatBalanceWithCommas(totalBalance)} ${selectedToken}`
191+
: undefined;
192+
181193
return (
182194
<div className="relative">
195+
{/* Intro Video */}
196+
{showIntro && (
197+
<IntroVideo onComplete={() => setShowIntro(false)} />
198+
)}
199+
{/* Wallet Controls - Top Right */}
200+
<div className="fixed top-4 right-4 z-40 flex items-center gap-3">
201+
<NetworkSelector
202+
value={network}
203+
onChange={switchNetwork}
204+
disabled={isConnected}
205+
/>
206+
{isConnected ? (
207+
<div className="relative">
208+
<button
209+
onClick={() => setShowDisconnectMenu(!showDisconnectMenu)}
210+
className="flex items-center gap-2 px-4 py-2 bg-slate-800 rounded-lg border border-slate-700 hover:bg-slate-700 transition-colors"
211+
>
212+
<span className="w-2 h-2 bg-green-500 rounded-full"></span>
213+
<span className="text-sm text-slate-300">{formatAddress(address || '')}</span>
214+
</button>
215+
{showDisconnectMenu && (
216+
<>
217+
<div className="fixed inset-0 z-40" onClick={() => setShowDisconnectMenu(false)} />
218+
<div className="absolute top-full mt-2 right-0 z-50">
219+
<button
220+
onClick={() => {
221+
disconnectWallet();
222+
setShowDisconnectMenu(false);
223+
}}
224+
className="px-4 py-2 bg-slate-700 hover:bg-slate-600 text-white rounded-lg transition-colors whitespace-nowrap"
225+
>
226+
Disconnect
227+
</button>
228+
</div>
229+
</>
230+
)}
231+
</div>
232+
) : (
233+
<button
234+
onClick={() => setShowWalletModal(true)}
235+
className="px-6 py-2 rounded-lg font-bold bg-gradient-to-b from-yellow-400 via-yellow-500 to-yellow-600 text-yellow-900 hover:brightness-110 transition-all"
236+
>
237+
Connect Wallet
238+
</button>
239+
)}
240+
</div>
241+
183242
<FortuneTigerBetCard selectedToken={selectedToken} />
184-
<UIModeSwitcher currentMode={uiMode} onModeChange={handleModeChange} />
243+
<UIModeSwitcher
244+
currentMode={uiMode}
245+
onModeChange={handleModeChange}
246+
balance={formattedBalance}
247+
onGetBalance={refreshBalance}
248+
isConnected={isConnected}
249+
isLoadingBalance={isLoadingBalance}
250+
walletType={walletType}
251+
/>
252+
253+
{/* Wallet Connection Modal */}
254+
<WalletConnectionModal
255+
open={showWalletModal}
256+
onOpenChange={setShowWalletModal}
257+
/>
185258
</div>
186259
);
187260
}
@@ -191,11 +264,6 @@ export default function Home() {
191264
<Header />
192265

193266
<main className="container mx-auto px-6 py-8">
194-
<div className="mb-6 flex justify-between items-center">
195-
<h1 className="text-2xl font-bold text-white">HathorDice DApp</h1>
196-
<NetworkSelector value={network} onChange={switchNetwork} disabled={isConnected} />
197-
</div>
198-
199267
<div className="grid grid-cols-1 lg:grid-cols-3 gap-6">
200268
<div className="lg:col-span-2 space-y-6">
201269
{connected && <BalanceCard selectedToken={selectedToken} />}
@@ -208,7 +276,7 @@ export default function Home() {
208276
{/* Place Bet - Right Panel */}
209277
<div className="bg-slate-800 rounded-xl border border-slate-700 p-6">
210278
<div className="flex items-center justify-between mb-4">
211-
<h2 className="text-lg font-bold text-white">🎲 PLACE BET</h2>
279+
<h2 className="text-lg font-bold text-white">PLACE BET</h2>
212280
<TokenSelector selectedToken={selectedToken} onTokenChange={setSelectedToken} />
213281
</div>
214282

@@ -219,68 +287,55 @@ export default function Home() {
219287
Wallet Balance:
220288
<HelpIcon text="Your wallet's token balance. This is stored in your personal wallet and can be used for betting or adding liquidity." />
221289
</span>
222-
<div className="flex items-center gap-2">
290+
{balanceVerified && balance > 0n ? (
223291
<span className="text-white font-bold">
224-
{balance > 0n ? (
225-
`${formatBalance(balance)} ${selectedToken}`
226-
) : (
227-
<span className="text-slate-400 text-xs">Authorize to view balance</span>
228-
)}
292+
{formatBalanceWithCommas(balance)} {selectedToken}
229293
</span>
294+
) : isLoadingBalance ? (
295+
<span className="text-slate-400 text-xs">Authorize to view balance</span>
296+
) : isConnected ? (
230297
<button
231-
onClick={handleRefreshWalletBalance}
232-
disabled={isRefreshingWallet}
233-
className="px-2 py-1 bg-slate-600 hover:bg-slate-500 disabled:bg-slate-700 disabled:cursor-not-allowed text-white text-xs font-medium rounded transition-colors"
234-
title="Refresh wallet balance"
298+
onClick={() => {
299+
// Only show confirmation toast for WalletConnect (not MetaMask Snap)
300+
if (walletType !== 'metamask') {
301+
toast.info('⏳ Please confirm the operation in your wallet...');
302+
}
303+
refreshBalance();
304+
}}
305+
className="px-3 py-1 font-medium rounded transition-colors hover:opacity-90"
306+
style={{ background: 'linear-gradient(244deg, rgb(255, 166, 0) 0%, rgb(255, 115, 0) 100%)', color: '#1e293b' }}
235307
>
236-
{isRefreshingWallet ? '⏳' : '🔄'}
308+
Load Balance
237309
</button>
238-
</div>
310+
) : (
311+
<span className="text-slate-400 text-xs">Connect wallet first</span>
312+
)}
239313
</div>
240-
<div className="flex items-center justify-between border-t border-slate-600 pt-3">
241-
<span className="text-slate-300 text-sm font-medium flex items-center gap-1">
242-
Contract Balance:
243-
<HelpIcon text="Your claimable balance held in the contract from previous bet winnings. Can be used for betting, or withdrawn to your wallet." />
244-
</span>
245-
<div className="flex items-center gap-2">
246-
{isLoadingClaimable || isRefreshingContract ? (
247-
<span className="text-slate-400 text-xs">Loading...</span>
248-
) : claimableError ? (
249-
<>
250-
<span className="text-red-400 text-xs">{claimableError}</span>
251-
<button
252-
onClick={handleRefreshContractBalance}
253-
className="px-2 py-1 bg-slate-600 hover:bg-slate-500 text-white text-xs font-medium rounded transition-colors"
254-
title="Refresh contract balance"
255-
>
256-
🔄
257-
</button>
258-
</>
259-
) : (
260-
<>
314+
<div className="border-t border-slate-600 pt-3">
315+
<div className="flex items-center justify-between mb-3">
316+
<span className="text-slate-300 text-sm font-medium flex items-center gap-1">
317+
Contract Balance:
318+
<HelpIcon text="Your claimable balance held in the contract from previous bet winnings. Can be used for betting, or withdrawn to your wallet." />
319+
</span>
320+
<div className="flex items-center gap-2">
321+
{claimableError ? (
322+
<span className="text-red-400 text-xs">{claimableError}</span>
323+
) : (
261324
<span className="text-green-400 font-bold">
262-
{formatBalance(contractBalance)} {selectedToken}
325+
{formatBalanceWithCommas(contractBalance)} {selectedToken}
263326
</span>
264-
<button
265-
onClick={handleRefreshContractBalance}
266-
disabled={isRefreshingContract}
267-
className="px-2 py-1 bg-slate-600 hover:bg-slate-500 disabled:bg-slate-700 disabled:cursor-not-allowed text-white text-xs font-medium rounded transition-colors"
268-
title="Refresh contract balance"
269-
>
270-
🔄
271-
</button>
272-
{contractBalance > 0n && (
273-
<button
274-
onClick={handleWithdrawClick}
275-
disabled={isClaiming}
276-
className="px-2 py-1 bg-green-600 hover:bg-green-700 disabled:bg-slate-600 disabled:cursor-not-allowed text-white text-xs font-medium rounded transition-colors"
277-
>
278-
💸 Withdraw
279-
</button>
280-
)}
281-
</>
282-
)}
327+
)}
328+
</div>
283329
</div>
330+
{contractBalance > 0n && !claimableError && (
331+
<button
332+
onClick={handleWithdrawClick}
333+
disabled={isClaiming}
334+
className="w-full px-4 py-2 bg-green-600 hover:bg-green-700 disabled:bg-slate-600 disabled:cursor-not-allowed text-white text-sm font-medium rounded transition-colors"
335+
>
336+
Withdraw
337+
</button>
338+
)}
284339
</div>
285340
</div>
286341
)}
@@ -294,7 +349,7 @@ export default function Home() {
294349

295350
<div className="bg-slate-800 rounded-xl border border-slate-700 p-6">
296351
<div className="flex items-center justify-between mb-6">
297-
<h2 className="text-lg font-bold text-white">📊 INFO & LIQUIDITY</h2>
352+
<h2 className="text-lg font-bold text-white">INFO & LIQUIDITY</h2>
298353
</div>
299354

300355
<ContractInfoCompact contractState={contractState} token={selectedToken} />
@@ -312,10 +367,6 @@ export default function Home() {
312367
/>
313368
</div>
314369
</div>
315-
316-
<footer className="text-center text-sm text-slate-400 py-4 border-t border-slate-700">
317-
Built on Hathor Network • Powered by Nano Contracts
318-
</footer>
319370
</div>
320371
</div>
321372
</main>
@@ -382,8 +433,9 @@ export default function Home() {
382433
)}
383434

384435
{/* Version Footer */}
385-
<footer className="mt-8 text-center text-slate-500 text-sm">
386-
<p>HathorDice {APP_VERSION}</p>
436+
<footer className="mt-8 text-center text-sm pb-6">
437+
<p className="text-slate-400 mb-2">Built on Hathor Network • Powered by Nano Contracts</p>
438+
<p className="text-slate-500">HathorDice {APP_VERSION}</p>
387439
</footer>
388440

389441
{/* UI Mode Switcher - Only show in classic mode */}

components/AddLiquidityCard.tsx

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ export default function AddLiquidityCard({ selectedToken, isExpanded, onToggle }
6363
}
6464
};
6565

66-
const houseEdgeBasisPoints = contractState?.house_edge_basis_points || 200;
66+
const houseEdgeBasisPoints = contractState?.house_edge_basis_points || 190;
6767
const houseEdgePercent = (houseEdgeBasisPoints / 100).toFixed(2);
6868

6969
return (
@@ -73,7 +73,7 @@ export default function AddLiquidityCard({ selectedToken, isExpanded, onToggle }
7373
className="w-full px-6 py-4 flex items-center justify-between hover:bg-slate-700/50 transition-colors"
7474
>
7575
<span className="text-white font-medium flex items-center gap-2">
76-
💧 ADD LIQUIDITY
76+
ADD LIQUIDITY
7777
<HelpIcon text="Provide liquidity to the pool and earn a share of the house edge from all bets. Your liquidity helps pay out winners and you share in the profits when players lose." />
7878
</span>
7979
<span className={`transform transition-transform ${isExpanded ? 'rotate-180' : ''}`}></span>
@@ -102,17 +102,17 @@ export default function AddLiquidityCard({ selectedToken, isExpanded, onToggle }
102102
</div>
103103
</div>
104104

105-
<div className="flex items-center gap-2 text-sm text-slate-400">
106-
<span>ℹ️</span>
105+
<div className="text-sm text-slate-400">
107106
<span>Earn fees from house edge ({houseEdgePercent}%)</span>
108107
</div>
109108

110109
<button
111110
onClick={handleAddLiquidity}
112111
disabled={!isConnected || isAddingLiquidity || amount <= 0}
113-
className="w-full py-3 bg-blue-600 hover:bg-blue-700 disabled:bg-slate-600 disabled:cursor-not-allowed text-white font-medium rounded-lg transition-colors"
112+
className="w-full py-3 disabled:bg-slate-600 disabled:cursor-not-allowed font-medium rounded-lg transition-colors hover:opacity-90"
113+
style={!isConnected || isAddingLiquidity || amount <= 0 ? { color: 'white' } : { background: 'linear-gradient(244deg, rgb(255, 166, 0) 0%, rgb(255, 115, 0) 100%)', color: '#1e293b' }}
114114
>
115-
{isAddingLiquidity ? 'Adding Liquidity...' : '💧 Add Liquidity'}
115+
{isAddingLiquidity ? 'Adding Liquidity...' : 'Add Liquidity'}
116116
</button>
117117
</div>
118118
)}

components/BalanceCard.tsx

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
'use client';
22

33
import { useWallet } from '@/contexts/WalletContext';
4-
import { formatNumber } from '@/lib/utils';
4+
import { formatBalanceWithCommas } from '@/lib/utils';
55

66
interface BalanceCardProps {
77
selectedToken: string;
@@ -14,31 +14,31 @@ export default function BalanceCard({ selectedToken }: BalanceCardProps) {
1414

1515
return (
1616
<div className="bg-gradient-to-br from-slate-800 to-slate-900 rounded-xl p-6 border border-slate-700 mb-6">
17-
<div className="text-lg font-bold text-white mb-4 flex items-center gap-2">
18-
💰 YOUR BALANCE
17+
<div className="text-lg font-bold text-white mb-4">
18+
YOUR BALANCE
1919
</div>
20-
20+
2121
<div className="space-y-3">
2222
<div className="flex justify-between items-center">
2323
<span className="text-slate-400">Wallet Balance:</span>
2424
<span className="text-white font-medium">
25-
{formatNumber(walletBalance)} {selectedToken}
25+
{formatBalanceWithCommas(walletBalance)} {selectedToken}
2626
</span>
2727
</div>
28-
28+
2929
<div className="flex justify-between items-center">
3030
<span className="text-slate-400">Contract Balance:</span>
3131
<span className="text-white font-medium">
32-
{formatNumber(contractBalanceInTokens)} {selectedToken}
32+
{formatBalanceWithCommas(contractBalanceInTokens)} {selectedToken}
3333
</span>
3434
</div>
35-
35+
3636
<div className="h-px bg-slate-700 my-2"></div>
37-
37+
3838
<div className="flex justify-between items-center">
3939
<span className="text-slate-400">Available to Bet:</span>
4040
<span className="text-green-400 font-bold text-lg">
41-
{formatNumber(totalBalance)} {selectedToken}
41+
{formatBalanceWithCommas(totalBalance)} {selectedToken}
4242
</span>
4343
</div>
4444
</div>

0 commit comments

Comments
 (0)