Frontend - i18n: install tailwindcss-rtl, Cairo font, RTL-aware direction in index.css. - Language toggle: localize aria-label / menu label, persist choice, update document dir synchronously. - Sidebar: add `side` prop so the drawer pins to the right in RTL; wire up AdminLmsLayout, RoleLayout (student/teacher) and AppSidebar to pass side = i18n.dir() === 'rtl' ? 'right' : 'left'. - AdminLmsLayout: convert every nav item from hard-coded title to titleKey, translate group labels (incl. the collapsible Training), breadcrumbs, user menu (Profile / Settings / Logout), help button and toggle aria labels; replace physical mr-/right- utilities with logical me-/end-. - AI components (AiTipBanner, AiInsightsPanel, AiAlertBanner, AiSearchBar, AiAssistantDrawer): apply dir="auto" at the container level, localize titles, loading / error / empty states. - Dashboards (admin / student / teacher): wrap numeric values in <bdi>, localize dates via ar-EG, fix flex direction for KPI and assignment cards. - UI primitives (breadcrumb, calendar, carousel, dropdown-menu, menubar, context-menu, pagination, sidebar): flip chevrons in RTL via a scoped CSS rule, swap pl-/pr-/ml-/mr- for ps-/pe-/ms-/me-. - Add logical-direction helpers and bidirectional isolation classes. Locales - Expand en.ts and ar.ts with full `nav`, `sidebarGroup`, `breadcrumb`, `userMenu`, `chrome`, `ai`, and dashboard key sets; keep key parity. API client - `api-client.ts` reads the active language from localStorage/i18n and sends `Accept-Language` on every request so the backend can localize AI output. Backend (encoach_ai) - openai_service: add _LANGUAGE_NAMES, normalize_language, language-aware system prompt injection for every OpenAI call. - coach_service + controllers (coach_controller, ai_controller): thread the requested language from headers / user locale down to OpenAIService. - ai_feedback: fix latent registry error by pointing course_id at op.course instead of the non-existent encoach.course. Other - .gitignore: ignore runtime odoo logs and local caches. Made-with: Cursor
343 lines
14 KiB
TypeScript
343 lines
14 KiB
TypeScript
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: "الرئيسية",
|
|
},
|
|
auth: {
|
|
signIn: "تسجيل الدخول",
|
|
signInTitle: "تسجيل الدخول إلى EnCoach",
|
|
welcomeBack: "مرحباً بعودتك",
|
|
signInDescription: "سجّل الدخول إلى حسابك للمتابعة",
|
|
email: "البريد الإلكتروني",
|
|
emailPlaceholder: "you@example.com",
|
|
password: "كلمة المرور",
|
|
rememberMe: "تذكرني",
|
|
forgotPassword: "هل نسيت كلمة المرور؟",
|
|
needAccount: "ليس لديك حساب؟",
|
|
signUp: "إنشاء حساب",
|
|
invalidCredentials: "البريد الإلكتروني أو كلمة المرور غير صحيحة",
|
|
missingCredentials: "يرجى إدخال البريد الإلكتروني وكلمة المرور",
|
|
loginFailedTitle: "فشل تسجيل الدخول",
|
|
errorTitle: "خطأ",
|
|
},
|
|
nav: {
|
|
adminDashboard: "لوحة الإدارة",
|
|
platformDashboard: "لوحة المنصّة",
|
|
dashboard: "لوحة التحكم",
|
|
courses: "الدورات",
|
|
myCourses: "دوراتي",
|
|
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: "إرسال الملاحظات",
|
|
},
|
|
};
|
|
|
|
export default ar;
|