import { useEffect, useState } from 'react'; import { api, type Hotel } from './api'; import { hotelTime } from './time'; type Snapshot={id:string;reservationId:string;confirmation:string;guestName:string;arrival:string;departure:string;status:string;roomType:string;total:string;fetchedAt:string}; type Change={id:string;reservationId:string;kind:string;arrival:string;departure:string;note:string;state:string;detail:string;version:number;updatedAt:string;expiresAt:string;before:Snapshot;after:Snapshot|null}; type Connection={configured:boolean;writesConfigured:boolean;hotelCode:string;preview:boolean}; type Props={hotel:Hotel;owner:boolean;canPropose:boolean;busy:boolean;run:(f:()=>Promise)=>Promise;onHotel:(h:Hotel)=>void}; export function PmsPage({hotel,owner,canPropose,busy,run,onHotel}:Props){ const [connection,setConnection]=useState(null),[changes,setChanges]=useState([]),[confirmation,setConfirmation]=useState(''),[snapshot,setSnapshot]=useState(null); const [kind,setKind]=useState('AddNote'),[arrival,setArrival]=useState(''),[departure,setDeparture]=useState(''),[note,setNote]=useState(''),[selected,setSelected]=useState(null),[checked,setChecked]=useState(false); async function refresh(){const [status,history]=await Promise.all([api('/pms/status'),api('/pms/changes')]);setConnection(status);setChanges(history);} useEffect(()=>{run(refresh);},[hotel.id]); const current=changes.find(c=>c.id===selected); function update(change:Change){setChanges(old=>[change,...old.filter(c=>c.id!==change.id)]);setSelected(change.id);setChecked(false);} async function lookup(e:React.FormEvent){e.preventDefault();await run(async()=>{const found=await api('/pms/lookup','POST',{confirmation:confirmation.trim()});setSnapshot(found);setArrival(found.arrival);setDeparture(found.departure);setSelected(null);setNote('');setChecked(false);});} async function propose(e:React.FormEvent){e.preventDefault();if(!snapshot)return;await run(async()=>update(await api('/pms/changes','POST',{snapshotId:snapshot.id,kind,arrival,departure,note})));} async function action(name:string){if(!current)return;await run(async()=>{ if(name==='apply'&&!window.confirm(`Apply this change to OHIP reservation ${current.before.confirmation} for ${current.before.guestName||'the displayed guest'}?\n\n${current.kind==='StayDates'?`${current.before.arrival} – ${current.before.departure} → ${current.arrival} – ${current.departure}`:current.note}\n\nThis changes the live PMS selected by your administrator.`))return; update(await api(`/pms/changes/${current.id}/${name}`,'POST',{version:current.version,availabilityAndPriceChecked:checked})); });} return
Booking details, close at hand

Reservations

Look up a booking and review changes before applying them to your PMS.

OHIP connection

{connection?.configured?`Connected configuration for property ${connection.hotelCode}. Lookup will verify access.`:connection?.preview?'Sample workspace: real PMS lookup and updates are disabled.':'Your administrator needs to configure this hotel’s OHIP connection.'}

GuestOps hotel ID: {hotel.id}

Lookup is available separately. Every change needs review; automatic PMS updates are off.

Find a reservation

{snapshot&&<>
{kind==='AddNote'?