Org admins see every Express schedule in the organization, so a shared organization mixed everyone's schedules together. The Schedule page now shows "Created by …" on each one and, when others' schedules are listed, switches between Mine and Everyone in the organization. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
61 lines
3.3 KiB
TypeScript
61 lines
3.3 KiB
TypeScript
import type { ContentKind, Rule } from '../express/parse'
|
||
|
||
// Line icons from the mockup (24×24, stroke = currentColor).
|
||
const paths: Record<string, string> = {
|
||
book: '<path d="M3 5c3-1 6 0 9 2 3-2 6-3 9-2v14c-3-1-6 0-9 2-3-2-6-3-9-2z"/><path d="M12 7v14M6 9l3 1M15 10l3-1"/>',
|
||
home: '<path d="m3 10 9-7 9 7v10H3z"/><path d="M9 20v-7h6v7"/>',
|
||
spark: '<path d="m12 3 2.5 6.5L21 12l-6.5 2.5L12 21l-2.5-6.5L3 12l6.5-2.5z"/><path d="m20 2 .5 1.5L22 4l-1.5.5L20 6l-.5-1.5L18 4l1.5-.5z"/>',
|
||
calendar: '<rect x="3" y="5" width="18" height="16" rx="2"/><path d="M7 3v4M17 3v4M3 11h18M7 15h3M14 15h3"/>',
|
||
clock: '<circle cx="12" cy="12" r="9"/><path d="M12 7v6l4 2"/>',
|
||
layers: '<path d="m12 3 10 5-10 5L2 8zM2 12l10 5 10-5M2 16l10 5 10-5"/>',
|
||
download: '<path d="M12 3v12m-5-5 5 5 5-5M4 16v5h16v-5"/>',
|
||
upload: '<path d="M12 16V4m-5 5 5-5 5 5M4 16v5h16v-5"/>',
|
||
file: '<path d="M5 3h9l5 5v13H5zM14 3v6h5M8 13h8M8 17h6"/>',
|
||
'arrow-right': '<path d="M4 12h16m-6-6 6 6-6 6"/>',
|
||
external: '<path d="M14 4h6v6M20 4l-9 9M18 14v6H4V6h6"/>',
|
||
close: '<path d="M6 6l12 12M18 6 6 18"/>',
|
||
search: '<circle cx="10" cy="10" r="6"/><path d="m15 15 5 5"/>',
|
||
info: '<circle cx="12" cy="12" r="9"/><path d="M12 11v6M12 7v.2"/>',
|
||
check: '<path d="m5 12 4 4L19 6"/>',
|
||
'chevron-down': '<path d="m6 9 6 6 6-6"/>',
|
||
expand: '<path d="M4 9V4h5M20 9V4h-5M4 15v5h5M20 15v5h-5"/>',
|
||
shrink: '<path d="M9 4v5H4M15 4v5h5M9 20v-5H4M15 20v-5h5"/>',
|
||
sidebar: '<rect x="3" y="4" width="18" height="16" rx="2"/><path d="M9 4v16"/>',
|
||
'chevron-updown': '<path d="m8 9 4-4 4 4M8 15l4 4 4-4"/>',
|
||
logout:'<path d="M10 4H4v16h6M10 12h11m-4-4 4 4-4 4"/>',
|
||
user: '<circle cx="12" cy="8" r="4"/><path d="M4 21c1-4 4-6 8-6s7 2 8 6"/>',
|
||
plus: '<path d="M12 4v16M4 12h16"/>',
|
||
trash: '<path d="M3 6h18M9 3h6l1 3M6 6l1 15h10l1-15M10 10v7M14 10v7"/>',
|
||
video: '<rect x="3" y="5" width="18" height="14" rx="3"/><path d="m10 9 5 3-5 3z"/>',
|
||
audio: '<path d="M4 13v-2a8 8 0 0 1 16 0v2"/><rect x="3" y="11" width="4" height="8" rx="2"/><rect x="17" y="11" width="4" height="8" rx="2"/>',
|
||
scorm: '<path d="m12 3 9 5-9 5-9-5zM3 8v9l9 5 9-5V8M12 13v9"/>',
|
||
chart: '<path d="M4 20V10M10 20V4M16 20v-7M22 20H2"/>',
|
||
coin: '<circle cx="12" cy="12" r="9"/><path d="M15 9.5c-.5-1-1.6-1.5-3-1.5-1.7 0-3 .8-3 2s1.3 1.7 3 2 3 .8 3 2-1.3 2-3 2c-1.4 0-2.5-.5-3-1.5M12 6v2M12 16v2"/>',
|
||
brain: '<path d="M12 5c-3-4-8-1-7 3-4 2-3 7 0 8-1 4 5 6 7 2M12 5c3-4 8-1 7 3 4 2 3 7 0 8 1 4-5 6-7 2M12 5v15M7 9l3 2M17 9l-3 2M6 15l3-1M18 15l-3-1"/>',
|
||
}
|
||
|
||
export type IconName = keyof typeof paths
|
||
|
||
export const KIND_ICON: Record<ContentKind, IconName> = {
|
||
summary: 'file', quiz: 'check', flashcards: 'layers', roleplay: 'spark', simulator: 'spark', slide_deck: 'layers',
|
||
video: 'video', audio: 'audio', scorm: 'scorm',
|
||
}
|
||
|
||
export const ruleIcon = (rule: Rule): IconName => (rule.type === 'research' ? 'search' : KIND_ICON[rule.kind])
|
||
|
||
export function Icon({ name }: { name: IconName }) {
|
||
return (
|
||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth={1.7} strokeLinecap="round" strokeLinejoin="round" aria-hidden="true"
|
||
dangerouslySetInnerHTML={{ __html: paths[name] ?? paths.file }} />
|
||
)
|
||
}
|
||
|
||
export function Brand() {
|
||
return (
|
||
<span className="brand">
|
||
<span className="brand-mark"><Icon name="book" /></span>
|
||
<span>Learning Lab <b>Express</b><small>by Bawana</small></span>
|
||
</span>
|
||
)
|
||
}
|