Skip to content

Commit 6f37ffc

Browse files
fix(ux): add setup validation, room code feedback, and remote join usability improvements
1 parent 3cdf6b4 commit 6f37ffc

1 file changed

Lines changed: 32 additions & 4 deletions

File tree

App.tsx

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,11 @@ const App: React.FC = () => {
226226
participantCount: Math.max(1, Math.floor(draftConfig.participantCount)),
227227
};
228228

229+
if (nextConfig.floorPrice >= nextConfig.startPrice) {
230+
showError('Floor price must be less than start price.');
231+
return;
232+
}
233+
229234
const parsedNames = draftInitials
230235
.split(',')
231236
.map((n) => n.trim().toUpperCase())
@@ -266,7 +271,7 @@ const App: React.FC = () => {
266271
</div>
267272

268273
<div className="flex items-center gap-2 md:gap-4">
269-
<button disabled={isRemote && !isHost} onClick={() => { setDraftConfig(config); setDraftInitials(founders.map((f) => f.name).join(', ')); setSetupOpen(true); }} className="text-[9px] md:text-[10px] uppercase font-bold text-slate-500 hover:text-amber-300 disabled:opacity-40 disabled:cursor-not-allowed transition-colors">
274+
<button disabled={(isRemote && isConnected) || gameState.status === AuctionStatus.RUNNING || (isRemote && !isHost)} onClick={() => { setDraftConfig(config); setDraftInitials(founders.map((f) => f.name).join(', ')); setSetupOpen(true); }} className="text-[9px] md:text-[10px] uppercase font-bold text-slate-500 hover:text-amber-300 disabled:opacity-40 disabled:cursor-not-allowed transition-colors">
270275
Setup
271276
</button>
272277
{!isRemote ? (
@@ -278,10 +283,27 @@ const App: React.FC = () => {
278283
{!isConnected ? (
279284
<div className="flex gap-1">
280285
<input type="text" placeholder="Room" className="bg-slate-800 border border-slate-700 rounded px-2 py-1 text-[10px] w-16 md:w-24 outline-none focus:border-cyan-500" value={roomCode} onChange={(e) => setRoomCode(e.target.value)} />
281-
<button onClick={async () => { if (!roomCode) return; await syncService.joinRoom(roomCode, handleRemoteEvent); setIsConnected(true); setIsHost(syncService.isHost()); setClaimedIds(await syncService.listClaimedParticipants()); }} className="bg-cyan-600 px-2 py-1 rounded text-[10px] font-bold">JOIN</button>
286+
<button onClick={async () => { if (!roomCode.trim()) { showError('Please enter a room code.'); return; } await syncService.joinRoom(roomCode, handleRemoteEvent); setIsConnected(true); setIsHost(syncService.isHost()); setClaimedIds(await syncService.listClaimedParticipants()); }} className="bg-cyan-600 px-2 py-1 rounded text-[10px] font-bold">JOIN</button>
282287
</div>
283288
) : (
284-
<button onClick={() => { syncService.leaveRoom(); setIsConnected(false); setIsHost(false); setClaimedIds(new Set()); setIsRemote(false); setMyFounderId(null); }} className="text-[9px] md:text-[10px] text-red-500 uppercase font-bold">Disconnect</button>
289+
<div className="flex items-center gap-2">
290+
<span className="text-[9px] md:text-[10px] text-cyan-300 font-mono uppercase">Room: {roomCode}</span>
291+
<button
292+
onClick={async () => {
293+
try {
294+
await navigator.clipboard.writeText(roomCode);
295+
setToast('Room code copied.');
296+
window.setTimeout(() => setToast(null), 1800);
297+
} catch {
298+
showError('Could not copy room code.');
299+
}
300+
}}
301+
className="text-[9px] md:text-[10px] text-cyan-400 uppercase font-bold"
302+
>
303+
Copy
304+
</button>
305+
<button onClick={() => { syncService.leaveRoom(); setIsConnected(false); setIsHost(false); setClaimedIds(new Set()); setIsRemote(false); setMyFounderId(null); }} className="text-[9px] md:text-[10px] text-red-500 uppercase font-bold">Disconnect</button>
306+
</div>
285307
)}
286308
</div>
287309
)}
@@ -369,7 +391,13 @@ const App: React.FC = () => {
369391
<div className="absolute inset-0 bg-slate-950/95 z-[100] flex items-center justify-center backdrop-blur-md p-4 animate-in fade-in duration-300">
370392
<div className="bg-slate-900 border border-slate-800 p-6 md:p-8 rounded-2xl max-w-sm w-full text-center shadow-2xl">
371393
<h2 className="text-lg md:text-xl font-bold mb-1 font-display text-white">WHO ARE YOU?</h2>
372-
<p className="text-slate-500 text-[10px] md:text-sm mb-6 uppercase tracking-widest font-mono">Select your identity for this room</p>
394+
<p className="text-slate-500 text-[10px] md:text-sm mb-4 uppercase tracking-widest font-mono">Select your identity for this room</p>
395+
<button
396+
onClick={() => { syncService.leaveRoom(); setIsConnected(false); setIsHost(false); setClaimedIds(new Set()); setIsRemote(false); setMyFounderId(null); }}
397+
className="mb-4 text-[10px] text-slate-400 hover:text-white uppercase font-bold"
398+
>
399+
← Back
400+
</button>
373401
<div className="grid grid-cols-1 gap-3">{founders.map((f) => {
374402
const alreadyClaimed = claimedIds.has(f.id);
375403
return <button key={f.id} disabled={alreadyClaimed} onClick={async () => { const ok = await syncService.claimParticipant(f.id); if (ok) { setMyFounderId(f.id); setClaimedIds(await syncService.listClaimedParticipants()); } else { showError('This participant is already claimed. Choose another.'); } }} className={`p-3 md:p-4 rounded-xl border-2 border-slate-800 transition-all font-bold text-base md:text-lg ${f.color.replace('bg-', 'text-')} ${alreadyClaimed ? 'opacity-40 cursor-not-allowed' : 'hover:border-cyan-500'}`}>

0 commit comments

Comments
 (0)