fix : btid, login without docker
This commit is contained in:
parent
389ffe6555
commit
c7a9f1fcf2
@ -8,6 +8,7 @@ let currentSharedData = null; // Store latest data for initial sync
|
|||||||
let currentSelectedVenue = 'Select Venue';
|
let currentSelectedVenue = 'Select Venue';
|
||||||
let currentSelectedRace = 1;
|
let currentSelectedRace = 1;
|
||||||
let currentStopMessage = '';
|
let currentStopMessage = '';
|
||||||
|
let currentBtid = null; // Store in-memory BTID
|
||||||
|
|
||||||
function createWindows() {
|
function createWindows() {
|
||||||
const displays = screen.getAllDisplays();
|
const displays = screen.getAllDisplays();
|
||||||
@ -42,6 +43,9 @@ function createWindows() {
|
|||||||
|
|
||||||
screenWindow.loadURL('http://10.150.40.124:4200/shared-display');
|
screenWindow.loadURL('http://10.150.40.124:4200/shared-display');
|
||||||
|
|
||||||
|
// Debugging: Open DevTools for second screen to verify logs
|
||||||
|
// screenWindow.webContents.openDevTools({ mode: 'detach' });
|
||||||
|
|
||||||
// Handle opening second screen and send initial data
|
// Handle opening second screen and send initial data
|
||||||
ipcMain.on('open-second-screen', () => {
|
ipcMain.on('open-second-screen', () => {
|
||||||
screenWindow.show();
|
screenWindow.show();
|
||||||
@ -52,6 +56,7 @@ function createWindows() {
|
|||||||
screenWindow.webContents.send('update-selected-venue', currentSelectedVenue);
|
screenWindow.webContents.send('update-selected-venue', currentSelectedVenue);
|
||||||
screenWindow.webContents.send('update-selected-race', currentSelectedRace);
|
screenWindow.webContents.send('update-selected-race', currentSelectedRace);
|
||||||
screenWindow.webContents.send('update-stop-message', currentStopMessage);
|
screenWindow.webContents.send('update-stop-message', currentStopMessage);
|
||||||
|
screenWindow.webContents.send('update-btid', currentBtid);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -81,7 +86,7 @@ function createWindows() {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Add this new handler
|
// Handle stop message sync
|
||||||
ipcMain.on('sync-stop-message', (event, message) => {
|
ipcMain.on('sync-stop-message', (event, message) => {
|
||||||
currentStopMessage = message;
|
currentStopMessage = message;
|
||||||
if (screenWindow && screenWindow.webContents) {
|
if (screenWindow && screenWindow.webContents) {
|
||||||
@ -89,7 +94,16 @@ function createWindows() {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Handle BTID request
|
// Handle BTID sync
|
||||||
|
ipcMain.on('sync-btid', (event, btid) => {
|
||||||
|
console.log('[MAIN] sync-btid received:', btid);
|
||||||
|
currentBtid = btid; // Store in-memory BTID
|
||||||
|
if (screenWindow && screenWindow.webContents) {
|
||||||
|
screenWindow.webContents.send('update-btid', btid);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Handle BTID request from file
|
||||||
ipcMain.handle('get-btid', () => {
|
ipcMain.handle('get-btid', () => {
|
||||||
try {
|
try {
|
||||||
const filePath = path.join(process.env.HOME || process.env.USERPROFILE, 'BTID', 'betting.txt');
|
const filePath = path.join(process.env.HOME || process.env.USERPROFILE, 'BTID', 'betting.txt');
|
||||||
@ -97,10 +111,16 @@ function createWindows() {
|
|||||||
const match = content.match(/Btid\s*=\s*(\d+)/i);
|
const match = content.match(/Btid\s*=\s*(\d+)/i);
|
||||||
return match ? match[1] : null;
|
return match ? match[1] : null;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error('Error reading betting.txt:', err);
|
console.error('[MAIN] Error reading betting.txt:', err);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Allow renderers to request current in-memory BTID on demand
|
||||||
|
ipcMain.handle('request-current-btid', async () => {
|
||||||
|
console.log('[MAIN] request-current-btid =>', currentBtid);
|
||||||
|
return currentBtid || null;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
app.whenReady().then(createWindows);
|
app.whenReady().then(createWindows);
|
||||||
|
|||||||
@ -4,13 +4,15 @@ contextBridge.exposeInMainWorld('electronAPI', {
|
|||||||
openSecondScreen: () => ipcRenderer.send('open-second-screen'),
|
openSecondScreen: () => ipcRenderer.send('open-second-screen'),
|
||||||
closeSecondScreen: () => ipcRenderer.send('close-second-screen'),
|
closeSecondScreen: () => ipcRenderer.send('close-second-screen'),
|
||||||
getBtid: () => ipcRenderer.invoke('get-btid'),
|
getBtid: () => ipcRenderer.invoke('get-btid'),
|
||||||
|
getCurrentBtid: () => ipcRenderer.invoke('request-current-btid'), // NEW: Request in-memory BTID
|
||||||
syncSharedData: (data) => ipcRenderer.send('sync-shared-data', data),
|
syncSharedData: (data) => ipcRenderer.send('sync-shared-data', data),
|
||||||
onUpdateSharedData: (callback) => ipcRenderer.on('update-shared-data', (event, data) => callback(data)),
|
onUpdateSharedData: (callback) => ipcRenderer.on('update-shared-data', (event, data) => callback(data)),
|
||||||
// Add these new lines
|
|
||||||
syncStopMessage: (message) => ipcRenderer.send('sync-stop-message', message),
|
syncStopMessage: (message) => ipcRenderer.send('sync-stop-message', message),
|
||||||
onUpdateStopMessage: (callback) => ipcRenderer.on('update-stop-message', (event, message) => callback(message)),
|
onUpdateStopMessage: (callback) => ipcRenderer.on('update-stop-message', (event, message) => callback(message)),
|
||||||
syncSelectedVenue: (venue) => ipcRenderer.send('sync-selected-venue', venue),
|
syncSelectedVenue: (venue) => ipcRenderer.send('sync-selected-venue', venue),
|
||||||
onUpdateSelectedVenue: (callback) => ipcRenderer.on('update-selected-venue', (event, venue) => callback(venue)),
|
onUpdateSelectedVenue: (callback) => ipcRenderer.on('update-selected-venue', (event, venue) => callback(venue)),
|
||||||
syncSelectedRace: (race) => ipcRenderer.send('sync-selected-race', race),
|
syncSelectedRace: (race) => ipcRenderer.send('sync-selected-race', race),
|
||||||
onUpdateSelectedRace: (callback) => ipcRenderer.on('update-selected-race', (event, race) => callback(race)),
|
onUpdateSelectedRace: (callback) => ipcRenderer.on('update-selected-race', (event, race) => callback(race)),
|
||||||
|
syncBtid: (btid) => ipcRenderer.send('sync-btid', btid), // NEW: Send BTID to main
|
||||||
|
onUpdateBtid: (callback) => ipcRenderer.on('update-btid', (event, btid) => callback(btid)), // NEW: Listen for BTID updates
|
||||||
});
|
});
|
||||||
@ -1,4 +1,4 @@
|
|||||||
// shared-display.component.ts
|
// shared-display.component.ts (updated ngOnInit to read initial values from localStorage)
|
||||||
import { Component, OnInit, ChangeDetectorRef } from '@angular/core';
|
import { Component, OnInit, ChangeDetectorRef } from '@angular/core';
|
||||||
import { CommonModule } from '@angular/common';
|
import { CommonModule } from '@angular/common';
|
||||||
import { SharedStateService } from '../../service/shared-state.service';
|
import { SharedStateService } from '../../service/shared-state.service';
|
||||||
@ -13,7 +13,6 @@ interface SharedData {
|
|||||||
salesTotal: number;
|
salesTotal: number;
|
||||||
receiveTotal: number;
|
receiveTotal: number;
|
||||||
totalClicks: number;
|
totalClicks: number;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
@ -51,11 +50,66 @@ export class SharedDisplayComponent implements OnInit {
|
|||||||
) {}
|
) {}
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
console.log('[SHARED DISPLAY] Initializing, electronAPI available:', !!window.electronAPI);
|
console.log('[SHARED DISPLAY] Initializing, electronAPI available:', !!(window as any).electronAPI);
|
||||||
this.btid = localStorage.getItem('btid');
|
|
||||||
|
// NEW: Read initial values from localStorage (set by login)
|
||||||
|
this.btid = localStorage.getItem('btid') || null;
|
||||||
|
this.selectedVenue = localStorage.getItem('selectedVenue') || this.selectedVenue;
|
||||||
|
this.selectedRace = localStorage.getItem('selectedRace') || this.selectedRace;
|
||||||
|
console.log('[SHARED DISPLAY] Initial values from localStorage:', { btid: this.btid, selectedVenue: this.selectedVenue, selectedRace: this.selectedRace });
|
||||||
|
|
||||||
const electronAPI = (window as any).electronAPI;
|
const electronAPI = (window as any).electronAPI;
|
||||||
if (electronAPI) {
|
if (!electronAPI) {
|
||||||
|
console.error('[SHARED DISPLAY] electronAPI not available');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 1) Ask main process for the current in-memory BTID (avoid race)
|
||||||
|
if (electronAPI.getCurrentBtid) {
|
||||||
|
try {
|
||||||
|
electronAPI.getCurrentBtid().then((btidFromMain: string | null) => {
|
||||||
|
console.log('[SHARED DISPLAY] getCurrentBtid returned:', btidFromMain);
|
||||||
|
if (btidFromMain) {
|
||||||
|
this.btid = btidFromMain;
|
||||||
|
try { localStorage.setItem('btid', btidFromMain); } catch (e) { /* ignore */ }
|
||||||
|
this.cdRef.detectChanges();
|
||||||
|
}
|
||||||
|
}).catch((err: any) => {
|
||||||
|
console.warn('[SHARED DISPLAY] getCurrentBtid failed:', err);
|
||||||
|
});
|
||||||
|
} catch (err) {
|
||||||
|
console.warn('[SHARED DISPLAY] getCurrentBtid exception:', err);
|
||||||
|
}
|
||||||
|
} else if (electronAPI.getBtid) {
|
||||||
|
// Fallback to existing getBtid (reads file via main handler)
|
||||||
|
electronAPI.getBtid().then((btidFromFile: string | null) => {
|
||||||
|
console.log('[SHARED DISPLAY] getBtid returned:', btidFromFile);
|
||||||
|
if (btidFromFile) {
|
||||||
|
this.btid = btidFromFile;
|
||||||
|
try { localStorage.setItem('btid', btidFromFile); } catch (e) { /* ignore */ }
|
||||||
|
this.cdRef.detectChanges();
|
||||||
|
}
|
||||||
|
}).catch((err: any) => {
|
||||||
|
console.warn('[SHARED DISPLAY] getBtid failed:', err);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2) Listen for update-btid events (handles later syncs)
|
||||||
|
if (electronAPI.onUpdateBtid) {
|
||||||
|
electronAPI.onUpdateBtid((btid: string) => {
|
||||||
|
console.log('[SHARED DISPLAY] Received update-btid:', btid);
|
||||||
|
if (btid) {
|
||||||
|
this.btid = btid;
|
||||||
|
try { localStorage.setItem('btid', btid); } catch (e) { /* ignore */ }
|
||||||
|
this.cdRef.detectChanges();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
console.warn('[SHARED DISPLAY] onUpdateBtid not available');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Existing shared-data / venue / race listeners
|
||||||
|
if (electronAPI.onUpdateSharedData) {
|
||||||
electronAPI.onUpdateSharedData((data: SharedData) => {
|
electronAPI.onUpdateSharedData((data: SharedData) => {
|
||||||
console.log('[SHARED DISPLAY] Received IPC data:', data);
|
console.log('[SHARED DISPLAY] Received IPC data:', data);
|
||||||
if (!data) return;
|
if (!data) return;
|
||||||
@ -68,20 +122,32 @@ export class SharedDisplayComponent implements OnInit {
|
|||||||
console.log('[SHARED DISPLAY] Updated filledRows:', this.filledRows.map(row => ({ ...row, numbers: JSON.stringify(row.numbers) })));
|
console.log('[SHARED DISPLAY] Updated filledRows:', this.filledRows.map(row => ({ ...row, numbers: JSON.stringify(row.numbers) })));
|
||||||
this.cdRef.detectChanges();
|
this.cdRef.detectChanges();
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (electronAPI.onUpdateSelectedVenue) {
|
||||||
electronAPI.onUpdateSelectedVenue((venue: string) => {
|
electronAPI.onUpdateSelectedVenue((venue: string) => {
|
||||||
this.selectedVenue = venue;
|
this.selectedVenue = venue;
|
||||||
console.log('[SHARED DISPLAY] Venue updated via IPC to:', this.selectedVenue);
|
console.log('[SHARED DISPLAY] Venue updated via IPC to:', this.selectedVenue);
|
||||||
|
try { localStorage.setItem('selectedVenue', venue); } catch (e) { /* ignore */ }
|
||||||
this.cdRef.detectChanges();
|
this.cdRef.detectChanges();
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (electronAPI.onUpdateSelectedRace) {
|
||||||
electronAPI.onUpdateSelectedRace((race: number) => {
|
electronAPI.onUpdateSelectedRace((race: number) => {
|
||||||
this.selectedRace = race.toString();
|
this.selectedRace = race.toString();
|
||||||
console.log('[SHARED DISPLAY] Race updated via IPC to:', this.selectedRace);
|
console.log('[SHARED DISPLAY] Race updated via IPC to:', this.selectedRace);
|
||||||
|
try { localStorage.setItem('selectedRace', race.toString()); } catch (e) { /* ignore */ }
|
||||||
|
this.cdRef.detectChanges();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (electronAPI.onUpdateStopMessage) {
|
||||||
|
electronAPI.onUpdateStopMessage((msg: string) => {
|
||||||
|
console.log('[SHARED DISPLAY] Stop message received:', msg);
|
||||||
|
// Optionally handle display of stop message
|
||||||
this.cdRef.detectChanges();
|
this.cdRef.detectChanges();
|
||||||
});
|
});
|
||||||
} else {
|
|
||||||
console.error('[SHARED DISPLAY] electronAPI not available');
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -168,7 +168,7 @@ div[style*="background-color: black"] .custom-cell {
|
|||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
animation: scroll 20s linear infinite; /* Adjust duration for speed */
|
animation: scroll 20s linear infinite; /* Adjust duration for speed */
|
||||||
width: 55%; /* Ensure it takes full width */
|
width: 100%; /* Ensure it takes full width */
|
||||||
}
|
}
|
||||||
|
|
||||||
@keyframes scroll {
|
@keyframes scroll {
|
||||||
|
|||||||
@ -220,137 +220,156 @@ export class LoginComponent implements OnInit, OnDestroy {
|
|||||||
* Will fail if BTID cannot be fetched from Electron API
|
* Will fail if BTID cannot be fetched from Electron API
|
||||||
*/
|
*/
|
||||||
async onSubmit(): Promise<void> {
|
async onSubmit(): Promise<void> {
|
||||||
// validate form
|
// validate form
|
||||||
if (this.loginForm.invalid) {
|
if (this.loginForm.invalid) {
|
||||||
this.loginForm.markAllAsTouched();
|
this.loginForm.markAllAsTouched();
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
this.loginError = null;
|
|
||||||
this.passwordStatus = true;
|
|
||||||
|
|
||||||
const email = (this.loginForm.get('email')!.value || '').toString().trim();
|
|
||||||
const password = (this.loginForm.get('password')!.value || '').toString();
|
|
||||||
|
|
||||||
// ✅ CRITICAL: Load BTID FIRST - This will throw if fails
|
|
||||||
let fetchedBtid: string;
|
|
||||||
try {
|
|
||||||
console.log('🔄 Fetching BTID from Electron API...');
|
|
||||||
await this.btcService.loadBtid();
|
|
||||||
|
|
||||||
fetchedBtid = this.btcService.btid!;
|
|
||||||
if (!fetchedBtid) {
|
|
||||||
throw new Error('BTID is null after fetch');
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log('✅ BTID successfully fetched:', fetchedBtid);
|
|
||||||
} catch (btidError: any) {
|
|
||||||
console.error('❌ BTID fetch failed:', btidError);
|
|
||||||
this.loginError = `Failed to load BTID: ${btidError.message}. Please check Electron connection and try again.`;
|
|
||||||
this.passwordStatus = false;
|
|
||||||
return; // STOP LOGIN - No fallback allowed
|
|
||||||
}
|
|
||||||
|
|
||||||
// ✅ Build payload with REAL BTID - NO FALLBACK
|
|
||||||
const payload = {
|
|
||||||
opCard: email,
|
|
||||||
password: password,
|
|
||||||
btId: fetchedBtid, // Real BTID only
|
|
||||||
usrId: '',
|
|
||||||
btMake: 0,
|
|
||||||
};
|
|
||||||
|
|
||||||
console.log('📦 Login payload being sent:', payload);
|
|
||||||
|
|
||||||
try {
|
|
||||||
// 1) POST to login endpoint
|
|
||||||
const loginUrl = 'http://localhost:8080/login';
|
|
||||||
const loginResp: any = await lastValueFrom(
|
|
||||||
this.http.post(loginUrl, payload, { observe: 'body' })
|
|
||||||
);
|
|
||||||
|
|
||||||
console.log('🧠 Login response:', loginResp);
|
|
||||||
|
|
||||||
// Store response safely
|
|
||||||
try {
|
|
||||||
localStorage.setItem('loginRes', JSON.stringify(loginResp));
|
|
||||||
console.log('✅ Full login response saved');
|
|
||||||
} catch (e) {
|
|
||||||
console.error('❌ Failed to stringify login response:', e);
|
|
||||||
localStorage.setItem('loginRes', JSON.stringify(loginResp, Object.getOwnPropertyNames(loginResp)));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Parse username from response
|
|
||||||
const rawLoginRes = localStorage.getItem('loginRes');
|
|
||||||
if (rawLoginRes) {
|
|
||||||
try {
|
|
||||||
const parsed = JSON.parse(rawLoginRes);
|
|
||||||
const username = parsed?.log?.cUsrNm || 'Unknown User';
|
|
||||||
console.log('🧑 Username from loginRes:', username);
|
|
||||||
localStorage.setItem('userName', username);
|
|
||||||
} catch (e) {
|
|
||||||
console.error('❌ Failed to parse loginRes from localStorage', e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ✅ Save REAL BTID to localStorage for second screen
|
|
||||||
localStorage.setItem('btid', fetchedBtid);
|
|
||||||
console.log('💾 BTID saved to localStorage:', fetchedBtid);
|
|
||||||
|
|
||||||
// Prepare print payload
|
|
||||||
const printData = {
|
|
||||||
name: localStorage.getItem('userName') || 'Unknown User',
|
|
||||||
employeeId: email, // Use email as employee ID
|
|
||||||
action: 'login',
|
|
||||||
type: 'login',
|
|
||||||
};
|
|
||||||
|
|
||||||
// 2) Print (commented out - uncomment if needed)
|
|
||||||
/*
|
|
||||||
const printRes = await fetch('http://localhost:9100/print', {
|
|
||||||
method: 'POST',
|
|
||||||
headers: { 'Content-Type': 'application/json' },
|
|
||||||
body: JSON.stringify(printData),
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!printRes.ok) {
|
|
||||||
throw new Error(`Print failed (${printRes.status})`);
|
|
||||||
}
|
|
||||||
console.log('🖨️ Print successful');
|
|
||||||
*/
|
|
||||||
|
|
||||||
// 3) Fetch race card with DYNAMIC values - NO FALLBACKS
|
|
||||||
console.log('🔄 Fetching race card with:', { opCard: email, password, btId: fetchedBtid });
|
|
||||||
const rpInfo = await lastValueFrom(
|
|
||||||
this.btcService.fetchRaceCard(email, password, fetchedBtid) // Dynamic opCard, real BTID
|
|
||||||
);
|
|
||||||
|
|
||||||
console.log('📦 Race Card fetched successfully:', rpInfo);
|
|
||||||
localStorage.setItem('rpinfo', JSON.stringify(rpInfo));
|
|
||||||
|
|
||||||
// 4) Navigate to second screen
|
|
||||||
console.log('🚀 Navigating to home with BTID:', fetchedBtid);
|
|
||||||
(window as any).electronAPI?.openSecondScreen?.();
|
|
||||||
this.router.navigate(['/home']);
|
|
||||||
|
|
||||||
} catch (err: any) {
|
|
||||||
console.error('❌ Login flow failed:', err);
|
|
||||||
|
|
||||||
// Specific error handling
|
|
||||||
if (err?.message?.includes('Print failed')) {
|
|
||||||
this.loginError = 'Login failed: printing service unavailable.';
|
|
||||||
} else if (err?.status === 401 || err?.status === 400) {
|
|
||||||
this.loginError = 'Invalid login credentials';
|
|
||||||
} else if (err?.message?.includes('BTID')) {
|
|
||||||
this.loginError = `BTID Error: ${err.message}`;
|
|
||||||
} else {
|
|
||||||
this.loginError = err?.message || 'Login failed. Please try again.';
|
|
||||||
}
|
|
||||||
|
|
||||||
this.passwordStatus = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.loginError = null;
|
||||||
|
this.passwordStatus = true;
|
||||||
|
|
||||||
|
const email = (this.loginForm.get('email')!.value || '').toString().trim();
|
||||||
|
const password = (this.loginForm.get('password')!.value || '').toString();
|
||||||
|
|
||||||
|
// ✅ CRITICAL: Load BTID FIRST - This will throw if fails
|
||||||
|
let fetchedBtid: string;
|
||||||
|
try {
|
||||||
|
console.log('🔄 Fetching BTID from Electron API...');
|
||||||
|
await this.btcService.loadBtid();
|
||||||
|
|
||||||
|
fetchedBtid = this.btcService.btid!;
|
||||||
|
if (!fetchedBtid) {
|
||||||
|
throw new Error('BTID is null after fetch');
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('✅ BTID successfully fetched:', fetchedBtid);
|
||||||
|
} catch (btidError: any) {
|
||||||
|
console.error('❌ BTID fetch failed:', btidError);
|
||||||
|
this.loginError = `Failed to load BTID: ${btidError.message}. Please check Electron connection and try again.`;
|
||||||
|
this.passwordStatus = false;
|
||||||
|
return; // STOP LOGIN - No fallback allowed
|
||||||
|
}
|
||||||
|
|
||||||
|
// ✅ Build payload with REAL BTID - NO FALLBACK
|
||||||
|
const payload = {
|
||||||
|
opCard: email,
|
||||||
|
password: password,
|
||||||
|
btId: fetchedBtid, // Real BTID only
|
||||||
|
usrId: '',
|
||||||
|
btMake: 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
console.log('📦 Login payload being sent:', payload);
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 1) POST to login endpoint
|
||||||
|
const loginUrl = 'http://localhost:8080/login';
|
||||||
|
const loginResp: any = await lastValueFrom(
|
||||||
|
this.http.post(loginUrl, payload, { observe: 'body' })
|
||||||
|
);
|
||||||
|
|
||||||
|
console.log('🧠 Login response:', loginResp);
|
||||||
|
|
||||||
|
// Store response safely
|
||||||
|
try {
|
||||||
|
localStorage.setItem('loginRes', JSON.stringify(loginResp));
|
||||||
|
console.log('✅ Full login response saved');
|
||||||
|
} catch (e) {
|
||||||
|
console.error('❌ Failed to stringify login response:', e);
|
||||||
|
localStorage.setItem('loginRes', JSON.stringify(loginResp, Object.getOwnPropertyNames(loginResp)));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse username from response
|
||||||
|
const rawLoginRes = localStorage.getItem('loginRes');
|
||||||
|
if (rawLoginRes) {
|
||||||
|
try {
|
||||||
|
const parsed = JSON.parse(rawLoginRes);
|
||||||
|
const username = parsed?.log?.cUsrNm || 'Unknown User';
|
||||||
|
console.log('🧑 Username from loginRes:', username);
|
||||||
|
localStorage.setItem('userName', username);
|
||||||
|
} catch (e) {
|
||||||
|
console.error('❌ Failed to parse loginRes from localStorage', e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ✅ Save REAL BTID to localStorage for second screen
|
||||||
|
localStorage.setItem('btid', fetchedBtid);
|
||||||
|
console.log('💾 BTID saved to localStorage:', fetchedBtid);
|
||||||
|
|
||||||
|
// NEW: Sync BTID to main process for immediate second screen access via getCurrentBtid
|
||||||
|
if ((window as any).electronAPI?.syncBtid) {
|
||||||
|
(window as any).electronAPI.syncBtid(fetchedBtid);
|
||||||
|
console.log('📡 BTID synced to main process via IPC');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prepare print payload
|
||||||
|
const printData = {
|
||||||
|
name: localStorage.getItem('userName') || 'Unknown User',
|
||||||
|
employeeId: email, // Use email as employee ID
|
||||||
|
action: 'login',
|
||||||
|
type: 'login',
|
||||||
|
};
|
||||||
|
|
||||||
|
// 2) Print (commented out - uncomment if needed)
|
||||||
|
/*
|
||||||
|
const printRes = await fetch('http://localhost:9100/print', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: { 'Content-Type': 'application/json' },
|
||||||
|
body: JSON.stringify(printData),
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!printRes.ok) {
|
||||||
|
throw new Error(`Print failed (${printRes.status})`);
|
||||||
|
}
|
||||||
|
console.log('🖨️ Print successful');
|
||||||
|
*/
|
||||||
|
|
||||||
|
// 3) Fetch race card with DYNAMIC values - NO FALLBACKS
|
||||||
|
console.log('🔄 Fetching race card with:', { opCard: email, password, btId: fetchedBtid });
|
||||||
|
const rpInfo = await lastValueFrom(
|
||||||
|
this.btcService.fetchRaceCard(email, password, fetchedBtid) // Dynamic opCard, real BTID
|
||||||
|
);
|
||||||
|
|
||||||
|
console.log('📦 Race Card fetched successfully:', rpInfo);
|
||||||
|
localStorage.setItem('rpinfo', JSON.stringify(rpInfo));
|
||||||
|
|
||||||
|
// NEW: Set initial race from rpInfo to localStorage for second screen initial display
|
||||||
|
// Adjust these extractions based on the actual structure of rpInfo (e.g., rpInfo.currentRace)
|
||||||
|
const initialRace = rpInfo.race || rpInfo.currentRace || 1; // Example: Adjust path to your rpInfo structure
|
||||||
|
localStorage.setItem('selectedRace', initialRace.toString());
|
||||||
|
console.log('💾 Initial race saved to localStorage:', { initialRace });
|
||||||
|
|
||||||
|
// NEW: Sync initial race to main process (for currentSelectedRace in main.js)
|
||||||
|
if ((window as any).electronAPI) {
|
||||||
|
if ((window as any).electronAPI.syncSelectedRace) {
|
||||||
|
(window as any).electronAPI.syncSelectedRace(initialRace);
|
||||||
|
console.log('📡 Initial race synced to main process via IPC');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4) Navigate to second screen
|
||||||
|
console.log('🚀 Navigating to home with BTID:', fetchedBtid);
|
||||||
|
(window as any).electronAPI?.openSecondScreen?.();
|
||||||
|
this.router.navigate(['/home']);
|
||||||
|
|
||||||
|
} catch (err: any) {
|
||||||
|
console.error('❌ Login flow failed:', err);
|
||||||
|
|
||||||
|
// Specific error handling
|
||||||
|
if (err?.message?.includes('Print failed')) {
|
||||||
|
this.loginError = 'Login failed: printing service unavailable.';
|
||||||
|
} else if (err?.status === 401 || err?.status === 400) {
|
||||||
|
this.loginError = 'Invalid login credentials';
|
||||||
|
} else if (err?.message?.includes('BTID')) {
|
||||||
|
this.loginError = `BTID Error: ${err.message}`;
|
||||||
|
} else {
|
||||||
|
this.loginError = err?.message || 'Login failed. Please try again.';
|
||||||
|
}
|
||||||
|
|
||||||
|
this.passwordStatus = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
showConfirmModal: boolean = false;
|
showConfirmModal: boolean = false;
|
||||||
|
|
||||||
confirmShutdown(): void {
|
confirmShutdown(): void {
|
||||||
|
|||||||
@ -169,7 +169,7 @@ export class StopbetService implements OnDestroy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.http
|
this.http
|
||||||
.get(`http://localhost:8080/stopbet/raw?venue=${this.currentVenue}&date=${this.currentDate}`)
|
.get(`http://localhost:8089/stopbet/raw?venue=${this.currentVenue}&date=${this.currentDate}`)
|
||||||
.subscribe({
|
.subscribe({
|
||||||
next: (res: any) => {
|
next: (res: any) => {
|
||||||
if (res && res.ok && res.data) {
|
if (res && res.ok && res.data) {
|
||||||
@ -205,7 +205,7 @@ export class StopbetService implements OnDestroy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
this.eventSource = new EventSource('http://localhost:8080/stopbet/stream');
|
this.eventSource = new EventSource('http://localhost:8089/stopbet/stream');
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error('[STOPBET] Failed to create EventSource:', err);
|
console.error('[STOPBET] Failed to create EventSource:', err);
|
||||||
return;
|
return;
|
||||||
|
|||||||
4
btc-UI/src/electron.d.ts
vendored
4
btc-UI/src/electron.d.ts
vendored
@ -2,15 +2,17 @@ interface ElectronAPI {
|
|||||||
openSecondScreen: () => void;
|
openSecondScreen: () => void;
|
||||||
closeSecondScreen: () => void;
|
closeSecondScreen: () => void;
|
||||||
getBtid: () => Promise<string | null>;
|
getBtid: () => Promise<string | null>;
|
||||||
|
getCurrentBtid: () => Promise<string | null>; // NEW: Request in-memory BTID
|
||||||
syncSharedData: (data: SharedData) => void;
|
syncSharedData: (data: SharedData) => void;
|
||||||
onUpdateSharedData: (callback: (data: SharedData) => void) => void;
|
onUpdateSharedData: (callback: (data: SharedData) => void) => void;
|
||||||
// Add these new lines
|
|
||||||
syncStopMessage: (message: string) => void;
|
syncStopMessage: (message: string) => void;
|
||||||
onUpdateStopMessage: (callback: (message: string) => void) => void;
|
onUpdateStopMessage: (callback: (message: string) => void) => void;
|
||||||
syncSelectedVenue: (venue: string) => void;
|
syncSelectedVenue: (venue: string) => void;
|
||||||
onUpdateSelectedVenue: (callback: (venue: string) => void) => void;
|
onUpdateSelectedVenue: (callback: (venue: string) => void) => void;
|
||||||
syncSelectedRace: (race: number) => void;
|
syncSelectedRace: (race: number) => void;
|
||||||
onUpdateSelectedRace: (callback: (race: number) => void) => void;
|
onUpdateSelectedRace: (callback: (race: number) => void) => void;
|
||||||
|
syncBtid: (btid: string) => void; // NEW: Send BTID to main
|
||||||
|
onUpdateBtid: (callback: (btid: string) => void) => void; // NEW: Listen for BTID updates
|
||||||
}
|
}
|
||||||
|
|
||||||
interface SharedData {
|
interface SharedData {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user