Files
TS_Proto/frontend/src/app/features/bookings/bookings.html
T
nilesh.pandClaude Opus 4.8 4d3eb18a6c Initial commit: TravelHub multi-tenant flight booking platform
Angular + Go + PostgreSQL sample with strict per-tenant isolation.

- Backend: Go API (basic auth, tenant-scoped repository layer, pgx pool)
- Frontend: Angular 22 SPA (search, checkout, bookings, dashboard)
- Database: schema, seed data and demo bookings migrations
- Tests: 311 across Go (integration), Angular (unit) and Playwright (e2e),
  plus a generated evidence report with PDF export
- Security: whitebox VAPT report under security/

Secrets (.env, tokens, DB credentials) are git-ignored.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-09-13 11:38:01 +05:30

106 lines
3.1 KiB
HTML

<div class="page-head">
<div>
<h1>Bookings</h1>
<p class="subtitle">Every reservation sold by your agency.</p>
</div>
<a routerLink="/search" class="btn btn-primary btn-sm">+ New booking</a>
</div>
<div class="filters" role="group" aria-label="Filter by status">
<button
type="button"
class="filter"
[class.active]="status() === ''"
(click)="filterBy('')"
>
All
</button>
<button
type="button"
class="filter"
[class.active]="status() === 'confirmed'"
(click)="filterBy('confirmed')"
>
Confirmed
</button>
<button
type="button"
class="filter"
[class.active]="status() === 'cancelled'"
(click)="filterBy('cancelled')"
>
Cancelled
</button>
</div>
@if (error()) {
<div class="alert alert-error" role="alert">{{ error() }}</div>
}
@if (loading()) {
<div class="card card-pad"><div class="skeleton" style="height: 260px"></div></div>
} @else if (bookings().length === 0) {
<div class="card empty">
<h3>No bookings yet</h3>
<p>Search for a flight to create the first reservation.</p>
<p style="margin-top: 14px">
<a routerLink="/search" class="btn btn-primary btn-sm">Search flights</a>
</p>
</div>
} @else {
<div class="card table-wrap">
<table class="data">
<thead>
<tr>
<th>Reference</th>
<th>Route</th>
<th>Departure</th>
<th>Travellers</th>
<th>Total</th>
<th>Status</th>
<th>Booked by</th>
<th></th>
</tr>
</thead>
<tbody>
@for (booking of bookings(); track booking.id) {
<tr>
<td><span class="pnr">{{ booking.bookingReference }}</span></td>
<td>
<span class="route">
{{ booking.flight.origin.iataCode }} → {{ booking.flight.destination.iataCode }}
</span>
<span class="route-meta">
{{ booking.flight.airline.iataCode }} {{ booking.flight.flightNumber }}
</span>
</td>
<td class="tabular">{{ booking.flight.departureTime | date: 'd MMM y, HH:mm' }}</td>
<td class="tabular">{{ booking.passengerCount }}</td>
<td class="tabular">
{{ booking.totalAmount | currency: booking.currency : 'symbol' : '1.2-2' }}
</td>
<td>
<span class="badge" [class]="'badge-' + booking.status">{{ booking.status }}</span>
</td>
<td class="muted">{{ booking.bookedBy }}</td>
<td class="right">
<a [routerLink]="['/bookings', booking.id]" class="btn btn-ghost btn-sm">View</a>
</td>
</tr>
}
</tbody>
</table>
</div>
@if (canPrev() || canNext()) {
<nav class="pager" aria-label="Pagination">
<button type="button" class="btn btn-ghost btn-sm" [disabled]="!canPrev()" (click)="prevPage()">
← Previous
</button>
<button type="button" class="btn btn-ghost btn-sm" [disabled]="!canNext()" (click)="nextPage()">
Next →
</button>
</nav>
}
}