@@ -140,13 +140,16 @@ const App: React.FC = () => {
140140 if ( prev . status !== AuctionStatus . RUNNING ) return prev ;
141141 const newPrice = prev . currentPrice - config . decrementAmount ;
142142
143- if ( newPrice < config . floorPrice ) {
143+ if ( newPrice <= config . floorPrice ) {
144+ const terminalPrice = config . floorPrice ;
144145 soundService . playEnd ( ) ;
146+ showInfo ( 'Floor reached — no deal.' ) ;
145147 return {
146148 ...prev ,
149+ currentPrice : terminalPrice ,
147150 status : AuctionStatus . ENDED ,
148151 winner : null ,
149- history : [ ...prev . history , { price : prev . currentPrice , timestamp : new Date ( ) , event : 'PAUSE ' , details : 'Floor Reached' } ] ,
152+ history : [ ...prev . history , { price : terminalPrice , timestamp : new Date ( ) , event : 'NO_DEAL ' , details : 'Floor Reached' } ] ,
150153 } ;
151154 }
152155
@@ -354,7 +357,11 @@ const App: React.FC = () => {
354357 if ( ! Number . isFinite ( parsed ) ) {
355358 throw new Error ( `${ label } must be a valid number.` ) ;
356359 }
357- return Math . max ( min , Math . floor ( parsed ) ) ;
360+ const normalized = Math . floor ( parsed ) ;
361+ if ( normalized < min ) {
362+ throw new Error ( `${ label } must be at least ${ min } .` ) ;
363+ }
364+ return normalized ;
358365 } ;
359366
360367 let nextConfig : AuctionConfig ;
@@ -382,7 +389,12 @@ const App: React.FC = () => {
382389 . filter ( Boolean )
383390 . map ( ( name , idx ) => ( { id : String ( idx + 1 ) , name, color : founders [ idx ] ?. color ?? 'bg-cyan-500' } ) ) ;
384391
385- const nextFounders = buildParticipants ( nextConfig . participantCount , parsedNames . length > 0 ? parsedNames : founders ) ;
392+ if ( parsedNames . length !== nextConfig . participantCount ) {
393+ showError ( `Please provide exactly ${ nextConfig . participantCount } participant initials.` ) ;
394+ return ;
395+ }
396+
397+ const nextFounders = buildParticipants ( nextConfig . participantCount , parsedNames ) ;
386398
387399 setConfig ( nextConfig ) ;
388400 setFounders ( nextFounders ) ;
@@ -618,13 +630,25 @@ const App: React.FC = () => {
618630 < div className = "flex-none mb-2 border-b border-slate-800 pb-2" >
619631 < h3 className = "text-[10px] md:text-xs font-bold text-slate-500 uppercase tracking-widest mb-1 md:mb-3" > History</ h3 >
620632 < div className = "flex gap-1.5 md:gap-2 overflow-x-auto pb-1 mask-linear scrollbar-hide" >
621- { gameState . history . slice ( ) . reverse ( ) . map ( ( log , idx ) => < div key = { idx } className = "flex-shrink-0 px-2 py-1 rounded bg-slate-900 border border-slate-800 text-xs md:text-sm font-mono whitespace-nowrap" > < span className = { log . event === 'WIN' ? 'text-green-400' : ' text-slate-300'} > ${ log . price . toLocaleString ( ) } </ span > < span className = "mx-1 opacity-20" > |</ span > < span className = "opacity-75" > { log . event === 'WIN' ? log . details : log . event } </ span > </ div > ) }
633+ { gameState . history . slice ( ) . reverse ( ) . map ( ( log , idx ) => < div key = { idx } className = "flex-shrink-0 px-2 py-1 rounded bg-slate-900 border border-slate-800 text-xs md:text-sm font-mono whitespace-nowrap" > < span className = { log . event === 'WIN' ? 'text-green-400' : log . event === 'NO_DEAL' ? ' text-amber-300' : 'text- slate-300'} > ${ log . price . toLocaleString ( ) } </ span > < span className = "mx-1 opacity-20" > |</ span > < span className = "opacity-75" > { log . event === 'WIN' ? log . details : log . event === 'NO_DEAL' ? 'NO DEAL' : log . event } </ span > </ div > ) }
622634 </ div >
623635 </ div >
624636
625637 < div className = "flex-1 flex flex-col justify-center items-center min-h-0" >
626638 < div className = "w-full max-w-4xl flex flex-col items-center" >
627639 < Ticker price = { gameState . currentPrice } status = { gameState . status } nextDropTime = { gameState . nextDropTime } dropIntervalMs = { config . dropIntervalMs } />
640+
641+ { gameState . status === AuctionStatus . ENDED && gameState . winner && (
642+ < div className = "mt-4 px-4 py-2 rounded-xl border border-emerald-400/40 bg-emerald-500/10 text-emerald-200 text-sm md:text-base font-semibold text-center" >
643+ SOLD — ${ gameState . currentPrice . toLocaleString ( ) } to { gameState . winner . name }
644+ </ div >
645+ ) }
646+
647+ { gameState . status === AuctionStatus . ENDED && ! gameState . winner && (
648+ < div className = "mt-4 px-4 py-2 rounded-xl border border-amber-400/40 bg-amber-500/10 text-amber-200 text-sm md:text-base font-semibold text-center" >
649+ FLOOR REACHED — NO DEAL
650+ </ div >
651+ ) }
628652 </ div >
629653 </ div >
630654 </ div >
0 commit comments