diff --git a/backend/docs/swagger.yaml b/backend/docs/swagger.yaml index 0b773456..8db8bc6a 100644 --- a/backend/docs/swagger.yaml +++ b/backend/docs/swagger.yaml @@ -66,6 +66,7 @@ definitions: type: integer type: array limit: + minimum: 0 type: integer type: object GenerateRequestInput: diff --git a/clients/web/src/components/rooms/FilterTag.tsx b/clients/web/src/components/rooms/FilterTag.tsx new file mode 100644 index 00000000..12e58291 --- /dev/null +++ b/clients/web/src/components/rooms/FilterTag.tsx @@ -0,0 +1,28 @@ +import { X } from "lucide-react"; +import { cn } from "@/lib/utils"; + +type FilterTagProps = { + label: string; + onRemove: () => void; + className?: string; +}; + +export function FilterTag({ label, onRemove, className }: FilterTagProps) { + return ( +
+ {label} + +
+ ); +} diff --git a/clients/web/src/components/rooms/OrderByDropdown.tsx b/clients/web/src/components/rooms/OrderByDropdown.tsx new file mode 100644 index 00000000..ba5ef2ce --- /dev/null +++ b/clients/web/src/components/rooms/OrderByDropdown.tsx @@ -0,0 +1,60 @@ +import { ChevronDown } from "lucide-react"; +import { useState } from "react"; +import { cn } from "@/lib/utils"; + +type OrderByDropdownProps = { + ascending: boolean; + setAscending: (ascending: boolean) => void; +}; + +export function OrderByDropdown({ + ascending, + setAscending, +}: OrderByDropdownProps) { + const [open, setOpen] = useState(false); + const label = ascending ? "Ascending" : "Descending"; + + return ( +
{ + if (!e.currentTarget.contains(e.relatedTarget)) setOpen(false); + }} + > + + + {open && ( +
+ +
+ )} +
+ ); +} diff --git a/clients/web/src/components/rooms/RoomsList.tsx b/clients/web/src/components/rooms/RoomsList.tsx index 58777a41..cc3e335a 100644 --- a/clients/web/src/components/rooms/RoomsList.tsx +++ b/clients/web/src/components/rooms/RoomsList.tsx @@ -1,22 +1,41 @@ +import { useMemo } from "react"; import type { RoomWithOptionalGuestBooking } from "@shared"; import { RoomCard } from "@/components/rooms/RoomCard"; type RoomsListProps = { rooms: Array; onRoomSelect: (room: RoomWithOptionalGuestBooking) => void; + ascending: boolean; selectedRoomNumber?: number | null; }; +function sortRoomsByRoomNumber( + rooms: Array, + ascending: boolean, +): Array { + return [...rooms].sort((a, b) => { + const an = a.room_number ?? 0; + const bn = b.room_number ?? 0; + return ascending ? an - bn : bn - an; + }); +} + export function RoomsList({ rooms, onRoomSelect, + ascending, selectedRoomNumber = null, }: RoomsListProps) { + const sortedRooms = useMemo( + () => sortRoomsByRoomNumber(rooms, ascending), + [rooms, ascending], + ); + return (