feat(pitch): showcase mode — per-investor toggle hides financial/investor slides for customer demos
Build pitch-deck / build-push-deploy (push) Successful in 1m35s
CI / go-lint (push) Has been skipped
CI / python-lint (push) Has been skipped
CI / nodejs-lint (push) Has been skipped
CI / test-go-consent (push) Successful in 39s
CI / test-python-voice (push) Successful in 32s
CI / test-bqas (push) Successful in 30s

Adds is_showcase boolean to pitch_investors; when set, filters out financials,
the ask, cap table, assumptions, finanzplan, risks, and intro-presenter slides.
Slide navigation is fully dynamic — progress bar and counts update accordingly.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Sharang Parnerkar
2026-05-04 22:41:15 +02:00
parent f2184be02f
commit 30a9165497
7 changed files with 74 additions and 22 deletions
@@ -21,6 +21,7 @@ interface InvestorDetail {
assigned_version_id: string | null
version_name: string | null
version_status: string | null
is_showcase: boolean
}
sessions: Array<{
id: string
@@ -293,7 +294,7 @@ export default function InvestorDetailPage() {
{/* Version assignment */}
<section className="bg-white/[0.04] border border-white/[0.06] rounded-2xl p-5">
<h2 className="text-sm font-semibold text-white mb-3">Pitch Version</h2>
<div className="flex items-center gap-3">
<div className="flex items-center gap-3 flex-wrap">
<select
value={inv.assigned_version_id || ''}
onChange={async (e) => {
@@ -318,10 +319,35 @@ export default function InvestorDetailPage() {
</select>
<span className="text-xs text-white/40">
{inv.assigned_version_id
? `Investor sees version "${inv.version_name || ''}"`
: 'Investor sees default pitch data'}
? `Sees version "${inv.version_name || ''}"`
: 'Sees default pitch data'}
</span>
</div>
{/* Showcase toggle */}
<div className="flex items-center justify-between mt-4 pt-4 border-t border-white/[0.06]">
<div>
<div className="text-sm text-white font-medium">Showcase mode</div>
<div className="text-xs text-white/40 mt-0.5">Hides financials, The Ask, and investor-only slides for customer demos</div>
</div>
<button
onClick={async () => {
setBusy(true)
const res = await fetch(`/api/admin/investors/${id}`, {
method: 'PATCH',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ is_showcase: !inv.is_showcase }),
})
setBusy(false)
if (res.ok) { flashToast(inv.is_showcase ? 'Switched to investor mode' : 'Switched to showcase mode'); load() }
else { flashToast('Update failed') }
}}
disabled={busy}
className={`relative w-11 h-6 rounded-full transition-colors duration-200 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-offset-black focus:ring-indigo-500 ${inv.is_showcase ? 'bg-indigo-500' : 'bg-white/10'}`}
>
<span className={`absolute top-0.5 left-0.5 w-5 h-5 bg-white rounded-full shadow transition-transform duration-200 ${inv.is_showcase ? 'translate-x-5' : 'translate-x-0'}`} />
</button>
</div>
</section>
{/* Audit log for this investor */}