Skip to content

Commit cdbbb0f

Browse files
committed
feat(site): add interactive course lesson player route and remove legacy Brittney Postma contact text
1 parent 753b2fe commit cdbbb0f

3 files changed

Lines changed: 480 additions & 15 deletions

File tree

‎apps/site/src/pages/course/[slug].astro‎

Lines changed: 95 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ interface CourseLesson {
1515
title?: string | null;
1616
slug?: string | null;
1717
excerpt?: string | null;
18+
youtube?: string | null;
19+
videoCloudinary?: { asset?: { _ref?: string } } | null;
1820
}
1921
2022
interface CourseSection {
@@ -30,7 +32,11 @@ interface CourseDetail {
3032
coverImage?: CoverImageType | null;
3133
videoCloudinary?: { asset?: { _ref?: string } } | null;
3234
youtube?: string | null;
33-
content?: Array<{ _type: string; [key: string]: unknown }> | null;
35+
content?: Array<{
36+
_type: string;
37+
children?: Array<{ text?: string }>;
38+
[key: string]: unknown;
39+
}> | null;
3440
sections?: CourseSection[] | null;
3541
}
3642
@@ -45,6 +51,18 @@ if (!course?._id) {
4551
}
4652
4753
const sections: CourseSection[] = course.sections ?? [];
54+
const allLessons: CourseLesson[] = sections.flatMap((sec) =>
55+
(sec?.lesson ?? []).filter((l): l is CourseLesson => Boolean(l?.slug)),
56+
);
57+
const firstLesson = allLessons[0] ?? null;
58+
59+
// Strip legacy blocks mentioning contacting @BrittneyPostma or @codercatdev
60+
const sanitizedContent = (course.content ?? []).filter((block) => {
61+
const blockText = Array.isArray(block?.children)
62+
? block.children.map((child) => child?.text ?? "").join("")
63+
: "";
64+
return !/brittneypostma|codercatdev/i.test(blockText);
65+
});
4866
---
4967

5068
<BaseLayout
@@ -65,8 +83,29 @@ const sections: CourseSection[] = course.sections ?? [];
6583
/>
6684

6785
<article class="py-6">
68-
<div class="mb-6 inline-flex items-center gap-2 rounded-full border-2 border-[#2A1155] bg-[#EDE9FE] px-4 py-1 font-mono text-xs font-extrabold uppercase tracking-wider text-[#7C3AED] dark:border-purple-400/40 dark:bg-purple-950/60 dark:text-purple-200 hand-border shadow-sketch-sm">
69-
🧶 CodingCat.dev Course
86+
<div class="mb-6 flex flex-wrap items-center justify-between gap-4">
87+
<div class="flex flex-wrap items-center gap-3">
88+
<div class="inline-flex items-center gap-2 rounded-full border-2 border-[#2A1155] bg-[#EDE9FE] px-4 py-1 font-mono text-xs font-extrabold uppercase tracking-wider text-[#7C3AED] dark:border-purple-400/40 dark:bg-purple-950/60 dark:text-purple-200 hand-border shadow-sketch-sm">
89+
🧶 CodingCat.dev Course
90+
</div>
91+
{
92+
allLessons.length > 0 && (
93+
<span class="rounded-full border-2 border-[#2A1155]/30 bg-white/80 px-3 py-1 font-mono text-xs font-bold text-[#2A1155] dark:border-white/20 dark:bg-[#131B2E] dark:text-slate-200">
94+
{allLessons.length} {allLessons.length === 1 ? "Lesson" : "Lessons"}
95+
</span>
96+
)
97+
}
98+
</div>
99+
{
100+
firstLesson?.slug && (
101+
<a
102+
href={`/course/${slug}/lesson/${firstLesson.slug}`}
103+
class="tactile-btn inline-flex items-center gap-2 rounded-xl border-2 border-[#2A1155] bg-[#7C3AED] px-5 py-2.5 font-display text-sm font-black text-white shadow-sketch-sm transition hover:bg-[#6D28D9] dark:border-white/80"
104+
>
105+
Start Course →
106+
</a>
107+
)
108+
}
70109
</div>
71110

72111
<h1 class="mb-8 font-display text-4xl font-black leading-tight tracking-tight text-[#2A1155] dark:text-white md:text-6xl">
@@ -88,10 +127,10 @@ const sections: CourseSection[] = course.sections ?? [];
88127
/>
89128

90129
{
91-
course.content && (
130+
sanitizedContent.length > 0 && (
92131
<div class="my-8">
93132
<PortableTextContent
94-
value={course.content}
133+
value={sanitizedContent}
95134
class="mx-auto prose-violet lg:prose-xl"
96135
/>
97136
</div>
@@ -117,16 +156,57 @@ const sections: CourseSection[] = course.sections ?? [];
117156
</div>
118157
{sec?.lesson && sec.lesson.length > 0 && (
119158
<ul class="grid gap-3 sm:grid-cols-2">
120-
{sec.lesson.map((lesson, lIdx) => (
121-
<li class="flex items-start gap-3 rounded-xl border-2 border-[#2A1155] bg-[#FAF9FC] p-3.5 dark:border-white/20 dark:bg-[#0B1326] shadow-sketch-sm">
122-
<span class="font-mono text-xs font-extrabold text-[#7C3AED] dark:text-[#C084FC]">
123-
{sIdx + 1}.{lIdx + 1}
124-
</span>
125-
<span class="font-bold text-[#2A1155] dark:text-slate-100">
126-
{lesson?.title || `Lesson ${lIdx + 1}`}
127-
</span>
128-
</li>
129-
))}
159+
{sec.lesson.map((lesson, lIdx) => {
160+
const lessonHref = lesson?.slug
161+
? `/course/${slug}/lesson/${lesson.slug}`
162+
: null;
163+
const hasVideo = Boolean(
164+
lesson?.youtube || lesson?.videoCloudinary?.asset?._ref,
165+
);
166+
return (
167+
<li>
168+
{lessonHref ? (
169+
<a
170+
href={lessonHref}
171+
class="group flex h-full flex-col justify-between gap-3 rounded-xl border-2 border-[#2A1155] bg-[#FAF9FC] p-4 shadow-sketch-sm transition hover:-translate-y-0.5 hover:border-[#7C3AED] hover:bg-[#F3E8FF]/60 dark:border-white/20 dark:bg-[#0B1326] dark:hover:border-[#C084FC] dark:hover:bg-[#131B2E]"
172+
>
173+
<div class="flex items-start gap-3">
174+
<span class="mt-0.5 inline-flex shrink-0 items-center justify-center rounded-md border border-[#7C3AED]/40 bg-[#EDE9FE] px-2 py-0.5 font-mono text-xs font-extrabold text-[#7C3AED] dark:border-purple-400/40 dark:bg-purple-950/60 dark:text-[#C084FC]">
175+
{sIdx + 1}.{lIdx + 1}
176+
</span>
177+
<div class="min-w-0 flex-1">
178+
<span class="block font-bold text-[#2A1155] transition group-hover:text-[#7C3AED] dark:text-slate-100 dark:group-hover:text-[#C084FC]">
179+
{lesson?.title || `Lesson ${lIdx + 1}`}
180+
</span>
181+
{lesson?.excerpt && (
182+
<p class="mt-1 line-clamp-2 text-xs text-slate-600 dark:text-slate-400">
183+
{lesson.excerpt}
184+
</p>
185+
)}
186+
</div>
187+
</div>
188+
<div class="flex items-center justify-between border-t border-[#2A1155]/10 pt-2.5 font-mono text-[11px] font-bold text-[#7C3AED] dark:border-white/10 dark:text-[#C084FC]">
189+
<span>
190+
{hasVideo ? "▶ Video + Lesson" : "📖 Written Lesson"}
191+
</span>
192+
<span class="transition group-hover:translate-x-0.5">
193+
Start Lesson →
194+
</span>
195+
</div>
196+
</a>
197+
) : (
198+
<div class="flex items-start gap-3 rounded-xl border-2 border-[#2A1155] bg-[#FAF9FC] p-4 shadow-sketch-sm dark:border-white/20 dark:bg-[#0B1326]">
199+
<span class="font-mono text-xs font-extrabold text-[#7C3AED] dark:text-[#C084FC]">
200+
{sIdx + 1}.{lIdx + 1}
201+
</span>
202+
<span class="font-bold text-[#2A1155] dark:text-slate-100">
203+
{lesson?.title || `Lesson ${lIdx + 1}`}
204+
</span>
205+
</div>
206+
)}
207+
</li>
208+
);
209+
})}
130210
</ul>
131211
)}
132212
</div>

0 commit comments

Comments
 (0)