Files
encoach_backend_new_v2/frontend/src/i18n/locales/ar.ts
Yamen Ahmad 096b042daf
Some checks failed
Deploy to Staging / Deploy backend + frontend to staging (push) Failing after 14s
feat(course-plan): RAG sources + multi-modal media + assignments + student view
Builds the §24 product on top of the LangGraph runtime from §22:

Phase A (Sources / RAG)
  - encoach.course.plan.source model (file | url | text)
  - SourceIndexer extracts PDF (pypdf), DOCX (python-docx), HTML, plain
    text and embeds chunks via the existing pgvector pipeline scoped to
    plan_id, so resources.search only returns the plan's own corpus
  - Endpoints: list/create/upload/reindex/delete + plan-scoped retrieval

Phase B (Deliverables)
  - services.deliverables.compute_deliverables walks the plan, derives
    {planned, generated, ready} per week from material + media state
  - GET /api/ai/course-plan/<id>/deliverables drives the new wizard
    preview step and the live progress strip on the detail page

Phase C (Multi-modal media)
  - encoach.course.plan.media model + MediaService:
    audio: AWS Polly (default) or ElevenLabs
    image: OpenAI DALL-E 3, capped per plan via system parameter
    video: local ffmpeg subprocess (image + audio -> MP4 1280x720)
  - Three new agent tools (media.synthesize_audio / generate_image /
    compose_video), wired into course_week_materials and a new
    course_media_director agent
  - Endpoints per material + week-level batch generator

Phase D (Assignments)
  - encoach.course.plan.assignment supports mode='batch' (op.batch) or
    mode='students' (res.users), with due_date + message + state
  - REST endpoints to list / create / delete assignments

Phase E (Student view)
  - /api/student/course-plans + /api/student/course-plans/<id>
    enforce visibility via assignment.expand_user_ids()
  - New /student/course-plans list + read-only drilldown rendering
    audio/image/video tiles from /web/content/<attachment_id>

Cross-cutting
  - encoach.ai.tool.category: + media (so the new tools register)
  - encoach.embedding gains a plan_id filter for plan-scoped RAG
  - Wizard adds Sources + Multimedia steps; AdminCoursePlanDetail
    rewritten with DeliverablesStrip + SourcesCard + AssignmentsCard +
    per-material MediaDrawer
  - ~280 new EN + AR i18n keys (full RTL coverage)
  - smoke_course_plan.py exercises every phase via odoo-bin shell;
    last run: PASS A/B/D/E + DALL-E 3 image (753 KB), Polly audio
    fails cleanly when AWS creds aren't configured (expected)

Documentation: §24 added to docs/PROJECT_SUMMARY.md with phase-by-phase
artefact list, endpoints, smoke test, ops notes, and gotchas.

Made-with: Cursor
2026-04-25 17:13:01 +04:00

1032 lines
49 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import type { Translations } from "./en";
/** Arabic (RTL) translations. Keep key parity with `en.ts`. */
const ar: Translations = {
common: {
cancel: "إلغاء",
save: "حفظ",
delete: "حذف",
edit: "تعديل",
close: "إغلاق",
back: "رجوع",
next: "التالي",
search: "بحث",
loading: "جارٍ التحميل…",
error: "خطأ",
retry: "إعادة المحاولة",
yes: "نعم",
no: "لا",
actions: "إجراءات",
status: "الحالة",
settings: "الإعدادات",
signOut: "تسجيل الخروج",
viewAll: "عرض الكل",
dismiss: "تجاهل",
pending: "قيد الانتظار",
active: "نشط",
inactive: "غير نشط",
available: "متاح",
unavailable: "غير متاح",
name: "الاسم",
email: "البريد الإلكتروني",
user: "المستخدم",
home: "الرئيسية",
saving: "جارٍ الحفظ…",
disabled: "معطّل",
},
auth: {
signIn: "تسجيل الدخول",
signInTitle: "تسجيل الدخول إلى EnCoach",
welcomeBack: "مرحباً بعودتك",
signInDescription: "سجّل الدخول إلى حسابك للمتابعة",
email: "البريد الإلكتروني",
emailPlaceholder: "you@example.com",
password: "كلمة المرور",
rememberMe: "تذكرني",
forgotPassword: "هل نسيت كلمة المرور؟",
needAccount: "ليس لديك حساب؟",
signUp: "إنشاء حساب",
invalidCredentials: "البريد الإلكتروني أو كلمة المرور غير صحيحة",
missingCredentials: "يرجى إدخال البريد الإلكتروني وكلمة المرور",
loginFailedTitle: "فشل تسجيل الدخول",
errorTitle: "خطأ",
},
nav: {
smartWizard: "المعالج الذكي",
quickSetup: "الإعداد السريع",
coursePlans: "خطط المقررات (الذكاء الاصطناعي)",
adminDashboard: "لوحة الإدارة",
platformDashboard: "لوحة المنصّة",
dashboard: "لوحة التحكم",
courses: "الدورات",
myCourses: "دوراتي",
myCoursePlans: "خططي الدراسية",
students: "الطلاب",
teachers: "المعلمون",
batches: "الدفعات",
timetable: "الجدول الدراسي",
reports: "التقارير",
assignments: "الواجبات",
examsList: "قائمة الاختبارات",
examStructures: "هياكل الاختبارات",
rubrics: "معايير التقييم",
generation: "التوليد",
reviewQueue: "قائمة المراجعة",
aiPrompts: "وكلاء الذكاء الاصطناعي والأدوات",
aiFeedback: "ملاحظات الذكاء الاصطناعي",
approvalWorkflows: "سير عمل الموافقات",
taxonomy: "التصنيف",
resources: "الموارد",
resourceLibrary: "مكتبة الموارد",
academicYears: "السنوات الأكاديمية",
departments: "الأقسام",
admissions: "القبول",
admissionRegister: "سجل القبول",
examSessions: "جلسات الاختبارات",
marksheets: "كشوفات الدرجات",
studentLeave: "إجازات الطلاب",
fees: "الرسوم والمدفوعات",
lessons: "الدروس",
gradebook: "سجل الدرجات",
studentProgress: "تقدم الطالب",
library: "المكتبة",
activities: "الأنشطة",
facilities: "المرافق",
users: "المستخدمون",
entities: "الكيانات",
classrooms: "الفصول",
userRoles: "أدوار المستخدمين",
rolesPermissions: "الأدوار والصلاحيات",
authorityMatrix: "مصفوفة الصلاحيات",
studentPerformance: "أداء الطلاب",
statsCorporate: "إحصاءات الشركات",
record: "السجل",
vocabulary: "المفردات",
grammar: "القواعد",
faqManager: "إدارة الأسئلة الشائعة",
notificationRules: "قواعد الإشعارات",
approvalConfig: "إعدادات الموافقات",
paymentRecord: "سجل المدفوعات",
tickets: "التذاكر",
settings: "الإعدادات",
profile: "الملف الشخصي",
privacy: "مركز الخصوصية",
subjectRegistration: "تسجيل المواد",
mySubjects: "موادي",
grades: "الدرجات",
attendance: "الحضور",
myJourney: "رحلتي",
discussions: "المناقشات",
messages: "الرسائل",
announcements: "الإعلانات",
},
sidebarGroup: {
overview: "نظرة عامة",
lms: "نظام التعلم",
adaptiveLearning: "التعلم التكيّفي",
institutional: "المؤسسي",
academic: "الأكاديمي",
management: "الإدارة",
reports: "التقارير",
configuration: "الإعدادات",
training: "التدريب",
support: "الدعم",
learning: "التعلم",
progress: "التقدم",
communication: "التواصل",
account: "الحساب",
teaching: "التدريس",
},
breadcrumb: {
home: "الرئيسية",
admin: "الإدارة",
dashboard: "لوحة التحكم",
platform: "المنصّة",
exam: "الاختبار",
review: "مراجعة",
ai: "الذكاء الاصطناعي",
feedback: "ملاحظات",
},
userMenu: {
profile: "الملف الشخصي",
settings: "الإعدادات",
logout: "تسجيل الخروج",
userFallback: "مستخدم",
},
chrome: {
needHelp: "هل تحتاج مساعدة؟",
ticketsTooltip: "تذاكر الدعم",
aiSearchPlaceholder: "اسأل عن أي شيء… مثال: «اعرض الطلاب ذوي الحضور المنخفض»",
aiSearching: "الذكاء الاصطناعي يبحث…",
aiRelatedQueries: "استفسارات ذات صلة",
aiNoResults: "لا توجد نتائج لـ «{{q}}». جرّب سؤالاً أو كلمة مفتاحية مختلفة.",
aiSearchFailedTitle: "فشل البحث",
aiSearchFailedDesc: "تعذّر إكمال بحث الذكاء الاصطناعي.",
portalSuffix: "البوابة",
adminAlt: "EnCoach",
adminAltLong: "EnCoach — أطلق إمكاناتك مع منصّة مدعومة بالذكاء الاصطناعي",
toggleSidebar: "إظهار/إخفاء الشريط الجانبي",
},
notifications: {
title: "الإشعارات",
empty: "ليست لديك إشعارات جديدة.",
ariaLabel: "الإشعارات",
},
theme: {
title: "المظهر",
light: "فاتح",
dark: "داكن",
system: "النظام",
toggleLabel: "تبديل المظهر",
},
language: {
change: "تغيير اللغة",
label: "اللغة",
},
roles: {
student: "طالب",
teacher: "معلّم",
admin: "مسؤول",
developer: "مطوّر",
corporate: "شركة",
mastercorporate: "شركة رئيسية",
agent: "وكيل",
},
dashboard: {
greetingFallback: "الطالب",
},
studentDash: {
welcome: "مرحباً بعودتك، {{name}}!",
subtitle: "إليك نظرة عامة على تقدّمك الدراسي.",
enrolledCourses: "الدورات المسجّلة",
overallProgress: "التقدم العام",
averageGrade: "متوسط الدرجات",
totalChapters: "إجمالي الفصول",
myCourses: "دوراتي",
noEnrolledCourses: "لم تسجّل في أي دورة بعد.",
chaptersMaterials: "{{chapters}} فصل · {{materials}} مادة",
quickActions: "إجراءات سريعة",
enrollToStart: "سجّل في دورة للبدء.",
continue: "متابعة",
start: "ابدأ",
chaptersDone: "{{done}}/{{total}} فصل مكتمل",
recentGrades: "آخر الدرجات",
noGradesYet: "لا توجد درجات بعد.",
},
teacherDash: {
title: "لوحة المعلّم",
subtitle: "نظرة عامة على نشاطك التدريسي.",
activeCourses: "الدورات النشطة",
totalStudents: "إجمالي الطلاب",
pendingGrading: "تقييمات قيد الانتظار",
avgPassRate: "متوسط نسبة النجاح",
myCourses: "دوراتي",
colCourse: "الدورة",
colStudents: "الطلاب",
colStatus: "الحالة",
recentActivity: "النشاط الأخير",
submitted: "تم الإرسال {{when}}",
pending: "قيد الانتظار",
},
adminDash: {
title: "لوحة الإدارة",
subtitle: "نظرة عامة على المنصّة والمؤشرات الرئيسية.",
addStudent: "إضافة طالب",
newCourse: "دورة جديدة",
totalStudents: "إجمالي الطلاب",
activeCourses: "الدورات النشطة",
teachers: "المعلمون",
activeBatches: "الدفعات النشطة",
openTickets: "تذاكر مفتوحة",
revenue: "الإيرادات",
departments: "الأقسام",
classrooms: "الفصول",
subjects: "المواد",
resources: "الموارد",
coursesOverview: "نظرة عامة على الدورات",
batchCapacity: "سعة الدفعات",
noCourseData: "لا توجد بيانات دورات متاحة.",
noBatchData: "لا توجد بيانات دفعات متاحة.",
quickSummary: "ملخّص سريع",
colModule: "الوحدة",
colCount: "العدد",
colStatus: "الحالة",
exams: "الاختبارات",
examSessionsCount: "{{n}} جلسة",
assignments: "الواجبات",
acrossCourses: "عبر جميع الدورات",
supportTickets: "تذاكر الدعم",
ticketsOpenCount: "{{n}} مفتوحة",
payments: "المدفوعات",
revenueTotal: "{{amount}} إجمالاً",
chartCapacity: "السعة",
chartEnrolled: "المسجّلون",
},
examPopup: {
title: "اختبارات قادمة ({{n}})",
activeNow: "متاح الآن",
from: "من:",
to: "إلى:",
startExam: "ابدأ الاختبار",
notAvailableYet: "غير متاح بعد",
willBeAvailable: "سيتاح الاختبار عندما يصبح نشطاً",
notActive: "الاختبار غير نشط حالياً",
},
errors: {
somethingWrong: "حدث خطأ ما",
unexpectedDescription: "حدث خطأ غير متوقع. يرجى تحديث الصفحة والمحاولة مرة أخرى.",
errorDetails: "تفاصيل الخطأ",
refreshPage: "تحديث الصفحة",
notFoundCode: "404",
notFoundMessage: "عذراً! الصفحة غير موجودة",
returnHome: "العودة إلى الرئيسية",
},
ai: {
assistantLabel: "مساعد الذكاء الاصطناعي",
assistantTitle: "مساعد EnCoach الذكي",
placeholder: "اسأل عن أي شيء…",
send: "إرسال",
thinking: "يفكّر…",
emptyLine1: "اسألني عن أي شيء يخص المنصّة،",
emptyLine2: "أو اختر إجراءً سريعاً من الأعلى.",
fallbackReply: "عذراً، تعذّر الوصول إلى المساعد. يرجى المحاولة مرة أخرى بعد قليل.",
replyErrorTitle: "تعذّر الحصول على ردّ",
replyErrorDesc: "حدث خطأ ما. يرجى المحاولة مرة أخرى.",
quickHealth: "ملخّص حالة المنصّة",
quickDropouts: "عرض مخاطر التسرّب",
quickCompare: "مقارنة أداء الدورات",
quickBatch: "اقتراحات لتحسين الدفعات",
tipLabel: "نصيحة الذكاء الاصطناعي",
insightLabel: "رؤية الذكاء الاصطناعي",
recommendationLabel: "توصية الذكاء الاصطناعي",
categoryTipLabel: "نصيحة {{category}} من الذكاء الاصطناعي",
loadingTip: "جارٍ تحميل النصيحة…",
loadingInsights: "جارٍ تحميل الرؤى…",
loadingAlerts: "جارٍ تحميل التنبيهات…",
couldNotLoadTip: "تعذّر تحميل النصيحة.",
couldNotLoadInsights: "تعذّر تحميل الرؤى.",
couldNotLoadAlerts: "تعذّر تحميل التنبيهات.",
noTipAvailable: "لا توجد نصيحة متاحة.",
noTipForContext: "لا توجد نصيحة لهذا السياق بعد.",
noInsightsAvailable: "لا توجد رؤى متاحة لهذا العرض.",
noAlertsRightNow: "لا توجد تنبيهات ذكاء اصطناعي حالياً.",
alertsUnavailable: "التنبيهات غير متاحة",
insightsUnavailable: "الرؤى غير متاحة",
platformInsightsTitle: "رؤى المنصّة من الذكاء الاصطناعي",
},
privacy: {
title: "مركز الخصوصية",
description:
"إدارة بياناتك الشخصية لدى EnCoach وفقاً للائحة حماية البيانات العامة وما يماثلها.",
exportTitle: "تنزيل بياناتك",
exportDescription:
"سنقوم بتجميع ملفك الشخصي، عضويات الكيانات، محاولات الاختبارات، الإجابات، ملاحظات الذكاء الاصطناعي، والتذاكر في ملف JSON واحد.",
exportButton: "تنزيل بياناتي",
exportPreparing: "جارٍ تحضير التصدير…",
exportSuccess: "تم تنزيل البيانات بنجاح",
deleteTitle: "حذف حسابي",
deleteDescription:
"سيتم إخفاء هوية ملفك الشخصي وإزالة الحقول الشخصية من سجلاتنا. سيتم الاحتفاظ بمحاولات الاختبارات (دون معلومات تعريفية) لسلامة الإحصائيات. لا يمكن التراجع عن هذا الإجراء.",
deleteButton: "محو حسابي",
deleteErasing: "جارٍ المحو…",
confirmTitle: "هل تريد محو حسابك؟",
confirmDescription:
"سنقوم بإخفاء هوية بياناتك الشخصية وتعطيل تسجيل الدخول. ستبقى التحليلات المجمعة لكنها لن تكون مرتبطة بك.",
confirmTypeDelete: "اكتب DELETE للتأكيد",
confirmErased: "تم محو حسابك. جارٍ تسجيل الخروج…",
},
feedback: {
thumbsUp: "إعجاب",
thumbsDown: "عدم إعجاب",
whatWentWrong: "ما الخطأ الذي حدث؟",
commentPlaceholder: "مثال: إجابة خاطئة، صياغة مربكة، خارج الموضوع…",
commentRequired: "من فضلك أخبرنا بالخطأ.",
submit: "إرسال الملاحظات",
},
quickSetup: {
adminTitle: "الإعداد السريع",
adminSubtitle:
"كل ما تحتاجه لإطلاق منصّة جاهزة للامتحانات بالترتيب الموصى به. يتم تعليم كل خطوة تلقائياً عند اكتمالها.",
teacherTitle: "الإعداد السريع",
teacherSubtitle: "ابدأ دورة جديدة من البداية إلى النهاية، ثم انتقل إلى المهام اليومية الشائعة.",
progressLabel: "التقدم",
recommendedFlow: "المسار الموصى به",
otherQuickCreates: "إنشاء سريع آخر",
ready: "جاهز",
start: "ابدأ",
review: "مراجعة",
open: "فتح",
helpAria: "عرض المساعدة",
admin: {
step1: {
title: "أنشئ معيار تقييم (Rubric)",
description: "حدّد معايير التقييم لمهام الكتابة والتحدّث. تُستخدم هذه المعايير لاحقاً عند توليد الامتحانات واعتمادها.",
help: "المعيار هو شبكة تقييم (درجات × عناصر). يمكنك البدء من قالب جاهز أو تركيبه من عناصر محدّدة مسبقاً.",
},
step2: {
title: "عرّف بنية الامتحان",
description: "حدّد الأقسام والمهام والأجزاء التي يجب أن يحتويها كل امتحان من هذا النوع سواء مولّداً أو مخصّصاً.",
help: "البنى تضمن الاتساق. مثلاً: بنية IELTS للكتابة تحتوي على المهمة ١ (١٥٠ كلمة) والمهمة ٢ (٢٥٠ كلمة)؛ سيرفض النظام الإرسال إن نقصت إحداهما.",
},
step3: {
title: "ولّد أو أنشئ امتحاناً",
description: "استخدم التوليد بالذكاء الاصطناعي (الأسرع) أو أنشئ امتحاناً مخصّصاً يدوياً. احفظ كمسودة أو أرسله للموافقة.",
help: "التوليد يختار بنية ومعيار تقييم ثم يُنتج الأسئلة. المنشئ المخصّص يتيح لك تحكّماً كاملاً للامتحانات التجريبية.",
},
step4: {
title: "راجع واعتمد",
description: "يعتمد المصدّقون الامتحانات قبل ظهورها للطلاب. اضبط سير العمل مرة واحدة ليتم توجيه الطلبات تلقائياً.",
help: "قائمة الاعتماد تعرض كل امتحان في انتظار المصادقة. الرفض يعيده للمؤلّف، والقبول ينشره.",
},
step5: {
title: "عيّن للطلاب",
description: "جدول الامتحان المنشور، اختر الدفعة، وأرسله. يراه الطلاب فوراً في بوّابتهم.",
help: "يمكن استهداف طلاب أفراد أو دفعات أو صفوف كاملة مع مراعاة المنطقة الزمنية.",
},
quick: {
course: { title: "دورة جديدة", description: "أنشئ هيكل دورة ليملأها المعلّمون بالفصول." },
resource: { title: "رفع مورد", description: "أضف ملفات PDF أو صوت أو فيديو أو روابط إلى المكتبة المشتركة." },
student: { title: "إضافة طالب", description: "أنشئ حساب طالب وعيّنه إلى دفعة." },
teacher: { title: "إضافة معلّم", description: "ادعُ معلّماً وامنحه صلاحيات التدريس." },
classroom: { title: "صف جديد", description: "جمّع الطلاب لأغراض الجدولة والحضور." },
examSession: { title: "جدولة جلسة امتحان", description: "أنشئ جلسة امتحان مراقبة لامتحان مؤسسي." },
customExam: { title: "امتحان مخصّص", description: "أنشئ امتحاناً يدوياً من الصفر بتحكّم كامل." },
ticket: { title: "فتح تذكرة", description: "افتح تذكرة دعم نيابة عن مستخدم." },
},
},
teacher: {
step1: {
title: "أنشئ دورة",
description: "امنح دورتك اسماً، اختر المادّة، وحدّد مستواها. يمكنك تعديل الفصول بعد الإنشاء.",
help: "الدورات هي الحاوية للفصول والمواد والواجبات.",
},
step2: {
title: "أضف الفصول والمحتوى",
description: "افتح دورتك وأضف فصولاً تحتوي على دروس وفيديوهات واختبارات ومهام تدريب.",
help: "الفصول تنظّم أهداف التعلّم. استخدم الورشة الذكية لإنشاء المحتوى تلقائياً.",
},
step3: {
title: "ارفع الموارد",
description: "شارك مع طلابك ملفات PDF أو صوت أو فيديو داعمة عبر المكتبة.",
help: "الملفات الكبيرة مدعومة — يقبل الخادم حتى ١٢٨ ميغابايت للرفعة الواحدة.",
},
step4: {
title: "أنشئ واجباً",
description: "حوّل امتحاناً منشوراً أو مهمّة إلى واجب بتاريخ تسليم ودفعة مستهدفة.",
help: "تظهر الواجبات تلقائياً في لوحة كل طالب وفي جدوله.",
},
step5: {
title: "تابع تقدّم الطلاب",
description: "راقب التسليمات والحضور ورؤى التعلّم التكيّفي لصفّك.",
help: "يحدّد محرك التعلّم التكيّفي الطلاب المعرّضين للخطر لتتدخّل مبكّراً.",
},
quick: {
discussion: { title: "نقاش جديد", description: "ابدأ موضوع نقاش لصفّك." },
announcement: { title: "إعلان جديد", description: "أرسل رسالة لجميع طلابك." },
attendance: { title: "تسجيل الحضور", description: "سجّل حضور اليوم لإحدى الجلسات." },
},
},
},
wizardHub: {
title: "المعالج الذكي",
subtitle:
"اختر أي سيناريو وسيرشدك المعالج خطوة بخطوة. لا حاجة للبحث في الإعدادات — كلّ ضغطة على \"التالي\" تقرّبك أكثر من الإنجاز.",
recommendedOrder: "الترتيب الموصى به",
order: {
rubric: "أنشئ معايير التقييم (الكتابة / المحادثة)",
structure: "حدّد هيكل الامتحان (الأقسام والمهام والمدد)",
generate: "أنشئ امتحاناً تلقائياً أو يدوياً",
approve: "راجع الامتحانات المعلّقة واعتمدها",
assign: "أسند الامتحانات إلى الطلاب",
},
guided: "معالجات موجّهة",
advanced: "الصفحات الكاملة (متقدّم)",
advancedBadge: "متقدّم",
aiBadge: "ذكاء اصطناعي",
startWizard: "ابدأ المعالج",
openPage: "افتح الصفحة",
cards: {
rubric: {
title: "إنشاء معيار تقييم",
description: "الاسم ← المهارة ← المعايير ← الوصف ← المراجعة. للكتابة والمحادثة فقط.",
},
examStructure: {
title: "تعريف هيكل امتحان",
description: "الاسم ← الوحدات ← مهام الكتابة ← المراجعة. قالب قابل لإعادة الاستخدام.",
},
course: {
title: "إنشاء مساق",
description: "العنوان ← المستوى والسعة ← المراجعة. الفصول تُضاف من صفحة المساق.",
},
coursePlan: {
title: "توليد خطة مقرر (ذكاء اصطناعي)",
description: "اوصف المقرر فيكتب الذكاء الاصطناعي الأهداف ونتائج التعلّم لكل مهارة ونطاق القواعد وخطة التسليم أسبوعياً، ثم يولّد المواد التعليمية الجاهزة لكل أسبوع.",
},
generation: {
title: "توليد امتحان",
description: "صفحة التوليد الكاملة بخيارات المعايير والهيكل وتحكّم في كل وحدة.",
},
approval: {
title: "مسارات الموافقة",
description: "حدّد من يراجع الامتحانات، وتابع الطلبات المعلّقة.",
},
assign: {
title: "إسناد إلى الطلاب",
description: "صفحة الجدولة الكاملة مع منتقي الطلاب والنوافذ الزمنية والمنطقة الزمنية.",
},
resource: {
title: "رفع مورد",
description: "أضف ملفات PDF أو صوت أو فيديو أو روابط إلى المكتبة.",
},
student: {
title: "إضافة طالب",
description: "أنشئ حساب طالب وسجّله في دفعة.",
},
},
},
wizard: {
back: "السابق",
next: "التالي",
finish: "إنهاء",
backToHub: "العودة إلى المعالجات",
stepOf: "الخطوة {{current}} من {{total}}",
rubric: {
title: "إنشاء معيار تقييم",
subtitle: "شبكة تقييم لمهام الكتابة أو المحادثة، يُرجَع إليها عند توليد الامتحانات أو اعتمادها.",
finish: "إنشاء المعيار",
toastSuccess: "تم إنشاء المعيار",
toastError: "تعذّر إنشاء المعيار",
addCriterion: "إضافة معيار",
removeCriterion: "حذف المعيار",
unnamedCriterion: "(معيار بلا اسم)",
descriptorHint: "الوصف اختياري. يظهر للمصحّحين كإرشاد لكل معيار.",
maxLabel: "الحد الأقصى",
moduleHint: "تنطبق المعايير على الكتابة والمحادثة فقط. الاستماع والقراءة يُصحَّحان تلقائياً.",
step1: {
title: "الأساسيات",
description: "امنح المعيار اسماً وحدّد المهارة التي يطبّق عليها.",
},
step2: {
title: "المعايير",
description: "أضف المعايير التي سيقوم المصحّحون بتقييمها. لكل معيار حد أقصى (مثل 9 لامتحان IELTS).",
},
step3: {
title: "الأوصاف",
description: "اختياري: صف ما يقيسه كل معيار. يراها المصحّحون كتلميحات.",
},
step4: {
title: "المراجعة",
description: "راجع وأنشئ.",
},
labels: {
name: "اسم المعيار",
module: "المهارة",
description: "الوصف",
criterionName: "اسم المعيار الفرعي",
maxScore: "الحد الأقصى",
},
placeholders: {
name: "مثال: IELTS مهمة كتابة 2",
description: "وصف قصير يظهر للمصحّحين.",
criterionName: "مثال: الاستجابة للمهمة",
descriptor: "ماذا يجب على المصحّح أن يتحقق منه لهذا المعيار.",
},
modules: {
writing: "الكتابة",
speaking: "المحادثة",
},
errors: {
nameRequired: "يرجى إدخال اسم للمعيار.",
moduleRestricted: "المعايير تنطبق على الكتابة أو المحادثة فقط.",
criterionRequired: "أضف معياراً واحداً على الأقل.",
criterionName: "كل معيار يحتاج إلى اسم.",
criterionScore: "الحد الأقصى يجب أن يكون بين 1 و 100.",
},
},
structure: {
title: "تعريف هيكل امتحان",
subtitle: "قالب يحدّد الأقسام والمهام التي يجب أن يحتويها كل امتحان من هذا النوع.",
finish: "إنشاء الهيكل",
toastSuccess: "تم إنشاء هيكل الامتحان",
toastError: "تعذّر إنشاء هيكل الامتحان",
industryHint: "اختياري: مثل \"الإنجليزية التجارية\"، \"الرعاية الصحية\".",
writingSkipped: "الكتابة غير مُحدَّدة ضمن الوحدات — تم تخطّي هذه الخطوة.",
wordsSuffix: "كلمة",
addTask: "إضافة مهمة",
removeTask: "حذف المهمة",
step1: {
title: "الأساسيات",
description: "سمِّ الهيكل وحدّد نوع الامتحان.",
},
step2: {
title: "الوحدات",
description: "اختر الوحدات التي يغطّيها هذا الهيكل. سيراها الطلاب كأقسام.",
},
step3: {
title: "مهام الكتابة",
description: "للكتابة، حدّد الحد الأدنى لعدد الكلمات لكل مهمة.",
},
step4: {
title: "المراجعة",
description: "راجع وأنشئ.",
},
labels: {
name: "اسم الهيكل",
industry: "المجال / السياق",
examType: "نوع الامتحان",
modules: "الوحدات",
taskLabel: "اسم المهمة",
minWords: "أدنى كلمات",
},
placeholders: {
name: "مثال: IELTS أكاديمي كتابة",
industry: "مثال: الإنجليزية التجارية",
},
examTypes: {
academic: "أكاديمي",
general: "عام",
},
modules: {
listening: {
title: "الاستماع",
description: "أسئلة مبنيّة على الصوت (تصحيح تلقائي).",
},
reading: {
title: "القراءة",
description: "أسئلة مبنيّة على مقاطع (تصحيح تلقائي).",
},
writing: {
title: "الكتابة",
description: "مهام مقاليّة تُصحَّح باستخدام معيار تقييم.",
},
speaking: {
title: "المحادثة",
description: "مهام شفهيّة تُصحَّح باستخدام معيار تقييم.",
},
},
errors: {
nameRequired: "يرجى إدخال اسم للهيكل.",
moduleRequired: "اختر وحدة واحدة على الأقل.",
writingTaskRequired: "الكتابة تحتاج إلى مهمة واحدة على الأقل.",
writingTaskLabel: "كل مهمة كتابة تحتاج إلى اسم.",
writingTaskWords: "الحد الأدنى للكلمات يجب أن يكون 1 على الأقل.",
},
},
course: {
title: "إنشاء مساق",
subtitle: "هيكل مساق خفيف. يمكنك إضافة الفصول والمواد وتسجيل الطلاب بعد الإنشاء.",
finish: "إنشاء المساق",
toastSuccess: "تم إنشاء المساق",
toastError: "تعذّر إنشاء المساق",
codeHint: "اتركه فارغاً لتوليده تلقائياً من العنوان.",
difficultyHint: "ما مدى تحدّي هذا المساق إجمالاً؟ يُستخدم للبحث والتصفية.",
cefrHint: "إن كان المساق يستهدف مستوى CEFR محدداً، اختره هنا.",
step1: {
title: "الأساسيات",
description: "امنح المساق اسماً ووصفاً قصيراً.",
},
step2: {
title: "المستوى والسعة",
description: "حدّد الصعوبة ومستوى CEFR المستهدف والحد الأقصى لعدد الطلاب.",
},
step3: {
title: "المراجعة",
description: "راجع وأنشئ.",
},
labels: {
title: "عنوان المساق",
code: "رمز المساق",
description: "الوصف",
difficulty: "الصعوبة",
cefrLevel: "مستوى CEFR",
capacity: "السعة القصوى",
},
placeholders: {
title: "مثال: إنجليزية تأسيسية المستوى 1",
code: "سيتم توليده تلقائياً إذا تُرك فارغاً",
description: "لمن هذا المساق؟ ماذا سيتعلّمون؟",
difficulty: "اختر مستوى صعوبة",
cefr: "اختر مستوى CEFR",
},
difficulty: {
beginner: "مبتدئ",
intermediate: "متوسط",
advanced: "متقدّم",
},
errors: {
titleRequired: "يرجى إدخال عنوان المساق.",
capacityRequired: "السعة القصوى يجب أن تكون 1 على الأقل.",
},
},
},
coursePlan: {
listTitle: "خطط المقررات",
listSubtitle:
"خطط مناهج يُنشئها الذكاء الاصطناعي: الأهداف، ونتائج التعلّم لكل مهارة، ونطاق القواعد، وخطة التسليم أسبوعياً، مع توليد المواد التعليمية لكل أسبوع عند الطلب.",
generateNew: "توليد خطة جديدة",
searchPlaceholder: "ابحث عن خطة بالاسم…",
loadFailed: "تعذّر تحميل الخطط.",
deleted: "تم حذف الخطة.",
deleteFailed: "تعذّر حذف الخطة.",
delete: "حذف",
confirmDelete: "حذف الخطة \"{{name}}\"؟ سيؤدي ذلك إلى إزالة جميع الأسابيع والمواد.",
emptyTitle: "لا توجد خطط بعد",
emptySubtitle: "استخدم معالج الذكاء الاصطناعي لتوليد أول خطة — يستغرق الأمر نحو دقيقة.",
open: "فتح",
backToList: "العودة إلى الخطط",
noDescription: "لا يوجد وصف.",
weeksCount_one: "{{count}} أسبوع",
weeksCount_other: "{{count}} أسابيع",
materialsCount_one: "{{count}} مادة",
materialsCount_other: "{{count}} مواد",
hoursPerWeek: "{{count}} ساعة/أسبوع",
weekN: "الأسبوع {{n}}",
generateMaterials: "توليد مواد الأسبوع (ذكاء اصطناعي)",
regenerateMaterials: "إعادة توليد مواد الأسبوع",
generating: "جاري التوليد…",
generateHint:
"سيُنتج الذكاء الاصطناعي نصّ قراءة وسيناريو استماع ومحفّزات محادثة وسؤال كتابة ودرس قواعد وقائمة مفردات لهذا الأسبوع.",
weekMaterialsGenerated: "تم توليد مواد الأسبوع.",
weekMaterialsFailed: "تعذّر توليد مواد الأسبوع.",
generateSuccess: "تم توليد خطة المقرر.",
generateFailed: "تعذّر توليد خطة المقرر.",
deliveryHint: "افتح أي أسبوع لعرض النتائج المخطَّطة وتوليد المواد الجاهزة للاستخدام.",
status: {
draft: "مسودة",
generated: "مُولّدة",
approved: "معتمدة",
archived: "مؤرشفة",
},
sections: {
objectives: "أهداف المقرر",
outcomes: "نتائج التعلّم حسب المهارة",
grammar: "نطاق القواعد",
assessment: "التقييم",
resources: "المصادر",
delivery: "خطة التسليم الأسبوعية",
},
skill: {
reading: "القراءة",
writing: "الكتابة",
listening: "الاستماع",
speaking: "المحادثة",
grammar: "القواعد",
vocabulary: "المفردات",
integrated: "متكامل",
},
materialType: {
reading_text: "نص قراءة",
listening_script: "نص استماع",
speaking_prompt: "محفّز محادثة",
writing_prompt: "مهمّة كتابة",
grammar_lesson: "درس قواعد",
vocabulary_list: "قائمة مفردات",
practice: "تمرين",
other: "مادة",
},
table: {
skill: "المهارة",
outcomes: "النتائج",
remarks: "ملاحظات",
},
wizard: {
title: "توليد خطة مقرر",
subtitle:
"اوصف المقرر مرّة واحدة، ويكتب الذكاء الاصطناعي الخطة كاملة — الأهداف والنتائج والقواعد والخطة الأسبوعية — ويمكنك توليد مواد الأسبوع الأول بضغطة واحدة.",
finish: "توليد الخطة",
reviewHint: "اضغط على \"توليد الخطة\" لبدء الذكاء الاصطناعي. يستغرق عادةً 3060 ثانية، وستنتقل إلى صفحة الخطة عند الانتهاء.",
steps: {
basics: "الأساسيات",
basicsDesc: "سمِّ المقرر وحدّد المستوى والمدة وعدد الساعات الأسبوعية.",
coverage: "التغطية",
coverageDesc: "أخبر الذكاء الاصطناعي بتوزيع الساعات على المهارات ومن هم المتعلّمون.",
sources: "المصادر المرجعية",
sourcesDesc:
"ارفع ملفات PDF أو روابط أو نصوص. يستخدمها الذكاء الاصطناعي كمرجع لتوليد مواد كل أسبوع.",
scope: "النطاق",
scopeDesc: "اختياري: تركيز القواعد، والمصادر، وملاحظات حرّة.",
media: "الوسائط",
mediaDesc:
"اختر أي وسائط يولّدها الذكاء الاصطناعي تلقائياً مع المواد النصّية.",
review: "المراجعة",
reviewDesc: "راجع البيانات قبل بدء التوليد.",
},
fields: {
title: "عنوان المقرر",
cefr: "مستوى CEFR",
cefrPlaceholder: "اختر مستوى",
totalWeeks: "إجمالي الأسابيع",
contactHours: "عدد الساعات أسبوعياً",
skillsDivision: "توزيع المهارات",
skillsDivisionHint:
"صيغة حرّة — مثال: \"10 س/أسبوع قراءة وكتابة + 8 س/أسبوع استماع ومحادثة\". اتركه فارغاً ليقرّر الذكاء الاصطناعي.",
learnerProfile: "ملف المتعلّمين",
learnerProfilePlaceholder: "من هم المتعلّمون؟ الفئة العمرية، اللغة الأم، الخلفية الدراسية، الأهداف…",
grammarFocus: "تركيز القواعد (Enter للإضافة)",
grammarFocusPlaceholder: "مثال: المضارع البسيط",
resources: "المصادر (Enter للإضافة)",
resourcesPlaceholder: "مثال: Pathways 1 (National Geographic)",
notes: "ملاحظات إضافية",
notesPlaceholder: "أي شيء آخر يحتاج الذكاء الاصطناعي معرفته.",
},
errors: {
titleRequired: "يرجى إدخال عنوان المقرر.",
cefrRequired: "يرجى اختيار مستوى CEFR.",
weeksRange: "عدد الأسابيع يجب أن يكون 1 على الأقل.",
},
review: {
sourcesCount_one: "{{count}} مصدر",
sourcesCount_other: "{{count}} مصادر",
noSources: "لا توجد مصادر",
mediaNone: "لا يوجد توليد وسائط",
},
},
sections_extras: {
sources: "المصادر المرجعية",
progress: "تقدّم التوليد",
assignments: "الإسنادات",
media: "الوسائط المُولَّدة",
},
sources: {
sectionTitle: "المصادر المرجعية (RAG)",
sectionDesc:
"ارفع PDF أو أضف روابط أو نصوصاً. يستخدمها الذكاء الاصطناعي كمرجع عند توليد المواد الأسبوعية.",
collected_one: "{{count}} مصدر جاهز",
collected_other: "{{count}} مصادر جاهزة",
empty: "لا توجد مصادر مرجعية بعد.",
dropTitle: "أضف مواد مرجعية",
dropHint: "PDF أو DOCX أو TXT أو HTML أو نص — حتى بضعة ميغابايت لكل ملف.",
uploadFiles: "رفع ملفات",
urlLabel: "إضافة رابط",
textLabel: "أو ألصق نصاً مباشرة",
textPlaceholder: "ألصق فقرة لتوجيه الذكاء الاصطناعي…",
uploadFailed: "تعذّر رفع \"{{name}}\".",
reindex: "إعادة فهرسة",
reindexed: "أُعيدت فهرسة المصدر.",
reindexFailed: "فشلت إعادة الفهرسة.",
deleted: "تم حذف المصدر.",
deleteFailed: "تعذّر حذف المصدر.",
status: {
pending: "في الانتظار",
indexing: "يُفهرس…",
indexed: "مُفهرس",
failed: "فشل",
},
kindLabel: {
file: "ملف",
url: "رابط",
text: "نص",
},
chunks_one: "{{count}} جزء",
chunks_other: "{{count}} أجزاء",
},
sourceKind: {
file: "ملف",
url: "رابط",
text: "نص",
},
deliverables: {
title: "تقدّم التوليد",
subtitle:
"ما الذي سيُنتجه الذكاء الاصطناعي، وما تم إنتاجه، وما اكتمل تماماً (مواد + وسائط).",
summary: {
planned_one: "{{count}} مخطّط",
planned_other: "{{count}} مخطّط",
generated_one: "{{count}} مُولَّد",
generated_other: "{{count}} مُولَّد",
ready_one: "{{count}} جاهز",
ready_other: "{{count}} جاهز",
},
mediaCounts: "صوت {{audio}} · صورة {{image}} · فيديو {{video}}",
status: {
planned: "مخطّط",
generated: "مُولَّد",
ready: "جاهز",
},
perWeek: "تفصيل لكل أسبوع",
noWeeks: "لا توجد أسابيع — ولّد الخطة أولاً.",
},
media: {
audio: "صوت",
image: "صورة",
video: "فيديو",
audioTitle: "تعليق صوتي",
audioDesc:
"توليد صوت منطوق (Polly / ElevenLabs) لنصوص الاستماع ومحفّزات المحادثة.",
imageTitle: "صور تغطية",
imageDesc:
"توليد صور DALL·E 3 لنصوص القراءة والاستماع. يحتسب من ميزانية الصور للخطة.",
videoTitle: "فيديو شرائح",
videoDesc: "دمج الصوت + الصورة في فيديو MP4 قصير عبر ffmpeg. أبطأ الخيارات.",
hint:
"الصوت مفعّل افتراضياً. الفيديو معطّل افتراضياً — فعّله بعد مراجعة الصوت والصورة.",
drawerTitle: "وسائط \"{{title}}\"",
drawerSubtitle: "ولّد أو احذف الصوت والصورة والفيديو.",
generateAudio: "توليد صوت",
generateImage: "توليد صورة",
generateVideo: "توليد فيديو",
generating: "جاري التوليد…",
audioReady: "الصوت جاهز",
imageReady: "الصورة جاهزة",
videoReady: "الفيديو جاهز",
audioFailed: "فشل توليد الصوت.",
imageFailed: "فشل توليد الصورة.",
videoFailed: "فشل توليد الفيديو.",
deleted: "تم حذف الوسيط.",
deleteFailed: "تعذّر حذف الوسيط.",
open: "فتح",
download: "تنزيل",
noMedia: "لا توجد وسائط لهذه المادة بعد.",
mediaForMaterial: "وسائط",
bulk: "توليد وسائط الأسبوع",
bulkSuccess: "اكتمل توليد وسائط الأسبوع.",
bulkFailed: "تعذّر توليد وسائط الأسبوع.",
provider: "المزوّد",
},
assignments: {
title: "مُسندة إلى",
empty: "لم تُسند إلى أحد بعد.",
assign: "إسناد",
assignTitle: "إسناد خطة المقرر",
assignSubtitle:
"اختر شعبة (دفعة) للجميع، أو طلاباً محدّدين. ستظهر الخطة في لوحة الطالب.",
modeBatch: "دفعة كاملة",
modeStudents: "طلاب محدّدون",
pickBatch: "اختر دفعة",
pickStudents: "اختر طلاباً",
noBatches: "لا توجد دفعات.",
noStudents: "لا يوجد طلاب.",
dueDate: "تاريخ التسليم (اختياري)",
message: "رسالة للمتعلّمين (اختياري)",
messagePlaceholder: "ترحيب، توقّعات، مواعيد…",
created: "تم إسناد الخطة.",
createFailed: "تعذّر إسناد الخطة.",
removed: "تمت إزالة الإسناد.",
removeFailed: "تعذّر إزالة الإسناد.",
remove: "إزالة",
confirmRemove: "إزالة هذا الإسناد؟",
assignedBy: "أسندها {{name}}",
students_one: "{{count}} طالب",
students_other: "{{count}} طلاب",
cancel: "إلغاء",
save: "إسناد",
},
student: {
listTitle: "خططي الدراسية",
listSubtitle:
"خطط مناهج مخصّصة يُنشئها الذكاء الاصطناعي ويُسندها معلّمك. افتح خطة لرؤية الأسابيع والمواد والوسائط.",
empty: "لم تُسند إليك خطط بعد.",
open: "فتح المقرر",
assignedBy: "أسندها {{name}}",
due: "موعد التسليم {{date}}",
noDue: "بدون موعد",
backToList: "العودة إلى خططي",
},
wizardSourcesStep: "المصادر",
},
aiAdmin: {
title: "وكلاء الذكاء الاصطناعي والأدوات",
subtitle:
"هيّئ الوكلاء المبنيين على LangGraph الذين يشغّلون تخطيط المقررات وتوليد الاختبارات والتمارين والمدرّس داخل LMS والتصحيح. الإعدادات الافتراضية جاهزة للاستخدام مباشرة.",
tabs: {
agents: "الوكلاء",
tools: "الأدوات",
prompts: "التعليمات",
},
},
agents: {
list: {
title: "الوكلاء",
subtitle: "مهيّأون مسبقاً لكل ركيزة في المنصة — يمكن تعديل الإعدادات الافتراضية أدناه.",
search: "ابحث عن وكيل…",
empty: "لا توجد وكلاء مطابقون لبحثك.",
},
detail: {
configure: "ضبط الإعدادات",
empty: "اختر وكيلاً لعرض إعداداته.",
graph: "نوع الرسم البياني",
model: "النموذج",
temperature: "درجة الإبداع",
tokens: "أقصى عدد رموز",
format: "صيغة المخرجات",
fallback: "الاحتياطي",
revisions: "أقصى عدد مراجعات",
promptKey: "مفتاح القالب",
toolsTitle: "الأدوات المفعّلة",
noTools: "لا توجد أدوات مفعّلة لهذا الوكيل.",
systemPrompt: "تعليمات النظام",
noPrompt: "(فارغ)",
},
config: {
title: "ضبط الإعدادات",
saved: "تم حفظ إعدادات الوكيل",
name: "اسم العرض",
promptKey: "مفتاح القالب (مع نسخ)",
description: "الوصف",
systemPrompt: "تعليمات النظام",
systemPromptHint:
"إذا تم تعيين مفتاح قالب أعلاه، فإن النسخة النشطة من ذلك القالب تستبدل هذا الحقل وقت التشغيل.",
model: "النموذج",
fallbackModel: "النموذج الاحتياطي",
responseFormat: "صيغة المخرجات",
text: "نص",
temperature: "درجة الإبداع",
maxTokens: "أقصى عدد رموز",
maxRevisions: "أقصى عدد مراجعات",
graphType: "بنية الرسم البياني",
qualityChecks: "فحوصات الجودة (مفاتيح أدوات مفصولة بفواصل)",
tools: "الأدوات المفعّلة",
mutates: "كتابة",
active: "الوكيل مفعّل",
},
test: {
title: "محرّك الاختبار",
subtitle:
"أرسل طلباً صغيراً وافحص مخرجات الوكيل واستدعاءات الأدوات وتنبيهات الجودة.",
variables: "المتغيّرات (JSON)",
payload: "الطلب (نص أو JSON)",
payloadPlaceholder:
"ماذا يجب أن يفعل الوكيل؟ مثال: «أنشئ 5 أسئلة اختيار من متعدد للقراءة لمستوى B1.»",
run: "تشغيل الوكيل",
running: "جارٍ التشغيل…",
ok: "تم تنفيذ الوكيل بنجاح",
output: "المخرجات",
toolTrace: "سجلّ استدعاءات الأدوات",
iterations: "التكرارات",
revisions: "المراجعات",
toolCalls: "استدعاءات الأدوات",
retrievalHits: "نتائج الاسترجاع",
qualityIssues: "تنبيهات الجودة",
badVarsJson: "يجب أن تكون المتغيّرات بصيغة JSON صحيحة.",
},
graph: {
simple: "بسيط",
planReviewRevise: "تخطيط • مراجعة • تنقيح",
rag: "استرجاع وتوليد",
react: "ReAct (استدعاء أدوات)",
},
},
tools: {
title: "أدوات الوكلاء",
subtitle:
"القدرات التي يمكن للوكلاء استدعاؤها. أوقف أداة لإخراجها من جميع الوكلاء دون تعديل كل واحد منهم.",
search: "ابحث عن أداة…",
empty: "لا توجد أدوات مطابقة لبحثك.",
writes: "كتابة",
toggle: {
enabled: "تم تفعيل الأداة",
disabled: "تم تعطيل الأداة",
},
col: {
key: "المفتاح",
name: "الاسم",
category: "الفئة",
description: "الوصف",
params: "المعاملات",
active: "نشط",
},
},
};
export default ar;