Two issues:
1. Race condition: me.php resolves before the platforms fetch, so
showApp() runs with an empty CFG.platforms and the grid stays
blank until the Promise.all resolves. Fixed by calling
buildPlatforms() inside showApp() when platforms are already
loaded, guaranteeing the grid renders when the app becomes visible.
2. Stale placeholder: 'links' platform (is_active=1) was polluting
the grid with a "Platform Links coming..." card. Disabled in DB
(is_active=0).
Also hardened buildPlatforms/buildCashoutPlatforms: null-guard on
selects, early return when CFG.platforms is empty, and clear select
options before re-populating to prevent duplicates on re-call.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Players now paste the URL of their post instead of just clicking a
platform button. The server fetches the URL and looks for the player's
referral code in the page content. If found, the share is auto-approved
and tokens are awarded immediately. If not (login wall, private page,
code missing), it falls into the pending queue with a reason so admins
can click the link directly for manual review.
- api/referrals.php: replace submit_share with URL-accepting version;
add scrapeForReferralCode() (SSRF-guarded cURL, 8s timeout, 512KB cap)
and inferPlatformFromUrl() helpers
- db/schema.sql: add share_url, auto_verified, verify_result columns
- index.php: replace platform buttons with URL input form; show auto-
verify result inline; shares list shows URL and auto-verify badge
- admin/index.php: share cards show clickable URL, auto-check result
label, and auto-verified tag
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>