// Hotel Walks — Incoming opportunities (receiving hotel side). // IncomingList: a queue with quick accept/pass. // IncomingDetail: full opportunity with revise rate / rooms, accept, pass. (function() { const { useState } = React; const { Caps, Btn, Field, Input, Stepper, Pill, Hr, money } = window.UI; const { INCOMING, ME, HOTEL_BY_ID } = window.HW_DATA; function ListHead() { return (
Inbound queue
{INCOMING.length} opportunities waiting on you.

Each row shows a request from a partner. Accept, pass, or open to negotiate the rate or rooms.

); } function IncomingList() { return (
{["When","From","Rooms","Target","Your rate","Note","Decision"].map((h, i) => (
{h}
))}
{INCOMING.map(op => (
{op.when}
{op.urgent ? Urgent · {op.expiresIn}m : Expires in {op.expiresIn}m}
{op.from.name}
{op.from.area}
{op.rooms} × {op.nights}n
{op.targetRate ? money(op.targetRate) : "—"}
{money(op.myRate)}
{op.notes}
Open → alert("Passed (demo)")}>Pass
))}
); } /* ──────────────────────────────────────────── */ function IncomingDetail({ id }) { const op = INCOMING.find(o => o.id === id); if (!op) return (
Opportunity not found
This request has expired or been withdrawn.
Back to queue
); const [decision, setDecision] = useState(null); // null | "accept" | "revise" | "pass" | "done" const [revisedRooms, setRevisedRooms] = useState(op.rooms); const [revisedRate, setRevisedRate] = useState(String(op.targetRate || op.myRate)); const [confirmation, setConfirmation] = useState(""); if (decision === "done") { return (
Sent
Confirmation returned to {op.from.name}.

We're holding {revisedRooms} room{revisedRooms>1?"s":""} at {money(revisedRate)} per night for the arrival of {op.arrival}. Confirmation number {confirmation || "WY-PENDING"}.

Back to queue Today
); } return (
← Incoming · {op.id} {op.urgent && Urgent · {op.expiresIn}m}
{op.from.name}
requests {op.rooms} room{op.rooms>1?"s":""}
{/* LEFT — request envelope */}
The request
1?"s":""}`} />
Note from sender
"{op.notes}"
What you'll receive
{money((Number(op.targetRate || op.myRate) * op.rooms * op.nights))}
gross · before $4 + 10%
{/* RIGHT — decision panel */}
Your decision {/* Decision tabs */}
{[ ["accept", "Accept as-is"], ["revise", "Counter"], ["pass", "Pass"], ].map(([k, label], i) => ( ))}
{/* Accept */} {decision === "accept" && (
setConfirmation(e.target.value)} placeholder="WY-882190" />

You're confirming {op.rooms} room{op.rooms>1?"s":""} × {op.nights} night{op.nights>1?"s":""} at {money(op.targetRate || op.myRate)} per night, arriving {op.arrival}.

setDecision("done")}> Confirm & return
)} {/* Revise */} {decision === "revise" && (
setRevisedRate(e.target.value.replace(/[^0-9]/g,""))} />
setConfirmation(e.target.value)} placeholder="WY-882190" />

Sender will see the counter immediately. If they accept, the walk letter is generated with these terms.

setDecision("done")}> Return counter
)} {/* Pass */} {decision === "pass" && (

Passing this opportunity tells {op.from.name} we can't accept. They'll route to the next partner.

Reason (optional)
{["Sold out","Rate too low","Wrong date","Other"].map(r => ( ))}
setDecision("done")}> Pass on this walk
)} {/* Initial state — nudge */} {!decision && (
Pick one above
Accept as offered, counter with new terms, or pass.
)}
); } function Row({ k, v }) { return (
{k}
{v}
); } const responsiveCSS = ` @media (max-width: 1000px) { .incoming-grid { grid-template-columns: 1fr !important; gap: 8px !important; padding: 20px 0 !important; } .detail-cols { grid-template-columns: 1fr !important; } .detail-cols > *:first-child { border-right: none !important; border-bottom: 1px solid var(--rule); } } `; function WrappedList() { return (<>); } function WrappedDetail(props) { return (<>); } window.Screens = window.Screens || {}; window.Screens.IncomingList = WrappedList; window.Screens.IncomingDetail = WrappedDetail; })();