Compare commits

..

No commits in common. "e66842d5109f7490c5c46918947665bb7416801a" and "0bc77c0124271812e87910d1799fbd94f3abecc2" have entirely different histories.

4 changed files with 36 additions and 219 deletions

View File

@ -32,11 +32,6 @@ 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) {
@ -116,7 +111,7 @@ export class SelectionService {
const nonFieldNumbers = (group1_is_field ? group2 : group1).filter(n => typeof n === 'number') as number[];
const pairSet = new Set<string>();
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);
@ -220,10 +215,7 @@ export class SelectionService {
finalizeCurrentRow() {
const completed = this.currentRow.value;
if (!completed.label || completed.numbers.length === 0 || completed.value <= 0) return;
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.selections.next([...this.selections.value, { ...completed }]);
this.currentRow.next({ label: '', numbers: [], value: 0, total: 0, isBoxed: false });
}

View File

@ -283,9 +283,8 @@ button {
> div:last-child
button:nth-child(1) {
min-width: 20%;
/* margin-right: 4rem; */
margin-left: 0px;
padding: 1px;
margin-right: 4rem;
margin-left: 1rem;
}
.touch-pad-container
@ -683,55 +682,4 @@ button.ready-to-print {
.pool-replace-btn{
background-color: #125cac;
color: white;
}
.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;
}
}

View File

@ -88,6 +88,7 @@
<div class="col-2 column">
<div class="p-2 rounded wrapper-pad" style="background-color: #f1f1f1df">
<div class="row gx-1 gy-1 custom-touchpad">
<div class="col-6">
<button class="btn btn-secondary w-100 number-button" [disabled]="!numericPadEnabled" (click)="enterPadVal('0')">0</button>
</div>
@ -109,6 +110,7 @@
<div class="col-6">
<button class="btn btn-secondary w-100 number-button" [disabled]="!canPrint" (click)="print()">Print</button>
</div>
</div>
</div>
</div>
@ -179,72 +181,29 @@
</div>
</div>
<!-- 🟩 POOL REPLACE Modal -->
<div
id="poolReplaceModal"
class="pool-replace-modal"
[style.display]="poolReplaceOpen ? 'block' : 'none'"
(click)="closePoolReplaceModal()"
>
<div class="pool-replace-content" (click)="$event.stopPropagation()">
<div class="pool-replace-header">
<span class="close-btn" (click)="closePoolReplaceModal()">&times;</span>
<h5>POOL REPLACE</h5>
</div>
<div class="pool-replace-body">
<p>Select an option to replace the pool:</p>
<button class="btn btn-light">WIN</button>
<button class="btn btn-light">SHP</button>
<button class="btn btn-light">THP</button>
<button class="btn btn-light">PLC</button>
<button class="btn btn-light">SHW</button>
</div>
<div class="pool-replace-footer">
<button class="btn btn-secondary" (click)="closePoolReplaceModal()">Cancel</button>
<button class="btn btn-primary">Confirm</button>
</div>
</div>
</div>
<!-- 🟦 TRE Popup Modal -->
<div
class="tre-popup-backdrop"
*ngIf="trePopupVisible"
style="position: fixed; top: 0; left: 0; width: 100vw; height: 100vh; background: rgba(0,0,0,0.15); z-index: 2000;"
(click)="closeTrePopup()"
>
<div
class="tre-popup-dialog"
(click)="$event.stopPropagation()"
style="background: #fff; border-radius: 8px; padding: 24px 16px; position: absolute; top: 30%; left: 50%; transform: translate(-50%, -50%); min-width: 700px;margin-top: 10%; box-shadow: 0 3px 16px rgba(0,0,0,0.25);"
>
<div style="font-weight: bold; text-align: center; font-size: 1.25rem; margin-bottom: 1.25rem;">Select TRE</div>
<button class="btn btn-primary my-2 w-100" (click)="treButtonClick(1)">TRB1</button>
<button class="btn btn-primary my-2 w-100" (click)="treButtonClick(2)">TRB2</button>
<button class="btn btn-secondary my-2 w-100" style="opacity: 0.6; pointer-events: none;">TRB3</button>
</div>
</div>
<!-- 🟥 Limit Popup Modal -->
<div
class="limit-overlay"
*ngIf="showLimitPopup"
style="position: fixed; top: 0; left: 0; width: 100vw; height: 100vh; background: rgba(0,0,0,0.15); z-index: 2000;"
(click)="closeLimitPopup()"
<!-- 🟩 POOL REPLACE Modal -->
<div
id="poolReplaceModal"
class="pool-replace-modal"
[style.display]="poolReplaceOpen ? 'block' : 'none'"
(click)="closePoolReplaceModal()"
>
<div
class="limit-dialog"
(click)="$event.stopPropagation()"
style="background: #fff; 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);height: 200px;"
>
<div class="limit-title" style="font-weight: bold; text-align: center; font-size: 1.25rem; margin-bottom: 1.25rem;">
Limit Reached
<div class="pool-replace-content" (click)="$event.stopPropagation()">
<div class="pool-replace-header">
<span class="close-btn" (click)="closePoolReplaceModal()">&times;</span>
<h5>POOL REPLACE</h5>
</div>
<div class="pool-replace-body">
<p>Select an option to replace the pool:</p>
<button class="btn btn-light">WIN</button>
<button class="btn btn-light">SHP</button>
<button class="btn btn-light">THP</button>
<button class="btn btn-light">PLC</button>
<button class="btn btn-light">SHW</button>
</div>
<div class="pool-replace-footer">
<button class="btn btn-secondary" (click)="closePoolReplaceModal()">Cancel</button>
<button class="btn btn-primary">Confirm</button>
</div>
<p class="limit-message" style="text-align: center; margin-bottom: 1.25rem;">
Total amount limit of 5000 rupees has been reached. No further selections can be made.
</p>
<button class="limit-button" (click)="closeLimitPopup()">OK</button>
</div>
</div>
</div>

View File

@ -1,8 +1,6 @@
import { Component, Input, OnInit, OnDestroy } from '@angular/core';
import { Component, Input, OnInit } 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',
@ -11,7 +9,7 @@ import { SelectionData } from '../selection.service/selection.service';
templateUrl: './touch-pad-menu.component.html',
styleUrls: ['./touch-pad-menu.component.css']
})
export class TouchPadMenuComponent implements OnInit, OnDestroy {
export class TouchPadMenuComponent implements OnInit {
@Input() ticketingActive: boolean = false;
public twoGroupLabels = ['FOR', 'QUI'];
@ -36,8 +34,6 @@ export class TouchPadMenuComponent implements OnInit, OnDestroy {
calculatorOpen = false;
calcDisplay = '';
maxRowsReached: boolean = false;
totalAmountLimitReached: boolean = false;
showLimitPopup: boolean = false;
disabledLabels: string[] = ['SHW', 'SJP', '.'];
@ -64,40 +60,14 @@ export class TouchPadMenuComponent implements OnInit, OnDestroy {
// POOL REPLACE modal
poolReplaceOpen = false;
// 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.selectionsSubscription = this.selectionService.selections$.subscribe(selections => {
this.currentSelections = selections;
this.selectionService.selections$.subscribe(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() {
@ -167,18 +137,10 @@ export class TouchPadMenuComponent implements OnInit, OnDestroy {
}
isLabelDisabled(label: string): boolean {
return this.disabledLabels.includes(label) || this.totalAmountLimitReached;
return this.disabledLabels.includes(label);
}
selectLabel(label: string) {
if (this.totalAmountLimitReached) {
this.showLimitPopup = true;
return;
}
if (label === 'TRE') {
this.trePopupVisible = true;
return;
}
this.selectedLabel = label;
this.selectedNumbers = [];
this.padValue = '';
@ -202,7 +164,7 @@ export class TouchPadMenuComponent implements OnInit, OnDestroy {
}
selectNumber(number: number) {
if (!this.selectedLabel || this.totalAmountLimitReached) return;
if (!this.selectedLabel) return;
// TAN Box mode: freestyle selection with dash-separated format
if (this.selectedLabel === 'TAN' && this.isBoxed) {
@ -295,7 +257,7 @@ export class TouchPadMenuComponent implements OnInit, OnDestroy {
if (this.selectedLabel === 'TAN' || this.multiLegLabels.includes(this.selectedLabel || '') || this.twoGroupLabels.includes(this.selectedLabel || '')) {
return false;
}
return this.selectedNumbers.includes(number) || this.totalAmountLimitReached;
return this.selectedNumbers.includes(number);
}
onPadEnter() {
@ -342,14 +304,11 @@ export class TouchPadMenuComponent implements OnInit, OnDestroy {
}
enterPadVal(key: string) {
if (!this.numericPadEnabled || this.totalAmountLimitReached) return;
if (!this.numericPadEnabled) 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;
}
@ -369,11 +328,6 @@ export class TouchPadMenuComponent implements OnInit, OnDestroy {
}
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();
}
@ -406,7 +360,6 @@ export class TouchPadMenuComponent implements OnInit, OnDestroy {
}
toggleBoxMode() {
if (this.totalAmountLimitReached) return;
this.isBoxed = !this.isBoxed;
const value = parseFloat(this.padValue) || 0;
// For TAN Box mode, reset to freestyle selection
@ -576,7 +529,6 @@ export class TouchPadMenuComponent implements OnInit, OnDestroy {
}
canUseField(): boolean {
if (this.totalAmountLimitReached) return false;
if (this.selectedLabel === 'FOR' || this.selectedLabel === 'QUI') {
if (!this.isFirstGroupComplete && this.firstGroup.length === 0) {
return true;
@ -603,7 +555,6 @@ export class TouchPadMenuComponent implements OnInit, OnDestroy {
}
openFieldModal() {
if (this.totalAmountLimitReached) return;
if (['FOR', 'QUI', 'TAN'].includes(this.selectedLabel || '') || this.multiLegLabels.includes(this.selectedLabel || '')) {
this.handleFieldForSpecialLabels();
} else {
@ -689,43 +640,10 @@ export class TouchPadMenuComponent implements OnInit, OnDestroy {
}
openPoolReplaceModal() {
if (this.totalAmountLimitReached) return;
this.poolReplaceOpen = true;
}
closePoolReplaceModal() {
this.poolReplaceOpen = false;
}
// TRE Popup Methods
treButtonClick(btnNum: number) {
this.trePopupVisible = false;
this._selectTreAfterPopup();
}
private _selectTreAfterPopup() {
this.selectedLabel = 'TRE';
this.selectedNumbers = [];
this.padValue = '';
this.canPrint = false;
this.isBoxed = false;
this.tanGroupStage = 0;
this.tanGroups = [[], [], []];
this.isFirstGroupComplete = false;
this.firstGroup = [];
this.secondGroup = [];
this.multiLegStage = 0;
this.multiLegGroups = [[], [], [], [], []];
this.selectionService.updatePartial({ label: 'TRE' });
}
closeTrePopup() {
this.trePopupVisible = false;
}
closeLimitPopup() {
this.showLimitPopup = false;
}
}