Skip to content

Commit d2d50e3

Browse files
committed
chore: merge origin/dev and sync Sanity extract.json
2 parents 296ece5 + 3ae1e48 commit d2d50e3

33 files changed

Lines changed: 8552 additions & 907 deletions

‎.github/workflows/syndicate-post.yml‎

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,23 @@ jobs:
3737

3838
- name: Syndicate Post
3939
run: |
40-
node scripts/run-syndicate-post.mjs
40+
if [ "$TARGET_DOCUMENT_ID" = "backfill-dailydev" ]; then
41+
node scripts/backfill-dailydev-and-links.mjs
42+
elif [ "$TARGET_DOCUMENT_ID" = "enrich-aeo-seo" ]; then
43+
SANITY_STUDIO_DATASET=production node scripts/enrich-all-posts-aeo-seo-links.mjs
44+
SANITY_STUDIO_DATASET=dev node scripts/enrich-all-posts-aeo-seo-links.mjs
45+
elif [ "$TARGET_DOCUMENT_ID" = "trend-radar" ]; then
46+
SANITY_STUDIO_DATASET=production node scripts/run-trend-radar.mjs
47+
SANITY_STUDIO_DATASET=dev node scripts/run-trend-radar.mjs
48+
elif [ "$TARGET_DOCUMENT_ID" = "firebase-archive-2025-2026" ]; then
49+
FIREBASE_ARCHIVE_YEARS=2025,2026 SANITY_STUDIO_DATASET=production node scripts/generate-firebase-archive-posts.mjs
50+
FIREBASE_ARCHIVE_YEARS=2025,2026 SANITY_STUDIO_DATASET=dev node scripts/generate-firebase-archive-posts.mjs
51+
elif [ "$TARGET_DOCUMENT_ID" = "firebase-archive-2017-2024" ]; then
52+
FIREBASE_ARCHIVE_YEARS=2017,2018,2019,2020,2021,2022,2023,2024 SANITY_STUDIO_DATASET=production node scripts/generate-firebase-archive-posts.mjs
53+
FIREBASE_ARCHIVE_YEARS=2017,2018,2019,2020,2021,2022,2023,2024 SANITY_STUDIO_DATASET=dev node scripts/generate-firebase-archive-posts.mjs
54+
else
55+
node scripts/run-syndicate-post.mjs
56+
fi
4157
env:
4258
TARGET_DOCUMENT_ID: ${{ inputs.document_id }}
4359
SANITY_AUTH_TOKEN: ${{ secrets.SANITY_AUTH_TOKEN }}
@@ -51,6 +67,7 @@ jobs:
5167
AWS_BUILDER_SESSION_TOKEN: ${{ secrets.AWS_BUILDER_SESSION_TOKEN }}
5268
DAILY_DEV_TOKEN: ${{ secrets.DAILY_DEV_TOKEN }}
5369
DAILY_DEV_SESSION_COOKIE: ${{ secrets.DAILY_DEV_SESSION_COOKIE }}
70+
REDDIT_REFRESH_TOKEN: ${{ secrets.REDDIT_REFRESH_TOKEN }}
5471
GOOGLE_WORKSPACE_REFRESH_TOKEN: ${{ secrets.GOOGLE_WORKSPACE_REFRESH_TOKEN }}
5572
GOOGLE_CLIENT_ID: ${{ secrets.GOOGLE_CLIENT_ID }}
5673
GOOGLE_CLIENT_SECRET: ${{ secrets.GOOGLE_CLIENT_SECRET }}

‎apps/ops/src/App.tsx‎

Lines changed: 171 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { useDocuments } from "@sanity/sdk-react";
2-
import { useState } from "react";
2+
import { useEffect, useState } from "react";
33

4-
type WorkspaceTab = "crm" | "bookings" | "billing";
4+
type WorkspaceTab = "crm" | "bookings" | "billing" | "syndication";
55

66
interface SeededGmailDraft {
77
companyName: string;
@@ -111,6 +111,33 @@ export function App() {
111111
const sponsorLeads = useDocuments({ documentType: "sponsorLead" });
112112
const sponsorPool = useDocuments({ documentType: "sponsorPool" });
113113
const bookings = useDocuments({ documentType: "booking" });
114+
const syndications = useDocuments({ documentType: "syndication" });
115+
const [syndicatedContent, setSyndicatedContent] = useState<Array<any>>([]);
116+
117+
useEffect(() => {
118+
const query = encodeURIComponent(
119+
`*[_type in ["post", "podcast"] && !(_id in path("drafts.**"))] | order(coalesce(date, _createdAt) desc)[0...40] {
120+
_id,
121+
_type,
122+
title,
123+
"slug": slug.current,
124+
"date": coalesce(date, _createdAt),
125+
youtube,
126+
dailydev,
127+
devto,
128+
hashnode,
129+
awsbuilder,
130+
medium,
131+
reddit
132+
}`,
133+
);
134+
fetch(`https://${projectId}.apicdn.sanity.io/v2025-09-30/data/query/${dataset}?query=${query}`)
135+
.then((r) => r.json())
136+
.then((d) => {
137+
if (Array.isArray(d?.result)) setSyndicatedContent(d.result);
138+
})
139+
.catch(() => {});
140+
}, [projectId, dataset]);
114141

115142
const handleDiscoverOutbound = async () => {
116143
setDiscovering(true);
@@ -185,6 +212,21 @@ export function App() {
185212
>
186213
3. Stripe 50/50 Billing &amp; Deal Rooms
187214
</button>
215+
<button
216+
type="button"
217+
onClick={() => setActiveTab("syndication")}
218+
style={{
219+
padding: "8px 16px",
220+
borderRadius: 8,
221+
border: "1px solid #ccc",
222+
background: activeTab === "syndication" ? "#111" : "#fff",
223+
color: activeTab === "syndication" ? "#fff" : "#111",
224+
fontWeight: 600,
225+
cursor: "pointer",
226+
}}
227+
>
228+
4. Syndication &amp; Platform Links ({syndications.data?.length || syndicatedContent.length})
229+
</button>
188230
</div>
189231
</header>
190232

@@ -318,6 +360,133 @@ export function App() {
318360
</ul>
319361
</section>
320362
)}
363+
364+
{activeTab === "syndication" && (
365+
<section style={{ padding: 20, border: "1px solid #ddd", borderRadius: 12 }}>
366+
<div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", marginBottom: 16 }}>
367+
<div>
368+
<h2 style={{ margin: 0, fontSize: 18 }}>Cross-Platform Syndication &amp; YouTube Funnel Tracker</h2>
369+
<p style={{ margin: "4px 0 0", color: "#666", fontSize: 13 }}>
370+
Tracks canonical <code>codingcat.dev</code> URLs and outbound links across YouTube, daily.dev Squad, Dev.to, Hashnode, AWS Builder Center, Medium, and Reddit.
371+
</p>
372+
</div>
373+
<div style={{ display: "flex", gap: 8 }}>
374+
<a
375+
href="https://daily.dev/squads/codingcatdev"
376+
target="_blank"
377+
rel="noreferrer"
378+
style={{ padding: "8px 12px", border: "1px solid #ccc", borderRadius: 6, textDecoration: "none", color: "#111", fontSize: 12, fontWeight: 600 }}
379+
>
380+
daily.dev Squad &nearr;
381+
</a>
382+
<a
383+
href="https://dev.to/codingcatdev"
384+
target="_blank"
385+
rel="noreferrer"
386+
style={{ padding: "8px 12px", border: "1px solid #ccc", borderRadius: 6, textDecoration: "none", color: "#111", fontSize: 12, fontWeight: 600 }}
387+
>
388+
Dev.to Org &nearr;
389+
</a>
390+
</div>
391+
</div>
392+
<div style={{ overflowX: "auto" }}>
393+
<table style={{ width: "100%", borderCollapse: "collapse", fontSize: 13 }}>
394+
<thead>
395+
<tr style={{ textAlign: "left", borderBottom: "2px solid #eee" }}>
396+
<th style={{ padding: "8px 6px" }}>Date</th>
397+
<th style={{ padding: "8px 6px" }}>Title (Canonical)</th>
398+
<th style={{ padding: "8px 6px" }}>YouTube</th>
399+
<th style={{ padding: "8px 6px" }}>daily.dev Squad</th>
400+
<th style={{ padding: "8px 6px" }}>Dev.to</th>
401+
<th style={{ padding: "8px 6px" }}>Hashnode</th>
402+
<th style={{ padding: "8px 6px" }}>AWS Builder</th>
403+
<th style={{ padding: "8px 6px" }}>Medium / Reddit</th>
404+
</tr>
405+
</thead>
406+
<tbody>
407+
{syndicatedContent.map((item) => {
408+
const canonical = `${siteOrigin}/${item._type}/${item.slug}`;
409+
const hnUrl = item.hashnode
410+
? item.hashnode.startsWith("http")
411+
? item.hashnode
412+
: `https://hashnode.codingcat.dev/${item.hashnode}`
413+
: null;
414+
return (
415+
<tr key={item._id} style={{ borderBottom: "1px solid #f0f0f0" }}>
416+
<td style={{ padding: "8px 6px", whiteSpace: "nowrap", color: "#666" }}>
417+
{(item.date || "").slice(0, 10)}
418+
</td>
419+
<td style={{ padding: "8px 6px", fontWeight: 600 }}>
420+
<a href={canonical} target="_blank" rel="noreferrer" style={{ color: "#111" }}>
421+
{item.title}
422+
</a>
423+
</td>
424+
<td style={{ padding: "8px 6px" }}>
425+
{item.youtube ? (
426+
<a href={item.youtube} target="_blank" rel="noreferrer" style={{ color: "#c00", fontWeight: 600 }}>
427+
Watch &nearr;
428+
</a>
429+
) : (
430+
<span style={{ color: "#aaa" }}>-</span>
431+
)}
432+
</td>
433+
<td style={{ padding: "8px 6px" }}>
434+
{item.dailydev ? (
435+
<a href={item.dailydev} target="_blank" rel="noreferrer" style={{ color: "#7c3aed", fontWeight: 600 }}>
436+
Squad &nearr;
437+
</a>
438+
) : (
439+
<span style={{ color: "#aaa" }}>-</span>
440+
)}
441+
</td>
442+
<td style={{ padding: "8px 6px" }}>
443+
{item.devto ? (
444+
<a href={item.devto} target="_blank" rel="noreferrer" style={{ color: "#2563eb", fontWeight: 600 }}>
445+
Dev.to &nearr;
446+
</a>
447+
) : (
448+
<span style={{ color: "#aaa" }}>-</span>
449+
)}
450+
</td>
451+
<td style={{ padding: "8px 6px" }}>
452+
{hnUrl ? (
453+
<a href={hnUrl} target="_blank" rel="noreferrer" style={{ color: "#2563eb", fontWeight: 600 }}>
454+
Hashnode &nearr;
455+
</a>
456+
) : (
457+
<span style={{ color: "#aaa" }}>-</span>
458+
)}
459+
</td>
460+
<td style={{ padding: "8px 6px" }}>
461+
{item.awsbuilder ? (
462+
<a href={item.awsbuilder} target="_blank" rel="noreferrer" style={{ color: "#d97706", fontWeight: 600 }}>
463+
AWS &nearr;
464+
</a>
465+
) : (
466+
<span style={{ color: "#aaa" }}>-</span>
467+
)}
468+
</td>
469+
<td style={{ padding: "8px 6px" }}>
470+
{item.medium && (
471+
<a href={item.medium} target="_blank" rel="noreferrer" style={{ marginRight: 8 }}>
472+
Medium &nearr;
473+
</a>
474+
)}
475+
{item.reddit && (
476+
<a href={item.reddit} target="_blank" rel="noreferrer" style={{ color: "#ea580c" }}>
477+
Reddit &nearr;
478+
</a>
479+
)}
480+
{!item.medium && !item.reddit && <span style={{ color: "#aaa" }}>-</span>}
481+
</td>
482+
</tr>
483+
);
484+
})}
485+
</tbody>
486+
</table>
487+
</div>
488+
</section>
489+
)}
321490
</div>
322491
);
323492
}

0 commit comments

Comments
 (0)