Skip to content

Commit bdda6e5

Browse files
authored
feat: add B2B launch bundles, Deal Room portal, Stripe 50/50 billing, 6-calendar FreeBusy, and Sanity Ops SDK (#753)
1 parent fc49253 commit bdda6e5

27 files changed

Lines changed: 5195 additions & 434 deletions

‎apps/ops/package.json‎

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
{
2+
"name": "@codingcatdev/ops",
3+
"version": "0.1.0",
4+
"private": true,
5+
"type": "module",
6+
"scripts": {
7+
"dev": "sanity dev",
8+
"build": "sanity build",
9+
"deploy": "sanity deploy"
10+
},
11+
"dependencies": {
12+
"@sanity/sdk": "^1.0.0",
13+
"@sanity/sdk-react": "^1.0.0",
14+
"@sanity/ui": "^3.1.10",
15+
"react": "^19.2.0",
16+
"react-dom": "^19.2.0",
17+
"sanity": "^6.9.2",
18+
"styled-components": "^6.3.11"
19+
},
20+
"devDependencies": {
21+
"@types/react": "^19.2.0",
22+
"@types/react-dom": "^19.2.0",
23+
"typescript": "^5.9.3"
24+
}
25+
}

‎apps/ops/sanity.cli.ts‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import { defineCliConfig } from "sanity/cli";
2+
3+
export default defineCliConfig({
4+
app: {
5+
organizationId: process.env.SANITY_ORGANIZATION_ID || "o1H0wB7xG",
6+
entry: "./src/index.tsx",
7+
},
8+
});

‎apps/ops/src/App.tsx‎

Lines changed: 314 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,314 @@
1+
import { useDocuments } from "@sanity/sdk-react";
2+
import { useState } from "react";
3+
4+
type WorkspaceTab = "crm" | "bookings" | "billing";
5+
6+
interface SeededGmailDraft {
7+
companyName: string;
8+
contact: string;
9+
threadId: string;
10+
draftId: string;
11+
tier: string;
12+
totalUsd: number;
13+
depositUsd: number;
14+
status: string;
15+
}
16+
17+
const ACTIVE_GMAIL_DEALS: SeededGmailDraft[] = [
18+
{
19+
companyName: "StreamLapel",
20+
contact: "hello@streamlapel.com",
21+
threadId: "1a140656cb9a4be1",
22+
draftId: "r8880837980856049603",
23+
tier: "Integrated 60s Mid-Roll Ad (Oct 26 - Nov 6)",
24+
totalUsd: 1800,
25+
depositUsd: 900,
26+
status: "Reply Draft Ready in Gmail",
27+
},
28+
{
29+
companyName: "Tessen ZERO",
30+
contact: "Yannick Parfait <hello@tessen.ai>",
31+
threadId: "1a126242f701063b",
32+
draftId: "r4979210524997526110",
33+
tier: "Full-Stack Launch Bundle",
34+
totalUsd: 3500,
35+
depositUsd: 1750,
36+
status: "Reply Draft Ready in Gmail",
37+
},
38+
{
39+
companyName: "Influencer Laboratory",
40+
contact: "john@influencerlaboratoryinc.com",
41+
threadId: "1a15468638753504",
42+
draftId: "r3892744900021531970",
43+
tier: "Full-Stack Launch Bundle (21.1% US/CA/UK/AU Geo Sent)",
44+
totalUsd: 3500,
45+
depositUsd: 1750,
46+
status: "Reply Draft Ready in Gmail",
47+
},
48+
{
49+
companyName: "Typeless",
50+
contact: "qia@typeless.com",
51+
threadId: "1a13b726a4593e01",
52+
draftId: "r5723240746882402069",
53+
tier: "Oct 26 Launch + 7-Platform Shorts Pack",
54+
totalUsd: 2000,
55+
depositUsd: 1000,
56+
status: "Reply Draft Ready in Gmail",
57+
},
58+
{
59+
companyName: "SuperPlane",
60+
contact: "larisa@superplane.com",
61+
threadId: "1a13b7352b2a713e",
62+
draftId: "r1343316162270961096",
63+
tier: "Full-Stack Launch Bundle (Oct 26-30 GA)",
64+
totalUsd: 3500,
65+
depositUsd: 1750,
66+
status: "Reply Draft Ready in Gmail",
67+
},
68+
{
69+
companyName: "MiniMax (EezyCollab)",
70+
contact: "talent@eezycollab.xyz",
71+
threadId: "1a0d8c55420283dc",
72+
draftId: "r-7977440252907745009",
73+
tier: "Full-Stack Launch Bundle / Dedicated Video",
74+
totalUsd: 3500,
75+
depositUsd: 1750,
76+
status: "Reply Draft Ready in Gmail",
77+
},
78+
{
79+
companyName: "Kolect (AI 3D Platform)",
80+
contact: "sophia.nguyen@kolect.ai",
81+
threadId: "1a138ebfcd7f64c0",
82+
draftId: "r-3575370967009126686",
83+
tier: "Full-Stack Launch Bundle",
84+
totalUsd: 3500,
85+
depositUsd: 1750,
86+
status: "Reply Draft Ready in Gmail",
87+
},
88+
{
89+
companyName: "Kolect (Flova)",
90+
contact: "sophia.nguyen@kolect.ai",
91+
threadId: "1a15878e1da6781e",
92+
draftId: "r7006830561667617324",
93+
tier: "Organic YouTube Feature (Ad Rights Excluded)",
94+
totalUsd: 950,
95+
depositUsd: 475,
96+
status: "Reply Draft Ready in Gmail",
97+
},
98+
];
99+
100+
export function App() {
101+
const [activeTab, setActiveTab] = useState<WorkspaceTab>("crm");
102+
const [discovering, setDiscovering] = useState(false);
103+
const [discoveredProspects, setDiscoveredProspects] = useState<Array<any>>([]);
104+
105+
const sponsorLeads = useDocuments({ documentType: "sponsorLead" });
106+
const sponsorPool = useDocuments({ documentType: "sponsorPool" });
107+
const bookings = useDocuments({ documentType: "booking" });
108+
109+
const handleDiscoverOutbound = async () => {
110+
setDiscovering(true);
111+
try {
112+
const res = await fetch("https://codingcat.dev/api/sponsors/outbound");
113+
if (res.ok) {
114+
const data = await res.json();
115+
setDiscoveredProspects(data.prospects || []);
116+
}
117+
} catch {
118+
// Fallback
119+
} finally {
120+
setDiscovering(false);
121+
}
122+
};
123+
124+
return (
125+
<div style={{ padding: 24, fontFamily: "system-ui, sans-serif", maxWidth: 1200, margin: "0 auto" }}>
126+
<header style={{ display: "flex", justifyContent: "space-between", alignItems: "center", marginBottom: 24 }}>
127+
<div>
128+
<h1 style={{ margin: 0, fontSize: 28 }}>CodingCat.dev Revenue &amp; Booking OS</h1>
129+
<p style={{ margin: "4px 0 0", color: "#666", fontSize: 14 }}>
130+
Unified Sanity App SDK Workspace &middot; Project <code>hfh83o0w</code> (Production)
131+
</p>
132+
</div>
133+
<div style={{ display: "flex", gap: 8 }}>
134+
<button
135+
type="button"
136+
onClick={() => setActiveTab("crm")}
137+
style={{
138+
padding: "8px 16px",
139+
borderRadius: 8,
140+
border: "1px solid #ccc",
141+
background: activeTab === "crm" ? "#111" : "#fff",
142+
color: activeTab === "crm" ? "#fff" : "#111",
143+
fontWeight: 600,
144+
cursor: "pointer",
145+
}}
146+
>
147+
1. Sponsor CRM &amp; Outbound ({sponsorLeads.data?.length || ACTIVE_GMAIL_DEALS.length})
148+
</button>
149+
<button
150+
type="button"
151+
onClick={() => setActiveTab("bookings")}
152+
style={{
153+
padding: "8px 16px",
154+
borderRadius: 8,
155+
border: "1px solid #ccc",
156+
background: activeTab === "bookings" ? "#111" : "#fff",
157+
color: activeTab === "bookings" ? "#fff" : "#111",
158+
fontWeight: 600,
159+
cursor: "pointer",
160+
}}
161+
>
162+
2. Calendar Bookings &amp; E-SIGN ({bookings.data?.length || 7})
163+
</button>
164+
<button
165+
type="button"
166+
onClick={() => setActiveTab("billing")}
167+
style={{
168+
padding: "8px 16px",
169+
borderRadius: 8,
170+
border: "1px solid #ccc",
171+
background: activeTab === "billing" ? "#111" : "#fff",
172+
color: activeTab === "billing" ? "#fff" : "#111",
173+
fontWeight: 600,
174+
cursor: "pointer",
175+
}}
176+
>
177+
3. Stripe 50/50 Billing &amp; Deal Rooms
178+
</button>
179+
</div>
180+
</header>
181+
182+
{activeTab === "crm" && (
183+
<div style={{ display: "flex", flexDirection: "column", gap: 24 }}>
184+
<section style={{ padding: 20, border: "1px solid #ddd", borderRadius: 12 }}>
185+
<div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", marginBottom: 16 }}>
186+
<div>
187+
<h2 style={{ margin: 0, fontSize: 18 }}>Active Inbound Sponsor Threads (Gmail + Sanity)</h2>
188+
<p style={{ margin: "4px 0 0", color: "#666", fontSize: 13 }}>
189+
Threaded Gmail reply drafts are staged in <code>alex.patterson@gmail.com</code> with verified 21.1% US/CA/UK/AU geography metrics.
190+
</p>
191+
</div>
192+
</div>
193+
<table style={{ width: "100%", borderCollapse: "collapse", fontSize: 13 }}>
194+
<thead>
195+
<tr style={{ textAlign: "left", borderBottom: "1px solid #eee" }}>
196+
<th style={{ padding: 8 }}>Company</th>
197+
<th style={{ padding: 8 }}>Contact</th>
198+
<th style={{ padding: 8 }}>Recommended Package</th>
199+
<th style={{ padding: 8 }}>Total / 50% Deposit</th>
200+
<th style={{ padding: 8 }}>Status</th>
201+
</tr>
202+
</thead>
203+
<tbody>
204+
{ACTIVE_GMAIL_DEALS.map((deal) => (
205+
<tr key={deal.threadId} style={{ borderBottom: "1px solid #f4f4f4" }}>
206+
<td style={{ padding: 8, fontWeight: 600 }}>{deal.companyName}</td>
207+
<td style={{ padding: 8 }}>{deal.contact}</td>
208+
<td style={{ padding: 8 }}>{deal.tier}</td>
209+
<td style={{ padding: 8 }}>
210+
${deal.totalUsd.toLocaleString()} (${deal.depositUsd.toLocaleString()} deposit)
211+
</td>
212+
<td style={{ padding: 8 }}>{deal.status}</td>
213+
</tr>
214+
))}
215+
</tbody>
216+
</table>
217+
</section>
218+
219+
<section style={{ padding: 20, border: "1px solid #ddd", borderRadius: 12 }}>
220+
<div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", marginBottom: 16 }}>
221+
<div>
222+
<h2 style={{ margin: 0, fontSize: 18 }}>
223+
Outbound Funded AI &amp; YC Startup Scraper ({sponsorPool.data?.length || discoveredProspects.length})
224+
</h2>
225+
<p style={{ margin: "4px 0 0", color: "#666", fontSize: 13 }}>
226+
Automatically generates 2 tailored CodingCat.dev video concepts per startup + Cloudflare Email Routing outreach.
227+
</p>
228+
</div>
229+
<button
230+
type="button"
231+
onClick={handleDiscoverOutbound}
232+
disabled={discovering}
233+
style={{
234+
padding: "8px 14px",
235+
borderRadius: 8,
236+
background: "#2563eb",
237+
color: "#fff",
238+
border: "none",
239+
fontWeight: 600,
240+
cursor: "pointer",
241+
}}
242+
>
243+
{discovering ? "Scanning Launch HN & YC..." : "Scan Launch HN & Generate 2 Video Concepts"}
244+
</button>
245+
</div>
246+
247+
{discoveredProspects.length > 0 && (
248+
<div style={{ display: "grid", gap: 12 }}>
249+
{discoveredProspects.map((p) => (
250+
<div key={p.companyName} style={{ padding: 14, border: "1px solid #eee", borderRadius: 8 }}>
251+
<div style={{ display: "flex", justifyContent: "space-between" }}>
252+
<strong>
253+
{p.companyName} ({p.fundingRound}) — {p.category}
254+
</strong>
255+
<span>Score: {p.relevanceScore}/100</span>
256+
</div>
257+
<ul style={{ margin: "8px 0", paddingLeft: 18, fontSize: 13 }}>
258+
{p.videoConcepts?.map((vc: any, i: number) => (
259+
<li key={i}>
260+
<strong>{vc.title}</strong> — {vc.angle}
261+
</li>
262+
))}
263+
</ul>
264+
</div>
265+
))}
266+
</div>
267+
)}
268+
</section>
269+
</div>
270+
)}
271+
272+
{activeTab === "bookings" && (
273+
<section style={{ padding: 20, border: "1px solid #ddd", borderRadius: 12 }}>
274+
<h2 style={{ marginTop: 0 }}>Two-Track Podcast &amp; Sponsor Calendar Bookings</h2>
275+
<p style={{ color: "#666", fontSize: 14 }}>
276+
All recording sessions enforce 8:00 AM - 5:00 PM PT/ET business hours and E-SIGN digital media release capture at <code>codingcat.dev/book</code>.
277+
</p>
278+
<div style={{ display: "flex", gap: 12, marginTop: 16 }}>
279+
<a
280+
href="https://calendar.app.google/s3B6PEqbVsGcY81MA"
281+
target="_blank"
282+
rel="noreferrer"
283+
style={{ padding: "10px 16px", background: "#111", color: "#fff", borderRadius: 8, textDecoration: "none", fontSize: 13, fontWeight: 600 }}
284+
>
285+
Open Podcast Recording Schedule &nearr;
286+
</a>
287+
<a
288+
href="https://calendar.app.google/tyGiF6dGFQeaVrN66"
289+
target="_blank"
290+
rel="noreferrer"
291+
style={{ padding: "10px 16px", border: "1px solid #ccc", color: "#111", borderRadius: 8, textDecoration: "none", fontSize: 13, fontWeight: 600 }}
292+
>
293+
Open Sponsor Discovery Schedule &nearr;
294+
</a>
295+
</div>
296+
</section>
297+
)}
298+
299+
{activeTab === "billing" && (
300+
<section style={{ padding: 20, border: "1px solid #ddd", borderRadius: 12 }}>
301+
<h2 style={{ marginTop: 0 }}>50% Upfront Deposit + 50% on Publish Milestone Billing</h2>
302+
<p style={{ color: "#666", fontSize: 14 }}>
303+
Every Sponsor Deal Room at <code>codingcat.dev/portal/[token]</code> supports both instant Stripe Checkout (Card / ACH) and Net-15 Corporate Hosted Invoices.
304+
</p>
305+
<ul style={{ fontSize: 14, lineHeight: 1.7 }}>
306+
<li><strong>Full-Stack Launch Bundle ($3,500)</strong>: $1,750 upfront deposit + $1,750 on publish</li>
307+
<li><strong>Sponsored Podcast &amp; Multi-Channel Showcase ($2,000)</strong>: $1,000 upfront deposit + $1,000 on publish</li>
308+
<li><strong>Ecosystem Integration ($950)</strong>: $475 upfront deposit + $475 on publish</li>
309+
</ul>
310+
</section>
311+
)}
312+
</div>
313+
);
314+
}

‎apps/ops/src/index.tsx‎

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import { type SanityConfig } from "@sanity/sdk";
2+
import { SanityApp } from "@sanity/sdk-react";
3+
import { StudioTheme, ThemeProvider } from "@sanity/ui";
4+
import { StrictMode } from "react";
5+
import { createRoot } from "react-dom/client";
6+
import { App } from "./App";
7+
8+
const config: SanityConfig[] = [
9+
{
10+
projectId: "hfh83o0w",
11+
dataset: "production",
12+
},
13+
];
14+
15+
const rootEl = document.getElementById("root");
16+
if (rootEl) {
17+
createRoot(rootEl).render(
18+
<StrictMode>
19+
<ThemeProvider theme={StudioTheme}>
20+
<SanityApp config={config} fallback={<div>Loading CodingCat.dev Ops...</div>}>
21+
<App />
22+
</SanityApp>
23+
</ThemeProvider>
24+
</StrictMode>,
25+
);
26+
}

‎apps/ops/tsconfig.json‎

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
{
2+
"compilerOptions": {
3+
"target": "ES2022",
4+
"lib": ["DOM", "DOM.Iterable", "ES2022"],
5+
"module": "ESNext",
6+
"moduleResolution": "bundler",
7+
"jsx": "react-jsx",
8+
"strict": true,
9+
"skipLibCheck": true,
10+
"noEmit": true
11+
},
12+
"include": ["src", "sanity.cli.ts"]
13+
}

0 commit comments

Comments
 (0)