// screens-admin-schedule.jsx — Admin schedule ops + session edit sheet const { fmtIDR, findClass, findCoach, DAYS_SHORT, DAYS_LONG, DATES_THIS_WEEK, TODAY_DAY } = window.NADI_HELPERS; function AdminScheduleScreen({ openSession, openAddSession, showToast }) { const [day, setDay] = useState(TODAY_DAY); const sessions = window.NADI.SCHEDULE.filter((s) => s.day === day).sort((a, b) => a.time.localeCompare(b.time)); // Total this day const totalBooked = sessions.reduce((s, x) => s + x.booked, 0); const totalCap = sessions.reduce((s, x) => s + x.capacity, 0); const fillPct = Math.round((totalBooked / totalCap) * 100); return (
{/* Header */}
schedule · this week

{day === TODAY_DAY ? <>Today, {DAYS_LONG[day].toLowerCase()}. : <>{DAYS_LONG[day]}.}

{sessions.length} sessions · {totalBooked}/{totalCap} seats ({fillPct}% full)
{/* Sessions list */}
{sessions.map((s) => openSession(s)} />)}
); } function AdminDayStrip({ day, setDay }) { return (
{DAYS_SHORT.map((d, i) => { const active = i === day; const isToday = i === TODAY_DAY; return ( ); })}
); } function AdminSessionRow({ s, onClick }) { const c = findClass(s.classId), co = findCoach(s.coachId); const left = s.capacity - s.booked; const full = left === 0; const pct = Math.round((s.booked / s.capacity) * 100); return ( ); } // ── Session edit sheet (used from admin schedule + now) ──────────── function AdminSessionSheet({ session, onClose, showToast, openRoster }) { if (!session) return null; const c = findClass(session.classId), co = findCoach(session.coachId); const checkin = (window.NADI_ADMIN.CHECKINS && window.NADI_ADMIN.CHECKINS[session.id]) || { checked: 0 }; const isPast = session.day < TODAY_DAY || (session.day === TODAY_DAY && session.time < "14:08"); const pct = Math.round((session.booked / session.capacity) * 100); return (
{DAYS_LONG[session.day].toLowerCase()} · {session.time} · {c.duration}m

{c.name}

with {co.name.toLowerCase()} · {session.roomShort.toLowerCase()} {/* Capacity bar */}
occupancy {session.booked}/{session.capacity} · {pct}%
{/* Detail grid */}
0 ? `${session.waitlistCount} waiting` : "—"} sub={session.waitlistCount > 0 ? "promote on cancel" : "open"} />
{/* Quick actions */}
{/* Notify attendees */}
notify attendees

Push a quick note to everyone booked — late teacher, room change, weather.

); } // ── Roster sheet (member list for a session) ────────────────────── function AdminRosterSheet({ session, onClose, openMember, showToast }) { if (!session) return null; const c = findClass(session.classId); // Mock roster — take the friends + a few members const friendIds = session.friends; const friendMembers = friendIds.map((fid) => { // Friends map approximately to members by initials const f = window.NADI.FRIENDS.find((x) => x.id === fid); if (!f) return null; return { id: fid, name: f.name + " " + (f.id === "f1" ? "Putri" : ""), initials: f.initials, tone: f.tone }; }).filter(Boolean); const extra = window.NADI_ADMIN.MEMBERS.slice(0, session.booked - friendMembers.length).map((m) => ({ id: m.id, name: m.name, initials: m.initials, tone: m.tone, memberId: m.id, })); const roster = [...friendMembers, ...extra]; const dateStr = session.date ? window.NADI_HELPERS.parseLocalDate(session.date).toLocaleDateString("en-GB", { day: "2-digit", month: "short" }).toLowerCase() : ""; const nameSuffix = dateStr ? ` (${dateStr})` : ""; return (
roster · {DAYS_LONG[session.day].toLowerCase()} · {session.time}

{c.name}

{session.booked} booked · {session.capacity - session.booked} open
{roster.map((r, i) => ( ))}
); } // ── Add session sheet ──────────────────────────────────────────── function AdminAddSessionSheet({ open, onClose, showToast }) { const [classId, setClassId] = useState("hatha"); const [coachId, setCoachId] = useState("ayu"); const [day, setDay] = useState(TODAY_DAY); const [time, setTime] = useState("18:00"); const [room, setRoom] = useState(0); const [capacity, setCapacity] = useState(14); return (
schedule · add session

New session.

class type
{window.NADI.CLASS_TYPES.map((c) => ( setClassId(c.id)}>{c.name.toLowerCase()} ))}
teacher
{window.NADI.COACHES.map((co) => ( setCoachId(co.id)}>{co.firstName.toLowerCase()} ))}
day
{DAYS_SHORT.map((d, i) => ( setDay(i)}>{d.toLowerCase()} ))}
room
{window.NADI.STUDIOS.map((st, i) => ( setRoom(i)}>{st.name.toLowerCase()} ))}
); } Object.assign(window, { AdminScheduleScreen, AdminSessionRow, AdminSessionSheet, AdminRosterSheet, AdminAddSessionSheet, });