From 8aed9b95925c005b989c357419c3ad6d2f8c61d2 Mon Sep 17 00:00:00 2001 From: karthik Date: Sun, 3 Aug 2025 18:35:32 +0530 Subject: [PATCH] fix : having issues with last 3 labels and racenumbers not fetching properly --- .../app/components/navbar/navbar.component.ts | 23 ++++--- .../selection.service/selection.service.ts | 61 +++++++++-------- .../touch-pad-menu.component.ts | 66 ++++++++++++------- btc-UI/src/app/home/home.component.ts | 15 +++-- .../src/app/service/shared-state.service.ts | 14 +++- 5 files changed, 114 insertions(+), 65 deletions(-) diff --git a/btc-UI/src/app/components/navbar/navbar.component.ts b/btc-UI/src/app/components/navbar/navbar.component.ts index 5e0187f..1c6c68e 100755 --- a/btc-UI/src/app/components/navbar/navbar.component.ts +++ b/btc-UI/src/app/components/navbar/navbar.component.ts @@ -24,6 +24,7 @@ export class NavbarComponent implements OnInit, OnDestroy { showRaceModal = false; selectedVenue = 'Select Venue'; selectedRace: number = 1; + currentLegRaceDisplay: string = ''; // Display current leg's race showWalletModal = false; showResultModal = false; @@ -36,6 +37,7 @@ export class NavbarComponent implements OnInit, OnDestroy { selectedRaceId: number = 0; enabledHorseNumbers: number[] = []; + multiLegBaseRaceIdx: number = 0; // Track base race index for multi-leg pools wallet = { withdraw: 0, @@ -64,7 +66,6 @@ export class NavbarComponent implements OnInit, OnDestroy { constructor( private btcService: BtcService, private router: Router, - // private horseService: HorseService, private sharedStateService: SharedStateService ) {} @@ -94,11 +95,19 @@ export class NavbarComponent implements OnInit, OnDestroy { this.raceCardData = JSON.parse(cachedData); console.log('📦 Loaded race card from localStorage:', this.raceCardData); this.selectedVenue = this.raceCardData?.Venue || 'Select Venue'; - this.updateEnabledHorseNumbers(); // Initialize horse numbers + this.updateEnabledHorseNumbers(); } else { this.raceCardData = { raceVenueRaces: { races: [] }, pools: {} }; console.warn('⚠️ No race card data found in localStorage.'); } + + this.sharedStateService.sharedData$.subscribe(data => { + if (data.type === 'currentLegRace') { + this.selectedRace = data.value; + this.currentLegRaceDisplay = `Race ${data.value}`; + this.updateEnabledHorseNumbers(); + } + }); } updateDateTime() { @@ -163,32 +172,30 @@ export class NavbarComponent implements OnInit, OnDestroy { selectRace(race: number) { this.selectedRace = race; + this.multiLegBaseRaceIdx = race; this.sharedStateService.updateSharedData({ type: 'selectedRace', value: this.selectedRace, }); - // Push updated runner count from raceCardData const raceCard = JSON.parse(localStorage.getItem('raceCardData') || '{}'); const raceList = raceCard?.raceVenueRaces?.races || []; - const selectedRaceData = raceList[race - 1] || []; // Adjust for 1-based race number + const selectedRaceData = raceList[race - 1] || []; const runnerCount = selectedRaceData.length || 12; this.sharedStateService.setRunnerCount(runnerCount); - this.updateEnabledHorseNumbers(); // Update local horse numbers + this.updateEnabledHorseNumbers(); console.log('[RACE] Race selected:', this.selectedRace, '| Runner count:', runnerCount); this.closeModals(); } - // ✅ Updated method to use exact horseNumbers updateEnabledHorseNumbers() { const raceIndex = this.selectedRace - 1; const race = this.raceCardData?.raceVenueRaces?.races?.[raceIndex]; if (Array.isArray(race)) { - // Assuming each runner has a "horseNumber" property this.enabledHorseNumbers = race .map((runner: any) => runner?.horseNumber) .filter((n: any) => typeof n === 'number' && n >= 1 && n <= 30); @@ -206,8 +213,6 @@ export class NavbarComponent implements OnInit, OnDestroy { selectHorseNumber(number: number) { console.log('[HORSE] Selected horse number:', number); - // Add logic to pass the selected number to SelectionService - // Example: this.selectionService.updatePartial({ numbers: [...current.numbers, number] }); } openWalletModal() { diff --git a/btc-UI/src/app/components/selection.service/selection.service.ts b/btc-UI/src/app/components/selection.service/selection.service.ts index 0978dd7..71363de 100644 --- a/btc-UI/src/app/components/selection.service/selection.service.ts +++ b/btc-UI/src/app/components/selection.service/selection.service.ts @@ -24,11 +24,17 @@ export class SelectionService { }); currentRow$ = this.currentRow.asObservable(); - private runnerCount: number = 12; // Fallback + private runnerCount: number = 12; + private multiLegBaseRaceIdx: number = 0; constructor(private sharedStateService: SharedStateService) { this.sharedStateService.runnerCount$.subscribe(count => { - this.runnerCount = count || 12; // Update runner count dynamically + this.runnerCount = count || 12; + }); + this.sharedStateService.sharedData$.subscribe(data => { + if (data.type === 'selectedRace') { + this.multiLegBaseRaceIdx = data.value; + } }); } @@ -74,7 +80,6 @@ export class SelectionService { } } } else { - // Keep the latest fallback logic for boxed or F const group1Count = group1.includes('F') ? this.runnerCount : group1.filter(n => typeof n === 'number').length; const group2Count = group2.includes('F') ? this.runnerCount : group2.filter(n => typeof n === 'number').length; combinations = isBoxed @@ -107,7 +112,6 @@ export class SelectionService { } combinations = pairSet.size; } else { - // Keep latest logic for boxed/F const group1Count = group1.includes('F') ? this.runnerCount : group1.filter(n => typeof n === 'number').length; const group2Count = group2.includes('F') ? this.runnerCount : group2.filter(n => typeof n === 'number').length; combinations = isBoxed @@ -145,10 +149,9 @@ export class SelectionService { } } } else { - // Keep fallback logic combinations = isBoxed ? this.calculatePermutationsN(numbers.includes('F') ? this.runnerCount : numbers.filter(n => typeof n === 'number').length, 3) - : this.runnerCount * this.runnerCount * this.runnerCount; // fallback approximation + : this.runnerCount * this.runnerCount * this.runnerCount; } updated.numbers = [...group1, '-', ...group2, '-', ...group3]; @@ -159,19 +162,26 @@ export class SelectionService { case 'TRE': case 'MJP': case 'JKP': { - const legs = this.splitToLegs(numbers, this.getLegCount(label)); - const requiredLegs = this.getLegCount(label); - const legCounts = legs.map(leg => leg.includes('F') ? this.runnerCount : leg.filter(n => typeof n === 'number').length); - const filledLegs = legs.filter(leg => leg.length > 0).length; + const legCount = this.getLegCount(label); + const legs = this.splitToLegs(numbers, legCount); - if (filledLegs >= requiredLegs - 1) { - const combinations = legCounts.reduce((acc, count) => acc * (count || 1), 1); - updated.total = combinations * value * 10; - } + const legCounts = legs.map((leg, idx) => { + let count = 0; + for (const item of leg) { + if (item === 'F') { + count += this.getRunnerCountForLeg(this.multiLegBaseRaceIdx, idx); + } else if (typeof item === 'number') { + count += 1; + } + } + return count; + }); + + const combinations = legCounts.reduce((acc, count) => acc * (count || 1), 1); + updated.total = combinations * value * 10; break; } - // ⚪ BOX logic default: { const combCount = isBoxed ? this.calculatePermutations(numbers.filter(n => typeof n === 'number').length) @@ -220,25 +230,17 @@ export class SelectionService { private splitToLegs(numbers: (number | string)[], legCount: number): (number | string)[][] { const result: (number | string)[][] = []; let currentLeg: (number | string)[] = []; - let separatorCount = 0; for (const item of numbers) { if (item === '/') { - if (currentLeg.length > 0) { - result.push([...currentLeg]); - currentLeg = []; - separatorCount++; - } - if (separatorCount >= legCount - 1) break; + result.push(currentLeg); + currentLeg = []; } else { currentLeg.push(item); } } - - if (currentLeg.length > 0) result.push([...currentLeg]); - + result.push(currentLeg); while (result.length < legCount) result.push([]); - return result.slice(0, legCount); } @@ -250,4 +252,11 @@ export class SelectionService { default: return 3; } } + + private getRunnerCountForLeg(baseIdx: number, leg: number): number { + const raceCardData = JSON.parse(localStorage.getItem('raceCardData') || '{}'); + const raceIdx = Number(baseIdx) - 1 + leg; + const race = raceCardData?.raceVenueRaces?.races?.[raceIdx] || []; + return Array.isArray(race) ? race.length : 12; + } } diff --git a/btc-UI/src/app/components/touch-pad-menu/touch-pad-menu.component.ts b/btc-UI/src/app/components/touch-pad-menu/touch-pad-menu.component.ts index 0ff8f3d..83a8fc8 100755 --- a/btc-UI/src/app/components/touch-pad-menu/touch-pad-menu.component.ts +++ b/btc-UI/src/app/components/touch-pad-menu/touch-pad-menu.component.ts @@ -43,18 +43,20 @@ export class TouchPadMenuComponent implements OnInit, OnDestroy { disabledLabels: string[] = ['SHW', 'SJP', '.']; - // ✅ Original TAN logic + // TAN logic tanGroupStage = 0; tanGroups: (number | string)[][] = [[], [], []]; - // ✅ FOR/QUI logic + // FOR/QUI logic isFirstGroupComplete = false; firstGroup: (number | string)[] = []; secondGroup: (number | string)[] = []; - // ✅ Multi-leg logic (TRE, MJP, JKP) + // Multi-leg logic (TRE, MJP, JKP) multiLegStage = 0; multiLegGroups: (number | string)[][] = [[], [], [], [], []]; + multiLegBaseRaceIdx: number = 0; // Track starting race index + currentLegRaceDisplay: string = ''; // Display current leg's race isBoxed: boolean = false; @@ -83,8 +85,9 @@ export class TouchPadMenuComponent implements OnInit, OnDestroy { ngOnInit() { this.runnerCountSubscription = this.sharedStateService.runnerCount$.subscribe(count => { this.runnerCount = count || 12; - this.numbers = Array.from({ length: 30 }, (_, i) => i + 1); // Always 1 to 30 + this.numbers = Array.from({ length: 30 }, (_, i) => i + 1); this.numbersFlat = this.numberRows.flat(); + this.updateLegRaceDisplay(this.selectedLabel || ''); }); this.labelRowsFlat = this.labelRows.flat(); @@ -131,7 +134,6 @@ export class TouchPadMenuComponent implements OnInit, OnDestroy { get isShashEnterDisabled(): boolean { if (this.selectedLabel === 'TAN') { - // In box mode, shash enter is always disabled if (this.isBoxed) { return true; } @@ -154,13 +156,11 @@ export class TouchPadMenuComponent implements OnInit, OnDestroy { get isBoxToggleDisabled(): boolean { if (!this.selectedLabel) return true; - // Disable box mode for these labels const disallowedBoxLabels = ['WIN', 'SHP', 'THP', 'PLC', 'SHW', 'TRE', 'MJP', 'JKP']; if (disallowedBoxLabels.includes(this.selectedLabel)) { return true; } - // Disable box toggle if FIELD (F) is selected if (this.selectedNumbers.includes('F')) { return true; } @@ -179,7 +179,6 @@ export class TouchPadMenuComponent implements OnInit, OnDestroy { } isNumberDisabled(number: number): boolean { - // Only numbers up to runnerCount are enabled, others are disabled if (number > this.runnerCount) { return true; } @@ -207,6 +206,12 @@ export class TouchPadMenuComponent implements OnInit, OnDestroy { this.canPrint = false; this.isBoxed = false; + // Store base race index for multi-leg pools + if (this.multiLegLabels.includes(label)) { + this.multiLegBaseRaceIdx = this.sharedStateService.getSelectedRace(); + this.updateLegRaceDisplay(label); + } + // Reset TAN this.tanGroupStage = 0; this.tanGroups = [[], [], []]; @@ -226,13 +231,11 @@ export class TouchPadMenuComponent implements OnInit, OnDestroy { selectNumber(number: number) { if (!this.selectedLabel || this.totalAmountLimitReached || number > this.runnerCount) return; - // TAN Box mode: freestyle selection with dash-separated format + // TAN Box mode if (this.selectedLabel === 'TAN' && this.isBoxed) { if (!this.selectedNumbers.includes(number)) { - // Extract current numbers (excluding dashes) const currentNumbers = this.selectedNumbers.filter(n => typeof n === 'number') as number[]; const allBoxed = [...currentNumbers, number]; - // Split into 3 roughly equal groups for display consistency const groupSize = Math.ceil(allBoxed.length / 3); const group1 = allBoxed.slice(0, groupSize); const group2 = allBoxed.slice(group1.length, group1.length + groupSize); @@ -253,7 +256,7 @@ export class TouchPadMenuComponent implements OnInit, OnDestroy { return; } - // Original TAN logic (unboxed) + // TAN unboxed if (this.selectedLabel === 'TAN') { if (!this.tanGroups[this.tanGroupStage].includes(number)) { this.tanGroups[this.tanGroupStage].push(number); @@ -292,7 +295,7 @@ export class TouchPadMenuComponent implements OnInit, OnDestroy { return; } - // Default single-number selection (WIN, SHP, THP, etc.) + // Default single-number selection if (!this.selectedNumbers.includes(number)) { this.selectedNumbers.push(number); this.selectionService.updatePartial({ numbers: [...this.selectedNumbers] }); @@ -307,6 +310,7 @@ export class TouchPadMenuComponent implements OnInit, OnDestroy { } this.selectedNumbers = combined; this.selectionService.updatePartial({ numbers: [...this.selectedNumbers] }); + this.updateLegRaceDisplay(this.selectedLabel || ''); } onPadEnter() { @@ -316,7 +320,6 @@ export class TouchPadMenuComponent implements OnInit, OnDestroy { } onShashEnter() { - // Disable shash enter for TAN Box mode if (this.selectedLabel === 'TAN' && this.isBoxed) { return; } @@ -338,6 +341,7 @@ export class TouchPadMenuComponent implements OnInit, OnDestroy { if (this.multiLegStage < maxLegs - 1) { this.multiLegStage++; this.updateMultiLegSelection(); + this.updateLegRaceDisplay(this.selectedLabel || ''); } return; } @@ -358,7 +362,6 @@ export class TouchPadMenuComponent implements OnInit, OnDestroy { if (key === 'X') { this.padValue = ''; } else if (/[0-9]/.test(key)) { - // Limit ticket number to 1-100 for all labels const currentValue = parseInt(this.padValue + key) || 0; if (currentValue > 100) return; this.padValue += key; @@ -408,6 +411,8 @@ export class TouchPadMenuComponent implements OnInit, OnDestroy { this.secondGroup = []; this.multiLegStage = 0; this.multiLegGroups = [[], [], [], [], []]; + this.multiLegBaseRaceIdx = 0; + this.currentLegRaceDisplay = ''; this.fieldModalOpen = false; this.fieldInput = ''; @@ -418,7 +423,6 @@ export class TouchPadMenuComponent implements OnInit, OnDestroy { if (this.totalAmountLimitReached) return; this.isBoxed = !this.isBoxed; const value = parseFloat(this.padValue) || 0; - // For TAN Box mode, reset to freestyle selection if (this.selectedLabel === 'TAN' && this.isBoxed) { this.tanGroupStage = 0; this.tanGroups = [[], [], []]; @@ -450,7 +454,6 @@ export class TouchPadMenuComponent implements OnInit, OnDestroy { const currentNumbers = this.selectedNumbers.filter(n => typeof n === 'number') as number[]; if (currentNumbers.length > 0) { currentNumbers.pop(); - // Rebuild dash-separated structure const groupSize = Math.ceil(currentNumbers.length / 3); const group1 = currentNumbers.slice(0, groupSize); const group2 = currentNumbers.slice(group1.length, group1.length + groupSize); @@ -471,7 +474,6 @@ export class TouchPadMenuComponent implements OnInit, OnDestroy { return; } - // Original TAN logic (unboxed) if (this.selectedLabel === 'TAN') { const currentGroup = this.tanGroups[this.tanGroupStage]; if (currentGroup.length > 0) { @@ -485,7 +487,6 @@ export class TouchPadMenuComponent implements OnInit, OnDestroy { return; } - // Multi-leg logic if (this.multiLegLabels.includes(this.selectedLabel)) { const currentGroup = this.multiLegGroups[this.multiLegStage]; if (currentGroup.length > 0) { @@ -495,7 +496,6 @@ export class TouchPadMenuComponent implements OnInit, OnDestroy { return; } - // FOR/QUI logic if (this.twoGroupLabels.includes(this.selectedLabel)) { if (!this.isFirstGroupComplete && this.firstGroup.length > 0) { this.firstGroup.pop(); @@ -508,7 +508,6 @@ export class TouchPadMenuComponent implements OnInit, OnDestroy { return; } - // Default single-number removal this.selectedNumbers.pop(); this.selectionService.updatePartial({ numbers: [...this.selectedNumbers] }); } @@ -522,6 +521,28 @@ export class TouchPadMenuComponent implements OnInit, OnDestroy { } } + private updateLegRaceDisplay(label: string) { + if (!this.multiLegLabels.includes(label)) { + this.currentLegRaceDisplay = ''; + return; + } + const raceIdx = this.multiLegBaseRaceIdx + this.multiLegStage; + this.currentLegRaceDisplay = `Leg ${this.multiLegStage + 1} (Race ${raceIdx})`; + const runnerCount = this.getRunnerCountForLeg(this.multiLegBaseRaceIdx, this.multiLegStage); + this.sharedStateService.setRunnerCount(runnerCount); + this.sharedStateService.updateSharedData({ + type: 'currentLegRace', + value: raceIdx + }); + } + + private getRunnerCountForLeg(baseIdx: number, leg: number): number { + const raceCardData = JSON.parse(localStorage.getItem('raceCardData') || '{}'); + const raceIdx = baseIdx - 1 + leg; // 0-based index + const race = raceCardData?.raceVenueRaces?.races?.[raceIdx] || []; + return Array.isArray(race) ? race.length : 12; + } + private handleFieldForSpecialLabels() { if (!this.selectedLabel) return; @@ -706,7 +727,6 @@ export class TouchPadMenuComponent implements OnInit, OnDestroy { this.poolReplaceOpen = false; } - // TRE Popup Methods treButtonClick(btnNum: number) { this.trePopupVisible = false; this._selectTreAfterPopup(); @@ -726,6 +746,8 @@ export class TouchPadMenuComponent implements OnInit, OnDestroy { this.secondGroup = []; this.multiLegStage = 0; this.multiLegGroups = [[], [], [], [], []]; + this.multiLegBaseRaceIdx = this.sharedStateService.getSelectedRace(); + this.updateLegRaceDisplay('TRE'); this.selectionService.updatePartial({ label: 'TRE' }); } diff --git a/btc-UI/src/app/home/home.component.ts b/btc-UI/src/app/home/home.component.ts index d8eea60..c760191 100755 --- a/btc-UI/src/app/home/home.component.ts +++ b/btc-UI/src/app/home/home.component.ts @@ -29,6 +29,7 @@ export class HomeComponent implements OnInit, OnDestroy { private resizeObserver!: () => void; private currentRaceIdx: number = 0; races: any[] = []; + multiLegBaseRaceIdx: number = 0; constructor( private cdr: ChangeDetectorRef, @@ -48,7 +49,6 @@ export class HomeComponent implements OnInit, OnDestroy { console.log('🏠 HomeComponent loaded'); - // ✅ Fetch & push horse race data this.btcService.getAllRaceEventsToday().subscribe({ next: (response: HttpResponse) => { const horseRaceData = response.body; @@ -64,7 +64,6 @@ export class HomeComponent implements OnInit, OnDestroy { }, }); - // ✅ Preload Race Card if not cached const raceCardCached = localStorage.getItem('raceCardData'); if (!raceCardCached) { this.btcService.getRaceCard().subscribe({ @@ -94,8 +93,6 @@ export class HomeComponent implements OnInit, OnDestroy { onTicketingClicked() { this.isTicketingActive = true; - - // 🔁 Push ticketing state to shared screen this.sharedStateService.updateSharedData({ type: 'ticketing', value: true, @@ -104,8 +101,6 @@ export class HomeComponent implements OnInit, OnDestroy { onOtherActionClicked() { this.isTicketingActive = false; - - // 🔁 Push ticketing state to shared screen this.sharedStateService.updateSharedData({ type: 'ticketing', value: false, @@ -114,12 +109,18 @@ export class HomeComponent implements OnInit, OnDestroy { onRaceSelected(raceIdx: number) { this.currentRaceIdx = raceIdx; + this.multiLegBaseRaceIdx = raceIdx; this.updateRunnerCount(raceIdx); + this.sharedStateService.updateSharedData({ + type: 'selectedRace', + value: raceIdx, + }); } private updateRunnerCount(raceIdx: number) { const raceCardData = JSON.parse(localStorage.getItem('raceCardData') || '{}'); - const runnerCount = raceCardData?.raceVenueRaces?.races?.[raceIdx]?.length || 12; + const race = raceCardData?.raceVenueRaces?.races?.[raceIdx] || []; + const runnerCount = Array.isArray(race) ? race.length : 12; if (!raceCardData?.raceVenueRaces?.races?.[raceIdx]) { console.warn('⚠️ Race data not found for index:', raceIdx); } diff --git a/btc-UI/src/app/service/shared-state.service.ts b/btc-UI/src/app/service/shared-state.service.ts index 2bb7988..077aec3 100644 --- a/btc-UI/src/app/service/shared-state.service.ts +++ b/btc-UI/src/app/service/shared-state.service.ts @@ -14,10 +14,12 @@ export class SharedStateService { private sharedDataSubject = new BehaviorSubject({ type: '', value: null }); sharedData$ = this.sharedDataSubject.asObservable(); + private selectedRaceSubject = new BehaviorSubject(1); + selectedRace$ = this.selectedRaceSubject.asObservable(); + private channel = new BroadcastChannel('shared-display-channel'); constructor() { - // Listen to messages from other windows this.channel.onmessage = (event) => { console.log('[BroadcastChannel] Received data:', event.data); if (event.data?.runnerCount !== undefined) { @@ -25,6 +27,9 @@ export class SharedStateService { } if (event.data?.type !== undefined && event.data?.value !== undefined) { this.sharedDataSubject.next({ type: event.data.type, value: event.data.value }); + if (event.data.type === 'selectedRace') { + this.selectedRaceSubject.next(event.data.value); + } } }; } @@ -39,5 +44,12 @@ export class SharedStateService { console.log('[SharedStateService] Broadcasting data:', data); this.channel.postMessage(data); this.sharedDataSubject.next(data); + if (data.type === 'selectedRace') { + this.selectedRaceSubject.next(data.value); + } + } + + getSelectedRace(): number { + return this.selectedRaceSubject.value; } } \ No newline at end of file