feat: productionize learning engine and classroom
This commit is contained in:
@@ -18,6 +18,7 @@ import { Button } from '@/components/ui/button';
|
||||
import { MediaPopover, type MediaCapabilityOverride } from '@/components/generation/media-popover';
|
||||
import type { SettingsSection } from '@/lib/types/settings';
|
||||
import { cn } from '@/lib/utils';
|
||||
import { opsApiFetch } from '@/lib/ops/api-fetch';
|
||||
|
||||
const WEB_SEARCH_STORAGE_KEY = 'webSearchEnabled';
|
||||
|
||||
@@ -64,16 +65,13 @@ export function LargeCourseWorkbench({
|
||||
const [webSearch, setWebSearch] = useState(false);
|
||||
const [enableImageGeneration, setEnableImageGeneration] = useState(false);
|
||||
const [enableVideoGeneration, setEnableVideoGeneration] = useState(false);
|
||||
const [enableTTS, setEnableTTS] = useState(true);
|
||||
const [creating, setCreating] = useState(false);
|
||||
const [createError, setCreateError] = useState<string | null>(null);
|
||||
const [items, setItems] = useState<CourseListItem[]>([]);
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [loadError, setLoadError] = useState<string | null>(null);
|
||||
|
||||
// Large courses always keep narration enabled because publishing requires
|
||||
// persisted speech audio for every module.
|
||||
const enableTTS = true;
|
||||
|
||||
useEffect(() => {
|
||||
try {
|
||||
if (localStorage.getItem(WEB_SEARCH_STORAGE_KEY) === 'true') setWebSearch(true);
|
||||
@@ -95,7 +93,7 @@ export function LargeCourseWorkbench({
|
||||
setLoading(true);
|
||||
setLoadError(null);
|
||||
try {
|
||||
const response = await fetch('/api/courses');
|
||||
const response = await opsApiFetch('/api/courses');
|
||||
const body = (await response.json()) as { items?: CourseListItem[] };
|
||||
if (!response.ok || !Array.isArray(body.items)) {
|
||||
throw new Error(`HTTP ${response.status}`);
|
||||
@@ -119,7 +117,7 @@ export function LargeCourseWorkbench({
|
||||
setCreating(true);
|
||||
setCreateError(null);
|
||||
try {
|
||||
const response = await fetch('/api/courses', {
|
||||
const response = await opsApiFetch('/api/courses', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({
|
||||
@@ -127,7 +125,7 @@ export function LargeCourseWorkbench({
|
||||
enableWebSearch: webSearch || undefined,
|
||||
enableImageGeneration: enableImageGeneration || undefined,
|
||||
enableVideoGeneration: enableVideoGeneration || undefined,
|
||||
enableTTS: enableTTS || undefined,
|
||||
enableTTS,
|
||||
}),
|
||||
});
|
||||
const body = (await response.json()) as {
|
||||
@@ -151,9 +149,7 @@ export function LargeCourseWorkbench({
|
||||
> = {
|
||||
image: { enabled: enableImageGeneration, onToggle: setEnableImageGeneration },
|
||||
video: { enabled: enableVideoGeneration, onToggle: setEnableVideoGeneration },
|
||||
// Narration is a large-course publishing requirement, so keep it visible
|
||||
// in the shared settings bar without allowing it to be switched off.
|
||||
tts: { enabled: enableTTS, disabled: true },
|
||||
tts: { enabled: enableTTS, onToggle: setEnableTTS },
|
||||
asr: { enabled: false, disabled: true },
|
||||
};
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ import { useI18n } from '@/lib/hooks/use-i18n';
|
||||
import { cn } from '@/lib/utils';
|
||||
import type { SceneOutline } from '@/lib/types/generation';
|
||||
import type { WidgetType } from '@/lib/types/widgets';
|
||||
import { changeOutlineType } from '@openmaic/generation';
|
||||
import { changeOutlineType } from '@openmaic/generation/outline-type';
|
||||
import { countBlockingOutlines, validateOutline } from '@/lib/edit/content-validation';
|
||||
|
||||
type SceneType = SceneOutline['type'];
|
||||
|
||||
Reference in New Issue
Block a user