);
}
/* -------------------- BOOKING (claim a spot in the DIV Tour entry) -------------------- */
function SeatFilled({ p, you, onRemove, onMove, onTransport, approved }) {
return (
);
}
function SeatOpen({ onClaim, canClaim, manager }) {
if (manager) {
return (
);
}
return (
);
}
function BookingScreen({ ctx }) {
const Y = window.YCC;
const { tour, dayKeys, member, requestClaim, role, t, go, activeManager, removeSignup, requestManagerMove, requestAddPlayer, setTransport, managerSwapPlayers, managerMovePlayer, phase, entry, confirmedNames, requestManagerEmail, primaryManager } = ctx;
const [activeDay, setActiveDay] = useState(dayKeys[0].iso);
const dragRef = useRef(null);
const [dragName, setDragName] = useState(null);
const slots = Y.sortByTime(tour.slots[activeDay] || []);
const dayNote = (tour.notes || {})[activeDay];
const flow = t.bookingFlow || "sheet";
const isManager = role === "manager";
const myDaySlot = slots.find(s => s.players.some(p => p.name === member.name));
const memberOpen = phase === "open"; // members can self-serve only while open
const managerLocked = false; // managers keep control through game day
const isApproved = (p) => p.guest || (confirmedNames && confirmedNames.has(p.name));
const fmtET = (d) => d.toLocaleString("en-US", { weekday: "short", month: "short", day: "numeric", hour: "numeric", minute: "2-digit" });
// game-day drag/drop: drop A onto B → swap; drop A onto an open seat → move.
function handleSeatDrop(dstSlotId, dstName) {
const src = dragRef.current; dragRef.current = null; setDragName(null);
if (!src) return;
if (dstName) managerSwapPlayers(activeDay, src.slotId, src.name, dstSlotId, dstName);
else if (src.slotId !== dstSlotId) managerMovePlayer(activeDay, src.slotId, dstSlotId, src.name);
}
if (!tour.published && !isManager) {
return (
This weekend isn't published yet
{activeManager.name} hasn't released the DIV Tour tee times for {tour.weekendLabel}. You'll be notified by email when sign-up opens.
);
}
return (
DIV Tour · Weekend of {tour.weekendLabel}
{isManager ? "Tee sheet" : "Tee times"}
{isManager
? "Live view of who has claimed a spot in this weekend's published entry. Edit the times in Tour Setup."
: "Claim an open spot in any group. Your handicap and GHIN are attached automatically when you join."}
Published by {activeManager.name}
{tour.publishedAt}
{/* sign-up window banner */}
{(() => {
const map = {
open: { bg: "var(--brand-soft)", fg: "var(--brand)", icon: "calendar", text: <>Open sign-ups — claim, move, or release your own spot until Wednesday 11:59 PM ET ({fmtET(entry.wed)}). After that, changes go through your manager.> },
managerOnly: { bg: "color-mix(in srgb,var(--accent) 14%,var(--surface))", fg: "var(--accent-deep)", icon: "shield", text: <>Member sign-ups are closed. Your manager can add, release, or move players until the final lock Friday 9:00 AM ET ({fmtET(entry.fri)}). Ask your manager for any changes.> },
locked: { bg: "var(--surface-2)", fg: "var(--ink-soft)", icon: "clock", text: <>Groups are final — the Friday 9:00 AM ET lock has passed. The tee sheet is set for the weekend.> },
}[phase];
return (
{map.text}
{!isManager && phase !== "open" && (
)}
);
})()}
{/* day tabs */}
{dayKeys.map((d) => {
const daySlots = tour.slots[d.iso] || [];
const open = daySlots.reduce((n, s) => n + (4 - s.players.length), 0);
const active = activeDay === d.iso;
return (
);
})}
{myDaySlot && !isManager && (
You're in the {myDaySlot.time} group
)}
{dayNote && slots.length > 0 && (
Club event this day. {dayNote}
)}
{isManager && slots.length > 0 && (
Drag a player onto another to swap their groups, or onto an open seat to move them.
)}
{slots.length === 0 ? (
{dayNote ? "No DIV Tour group times this day" : "No tee times set for this day"}
{dayNote || (isManager ? "Add times in Tour Setup." : "Check back once the manager publishes them.")}