diff --git a/frontend/src/pages/BookingDetail.tsx b/frontend/src/pages/BookingDetail.tsx index 0c29cf0..4303610 100644 --- a/frontend/src/pages/BookingDetail.tsx +++ b/frontend/src/pages/BookingDetail.tsx @@ -4,6 +4,8 @@ import { api } from "../api/client"; import type { Booking, RegisterReturnResult } from "../api/types"; import { StatusBadge } from "../components/Badge"; import { ReturnForm, ReturnResultPanel } from "../components/ReturnForm"; +import { Icon } from "../components/Icons"; +import { ErrorState, LoadingState, PageHeader } from "../components/PageChrome"; export function BookingDetail() { const { publicRef } = useParams<{ publicRef: string }>(); @@ -31,15 +33,14 @@ export function BookingDetail() { load(); } - if (error) return

{error}

; - if (!booking) return

Loading booking…

; + if (error) return ; + if (!booking) return ; return (
-

← Back to bookings

-

{booking.public_ref}

-

-
+ Booking ledger + } /> +
Customer
{booking.customer_name} ({booking.customer_ref})
Vehicle
{booking.vehicle_ref}
Starts
{new Date(booking.starts_at).toLocaleString("en-GB", { timeZone: "Europe/Brussels" })}
@@ -47,7 +48,7 @@ export function BookingDetail() {
Start odometer
{booking.start_odometer_km ?? "—"} km
End odometer
{booking.end_odometer_km ?? "—"} km
Requirements complete
{booking.requirements_complete ? "Yes" : "No"}
-
+
{returnResult && } {!returnResult && booking.status === "active" && ( diff --git a/frontend/src/pages/Bookings.tsx b/frontend/src/pages/Bookings.tsx index b2fe9b2..ac02d2a 100644 --- a/frontend/src/pages/Bookings.tsx +++ b/frontend/src/pages/Bookings.tsx @@ -3,6 +3,7 @@ import { Link } from "react-router-dom"; import { api } from "../api/client"; import type { Booking } from "../api/types"; import { StatusBadge } from "../components/Badge"; +import { EmptyState, ErrorState, LoadingState, PageHeader } from "../components/PageChrome"; const STATUS_OPTIONS = ["reserved", "active", "returned", "cancelled", "blocked"]; @@ -10,8 +11,13 @@ export function Bookings() { const [bookings, setBookings] = useState(null); const [error, setError] = useState(null); const [status, setStatus] = useState(""); + const [query, setQuery] = useState(""); + const [page, setPage] = useState(1); + const perPage = 25; useEffect(() => { + setBookings(null); + setError(null); const params = new URLSearchParams(); if (status) params.set("status", status); api @@ -22,12 +28,16 @@ export function Bookings() { return (
-

Bookings

+
+
- {error &&

{error}

} - {!error && !bookings &&

Loading bookings…

} - {bookings && bookings.length === 0 &&

No bookings match these filters.

} + {error && } + {!error && !bookings && } + {bookings && bookings.length === 0 && } - {bookings && bookings.length > 0 && ( - + {bookings && bookings.length > 0 && (() => { + const filtered = bookings.filter((b) => `${b.public_ref} ${b.customer_name} ${b.vehicle_ref}`.toLowerCase().includes(query.toLowerCase())); + const totalPages = Math.max(1, Math.ceil(filtered.length / perPage)); + const visible = filtered.slice((page - 1) * perPage, page * perPage); + return filtered.length === 0 ? :
{filtered.length} bookingsPage {page} of {totalPages}
@@ -57,24 +70,24 @@ export function Bookings() { {bookings.map((b) => ( - - - + - - ))} -
Bookings
+ {b.public_ref} {b.customer_name} + {b.customer_name} {b.vehicle_ref} + {new Date(b.starts_at).toLocaleDateString("en-GB")} → {new Date(b.ends_at).toLocaleDateString("en-GB")} +
- )} +
{(page - 1) * perPage + 1}–{Math.min(page * perPage, filtered.length)} of {filtered.length}
; + })()}
); } diff --git a/frontend/src/pages/VehicleDetail.tsx b/frontend/src/pages/VehicleDetail.tsx index aba10f5..fe6f3fd 100644 --- a/frontend/src/pages/VehicleDetail.tsx +++ b/frontend/src/pages/VehicleDetail.tsx @@ -3,6 +3,8 @@ import { Link, useParams } from "react-router-dom"; import { api } from "../api/client"; import type { VehicleDetail as VehicleDetailData } from "../api/types"; import { SeverityBadge, StatusBadge } from "../components/Badge"; +import { Icon } from "../components/Icons"; +import { ErrorState, LoadingState, PageHeader } from "../components/PageChrome"; const TABS = ["overview", "bookings", "inspections", "maintenance", "quality"] as const; type Tab = (typeof TABS)[number]; @@ -23,21 +25,15 @@ export function VehicleDetail() { .catch(() => setError("This vehicle could not be found.")); }, [publicRef]); - if (error) return

{error}

; - if (!vehicle) return

Loading vehicle…

; + if (error) return ; + if (!vehicle) return ; return (
-

← Back to vehicles

-

- {vehicle.public_ref} — {vehicle.make} {vehicle.model} -

-

- - {vehicle.attention && Needs attention} -

+ Fleet registry + {vehicle.attention && Needs attention}
} /> -
+
{TABS.map((t) => (