import { useEffect, useState } from "react"; import { Badge } from "@/components/ui/badge"; import { Button } from "@/components/ui/button"; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogTrigger, } from "@/components/ui/dialog"; import { FileUploadField } from "@/components/ui/file-upload-field"; import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from "@/components/ui/select"; import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow, } from "@/components/ui/table"; import { apiGet, apiPatch, apiPost } from "@/lib/api"; import { Spinner } from "@/components/ui/spinner"; import { isLikelyApiHotelRoom, mapApiRoomToRoom, } from "@/lib/hotel-adapters"; import { ROOM_CATALOGUE } from "@/lib/constants"; import type { Room } from "@/lib/types"; import { formatMoney } from "@/lib/format"; import { useAuthStore } from "@/store/authStore"; export function RoomsPage() { const selectedPropertyId = useAuthStore((s) => s.selectedPropertyId); const [rooms, setRooms] = useState([]); const [loading, setLoading] = useState(true); const [submitting, setSubmitting] = useState(false); const [open, setOpen] = useState(false); const [editOpen, setEditOpen] = useState(false); const [editingRoomId, setEditingRoomId] = useState(null); const [name, setName] = useState(""); const [slug, setSlug] = useState(ROOM_CATALOGUE[0].slug); const [maxGuests, setMaxGuests] = useState("2"); const [baseRate, setBaseRate] = useState("120"); const [imageFiles, setImageFiles] = useState([]); function load() { setLoading(true); apiGet<{ data: unknown[] }>("/rooms") .then((r) => { const mapped = r.data.map((row) => isLikelyApiHotelRoom(row) ? mapApiRoomToRoom(row) : (row as Room) ); setRooms(mapped); }) .finally(() => setLoading(false)); } useEffect(() => { load(); }, [selectedPropertyId]); function resetForm() { setEditingRoomId(null); setName(""); setSlug(ROOM_CATALOGUE[0].slug); setMaxGuests("2"); setBaseRate("120"); setImageFiles([]); } async function addRoom(e: React.FormEvent) { e.preventDefault(); setSubmitting(true); try { const formData = new FormData(); formData.append("name", name); formData.append("roomType", slug); formData.append("maxGuests", maxGuests); formData.append("baseRate", baseRate); imageFiles.forEach((file) => formData.append("images", file)); await apiPost("/rooms", formData); setOpen(false); resetForm(); load(); } finally { setSubmitting(false); } } function startEdit(room: Room) { setEditingRoomId(room.id); setName(room.name); setSlug(room.roomTypeSlug); setMaxGuests(String(room.maxGuests)); setBaseRate(String(room.baseRate)); setImageFiles([]); setEditOpen(true); } async function updateRoom(e: React.FormEvent) { e.preventDefault(); if (!editingRoomId) return; setSubmitting(true); try { const formData = new FormData(); formData.append("name", name); formData.append("roomType", slug); formData.append("maxGuests", maxGuests); formData.append("baseRate", baseRate); imageFiles.forEach((file) => formData.append("images", file)); await apiPatch(`/rooms/${editingRoomId}`, formData); setEditOpen(false); resetForm(); load(); } finally { setSubmitting(false); } } if (loading && rooms.length === 0) return (
); return (

Rooms

{ setOpen(next); if (!next) resetForm(); }} > Add room
setName(e.target.value)} />
setMaxGuests(e.target.value)} />
setBaseRate(e.target.value)} />
setImageFiles(Array.from(e.target.files ?? []))} />
{ setEditOpen(next); if (!next) resetForm(); }} > Edit room
setName(e.target.value)} />
setMaxGuests(e.target.value)} />
setBaseRate(e.target.value)} />
setImageFiles(Array.from(e.target.files ?? []))} />
List Name Type Guests Rate Status {rooms.map((r) => ( {r.imageKeys?.length > 0 ? ( {r.name} ) : (
No Image
)}
{r.name} {r.roomTypeSlug} {r.maxGuests} {formatMoney(r.baseRate)} {r.status}
))}
{rooms.map((r) => (

{r.name}

{r.roomTypeSlug} ยท {formatMoney(r.baseRate)}

{r.status}
))}
); }