-
Notifications
You must be signed in to change notification settings - Fork 20
[NEWBIE-FRONTEND] Add Complete i18n Translations for Courses Feature #252
Description
Claiming This Task
Before you start working, check the Assignees section. If no one is assigned, leave a comment claiming the issue and assign it to yourself. This prevents duplicate work.
See the Community Wiki for contributing guidelines and git workflow.
Goal
Add complete internationalization (i18n) translations for the entire courses feature in both English and Arabic. This ensures all user-facing text in courses pages uses t() calls instead of hardcoded strings, and that the Arabic experience is fully translated.
Task Description
- Open
Frontend/EduLiteFrontend/src/i18n/locales/en.json - Add a complete
"courses"section covering all courses UI text (see structure below) - Open
Frontend/EduLiteFrontend/src/i18n/locales/ar.json - Add the Arabic translations for every key
- Search all courses-related components for any hardcoded strings and replace them with
t()calls - Test in both English and Arabic, and verify RTL layout doesn't break
Translation Keys to Add
{
"courses": {
"list": {
"title": "Courses",
"myCourses": "My Courses",
"publicCourses": "Public Courses",
"createButton": "Create Course",
"emptyMine": "You're not enrolled in any courses yet",
"emptyPublic": "No public courses available",
"browsePublic": "Browse public courses to get started",
"loading": "Loading courses...",
"errorLoading": "Failed to load courses",
"titleColumn": "Title",
"subjectColumn": "Subject",
"languageColumn": "Language",
"visibilityColumn": "Visibility",
"membersColumn": "Members",
"startDateColumn": "Start Date",
"showing": "Showing {{start}}-{{end}} of {{total}}",
"pageOf": "Page {{current}} of {{total}}"
},
"detail": {
"title": "Course Details",
"outline": "Outline",
"subject": "Subject",
"language": "Language",
"country": "Country",
"visibility": "Visibility",
"startDate": "Start Date",
"endDate": "End Date",
"duration": "Duration",
"members": "Members",
"modules": "Modules",
"memberCount": "{{count}} member",
"memberCount_plural": "{{count}} members",
"editCourse": "Edit Course",
"deleteCourse": "Delete Course",
"deleteConfirmTitle": "Delete Course",
"deleteConfirmMessage": "Are you sure you want to delete \"{{title}}\"? This will remove all modules, memberships, and chat rooms. This action cannot be undone.",
"deleteConfirmButton": "Delete Course"
},
"form": {
"createTitle": "Create Course",
"editTitle": "Edit Course",
"titleLabel": "Title",
"titlePlaceholder": "Enter course title",
"outlineLabel": "Outline",
"outlinePlaceholder": "Describe what this course covers...",
"subjectLabel": "Subject",
"languageLabel": "Language",
"countryLabel": "Country",
"visibilityLabel": "Visibility",
"startDateLabel": "Start Date",
"endDateLabel": "End Date",
"allowJoinRequests": "Allow Join Requests",
"allowJoinRequestsHint": "Students can request to join this restricted course",
"saveButton": "Save Changes",
"createButton": "Create Course",
"draftRecovered": "Draft recovered from {{time}}",
"validationTitleRequired": "Course title is required",
"validationDateOrder": "Start date must be before end date"
},
"enrollment": {
"joinCourse": "Join Course",
"leaveCourse": "Leave Course",
"requestToJoin": "Request to Join",
"cancelRequest": "Cancel Request",
"acceptInvite": "Accept Invitation",
"declineInvite": "Decline Invitation",
"enrolled": "Enrolled",
"pending": "Request Pending",
"invited": "Invited",
"notEnrolled": "Not Enrolled",
"leaveConfirmTitle": "Leave Course",
"leaveConfirmMessage": "Are you sure you want to leave \"{{title}}\"?",
"enrollSuccess": "Successfully enrolled in course",
"enrollPending": "Join request submitted — awaiting approval",
"leaveSuccess": "Successfully left course",
"alreadyEnrolled": "You are already enrolled in this course",
"cannotJoin": "This course is not accepting new members",
"lastTeacher": "Cannot leave — you are the only teacher in this course"
},
"members": {
"title": "Members",
"inviteMember": "Invite Member",
"removeMember": "Remove Member",
"changeRole": "Change Role",
"approveRequest": "Approve",
"denyRequest": "Deny",
"removeConfirmTitle": "Remove Member",
"removeConfirmMessage": "Are you sure you want to remove {{name}} from this course?",
"inviteSuccess": "Invitation sent to {{name}}",
"removeSuccess": "{{name}} removed from course",
"alreadyMember": "This user is already a member",
"lastTeacherRemove": "Cannot remove the only teacher",
"lastTeacherDemote": "Cannot change role — this is the only teacher"
},
"modules": {
"title": "Modules",
"addModule": "Add Module",
"editModule": "Edit Module",
"deleteModule": "Delete Module",
"moduleTitle": "Module Title",
"contentType": "Content Type",
"order": "Order",
"deleteConfirmTitle": "Delete Module",
"deleteConfirmMessage": "Are you sure you want to delete this module?"
},
"roles": {
"teacher": "Teacher",
"student": "Student",
"assistant": "Assistant"
},
"visibility": {
"public": "Public",
"restricted": "Restricted",
"private": "Private",
"publicDesc": "Anyone can view and join",
"restrictedDesc": "Visible but requires approval to join",
"privateDesc": "Only visible to members"
},
"profile": {
"emptyTitle": "No courses yet",
"emptyMessage": "You're not enrolled in any courses",
"browseCourses": "Browse Courses",
"memberCount": "{{count}} members"
}
}
}- For each key above, provide the Arabic translation in
ar.json.
Definition of Done
- Every user-facing string in courses components uses
t("courses....")calls - Both
en.jsonandar.jsonhave the complete"courses"section - Switching language to Arabic shows fully translated courses UI
- RTL layout is not broken by any of the new text
- No hardcoded English strings remain in courses components
- No console warnings about missing translation keys
Benefits
This ensures EduLite's courses feature is accessible to Arabic-speaking users from day one. Internationalization is core to our mission of serving areas with limited resources — language should never be a barrier. The contributor will learn how i18n works in a real React app with react-i18next.
Skills You'll Practice
- Working with JSON translation files
- react-i18next
t()function usage - String interpolation in translations (
{{variable}}) - Plural forms (
_pluralsuffix) - RTL layout awareness
- Searching codebases for hardcoded strings
Files to be Altered
Frontend/EduLiteFrontend/src/i18n/locales/en.json— addcoursessectionFrontend/EduLiteFrontend/src/i18n/locales/ar.json— addcoursessection with Arabic translations- Any courses component files with hardcoded strings (search for them)
Testing
- Run the dev server and navigate to each courses page
- Switch language to Arabic — verify all text is translated
- Switch language back to English — verify nothing is broken
- Check browser console for missing translation key warnings
- Verify RTL layout on Arabic: text alignment, button positions, form labels
Tips
- Use the existing
"slideshow"section in both JSON files as a reference for structure and patterns - For Arabic translations, use formal Modern Standard Arabic (MSA)
- Plural forms in Arabic are complex — for simplicity, use
_pluralsuffix which covers the "other" form - If you're not confident in Arabic, mark uncertain translations with a
TODOcomment and note it in the PR — the team will review
Getting started? These wiki pages will help you get set up:
This is a beginner-friendly task. Ask questions in Discord — we're here to help!