Annual Practitioner Membership — WellSourced

Loading your membership status…

const API_BASE = ''; let authToken = localStorage.getItem('ws_token') || localStorage.getItem('ws_auth_token'); let currentMembership = null; function fmtDate(d) { if (!d) return '—'; return new Date(d).toLocaleDateString('en-US', { year: 'numeric', month: 'long', day: 'numeric' }); } function daysUntil(d) { if (!d) return 0; return Math.max(0, Math.ceil((new Date(d) - Date.now()) / (1000 * 60 * 60 * 24))); } function showPanel(id) { ['panel-active','panel-grace','panel-inactive'].forEach(p => { document.getElementById(p).style.display = (p === id) ? 'block' : 'none'; }); } async function loadMembership() { document.getElementById('loading-state').style.display = 'block'; if (!authToken) { document.getElementById('loading-state').style.display = 'none'; document.getElementById('auth-gate').style.display = 'block'; return; } try { const res = await fetch(`${API_BASE}/api/practitioners/membership`, { headers: { 'Authorization': `Bearer ${authToken}` } }); if (res.status === 401) { localStorage.removeItem('ws_auth_token'); document.getElementById('loading-state').style.display = 'none'; document.getElementById('auth-gate').style.display = 'block'; return; } if (res.status === 403) { document.getElementById('loading-state').style.display = 'none'; document.getElementById('not-enrolled').style.display = 'block'; return; } const data = await res.json(); document.getElementById('loading-state').style.display = 'none'; document.getElementById('membership-panel').style.display = 'block'; currentMembership = data.membership; const status = data.display_status; if (status === 'active' || status === 'cancelled_active') { const m = data.membership; document.getElementById('period-start-display').textContent = fmtDate(m.period_start); document.getElementById('period-end-display').textContent = fmtDate(m.period_end); const days = daysUntil(m.period_end); if (days <= 7 && days > 0) { document.getElementById('renewal-notice').style.display = 'block'; document.getElementById('days-until-renewal').textContent = days; } if (status === 'cancelled_active' || m.cancel_requested) { document.getElementById('cancelled-notice').style.display = 'block'; document.getElementById('btn-cancel').style.display = 'none'; } showPanel('panel-active'); } else if (status === 'grace_period') { const m = data.membership; document.getElementById('grace-end-display').textContent = fmtDate(m.grace_period_until); showPanel('panel-grace'); } else { showPanel('panel-inactive'); } } catch (e) { document.getElementById('loading-state').style.display = 'none'; document.getElementById('membership-panel').style.display = 'block'; showPanel('panel-inactive'); console.error('Failed to load membership:', e); } } async function startSubscription() { if (!authToken) { window.location.href = '/login?redirect=/practitioners/membership'; return; } try { const res = await fetch(`${API_BASE}/api/practitioners/membership/subscribe`, { method: 'POST', headers: { 'Authorization': `Bearer ${authToken}`, 'Content-Type': 'application/json' } }); const data = await res.json(); if (data.already_active) { loadMembership(); return; } if (data.checkout_url) { window.location.href = data.checkout_url; } else { alert('Something went wrong. Please try again or contact hello@wellsourced.co'); } } catch (e) { alert('Failed to start subscription. Please try again.'); } } function confirmCancel() { document.getElementById('cancel-modal').style.display = 'flex'; } function closeCancelModal() { document.getElementById('cancel-modal').style.display = 'none'; } async function cancelMembership() { closeCancelModal(); try { const res = await fetch(`${API_BASE}/api/practitioners/membership/cancel`, { method: 'POST', headers: { 'Authorization': `Bearer ${authToken}`, 'Content-Type': 'application/json' } }); const data = await res.json(); if (data.success) { loadMembership(); } else { alert(data.error || 'Failed to cancel. Please contact hello@wellsourced.co'); } } catch (e) { alert('Failed to cancel. Please try again.'); } } loadMembership();