Skip to content

Commit b6333d9

Browse files
committed
chore: add new lesson for js 7 day
1 parent 359aef1 commit b6333d9

7 files changed

Lines changed: 367 additions & 498 deletions

File tree

src/lib/content/courses/js-7day/day-1/what-is-javascript.mdx

Lines changed: 0 additions & 164 deletions
This file was deleted.

src/routes/api/lessons/[courseId]/[slug]/+server.ts

Lines changed: 65 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { marked, Renderer } from 'marked';
44
import matter from 'gray-matter';
55
import hljs from 'highlight.js';
66
import * as m from '$lib/paraglide/messages';
7+
import type { CourseDetail } from '$lib/types/course-detail';
78

89
// Custom renderer for code blocks with syntax highlighting
910
const renderer = new Renderer();
@@ -38,24 +39,72 @@ export const GET: RequestHandler = async ({ params, url, fetch }) => {
3839
const locale = (langParam === 'tr' ? 'tr' : 'en') as 'en' | 'tr';
3940

4041
try {
41-
// Try to load language-specific file, fallback to English
42-
const contentPath = `/content/courses/${params.courseId}/${locale}/${params.slug}.md`;
43-
let rawMarkdown: string;
42+
const courseId = params.courseId;
43+
const slug = params.slug;
4444

45-
try {
46-
// In production (Cloudflare), fetch from static assets
47-
// In dev, this will be served by Vite's dev server
48-
const response = await fetch(contentPath);
49-
if (!response.ok) throw new Error('File not found');
50-
rawMarkdown = await response.text();
51-
} catch {
52-
// Fallback to English if language-specific file not found
53-
const fallbackPath = `/content/courses/${params.courseId}/en/${params.slug}.md`;
54-
const response = await fetch(fallbackPath);
55-
if (!response.ok) {
56-
throw new Error('Lesson not found');
45+
const loadCourseDetail = async (lang: 'en' | 'tr'): Promise<CourseDetail | null> => {
46+
try {
47+
const module = await import(`$lib/data/course-details/${courseId}-${lang}.json`);
48+
return module.default as CourseDetail;
49+
} catch {
50+
return null;
51+
}
52+
};
53+
54+
const localeDetail = await loadCourseDetail(locale);
55+
const englishDetail = locale === 'en' ? localeDetail : await loadCourseDetail('en');
56+
57+
const findDayInfo = (detail: CourseDetail | null) => {
58+
if (!detail) return null;
59+
for (const day of detail.curriculum) {
60+
const lessonIndex = day.lessons.findIndex((lesson) => lesson.slug === slug);
61+
if (lessonIndex !== -1) {
62+
return {
63+
day: day.day,
64+
lessonIndex: lessonIndex + 1
65+
};
66+
}
67+
}
68+
return null;
69+
};
70+
71+
const dayInfo = findDayInfo(localeDetail) ?? findDayInfo(englishDetail);
72+
73+
const candidatePaths: string[] = [];
74+
75+
if (dayInfo) {
76+
const dayFolder = `day-${String(dayInfo.day).padStart(2, '0')}`;
77+
candidatePaths.push(`/content/courses/${courseId}/${locale}/${dayFolder}/${slug}.md`);
78+
if (locale !== 'en') {
79+
candidatePaths.push(`/content/courses/${courseId}/en/${dayFolder}/${slug}.md`);
5780
}
58-
rawMarkdown = await response.text();
81+
}
82+
83+
// Legacy structure fallback
84+
candidatePaths.push(`/content/courses/${courseId}/${locale}/${slug}.md`);
85+
if (locale !== 'en') {
86+
candidatePaths.push(`/content/courses/${courseId}/en/${slug}.md`);
87+
}
88+
89+
const uniquePaths = Array.from(new Set(candidatePaths));
90+
91+
let rawMarkdown: string | null = null;
92+
93+
for (const path of uniquePaths) {
94+
try {
95+
const response = await fetch(path);
96+
if (!response.ok) {
97+
continue;
98+
}
99+
rawMarkdown = await response.text();
100+
break;
101+
} catch (err) {
102+
console.warn(`Could not load lesson from ${path}:`, err);
103+
}
104+
}
105+
106+
if (!rawMarkdown) {
107+
throw new Error('Lesson not found');
59108
}
60109

61110
// Parse frontmatter and content (server-side only)

0 commit comments

Comments
 (0)