feat: introducing @classroomio/course-app (#490)

* feat: v1 templates

* update nvm

* working on the displaying the course content

* working on the displaying the course content

* displayed the content

* finished with the logic for rendering the content for all the courses and lessons

* post hog template UI is good to go

* classic and minimalistic template UI is good to go

* some refactoring

* some refactoring

* layout adjustments

* update tsconfig

* trying to get the filter to work well

* this is working now

* cleanup

* cleanup

* UI updates

* course page UI for posthog

* navbar and sidebar for course page in all templates complete

* all templates course page showing lesson content from md file with mdsvex
configured

* wokring on sections

* posthog lesson content done

* all templates fetches the lesson content from the section

* all templates properly typed

* scaffolding the new template

* finished the webflow-saas

* done with the webflow saas UI

* new calcom template

* new calcom template

* masonry layout for testitomonail section layout done

* calcom UI done

* UI all done

* cleanup

* trying to fix dark mode for the course page and home page

* done with this

* done with this

* working on tests

* migrated minimalistic template to svelte 5

* updated the syntax to svelte 5 for webflow

* migrated classic to svelte 5

* migrated posthog to svelte 5

* used svelte 5 syntax in calcom

* cli tool woks locally

* rename to course-sites

* use pnpm in root

* calcom refactoring

* remove unused files

* chore: biggest refactoring in my life

* add basic readme

* refactoring on course page

* restructure how courses are ordered

* proper state propagation

* add cf adapter

* fix pnpm i issue

* fix folder icon size

* use 18.17 version

* update npmrc

* add engine to packagejson

* pnpm install

* add engine to cio-com

* make it 18.x

* remove sequence

* move mdsvex to dependencies

* update lock

* mdsvex please work

* replace fs with import from vite

* add lock

* styling improvements

* fix styling

* sidebar style improvements

* fix: mobile concerns

* fix spacing of course header on desktop

* update header

* top nav fix

* feat: make cal template

* setup another template

* classic basic UI

* fixed the /courses fetching wrong page content

* fix breaking template cause of logo

* adding some updates

* improve styles theming

* finished updates from reviews

* updated the custom styling css

* clean up posthog template

* cli tool done, needs some cleaning though

* moved components to home

* improved the UI of the minimal template

* Add CLI tool and course app site

* prettier lint

* improve CLI

* ignore sveltekit folder

* publish course app

* fix tailwing theme + improve README

* finish up course-app site

* update README.md

---------

Co-authored-by: emmanuel <chifez1@gmail.com>
This commit is contained in:
Rotimi Best
2024-12-14 03:40:47 +01:00
committed by GitHub
co-authored by emmanuel
parent 7e239da7d2
commit 26700dccd0
343 changed files with 17993 additions and 350 deletions
@@ -0,0 +1,109 @@
import { test, expect } from '@playwright/test';
const PORT = process.env.PORT || '5173';
const BASE_URL = `http://localhost:${PORT}`;
test.describe('Course Page', () => {
// Mock data for our tests
const mockCourseData = {
metadata: {
title: 'Test Course'
},
sections: [
{
title: 'Section 1',
sectionSlug: 'section-1',
published: true,
children: [
{ title: 'Lesson 1', filename: 'lesson-1.md' },
{ title: 'Lesson 2', filename: 'lesson-2.md' }
]
},
{
title: 'Section 2',
sectionSlug: 'section-2',
published: true,
children: [{ title: 'Lesson 3', filename: 'lesson-3.md' }]
}
]
};
const mockLessonContent = {
content: '<h1>Test Lesson Content</h1>'
};
test.beforeEach(async ({ page }) => {
// Mock the API responses
await page.route('**/api/lesson/**', async (route) => {
await route.fulfill({
json: mockLessonContent
});
});
// Navigate to the course page
await page.goto(`${BASE_URL}/course/test-course`);
});
test('loads initial lesson content correctly', async ({ page }) => {
// Check if course title is displayed
await expect(page.locator('text=Test Course')).toBeVisible();
// Check if first lesson is loaded by default
await expect(page.locator('text=Lesson 1')).toBeVisible();
await expect(page.locator('h1:has-text("Test Lesson Content")')).toBeVisible();
});
test('sidebar navigation works correctly', async ({ page }) => {
// Click on second lesson
await page.click('text=Lesson 2');
// Verify lesson content changed
await expect(page.locator('h1:has-text("Test Lesson Content")')).toBeVisible();
// Verify active lesson indicator
await expect(page.locator('.border-black:has-text("Lesson 2")')).toBeVisible();
});
test('toggles dark mode correctly', async ({ page }) => {
// Check initial light mode
await expect(page.locator('body')).not.toHaveClass(/dark/);
// Click dark mode toggle
await page.click('button:has(svg)'); // Adjust selector based on your Moon/Light icon implementation
// Verify dark mode is enabled
await expect(page.locator('body')).toHaveClass(/dark/);
});
test('mobile sidebar toggle works', async ({ page }) => {
// Set viewport to mobile size
await page.setViewportSize({ width: 375, height: 667 });
// Verify sidebar is hidden initially
await expect(page.locator('.translate-x-full')).toBeVisible();
// Click menu button
await page.click('button:has(.carbon-icons-svelte-Menu)');
// Verify sidebar is visible
await expect(page.locator('.translate-x-0')).toBeVisible();
// Click lesson and verify sidebar closes
await page.click('text=Lesson 2');
await expect(page.locator('.translate-x-full')).toBeVisible();
});
test('handles unpublished sections correctly', async ({ page }) => {
// Add test for sections marked as "coming soon"
await expect(page.locator('text=coming soon')).toBeVisible();
// Verify unpublished sections can't be expanded
await page.click('text=coming soon');
await expect(page.locator('text=Lesson 3')).not.toBeVisible();
});
test('back to course page link works', async ({ page }) => {
await page.click('text=Back to course page');
await expect(page).toHaveURL('/courses');
});
});