style : added 12 & 6 to user and pass (login)

This commit is contained in:
MathewFrancis 2025-06-20 12:36:20 +05:30
parent 47bfdbe7a0
commit 273a28e450
7 changed files with 136 additions and 99 deletions

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,6 @@
{
"workspace": {
"root": "/home/btc/Desktop/horse-betting/btc-ui-app-2",
"uuid": "bb38f57c-38d4-4829-b806-7831b7eb4ed8"
}
}

View File

@ -1,37 +1,37 @@
{ {
"hash": "70b30680", "hash": "fdc6de62",
"configHash": "47a48695", "configHash": "d9529696",
"lockfileHash": "f769d007", "lockfileHash": "96525434",
"browserHash": "f8601d4d", "browserHash": "65ecf150",
"optimized": { "optimized": {
"@angular/common": { "@angular/common": {
"src": "../../../../../../node_modules/@angular/common/fesm2022/common.mjs", "src": "../../../../../../node_modules/@angular/common/fesm2022/common.mjs",
"file": "@angular_common.js", "file": "@angular_common.js",
"fileHash": "3bbc72ca", "fileHash": "e49436cc",
"needsInterop": false "needsInterop": false
}, },
"@angular/core": { "@angular/core": {
"src": "../../../../../../node_modules/@angular/core/fesm2022/core.mjs", "src": "../../../../../../node_modules/@angular/core/fesm2022/core.mjs",
"file": "@angular_core.js", "file": "@angular_core.js",
"fileHash": "7407ecdc", "fileHash": "3148f944",
"needsInterop": false "needsInterop": false
}, },
"@angular/forms": { "@angular/forms": {
"src": "../../../../../../node_modules/@angular/forms/fesm2022/forms.mjs", "src": "../../../../../../node_modules/@angular/forms/fesm2022/forms.mjs",
"file": "@angular_forms.js", "file": "@angular_forms.js",
"fileHash": "83e9ef2e", "fileHash": "d850cf1d",
"needsInterop": false "needsInterop": false
}, },
"@angular/platform-browser": { "@angular/platform-browser": {
"src": "../../../../../../node_modules/@angular/platform-browser/fesm2022/platform-browser.mjs", "src": "../../../../../../node_modules/@angular/platform-browser/fesm2022/platform-browser.mjs",
"file": "@angular_platform-browser.js", "file": "@angular_platform-browser.js",
"fileHash": "cccee80f", "fileHash": "047f5f91",
"needsInterop": false "needsInterop": false
}, },
"@angular/router": { "@angular/router": {
"src": "../../../../../../node_modules/@angular/router/fesm2022/router.mjs", "src": "../../../../../../node_modules/@angular/router/fesm2022/router.mjs",
"file": "@angular_router.js", "file": "@angular_router.js",
"fileHash": "1bb4eb87", "fileHash": "3d06ffd0",
"needsInterop": false "needsInterop": false
} }
}, },

View File

@ -1,8 +1,8 @@
{ {
"hash": "e6220c80", "hash": "03bc282b",
"configHash": "fd041640", "configHash": "064eeeed",
"lockfileHash": "f769d007", "lockfileHash": "96525434",
"browserHash": "80fc46d8", "browserHash": "9a6604ec",
"optimized": {}, "optimized": {},
"chunks": {} "chunks": {}
} }

View File

@ -15,15 +15,30 @@ body {
padding: 0 20px; padding: 0 20px;
font-size: 14px; font-size: 14px;
} }
/* Main container */
.login-container { /* Bottom bar */
.bottom-bar {
height: 40px;
background-color: orange;
color: white;
display: flex; display: flex;
height: calc(100vh - 80px); /* minus top & bottom bar */ justify-content: flex;
align-items: center;
padding: 0 20px;
font-size: 14px;
} }
/* Left image */ /* Container */
.login-container {
display: flex;
/* flex-wrap: wrap; */
height: calc(100vh - 80px);
}
/* Left panel */
.login-left { .login-left {
flex: 2; flex: 2;
min-width: 300px;
} }
.bg-image { .bg-image {
@ -32,9 +47,10 @@ body {
object-fit: cover; object-fit: cover;
} }
/* Right side */ /* Right panel */
.login-right { .login-right {
flex: 1; flex: 1;
min-width: 300px;
padding: 40px; padding: 40px;
background-color: #f4f4f4; background-color: #f4f4f4;
display: flex; display: flex;
@ -58,13 +74,28 @@ body {
} }
.input-box { .input-box {
width: 80%; width: 75%;
padding: 10px; padding: 10px;
margin-bottom: 20px; margin-bottom: 15px;
font-size: 16px; font-size: 16px;
border: 1px solid #ccc; border: 1px solid #ccc;
text-align: center;
} }
.input-box.ng-invalid.ng-touched {
border-color: red;
}
/* Error */
.error-message {
color: red;
font-size: 20px;
margin-bottom: 3px;
width: 80%;
text-align: center;
}
/* Button */
.login-btn { .login-btn {
width: 80%; width: 80%;
padding: 12px; padding: 12px;
@ -76,7 +107,7 @@ body {
cursor: pointer; cursor: pointer;
} }
/* Keypad styling */ /* Keypad */
.numpad { .numpad {
width: 80%; width: 80%;
} }
@ -88,7 +119,7 @@ body {
} }
.row button { .row button {
flex: 1; flex: 1 1 30%;
margin: 0 5px; margin: 0 5px;
padding: 10px; padding: 10px;
font-size: 16px; font-size: 16px;
@ -101,23 +132,16 @@ body {
background-color: #f9d3b4; background-color: #f9d3b4;
} }
/* Bottom bar */ /* Responsive */
.bottom-bar { @media (max-width: 768px) {
height: 40px; .login-left{
background-color: orange; display: none;
color: white; }
display: flex;
justify-content: flex;
align-items: center;
padding: 0 20px;
font-size: 14px;
}
.error-message {
color: red;
font-size: 12px;
margin-bottom: 5px;
} }
.input-box.ng-invalid.ng-touched { .form-wrapper {
border-color: red; display: flex;
flex-direction: column;
align-items: center;
width: 100%;
} }

View File

@ -1,11 +1,10 @@
<!-- Top Bar --> <!-- Top Bar -->
<div class="top-bar"> <div class="top-bar">
<span>TOTE BETTING CONSOLE v7.9.1</span> <span>BANGALORE TURF CLUB LTD</span>
</div> </div>
<!-- Main Login Container --> <!-- Main Login Container -->
<div class="login-container"> <div class="login-container">
<!-- Left Image --> <!-- Left Image -->
<div class="login-left"> <div class="login-left">
<img <img
@ -17,34 +16,32 @@
<!-- Right Panel --> <!-- Right Panel -->
<div class="login-right"> <div class="login-right">
<div class="logo">BTC <span>BANGALORE TURF CLUB LTD</span></div> <div class="logo">
<strong>BTC</strong>
<!-- Email Error Message --> <span>BANGALORE TURF CLUB LTD</span>
<div </div>
class="error-message"
*ngIf="loginForm.get('email')?.touched && loginForm.get('email')?.invalid" <div class="form-wrapper" [formGroup]="loginForm">
> <!-- Username Errors -->
<small *ngIf="loginForm.get('email')?.errors?.['required']">Email is required.</small> <div class="error-message" *ngIf="loginForm.get('email')?.touched && loginForm.get('email')?.invalid">
<small *ngIf="loginForm.get('email')?.errors?.['email']">Invalid email format.</small> <small *ngIf="loginForm.get('email')?.errors?.['required']">Username is required.</small>
<small *ngIf="loginForm.get('email')?.errors?.['pattern']">Must be exactly 12 digits.</small>
</div> </div>
<!-- Email Input -->
<input <input
type="text" type="text"
placeholder="Enter Your Username" placeholder="Enter Your Username"
class="input-box" class="input-box"
formControlName="email"
(focus)="setFocus('email')" (focus)="setFocus('email')"
#emailInput #emailInput
[value]="formatUsernameDisplay(loginForm.get('email')?.value || '')"
readonly
/> />
<!-- Password Error Message --> <!-- Password Errors -->
<div <div class="error-message" *ngIf="loginForm.get('password')?.touched && loginForm.get('password')?.invalid">
class="error-message"
*ngIf="loginForm.get('password')?.touched && loginForm.get('password')?.invalid"
>
<small *ngIf="loginForm.get('password')?.errors?.['required']">Password is required.</small> <small *ngIf="loginForm.get('password')?.errors?.['required']">Password is required.</small>
<small *ngIf="loginForm.get('password')?.errors?.['pattern']">Must be exactly 6 digits.</small>
</div> </div>
<!-- Password Input -->
<input <input
type="password" type="password"
placeholder="Enter Your Password" placeholder="Enter Your Password"
@ -53,11 +50,10 @@
(focus)="setFocus('password')" (focus)="setFocus('password')"
#passwordInput #passwordInput
/> />
</div>
<!-- Login Button -->
<button class="login-btn" (click)="onSubmit()">LOGIN</button> <button class="login-btn" (click)="onSubmit()">LOGIN</button>
<!-- Numeric Keypad -->
<div class="numpad"> <div class="numpad">
<div class="row"> <div class="row">
<button (click)="onNumpadClick('0')">0</button> <button (click)="onNumpadClick('0')">0</button>

View File

@ -1,7 +1,7 @@
import { Component, ElementRef, ViewChild, ChangeDetectorRef } from '@angular/core'; import { Component, ElementRef, ViewChild, ChangeDetectorRef } from '@angular/core';
import { FormBuilder, FormGroup, Validators, ReactiveFormsModule } from '@angular/forms'; import { FormBuilder, FormGroup, Validators, ReactiveFormsModule } from '@angular/forms';
import { CommonModule } from '@angular/common'; import { CommonModule } from '@angular/common';
import { Router } from '@angular/router'; // <-- Router imported for navigation import { Router } from '@angular/router';
@Component({ @Component({
selector: 'app-login', selector: 'app-login',
@ -20,11 +20,11 @@ export class LoginComponent {
constructor( constructor(
private fb: FormBuilder, private fb: FormBuilder,
private cdRef: ChangeDetectorRef, private cdRef: ChangeDetectorRef,
private router: Router // <-- injected Router for navigation private router: Router
) { ) {
this.loginForm = this.fb.group({ this.loginForm = this.fb.group({
email: ['', [Validators.required, Validators.email]], email: ['', [Validators.required, Validators.pattern(/^\d{12}$/)]],
password: ['', Validators.required] password: ['', [Validators.required, Validators.pattern(/^\d{6}$/)]]
}); });
} }
@ -32,22 +32,32 @@ export class LoginComponent {
this.focusedField = field; this.focusedField = field;
} }
formatUsernameDisplay(rawValue: string): string {
return rawValue.replace(/(\d{4})(?=\d)/g, '$1-').slice(0, 14);
}
onNumpadClick(value: string): void { onNumpadClick(value: string): void {
if (!this.focusedField) return; if (!this.focusedField) return;
const control = this.loginForm.get(this.focusedField); const control = this.loginForm.get(this.focusedField);
const current = control?.value || ''; const currentRaw = control?.value || '';
const newValue = current + value; const maxLength = this.focusedField === 'email' ? 12 : 6;
control?.setValue(newValue); if (currentRaw.length >= maxLength) return;
const newRawValue = currentRaw + value;
control?.setValue(newRawValue);
const inputRef = this.focusedField === 'email' ? this.emailInputRef : this.passwordInputRef; const inputRef = this.focusedField === 'email' ? this.emailInputRef : this.passwordInputRef;
inputRef.nativeElement.value = newValue; const displayValue = this.focusedField === 'email'
? this.formatUsernameDisplay(newRawValue)
: newRawValue;
inputRef.nativeElement.value = displayValue;
setTimeout(() => { setTimeout(() => {
const el = inputRef.nativeElement; inputRef.nativeElement.focus();
el.focus(); inputRef.nativeElement.setSelectionRange(displayValue.length, displayValue.length);
el.setSelectionRange(newValue.length, newValue.length);
}, 0); }, 0);
this.cdRef.detectChanges(); this.cdRef.detectChanges();
@ -57,18 +67,21 @@ export class LoginComponent {
if (!this.focusedField) return; if (!this.focusedField) return;
const control = this.loginForm.get(this.focusedField); const control = this.loginForm.get(this.focusedField);
const current = control?.value || ''; const currentRaw = control?.value || '';
const newValue = current.slice(0, -1); const newRawValue = currentRaw.slice(0, -1);
control?.setValue(newValue); control?.setValue(newRawValue);
const inputRef = this.focusedField === 'email' ? this.emailInputRef : this.passwordInputRef; const inputRef = this.focusedField === 'email' ? this.emailInputRef : this.passwordInputRef;
inputRef.nativeElement.value = newValue; const displayValue = this.focusedField === 'email'
? this.formatUsernameDisplay(newRawValue)
: newRawValue;
inputRef.nativeElement.value = displayValue;
setTimeout(() => { setTimeout(() => {
const el = inputRef.nativeElement; inputRef.nativeElement.focus();
el.focus(); inputRef.nativeElement.setSelectionRange(displayValue.length, displayValue.length);
el.setSelectionRange(newValue.length, newValue.length);
}, 0); }, 0);
this.cdRef.detectChanges(); this.cdRef.detectChanges();
@ -76,13 +89,11 @@ export class LoginComponent {
onSubmit(): void { onSubmit(): void {
if (this.loginForm.invalid) { if (this.loginForm.invalid) {
this.loginForm.markAllAsTouched(); // Show all validation errors this.loginForm.markAllAsTouched();
return; return;
} }
console.log('Login successful:', this.loginForm.value); console.log('Login successful:', this.loginForm.value);
// Navigate to landing page
this.router.navigate(['/landing']); this.router.navigate(['/landing']);
} }
} }