Compare commits

..

2 Commits
main ... btc

Author SHA1 Message Date
da12f3bbdc Race card 2025-07-22 16:09:03 +05:30
a6c1668fed updated shared screen styling 2025-07-10 16:23:38 +05:30
17 changed files with 168 additions and 50 deletions

View File

@ -0,0 +1,14 @@
body {
background-image: url('../../../assets/horse.jpg');
background-size: cover;
background-position: center;
background-repeat: no-repeat;
background-attachment: fixed;
}
.wrapper{
display: flex;
flex-direction: column;
justify-content: space-between;
}

View File

@ -1,30 +1,45 @@
<div class="d-flex min-vh-100">
<div class="flex-grow-1 d-flex flex-column">
<!-- Header Section: BT No, Date/Time, Venue, Race No (matching navbar style) -->
<div class="top-bar d-flex justify-content-between align-items-center px-3 py-2" style="background:#0d329f; color:white;">
<body>
<div class="d-flex min-vh-100 flex-column">
<!-- Header Section (Navbar) -->
<div class="top-bar d-flex justify-content-between align-items-center px-3 py-2"
style="background:#0d329f; color:white; height: 60px;">
<div class="d-flex align-items-center">
<span class="me-2"><b>B.T.No:1111</b></span>
<span class="date-time">{{ dateTime }}</span>
</div>
<div class="d-flex align-items-center">
<button class="nav-dropdown me-2" style="background:transparent; border:none; color:white;" >
<button class="nav-dropdown me-2" style="background:transparent; border:none; color:white;">
{{ selectedVenue }}
</button>
<button class="nav-dropdown" style="background:transparent; border:none; color:white;" >
<button class="nav-dropdown" style="background:transparent; border:none; color:white;">
{{ selectedRace }}
</button>
</div>
</div>
<!-- Main Content -->
<div class="flex-grow-1 p-3">
<app-middle-section></app-middle-section>
<!-- Main Content Area (fills rest of screen) -->
<div class="flex-grow-1 d-flex flex-column wrapper" style="height: calc(100vh - 60px); margin-top: 2.8rem;">
<!-- Tablet View Touchpad -->
<div *ngIf="isTabletView" class="mt-3">
<app-touch-pad-menu [ticketingActive]="isTicketingActive"></app-touch-pad-menu>
<!-- 70%: Middle Section -->
<div style="flex: 0 0 56%;">
<app-middle-section [containerHeight]="'100%'"></app-middle-section>
</div>
<!-- 30%: Footer -->
<div style="flex: 0 0 10%; background-color: #469c7ba2; margin-bottom: 5rem;">
<!-- You can insert a component or HTML here -->
<div class="h-100 d-flex align-items-center justify-content-center">
<h5 class="mb-0">Live data goes here </h5>
</div>
</div>
</div>
</div>
</body>

View File

@ -23,10 +23,11 @@ div[style*="background-color: black"] .custom-cell {
.middle-section-container {
display: flex;
gap: 1rem;
height: 38vh;
width: 100%;
/* height is now controlled dynamically via [ngStyle] */
}
/* Desktop view (default) */
.main-table {
width: 60%;

View File

@ -1,5 +1,6 @@
<!-- Responsive Container -->
<div class="middle-section-container">
<div class="middle-section-container" [ngStyle]="{ height: containerHeight }">
<!-- Transaction Summary -->
<div class="transaction-summary">
<div
@ -33,7 +34,7 @@
</div>
<!-- Main Table -->
<div class="main-table">
<div class="main-table ">
<div
class="p-2 rounded h-100 d-flex flex-column justify-content-between"
style="background-color: #f1f1f1df"

View File

@ -1,15 +1,32 @@
import { Component } from '@angular/core';
import { CommonModule } from '@angular/common'; // ✅ Import this
// import { Component } from '@angular/core';
// import { CommonModule } from '@angular/common'; // ✅ Import this
// @Component({
// selector: 'app-middle-section',
// standalone: true,
// imports: [CommonModule], // ✅ Add CommonModule here
// templateUrl: './middle-section.component.html',
// styleUrls: ['./middle-section.component.css']
// })
// export class MiddleSectionComponent {
// rows = Array.from({ length: 5 });
// summaryRows = Array.from({ length: 4 }); // 4 empty rows for now
// }
import { Component, Input } from '@angular/core';
import { CommonModule } from '@angular/common';
@Component({
selector: 'app-middle-section',
standalone: true,
imports: [CommonModule], // ✅ Add CommonModule here
imports: [CommonModule],
templateUrl: './middle-section.component.html',
styleUrls: ['./middle-section.component.css']
})
export class MiddleSectionComponent {
@Input() containerHeight: string = '50vh'; // default for home screen
rows = Array.from({ length: 5 });
summaryRows = Array.from({ length: 4 }); // 4 empty rows for now
}

View File

@ -1,6 +1,6 @@
export class ApplicationHttpRouts {
private static readonly PROTOCOL: string = 'http';
private static readonly BACKEND_SERVER: string = '172.20.100.122';
private static readonly BACKEND_SERVER: string = '192.168.1.110';
private static readonly FRONT_PORT_NUMBER: string = '4200';
private static readonly PORT_NUMBER: string = '8083';
private static readonly SOCKET: string = `${this.PROTOCOL}://${this.BACKEND_SERVER}:${this.PORT_NUMBER}`;

View File

@ -17,7 +17,7 @@
<!-- Main Content -->
<div class="flex-grow-1 p-3">
<app-middle-section></app-middle-section>
<app-middle-section [containerHeight]="'38vh'"></app-middle-section>
<!-- Tablet View Touchpad -->
<div *ngIf="isTabletView" class="mt-3">

View File

@ -19,7 +19,7 @@
</div>
<!-- Scan Enable/Disable Toggle Button -->
<button
<!-- <button
type="button"
class="scan-toggle-btn"
(click)="toggleScan()"
@ -27,7 +27,7 @@
style="margin-bottom: 10px"
>
Scanner: {{ scanningEnabled ? "ON" : "OFF" }}
</button>
</button> -->
<!-- End Scan Toggle Button -->
<!-- Login Form -->

View File

@ -221,19 +221,19 @@ export class LoginComponent implements OnInit, OnDestroy {
// 🖨️ Print logic commented out
// 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');
// })
// .catch((err) => {
// console.error('‼️ Print failed', err);
// this.loginError = 'Login OK, but printing failed.';
// });
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');
})
.catch((err) => {
console.error('‼️ Print failed', err);
this.loginError = 'Login OK, but printing failed.';
});
// ✅ Open secondary screen after login

BIN
btc-UI/src/assets/horse.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 558 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 373 KiB

View File

@ -0,0 +1,9 @@
package com.example.cezenBTC.DTO.race_card;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
public record Pools(Map<String, Set<Integer>> comboRaces) {
}

View File

@ -0,0 +1,8 @@
package com.example.cezenBTC.DTO.race_card;
import java.time.LocalDate;
import java.util.List;
import java.util.Set;
public record RaceCard(String Venue, LocalDate date, RaceVenueRaces raceVenueRaces, Pools pools) {
}

View File

@ -0,0 +1,9 @@
package com.example.cezenBTC.DTO.race_card;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
public record RaceVenueRaces(Set<Set<Integer>> races) {
}

View File

@ -103,6 +103,7 @@ public class CezenRoutsSecurityChain {
"/btc/get_all_venues",
"/btc/get_races_by_venue_id",
"/btc/get_all_races_by_today",
"/btc/get_race_card",
"/cezen/set_aors",
"/cezen/set_password",
"/cezen/add_extension"

View File

@ -1,9 +1,11 @@
package com.example.cezenBTC.controller;
import com.example.cezenBTC.DTO.race_card.RaceCard;
import com.example.cezenBTC.entity.btc_entity.RaceNumber;
import com.example.cezenBTC.entity.btc_entity.RaceVenue;
import com.example.cezenBTC.service.BtcRaceService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
@ -39,4 +41,10 @@ public class BtcOperations {
return this.btcRaceService.getAllRacesByDateService(LocalDate.now());
}
@GetMapping("/get_race_card")
public ResponseEntity<RaceCard> getRaceCard(){
return this.btcRaceService.getRaceCard(LocalDate.now());
}
}

View File

@ -2,13 +2,17 @@ package com.example.cezenBTC.service;
import com.example.cezenBTC.DAO.BtcOpsDAO;
import com.example.cezenBTC.DTO.ReturnStatus;
import com.example.cezenBTC.DTO.race_card.Pools;
import com.example.cezenBTC.DTO.race_card.RaceCard;
import com.example.cezenBTC.DTO.race_card.RaceVenueRaces;
import com.example.cezenBTC.entity.btc_entity.RaceNumber;
import com.example.cezenBTC.entity.btc_entity.RaceVenue;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import java.time.LocalDate;
import java.util.List;
import java.util.*;
@Service
public class BtcRaceService {
@ -79,4 +83,35 @@ public class BtcRaceService {
return null;
}
}
public ResponseEntity<RaceCard> getRaceCard(LocalDate date){
//create race numbers
Set<Integer> races1 = new LinkedHashSet<>(List.of(1,2,3,4,5,6,7,8,10));
Set<Integer> races2 = new LinkedHashSet<>(List.of(2,4,6,8,10,12));
Set<Integer> races3 = new LinkedHashSet<>(List.of(1,2,3,5,7,8,9,10,11));
Set<Integer> races4 = new LinkedHashSet<>(List.of(1,2,3,4,5,6,7,8,10,12,13));
// create a Venue
Set<Set<Integer>> mysRaces = new LinkedHashSet<>();
mysRaces.add(races1);
mysRaces.add(races2);
mysRaces.add(races3);
mysRaces.add(races4);
RaceVenueRaces raceVenueMYS = new RaceVenueRaces(mysRaces);
//create a Pool combination
Set<Integer> pool1 = new LinkedHashSet<>(List.of(5, 6, 7));
Set<Integer> pool2 = new LinkedHashSet<>(List.of(1, 2, 3));
// pole id to pool combo
Map<String, Set<Integer>> mysPools = new LinkedHashMap<>();
mysPools.put("TRB2", pool1);
mysPools.put("MJP1", pool2);
Pools mysPool = new Pools(mysPools);
RaceCard raceCard = new RaceCard("MYS", date, raceVenueMYS, mysPool);
return ResponseEntity.status(200).body(raceCard);
}
}