Sponsor to downline messaging: lineage view, daily broadcast (email+inbox), login modal

- Downline resolver (3 levels); email visible for directs only, username+ID deeper
- Broadcast composer (rich editor) to directs or full downline, 1/day cap, sends email + on-site inbox
- Upline messages inbox in My line; unmissable sign-in modal for unread, ack marks read
- messages.js dual-mode store; sponsor_messages table; sanitizeRich reused

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
martbost
2026-09-06 08:39:06 -05:00
parent 289538dbeb
commit 7701a29169
14 changed files with 344 additions and 27 deletions
+50 -5
View File
@@ -4,7 +4,7 @@
<meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1">
<title>Member area | InstantAdPay</title>
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Sora:wght@600;700;800&display=swap">
<link rel="stylesheet" href="/assets/site.css?v=20260905y">
<link rel="stylesheet" href="/assets/site.css?v=20260905z">
</head>
<body class="bo-body">
@@ -82,6 +82,16 @@
</div>
</div>
<!-- ── sponsor message modal: unmissable on sign-in ── -->
<div id="msgModal" class="modal-back" hidden>
<div class="modal-card">
<p class="eyebrow" id="mmFrom">A message from your sponsor</p>
<h3 id="mmSubject" style="margin:.2em 0 .6em"></h3>
<div id="mmBody" class="promo-block ib-rich" style="max-height:50vh;overflow:auto"></div>
<p style="margin-top:16px;text-align:right"><button class="btn" id="mmAck" type="button">Got it</button></p>
</div>
</div>
<!-- ── signed-in: back-office shell ──────────────────────── -->
<div id="memberArea" class="bo" hidden>
<aside class="bo-side" id="boSide">
@@ -217,6 +227,41 @@
first package of $20 or more, they count toward your qualification.</p>
<div id="rosterWrap"><p class="muted small" id="rosterEmpty">Nobody yet. Your link is ready above; share it and this list starts filling.</p></div>
</div>
<div class="card">
<h3>Your downline, three levels deep</h3>
<p class="muted small">Everyone below you across levels 1–3. You see email addresses for your
direct referrals only; deeper levels show username and ID. You can message any of them below.</p>
<div id="lineageWrap"><p class="muted small">Loading…</p></div>
</div>
<div class="card" id="broadcastCard">
<h3>Message your team</h3>
<p class="muted small">Send one broadcast a day to your downline. It lands in their on-site inbox
and their email. Reaches the people who joined under you — they can't opt out of their sponsor,
so make it count.</p>
<p><select id="bcScope" style="width:100%">
<option value="direct">My direct referrals only (level 1)</option>
<option value="all">My whole downline (levels 1–3)</option>
</select></p>
<p><input id="bcSubject" maxlength="160" placeholder="Subject" style="width:100%"></p>
<div class="ed-bar" aria-label="Formatting">
<button type="button" data-bc="bold" title="Bold"><b>B</b></button>
<button type="button" data-bc="italic" title="Italic"><i>I</i></button>
<button type="button" data-bc="underline" title="Underline"><u>U</u></button>
<button type="button" data-bcblock="h3" title="Heading">H</button>
<button type="button" data-bc="insertUnorderedList" title="Bullet list">• List</button>
<button type="button" id="bcLinkBtn" title="Insert link">🔗 Link</button>
</div>
<div id="bcEd" class="ed-body" contenteditable="true" data-ph="Write to your team…"></div>
<p style="margin-top:12px"><button class="btn" id="bcSendBtn" type="button">Send broadcast</button>
<span class="small muted" id="bcHint"></span></p>
</div>
<div class="card" id="upMsgCard" hidden>
<h3>Messages from your upline</h3>
<div id="upList"></div>
</div>
</div>
<div class="pane" id="pane-buy" hidden>
@@ -484,9 +529,9 @@
</div>
</div>
<script src="/assets/common.js?v=20260905y"></script>
<script src="/assets/wallet.js?v=20260905y"></script>
<script src="/assets/my.js?v=20260905y"></script>
<script src="/assets/chat.js?v=20260905y"></script>
<script src="/assets/common.js?v=20260905z"></script>
<script src="/assets/wallet.js?v=20260905z"></script>
<script src="/assets/my.js?v=20260905z"></script>
<script src="/assets/chat.js?v=20260905z"></script>
</body>
</html>