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 ae763e4..7266a6f 100644 --- a/btc-UI/src/app/components/selection.service/selection.service.ts +++ b/btc-UI/src/app/components/selection.service/selection.service.ts @@ -32,6 +32,11 @@ export class SelectionService { const numbers = updated.numbers || []; const isBoxed = updated.isBoxed ?? false; + // Enforce ticket number limit (1-100) + if (value > 100) { + updated.value = 100; + } + updated.total = 0; if ((numbers.length > 0 || numbers.includes('F')) && value > 0 && label) { @@ -111,7 +116,7 @@ export class SelectionService { const nonFieldNumbers = (group1_is_field ? group2 : group1).filter(n => typeof n === 'number') as number[]; const pairSet = new Set(); const fieldNumbers = fieldSide.length > 0 ? fieldSide : Array.from({ length: 12 }, (_, i) => i + 1); - for (let j of nonFieldNumbers) { + for (let j of nonFieldNumbers) { for (let i of fieldNumbers) { if (i !== j) { let min = Math.min(i, j); @@ -215,7 +220,10 @@ export class SelectionService { finalizeCurrentRow() { const completed = this.currentRow.value; if (!completed.label || completed.numbers.length === 0 || completed.value <= 0) return; - this.selections.next([...this.selections.value, { ...completed }]); + const currentSelections = this.selections.value; + const totalAmount = currentSelections.reduce((sum, sel) => sum + sel.total, 0); + if (totalAmount + completed.total > 5000) return; + this.selections.next([...currentSelections, { ...completed }]); this.currentRow.next({ label: '', numbers: [], value: 0, total: 0, isBoxed: false }); } diff --git a/btc-UI/src/app/components/touch-pad-menu/touch-pad-menu.component.css b/btc-UI/src/app/components/touch-pad-menu/touch-pad-menu.component.css index 434afbc..a814ea6 100755 --- a/btc-UI/src/app/components/touch-pad-menu/touch-pad-menu.component.css +++ b/btc-UI/src/app/components/touch-pad-menu/touch-pad-menu.component.css @@ -283,8 +283,9 @@ button { > div:last-child button:nth-child(1) { min-width: 20%; - margin-right: 4rem; - margin-left: 1rem; + /* margin-right: 4rem; */ + margin-left: 0px; + padding: 1px; } .touch-pad-container @@ -682,4 +683,55 @@ button.ready-to-print { .pool-replace-btn{ background-color: #125cac; color: white; -} \ No newline at end of file +} +.limit-overlay { + position: fixed; + top: 0; + left: 0; + width: 100vw; + height: 100vh; + background: rgba(0, 0, 0, 0.15); + z-index: 2000; +} + +.limit-dialog { + background: #ffffff; + border-radius: 8px; + padding: 24px 16px; + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + min-width: 400px; + box-shadow: 0 3px 16px rgba(0, 0, 0, 0.25); +} + +.limit-title { + font-weight: bold; + text-align: center; + font-size: 1.25rem; + margin-bottom: 1.25rem; +} + +.limit-message { + text-align: center; + margin-bottom: 1.25rem; +} + +.limit-button { + width: 25%; + margin-left: 38%; + padding: 10px 0; + font-size: 1rem; + font-weight: 500; + background-color: #007bff; + color: white; + border: none; + border-radius: 4px; + cursor: pointer; + transition: background-color 0.2s ease; +} + +.limit-button:hover { + background-color: #0056b3; +} diff --git a/btc-UI/src/app/components/touch-pad-menu/touch-pad-menu.component.html b/btc-UI/src/app/components/touch-pad-menu/touch-pad-menu.component.html index 6f590c2..d916233 100755 --- a/btc-UI/src/app/components/touch-pad-menu/touch-pad-menu.component.html +++ b/btc-UI/src/app/components/touch-pad-menu/touch-pad-menu.component.html @@ -88,7 +88,6 @@
-
@@ -110,7 +109,6 @@
-
@@ -225,4 +223,28 @@ - \ No newline at end of file + + + +
+
+
+ Limit Reached +
+

+ Total amount limit of 5000 rupees has been reached. No further selections can be made. +

+ +
+
+ + \ No newline at end of file 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 8bc9b16..cea60ca 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 @@ -1,6 +1,8 @@ -import { Component, Input, OnInit } from '@angular/core'; +import { Component, Input, OnInit, OnDestroy } from '@angular/core'; import { CommonModule } from '@angular/common'; import { SelectionService } from '../selection.service/selection.service'; +import { Subscription } from 'rxjs'; +import { SelectionData } from '../selection.service/selection.service'; @Component({ selector: 'app-touch-pad-menu', @@ -9,7 +11,7 @@ import { SelectionService } from '../selection.service/selection.service'; templateUrl: './touch-pad-menu.component.html', styleUrls: ['./touch-pad-menu.component.css'] }) -export class TouchPadMenuComponent implements OnInit { +export class TouchPadMenuComponent implements OnInit, OnDestroy { @Input() ticketingActive: boolean = false; public twoGroupLabels = ['FOR', 'QUI']; @@ -34,6 +36,8 @@ export class TouchPadMenuComponent implements OnInit { calculatorOpen = false; calcDisplay = ''; maxRowsReached: boolean = false; + totalAmountLimitReached: boolean = false; + showLimitPopup: boolean = false; disabledLabels: string[] = ['SHW', 'SJP', '.']; @@ -63,14 +67,37 @@ export class TouchPadMenuComponent implements OnInit { // TRE popup trePopupVisible = false; + private currentRowSubscription: Subscription | null = null; + private selectionsSubscription: Subscription | null = null; + private currentTotal: number = 0; + private currentSelections: SelectionData[] = []; + constructor(private selectionService: SelectionService) {} ngOnInit() { this.labelRowsFlat = this.labelRows.flat(); this.numbersFlat = this.numberRows.flat(); - this.selectionService.selections$.subscribe(selections => { + this.selectionsSubscription = this.selectionService.selections$.subscribe(selections => { + this.currentSelections = selections; this.maxRowsReached = selections.length >= 5; + const totalAmount = selections.reduce((sum, selection) => sum + selection.total, 0); + this.totalAmountLimitReached = totalAmount >= 5000; + if (this.totalAmountLimitReached) { + this.showLimitPopup = true; + } }); + this.currentRowSubscription = this.selectionService.currentRow$.subscribe(row => { + this.currentTotal = row.total; + }); + } + + ngOnDestroy() { + if (this.currentRowSubscription) { + this.currentRowSubscription.unsubscribe(); + } + if (this.selectionsSubscription) { + this.selectionsSubscription.unsubscribe(); + } } get labelRows() { @@ -140,13 +167,17 @@ export class TouchPadMenuComponent implements OnInit { } isLabelDisabled(label: string): boolean { - return this.disabledLabels.includes(label); + return this.disabledLabels.includes(label) || this.totalAmountLimitReached; } selectLabel(label: string) { + if (this.totalAmountLimitReached) { + this.showLimitPopup = true; + return; + } if (label === 'TRE') { this.trePopupVisible = true; - return; // Stop further execution until popup interaction + return; } this.selectedLabel = label; this.selectedNumbers = []; @@ -171,7 +202,7 @@ export class TouchPadMenuComponent implements OnInit { } selectNumber(number: number) { - if (!this.selectedLabel) return; + if (!this.selectedLabel || this.totalAmountLimitReached) return; // TAN Box mode: freestyle selection with dash-separated format if (this.selectedLabel === 'TAN' && this.isBoxed) { @@ -264,7 +295,7 @@ export class TouchPadMenuComponent implements OnInit { if (this.selectedLabel === 'TAN' || this.multiLegLabels.includes(this.selectedLabel || '') || this.twoGroupLabels.includes(this.selectedLabel || '')) { return false; } - return this.selectedNumbers.includes(number); + return this.selectedNumbers.includes(number) || this.totalAmountLimitReached; } onPadEnter() { @@ -311,11 +342,14 @@ export class TouchPadMenuComponent implements OnInit { } enterPadVal(key: string) { - if (!this.numericPadEnabled) return; + if (!this.numericPadEnabled || this.totalAmountLimitReached) return; 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; } @@ -335,6 +369,11 @@ export class TouchPadMenuComponent implements OnInit { } print() { + const selectionsTotal = this.currentSelections.reduce((sum, sel) => sum + sel.total, 0); + if (selectionsTotal + this.currentTotal > 5000) { + this.showLimitPopup = true; + return; + } this.selectionService.finalizeCurrentRow(); this.resetSelections(); } @@ -367,6 +406,7 @@ export class TouchPadMenuComponent implements OnInit { } toggleBoxMode() { + if (this.totalAmountLimitReached) return; this.isBoxed = !this.isBoxed; const value = parseFloat(this.padValue) || 0; // For TAN Box mode, reset to freestyle selection @@ -536,6 +576,7 @@ export class TouchPadMenuComponent implements OnInit { } canUseField(): boolean { + if (this.totalAmountLimitReached) return false; if (this.selectedLabel === 'FOR' || this.selectedLabel === 'QUI') { if (!this.isFirstGroupComplete && this.firstGroup.length === 0) { return true; @@ -562,6 +603,7 @@ export class TouchPadMenuComponent implements OnInit { } openFieldModal() { + if (this.totalAmountLimitReached) return; if (['FOR', 'QUI', 'TAN'].includes(this.selectedLabel || '') || this.multiLegLabels.includes(this.selectedLabel || '')) { this.handleFieldForSpecialLabels(); } else { @@ -647,6 +689,7 @@ export class TouchPadMenuComponent implements OnInit { } openPoolReplaceModal() { + if (this.totalAmountLimitReached) return; this.poolReplaceOpen = true; } @@ -681,4 +724,8 @@ export class TouchPadMenuComponent implements OnInit { closeTrePopup() { this.trePopupVisible = false; } + + closeLimitPopup() { + this.showLimitPopup = false; + } } \ No newline at end of file