QUARTERLY

Quarterly Raffles

Big-ticket prizes that draw at the end of each quarter.

Status: Guest

Log in to enter raffles.

Earn tokens

Get tokens when you’re recognised by managers and peers.

Enter quarterly raffles

Use 1 token per entry for this quarter’s prizes.

Annual roll‑up

Your raffle entries also auto‑count towards the Annual Grand Finale.

// --- Wire Enter buttons to API (Quarterly) --- (function(){ if (!false) return; // only bind when signed in const grid = document.querySelector('#quarterlyRaffles .grid'); if(!grid) return; grid.addEventListener('click', async (e)=>{ const btn = e.target.closest('.btn-enter'); if(!btn) return; e.preventDefault(); const card = btn.closest('.raffle-card'); if(!card) return; const rid = parseInt(card.getAttribute('data-rid')||'0',10); if(!rid){ toast('Missing raffle id'); return; } const entries = parseInt(btn.getAttribute('data-entries')||'1',10); btn.disabled = true; const old = btn.textContent; btn.textContent = 'Entering…'; try{ const res = await fetch('/api/raffles/enter.php',{ method:'POST', credentials:'same-origin', headers:{'Content-Type':'application/json'}, body: JSON.stringify({ raffle_id: rid, entries }) }); const data = await res.json().catch(()=>({success:false})); if(!res.ok || !data.success){ let msg = (data && data.error) ? data.error.replace(/_/g,' ') : 'Server error'; if (data && data.error === 'cap_reached' && data.meta) { msg = `You’ve hit the limit. ${data.meta.remaining} left of ${data.meta.cap}.`; } toast('Could not enter', msg); } else { if(typeof data.new_balance === 'number'){ document.querySelectorAll('[data-wallet-amt]').forEach(el=>{ el.textContent = (data.new_balance|0); }); } else { try{ await refreshWallet(); }catch(_){} } let sub=''; if (typeof data.remaining_after === 'number' && typeof data.cap === 'number') { sub = `${data.remaining_after} of ${data.cap} entries left`; } else if (typeof data.cap === 'number') { sub = `Up to ${data.cap} entries per raffle`; } toast('Entry added ✓', sub); // Increment per-card entry count UI try{ const chip = card.querySelector('.you-chip'); if (chip) { const was = parseInt(chip.getAttribute('data-you-entries')||'0',10); const inc = (typeof entries === 'number' ? entries : 1); const now = was + inc; chip.setAttribute('data-you-entries', String(now)); const cnt = card.querySelector('.you-chip .you-count'); if (cnt) cnt.textContent = now === 1 ? '1 entry' : (now + ' entries'); } }catch(_){/* ignore */} } } catch(err){ toast('Network error', 'Please try again'); } finally { btn.disabled = false; btn.textContent = old; } }); })();