fix : race card fetching from the server and working
This commit is contained in:
parent
5974bf5535
commit
b680150a88
@ -19,20 +19,19 @@ export class NavbarComponent implements OnInit, OnDestroy {
|
||||
private subscription!: Subscription;
|
||||
userName: string = '';
|
||||
btid: string | null = null;
|
||||
|
||||
liveStatusOk: boolean = true;
|
||||
|
||||
showVenueModal = false;
|
||||
showRaceModal = false;
|
||||
selectedVenue = 'Select Venue';
|
||||
selectedRace: number = 1;
|
||||
currentLegRaceDisplay: string = ''; // Display current leg's race or pool start
|
||||
currentLegRaceDisplay: string = '';
|
||||
|
||||
showWalletModal = false;
|
||||
showResultModal = false;
|
||||
showMessagesModal = false;
|
||||
showLogModal = false;
|
||||
raceCardData: any = {};
|
||||
raceCardData: any = null;
|
||||
raceData: any[] = [];
|
||||
objectKeys = Object.keys;
|
||||
|
||||
@ -41,37 +40,19 @@ export class NavbarComponent implements OnInit, OnDestroy {
|
||||
multiLegBaseRaceIdx: number = 0;
|
||||
currentPool: string | null = null;
|
||||
|
||||
private prevEnabledKey = ''; // For memoization
|
||||
private prevEnabledKey = '';
|
||||
|
||||
wallet = {
|
||||
withdraw: 0,
|
||||
deposit: 0,
|
||||
payout: 0,
|
||||
cancel: 0,
|
||||
ticketing: 0,
|
||||
balance: 0,
|
||||
};
|
||||
wallet = { withdraw: 0, deposit: 0, payout: 0, cancel: 0, ticketing: 0, balance: 0 };
|
||||
|
||||
logs = [{
|
||||
description: '',
|
||||
venue: '',
|
||||
ticketNumber: '',
|
||||
poolName: '',
|
||||
totalAmount: '',
|
||||
}];
|
||||
logs = [{ description: '', venue: '', ticketNumber: '', poolName: '', totalAmount: '' }];
|
||||
|
||||
messages: string[] = [
|
||||
'System ready.',
|
||||
'Please select a venue.',
|
||||
'Races updated.',
|
||||
'Live status stable.',
|
||||
];
|
||||
messages: string[] = ['System ready.', 'Please select a venue.', 'Races updated.', 'Live status stable.'];
|
||||
|
||||
constructor(
|
||||
private btcService: BtcService,
|
||||
private router: Router,
|
||||
private sharedStateService: SharedStateService,
|
||||
private zone: NgZone // <-- Add NgZone
|
||||
private zone: NgZone
|
||||
) {}
|
||||
|
||||
ngOnInit() {
|
||||
@ -79,30 +60,19 @@ export class NavbarComponent implements OnInit, OnDestroy {
|
||||
this.btid = localStorage.getItem('btid');
|
||||
// Use NgZone to run setInterval outside Angular's change detection
|
||||
this.zone.runOutsideAngular(() => {
|
||||
setInterval(() => {
|
||||
this.zone.run(() => this.updateDateTime());
|
||||
}, 1000);
|
||||
setInterval(() => { this.zone.run(() => this.updateDateTime()); }, 1000);
|
||||
});
|
||||
|
||||
this.subscription = interval(5000)
|
||||
.pipe(
|
||||
switchMap(() =>
|
||||
this.btcService.pingLiveStatus().pipe(
|
||||
catchError((error) => {
|
||||
console.error('[LIVE STATUS] Ping failed:', error);
|
||||
this.liveStatusOk = false;
|
||||
return of(null);
|
||||
})
|
||||
catchError((error) => { console.error('[LIVE STATUS] Ping failed:', error); this.liveStatusOk = false; return of(null); })
|
||||
))
|
||||
).subscribe((response) => {
|
||||
if (response !== null) {
|
||||
console.log('[LIVE STATUS] OK');
|
||||
this.liveStatusOk = true;
|
||||
}
|
||||
if (response !== null) { this.liveStatusOk = true; console.log('[LIVE STATUS] OK'); }
|
||||
});
|
||||
|
||||
|
||||
|
||||
this.sharedStateService.sharedData$.subscribe(data => {
|
||||
if (data.type === 'currentLegRace') {
|
||||
this.selectedRace = data.value;
|
||||
@ -117,11 +87,11 @@ export class NavbarComponent implements OnInit, OnDestroy {
|
||||
}
|
||||
if (data.type === 'multiLegPoolStart') {
|
||||
const { label, baseRaceIdx } = data.value;
|
||||
this.currentPool = label;
|
||||
this.currentPool = this.normalizePoolName(label);
|
||||
this.multiLegBaseRaceIdx = baseRaceIdx;
|
||||
this.currentLegRaceDisplay = `Starting at Race ${baseRaceIdx} for ${label}`;
|
||||
this.currentLegRaceDisplay = `Starting at Race ${baseRaceIdx} for ${this.currentPool}`;
|
||||
this.updateEnabledHorseNumbersForMultiLeg(baseRaceIdx);
|
||||
console.log(`[Multi-leg Pool] Selected: ${label}, Base Race: ${baseRaceIdx}`);
|
||||
console.log(`[Multi-leg Pool] Selected: ${this.currentPool}, Base Race: ${baseRaceIdx}`);
|
||||
}
|
||||
if (data.type === 'multiLegPoolEnd') {
|
||||
this.currentPool = null;
|
||||
@ -137,115 +107,115 @@ export class NavbarComponent implements OnInit, OnDestroy {
|
||||
this.updateEnabledHorseNumbers();
|
||||
}
|
||||
});
|
||||
|
||||
this.loadRaceCardData();
|
||||
}
|
||||
|
||||
private safeGetJSON(key: string): any | null {
|
||||
try {
|
||||
const raw = localStorage.getItem(key);
|
||||
if (!raw) return null;
|
||||
return JSON.parse(raw);
|
||||
} catch (err) {
|
||||
console.warn(`[safeGetJSON] failed parse ${key}`, err);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private loadRaceCardData() {
|
||||
const cached = this.safeGetJSON('rpinfo');
|
||||
if (cached && cached.structuredRaceCard) {
|
||||
this.raceCardData = cached.structuredRaceCard;
|
||||
this.selectedVenue = this.raceCardData?.venue || 'Select Venue';
|
||||
this.updateEnabledHorseNumbers();
|
||||
return;
|
||||
}
|
||||
const rc = this.safeGetJSON('raceCardData');
|
||||
if (rc) {
|
||||
this.raceCardData = rc;
|
||||
this.selectedVenue = this.raceCardData?.venue || 'Select Venue';
|
||||
this.updateEnabledHorseNumbers();
|
||||
return;
|
||||
}
|
||||
this.raceCardData = { error: 'Race card not available locally' };
|
||||
this.selectedVenue = 'Select Venue';
|
||||
}
|
||||
|
||||
private normalizePoolName(name: string | null | undefined): string | null {
|
||||
if (!name) return null;
|
||||
const n = String(name).toLowerCase();
|
||||
if (n.startsWith('trb') || n.startsWith('tbp')) return n.includes('2') ? 'trb2' : 'trb1';
|
||||
if (n.startsWith('mjp')) return n.includes('2') ? 'mjp2' : 'mjp1';
|
||||
if (n.startsWith('jkp') || n.startsWith('jpp') || n.startsWith('jk')) return n.includes('2') ? 'jkp2' : 'jkp1';
|
||||
return n;
|
||||
}
|
||||
|
||||
private getLegIndexForRace(poolName: string, race: number): number {
|
||||
const raceMap: { [key: string]: number[] } = {
|
||||
'mjp1': [1, 2, 3, 4],
|
||||
'jkp1': [3, 4, 5, 6, 7],
|
||||
'trb1': [2, 3, 4],
|
||||
'trb2': [5, 6, 7]
|
||||
};
|
||||
return raceMap[poolName]?.indexOf(race) ?? 0;
|
||||
if (!this.raceCardData) return 0;
|
||||
const normalized = this.normalizePoolName(poolName) || poolName;
|
||||
const poolMap: { [key: string]: number[] } = this.raceCardData?.pools || {};
|
||||
const arr = poolMap[normalized] || poolMap[poolName] || [];
|
||||
return arr.indexOf(race) >= 0 ? arr.indexOf(race) : 0;
|
||||
}
|
||||
|
||||
private updateEnabledHorseNumbersForMultiLeg(baseRaceIdx: number) {
|
||||
const raceCardData = this.raceCardData?.raceVenueRaces?.races || [];
|
||||
const racesArr = this.raceCardData?.raceVenueRaces?.races || [];
|
||||
const legCount = this.getLegCountForLabel();
|
||||
const key = `${this.currentPool}-${baseRaceIdx}-${legCount}`;
|
||||
|
||||
if (this.prevEnabledKey === key) return; // 🧠 Memoization
|
||||
const poolKey = this.currentPool || '';
|
||||
const key = `${poolKey}-${baseRaceIdx}-${legCount}`;
|
||||
if (this.prevEnabledKey === key) return;
|
||||
this.prevEnabledKey = key;
|
||||
|
||||
let combinedHorseNumbers: number[] = [];
|
||||
|
||||
const raceIndices = Array.from({ length: legCount }, (_, i) =>
|
||||
this.getRaceForLeg(this.currentPool || '', i) - 1
|
||||
);
|
||||
const raceIndices = Array.from({ length: legCount }, (_, i) => this.getRaceForLeg(poolKey, i) - 1);
|
||||
|
||||
for (const raceIdx of raceIndices) {
|
||||
const race = raceCardData[raceIdx] || [];
|
||||
if (Array.isArray(race)) {
|
||||
const horses = race
|
||||
.map((runner: any) => runner?.horseNumber)
|
||||
.filter((n: number) => typeof n === 'number' && n >= 1 && n <= 30);
|
||||
const race = racesArr[raceIdx] || {};
|
||||
if (Array.isArray(race.horses)) {
|
||||
const horses = race.horses.filter((n: any) => typeof n === 'number' && n >= 1 && n <= 30);
|
||||
combinedHorseNumbers.push(...horses);
|
||||
}
|
||||
}
|
||||
|
||||
this.enabledHorseNumbers = Array.from(new Set(combinedHorseNumbers));
|
||||
|
||||
this.sharedStateService.updateSharedData({
|
||||
type: 'enabledHorseNumbers',
|
||||
value: this.enabledHorseNumbers,
|
||||
});
|
||||
|
||||
this.sharedStateService.updateSharedData({ type: 'enabledHorseNumbers', value: this.enabledHorseNumbers });
|
||||
console.log('[Multi-leg Pool] Updated enabled horse numbers:', this.enabledHorseNumbers);
|
||||
}
|
||||
|
||||
private getLegCountForLabel(): number {
|
||||
switch (this.currentPool) {
|
||||
case 'mjp1': return 4;
|
||||
case 'jkp1': return 5;
|
||||
case 'trb1':
|
||||
case 'trb2': return 3;
|
||||
const p = (this.currentPool || '').toLowerCase();
|
||||
switch (p) {
|
||||
case 'mjp1': case 'mjp2': return 4;
|
||||
case 'jkp1': case 'jkp2': return 5;
|
||||
case 'trb1': case 'trb2': return 3;
|
||||
default: return 3;
|
||||
}
|
||||
}
|
||||
|
||||
private getRaceForLeg(poolName: string, leg: number): number {
|
||||
const raceMap: { [key: string]: number[] } = {
|
||||
'mjp1': [1, 2, 3, 4],
|
||||
'jkp1': [3, 4, 5, 6, 7],
|
||||
'trb1': [2, 3, 4],
|
||||
'trb2': [5, 6, 7]
|
||||
};
|
||||
return raceMap[poolName]?.[leg] || (this.multiLegBaseRaceIdx + leg);
|
||||
const normalized = this.normalizePoolName(poolName) || poolName;
|
||||
const poolMap: { [key: string]: number[] } = this.raceCardData?.pools || {};
|
||||
const arr = poolMap[normalized] || poolMap[poolName] || [];
|
||||
if (arr.length > leg) return arr[leg];
|
||||
return (this.multiLegBaseRaceIdx || 1) + leg;
|
||||
}
|
||||
|
||||
updateDateTime() {
|
||||
const now = new Date();
|
||||
this.dateTime = now.toLocaleString();
|
||||
}
|
||||
updateDateTime() { this.dateTime = new Date().toLocaleString(); }
|
||||
|
||||
@HostListener('window:resize', ['$event'])
|
||||
onResize(event: any) {
|
||||
this.screenWidth = event.target.innerWidth;
|
||||
if (this.screenWidth > 800) {
|
||||
this.isMenuOpen = false;
|
||||
}
|
||||
if (this.screenWidth > 800) this.isMenuOpen = false;
|
||||
}
|
||||
|
||||
toggleMenu() {
|
||||
this.isMenuOpen = !this.isMenuOpen;
|
||||
}
|
||||
toggleMenu() { this.isMenuOpen = !this.isMenuOpen; }
|
||||
|
||||
openVenueModal() {
|
||||
|
||||
const cachedData = localStorage.getItem('raceCardData');
|
||||
if (cachedData) {
|
||||
this.raceCardData = JSON.parse(cachedData);
|
||||
// console.log('📦 Loaded race card from localStorage:', this.raceCardData); // comment out for perf
|
||||
this.selectedVenue = this.raceCardData?.Venue || 'Select Venue';
|
||||
this.updateEnabledHorseNumbers();
|
||||
} else {
|
||||
this.raceCardData = { raceVenueRaces: { races: [] }, pools: {} };
|
||||
// console.warn('⚠️ No race card data found in localStorage.'); // comment out for perf
|
||||
}
|
||||
console.log('[MODAL] Opening venue modal');
|
||||
this.showVenueModal = true;
|
||||
}
|
||||
openVenueModal() { this.loadRaceCardData(); this.showVenueModal = true; }
|
||||
|
||||
openRaceModal() {
|
||||
console.log('[MODAL] Opening race modal');
|
||||
this.showRaceModal = true;
|
||||
|
||||
const venueIndex = Object.keys(this.raceCardData?.raceVenueRaces?.races || [])
|
||||
.findIndex((_, idx) => idx === this.selectedRaceId);
|
||||
|
||||
if (venueIndex !== -1) {
|
||||
this.raceData = this.raceCardData.raceVenueRaces.races[venueIndex] || [];
|
||||
}
|
||||
const race = this.raceCardData?.raceVenueRaces?.races?.[this.selectedRaceId];
|
||||
this.raceData = race ? (race.horses || []) : [];
|
||||
}
|
||||
|
||||
closeModals() {
|
||||
@ -259,16 +229,9 @@ export class NavbarComponent implements OnInit, OnDestroy {
|
||||
}
|
||||
|
||||
selectVenue(index: number) {
|
||||
const venue = this.raceCardData?.Venue || 'Unknown Venue';
|
||||
this.selectedVenue = venue;
|
||||
this.selectedVenue = this.raceCardData?.venue || 'Unknown Venue';
|
||||
this.selectedRaceId = index;
|
||||
|
||||
this.sharedStateService.updateSharedData({
|
||||
type: 'selectedVenue',
|
||||
value: this.selectedVenue,
|
||||
});
|
||||
|
||||
console.log('[VENUE] Venue resolved to:', this.selectedVenue);
|
||||
this.sharedStateService.updateSharedData({ type: 'selectedVenue', value: this.selectedVenue });
|
||||
this.closeModals();
|
||||
}
|
||||
|
||||
@ -277,124 +240,57 @@ export class NavbarComponent implements OnInit, OnDestroy {
|
||||
this.currentPool = null;
|
||||
this.multiLegBaseRaceIdx = 0;
|
||||
this.currentLegRaceDisplay = '';
|
||||
this.sharedStateService.updateSharedData({ type: 'selectedRace', value: this.selectedRace });
|
||||
|
||||
this.sharedStateService.updateSharedData({
|
||||
type: 'selectedRace',
|
||||
value: this.selectedRace,
|
||||
});
|
||||
|
||||
const raceCard = JSON.parse(localStorage.getItem('raceCardData') || '{}');
|
||||
const raceList = raceCard?.raceVenueRaces?.races || [];
|
||||
const selectedRaceData = raceList[race - 1] || [];
|
||||
const runnerCount = selectedRaceData.length || 12;
|
||||
|
||||
const raceData = this.raceCardData?.raceVenueRaces?.races?.[race - 1] || {};
|
||||
const runnerCount = Array.isArray(raceData.horses) ? raceData.horses.length : (raceData.runners?.length || 12);
|
||||
this.sharedStateService.setRunnerCount(runnerCount);
|
||||
this.updateEnabledHorseNumbers();
|
||||
|
||||
console.log('[RACE] Race selected:', this.selectedRace, '| Runner count:', runnerCount);
|
||||
this.closeModals();
|
||||
}
|
||||
|
||||
updateEnabledHorseNumbers() {
|
||||
const raceIndex = this.selectedRace - 1;
|
||||
const race = this.raceCardData?.raceVenueRaces?.races?.[raceIndex];
|
||||
const race = this.raceCardData?.raceVenueRaces?.races?.[raceIndex] || {};
|
||||
let horses: any[] = [];
|
||||
|
||||
if (Array.isArray(race)) {
|
||||
this.enabledHorseNumbers = race
|
||||
.map((runner: any) => runner?.horseNumber)
|
||||
.filter((n: any) => typeof n === 'number' && n >= 1 && n <= 30);
|
||||
} else {
|
||||
this.enabledHorseNumbers = [];
|
||||
}
|
||||
|
||||
this.sharedStateService.updateSharedData({
|
||||
type: 'enabledHorseNumbers',
|
||||
value: this.enabledHorseNumbers,
|
||||
});
|
||||
if (Array.isArray(race?.horses)) horses = race.horses;
|
||||
else if (Array.isArray(race?.runners)) horses = race.runners.map((r: any) => r.number ?? r);
|
||||
else if (Array.isArray(race)) horses = race;
|
||||
|
||||
this.enabledHorseNumbers = horses.map((n: any) => Number(n)).filter((n: number) => !Number.isNaN(n) && n >= 1 && n <= 30);
|
||||
this.sharedStateService.updateSharedData({ type: 'enabledHorseNumbers', value: this.enabledHorseNumbers });
|
||||
console.log('[HORSE NUMBERS] Enabled horse numbers:', this.enabledHorseNumbers);
|
||||
}
|
||||
|
||||
selectHorseNumber(number: number) {
|
||||
console.log('[HORSE] Selected horse number:', number);
|
||||
}
|
||||
selectHorseNumber(number: number) { console.log('[HORSE] Selected horse number:', number); }
|
||||
|
||||
openWalletModal() {
|
||||
console.log('[MODAL] Opening wallet modal');
|
||||
this.showWalletModal = true;
|
||||
}
|
||||
openWalletModal() { this.showWalletModal = true; }
|
||||
openResultModal() { this.showResultModal = true; }
|
||||
openMessagesModal() { this.showMessagesModal = true; }
|
||||
openLogModal() { this.showLogModal = true; }
|
||||
|
||||
openResultModal() {
|
||||
console.log('[MODAL] Opening result modal');
|
||||
this.showResultModal = true;
|
||||
}
|
||||
|
||||
openMessagesModal() {
|
||||
console.log('[MODAL] Opening messages modal');
|
||||
this.showMessagesModal = true;
|
||||
}
|
||||
|
||||
openLogModal() {
|
||||
console.log('[MODAL] Opening log modal');
|
||||
this.showLogModal = true;
|
||||
}
|
||||
|
||||
|
||||
// formattedTicketLogs: {
|
||||
// label: string;
|
||||
// numbers: number[];
|
||||
// count: number;
|
||||
// amount: number;
|
||||
// }[] = [];
|
||||
formattedTicketLogs: {
|
||||
pool: string;
|
||||
horses: string;
|
||||
horsesArray: string[][];
|
||||
ticketCountLabel: string;
|
||||
price: string;
|
||||
numbers: number[];
|
||||
count: number;
|
||||
amount: number;
|
||||
maskedBarcode: string;
|
||||
displayBarcode: string;
|
||||
}[] = [];
|
||||
formattedTicketLogs: any[] = [];
|
||||
|
||||
openViewLog() {
|
||||
const storedTickets = localStorage.getItem('localTicketsViewlog');
|
||||
|
||||
if (storedTickets) {
|
||||
if (!storedTickets) { this.formattedTicketLogs = []; this.showLogModal = true; return; }
|
||||
const tickets = JSON.parse(storedTickets);
|
||||
|
||||
this.formattedTicketLogs = tickets.map((ticket: any, index: number) => {
|
||||
this.formattedTicketLogs = tickets.map((ticket: any) => {
|
||||
const rawLabel = ticket.winLabels?.trim() || '';
|
||||
const numbers = ticket.numbers || [];
|
||||
const count = ticket.ticketCount || 0;
|
||||
const amount = ticket.totalAmount || 0;
|
||||
const barcodeId = ticket.barcodeId || '';
|
||||
let pool = '', horses = '', horsesArray: string[][] = [], ticketCountLabel = '', price = '', maskedBarcode = '', displayBarcode = '';
|
||||
|
||||
if (rawLabel) {
|
||||
// 1️⃣ Extract pool (first word)
|
||||
const parts = rawLabel.split(/\s+/);
|
||||
pool = parts[0];
|
||||
|
||||
// 2️⃣ Extract ticket count (*n) & price if exists
|
||||
const countMatch = rawLabel.match(/\*(\d+)(?:\s+(Rs\s*\d+))?/);
|
||||
if (countMatch) {
|
||||
ticketCountLabel = `*${countMatch[1]}`;
|
||||
price = countMatch[2] || '';
|
||||
}
|
||||
|
||||
// 3️⃣ Extract horses part (between pool name & ticket count)
|
||||
if (countMatch) { ticketCountLabel = `*${countMatch[1]}`; price = countMatch[2] || ''; }
|
||||
const horsesPartMatch = rawLabel.match(/^\w+\s+(.+?)\s+\*\d+/);
|
||||
if (horsesPartMatch) {
|
||||
horses = horsesPartMatch[1].trim();
|
||||
|
||||
// Special pools split into races
|
||||
if (['MJP', 'JKP', 'TRE'].includes(pool)) {
|
||||
horsesArray = horses.split('/').map(r =>
|
||||
r.trim().split(',').map(h => h.trim())
|
||||
);
|
||||
if (['MJP', 'JKP', 'TRE', 'trb1', 'trb2', 'mjp1', 'jkp1'].includes(pool)) {
|
||||
horsesArray = horses.split('/').map((r: string) => r.trim().split(',').map(h => h.trim()));
|
||||
} else {
|
||||
horsesArray = [horses.split(',').map(h => h.trim())];
|
||||
}
|
||||
@ -403,62 +299,25 @@ openViewLog() {
|
||||
|
||||
if (barcodeId) {
|
||||
const last4 = barcodeId.slice(-4);
|
||||
|
||||
// Encrypt everything except last4
|
||||
const encryptedPart = btoa(barcodeId.slice(0, -4));
|
||||
|
||||
// Store masked barcode (if you still need encrypted form)
|
||||
maskedBarcode = encryptedPart;
|
||||
|
||||
// For GUI → show ******** + last4
|
||||
maskedBarcode = btoa(barcodeId.slice(0, -4));
|
||||
displayBarcode = '********' + last4;
|
||||
}
|
||||
|
||||
|
||||
console.log(maskedBarcode);
|
||||
console.log('Decoded:', atob(maskedBarcode));
|
||||
|
||||
|
||||
return {
|
||||
pool,
|
||||
horses,
|
||||
horsesArray,
|
||||
ticketCountLabel,
|
||||
price,
|
||||
numbers,
|
||||
count,
|
||||
amount,
|
||||
maskedBarcode,
|
||||
displayBarcode
|
||||
};
|
||||
return { pool, horses, horsesArray, ticketCountLabel, price, numbers: ticket.numbers || [], count: ticket.ticketCount || 0, amount: ticket.totalAmount || 0, maskedBarcode, displayBarcode };
|
||||
});
|
||||
} else {
|
||||
console.log('No tickets found in localStorage.');
|
||||
this.formattedTicketLogs = [];
|
||||
}
|
||||
|
||||
this.showLogModal = true;
|
||||
console.log('Log modal opened. Final formattedTicketLogs:', this.formattedTicketLogs);
|
||||
}
|
||||
|
||||
|
||||
logout(): void {
|
||||
const name = localStorage.getItem('userName') || 'Unknown User';
|
||||
const employeeId = localStorage.getItem('employeeId') || '000000';
|
||||
|
||||
const printData = {
|
||||
name,
|
||||
employeeId,
|
||||
action: 'logout',
|
||||
type: 'logout' // 👈 This is the missing piece
|
||||
};
|
||||
|
||||
const printData = { name, employeeId, action: 'logout', type: 'logout' };
|
||||
console.log('[LOGOUT] Initiating logout with printData:', printData);
|
||||
|
||||
|
||||
fetch('http://localhost:9100/print', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(printData),
|
||||
method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(printData),
|
||||
})
|
||||
.then((res) => {
|
||||
if (!res.ok) throw new Error('Logout print failed');
|
||||
@ -475,46 +334,9 @@ logout(): void {
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// logout(): void {
|
||||
// const name = localStorage.getItem('userName') || 'Unknown User';
|
||||
// const employeeId = localStorage.getItem('employeeId') || '000000';
|
||||
|
||||
// const printData = { name, employeeId, action: 'logout' };
|
||||
|
||||
// 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');
|
||||
// (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) {
|
||||
this.subscription.unsubscribe();
|
||||
}
|
||||
if (this.subscription) this.subscription.unsubscribe();
|
||||
}
|
||||
|
||||
// Add trackByHorse for use in *ngFor
|
||||
trackByHorse(index: number, item: number): number {
|
||||
return item;
|
||||
}
|
||||
trackByHorse(index: number, item: number): number { return item; }
|
||||
}
|
||||
|
||||
@ -221,7 +221,7 @@
|
||||
|
||||
|
||||
<!-- View RC Modal -->
|
||||
<div class="viewrc-modal-overlay" *ngIf="showViewRc">
|
||||
<!-- <div class="viewrc-modal-overlay" *ngIf="showViewRc">
|
||||
<div class="viewrc-modal-box">
|
||||
<h3 class="viewrc-modal-title">VIEW RC</h3>
|
||||
<div class="viewrc-modal-body">
|
||||
@ -271,6 +271,61 @@
|
||||
</ng-template>
|
||||
</div>
|
||||
|
||||
<div class="viewrc-modal-footer">
|
||||
<button class="viewrc-cancel-btn" (click)="closeViewRcPopup()">CANCEL</button>
|
||||
</div>
|
||||
</div>
|
||||
</div> -->
|
||||
<div class="viewrc-modal-overlay" *ngIf="showViewRc">
|
||||
<div class="viewrc-modal-box">
|
||||
<h3 class="viewrc-modal-title">VIEW RC</h3>
|
||||
<div class="viewrc-modal-body">
|
||||
<ng-container *ngIf="raceCardData && !raceCardData.error; else errorTpl">
|
||||
<p class="top"><strong>📍 Venue:</strong> {{ raceCardData.venue }}</p>
|
||||
<p class="top"><strong>📅 Date:</strong> {{ raceCardData.date }}</p>
|
||||
|
||||
<div class="rc-table-container">
|
||||
<h4>🏇 Race Lists</h4>
|
||||
<table class="rc-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="new">Races</th>
|
||||
<th class="new">Race Numbers</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr *ngFor="let race of raceCardData.raceVenueRaces.races">
|
||||
<td class="table_col">Race {{ race.raceNo }}</td>
|
||||
<td class="table_col1">{{ race.horses.join(', ') }}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="rc-table-container" *ngIf="raceCardData.pools?.comboRaces">
|
||||
<h4>🎯Races</h4>
|
||||
<table class="rc-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="new">Pool</th>
|
||||
<th class="new">Races</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr *ngFor="let pool of objectKeys(raceCardData.pools.comboRaces)">
|
||||
<td class="table_col">{{ pool }}</td>
|
||||
<td class="table_col1">{{ raceCardData.pools.comboRaces[pool].join(', ') }}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</ng-container>
|
||||
|
||||
<ng-template #errorTpl>
|
||||
<p class="error-text">❌ {{ raceCardData?.error }}</p>
|
||||
</ng-template>
|
||||
</div>
|
||||
|
||||
<div class="viewrc-modal-footer">
|
||||
<button class="viewrc-cancel-btn" (click)="closeViewRcPopup()">CANCEL</button>
|
||||
</div>
|
||||
|
||||
@ -441,17 +441,52 @@ ${receiptText}
|
||||
raceCardData: any = null; // ✅ Hold fetched data
|
||||
|
||||
|
||||
constructor(
|
||||
private btcService: BtcService
|
||||
|
||||
) {}
|
||||
// openViewRcPopup() {
|
||||
// const cachedData = localStorage.getItem('rpinfo');
|
||||
|
||||
// if (cachedData) {
|
||||
// this.raceCardData = JSON.parse(cachedData);
|
||||
// console.log('📦 Loaded race card from localStorage:', this.raceCardData);
|
||||
// } else {
|
||||
// this.raceCardData = { error: 'Race card not available locally' };
|
||||
// console.warn('⚠️ No race card data found in localStorage.');
|
||||
// }
|
||||
|
||||
// this.showViewRc = true;
|
||||
// }
|
||||
|
||||
// openViewRcPopup() {
|
||||
// const cachedData = localStorage.getItem('rpinfo');
|
||||
|
||||
// if (cachedData) {
|
||||
// try {
|
||||
// this.raceCardData = JSON.parse(cachedData); // now it's an array
|
||||
// console.log('📦 Loaded race card from localStorage:', this.raceCardData);
|
||||
// } catch (e) {
|
||||
// console.error('Error parsing rpinfo:', e);
|
||||
// this.raceCardData = { error: 'Invalid race card data' };
|
||||
// }
|
||||
// } else {
|
||||
// this.raceCardData = { error: 'Race card not available locally' };
|
||||
// console.warn('⚠️ No race card data found in localStorage.');
|
||||
// }
|
||||
|
||||
// this.showViewRc = true;
|
||||
// }
|
||||
|
||||
openViewRcPopup() {
|
||||
const cachedData = localStorage.getItem('raceCardData');
|
||||
const cachedData = localStorage.getItem('rpinfo');
|
||||
|
||||
if (cachedData) {
|
||||
this.raceCardData = JSON.parse(cachedData);
|
||||
console.log('📦 Loaded race card from localStorage:', this.raceCardData);
|
||||
try {
|
||||
const parsed = JSON.parse(cachedData);
|
||||
this.raceCardData = parsed.structuredRaceCard; // ✅ only keep structured
|
||||
console.log('📦 Loaded structured race card:', this.raceCardData);
|
||||
} catch (e) {
|
||||
console.error('Error parsing rpinfo:', e);
|
||||
this.raceCardData = { error: 'Invalid race card data' };
|
||||
}
|
||||
} else {
|
||||
this.raceCardData = { error: 'Race card not available locally' };
|
||||
console.warn('⚠️ No race card data found in localStorage.');
|
||||
@ -460,6 +495,8 @@ ${receiptText}
|
||||
this.showViewRc = true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
objectKeys = Object.keys;
|
||||
|
||||
closeViewRcPopup() {
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -49,6 +49,8 @@ export class HomeComponent implements OnInit, OnDestroy {
|
||||
|
||||
console.log('🏠 HomeComponent loaded');
|
||||
|
||||
|
||||
|
||||
this.btcService.getAllRaceEventsToday().subscribe({
|
||||
next: (response: HttpResponse<HorseRaceModel[]>) => {
|
||||
const horseRaceData = response.body;
|
||||
@ -64,13 +66,13 @@ export class HomeComponent implements OnInit, OnDestroy {
|
||||
},
|
||||
});
|
||||
|
||||
const raceCardCached = localStorage.getItem('raceCardData');
|
||||
const raceCardCached = localStorage.getItem('rpinfo');
|
||||
if (!raceCardCached) {
|
||||
this.btcService.getRaceCard().subscribe({
|
||||
next: (res) => {
|
||||
const raceCardData = res.body;
|
||||
console.log('📦 Race card preloaded:', raceCardData);
|
||||
localStorage.setItem('raceCardData', JSON.stringify(raceCardData));
|
||||
localStorage.setItem('rpinfo', JSON.stringify(raceCardData));
|
||||
this.updateRunnerCount(0);
|
||||
},
|
||||
error: (err) => {
|
||||
@ -118,7 +120,7 @@ export class HomeComponent implements OnInit, OnDestroy {
|
||||
}
|
||||
|
||||
private updateRunnerCount(raceIdx: number) {
|
||||
const raceCardData = JSON.parse(localStorage.getItem('raceCardData') || '{}');
|
||||
const raceCardData = JSON.parse(localStorage.getItem('rpinfo') || '{}');
|
||||
const race = raceCardData?.raceVenueRaces?.races?.[raceIdx] || [];
|
||||
const runnerCount = Array.isArray(race) ? race.length : 12;
|
||||
if (!raceCardData?.raceVenueRaces?.races?.[raceIdx]) {
|
||||
|
||||
@ -213,6 +213,7 @@ export class LoginComponent implements OnInit, OnDestroy {
|
||||
this.passwordStatus = true;
|
||||
}
|
||||
//--------------------------------------NEW LOGIN LOGIC ----------------------------------------//
|
||||
//--------------------------------------NEW LOGIN LOGIC ----------------------------------------//
|
||||
async onSubmit(): Promise<void> {
|
||||
if (this.loginForm.invalid) {
|
||||
this.loginForm.markAllAsTouched();
|
||||
@ -239,103 +240,37 @@ async onSubmit(): Promise<void> {
|
||||
const btid = this.btcService.btid;
|
||||
console.log("📦 BTID from file (via service):", btid);
|
||||
|
||||
// ✅ Prepare print data
|
||||
const printData = {
|
||||
name: userName,
|
||||
employeeId: employeeId,
|
||||
// btid: btid || "unknown",
|
||||
action: 'login',
|
||||
type: 'login'
|
||||
};
|
||||
|
||||
console.log(printData.name);
|
||||
console.log(printData.employeeId);
|
||||
//console.log(printData.btid);
|
||||
console.log(btid);
|
||||
|
||||
// ✅ Store in localStorage
|
||||
localStorage.setItem('userName', userName);
|
||||
localStorage.setItem('employeeId', employeeId);
|
||||
localStorage.setItem('password', password);
|
||||
localStorage.setItem('btid', btid || "unknown");
|
||||
|
||||
// ✅ Print first — login only if printing succeeds
|
||||
// fetch('http://localhost:9100/print', {
|
||||
// method: 'POST',
|
||||
// headers: { 'Content-Type': 'application/json' },
|
||||
// body: JSON.stringify(printData),
|
||||
// })
|
||||
// .then((res) => {
|
||||
// if (!res.ok) throw new Error('Print failed');
|
||||
// console.log('🖨️ Print successful');
|
||||
// ✅ Fetch race card after login success
|
||||
this.btcService
|
||||
.fetchRaceCard("021804111066", password, btid || "0483") // pass correct payload here
|
||||
.subscribe({
|
||||
next: (rpinfo) => {
|
||||
console.log("📦 Race Card:", rpinfo);
|
||||
|
||||
// ✅ Only here we allow login
|
||||
// Save in localStorage for later use
|
||||
localStorage.setItem('rpinfo', JSON.stringify(rpinfo));
|
||||
|
||||
// ✅ Navigate once race card stored
|
||||
(window as any).electronAPI?.openSecondScreen?.();
|
||||
this.router.navigate(['/home']);
|
||||
// })
|
||||
// .catch((err) => {
|
||||
// console.error('‼️ Print failed', err);
|
||||
// this.loginError = 'Login failed: printing service unavailable.';
|
||||
// this.passwordStatus = false; // reset status
|
||||
// });
|
||||
},
|
||||
error: (err) => {
|
||||
console.error("‼️ Failed to fetch race card", err);
|
||||
this.loginError = "Could not load race card.";
|
||||
}
|
||||
});
|
||||
},
|
||||
error: () => {
|
||||
this.loginError = 'Invalid login credentials';
|
||||
}
|
||||
});
|
||||
}
|
||||
//-------------------------NEW LOGIN ENDS HERE -------------------------------------------------//
|
||||
|
||||
|
||||
// async onSubmit(): Promise<void> {
|
||||
// if (this.loginForm.invalid) {
|
||||
// this.loginForm.markAllAsTouched();
|
||||
// return;
|
||||
// }
|
||||
|
||||
// const { email, password } = this.loginForm.value;
|
||||
|
||||
// // ✅ Await service (since it’s async)
|
||||
// (await this.btcService.userLogin(email, password)).subscribe({
|
||||
// next: (response) => {
|
||||
// const employee = response.body;
|
||||
// console.log('🧠 Raw employee response:', employee);
|
||||
|
||||
// const userName = employee?.userName || 'Unknown User';
|
||||
// const employeeId = employee?.userIdNumber || email;
|
||||
|
||||
// console.log('✅ Parsed name:', userName);
|
||||
// console.log('✅ Parsed ID:', employeeId);
|
||||
|
||||
// this.passwordStatus = true;
|
||||
|
||||
// // ✅ Get the BTID the service fetched
|
||||
// const btid = this.btcService.btid;
|
||||
// console.log("📦 BTID from file (via service):", btid);
|
||||
|
||||
// // Prepare print data
|
||||
// const printData = {
|
||||
// name: userName,
|
||||
// employeeId: employeeId,
|
||||
// action: 'login',
|
||||
// type: 'login'
|
||||
// };
|
||||
|
||||
// // ✅ Store in localStorage
|
||||
// localStorage.setItem('userName', userName);
|
||||
// localStorage.setItem('employeeId', employeeId);
|
||||
// localStorage.setItem('password', password);
|
||||
// localStorage.setItem('btid', btid || "unknown");
|
||||
|
||||
// // ✅ Open second screen + navigate
|
||||
// (window as any).electronAPI?.openSecondScreen?.();
|
||||
// this.router.navigate(['/home']);
|
||||
// },
|
||||
// error: () => {
|
||||
// this.loginError = 'Invalid login credentials';
|
||||
// }
|
||||
// });
|
||||
// }
|
||||
|
||||
showConfirmModal : boolean = false;
|
||||
|
||||
|
||||
@ -1,23 +1,57 @@
|
||||
import { HttpClient, HttpHeaders } from '@angular/common/http';
|
||||
import { Injectable } from '@angular/core';
|
||||
import { ApplicationHttpRouts } from '../constants/http-routs';
|
||||
// import { HttpClient, HttpHeaders } from '@angular/common/http';
|
||||
// import { Injectable } from '@angular/core';
|
||||
// import { ApplicationHttpRouts } from '../constants/http-routs';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
})
|
||||
// @Injectable({
|
||||
// providedIn: 'root',
|
||||
// })
|
||||
|
||||
// // export class BtcService {
|
||||
// // constructor(private http: HttpClient) {}
|
||||
// // btid: string | null = null;
|
||||
// // //user login
|
||||
// // public userLogin(employeeId: string, password: string) {
|
||||
// // console.log('Login route ' + ApplicationHttpRouts.LOG_IN);
|
||||
// // this.btid = localStorage.getItem('btid');
|
||||
// // if (this.btid) {
|
||||
// // employeeId += "," + this.btid;
|
||||
// // } else {
|
||||
// // employeeId += ",null"; // or just "," if you don’t want "null"
|
||||
// // }
|
||||
// // return this.http.get<any>(ApplicationHttpRouts.LOG_IN, {
|
||||
// // headers: this.basicAuthCredentialsBuilder(employeeId, password),
|
||||
// // withCredentials: true,
|
||||
// // observe: 'response',
|
||||
// // });
|
||||
// // }
|
||||
|
||||
// export class BtcService {
|
||||
// constructor(private http: HttpClient) {}
|
||||
// btid: string | null = null;
|
||||
|
||||
// // user login
|
||||
// public userLogin(employeeId: string, password: string) {
|
||||
// public async userLogin(employeeId: string, password: string) {
|
||||
// console.log('Login route ' + ApplicationHttpRouts.LOG_IN);
|
||||
// this.btid = localStorage.getItem('btid');
|
||||
// if (this.btid) {
|
||||
// employeeId += "," + this.btid;
|
||||
|
||||
// try {
|
||||
// if ((window as any).electronAPI?.getBtid) {
|
||||
// this.btid = await (window as any).electronAPI.getBtid();
|
||||
// } else {
|
||||
// employeeId += ",null"; // or just "," if you don’t want "null"
|
||||
// console.warn('Electron API not available — fallback to null');
|
||||
// this.btid = null;
|
||||
// }
|
||||
// } catch (err) {
|
||||
// console.error('Error fetching BTID:', err);
|
||||
// this.btid = null;
|
||||
// }
|
||||
|
||||
// // Append BTID after comma
|
||||
// if (this.btid) {
|
||||
// employeeId += ',' + this.btid;
|
||||
// } else {
|
||||
// employeeId += ',null';
|
||||
// }
|
||||
|
||||
// return this.http.get<any>(ApplicationHttpRouts.LOG_IN, {
|
||||
// headers: this.basicAuthCredentialsBuilder(employeeId, password),
|
||||
// withCredentials: true,
|
||||
@ -25,9 +59,59 @@ import { ApplicationHttpRouts } from '../constants/http-routs';
|
||||
// });
|
||||
// }
|
||||
|
||||
// // what goes to the backend for auth ... is the same as postman's basic auth
|
||||
// private basicAuthCredentialsBuilder(
|
||||
// employeeOrUserId: string,
|
||||
// password: string
|
||||
// ): HttpHeaders {
|
||||
// console.log(`username and password${employeeOrUserId} p = ${password}`);
|
||||
|
||||
// return new HttpHeaders().set(
|
||||
// 'Authorization',
|
||||
// 'basic ' + window.btoa(employeeOrUserId + ':' + password)
|
||||
// );
|
||||
// }
|
||||
|
||||
// public pingLiveStatus() {
|
||||
// return this.http.get<any>(ApplicationHttpRouts.PING, {
|
||||
// withCredentials: true,
|
||||
// observe: 'response',
|
||||
// responseType: 'text' as 'json',
|
||||
// });
|
||||
// }
|
||||
|
||||
// // Fetch all race events today
|
||||
|
||||
// public getAllRaceEventsToday() {
|
||||
// return this.http.get<any>(ApplicationHttpRouts.RACE_EVENTS_TODAY, {
|
||||
// withCredentials: true,
|
||||
// observe: 'response',
|
||||
// responseType: 'json',
|
||||
// });
|
||||
// }
|
||||
|
||||
// public getRaceCard(){
|
||||
// return this.http.get<any>(ApplicationHttpRouts.RACE_CARD, {
|
||||
// withCredentials: true,
|
||||
// observe: 'response',
|
||||
// responseType: 'json',
|
||||
// })
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
import { HttpClient, HttpHeaders } from '@angular/common/http';
|
||||
import { Injectable } from '@angular/core';
|
||||
import { ApplicationHttpRouts } from '../constants/http-routs';
|
||||
import { of,Observable, tap } from 'rxjs';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
})
|
||||
export class BtcService {
|
||||
constructor(private http: HttpClient) {}
|
||||
btid: string | null = null;
|
||||
private raceCard: any = null; // cache race card in memory
|
||||
|
||||
// user login
|
||||
public async userLogin(employeeId: string, password: string) {
|
||||
@ -59,12 +143,12 @@ export class BtcService {
|
||||
});
|
||||
}
|
||||
|
||||
// what goes to the backend for auth ... is the same as postman's basic auth
|
||||
// basic auth header
|
||||
private basicAuthCredentialsBuilder(
|
||||
employeeOrUserId: string,
|
||||
password: string
|
||||
): HttpHeaders {
|
||||
console.log(`username and password${employeeOrUserId} p = ${password}`);
|
||||
console.log(`username and password = ${employeeOrUserId} p = ${password}`);
|
||||
|
||||
return new HttpHeaders().set(
|
||||
'Authorization',
|
||||
@ -72,6 +156,7 @@ export class BtcService {
|
||||
);
|
||||
}
|
||||
|
||||
// Ping backend
|
||||
public pingLiveStatus() {
|
||||
return this.http.get<any>(ApplicationHttpRouts.PING, {
|
||||
withCredentials: true,
|
||||
@ -81,7 +166,6 @@ export class BtcService {
|
||||
}
|
||||
|
||||
// Fetch all race events today
|
||||
|
||||
public getAllRaceEventsToday() {
|
||||
return this.http.get<any>(ApplicationHttpRouts.RACE_EVENTS_TODAY, {
|
||||
withCredentials: true,
|
||||
@ -90,11 +174,75 @@ export class BtcService {
|
||||
});
|
||||
}
|
||||
|
||||
public getRaceCard(){
|
||||
return this.http.get<any>(ApplicationHttpRouts.RACE_CARD, {
|
||||
withCredentials: true,
|
||||
observe: 'response',
|
||||
responseType: 'json',
|
||||
/**
|
||||
* Fetch Race Card from backend (POST /download/rpinfo)
|
||||
* Stores result in memory for reuse
|
||||
// */
|
||||
// public fetchRaceCard(
|
||||
// opCard: string,
|
||||
// password: string,
|
||||
// btId: string,
|
||||
// usrId: string = '',
|
||||
// btMake: number = 0
|
||||
// ): Observable<any> {
|
||||
// const payload = { opCard, password, btId, usrId, btMake };
|
||||
|
||||
// return this.http
|
||||
// .post<any>('http://localhost:8082/download/rpinfo', payload)
|
||||
// .pipe(
|
||||
// tap((data) => {
|
||||
// console.log('📦 Race Card fetched:', data);
|
||||
// this.raceCard = data; // cache it
|
||||
// })
|
||||
// );
|
||||
// }
|
||||
|
||||
// /**
|
||||
// * Return cached race card (if available)
|
||||
// */
|
||||
// public getRaceCard(): any {
|
||||
// return this.raceCard;
|
||||
// }
|
||||
|
||||
|
||||
public fetchRaceCard(
|
||||
opCard: string,
|
||||
password: string,
|
||||
btId: string,
|
||||
usrId: string = '',
|
||||
btMake: number = 0
|
||||
): Observable<any> {
|
||||
const payload = { opCard, password, btId, usrId, btMake };
|
||||
|
||||
return this.http
|
||||
.post<any>('http://localhost:8082/download/rpinfo', payload)
|
||||
.pipe(
|
||||
tap((data) => {
|
||||
console.log('📦 Race Card fetched:', data);
|
||||
this.raceCard = data; // store in memory
|
||||
localStorage.setItem('rpinfo', JSON.stringify(data)); // store in localStorage
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return cached race card:
|
||||
* - from memory (fastest)
|
||||
* - fallback to localStorage (if reloaded)
|
||||
*/
|
||||
public getRaceCard(): Observable<any> {
|
||||
if (this.raceCard) {
|
||||
return of(this.raceCard);
|
||||
}
|
||||
|
||||
const cached = localStorage.getItem('rpinfo');
|
||||
if (cached) {
|
||||
this.raceCard = JSON.parse(cached);
|
||||
return of(this.raceCard);
|
||||
}
|
||||
|
||||
// Nothing available, return empty object
|
||||
return of(null);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -3,50 +3,23 @@ version: '3.8'
|
||||
|
||||
# Define the services for our application stack
|
||||
services:
|
||||
# PostgreSQL database service
|
||||
postgres:
|
||||
# Using the official PostgreSQL base image.
|
||||
# 'postgres:16' is recommended for a stable, recent version.
|
||||
# You can use 'postgres:latest' for the very newest, but versions like 13, 14, 15, 16 are common.
|
||||
image: postgres:16 # Or postgres:latest, postgres:13-alpine, etc.
|
||||
container_name: postgres_db # Assign a friendly name to the container
|
||||
environment:
|
||||
# --- CRITICAL: These settings will ONLY take effect if ./dbData directory is EMPTY on first run ---
|
||||
POSTGRES_DB: horse # Your database name
|
||||
POSTGRES_USER: postgres # Set to 'postgres', the default superuser for the official image
|
||||
POSTGRES_PASSWORD: root # Your desired password for the 'postgres' user
|
||||
# --------------------------------------------------------------------------------------------------
|
||||
ports:
|
||||
- "5434:5432" # Map host port 5434 to container port 5432
|
||||
volumes:
|
||||
# Using a bind mount. You MUST delete the ./dbData directory manually if you change user/pass/db.
|
||||
# This directory MUST be empty when the container first starts to trigger initialization.
|
||||
- ./dbData:/var/lib/postgresql/data # Persist PostgreSQL data to a local directory
|
||||
# Added command for more verbose logging during startup (optional, but highly recommended here)
|
||||
command: postgres -c log_statement=all
|
||||
networks:
|
||||
- app_network # Connect to our custom application network
|
||||
# networks:
|
||||
# - app_network # Connect to our custom application network
|
||||
|
||||
|
||||
spring:
|
||||
#image: mathewfrancisv/spring_back_postgres:v1.0.0
|
||||
image: mathewfrancisv/btc_cezen_backend:v1.1.6
|
||||
image: mathewfrancisv/btc_cezen_backend:v2.3.0
|
||||
container_name: spring_app
|
||||
ports:
|
||||
- "8083:8080"
|
||||
environment:
|
||||
# jdbc:postgresql://localhost:5432/horse
|
||||
# SPRING_DATASOURCE_URL: jdbc:postgresql://postgres:5432/horse
|
||||
SPRING_DATASOURCE_URL: jdbc:postgresql://postgres:5432/horse
|
||||
SPRING_DATASOURCE_USERNAME: postgres # Ensure this matches POSTGRES_USER
|
||||
SPRING_DATASOURCE_PASSWORD: root # Ensure this matches POSTGRES_PASSWORD
|
||||
SPRING_DATASOURCE_CORSIP: http://10.74.231.61:4200
|
||||
SPRING_DATASOURCE_CORSIP: http://10.236.119.124:4200
|
||||
#network_mode: host
|
||||
networks:
|
||||
- app_network
|
||||
depends_on:
|
||||
- postgres
|
||||
# depends_on:
|
||||
# - postgres
|
||||
|
||||
# Angular frontend application service
|
||||
angular-dev:
|
||||
|
||||
Loading…
Reference in New Issue
Block a user