|
256 | 256 | return [T.welcome, T.signin, T.connect, T.mode, T.voice, T.done]; // 2a Pro |
257 | 257 | } |
258 | 258 | function planWord(){ return S.plan==='power'?'Power':S.plan==='pro'?'Pro':'Free'; } |
| 259 | +// The Power upsell row in the Account card. One block, four states, so the |
| 260 | +// journey reads in one place: trialing → keep it; trial ended → upgrade (Pro |
| 261 | +// users get Power only, Free users get Power+Pro); never trialed → start free; |
| 262 | +// on Power plan but wrong build → get the app. Returns '' when nothing applies |
| 263 | +// (paying Power, or not signed in). |
| 264 | +function _powerUpsell(){ |
| 265 | + const line = (t,s)=>`<div><div style="font-weight:600">${t}</div><div style="font:400 13px var(--sans);color:var(--ink-2);margin-top:2px">${s}</div></div>`; |
| 266 | + const payBtns = `<div style="display:flex;gap:8px;margin-top:12px"><button class="btn btn-primary" style="padding:9px 16px;flex:1" onclick="bridge('upgrade_power',{interval:'monthly'})">$30 / month</button><button class="btn btn-primary" style="padding:9px 16px;flex:1" onclick="bridge('upgrade_power',{interval:'annual'})">$24 / mo · annual</button></div>`; |
| 267 | + const wrap = (inner)=>`<div style="border-top:1px solid var(--line);margin:14px -18px 0;padding:14px 18px 0">${inner}</div>`; |
| 268 | + if(!S.signedIn) return ''; |
| 269 | + // On Power plan but on the standard build → they need the Power app. |
| 270 | + if(S.plan==='power' && !S.powerBuild) |
| 271 | + return wrap(`<div style="display:flex;align-items:center;justify-content:space-between;gap:12px">${line('Get the Power app',"You're on Power - install the Power app to unlock voice input.")}<button class="btn btn-primary" style="padding:9px 16px" onclick="bridge('open_power_page')">Download</button></div>`); |
| 272 | + // Trialing → keep it. |
| 273 | + if(S.plan==='power' && S.trialDaysLeft!=null){ |
| 274 | + const d = S.trialDaysLeft===0?'Your trial ends today':S.trialDaysLeft+' day'+(S.trialDaysLeft===1?'':'s')+' left'; |
| 275 | + return wrap(line('Upgrade to Power', d+' in your trial - upgrade now to keep hands-free voice.')+payBtns); |
| 276 | + } |
| 277 | + if(!S.powerBuild) return ''; // OSS/Pro build, nothing Power to offer here |
| 278 | + // Trial ended (reverted off Power). |
| 279 | + if(S.plan!=='power' && S.powerTrialUsed){ |
| 280 | + if(S.plan==='pro'||S.plan==='pro_plus') |
| 281 | + return wrap(line('Your Power trial ended',"You're back on Pro. Add Power for hands-free voice control.")+payBtns); |
| 282 | + return wrap(line('Your Power trial ended','Get Power for hands-free voice, or Pro for managed cloud voices.')+payBtns+`<button class="btn" style="padding:9px 16px;margin-top:8px;width:100%" onclick="bridge('manage_account')">Or upgrade to Pro - $15/mo</button>`); |
| 283 | + } |
| 284 | + // Never trialed, still eligible → start the free trial. |
| 285 | + if(S.plan!=='power' && !S.powerTrialUsed) |
| 286 | + return wrap(`<div style="display:flex;align-items:center;justify-content:space-between;gap:12px">${line('Try Power free','14 days of hands-free voice control. No card.')}<button class="btn btn-primary" style="padding:9px 16px" onclick="bridge('start_power_trial')">Start trial</button></div>`); |
| 287 | + return ''; |
| 288 | +} |
259 | 289 |
|
260 | 290 | // ------------------------------------------------------------------ render |
261 | 291 | let current = null; |
|
481 | 511 | <div><div style="font-weight:600">Manage on heard.dev</div><div style="font:400 13px var(--sans);color:var(--ink-2);margin-top:2px">Plan, payment, and email in the browser.</div></div> |
482 | 512 | <button class="btn btn-ghost" style="padding:9px 16px" onclick="bridge('manage_account')">Open</button> |
483 | 513 | </div> |
484 | | - ${S.signedIn && S.plan!=='power' ? `<div style="border-top:1px solid var(--line);margin:14px -18px 0;padding:14px 18px 0;display:flex;align-items:center;justify-content:space-between;gap:12px"><div><div style="font-weight:600">Try Power free</div><div style="font:400 13px var(--sans);color:var(--ink-2);margin-top:2px">14 days of hands-free voice control. No card.</div></div><button class="btn btn-primary" style="padding:9px 16px" onclick="bridge('start_power_trial')">Start trial</button></div>` : ''} |
485 | | - ${S.plan==='power' && !S.powerBuild ? `<div style="border-top:1px solid var(--line);margin:14px -18px 0;padding:14px 18px 0;display:flex;align-items:center;justify-content:space-between;gap:12px"><div><div style="font-weight:600">Get the Power app</div><div style="font:400 13px var(--sans);color:var(--ink-2);margin-top:2px">You're on Power - install the Power app to unlock voice input.</div></div><button class="btn btn-primary" style="padding:9px 16px" onclick="bridge('open_power_page')">Download</button></div>` : ''} |
486 | | - ${S.plan==='power' && S.trialDaysLeft!=null ? `<div style="border-top:1px solid var(--line);margin:14px -18px 0;padding:14px 18px 0"><div style="display:flex;align-items:center;justify-content:space-between;gap:12px"><div><div style="font-weight:600">Keep Power</div><div style="font:400 13px var(--sans);color:var(--ink-2);margin-top:2px">${S.trialDaysLeft===0?'Your trial ends today':S.trialDaysLeft+' day'+(S.trialDaysLeft===1?'':'s')+' left in your trial'} - upgrade to keep hands-free voice.</div></div></div><div style="display:flex;gap:8px;margin-top:12px"><button class="btn btn-primary" style="padding:9px 16px;flex:1" onclick="bridge('upgrade_power',{interval:'monthly'})">$30 / month</button><button class="btn btn-primary" style="padding:9px 16px;flex:1" onclick="bridge('upgrade_power',{interval:'annual'})">$24 / mo · annual</button></div></div>` : ''} |
| 514 | + ${_powerUpsell()} |
487 | 515 | </div> |
488 | 516 | ${S.byokEnabled ? `${_HD('API keys')} |
489 | 517 | <div style="font:400 12.5px/1.5 var(--sans);color:var(--ink-2);margin:-6px 0 10px">Bring your own keys. Heard sends narration <b>straight to these providers</b> using your key - never through our servers. Leave blank to use your plan’s cloud voices, or the local Kokoro voice for zero cloud.</div> |
|
0 commit comments