Track all clickable interactions as Plausible events
Add tracking to play/pause button, welcome banner, modal dismiss buttons, exit screen return, and seek bar. Every user interaction now sends a named event to Plausible. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
40fed2a6f4
commit
f7f9955c37
1 changed files with 6 additions and 4 deletions
|
|
@ -116,7 +116,7 @@ const playAdJingle = async () => {
|
||||||
|
|
||||||
function WelcomeBanner({ balance, onStart }) {
|
function WelcomeBanner({ balance, onStart }) {
|
||||||
const [fading, setFading] = useState(false);
|
const [fading, setFading] = useState(false);
|
||||||
const dismiss = () => { setFading(true); setTimeout(onStart, 400); };
|
const dismiss = () => { setFading(true); track("click: start_spending"); setTimeout(onStart, 400); };
|
||||||
return (
|
return (
|
||||||
<div style={{position:"fixed",inset:0,background:"rgba(0,0,0,0.95)",display:"flex",alignItems:"center",justifyContent:"center",zIndex:3000,backdropFilter:"blur(8px)",animation:fading?"fadeOut 0.4s ease forwards":"none"}}>
|
<div style={{position:"fixed",inset:0,background:"rgba(0,0,0,0.95)",display:"flex",alignItems:"center",justifyContent:"center",zIndex:3000,backdropFilter:"blur(8px)",animation:fading?"fadeOut 0.4s ease forwards":"none"}}>
|
||||||
<div style={{textAlign:"center",maxWidth:340,padding:"40px 28px"}}>
|
<div style={{textAlign:"center",maxWidth:340,padding:"40px 28px"}}>
|
||||||
|
|
@ -154,7 +154,7 @@ function Modal({ sub, phase, successText, onSub, onMicro, onClose, onTopUp }) {
|
||||||
<div style={{fontSize:18,fontWeight:700,color:"#e74c3c",fontFamily:"'Anybody',system-ui,sans-serif",marginBottom:8}}>Insufficient Funds</div>
|
<div style={{fontSize:18,fontWeight:700,color:"#e74c3c",fontFamily:"'Anybody',system-ui,sans-serif",marginBottom:8}}>Insufficient Funds</div>
|
||||||
<div style={{fontSize:13,color:"#8899aa",marginBottom:24}}>Even your wallet is on a free tier.</div>
|
<div style={{fontSize:13,color:"#8899aa",marginBottom:24}}>Even your wallet is on a free tier.</div>
|
||||||
<button onClick={onTopUp} style={{width:"100%",padding:"14px 16px",background:"linear-gradient(135deg,#00ee44,#00aa33)",color:"#000",border:"none",borderRadius:10,fontSize:15,fontWeight:700,cursor:"pointer",marginBottom:12}}>Add $10 (+$0.50 fee)</button>
|
<button onClick={onTopUp} style={{width:"100%",padding:"14px 16px",background:"linear-gradient(135deg,#00ee44,#00aa33)",color:"#000",border:"none",borderRadius:10,fontSize:15,fontWeight:700,cursor:"pointer",marginBottom:12}}>Add $10 (+$0.50 fee)</button>
|
||||||
<button onClick={onClose} style={{background:"none",border:"none",color:"#667788",fontSize:11,cursor:"pointer",textDecoration:"underline"}}>Accept poverty</button>
|
<button onClick={() => { track("click: accept_poverty"); onClose(); }} style={{background:"none",border:"none",color:"#667788",fontSize:11,cursor:"pointer",textDecoration:"underline"}}>Accept poverty</button>
|
||||||
</>
|
</>
|
||||||
) : (
|
) : (
|
||||||
<>
|
<>
|
||||||
|
|
@ -163,7 +163,7 @@ function Modal({ sub, phase, successText, onSub, onMicro, onClose, onTopUp }) {
|
||||||
<div style={{fontSize:14,color:"#8899aa",marginBottom:24,lineHeight:1.5,fontStyle:"italic"}}>{s.desc}</div>
|
<div style={{fontSize:14,color:"#8899aa",marginBottom:24,lineHeight:1.5,fontStyle:"italic"}}>{s.desc}</div>
|
||||||
<button onClick={onSub} style={{width:"100%",padding:"14px 16px",background:`linear-gradient(135deg,${s.color},${s.color}cc)`,color:"#fff",border:"none",borderRadius:10,fontSize:15,fontWeight:700,cursor:"pointer",marginBottom:10}}>SUBSCRIBE — {s.price}</button>
|
<button onClick={onSub} style={{width:"100%",padding:"14px 16px",background:`linear-gradient(135deg,${s.color},${s.color}cc)`,color:"#fff",border:"none",borderRadius:10,fontSize:15,fontWeight:700,cursor:"pointer",marginBottom:10}}>SUBSCRIBE — {s.price}</button>
|
||||||
<button onClick={onMicro} style={{width:"100%",padding:"12px 16px",background:"transparent",color:s.color,border:`1px solid ${s.color}66`,borderRadius:10,fontSize:13,cursor:"pointer",marginBottom:16,fontWeight:600}}>One-time use — ${s.micro.toFixed(2)}</button>
|
<button onClick={onMicro} style={{width:"100%",padding:"12px 16px",background:"transparent",color:s.color,border:`1px solid ${s.color}66`,borderRadius:10,fontSize:13,cursor:"pointer",marginBottom:16,fontWeight:600}}>One-time use — ${s.micro.toFixed(2)}</button>
|
||||||
<button onClick={onClose} style={{background:"none",border:"none",color:"#667788",fontSize:11,cursor:"pointer",textDecoration:"underline"}}>{s.dismiss}</button>
|
<button onClick={() => { track("click: dismiss", { feature: sub }); onClose(); }} style={{background:"none",border:"none",color:"#667788",fontSize:11,cursor:"pointer",textDecoration:"underline"}}>{s.dismiss}</button>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
|
@ -396,6 +396,7 @@ function PayPlay() {
|
||||||
// ---- User actions ----
|
// ---- User actions ----
|
||||||
|
|
||||||
const handlePlay = async () => {
|
const handlePlay = async () => {
|
||||||
|
track(on ? "click: pause" : "click: play", { song: song.title });
|
||||||
if (on) { tryAct("pause", () => { stopAudio(); setOn(false); }); }
|
if (on) { tryAct("pause", () => { stopAudio(); setOn(false); }); }
|
||||||
else {
|
else {
|
||||||
if (prog > 0 && !has("continue")) {
|
if (prog > 0 && !has("continue")) {
|
||||||
|
|
@ -411,6 +412,7 @@ function PayPlay() {
|
||||||
|
|
||||||
const handleSeek = e => {
|
const handleSeek = e => {
|
||||||
const r = e.currentTarget.getBoundingClientRect(), pct = (e.clientX - r.left) / r.width, tgt = Math.floor(pct * song.duration);
|
const r = e.currentTarget.getBoundingClientRect(), pct = (e.clientX - r.left) / r.width, tgt = Math.floor(pct * song.duration);
|
||||||
|
track("click: seek", { subscribed: !!has("seek") });
|
||||||
if (has("seek")) { setProg(tgt); if (on) { stopAudio(); startAudio(ci, tgt); } }
|
if (has("seek")) { setProg(tgt); if (on) { stopAudio(); startAudio(ci, tgt); } }
|
||||||
else { setProg(Math.max(0, Math.min(song.duration, tgt + Math.floor(Math.random() * 40) - 15))); flash("Seek landed somewhere in the general vicinity.", "#f39c12"); }
|
else { setProg(Math.max(0, Math.min(song.duration, tgt + Math.floor(Math.random() * 40) - 15))); flash("Seek landed somewhere in the general vicinity.", "#f39c12"); }
|
||||||
};
|
};
|
||||||
|
|
@ -471,7 +473,7 @@ function PayPlay() {
|
||||||
<div style={{color:muted,fontSize:12,marginTop:4}}>{Object.keys(subs).length} subscription{Object.keys(subs).length !== 1 ? "s" : ""}</div>
|
<div style={{color:muted,fontSize:12,marginTop:4}}>{Object.keys(subs).length} subscription{Object.keys(subs).length !== 1 ? "s" : ""}</div>
|
||||||
<div style={{display:"flex",gap:12,marginTop:24}}>
|
<div style={{display:"flex",gap:12,marginTop:24}}>
|
||||||
<button onClick={shareReceipt} style={{padding:"10px 24px",background:accent,color:"#000",border:"none",borderRadius:8,cursor:"pointer",fontSize:12,fontWeight:700}}>Share Receipt</button>
|
<button onClick={shareReceipt} style={{padding:"10px 24px",background:accent,color:"#000",border:"none",borderRadius:8,cursor:"pointer",fontSize:12,fontWeight:700}}>Share Receipt</button>
|
||||||
<button onClick={() => setShowExit(false)} style={{padding:"10px 24px",background:"transparent",color:muted,border:`1px solid ${muted}44`,borderRadius:8,cursor:"pointer",fontSize:12}}>Return to suffering</button>
|
<button onClick={() => { track("click: return_to_suffering"); setShowExit(false); }} style={{padding:"10px 24px",background:"transparent",color:muted,border:`1px solid ${muted}44`,borderRadius:8,cursor:"pointer",fontSize:12}}>Return to suffering</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue