feat: live class sessions, CE workflow, and docs (#683)
Adds live-class session scheduling on lessons (join link, date/time, timezone) with automatic 24h and 1h reminder emails plus a calendar invite (.ics), a time-change notification with an updated invite, a teacher-authored welcome email and session invite on enrollment, and a "Notify students" quiz nudge. LMS gets an upcoming live-sessions card and Join buttons, plus a reusable live-session card component (3 states) in @cio/ui with a Storybook story. The sidebar content tree now reflects sequential progression locking like the content list, and the course-completion confetti regression is fixed. Org-based emails no longer reference ClassroomIO by name. Docs add live-class, welcome-email, and course-progression guides, expand the certificates guide (design, signatures, corrected labels), move plan-required callouts to the top, flatten how-to-guides to the docs root with redirects, and add screenshots. Includes an add-docs-image skill.
This commit is contained in:
@@ -2,7 +2,7 @@ import { useMemo } from 'react';
|
||||
|
||||
import type * as PageTree from 'fumadocs-core/page-tree';
|
||||
import browserCollections from 'fumadocs-mdx:collections/browser';
|
||||
import { isRouteErrorResponse, useLoaderData, useRouteError } from 'react-router';
|
||||
import { isRouteErrorResponse, redirect, useLoaderData, useRouteError } from 'react-router';
|
||||
import { DocsLayout } from 'fumadocs-ui/layouts/docs';
|
||||
import { DocsBody, DocsDescription, DocsPage, DocsTitle } from 'fumadocs-ui/layouts/docs/page';
|
||||
import { HomeLayout } from 'fumadocs-ui/layouts/home';
|
||||
@@ -26,6 +26,13 @@ const clientLoader = browserCollections.docs.createClientLoader({
|
||||
|
||||
export async function loader({ params }: { params: Record<string, string | undefined> }) {
|
||||
const slug = params['*'];
|
||||
|
||||
// How-to guides were flattened to the docs root; permanently redirect the old
|
||||
// `.../how-to-guides/<page>` URLs to `.../<page>`.
|
||||
if (slug && slug.includes('how-to-guides/')) {
|
||||
throw redirect('/' + slug.replace('how-to-guides/', ''), 301);
|
||||
}
|
||||
|
||||
const slugs = slug ? slug.split('/') : ['home'];
|
||||
const { getDocsRouteData } = await import('@/lib/source.server');
|
||||
const routeData = await getDocsRouteData(slugs);
|
||||
|
||||
Reference in New Issue
Block a user