// data.jsx — mock data for the mobile prototype const CLASS_TYPES = [ { id: "hatha", name: "Hatha", tagline: "Foundation, breath, alignment", duration: 75, level: "All levels", color: "primary" }, { id: "hip", name: "Hip Opening", tagline: "Release tension, open hips", duration: 60, level: "All levels", color: "accent" }, { id: "inversion", name: "Inversion", tagline: "Headstand, handstand work", duration: 75, level: "Intermediate", color: "primary" }, { id: "beginner", name: "Beginner", tagline: "First steps on the mat", duration: 60, level: "Beginner", color: "muted" }, { id: "stretch", name: "Gentle Stretch",tagline: "Slow, restorative lengthening", duration: 60, level: "All levels", color: "accent" }, { id: "shoulder", name: "Shoulder Care", tagline: "Mobility & release", duration: 60, level: "All levels", color: "muted" }, { id: "slow", name: "Slow Flow", tagline: "Deliberate vinyasa, breath-led", duration: 75, level: "All levels", color: "primary" }, { id: "body", name: "Body Opening", tagline: "Whole-body mobility", duration: 75, level: "All levels", color: "accent" }, { id: "armbalance", name: "Arm Balance", tagline: "Crow, side crow, more", duration: 75, level: "Intermediate", color: "primary" }, { id: "balance", name: "Yoga Balance", tagline: "Stability, focus, strength", duration: 60, level: "All levels", color: "muted" }, ]; const COACHES = [ { id: "ayu", name: "Ayu Pradnyani", firstName: "Ayu", title: "Founder & Lead Teacher", initials: "AP", tone: "#C28464", bio: "Studied Hatha and Vinyasa across Bali and Mysore for 12 years. Believes the breath is the practice.", specialties: ["hatha", "slow", "hip"], yrs: 12 }, { id: "made", name: "Made Wirawan", firstName: "Made", title: "Senior Teacher", initials: "MW", tone: "#8A7E5C", bio: "Background in martial arts and somatic movement. Slow, precise, deeply patient.", specialties: ["beginner", "stretch", "shoulder"], yrs: 8 }, { id: "kade", name: "Kadek Sari", firstName: "Kadek",title: "Inversions & Strength", initials: "KS", tone: "#A14A2E", bio: "From dance into yoga. Loves the playful edge of arm balances and inversions.", specialties: ["inversion", "armbalance", "balance"], yrs: 6 }, { id: "luh", name: "Ni Luh Maharani", firstName: "Luh", title: "Restorative & Yin", initials: "LM", tone: "#6D7A53", bio: "Trauma-informed restorative practice. Long, supported holds.", specialties: ["stretch", "hip", "body"], yrs: 9 }, ]; const PACKAGES = [ { id: "single", name: "Single Class", classes: 1, price: 180000, validityDays: 30, badge: null, desc: "Drop in once — perfect for a try-out." }, { id: "newcomer", name: "Newcomer Trial", classes: 3, price: 300000, validityDays: 30, badge: "First-timers", desc: "Three classes in your first month." }, { id: "five", name: "Standard 5", classes: 5, price: 750000, validityDays: 30, badge: "Most popular", desc: "Five classes within thirty days." }, { id: "ten", name: "Regular 10", classes: 10, price: 1350000, validityDays: 30, badge: null, desc: "For weekly practitioners." }, { id: "season", name: "Devoted 15", classes: 15, price: 1850000, validityDays: 30, badge: "Best value", desc: "Fifteen classes within thirty days." }, ]; const STUDIOS = [ { id: "daun", name: "Daun", full: "Studio A · Daun", desc: "Open-air, rice-field facing" }, { id: "akar", name: "Akar", full: "Studio B · Akar", desc: "Semi-enclosed, garden side" }, ]; const ROOMS = ["Studio A — Daun", "Studio B — Akar"]; const FRIENDS = [ { id: "m1", name: "Sinta", firstName: "Sinta", initials: "SP", tone: "#B5563C" }, { id: "m2", name: "Rio", firstName: "Rio", initials: "RA", tone: "#5C6E47" }, { id: "m3", name: "Maya", firstName: "Maya", initials: "ML", tone: "#8A7E5C" }, { id: "m4", name: "Dewa", firstName: "Dewa", initials: "DA", tone: "#A14A2E" }, { id: "m5", name: "Indira", firstName: "Indira", initials: "PI", tone: "#6D7A53" }, { id: "m6", name: "Bagus", firstName: "Bagus", initials: "BM", tone: "#C28464" }, { id: "m7", name: "Ratna", firstName: "Ratna", initials: "RK", tone: "#93826A" }, ]; // People you could follow but aren't yet friends with. Mix of mutual-friend // suggestions and people who've showed up in your classes. const FRIEND_SUGGESTIONS = [ { id: "x1", name: "Komang Suweta", firstName: "Komang", initials: "KS", tone: "#6E4A2D", reason: "12 classes together", mutual: 3 }, { id: "x2", name: "Ayu Wulandari", firstName: "Ayu", initials: "AW", tone: "#8A4D2E", reason: "shared 4 morning classes", mutual: 5 }, { id: "x3", name: "Putri Ananda", firstName: "Putri", initials: "PA", tone: "#557048", reason: "from your friend Maya", mutual: 2 }, { id: "x4", name: "Sari Nuraini", firstName: "Sari", initials: "SN", tone: "#9C5E3A", reason: "in your hatha class", mutual: 1 }, ]; // Incoming follow requests waiting on you const PENDING_REQUESTS = [ { id: "p1", name: "Wayan Aditama", firstName: "Wayan", initials: "WA", tone: "#7E806A", mutual: 1, since: "yesterday" }, { id: "p2", name: "Ni Made Sari", firstName: "Made", initials: "NS", tone: "#5C6E47", mutual: 0, since: "3 days ago" }, ]; // 7-day schedule (day 0 = Monday). Includes friends-going for social proof. function buildSchedule() { const week = [ [0, "06:30", "slow", "ayu", 0, 14, 11, ["m1","m3"], 1], [0, "09:00", "beginner", "made", 1, 12, 5, ["m5","m7"], 0], [0, "17:30", "hatha", "ayu", 0, 14, 14, ["m1","m2","m4","m6"], 2], [0, "19:00", "stretch", "luh", 1, 12, 7, ["m3","m5"], 1], [1, "07:00", "hip", "luh", 0, 14, 9, ["m1","m2"], 0], [1, "10:00", "shoulder", "made", 1, 12, 4, ["m7"], 0], [1, "18:00", "inversion", "kade", 0, 12, 12, ["m4","m6","m2"], 2], [1, "19:30", "slow", "ayu", 1, 14, 8, ["m1","m5"], 1], [2, "06:30", "hatha", "ayu", 0, 14, 12, ["m1","m3","m6"], 1], [2, "09:00", "stretch", "luh", 1, 12, 6, ["m3","m7"], 0], [2, "17:30", "armbalance", "kade", 0, 12, 10, ["m2","m4"], 0], [2, "19:00", "body", "luh", 1, 14, 8, ["m5","m6"], 1], [3, "07:00", "slow", "ayu", 0, 14, 13, ["m1","m6"], 0], [3, "10:00", "beginner", "made", 1, 12, 3, ["m7"], 0], [3, "18:00", "balance", "kade", 0, 14, 9, ["m2","m4","m6"], 0], [3, "19:30", "hip", "luh", 1, 12, 7, ["m1","m3"], 1], [4, "06:30", "hatha", "ayu", 0, 14, 14, ["m1","m4","m6","m2","m3"], 3], [4, "09:00", "shoulder", "made", 1, 12, 5, ["m5"], 0], [4, "17:30", "inversion", "kade", 0, 12, 11, ["m2","m4","m6"], 0], [4, "19:00", "stretch", "luh", 1, 14, 6, ["m3","m5","m7"], 0], [5, "08:00", "slow", "ayu", 0, 14, 10, ["m1","m3","m5"], 0], [5, "10:00", "beginner", "made", 1, 12, 6, ["m7","m5"], 1], [5, "16:00", "body", "luh", 0, 14, 8, ["m4","m6"], 0], [6, "08:00", "hatha", "ayu", 0, 14, 12, ["m1","m2","m6"], 0], [6, "10:00", "stretch", "luh", 1, 12, 9, ["m3","m5","m7"], 1], [6, "16:30", "slow", "made", 0, 14, 7, ["m4","m5"], 0], ]; return week.map((row, i) => { const monday = new Date(2026, 4, 25); const d = new Date(monday.getTime() + row[0] * 24 * 60 * 60 * 1000); const yyyy = d.getFullYear(); const mm = String(d.getMonth() + 1).padStart(2, '0'); const dd = String(d.getDate()).padStart(2, '0'); const dateStr = `${yyyy}-${mm}-${dd}`; return { id: "s" + i, day: row[0], date: dateStr, time: row[1], classId: row[2], coachId: row[3], room: ROOMS[row[4]], roomShort: STUDIOS[row[4]].name, capacity: row[5], booked: row[6], friends: row[7] || [], anonCount: row[8] || 0, }; }); } const SCHEDULE = buildSchedule(); // Today's "current week" is Monday May 4, 2026. The current user has joined // for Wednesday 18:00 inversion (s10 ish). const CURRENT_USER = { name: "Sinta Putri", email: "sinta@mail.com", initials: "SP", joined: "Sept 2024", visits: 22, streak: 4, // weeks // Active credit packs creditPacks: [ { packageId: "five", packageName: "Standard 5", credits: 3, total: 5, purchased: "2026-04-20", expires: "2026-05-20" }, { packageId: "ten", packageName: "Regular 10", credits: 8, total: 10, purchased: "2026-05-02", expires: "2026-06-01" }, ], // Booked session IDs (live state) booked: ["s11"], // Wed 18:00 arm balance kade // Per-session privacy: "self" (default) or "anon" bookingPrivacy: { "s11": "self" }, // Privacy preference: visible to friends by default visibleByDefault: true, // Waitlisted (full classes) waitlist: [], // Saved savedClasses: ["slow", "hip"], savedCoaches: ["ayu", "luh"], following: ["m2","m3","m4","m5","m6","m7"], // Incoming follow requests pendingFollowers: ["p1", "p2"], // Outgoing requests (waiting on them) sentRequests: ["x3"], // Recent (last 6 months) monthly: [ { m: "Dec", n: 2 }, { m: "Jan", n: 4 }, { m: "Feb", n: 5 }, { m: "Mar", n: 7 }, { m: "Apr", n: 9 }, { m: "May", n: 6 }, ], // History (latest first) — mock history: [ { id: "h1", date: "Fri 02 May", classId: "hatha", coachId: "ayu", roomShort: "Daun" }, { id: "h2", date: "Wed 30 Apr", classId: "slow", coachId: "ayu", roomShort: "Daun" }, { id: "h3", date: "Mon 28 Apr", classId: "hip", coachId: "luh", roomShort: "Daun" }, { id: "h4", date: "Sat 26 Apr", classId: "stretch", coachId: "luh", roomShort: "Akar" }, { id: "h5", date: "Thu 24 Apr", classId: "inversion", coachId: "kade", roomShort: "Daun" }, ], }; // Return Monday May 4, 2026 at 09:00:00 as the simulated application time function getAppToday() { return new Date(2026, 4, 29, 9, 0, 0); // May 29, 2026 } function parseLocalDate(dateStr) { if (!dateStr) return null; const [year, month, day] = dateStr.split('-').map(Number); return new Date(year, month - 1, day); } function formatLocalDateISO(d) { if (!d) return ""; const yyyy = d.getFullYear(); const mm = String(d.getMonth() + 1).padStart(2, '0'); const dd = String(d.getDate()).padStart(2, '0'); return `${yyyy}-${mm}-${dd}`; } const mockNow = getAppToday(); const TODAY_DAY = 4; // Friday const TODAY_HOUR = 9; const TODAY_MIN = 0; function getTodayLabel() { return "Friday, 29 May"; } const TODAY_LABEL = getTodayLabel(); // Helpers ───────────────────────────────────────────────────────────────── const DAYS_SHORT = ["Mon","Tue","Wed","Thu","Fri","Sat","Sun"]; const DAYS_LONG = ["Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sunday"]; function getDatesThisWeek() { const dates = []; const monday = new Date(2026, 4, 25); for (let i = 0; i < 7; i++) { const d = new Date(monday.getTime() + i * 24 * 60 * 60 * 1000); dates.push(d.getDate()); } return dates; } const DATES_THIS_WEEK = getDatesThisWeek(); function fmtIDR(n) { return "Rp " + n.toLocaleString("id-ID"); } function findClass(id) { const list = (window.NADI && window.NADI.CLASS_TYPES) || (typeof CLASS_TYPES !== 'undefined' ? CLASS_TYPES : []); return list.find((c) => c.id === id) || { id: id, name: "Unknown Class", duration: 60 }; } function findCoach(id) { const list = (window.NADI && window.NADI.COACHES) || (typeof COACHES !== 'undefined' ? COACHES : []); return list.find((c) => c.id === id) || { id: id, name: "Unknown Coach", firstName: "Unknown", initials: "UC", tone: "#6D7A53" }; } function findFriend(id) { const list = (window.NADI && window.NADI.FRIENDS) || FRIENDS; return list.find((f) => f.id === id) || FRIEND_SUGGESTIONS.find((f) => f.id === id) || PENDING_REQUESTS.find((f) => f.id === id); } // Given a session day+time and "today", figure out human-friendly "in 3h 24m" countdown. // Today = dynamic. function minutesUntil(session) { // Convert today to minutes-of-week. const nowMin = TODAY_DAY * 1440 + TODAY_HOUR * 60 + TODAY_MIN; const [h, m] = session.time.split(":").map(Number); let sessMin = session.day * 1440 + h * 60 + m; if (sessMin < nowMin) sessMin += 7 * 1440; return sessMin - nowMin; } function fmtCountdown(mins) { if (mins < 60) return `in ${mins} min`; const h = Math.floor(mins / 60), m = mins % 60; if (h < 24) return m === 0 ? `in ${h}h` : `in ${h}h ${m}m`; const d = Math.floor(h / 24); const rh = h % 24; return rh === 0 ? `in ${d}d` : `in ${d}d ${rh}h`; } window.NADI = { CLASS_TYPES, COACHES, PACKAGES, SCHEDULE, STUDIOS, ROOMS, FRIENDS, FRIEND_SUGGESTIONS, PENDING_REQUESTS, CURRENT_USER, TODAY_DAY, TODAY_LABEL, DAYS_SHORT, DAYS_LONG, DATES_THIS_WEEK, getAppToday, parseLocalDate, formatLocalDateISO, }; window.NADI_HELPERS = { fmtIDR, findClass, findCoach, findFriend, minutesUntil, fmtCountdown, DAYS_SHORT, DAYS_LONG, DATES_THIS_WEEK, TODAY_DAY, TODAY_HOUR, TODAY_MIN, getAppToday, parseLocalDate, formatLocalDateISO, }; // ── ADMIN MOCK DATA ───────────────────────────────────────────────────── const MEMBERS = [ { id: "m1", name: "Sinta Putri", email: "sinta@mail.com", phone: "+62 812 1100 2030", joined: "2024-09-12", credits: 11, package: "Standard 5 + Regular 10", visits: 22, status: "active", lastVisit: "Fri 02 May", initials: "SP", tone: "#B5563C" }, { id: "m2", name: "Rio Adriansyah", email: "rio@mail.com", phone: "+62 813 8866 1102", joined: "2025-01-04", credits: 8, package: "Regular 10", visits: 14, status: "active", lastVisit: "Sun 04 May", initials: "RA", tone: "#5C6E47" }, { id: "m3", name: "Maya Lestari", email: "maya@mail.com", phone: "+62 821 4423 5577", joined: "2025-02-21", credits: 0, package: "—", visits: 9, status: "lapsed", lastVisit: "Tue 25 Mar", initials: "ML", tone: "#8A7E5C" }, { id: "m4", name: "Dewa Anggara", email: "dewa@mail.com", phone: "+62 877 2298 4501", joined: "2024-11-30", credits: 2, package: "Standard 5", visits: 31, status: "active", lastVisit: "Sat 03 May", initials: "DA", tone: "#A14A2E" }, { id: "m5", name: "Putu Indira", email: "indira@mail.com", phone: "+62 819 0019 6644", joined: "2025-03-15", credits: 5, package: "Newcomer Trial", visits: 1, status: "new", lastVisit: "Mon 28 Apr", initials: "PI", tone: "#6D7A53" }, { id: "m6", name: "Bagus Mahendra", email: "bagus@mail.com", phone: "+62 815 7733 8821", joined: "2024-07-09", credits: 11, package: "Devoted 15", visits: 47, status: "active", lastVisit: "Mon 04 May", initials: "BM", tone: "#C28464" }, { id: "m7", name: "Ratna Kemala", email: "ratna@mail.com", phone: "+62 856 2299 0098", joined: "2025-04-02", credits: 4, package: "Standard 5", visits: 4, status: "new", lastVisit: "Thu 01 May", initials: "RK", tone: "#93826A" }, { id: "m8", name: "Wayan Aditama", email: "wayan@mail.com", phone: "+62 822 4488 9912", joined: "2024-04-18", credits: 0, package: "—", visits: 18, status: "lapsed", lastVisit: "Sun 23 Feb", initials: "WA", tone: "#7E806A" }, { id: "m9", name: "Sari Nuraini", email: "sari@mail.com", phone: "+62 838 1100 3344", joined: "2025-04-22", credits: 3, package: "Standard 5", visits: 5, status: "active", lastVisit: "Sat 03 May", initials: "SN", tone: "#9C5E3A" }, { id: "ma", name: "Komang Suweta", email: "komang@mail.com", phone: "+62 877 5556 7788", joined: "2024-10-08", credits: 13, package: "Devoted 15", visits: 35, status: "active", lastVisit: "Sun 04 May", initials: "KS", tone: "#6E4A2D" }, { id: "mb", name: "Ayu Wulandari", email: "ayu.w@mail.com", phone: "+62 821 9911 4477", joined: "2024-12-01", credits: 1, package: "Standard 5", visits: 22, status: "active", lastVisit: "Fri 02 May", initials: "AW", tone: "#8A4D2E" }, { id: "mc", name: "Putri Ananda", email: "putri@mail.com", phone: "+62 813 0088 1122", joined: "2024-08-19", credits: 0, package: "—", visits: 12, status: "lapsed", lastVisit: "Mon 03 Mar", initials: "PA", tone: "#557048" }, ]; const PAYMENTS = [ { id: "p01", date: "2026-05-05", time: "13:42", member: "Bagus Mahendra", memberId: "m6", item: "Devoted 15", amount: 1850000, method: "Transfer" }, { id: "p02", date: "2026-05-05", time: "11:18", member: "Sinta Putri", memberId: "m1", item: "Standard 5", amount: 750000, method: "QRIS" }, { id: "p03", date: "2026-05-05", time: "09:55", member: "Sari Nuraini", memberId: "m9", item: "Single Class", amount: 180000, method: "QRIS" }, { id: "p04", date: "2026-05-04", time: "18:30", member: "Rio Adriansyah", memberId: "m2", item: "Regular 10", amount: 1350000, method: "Transfer" }, { id: "p05", date: "2026-05-04", time: "10:12", member: "Putu Indira", memberId: "m5", item: "Newcomer Trial",amount: 300000, method: "QRIS" }, { id: "p06", date: "2026-05-03", time: "16:24", member: "Dewa Anggara", memberId: "m4", item: "Standard 5", amount: 750000, method: "Card" }, { id: "p07", date: "2026-05-03", time: "08:09", member: "Komang Suweta", memberId: "ma", item: "Devoted 15", amount: 1850000, method: "QRIS" }, { id: "p08", date: "2026-05-02", time: "19:45", member: "Ratna Kemala", memberId: "m7", item: "Standard 5", amount: 750000, method: "Transfer" }, { id: "p09", date: "2026-05-02", time: "12:30", member: "Ayu Wulandari", memberId: "mb", item: "Single Class", amount: 180000, method: "Card" }, ]; // Today's revenue, broken down by hour. Today is Tuesday so it's partial. const TODAY_REVENUE_HOURLY = [ { h: "08", v: 0 }, { h: "09", v: 180000 }, { h: "10", v: 0 }, { h: "11", v: 750000 }, { h: "12", v: 0 }, { h: "13", v: 1850000 }, { h: "14", v: 0 }, { h: "15", v: 0 }, { h: "16", v: 0 }, { h: "17", v: 0 }, { h: "18", v: 0 }, { h: "19", v: 0 }, ]; const TODAY_REVENUE = TODAY_REVENUE_HOURLY.reduce((s, r) => s + r.v, 0); const YESTERDAY_REVENUE = 1650000; const WEEK_REVENUE = 8470000; // Bank accounts members can transfer to (admin-managed) const BANK_ACCOUNTS = [ { id: "b1", bank: "BCA", name: "Nadi Yoga Studio", number: "8475 0992 105", branch: "Tangerang", active: true }, { id: "b2", bank: "Mandiri", name: "Nadi Yoga Studio", number: "1430 0088 7711 04", branch: "Jakarta Pusat", active: true }, { id: "b3", bank: "BNI", name: "PT Nadi Yoga", number: "0552 113 668", branch: "Tangerang", active: true }, { id: "b4", bank: "Permata", name: "PT Nadi Yoga", number: "7008 1144 2200", branch: "Tangerang", active: false }, ]; // Pack purchases awaiting admin confirmation (proof-of-transfer) const PACK_PURCHASES = [ { id: "pp1", memberId: "m6", memberName: "Bagus Mahendra", packageId: "season", packageName: "Devoted 15", classes: 15, validityDays: 30, amount: 1850000, bankId: "b1", submitted: "2026-05-05 13:42", status: "pending", note: "transfer from BCA ending 4421" }, { id: "pp2", memberId: "m2", memberName: "Rio Adriansyah", packageId: "ten", packageName: "Regular 10", classes: 10, validityDays: 30, amount: 1350000, bankId: "b2", submitted: "2026-05-05 11:08", status: "pending", note: "" }, { id: "pp3", memberId: "m9", memberName: "Sari Nuraini", packageId: "single", packageName: "Single Class", classes: 1, validityDays: 30, amount: 180000, bankId: "b1", submitted: "2026-05-04 19:30", status: "pending", note: "" }, { id: "pp4", memberId: "m7", memberName: "Ratna Kemala", packageId: "five", packageName: "Standard 5", classes: 5, validityDays: 30, amount: 750000, bankId: "b3", submitted: "2026-05-04 09:12", status: "confirmed", note: "" }, ]; const ACCOUNTS = [ { id: "a1", name: "Ayu Pradnyani", email: "ayu@nadi.yoga", role: "Owner", lastActive: "Just now", initials: "AP", tone: "#C28464" }, { id: "a2", name: "Wayan Studio", email: "wayan@nadi.yoga", role: "Manager", lastActive: "12 min ago", initials: "WS", tone: "#5C6E47" }, { id: "a3", name: "Front Desk", email: "desk@nadi.yoga", role: "Front Desk", lastActive: "Yesterday", initials: "FD", tone: "#8A7E5C" }, ]; const ROLES = [ { name: "Owner", scope: "Full access", perms: ["Members","Coaches","Classes","Studios","Schedule","Packages","Payments","Accounts","Reports","Check-in","Bookings"] }, { name: "Manager", scope: "All ops, no accounts", perms: ["Members","Coaches","Classes","Studios","Schedule","Packages","Payments","Reports","Check-in","Bookings"] }, { name: "Front Desk", scope: "Bookings & check-in", perms: ["Members","Schedule","Check-in","Bookings"] }, { name: "Coach", scope: "Own roster + schedule", perms: ["Schedule","Members"] }, ]; // Per-teacher payouts this month const PAYOUTS = [ { coachId: "ayu", classes: 14, hours: 16.5, rate: 250000, total: 14 * 250000, paid: false }, { coachId: "made", classes: 9, hours: 9, rate: 220000, total: 9 * 220000, paid: false }, { coachId: "kade", classes: 11, hours: 12, rate: 240000, total: 11 * 240000, paid: false }, { coachId: "luh", classes: 12, hours: 12, rate: 230000, total: 12 * 230000, paid: true }, ]; // Churn / lapsed const CHURN_LIST = MEMBERS.filter((m) => m.status === "lapsed").map((m) => { const map = { "m3": 41, "m8": 71, "mc": 63 }; return { ...m, daysSinceVisit: map[m.id] || 30 }; }).sort((a, b) => a.daysSinceVisit - b.daysSinceVisit); const CHECKINS = { "s4": { checked: 9, ready: 0 }, "s5": { checked: 4, ready: 0 }, "s6": { checked: 0, ready: 12 }, "s7": { checked: 0, ready: 8 }, }; function todaysSessions() { const list = (window.NADI && window.NADI.SCHEDULE) || (typeof SCHEDULE !== 'undefined' ? SCHEDULE : []); return list.filter((s) => s.day === TODAY_DAY).sort((a, b) => a.time.localeCompare(b.time)); } function findMember(id) { const list = (window.NADI_ADMIN && window.NADI_ADMIN.MEMBERS) || (typeof MEMBERS !== 'undefined' ? MEMBERS : []); return list.find((m) => m.id === id) || { id: id, name: "Unknown Member", initials: "UM", tone: "#B5563C" }; } window.NADI_ADMIN = { MEMBERS, PAYMENTS, ACCOUNTS, ROLES, PAYOUTS, CHURN_LIST, BANK_ACCOUNTS, PACK_PURCHASES, TODAY_REVENUE, TODAY_REVENUE_HOURLY, YESTERDAY_REVENUE, WEEK_REVENUE, CHECKINS, todaysSessions, findMember, }; window.NADI.CURRENT_ADMIN = { id: "a1", name: "Ayu Pradnyani", email: "ayu@nadi.yoga", initials: "AP", tone: "#C28464", role: "Owner", permissions: ["Members","Coaches","Classes","Studios","Schedule","Packages","Payments","Accounts","Reports","Check-in","Bookings"], };