From dbe0a0497dd4b9d1e127f40d44e580028c617017 Mon Sep 17 00:00:00 2001 From: karthik Date: Sun, 3 Aug 2025 14:51:06 +0530 Subject: [PATCH] fix : race numbers sync with keypad 1 - 30 --- .../app/components/navbar/navbar.component.ts | 174 ++++++++---------- btc-UI/src/app/home/home.component.ts | 10 +- .../src/app/service/shared-state.service.ts | 25 ++- 3 files changed, 93 insertions(+), 116 deletions(-) diff --git a/btc-UI/src/app/components/navbar/navbar.component.ts b/btc-UI/src/app/components/navbar/navbar.component.ts index 24ccd60..5e0187f 100755 --- a/btc-UI/src/app/components/navbar/navbar.component.ts +++ b/btc-UI/src/app/components/navbar/navbar.component.ts @@ -3,8 +3,6 @@ import { CommonModule } from '@angular/common'; import { BtcService } from '../../service/btc.service'; import { Router } from '@angular/router'; import { catchError, interval, of, Subscription, switchMap } from 'rxjs'; -// import { HorseService } from '../../service/horseData.service'; -// import { HorseRaceModel } from '../../model/horseRaceData'; import { SharedStateService } from '../../service/shared-state.service'; @Component({ @@ -19,16 +17,13 @@ export class NavbarComponent implements OnInit, OnDestroy { isMenuOpen: boolean = false; screenWidth: number = window.innerWidth; private subscription!: Subscription; - // public horseDataAndProgramData: HorseRaceModel[] = []; - // public raceData: HorseRaceModel[] = []; - //private selectedRaceId: number = 0; liveStatusOk: boolean = true; showVenueModal = false; showRaceModal = false; selectedVenue = 'Select Venue'; - selectedRace : number =1; + selectedRace: number = 1; showWalletModal = false; showResultModal = false; @@ -40,6 +35,7 @@ export class NavbarComponent implements OnInit, OnDestroy { objectKeys = Object.keys; selectedRaceId: number = 0; + enabledHorseNumbers: number[] = []; wallet = { withdraw: 0, @@ -93,30 +89,17 @@ export class NavbarComponent implements OnInit, OnDestroy { } }); - // this.horseService.HorseData.subscribe({ - // next: (data) => { - // if (data === null) return; - // console.log('[HORSE DATA] Received:', data); - // this.horseDataAndProgramData = data; - // }, - // error: (err) => { - // console.error('[HORSE DATA] Error:', err); - // }, - // }); - // } - - const cachedData = localStorage.getItem('raceCardData'); - if (cachedData) { - this.raceCardData = JSON.parse(cachedData); - console.log('📦 Loaded race card from localStorage:', this.raceCardData); - - // ✅ Pre-fill the venue name directly - this.selectedVenue = this.raceCardData?.Venue || 'Select Venue'; - } else { - this.raceCardData = { raceVenueRaces: { races: [] }, pools: {} }; - console.warn('⚠️ No race card data found in localStorage.'); + const cachedData = localStorage.getItem('raceCardData'); + if (cachedData) { + 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 + } else { + this.raceCardData = { raceVenueRaces: { races: [] }, pools: {} }; + console.warn('⚠️ No race card data found in localStorage.'); + } } -} updateDateTime() { const now = new Date(); @@ -140,18 +123,6 @@ export class NavbarComponent implements OnInit, OnDestroy { this.showVenueModal = true; } - // openRaceModal() { - // console.log('[MODAL] Opening race modal'); - // this.showRaceModal = true; - - // this.horseDataAndProgramData.map((data) => { - // if (data.raceId === this.selectedRaceId) { - // this.raceData = [data]; - // } - // return data; - // }); - // } - openRaceModal() { console.log('[MODAL] Opening race modal'); this.showRaceModal = true; @@ -174,20 +145,8 @@ export class NavbarComponent implements OnInit, OnDestroy { this.showLogModal = false; } - // selectVenue(venue: number) { - // console.log('[VENUE] User selected raceId:', venue); - // this.selectedRaceId = venue; - - // this.horseDataAndProgramData.map((data) => { - // if (data.raceId === venue) { - // this.selectedVenue = data.raceVenue?.venue || 'Unknown Venue'; - // } - // return data; - // }); - selectVenue(index: number) { const venue = this.raceCardData?.Venue || 'Unknown Venue'; - const venueKeys = Object.keys(this.raceCardData?.raceVenueRaces?.races || {}); this.selectedVenue = venue; this.selectedRaceId = index; @@ -196,31 +155,12 @@ export class NavbarComponent implements OnInit, OnDestroy { value: this.selectedVenue, }); - console.log('[VENUE] Venue resolved to:', this.selectedVenue); - - this.sharedStateService.updateSharedData({ - type: 'selectedVenue', - value: this.selectedVenue, - }); - console.log('[VENUE] Venue sent to sharedStateService'); this.closeModals(); } - // selectRace(race: string) { - // this.selectedRace = race; - - // this.sharedStateService.updateSharedData({ - // type: 'selectedRace', - // value: this.selectedRace, - // }); - - // console.log('[RACE] Race selected:', this.selectedRace); - // this.closeModals(); - // } - selectRace(race: number) { this.selectedRace = race; @@ -229,10 +169,46 @@ export class NavbarComponent implements OnInit, OnDestroy { value: this.selectedRace, }); - console.log('[RACE] Race selected:', 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 runnerCount = selectedRaceData.length || 12; + + this.sharedStateService.setRunnerCount(runnerCount); + this.updateEnabledHorseNumbers(); // Update local horse numbers + + 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); + } else { + this.enabledHorseNumbers = []; + } + + console.log('[HORSE NUMBERS] Enabled horse numbers:', this.enabledHorseNumbers); + + this.sharedStateService.updateSharedData({ + type: 'enabledHorseNumbers', + value: this.enabledHorseNumbers, + }); + } + + 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() { console.log('[MODAL] Opening wallet modal'); @@ -254,39 +230,33 @@ export class NavbarComponent implements OnInit, OnDestroy { this.showLogModal = true; } - logout(): void { - const name = localStorage.getItem('userName') || 'Unknown User'; - const employeeId = localStorage.getItem('employeeId') || '000000'; + logout(): void { + const name = localStorage.getItem('userName') || 'Unknown User'; + const employeeId = localStorage.getItem('employeeId') || '000000'; - const printData = { name, employeeId, action: 'logout' }; + const printData = { name, employeeId, action: 'logout' }; - console.log('[LOGOUT] Initiating logout with printData:', printData); + console.log('[LOGOUT] Initiating logout with printData:', printData); - fetch('http://localhost:9100/print', { - method: 'POST', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify(printData), - }) - .then((res) => { - if (!res.ok) throw new Error('Logout print failed'); - console.log('[LOGOUT] Print successful'); - - // ✅ Close the shared display via Electron - (window as any).electronAPI?.closeSecondScreen?.(); - - localStorage.clear(); - this.router.navigate(['/logout']); + fetch('http://localhost:9100/print', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify(printData), }) - .catch((err) => { - console.error('[LOGOUT] Error printing:', err); - - // ✅ Still close the shared display on error - (window as any).electronAPI?.closeSecondScreen?.(); - - localStorage.clear(); - this.router.navigate(['/logout']); - }); -} + .then((res) => { + if (!res.ok) throw new Error('Logout print failed'); + console.log('[LOGOUT] Print successful'); + (window as any).electronAPI?.closeSecondScreen?.(); + localStorage.clear(); + this.router.navigate(['/logout']); + }) + .catch((err) => { + console.error('[LOGOUT] Error printing:', err); + (window as any).electronAPI?.closeSecondScreen?.(); + localStorage.clear(); + this.router.navigate(['/logout']); + }); + } ngOnDestroy(): void { if (this.subscription) { diff --git a/btc-UI/src/app/home/home.component.ts b/btc-UI/src/app/home/home.component.ts index f6a9b30..d8eea60 100755 --- a/btc-UI/src/app/home/home.component.ts +++ b/btc-UI/src/app/home/home.component.ts @@ -27,8 +27,8 @@ export class HomeComponent implements OnInit, OnDestroy { isTabletView = false; isTicketingActive = false; private resizeObserver!: () => void; - private currentRaceIdx: number = 0; // Track current race - races: any[] = []; // Store race data + private currentRaceIdx: number = 0; + races: any[] = []; constructor( private cdr: ChangeDetectorRef, @@ -53,7 +53,7 @@ export class HomeComponent implements OnInit, OnDestroy { next: (response: HttpResponse) => { const horseRaceData = response.body; this.horseService.HorseData.next(horseRaceData); - this.races = horseRaceData || []; // Populate races for selection + this.races = horseRaceData || []; this.sharedStateService.updateSharedData({ type: 'horseData', value: horseRaceData, @@ -72,7 +72,7 @@ export class HomeComponent implements OnInit, OnDestroy { const raceCardData = res.body; console.log('📦 Race card preloaded:', raceCardData); localStorage.setItem('raceCardData', JSON.stringify(raceCardData)); - this.updateRunnerCount(0); // Initialize with first race + this.updateRunnerCount(0); }, error: (err) => { console.error('❌ Failed to preload race card:', err); @@ -80,7 +80,7 @@ export class HomeComponent implements OnInit, OnDestroy { }); } else { console.log('📦 Race card already cached'); - this.updateRunnerCount(0); // Initialize with first race + this.updateRunnerCount(0); } } diff --git a/btc-UI/src/app/service/shared-state.service.ts b/btc-UI/src/app/service/shared-state.service.ts index 579707d..2bb7988 100644 --- a/btc-UI/src/app/service/shared-state.service.ts +++ b/btc-UI/src/app/service/shared-state.service.ts @@ -1,12 +1,17 @@ import { Injectable } from '@angular/core'; import { BehaviorSubject } from 'rxjs'; +export interface SharedData { + type: string; + value: any; +} + @Injectable({ providedIn: 'root' }) export class SharedStateService { - private runnerCountSubject = new BehaviorSubject(12); // Default runner count + private runnerCountSubject = new BehaviorSubject(12); runnerCount$ = this.runnerCountSubject.asObservable(); - private sharedDataSubject = new BehaviorSubject(null); + private sharedDataSubject = new BehaviorSubject({ type: '', value: null }); sharedData$ = this.sharedDataSubject.asObservable(); private channel = new BroadcastChannel('shared-display-channel'); @@ -16,21 +21,23 @@ export class SharedStateService { this.channel.onmessage = (event) => { console.log('[BroadcastChannel] Received data:', event.data); if (event.data?.runnerCount !== undefined) { - this.runnerCountSubject.next(event.data.runnerCount); // Sync runner count + this.runnerCountSubject.next(event.data.runnerCount); + } + if (event.data?.type !== undefined && event.data?.value !== undefined) { + this.sharedDataSubject.next({ type: event.data.type, value: event.data.value }); } - this.sharedDataSubject.next(event.data); // Sync other shared data }; } setRunnerCount(count: number) { console.log('[SharedStateService] Broadcasting runner count:', count); - this.channel.postMessage({ runnerCount: count }); // Broadcast runner count - this.runnerCountSubject.next(count); // Update local runner count + this.channel.postMessage({ runnerCount: count }); + this.runnerCountSubject.next(count); } - updateSharedData(data: any) { + updateSharedData(data: SharedData) { console.log('[SharedStateService] Broadcasting data:', data); - this.channel.postMessage(data); // Send to other windows - this.sharedDataSubject.next(data); // Update local BehaviorSubject + this.channel.postMessage(data); + this.sharedDataSubject.next(data); } } \ No newline at end of file