/** * Calcutta lifecycle state derivation and predicates. * * Maps the two server fields (status + auction_status) into one of five * user-facing lifecycle states so the UI can branch cleanly. */ export type CalcuttaLifecycleState = | 'pending' | 'scheduled' | 'auctioning' | 'tournament' | 'completed'; /** * Derive the lifecycle state from competition.status and competition.auction_status. * * Sweepstakes competitions skip the auctioning phase entirely: * pending → scheduled → tournament → completed * * @param auction_type - Optional. When 'sweepstakes', the auctioning state is never returned. */ export function deriveLifecycleState( status?: string, auction_status?: string, auction_type?: string, ): CalcuttaLifecycleState { // ── Sweepstakes: no auction phase ── if (auction_type === 'sweepstakes') { if (!status || status === 'pending') return 'pending'; if (status === 'scheduled') return 'scheduled'; if (status === 'closed') return 'completed'; // auction_closed, inprogress → tournament return 'tournament'; } // ── Hard gate: server confirmed auction closed ── if (auction_status === 'closed') { return status === 'closed' ? 'completed' : 'tournament'; } if (!status) { // No status but auction is in_progress — must be auctioning if (auction_status === 'in_progress') return 'auctioning'; return 'pending'; } switch (status) { case 'pending': return 'pending'; case 'scheduled': return 'scheduled'; case 'auction_open': return auction_status === 'in_progress' ? 'auctioning' : 'scheduled'; case 'auction_closed': case 'inprogress': return 'tournament'; case 'closed': return 'completed'; default: // Unknown status — fall back to auction_status if (auction_status === 'in_progress') return 'auctioning'; return 'pending'; } } /** True when users can place / update / cancel bids */ export const canBid = (state: CalcuttaLifecycleState, auction_type?: string): boolean => auction_type === 'sweepstakes' ? false : state === 'auctioning'; /** True when escrow deposit / withdraw controls should be interactive */ export const canManageEscrow = (state: CalcuttaLifecycleState, auction_type?: string): boolean => auction_type === 'sweepstakes' ? false : (state === 'scheduled' || state === 'auctioning'); /** True when round results / leaderboard data is meaningful */ export const showResults = (state: CalcuttaLifecycleState): boolean => state === 'tournament' || state === 'completed';