diff --git a/apps/librelingo-web/src/app/[sourceLanguageCode]/courses/[targetLanguageCode]/page.tsx b/apps/librelingo-web/src/app/[sourceLanguageCode]/courses/[targetLanguageCode]/page.tsx
index 268aee76728..fea9b2f476b 100644
--- a/apps/librelingo-web/src/app/[sourceLanguageCode]/courses/[targetLanguageCode]/page.tsx
+++ b/apps/librelingo-web/src/app/[sourceLanguageCode]/courses/[targetLanguageCode]/page.tsx
@@ -1,4 +1,4 @@
-import { listAvailableCourses } from "@/data/course"
+import { getCourseDetail, getCourseId, listAvailableCourses } from "@/data/course"
export async function generateStaticParams() {
const courses = await listAvailableCourses()
@@ -9,6 +9,16 @@ export async function generateStaticParams() {
}))
}
-export default function CourseHomePage() {
- return
Hello world
+type Props = {
+ params: {
+ sourceLanguageCode: string
+ targetLanguageCode: string
+ }
+}
+
+export default async function CourseHomePage({params}: Props) {
+ const courseId = await getCourseId(params)
+ const detail = await getCourseDetail(courseId)
+
+ return {detail.targetLanguage.name}
}
diff --git a/apps/librelingo-web/src/data/course.ts b/apps/librelingo-web/src/data/course.ts
index 382774292bc..6f8a7273bc3 100644
--- a/apps/librelingo-web/src/data/course.ts
+++ b/apps/librelingo-web/src/data/course.ts
@@ -1,6 +1,14 @@
+'use server'
+
import path from 'node:path'
import courseConfig from '@/courses/config.json'
import fs from 'node:fs'
+import { notFound } from 'next/navigation'
+
+export type CourseIdentityDescription = {
+ sourceLanguageCode: string
+ targetLanguageCode: string
+}
export type Course = {
id: string
@@ -59,3 +67,31 @@ export async function listAvailableCourses(): Promise {
})
)
}
+
+export async function getCourseId(
+ parameters: CourseIdentityDescription
+): Promise {
+ const availableCourses = await listAvailableCourses()
+
+ const course = availableCourses.find(
+ (item) =>
+ item.uiLanguage === parameters.sourceLanguageCode &&
+ item.languageCode === parameters.targetLanguageCode
+ )
+
+ if (course === undefined) {
+ notFound()
+ }
+
+ return course.id
+}
+
+export async function getCourseDetail(courseId: string) {
+ const { languageName } = await getCourseMetadataByJsonPath(courseId)
+
+ return {
+ targetLanguage: {
+ name: languageName,
+ },
+ }
+}
diff --git a/e2e-tests/course.spec.ts b/e2e-tests/course.spec.ts
new file mode 100644
index 00000000000..bc7f324a8ba
--- /dev/null
+++ b/e2e-tests/course.spec.ts
@@ -0,0 +1,9 @@
+import { test, expect } from '@playwright/test'
+
+test('has the correct content', async ({ page }) => {
+ await page.goto('/en/courses/test-1')
+
+ await expect(
+ page.getByRole('heading', { name: 'Test Language' })
+ ).toBeVisible()
+})
diff --git a/e2e-tests/home.spec.ts b/e2e-tests/home.spec.ts
index 763e3e8a995..551c219b1a1 100644
--- a/e2e-tests/home.spec.ts
+++ b/e2e-tests/home.spec.ts
@@ -1,9 +1,7 @@
import { test, expect } from '@playwright/test'
-const baseURL = 'http://localhost:3000/'
-
test('has the correct content', async ({ page }) => {
- await page.goto(baseURL)
+ await page.goto('/')
const firstCard = page.getByRole('listitem').first()
@@ -14,7 +12,7 @@ test('has the correct content', async ({ page }) => {
test('all card buttons lead to URLs matching the pattern', async ({ page }) => {
const courseHomePagePattern = new RegExp(`[^/]*/courses/[^/]+`)
- await page.goto(baseURL)
+ await page.goto('/')
const cards = await page.getByRole('listitem').all()
diff --git a/playwright.config.ts b/playwright.config.ts
index d26a1c1323b..b77cfa7d037 100644
--- a/playwright.config.ts
+++ b/playwright.config.ts
@@ -24,7 +24,7 @@ export default defineConfig({
/* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */
use: {
/* Base URL to use in actions like `await page.goto('/')`. */
- // baseURL: 'http://127.0.0.1:3000',
+ baseURL: 'http://127.0.0.1:3000',
/* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */
trace: 'on-first-retry',