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:
@@ -1,5 +1,37 @@
|
||||
export const getDefaultTemplate = (content: string): string =>
|
||||
`<!DOCTYPE html>
|
||||
import type { EmailBranding } from '../core/branding';
|
||||
|
||||
const DEFAULT_BUTTON_COLOR = '#1D4EE2';
|
||||
const CLASSROOMIO_LOGO = 'https://brand.cdn.clsrio.com/cio-bg-transparent.png';
|
||||
|
||||
function escapeHtmlAttr(value: string): string {
|
||||
return value.replace(/&/g, '&').replace(/"/g, '"').replace(/</g, '<').replace(/>/g, '>');
|
||||
}
|
||||
|
||||
function buildMasthead(branding: EmailBranding): string {
|
||||
const logoUrl = branding?.logoUrl;
|
||||
const orgName = branding?.orgName ? escapeHtmlAttr(branding.orgName) : '';
|
||||
|
||||
if (logoUrl) {
|
||||
const nameHtml = orgName
|
||||
? `<span style="margin-left:10px;font-size:16px;font-weight:600;color:#111827;vertical-align:middle;">${orgName}</span>`
|
||||
: '';
|
||||
return `<img src="${logoUrl}" alt="${orgName || 'Logo'}" style="max-height:40px;width:auto;display:inline-block;vertical-align:middle;" />${nameHtml}`;
|
||||
}
|
||||
|
||||
if (orgName) {
|
||||
return `<span style="font-size:18px;font-weight:600;color:#111827;">${orgName}</span>`;
|
||||
}
|
||||
|
||||
return `<a href="https://classroomio.com" target="_blank">
|
||||
<img src="${CLASSROOMIO_LOGO}" alt="ClassroomIO" width="130" style="width:130px;height:auto;display:block;" />
|
||||
</a>`;
|
||||
}
|
||||
|
||||
export const getDefaultTemplate = (content: string, branding?: EmailBranding): string => {
|
||||
const buttonColor = branding?.themeColor || DEFAULT_BUTTON_COLOR;
|
||||
const masthead = buildMasthead(branding);
|
||||
|
||||
return `<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
@@ -57,7 +89,7 @@ export const getDefaultTemplate = (content: string): string =>
|
||||
|
||||
.button {
|
||||
margin-top: 12px;
|
||||
background: #1D4EE2;
|
||||
background: ${buttonColor};
|
||||
border-radius: 6px;
|
||||
text-decoration: none !important;
|
||||
color: #fff !important;
|
||||
@@ -105,9 +137,7 @@ export const getDefaultTemplate = (content: string): string =>
|
||||
">
|
||||
<div style="background-color:#fff;max-width:525px;margin:0 auto;border-radius:4px;">
|
||||
<div style="padding:10px;border-bottom:1px solid #f0f0f0;">
|
||||
<a href="https://classroomio.com" target="_blank">
|
||||
<img src="https://brand.cdn.clsrio.com/cio-bg-transparent.png" alt="ClassroomIO" width="130" style="width:130px;height:auto;display:block;" />
|
||||
</a>
|
||||
${masthead}
|
||||
</div>
|
||||
<div style="padding:10px 15px;">
|
||||
${content}
|
||||
@@ -131,3 +161,4 @@ export const getDefaultTemplate = (content: string): string =>
|
||||
|
||||
</html>
|
||||
`;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user