Skip to content
This repository was archived by the owner on May 15, 2026. It is now read-only.

Commit 7df0f88

Browse files
committed
feat(blog): add source badges for podcast content (Office Hours, After Hours, Roo Cast)
- Add BlogSource type to types.ts - Export BlogSource from blog index - Add SourceBadge component to BlogPostList with colored badges - Each podcast has distinct color: blue (Office Hours), purple (After Hours), emerald (Roo Cast)
1 parent e9c598b commit 7df0f88

3 files changed

Lines changed: 46 additions & 3 deletions

File tree

apps/web-roo-code/src/components/blog/BlogPostList.tsx

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,46 @@
44
*/
55

66
import Link from "next/link"
7-
import type { BlogPost } from "@/lib/blog"
7+
import type { BlogPost, BlogSource } from "@/lib/blog"
88
import { formatPostDatePt } from "@/lib/blog"
99

1010
interface BlogPostListProps {
1111
posts: BlogPost[]
1212
}
1313

14+
/**
15+
* Source badge colors and icons
16+
* Each podcast has a distinct color for visual differentiation
17+
*/
18+
const SOURCE_STYLES: Record<BlogSource, { bg: string; text: string; icon: string }> = {
19+
"Office Hours": {
20+
bg: "bg-blue-500/10 dark:bg-blue-400/10",
21+
text: "text-blue-700 dark:text-blue-300",
22+
icon: "🎙️",
23+
},
24+
"After Hours": {
25+
bg: "bg-purple-500/10 dark:bg-purple-400/10",
26+
text: "text-purple-700 dark:text-purple-300",
27+
icon: "🌙",
28+
},
29+
"Roo Cast": {
30+
bg: "bg-emerald-500/10 dark:bg-emerald-400/10",
31+
text: "text-emerald-700 dark:text-emerald-300",
32+
icon: "📻",
33+
},
34+
}
35+
36+
function SourceBadge({ source }: { source: BlogSource }) {
37+
const style = SOURCE_STYLES[source]
38+
return (
39+
<span
40+
className={`inline-flex items-center gap-1 rounded-full px-2.5 py-0.5 text-xs font-medium ${style.bg} ${style.text}`}>
41+
<span aria-hidden="true">{style.icon}</span>
42+
{source}
43+
</span>
44+
)
45+
}
46+
1447
export function BlogPostList({ posts }: BlogPostListProps) {
1548
if (posts.length === 0) {
1649
return (
@@ -29,7 +62,10 @@ export function BlogPostList({ posts }: BlogPostListProps) {
2962
{post.title}
3063
</h2>
3164
</Link>
32-
<p className="mt-2 text-sm text-muted-foreground">{formatPostDatePt(post.publish_date)}</p>
65+
<div className="mt-2 flex flex-wrap items-center gap-2 text-sm text-muted-foreground">
66+
{post.source && <SourceBadge source={post.source} />}
67+
<span>{formatPostDatePt(post.publish_date)}</span>
68+
</div>
3369
<p className="mt-3 text-muted-foreground">{post.description}</p>
3470
{post.tags.length > 0 && (
3571
<div className="mt-4 flex flex-wrap gap-2">

apps/web-roo-code/src/lib/blog/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
*/
55

66
// Types
7-
export type { BlogPost, BlogPostFrontmatter, NowPt } from "./types"
7+
export type { BlogPost, BlogPostFrontmatter, BlogSource, NowPt } from "./types"
88
export type { PaginatedBlogPosts } from "./content"
99

1010
// Content loading

apps/web-roo-code/src/lib/blog/types.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,12 @@
33
* MKT-67: Blog Content Layer
44
*/
55

6+
/**
7+
* Content source for blog posts
8+
* Posts derived from podcast episodes have a source; standalone articles may not
9+
*/
10+
export type BlogSource = "Office Hours" | "After Hours" | "Roo Cast"
11+
612
export interface BlogPostFrontmatter {
713
title: string
814
slug: string
@@ -11,6 +17,7 @@ export interface BlogPostFrontmatter {
1117
status: "draft" | "published"
1218
publish_date: string // YYYY-MM-DD
1319
publish_time_pt: string // h:mmam/pm (e.g., "9:00am")
20+
source?: BlogSource // Optional: indicates podcast source
1421
}
1522

1623
export interface BlogPost extends BlogPostFrontmatter {

0 commit comments

Comments
 (0)