Files
myeasycms-v2/apps/web/i18n/messages/en/courses.json
Zaid Marzguioui a1719671df
Some checks failed
Workflow / ⚫️ Test (push) Has been cancelled
Workflow / ʦ TypeScript (push) Has been cancelled
fix: QA remediation — all 19 audit fixes (C+ → A-)
## Summary
Fixes all 31  FAILs and most ⚠️ WARNs from the QA audit (113/33⚠️/31).

## Changes

### FIX 1 — Loading Skeleton
- Replace full-screen GlobalLoader with PageBody-scoped animate-pulse skeleton
- Sidebar stays visible during page transitions

### FIX 2 — Status Badges i18n (15 files, 12 label maps)
- Add *_LABEL_KEYS maps to lib/status-badges.ts (i18n keys instead of German)
- Update all 15 consumer files to use t(*_LABEL_KEYS[status])
- Add status namespace to finance.json (de+en)
- Add registration_open to events.json status (de+en)
- Add status block to cms.json events section (de+en)
- Add missing pending/bounced keys to newsletter.json (de+en)
- Add active key to courses.json status (de+en)

### FIX 3 — Error Page i18n
- Replace 4 hardcoded German strings with useTranslations('common')
- Add error.* keys to common.json (de+en)

### FIX 4 — Account Not Found i18n
- Convert AccountNotFound to async Server Component
- Resolve default props from getTranslations('common')
- Add accountNotFoundCard.* keys to common.json (de+en)

### FIX 5 — Publish Toggle Button (6 strings + 2 bugs)
- Add useTranslations('siteBuilder'), replace 6 German strings
- Fix: add response.ok check before router.refresh()
- Fix: add disabled={isPending} to AlertDialogAction
- Fix: use Base UI render= prop pattern (not asChild)
- Add pages.hide/publish/hideTitle/publishTitle/hideDesc/publishDesc/
  toggleError/cancelAction to siteBuilder.json (de+en)

### FIX 6 — Cancel Booking Button (7 strings + bugs)
- Add useTranslations('bookings'), replace all strings
- Fix: use render= prop pattern, add disabled={isPending}
- Add cancel.* and calendar.* keys to bookings.json (de+en)

### FIX 7 — Portal Pages i18n (5 files, ~40 strings)
- Create i18n/messages/de/portal.json and en/portal.json
- Add 'portal' to i18n/request.ts namespace list
- Rewrite portal/page.tsx, invite/page.tsx, profile/page.tsx,
  documents/page.tsx with getTranslations('portal')
- Fix portal-linked-accounts.tsx: add useTranslations, replace
  hardcoded strings, fix AlertDialogTrigger render= pattern

### FIX 8 — Invitations View (1 string)
- Replace hardcoded string with t('invitations.emptyDescription')
- Add key to members.json (de+en)

### FIX 9 — Dead Navigation Link
- Comment out memberPortal nav entry (page does not exist)

### FIX 10 — Calendar Button Accessibility
- Add aria-label + aria-hidden to all icon buttons in bookings/calendar
- Add aria-label + aria-hidden to all icon buttons in courses/calendar
- Add previousMonth/nextMonth/backToBookings/backToCourses to
  bookings.json and courses.json (de+en)

### FIX 11 — Pagination Aria Labels
- Add aria-label to icon-only pagination buttons in finance/page.tsx
- Fix Link/Button nesting in newsletter/page.tsx, add aria-labels
- Add pagination.* to common.json (de+en)
- Add common.previous/next to newsletter.json (de+en)

### FIX 12 — Site Builder Type Safety
- Add SitePage interface, replace Record<string,unknown> in page.tsx
- Add SitePost interface, replace Record<string,unknown> in posts/page.tsx
- Remove String() casts on typed properties

### FIX 14 — EmptyState Heading Level
- Change <h3> to <h2> in empty-state.tsx (WCAG heading sequence)

### FIX 16 — CmsPageShell Nullish Coalescing
- Change description ?? <AppBreadcrumbs /> to !== undefined check

### FIX 17 — Meetings Protocol Hardcoded Strings
- Replace 5 hardcoded German strings with t() in protocol detail page
- Add notFound/back/backToList/statusPublished/statusDraft to meetings.json

### FIX 18 — Finance Toolbar Hardcoded Strings
- Replace toolbar filter labels with t() calls in finance/page.tsx

### FIX 19 — Admin Audit Hardcoded Strings
- Add getTranslations('cms.audit') to audit page
- Replace title, description, column headers, pagination labels
- Add description/timestamp/paginationPrevious/paginationNext to cms.json

## Verification
- tsc --noEmit: 0 errors
- Turbopack: Compiled successfully in 9.3s
- Lint: 0 new errors introduced
- All 8 audit verification checks pass
2026-04-02 01:18:15 +02:00

213 lines
6.0 KiB
JSON
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.

{
"nav": {
"courses": "Courses",
"newCourse": "New Course",
"calendar": "Calendar",
"categories": "Categories",
"instructors": "Instructors",
"locations": "Locations",
"statistics": "Statistics"
},
"pages": {
"coursesTitle": "Courses",
"coursesDescription": "Manage course catalogue",
"newCourseTitle": "New Course",
"newCourseDescription": "Create a course",
"editCourseTitle": "Edit",
"calendarTitle": "Course Calendar",
"categoriesTitle": "Course Categories",
"instructorsTitle": "Instructors",
"locationsTitle": "Locations",
"statisticsTitle": "Course Statistics"
},
"common": {
"all": "All",
"status": "Status",
"previous": "Previous",
"next": "Next",
"page": "Page",
"of": "of",
"entries": "Entries",
"yes": "Yes",
"no": "No",
"name": "Name",
"email": "Email",
"phone": "Phone",
"date": "Date",
"address": "Address",
"room": "Room",
"parent": "Parent",
"description": "Description",
"edit": "Edit"
},
"list": {
"searchPlaceholder": "Search courses...",
"title": "All Courses ({count})",
"noCourses": "No courses found",
"createFirst": "Create your first course to get started.",
"courseNumber": "Course No.",
"courseName": "Name",
"startDate": "Start",
"endDate": "End",
"participants": "Participants",
"fee": "Fee",
"status": "Status",
"capacity": "Capacity"
},
"stats": {
"total": "Total",
"active": "Active",
"totalCourses": "Total Courses",
"activeCourses": "Active Courses",
"participants": "Participants",
"completed": "Completed",
"utilization": "Course Utilization",
"distribution": "Distribution",
"activeCoursesBadge": "Active Courses ({count})",
"noActiveCourses": "No active courses this month."
},
"detail": {
"notFound": "Course not found",
"participants": "Participants",
"sessions": "Sessions",
"viewAllParticipants": "View all participants",
"viewAttendance": "View attendance",
"noParticipants": "No participants yet.",
"noSessions": "No sessions yet.",
"addParticipant": "Add Participant",
"edit": "Edit",
"instructor": "Instructor",
"dateRange": "Start End",
"viewAll": "View all",
"attendance": "Attendance",
"name": "Name",
"email": "Email",
"date": "Date",
"cancelled": "Cancelled"
},
"form": {
"basicData": "Basic Data",
"courseNumber": "Course Number",
"courseName": "Course Name *",
"description": "Description",
"schedule": "Schedule",
"startDate": "Start Date",
"endDate": "End Date",
"registrationDeadline": "Registration Deadline",
"capacity": "Capacity",
"maxParticipants": "Max Participants",
"minParticipants": "Min Participants",
"fee": "Fee (€)",
"reducedFee": "Reduced Fee (€)",
"statusSection": "Status",
"courseStatus": "Course Status",
"created": "Course created successfully",
"updated": "Course updated",
"errorCreating": "Error creating course",
"errorUpdating": "Error updating course"
},
"status": {
"planned": "Planned",
"open": "Open",
"running": "Running",
"completed": "Completed",
"cancelled": "Cancelled",
"active": "Active"
},
"enrollment": {
"enrolled": "Enrolled",
"waitlisted": "Waitlisted",
"cancelled": "Cancelled",
"completed": "Completed",
"enrolledAt": "Enrolled on",
"title": "Enrollment Status",
"registrationDate": "Registration Date"
},
"participants": {
"title": "Participants",
"add": "Add Participant",
"none": "No Participants",
"noneDescription": "Register the first participant for this course.",
"allTitle": "All Participants ({count})"
},
"attendance": {
"title": "Attendance",
"present": "Present",
"absent": "Absent",
"excused": "Excused",
"session": "Session",
"noSessions": "No sessions yet",
"noSessionsDescription": "Create sessions for this course first.",
"selectSession": "Select Session",
"attendanceList": "Attendance List",
"selectSessionPrompt": "Please select a session"
},
"calendar": {
"title": "Course Calendar",
"courseDay": "Course Day",
"free": "Free",
"today": "Today",
"overview": "Overview of course dates",
"activeCourses": "Active Courses ({count})",
"noActiveCourses": "No active courses this month.",
"weekdays": [
"Mon",
"Tue",
"Wed",
"Thu",
"Fri",
"Sat",
"Sun"
],
"months": [
"January",
"February",
"March",
"April",
"May",
"June",
"July",
"August",
"September",
"October",
"November",
"December"
],
"previousMonth": "Previous Month",
"nextMonth": "Next Month",
"backToCourses": "Back to Courses"
},
"categories": {
"title": "Categories",
"newCategory": "New Category",
"noCategories": "No categories found.",
"manage": "Manage course categories",
"allTitle": "All Categories ({count})",
"namePlaceholder": "e.g. Language Courses",
"descriptionPlaceholder": "Short description"
},
"instructors": {
"title": "Instructors",
"newInstructor": "New Instructor",
"noInstructors": "No instructors found.",
"manage": "Manage instructor pool",
"allTitle": "All Instructors ({count})",
"qualification": "Qualification",
"hourlyRate": "Hourly Rate",
"firstNamePlaceholder": "First name",
"lastNamePlaceholder": "Last name",
"qualificationsPlaceholder": "e.g. Certified Trainer, First Aid Instructor"
},
"locations": {
"title": "Locations",
"newLocation": "New Location",
"noLocations": "No locations found.",
"manage": "Manage course and event locations",
"allTitle": "All Locations ({count})",
"noLocationsDescription": "Add your first venue.",
"newLocationLabel": "New Location",
"namePlaceholder": "e.g. Club House",
"addressPlaceholder": "123 Main St, Springfield",
"roomPlaceholder": "e.g. Room 101"
}
}