@@ -4,6 +4,7 @@ import { marked, Renderer } from 'marked';
44import matter from 'gray-matter' ;
55import hljs from 'highlight.js' ;
66import * 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
910const 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