style:"ui fixed v2"
This commit is contained in:
parent
c25ee13cab
commit
1047757e9f
@ -18,7 +18,7 @@
|
||||
"zone.js"
|
||||
],
|
||||
"tsConfig": "tsconfig.app.json",
|
||||
"assets": [
|
||||
"assets": [
|
||||
"src/assets",
|
||||
"src/favicon.ico",
|
||||
{
|
||||
@ -62,6 +62,10 @@
|
||||
},
|
||||
"serve": {
|
||||
"builder": "@angular/build:dev-server",
|
||||
"options": {
|
||||
"host": "0.0.0.0",
|
||||
"allowedHosts": true
|
||||
},
|
||||
"configurations": {
|
||||
"production": {
|
||||
"buildTarget": "Btc-race-app:build:production"
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
"version": "0.0.0",
|
||||
"scripts": {
|
||||
"ng": "ng",
|
||||
"start": "ng serve",
|
||||
"start": "ng serve --host 0.0.0.0 --port 4200",
|
||||
"build": "ng build",
|
||||
"watch": "ng build --watch --configuration development",
|
||||
"test": "ng test"
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
import { Routes } from '@angular/router';
|
||||
import { LoginComponent } from './login/login.component';
|
||||
import { HomeComponent } from './home/home.component';
|
||||
import {AuthGuard} from './service/auth.guard';
|
||||
|
||||
export const routes: Routes = [
|
||||
{ path: 'login', component: LoginComponent },
|
||||
|
||||
@ -1,13 +1,11 @@
|
||||
|
||||
|
||||
|
||||
.borderless-custom {
|
||||
border-collapse: separate;
|
||||
border-spacing: 4px;
|
||||
}
|
||||
|
||||
.custom-cell {
|
||||
height: 3.4rem; /* increased height for better fill */
|
||||
height: 2.5rem; /* increased height for better fill */
|
||||
background-color: #f8f9fa;
|
||||
border: 1px solid #ced4da;
|
||||
border-radius: 0.3rem;
|
||||
@ -22,23 +20,27 @@ div[style*="background-color: black"] .custom-cell {
|
||||
/* Override custom cell color inside grey box */
|
||||
.pure-white {
|
||||
background-color: #ffffff !important;
|
||||
border-color: black;
|
||||
}
|
||||
|
||||
|
||||
.middle-section-container {
|
||||
display: flex;
|
||||
gap: 1rem;
|
||||
height: 49vh;
|
||||
height: 38vh;
|
||||
width: 100%;
|
||||
|
||||
}
|
||||
|
||||
/* Desktop view (default) */
|
||||
.main-table {
|
||||
width: 60%;
|
||||
background-color: #f1f1f1df;
|
||||
}
|
||||
|
||||
.transaction-summary {
|
||||
width: 40%;
|
||||
background-color: #d0ddf5;
|
||||
}
|
||||
|
||||
.borderless-custom {
|
||||
@ -46,11 +48,11 @@ div[style*="background-color: black"] .custom-cell {
|
||||
border-spacing: 4px;
|
||||
}
|
||||
|
||||
.custom-cell {
|
||||
height: 3.4rem;
|
||||
.custom-cell-new {
|
||||
height: 2.5rem;
|
||||
background-color: #f8f9fa;
|
||||
border: 1px solid #ced4da;
|
||||
border-radius: 0.3rem;
|
||||
border: 1px solid rgba(3, 27, 69, 0.678);
|
||||
}
|
||||
|
||||
div[style*="background-color: black"] .custom-cell {
|
||||
@ -60,6 +62,24 @@ div[style*="background-color: black"] .custom-cell {
|
||||
.pure-white {
|
||||
background-color: #ffffff !important;
|
||||
}
|
||||
|
||||
.buttons-custom{
|
||||
display: flex;
|
||||
height: 2.6rem;
|
||||
width: 100%;
|
||||
justify-content: space-between;
|
||||
padding-bottom: 0.2rem;
|
||||
}
|
||||
|
||||
|
||||
.btn{
|
||||
padding-bottom:0.8rem;
|
||||
height: 100%;
|
||||
}
|
||||
.fw-bold{
|
||||
margin-right: 2rem;
|
||||
padding-bottom: 1rem;
|
||||
}
|
||||
/* Desktop view (default) - reorder the layout */
|
||||
@media (min-width: 801px) {
|
||||
.main-table {
|
||||
@ -87,3 +107,14 @@ div[style*="background-color: black"] .custom-cell {
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
}
|
||||
|
||||
/* REMOVE or COMMENT this block */
|
||||
@media (min-width: 900px) and (max-width: 1400px) {
|
||||
.middle-section-container {
|
||||
height: auto;
|
||||
max-height: 50vh;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
/* REMOVE or COMMENT this block fixed */
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
|
||||
<!-- Transaction Summary -->
|
||||
<div class="transaction-summary">
|
||||
<div class="p-3 rounded text-white h-100 d-flex flex-column" style="background-color: black;">
|
||||
<div class="p-3 rounded text-white h-100 d-flex flex-column" style="background-color: #546c98;">
|
||||
<h5 class="text-center mb-3">Transaction Summary</h5>
|
||||
|
||||
<div class="rounded flex-grow-1" style="background-color: #f1f1f1df; padding: 1rem; overflow: hidden;">
|
||||
@ -27,7 +27,7 @@
|
||||
|
||||
<!-- Main Table -->
|
||||
<div class="main-table">
|
||||
<div class="p-3 rounded h-100 d-flex flex-column justify-content-between" style="background-color: #f1f1f1df;">
|
||||
<div class="p-2 rounded h-100 d-flex flex-column justify-content-between" style="background-color: #f1f1f1df; ">
|
||||
<table class="table borderless-custom w-100 mb-2">
|
||||
<colgroup>
|
||||
<col style="width: 12%">
|
||||
@ -37,19 +37,18 @@
|
||||
</colgroup>
|
||||
<tbody>
|
||||
<tr *ngFor="let row of rows">
|
||||
<td class="custom-cell"></td>
|
||||
<td class="custom-cell"></td>
|
||||
<td class="custom-cell"></td>
|
||||
<td class="custom-cell"></td>
|
||||
<td class="custom-cell-new"></td>
|
||||
<td class="custom-cell-new"></td>
|
||||
<td class="custom-cell-new"></td>
|
||||
<td class="custom-cell-new"></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<div class="d-flex justify-content-between align-items-center">
|
||||
<div class="buttons-custom">
|
||||
<button class="btn btn-dark">Repeat</button>
|
||||
<div class="fw-bold" style="margin-right: 3vw;">Amount :</div>
|
||||
<div class="fw-bold">Amount :</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
@ -1,13 +1,13 @@
|
||||
/* Top Bar */
|
||||
.top-bar {
|
||||
background-color: #6a4607;
|
||||
background-color: #043785;
|
||||
height: 2.5rem;
|
||||
font-size: 0.85rem;
|
||||
font-size: 1rem;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.top-live-button {
|
||||
background: rgb(5, 126, 43);
|
||||
background: rgb(3, 108, 36);
|
||||
color: #f8f3f3;
|
||||
font-weight: bold;
|
||||
height: 2.5rem;
|
||||
@ -21,13 +21,13 @@
|
||||
}
|
||||
|
||||
.top-live-button:hover {
|
||||
background-color: rgba(12, 249, 142, 0.903);
|
||||
background-color: rgba(3, 93, 52, 0.903);
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
/* Navbar */
|
||||
.custom-navbar {
|
||||
background-color: #a15914;
|
||||
background-color: #0e4487;
|
||||
height: 2.7rem;
|
||||
font-weight: bold;
|
||||
font-size: 0.9rem;
|
||||
@ -38,7 +38,7 @@
|
||||
background: none;
|
||||
border: none !important;
|
||||
height: 2.7rem;
|
||||
color: rgb(14, 0, 0);
|
||||
color: rgb(251, 248, 248);
|
||||
font-weight: bold;
|
||||
font-size: 1rem;
|
||||
}
|
||||
@ -50,11 +50,11 @@
|
||||
}
|
||||
|
||||
.nav-button {
|
||||
color: rgb(26, 1, 1);
|
||||
background: none;
|
||||
border-left: 1px solid white;
|
||||
border-right: 1px solid white;
|
||||
height: 2.7rem;
|
||||
color: rgb(254, 253, 253);
|
||||
|
||||
height: 2.3rem;
|
||||
margin-bottom: 0.5rem;
|
||||
|
||||
padding: 0 0.5rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
</div>
|
||||
<div class="d-flex align-items-center text-light small justify-content-end flex-grow-1">
|
||||
<span class="me-2">B.T.No:1111</span>
|
||||
<div class="top-live-button text-center">LIVE</div>
|
||||
<div class="top-live-button text-center" (click)="ping()">LIVE</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -31,7 +31,7 @@
|
||||
|
||||
<!-- Mobile View -->
|
||||
<div class="d-lg-none w-100 mt-2 d-flex justify-content-end" *ngIf="isMenuOpen">
|
||||
<div class="mobile-menu-container p-3" style="width: 50%; background-color: #c17a30;">
|
||||
<div class="mobile-menu-container p-3" style="width: 50%; background-color: #0d329f;">
|
||||
<button class="nav-dropdown w-100 text-end pe-3" (click)="openVenueModal()">Venue | {{ selectedVenue }}</button>
|
||||
<button class="nav-dropdown w-100 text-end pe-3" (click)="openRaceModal()">Race No. | {{ selectedRace }}</button>
|
||||
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
import { Component, OnInit, HostListener } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { BtcService } from '../../service/btc.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-navbar',
|
||||
@ -45,6 +46,10 @@ export class NavbarComponent implements OnInit {
|
||||
{ description: '', venue: '', ticketNumber: '', poolName: '', totalAmount: '' }
|
||||
];
|
||||
|
||||
constructor(private btcService : BtcService){
|
||||
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
this.updateDateTime();
|
||||
setInterval(() => this.updateDateTime(), 1000);
|
||||
@ -109,4 +114,13 @@ export class NavbarComponent implements OnInit {
|
||||
this.selectedRace = race;
|
||||
this.closeModals();
|
||||
}
|
||||
|
||||
ping() {
|
||||
console.log("Ping");
|
||||
|
||||
this.btcService.pingLiveStatus().subscribe({
|
||||
next: (employee) => {console.log(employee); console.log("Resp")},
|
||||
error: (e) => {console.log(e); console.log("Error")}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
align-items: center;
|
||||
height: 104vh;
|
||||
width: 5rem;
|
||||
background-color: #1e1e2f;
|
||||
background-color: #01050f;
|
||||
padding-top: 1rem;
|
||||
padding-bottom: 2rem;
|
||||
box-sizing: border-box;
|
||||
@ -16,6 +16,10 @@
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.logo{
|
||||
width: 4rem;
|
||||
height: 3rem;
|
||||
}
|
||||
.sidebar-menu {
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
@ -31,7 +35,8 @@
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
font-size: 0.75rem;
|
||||
font-size: 0.8rem;
|
||||
font-weight: bold;
|
||||
padding: 0.5rem 0;
|
||||
cursor: pointer;
|
||||
transition: background 0.2s;
|
||||
|
||||
@ -1,18 +1,25 @@
|
||||
<img src="logo" alt="new">
|
||||
<img src="./assets/logo_w.png" alt="new" class="logo">
|
||||
|
||||
<ul class="sidebar-menu">
|
||||
<li><i class="bi bi-ticket-perforated"></i><span>Ticketing</span></li>
|
||||
<li (click)="openWithdrawPopup()"><i class="bi bi-cash-stack"></i><span>Withdraw</span></li>
|
||||
<li (click)="openDepositPopup()"><i class="bi bi-piggy-bank"></i><span>Deposit</span></li>
|
||||
|
||||
<li (click)="openPayoutPopup()">
|
||||
<li (click)="ticketingClick.emit()">
|
||||
<i class="bi bi-ticket-perforated"></i><span>Ticketing</span>
|
||||
</li>
|
||||
<li (click)="openWithdrawPopup()">
|
||||
<i class="bi bi-cash-stack"></i><span>Withdraw</span>
|
||||
</li>
|
||||
<li (click)="openDepositPopup()">
|
||||
<i class="bi bi-piggy-bank"></i><span>Deposit</span>
|
||||
</li>
|
||||
<li (click)="openPayoutPopup()">
|
||||
<i class="bi bi-currency-exchange"></i><span>Pay-out</span>
|
||||
</li> <li><i class="bi bi-journal-text"></i><span>View RC</span></li>
|
||||
</li>
|
||||
<li><i class="bi bi-journal-text"></i><span>View RC</span></li>
|
||||
<li (click)="openCancelPopup()">
|
||||
<i class="bi bi-x-circle"></i><span>Cancel</span>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
||||
<!-- Cancel Modal -->
|
||||
<div class="modal-overlay" *ngIf="showCancel">
|
||||
<div class="modal-box">
|
||||
|
||||
@ -1,20 +1,40 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { Component, Output, EventEmitter } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { FormsModule } from '@angular/forms'; // Required for ngModel
|
||||
import { FormsModule } from '@angular/forms';
|
||||
|
||||
@Component({
|
||||
selector: 'app-sidebar',
|
||||
templateUrl: './sidebar.component.html',
|
||||
styleUrls: ['./sidebar.component.css'],
|
||||
standalone: true,
|
||||
imports: [CommonModule, FormsModule]
|
||||
imports: [CommonModule, FormsModule],
|
||||
})
|
||||
export class SidebarComponent {
|
||||
// Cancel Modal
|
||||
@Output() ticketingClick = new EventEmitter<void>();
|
||||
@Output() withdrawClick = new EventEmitter<void>();
|
||||
@Output() depositClick = new EventEmitter<void>();
|
||||
@Output() payoutClick = new EventEmitter<void>();
|
||||
@Output() cancelClick = new EventEmitter<void>();
|
||||
|
||||
showCancel: boolean = false;
|
||||
ticketNo: string = '';
|
||||
|
||||
showPayout: boolean = false;
|
||||
payoutTicketNo: string = '';
|
||||
|
||||
showDeposit: boolean = false;
|
||||
depositOperatorId = '';
|
||||
depositShroffId = '';
|
||||
depositAmount = '';
|
||||
|
||||
showWithdraw: boolean = false;
|
||||
withdrawOperatorId = '';
|
||||
withdrawShroffId = '';
|
||||
withdrawAmount = '';
|
||||
|
||||
// Modal handlers...
|
||||
openCancelPopup() {
|
||||
this.cancelClick.emit();
|
||||
this.showCancel = true;
|
||||
}
|
||||
|
||||
@ -28,11 +48,8 @@ export class SidebarComponent {
|
||||
this.closeCancelPopup();
|
||||
}
|
||||
|
||||
// Pay-out Modal
|
||||
showPayout: boolean = false;
|
||||
payoutTicketNo: string = '';
|
||||
|
||||
openPayoutPopup() {
|
||||
this.payoutClick.emit();
|
||||
this.showPayout = true;
|
||||
}
|
||||
|
||||
@ -50,13 +67,8 @@ export class SidebarComponent {
|
||||
this.closePayoutPopup();
|
||||
}
|
||||
|
||||
// Deposit Modal
|
||||
showDeposit: boolean = false;
|
||||
depositOperatorId = '';
|
||||
depositShroffId = '';
|
||||
depositAmount = '';
|
||||
|
||||
openDepositPopup() {
|
||||
this.depositClick.emit();
|
||||
this.showDeposit = true;
|
||||
}
|
||||
|
||||
@ -72,13 +84,8 @@ export class SidebarComponent {
|
||||
this.closeDepositPopup();
|
||||
}
|
||||
|
||||
// Withdraw Modal
|
||||
showWithdraw: boolean = false;
|
||||
withdrawOperatorId = '';
|
||||
withdrawShroffId = '';
|
||||
withdrawAmount = '';
|
||||
|
||||
openWithdrawPopup() {
|
||||
this.withdrawClick.emit();
|
||||
this.showWithdraw = true;
|
||||
}
|
||||
|
||||
@ -94,7 +101,6 @@ export class SidebarComponent {
|
||||
this.closeWithdrawPopup();
|
||||
}
|
||||
|
||||
// Numpad handlers for Deposit and Withdraw modals
|
||||
onNumpadClick(value: string, type: 'deposit' | 'withdraw') {
|
||||
if (type === 'deposit') {
|
||||
this.depositAmount += value;
|
||||
|
||||
@ -1,8 +1,14 @@
|
||||
/* 🔲 Base Styles */
|
||||
.touch-pad-container {
|
||||
background-color: #f9f9f9;
|
||||
/*background-color: #cc0f0f;*/
|
||||
border: 1px solid #ccc;
|
||||
padding: 1rem;
|
||||
border-radius: 8px;
|
||||
height: 56.8vh;
|
||||
}
|
||||
|
||||
.container-fluid.mb-2{
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.scrollable-touchpad {
|
||||
@ -13,6 +19,7 @@
|
||||
.scrollable-touchpad::-webkit-scrollbar {
|
||||
width: 6px;
|
||||
}
|
||||
|
||||
.scrollable-touchpad::-webkit-scrollbar-thumb {
|
||||
background-color: rgba(0, 0, 0, 0.2);
|
||||
border-radius: 4px;
|
||||
@ -28,75 +35,68 @@ button {
|
||||
color: #5d6165;
|
||||
}
|
||||
|
||||
/* ✅ Tablet & Mobile View */
|
||||
.number-button{
|
||||
height: 3rem;
|
||||
}
|
||||
|
||||
/* ✅ Responsive Tablet/Mobile Styles */
|
||||
@media (max-width: 800px) {
|
||||
.container-fluid {
|
||||
padding: 0 1rem;
|
||||
}
|
||||
|
||||
.row.align-items-center {
|
||||
/* Stack the top row groups */
|
||||
.touch-pad-container .container-fluid.mb-2 > .d-flex {
|
||||
flex-direction: column !important;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
/* Stack and center 3 sections */
|
||||
.touch-pad-container .container-fluid.mb-2 > .d-flex > div {
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.touch-pad-container .btn {
|
||||
min-width: 80px;
|
||||
flex: 1 1 auto;
|
||||
}
|
||||
|
||||
/* Main grid stacking */
|
||||
.touch-pad-container .row.gx-2 {
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.touch-pad-container .col-3 {
|
||||
width: 90% !important;
|
||||
margin-bottom: 1rem;
|
||||
order: 1;
|
||||
}
|
||||
|
||||
.touch-pad-container .col-3 .row.gx-1 {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.touch-pad-container .col-3 .col-4 {
|
||||
flex: 0 0 33.3333%;
|
||||
max-width: 33.3333%;
|
||||
}
|
||||
|
||||
.touch-pad-container .col-2 {
|
||||
width: 90% !important;
|
||||
margin-bottom: 1rem;
|
||||
order: 2;
|
||||
}
|
||||
|
||||
.touch-pad-container .col-2 .row.gx-1 {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.touch-pad-container .col-2 .col-6 {
|
||||
flex: 0 0 50%;
|
||||
max-width: 50%;
|
||||
}
|
||||
|
||||
.touch-pad-container .col-2 .col-4 {
|
||||
flex: 0 0 33.3333%;
|
||||
max-width: 33.3333%;
|
||||
}
|
||||
|
||||
.touch-pad-container .col-3,
|
||||
.touch-pad-container .col-2,
|
||||
.touch-pad-container .col-7 {
|
||||
width: 90% !important;
|
||||
margin: 0 auto 1rem auto;
|
||||
order: 3;
|
||||
width: 95% !important;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.touch-pad-container .col-3 .row.gx-1,
|
||||
.touch-pad-container .col-2 .row.gx-1,
|
||||
.touch-pad-container .col-7 .row.gx-1 {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
/* ✅ This ensures 6 columns (≈16.66% each) for 1–30 buttons */
|
||||
.touch-pad-container .col-7 .col-2 {
|
||||
flex: 0 0 16.6667%;
|
||||
max-width: 16.6667%;
|
||||
flex: 0 0 16.6667% !important;
|
||||
max-width: 16.6667% !important;
|
||||
}
|
||||
|
||||
/* Labels and number pad layout (unchanged logic) */
|
||||
.touch-pad-container .col-3 .col-4,
|
||||
.touch-pad-container .col-2 .col-4 {
|
||||
flex: 0 0 33.3333%;
|
||||
max-width: 33.3333%;
|
||||
}
|
||||
|
||||
.touch-pad-container .col-2 .col-6 {
|
||||
flex: 0 0 50%;
|
||||
max-width: 50%;
|
||||
}
|
||||
|
||||
.col-2 .btn,
|
||||
@ -108,4 +108,121 @@ button {
|
||||
.scrollable-touchpad {
|
||||
max-height: 40vh;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@media (min-width: 801px) {
|
||||
/* Remove container padding on desktop to align buttons edge-to-edge */
|
||||
.touch-pad-container .container-fluid.mb-2 {
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
}
|
||||
|
||||
/* Parent flex row */
|
||||
.touch-pad-container .container-fluid.mb-2 > .d-flex {
|
||||
/*justify-content: space-between;*/
|
||||
flex-wrap: nowrap;
|
||||
gap: 2rem;
|
||||
}
|
||||
|
||||
/* Left group: CALC to FIELD */
|
||||
.touch-pad-container .container-fluid.mb-2 > .d-flex > div:first-child {
|
||||
flex: 0 0 45%;
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
padding-left: 0; /* optional: add 1rem if you still want a little breathing room */
|
||||
}
|
||||
|
||||
/* Right group: COPY, CLEAR, PR */
|
||||
.touch-pad-container .container-fluid.mb-2 > .d-flex > div:last-child {
|
||||
flex: 0 0 50%;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
gap: 0.8rem;
|
||||
padding-right: 1rem; /* optional: for symmetry */
|
||||
}
|
||||
|
||||
/* Optional: widen left buttons slightly */
|
||||
.touch-pad-container .container-fluid.mb-2 > .d-flex > div:first-child button {
|
||||
min-width: 120px;
|
||||
margin-right: 2rem;
|
||||
}
|
||||
|
||||
|
||||
/* Increase COPY button width */
|
||||
.touch-pad-container .container-fluid.mb-2 > .d-flex > div:last-child button:nth-child(1) {
|
||||
min-width: 190px;
|
||||
margin-right: 2rem;
|
||||
margin-left: 2rem;
|
||||
}
|
||||
|
||||
/* Add 3rem gap between COPY and CLEAR */
|
||||
.touch-pad-container .container-fluid.mb-2 > .d-flex > div:last-child button:nth-child(2) {
|
||||
margin-left: 9rem;
|
||||
min-width: 150px;
|
||||
}
|
||||
|
||||
.touch-pad-container .container-fluid.mb-2 > .d-flex > div:last-child button:nth-child(3) {
|
||||
min-width: 100px;
|
||||
margin-left: 1rem;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* 🎯 POS Machine Optimization */
|
||||
@media (min-width: 900px) and (max-width: 1400px) {
|
||||
|
||||
.touch-pad-container .container-fluid.mb-2 {
|
||||
padding-left: 0.5rem;
|
||||
padding-right: 0.5rem;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.touch-pad-container .container-fluid.mb-2 > .d-flex {
|
||||
gap: 1rem;
|
||||
}
|
||||
|
||||
.touch-pad-container .container-fluid.mb-2 > .d-flex > div:first-child {
|
||||
flex: 0 0 50%;
|
||||
justify-content: flex-start;
|
||||
}
|
||||
|
||||
.touch-pad-container .container-fluid.mb-2 > .d-flex > div:first-child button {
|
||||
min-width: 110px;
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
.touch-pad-container .container-fluid.mb-2 > .d-flex > div:last-child {
|
||||
flex: 0 0 50%;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.touch-pad-container .container-fluid.mb-2 > .d-flex > div:last-child button:nth-child(1) {
|
||||
min-width: 160px;
|
||||
margin-right: 4rem;
|
||||
margin-left: 1rem;
|
||||
}
|
||||
|
||||
.touch-pad-container .container-fluid.mb-2 > .d-flex > div:last-child button:nth-child(2) {
|
||||
margin-left: 0.3rem;
|
||||
min-width: 130px;
|
||||
}
|
||||
|
||||
.touch-pad-container .container-fluid.mb-2 > .d-flex > div:last-child button:nth-child(3) {
|
||||
min-width: 90px;
|
||||
margin-left: 0.5rem;
|
||||
}
|
||||
|
||||
.scrollable-touchpad {
|
||||
max-height: 60vh;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@media(min-height: 600px) and (max-height: 725px){
|
||||
.number-button{
|
||||
height: 2rem;
|
||||
}
|
||||
}
|
||||
@ -1,57 +1,44 @@
|
||||
<!-- Touch Pad Container -->
|
||||
<div class="touch-pad-container scrollable-touchpad">
|
||||
|
||||
<!-- 🔘 Top Button Section (Responsive Wrapper) -->
|
||||
<div class="container-fluid mb-2">
|
||||
<div class="d-flex flex-wrap justify-content-center gap-2 flex-md-nowrap flex-column flex-md-row align-items-md-center wrap_one">
|
||||
|
||||
<!-- ✅ Desktop view -->
|
||||
<div class="row align-items-center d-none d-md-flex">
|
||||
<!-- CALC ERASE BOX FIELD -->
|
||||
<div class="col-5 d-flex justify-content-between">
|
||||
<button class="btn btn-dark flex-fill mx-1">CALC</button>
|
||||
<button class="btn btn-dark flex-fill mx-1">ERASE</button>
|
||||
<button class="btn btn-secondary flex-fill mx-1">BOX</button>
|
||||
<button class="btn btn-secondary flex-fill mx-1">FIELD</button>
|
||||
<!-- Left Group: CALC, ERASE, BOX, FIELD -->
|
||||
<div class="d-flex flex-wrap justify-content-center gap-2 first">
|
||||
<button class="btn btn-dark one">CALC</button>
|
||||
<button class="btn btn-dark two">ERASE</button>
|
||||
<button class="btn btn-secondary three">BOX</button>
|
||||
<button class="btn btn-secondary four">FIELD</button>
|
||||
</div>
|
||||
|
||||
<!-- COPY -->
|
||||
<div class="col-4 text-center">
|
||||
<button class="btn btn-dark px-4">COPY</button>
|
||||
</div>
|
||||
|
||||
<!-- CLEAR, PR -->
|
||||
<div class="col-3 d-flex justify-content-end gap-2">
|
||||
<button class="btn btn-dark px-4">CLEAR</button>
|
||||
<button class="btn btn-dark px-4">PR</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ✅ Tablet/Mobile view -->
|
||||
<div class="d-flex flex-column align-items-center gap-2 d-md-none">
|
||||
<!-- CALC ERASE BOX FIELD -->
|
||||
<div class="d-flex flex-wrap justify-content-center gap-2 w-100">
|
||||
<button class="btn btn-dark">CALC</button>
|
||||
<button class="btn btn-dark">ERASE</button>
|
||||
<button class="btn btn-secondary">BOX</button>
|
||||
<button class="btn btn-secondary">FIELD</button>
|
||||
</div>
|
||||
|
||||
<!-- COPY CLEAR PR in same row -->
|
||||
<div class="d-flex flex-wrap justify-content-center gap-2 w-100">
|
||||
<!-- Right Group: COPY, CLEAR, PR -->
|
||||
<div class="d-flex flex-wrap justify-content-center gap-2 second">
|
||||
<button class="btn btn-dark">COPY</button>
|
||||
<button class="btn btn-dark">CLEAR</button>
|
||||
<button class="btn btn-dark">PR</button>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Main Grid -->
|
||||
<!-- 🔳 Main Grid Area -->
|
||||
<div class="container-fluid">
|
||||
<div class="row gx-2 gy-2">
|
||||
|
||||
<!-- Label Section -->
|
||||
<div class="col-3">
|
||||
<div class="p-3 rounded" style="background-color: #f1f1f1df;">
|
||||
<div
|
||||
class="p-2 rounded"
|
||||
[ngStyle]="{
|
||||
'background-color': ticketingActive ? '#d0ddf5' : '#f1f1f1df',
|
||||
'border': ticketingActive ? '2px solid #050505' : 'none'
|
||||
}"
|
||||
>
|
||||
<div class="row gx-1 gy-1">
|
||||
<div class="col-4" *ngFor="let label of labelRowsFlat">
|
||||
<button class="btn btn-light w-100">{{ label }}</button>
|
||||
<button class="btn btn-light w-100 number-button">{{ label }}</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -59,10 +46,10 @@
|
||||
|
||||
<!-- Numbers 1 to 30 -->
|
||||
<div class="col-7">
|
||||
<div class="p-3 rounded" style="background-color: #f1f1f1df;">
|
||||
<div class="p-2 rounded" style="background-color: #f1f1f1df;">
|
||||
<div class="row gx-1 gy-1">
|
||||
<div class="col-2" *ngFor="let number of numbersFlat">
|
||||
<button class="btn btn-light w-100">{{ number }}</button>
|
||||
<button class="btn btn-light w-100 number-button">{{ number }}</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -70,25 +57,25 @@
|
||||
|
||||
<!-- Numeric Pad -->
|
||||
<div class="col-2">
|
||||
<div class="p-3 rounded" style="background-color: #f1f1f1df;">
|
||||
<div class="p-2 rounded" style="background-color: #f1f1f1df;">
|
||||
<div class="row gx-1 gy-1">
|
||||
<div class="col-6"><button class="btn btn-secondary w-100">0</button></div>
|
||||
<div class="col-6"><button class="btn btn-light w-100">X</button></div>
|
||||
<div class="col-6"><button class="btn btn-secondary w-100 number-button">0</button></div>
|
||||
<div class="col-6"><button class="btn btn-light w-100 number-button">X</button></div>
|
||||
|
||||
<ng-container *ngFor="let key of ['7', '8', '9']">
|
||||
<div class="col-4"><button class="btn btn-light w-100">{{ key }}</button></div>
|
||||
<div class="col-4"><button class="btn btn-light w-100 number-button">{{ key }}</button></div>
|
||||
</ng-container>
|
||||
|
||||
<ng-container *ngFor="let key of ['4', '5', '6']">
|
||||
<div class="col-4"><button class="btn btn-light w-100">{{ key }}</button></div>
|
||||
<div class="col-4"><button class="btn btn-light w-100 number-button">{{ key }}</button></div>
|
||||
</ng-container>
|
||||
|
||||
<ng-container *ngFor="let key of ['1', '2', '3']">
|
||||
<div class="col-4"><button class="btn btn-light w-100">{{ key }}</button></div>
|
||||
<div class="col-4"><button class="btn btn-light w-100 number-button" >{{ key }}</button></div>
|
||||
</ng-container>
|
||||
|
||||
<div class="col-6"><button class="btn btn-secondary w-100">Enter</button></div>
|
||||
<div class="col-6"><button class="btn btn-secondary w-100">Print</button></div>
|
||||
<div class="col-6"><button class="btn btn-secondary w-100 number-button">Enter</button></div>
|
||||
<div class="col-6"><button class="btn btn-secondary w-100 number-button">Print</button></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { Component, Input, OnInit } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
|
||||
@Component({
|
||||
@ -9,6 +9,8 @@ import { CommonModule } from '@angular/common';
|
||||
styleUrls: ['./touch-pad-menu.component.css']
|
||||
})
|
||||
export class TouchPadMenuComponent implements OnInit {
|
||||
@Input() ticketingActive: boolean = false;
|
||||
|
||||
labels: string[] = [
|
||||
'WIN', 'SHP', 'THP',
|
||||
'PLC', 'SHW', 'FOR',
|
||||
|
||||
12
src/app/constants/http-routs.ts
Normal file
12
src/app/constants/http-routs.ts
Normal file
@ -0,0 +1,12 @@
|
||||
export class ApplicationHttpRouts{
|
||||
|
||||
private static readonly PROTOCOL: string = 'http';
|
||||
private static readonly BACKEND_SERVER: string = 'localhost';
|
||||
private static readonly PORT_NUMBER: string = '8083';
|
||||
private static readonly SOCKET: string = `${this.PROTOCOL}://${this.BACKEND_SERVER}:${this.PORT_NUMBER}`;
|
||||
|
||||
|
||||
//login user
|
||||
static readonly LOG_IN: string = this.SOCKET + '/open/login';
|
||||
static readonly PING : string = this.SOCKET + '/user/ping';
|
||||
}
|
||||
@ -1,31 +1,33 @@
|
||||
<div class="d-flex min-vh-100">
|
||||
|
||||
<!-- Sidebar (fixed width) -->
|
||||
<!-- Sidebar -->
|
||||
<div class="sidebar-container">
|
||||
<app-sidebar></app-sidebar>
|
||||
<app-sidebar
|
||||
(ticketingClick)="onTicketingClicked()"
|
||||
(withdrawClick)="onOtherActionClicked()"
|
||||
(depositClick)="onOtherActionClicked()"
|
||||
(payoutClick)="onOtherActionClicked()"
|
||||
(cancelClick)="onOtherActionClicked()"
|
||||
></app-sidebar>
|
||||
</div>
|
||||
|
||||
<!-- Right Content Area -->
|
||||
<div class="flex-grow-1 d-flex flex-column">
|
||||
|
||||
<!-- Navbar -->
|
||||
<app-navbar></app-navbar>
|
||||
|
||||
<!-- Main Content -->
|
||||
<div class="flex-grow-1 p-3">
|
||||
<!-- Middle section -->
|
||||
<app-middle-section></app-middle-section>
|
||||
|
||||
<!-- 👇 Show Touch Pad *here* for Tablet/Mobile View -->
|
||||
<!-- Tablet View Touchpad -->
|
||||
<div *ngIf="isTabletView" class="mt-3">
|
||||
<app-touch-pad-menu></app-touch-pad-menu>
|
||||
<app-touch-pad-menu [ticketingActive]="isTicketingActive"></app-touch-pad-menu>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 👇 Desktop-only Touch Pad at the bottom -->
|
||||
<!-- Desktop View Touchpad -->
|
||||
<div *ngIf="!isTabletView" class="border-top p-2 bg-white">
|
||||
<app-touch-pad-menu></app-touch-pad-menu>
|
||||
<app-touch-pad-menu [ticketingActive]="isTicketingActive"></app-touch-pad-menu>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -20,6 +20,7 @@ import { CommonModule } from '@angular/common';
|
||||
})
|
||||
export class HomeComponent implements OnInit, OnDestroy {
|
||||
isTabletView = false;
|
||||
isTicketingActive = false;
|
||||
private resizeObserver!: () => void;
|
||||
|
||||
constructor(private cdr: ChangeDetectorRef) {}
|
||||
@ -40,4 +41,12 @@ export class HomeComponent implements OnInit, OnDestroy {
|
||||
private updateView() {
|
||||
this.isTabletView = window.innerWidth <= 800;
|
||||
}
|
||||
|
||||
onTicketingClicked() {
|
||||
this.isTicketingActive = true;
|
||||
}
|
||||
|
||||
onOtherActionClicked() {
|
||||
this.isTicketingActive = false;
|
||||
}
|
||||
}
|
||||
|
||||
@ -6,7 +6,7 @@ body {
|
||||
/* Top bar */
|
||||
.top-bar {
|
||||
height: 40px;
|
||||
background-color: orange;
|
||||
background-color: rgb(2, 37, 101);
|
||||
color: #fff;
|
||||
font-weight: bold;
|
||||
display: flex;
|
||||
@ -19,20 +19,21 @@ body {
|
||||
/* Bottom bar */
|
||||
.bottom-bar {
|
||||
height: 40px;
|
||||
background-color: orange;
|
||||
background-color: rgb(3, 37, 124);
|
||||
color: white;
|
||||
display: flex;
|
||||
justify-content: flex;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
padding: 0 20px;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
/* Container */
|
||||
/* Main container */
|
||||
.login-container {
|
||||
display: flex;
|
||||
/* flex-wrap: wrap; */
|
||||
height: calc(100vh - 80px);
|
||||
background-color: #666;
|
||||
/* flex-direction: row; */
|
||||
}
|
||||
|
||||
/* Left panel */
|
||||
@ -51,64 +52,87 @@ body {
|
||||
.login-right {
|
||||
flex: 1;
|
||||
min-width: 300px;
|
||||
padding: 40px;
|
||||
padding: 40px 20px;
|
||||
background-color: #f4f4f4;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.logo {
|
||||
font-size: 24px;
|
||||
font-weight: bold;
|
||||
margin-bottom: 30px;
|
||||
margin-bottom: 15px;
|
||||
color: #004aad;
|
||||
text-align: center;
|
||||
display: flex; /* Arrange children side by side */
|
||||
align-items: center; /* Vertically align */
|
||||
justify-content: center; /* Center horizontally */
|
||||
gap: 8px; /* Space between BTC and text */
|
||||
}
|
||||
|
||||
.logo_img{
|
||||
width: 5rem;
|
||||
height: 5rem;
|
||||
}
|
||||
|
||||
.logo span {
|
||||
display: block;
|
||||
display: inline; /* Inline so it sits beside BTC */
|
||||
font-size: 18px;
|
||||
color: orange;
|
||||
color: rgb(5, 77, 165);
|
||||
}
|
||||
|
||||
|
||||
/* Form */
|
||||
.input-box {
|
||||
width: 75%;
|
||||
width: 84%;
|
||||
/* height: 30px; */
|
||||
padding: 15px;
|
||||
padding: 12px;
|
||||
margin-bottom: 15px;
|
||||
font-size: 16px;
|
||||
border: 1px solid #ccc;
|
||||
text-align: center;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.input-box.ng-invalid.ng-touched {
|
||||
border-color: red;
|
||||
}
|
||||
|
||||
.form-wrapper {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
/* Error */
|
||||
.error-message {
|
||||
color: red;
|
||||
font-size: 20px;
|
||||
margin-bottom: 3px;
|
||||
width: 80%;
|
||||
font-size: 16px;
|
||||
margin-bottom: 8px;
|
||||
text-align: center;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
/* Button */
|
||||
/* Login Button */
|
||||
.login-btn {
|
||||
width: 80%;
|
||||
width: 84%;
|
||||
padding: 12px;
|
||||
background-color: orange;
|
||||
border: none;
|
||||
color: white;
|
||||
background-color: #d0ddf5;
|
||||
border-color: black;
|
||||
color: rgb(2, 38, 138);
|
||||
font-size: 16px;
|
||||
margin-bottom: 20px;
|
||||
margin-bottom: 16px;
|
||||
border-radius: 0.5rem;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
/* Keypad */
|
||||
.login-btn:hover{
|
||||
background-color:#073674e7 ;
|
||||
color: white;
|
||||
}
|
||||
|
||||
/* Numpad */
|
||||
.numpad {
|
||||
width: 80%;
|
||||
}
|
||||
@ -120,29 +144,142 @@ body {
|
||||
}
|
||||
|
||||
.row button {
|
||||
flex: 1 1 30%;
|
||||
flex: 1;
|
||||
margin: 0 5px;
|
||||
padding: 10px;
|
||||
font-size: 16px;
|
||||
background-color: white;
|
||||
border: 1px solid orange;
|
||||
padding: 14px;
|
||||
font-size: 18px;
|
||||
background-color: #d0ddf5;
|
||||
border-color: black;
|
||||
cursor: pointer;
|
||||
border-radius: 4px;
|
||||
color: rgb(3, 39, 122);
|
||||
}
|
||||
|
||||
|
||||
|
||||
.back-btn {
|
||||
background-color: #f9d3b4;
|
||||
background-color: #7b9af1;
|
||||
}
|
||||
|
||||
/* ─── FIELD WITH FLOATING LABEL ───────────────────── */
|
||||
.field-wrapper {
|
||||
position: relative;
|
||||
width: 84%;
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
.input-box {
|
||||
width: 100%;
|
||||
padding: 18px 12px 8px;
|
||||
font-size: 16px;
|
||||
text-align: center;
|
||||
border: 2px solid #022f63;
|
||||
background-color: #d0ddf5;
|
||||
border-radius: 4px;
|
||||
background: transparent;
|
||||
box-sizing: border-box;
|
||||
transition: border-color 0.2s ease;
|
||||
}
|
||||
.field-wrapper.active .input-box {
|
||||
border: 2px solid #009fe3;
|
||||
}
|
||||
/* Floating label inside the input box, vertically centered */
|
||||
.field-wrapper label {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
top: 0;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
pointer-events: none;
|
||||
font-size: 16px;
|
||||
color: #666;
|
||||
background: transparent;
|
||||
transition: all 0.18s cubic-bezier(.4,0,.2,1);
|
||||
padding: 0 12px;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
/* Float label above input when focused or filled */
|
||||
.field-wrapper.active label,
|
||||
.field-wrapper.filled label {
|
||||
left: 12px;
|
||||
right: auto;
|
||||
top: -10px;
|
||||
height: auto;
|
||||
font-size: 14px;
|
||||
color: #009fe3;
|
||||
background: #f4f4f4;
|
||||
padding: 0 4px;
|
||||
justify-content: flex-start;
|
||||
align-items: flex-end;
|
||||
}
|
||||
|
||||
/* Responsive */
|
||||
@media (max-width: 768px) {
|
||||
.login-left{
|
||||
display: none;
|
||||
.login-container {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.login-left {
|
||||
height: 200px;
|
||||
min-width: 100%;
|
||||
flex: none;
|
||||
}
|
||||
|
||||
.bg-image { html, body{
|
||||
overflow:auto;
|
||||
}
|
||||
object-fit: cover;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
/* Focus the entire login panel (inputs, buttons, numpad) in the center */
|
||||
.login-right {
|
||||
flex: none;
|
||||
width: 100%;
|
||||
padding: 20px;
|
||||
position: fixed;
|
||||
left: 50%;
|
||||
top: 51%;
|
||||
transform: translate(-50%, -50%);
|
||||
z-index: 1000;
|
||||
background: #f4f4f4;
|
||||
box-shadow: 0 2px 16px rgba(0,0,0,0.15);
|
||||
border-radius: 12px;
|
||||
/* Optional: add max-width for better appearance */
|
||||
max-width: 400px;
|
||||
}
|
||||
|
||||
.numpad {
|
||||
max-width: 100%;
|
||||
position: static;
|
||||
left: auto;
|
||||
top: auto;
|
||||
transform: none;
|
||||
z-index: auto;
|
||||
background: none;
|
||||
box-shadow: none;
|
||||
border-radius: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.row button {
|
||||
font-size: 16px;
|
||||
padding: 12px;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
.form-wrapper {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
|
||||
@media(min-height: 600px) and (max-height: 725px){
|
||||
.login-right{
|
||||
height: 100%;
|
||||
}
|
||||
.btn{
|
||||
height: 3rem;
|
||||
}
|
||||
}
|
||||
@ -3,12 +3,12 @@
|
||||
<span>BANGALORE TURF CLUB LTD</span>
|
||||
</div>
|
||||
|
||||
<!-- Main Login Container -->
|
||||
<!-- Main Login Container ---->
|
||||
<div class="login-container">
|
||||
<!-- Left Image -->
|
||||
<div class="login-left">
|
||||
<img
|
||||
src="./assets/image.jpg"
|
||||
src="./assets/img.jpg"
|
||||
alt="Horse Racing"
|
||||
class="bg-image"
|
||||
/>
|
||||
@ -17,40 +17,49 @@
|
||||
<!-- Right Panel -->
|
||||
<div class="login-right">
|
||||
<div class="logo">
|
||||
<strong>BTC</strong>
|
||||
<img src="./assets/newlogo.png" alt="logo" class="logo_img">
|
||||
<span>BANGALORE TURF CLUB LTD</span>
|
||||
</div>
|
||||
|
||||
<div class="form-wrapper" [formGroup]="loginForm">
|
||||
<!-- Username Errors -->
|
||||
<div class="error-message" *ngIf="loginForm.get('email')?.touched && loginForm.get('email')?.invalid">
|
||||
<small *ngIf="loginForm.get('email')?.errors?.['required']">Username is required.</small>
|
||||
<small *ngIf="loginForm.get('email')?.errors?.['pattern']">Must be exactly 12 digits.</small>
|
||||
<form class="form-wrapper" [formGroup]="loginForm">
|
||||
<!-- ────── USERNAME ────── -->
|
||||
<div
|
||||
class="field-wrapper"
|
||||
[ngClass]="{
|
||||
active: focusedField === 'email',
|
||||
filled: loginForm.get('email')?.value
|
||||
}"
|
||||
>
|
||||
<input
|
||||
#emailInput
|
||||
type="text"
|
||||
class="input-box"
|
||||
readonly
|
||||
(focus)="setFocus('email')"
|
||||
[value]="formatUsernameDisplay(loginForm.get('email')?.value || '')"
|
||||
/>
|
||||
<label for="emailInput">Enter Your Username</label>
|
||||
</div>
|
||||
<input
|
||||
type="text"
|
||||
placeholder="Enter Your Username"
|
||||
class="input-box"
|
||||
(focus)="setFocus('email')"
|
||||
#emailInput
|
||||
[value]="formatUsernameDisplay(loginForm.get('email')?.value || '')"
|
||||
readonly
|
||||
/>
|
||||
|
||||
<!-- Password Errors -->
|
||||
<div 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?.['pattern']">Must be exactly 6 digits.</small>
|
||||
<!-- ────── PASSWORD ────── -->
|
||||
<div
|
||||
class="field-wrapper"
|
||||
[ngClass]="{
|
||||
active: focusedField === 'password',
|
||||
filled: loginForm.get('password')?.value
|
||||
}"
|
||||
>
|
||||
<input
|
||||
#passwordInput
|
||||
type="password"
|
||||
class="input-box"
|
||||
readonly
|
||||
(focus)="setFocus('password')"
|
||||
[value]="loginForm.get('password')?.value || ''"
|
||||
/>
|
||||
<label for="passwordInput">Enter Your Password</label>
|
||||
</div>
|
||||
<input
|
||||
type="password"
|
||||
placeholder="Enter Your Password"
|
||||
class="input-box"
|
||||
formControlName="password"
|
||||
(focus)="setFocus('password')"
|
||||
#passwordInput
|
||||
/>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<!-- Login Button -->
|
||||
<button class="login-btn" (click)="onSubmit()">LOGIN</button>
|
||||
@ -63,23 +72,23 @@
|
||||
|
||||
<div class="numpad">
|
||||
<div class="row">
|
||||
<button (click)="onNumpadClick('0')">0</button>
|
||||
<button class="back-btn" (click)="onBackspace()">BACK</button>
|
||||
<button (click)="onNumpadClick('0')" class="btn">0</button>
|
||||
<button class="back-btn btn" (click)="onBackspace()">BACK</button>
|
||||
</div>
|
||||
<div class="row">
|
||||
<button (click)="onNumpadClick('7')">7</button>
|
||||
<button (click)="onNumpadClick('8')">8</button>
|
||||
<button (click)="onNumpadClick('9')">9</button>
|
||||
<button (click)="onNumpadClick('7')" class="btn">7</button>
|
||||
<button (click)="onNumpadClick('8')" class="btn">8</button>
|
||||
<button (click)="onNumpadClick('9')" class="btn">9</button>
|
||||
</div>
|
||||
<div class="row">
|
||||
<button (click)="onNumpadClick('4')">4</button>
|
||||
<button (click)="onNumpadClick('5')">5</button>
|
||||
<button (click)="onNumpadClick('6')">6</button>
|
||||
<button (click)="onNumpadClick('4')" class="btn">4</button>
|
||||
<button (click)="onNumpadClick('5')" class="btn">5</button>
|
||||
<button (click)="onNumpadClick('6')" class="btn">6</button>
|
||||
</div>
|
||||
<div class="row">
|
||||
<button (click)="onNumpadClick('1')">1</button>
|
||||
<button (click)="onNumpadClick('2')">2</button>
|
||||
<button (click)="onNumpadClick('3')">3</button>
|
||||
<button (click)="onNumpadClick('1')" class="btn">1</button>
|
||||
<button (click)="onNumpadClick('2')" class="btn">2</button>
|
||||
<button (click)="onNumpadClick('3')" class="btn">3</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -87,5 +96,5 @@
|
||||
|
||||
<!-- Bottom Bar -->
|
||||
<div class="bottom-bar">
|
||||
<span>Powered by <strong>Cezen Tech</strong></span>
|
||||
<span>Powered by <strong>Cezen Technologies Pvt. Ltd.</strong></span>
|
||||
</div>
|
||||
|
||||
@ -2,11 +2,13 @@ import { Component, ElementRef, ViewChild, ChangeDetectorRef } from '@angular/co
|
||||
import { FormBuilder, FormGroup, Validators, ReactiveFormsModule } from '@angular/forms';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { Router } from '@angular/router';
|
||||
import { BtcService } from '../service/btc.service';
|
||||
import { HttpClientModule } from '@angular/common/http';
|
||||
|
||||
@Component({
|
||||
selector: 'app-login',
|
||||
standalone: true,
|
||||
imports: [CommonModule, ReactiveFormsModule],
|
||||
imports: [CommonModule, ReactiveFormsModule, HttpClientModule],
|
||||
templateUrl: './login.component.html',
|
||||
styleUrls: ['./login.component.css']
|
||||
})
|
||||
@ -22,7 +24,8 @@ export class LoginComponent {
|
||||
constructor(
|
||||
private fb: FormBuilder,
|
||||
private cdRef: ChangeDetectorRef,
|
||||
private router: Router
|
||||
private router: Router,
|
||||
private btcService: BtcService
|
||||
) {
|
||||
this.loginForm = this.fb.group({
|
||||
email: ['', [Validators.required, Validators.pattern(/^\d{12}$/)]],
|
||||
@ -101,7 +104,13 @@ export class LoginComponent {
|
||||
// if (email === '123456789012' && password === '123456') {
|
||||
// this.loginError = null;
|
||||
console.log('Login successful:', this.loginForm.value);
|
||||
this.router.navigate(['/home']);
|
||||
|
||||
this.btcService.userLogin(this.loginForm.value.email, this.loginForm.value.password).subscribe({
|
||||
next: (employee) => {console.log(employee); this.router.navigate(['/home']);},
|
||||
error: (e) => {console.log(e)}
|
||||
});
|
||||
|
||||
|
||||
// } else {
|
||||
// this.loginError = 'Invalid username or password'; // 🔴 Show error
|
||||
// }
|
||||
|
||||
19
src/app/service/auth.guard.ts
Normal file
19
src/app/service/auth.guard.ts
Normal file
@ -0,0 +1,19 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { CanActivate, Router } from '@angular/router';
|
||||
import { AuthService } from './auth.service';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class AuthGuard implements CanActivate {
|
||||
constructor(private authService: AuthService, private router: Router) {}
|
||||
|
||||
canActivate(): boolean {
|
||||
if (this.authService.isAuthenticated()) {
|
||||
return true;
|
||||
} else {
|
||||
this.router.navigate(['/login']);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
20
src/app/service/auth.service.ts
Normal file
20
src/app/service/auth.service.ts
Normal file
@ -0,0 +1,20 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class AuthService {
|
||||
private authenticated = false;
|
||||
|
||||
isAuthenticated(): boolean {
|
||||
return this.authenticated;
|
||||
}
|
||||
|
||||
setAuthenticated(value: boolean): void {
|
||||
this.authenticated = value;
|
||||
}
|
||||
|
||||
logout(): void {
|
||||
this.authenticated = false;
|
||||
}
|
||||
}
|
||||
42
src/app/service/btc.service.ts
Normal file
42
src/app/service/btc.service.ts
Normal file
@ -0,0 +1,42 @@
|
||||
import { HttpClient, HttpHeaders } from "@angular/common/http";
|
||||
import { Injectable } from "@angular/core";
|
||||
import { ApplicationHttpRouts } from "../constants/http-routs";
|
||||
|
||||
@Injectable({
|
||||
providedIn: "root",
|
||||
})
|
||||
export class BtcService {
|
||||
constructor(private http: HttpClient) {}
|
||||
|
||||
//user login
|
||||
public userLogin(employeeId: string, password: string) {
|
||||
console.log("Login route " + ApplicationHttpRouts.LOG_IN);
|
||||
|
||||
return this.http.get<any>(ApplicationHttpRouts.LOG_IN, {
|
||||
headers: this.basicAuthCredentialsBuilder(employeeId, password),
|
||||
withCredentials: true,
|
||||
observe: "response",
|
||||
});
|
||||
}
|
||||
|
||||
// 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",
|
||||
})
|
||||
}
|
||||
}
|
||||
BIN
src/assets/image2.jpg
Normal file
BIN
src/assets/image2.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 970 KiB |
BIN
src/assets/img.jpg
Normal file
BIN
src/assets/img.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 889 KiB |
BIN
src/assets/logo_w.png
Normal file
BIN
src/assets/logo_w.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 19 KiB |
BIN
src/assets/newlogo.png
Normal file
BIN
src/assets/newlogo.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 73 KiB |
@ -9,8 +9,9 @@ bootstrapApplication(App, appConfig)
|
||||
import { App } from './app/app';
|
||||
import { provideRouter } from '@angular/router';
|
||||
import { routes } from './app/app.routes';
|
||||
import { provideHttpClient } from '@angular/common/http';
|
||||
|
||||
bootstrapApplication(App, {
|
||||
providers: [provideRouter(routes)]
|
||||
providers: [provideRouter(routes), provideHttpClient()]
|
||||
}).catch(err => console.error(err));
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user