diff --git a/app/api/generate/scene-content/route.ts b/app/api/generate/scene-content/route.ts index db9b772e..d101c062 100644 --- a/app/api/generate/scene-content/route.ts +++ b/app/api/generate/scene-content/route.ts @@ -67,7 +67,7 @@ export async function POST(req: NextRequest) { // Ensure outline has language from stageInfo (fallback for older outlines) const outline: SceneOutline = { ...rawOutline, - language: rawOutline.language || (stageInfo?.language as 'zh-CN' | 'en-US') || 'zh-CN', + language: rawOutline.language || (stageInfo?.language as 'en-US' | 'id-ID' | 'ar-SA') || 'id-ID', }; // ── Model resolution from request headers ── diff --git a/app/api/generate/scene-outlines-stream/route.ts b/app/api/generate/scene-outlines-stream/route.ts index 36c1606a..235b30c0 100644 --- a/app/api/generate/scene-outlines-stream/route.ts +++ b/app/api/generate/scene-outlines-stream/route.ts @@ -121,7 +121,7 @@ export async function POST(req: NextRequest) { // Build prompt (same logic as generateSceneOutlinesFromRequirements) let availableImagesText = - requirements.language === 'zh-CN' ? '无可用图片' : 'No images available'; + requirements.language === 'id-ID' ? 'Tidak ada gambar tersedia' : 'No images available'; let visionImages: Array<{ id: string; src: string }> | undefined; if (pdfImages && pdfImages.length > 0) { @@ -177,11 +177,11 @@ export async function POST(req: NextRequest) { language: requirements.language, pdfContent: pdfText ? pdfText.substring(0, MAX_PDF_CONTENT_CHARS) - : requirements.language === 'zh-CN' - ? '无' + : requirements.language === 'id-ID' + ? 'Tidak ada' : 'None', availableImages: availableImagesText, - researchContext: researchContext || (requirements.language === 'zh-CN' ? '无' : 'None'), + researchContext: researchContext || (requirements.language === 'id-ID' ? 'Tidak ada' : 'None'), mediaGenerationPolicy, teacherContext, }); diff --git a/app/layout.tsx b/app/layout.tsx index 271af553..47a98083 100644 --- a/app/layout.tsx +++ b/app/layout.tsx @@ -17,7 +17,7 @@ const inter = localFont({ }); export const metadata: Metadata = { - title: 'OpenMAIC', + title: 'Kelas Kecerdasan Artifisial', description: 'The open-source AI interactive classroom. Upload a PDF to instantly generate an immersive, multi-agent learning experience.', }; diff --git a/app/page.tsx b/app/page.tsx index 80dfbd85..ec4caade 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -56,14 +56,14 @@ const RECENT_OPEN_STORAGE_KEY = 'recentClassroomsOpen'; interface FormState { pdfFile: File | null; requirement: string; - language: 'zh-CN' | 'en-US'; + language: 'en-US' | 'id-ID' | 'ar-SA'; webSearch: boolean; } const initialFormState: FormState = { pdfFile: null, requirement: '', - language: 'zh-CN', + language: 'id-ID', webSearch: false, }; @@ -101,10 +101,10 @@ function HomePage() { const savedLanguage = localStorage.getItem(LANGUAGE_STORAGE_KEY); const updates: Partial = {}; if (savedWebSearch === 'true') updates.webSearch = true; - if (savedLanguage === 'zh-CN' || savedLanguage === 'en-US') { + if (savedLanguage === 'en-US' || savedLanguage === 'id-ID' || savedLanguage === 'ar-SA') { updates.language = savedLanguage; } else { - const detected = navigator.language?.startsWith('zh') ? 'zh-CN' : 'en-US'; + const detected = navigator.language?.startsWith('id') ? 'id-ID' : navigator.language?.startsWith('ar') ? 'ar-SA' : navigator.language?.startsWith('en') ? 'en-US' : 'id-ID'; updates.language = detected; } if (Object.keys(updates).length > 0) { @@ -338,22 +338,22 @@ function HomePage() { }} className="flex items-center gap-1 px-3 py-1.5 rounded-full text-xs font-bold text-gray-500 dark:text-gray-400 hover:bg-white dark:hover:bg-gray-700 hover:text-gray-800 dark:hover:text-gray-200 hover:shadow-sm transition-all" > - {locale === 'zh-CN' ? 'CN' : 'EN'} + {locale === 'id-ID' ? 'ID' : locale === 'ar-SA' ? 'AR' : 'EN'} {languageOpen && (
+
)} @@ -492,10 +505,8 @@ function HomePage() { classrooms.length === 0 ? 'justify-center min-h-[calc(100dvh-8rem)]' : 'mt-[10vh]', )} > - {/* ── Logo ── */} - + className="text-2xl md:text-4xl font-bold bg-gradient-to-r from-purple-600 via-violet-600 to-indigo-600 dark:from-purple-400 dark:via-violet-400 dark:to-indigo-400 bg-clip-text text-transparent mb-2" + > + {t('home.appTitle')} + {/* ── Slogan ── */} - OpenMAIC Open Source Project + {t('home.appTitle')} ); diff --git a/components/generation/generation-toolbar.tsx b/components/generation/generation-toolbar.tsx index 27301bbd..fc6c5fc3 100644 --- a/components/generation/generation-toolbar.tsx +++ b/components/generation/generation-toolbar.tsx @@ -28,8 +28,8 @@ const MAX_PDF_SIZE_BYTES = MAX_PDF_SIZE_MB * 1024 * 1024; // ─── Types ─────────────────────────────────────────────────── export interface GenerationToolbarProps { - language: 'zh-CN' | 'en-US'; - onLanguageChange: (lang: 'zh-CN' | 'en-US') => void; + language: 'en-US' | 'id-ID' | 'ar-SA'; + onLanguageChange: (lang: 'en-US' | 'id-ID' | 'ar-SA') => void; webSearch: boolean; onWebSearchChange: (v: boolean) => void; onSettingsOpen: (section?: SettingsSection) => void; @@ -361,11 +361,11 @@ export function GenerationToolbar({ {t('toolbar.languageHint')} diff --git a/components/header.tsx b/components/header.tsx index 77a63b03..9fc4a631 100644 --- a/components/header.tsx +++ b/components/header.tsx @@ -113,22 +113,22 @@ export function Header({ currentSceneTitle }: HeaderProps) { }} className="flex items-center gap-1 px-3 py-1.5 rounded-full text-xs font-bold text-gray-500 dark:text-gray-400 hover:bg-white dark:hover:bg-gray-700 hover:text-gray-800 dark:hover:text-gray-200 hover:shadow-sm transition-all" > - {locale === 'zh-CN' ? 'CN' : 'EN'} + {locale === 'id-ID' ? 'ID' : locale === 'ar-SA' ? 'AR' : 'EN'} {languageOpen && (
+
)} diff --git a/components/settings/index.tsx b/components/settings/index.tsx index 50236a69..9f31187b 100644 --- a/components/settings/index.tsx +++ b/components/settings/index.tsx @@ -141,6 +141,7 @@ const IMAGE_PROVIDER_NAMES: Record = { 'qwen-image': 'providerQwenImage', 'nano-banana': 'providerNanoBanana', 'grok-image': 'providerGrokImage', + 'openrouter-image': 'providerOpenRouterImage', }; const IMAGE_PROVIDER_ICONS: Record = { @@ -148,6 +149,7 @@ const IMAGE_PROVIDER_ICONS: Record = { 'qwen-image': '/logos/bailian.svg', 'nano-banana': '/logos/gemini.svg', 'grok-image': '/logos/grok.svg', + 'openrouter-image': '/logos/openrouter.svg', }; const VIDEO_PROVIDER_NAMES: Record = { diff --git a/components/stage/scene-sidebar.tsx b/components/stage/scene-sidebar.tsx index 4f50d732..922228d3 100644 --- a/components/stage/scene-sidebar.tsx +++ b/components/stage/scene-sidebar.tsx @@ -126,7 +126,7 @@ export function SceneSidebar({ className="flex items-center gap-2 cursor-pointer rounded-lg px-1.5 -mx-1.5 py-1 -my-1 hover:bg-gray-100/80 dark:hover:bg-gray-800/60 active:scale-[0.97] transition-all duration-150" title={t('generation.backToHome')} > - OpenMAIC + {t('home.appTitle')}