mirror of
https://github.com/Tria-plc/emaui.git
synced 2026-08-26 13:02:50 +00:00
1558 lines
54 KiB
TypeScript
1558 lines
54 KiB
TypeScript
import { landingEn } from '@ema-platform/ui';
|
||
|
||
export const en = {
|
||
landing: landingEn,
|
||
|
||
app: {
|
||
name: 'EMA Admin',
|
||
shortName: 'EMA',
|
||
authority: 'Ethiopian Maritime Authority',
|
||
tagline: 'Control Center',
|
||
},
|
||
|
||
// Strings only assistive technology encounters.
|
||
a11y: {
|
||
skipToContent: 'Skip to main content',
|
||
},
|
||
|
||
msg: {
|
||
genericError: 'Something went wrong. Please try again.',
|
||
serverError: 'Server error. Please try again later.',
|
||
validationError: 'Please check your input and try again.',
|
||
authError: 'Your session has expired. Please sign in again.',
|
||
permissionError: "You don't have permission to perform this action.",
|
||
notFoundError: 'The requested item was not found.',
|
||
fileTooLarge: 'The file is too large to upload.',
|
||
networkError: 'Network error. Check your connection and try again.',
|
||
},
|
||
|
||
language: {
|
||
label: 'Language',
|
||
en: 'English',
|
||
am: 'አማርኛ',
|
||
},
|
||
|
||
nav: {
|
||
groupLicensing: 'Licensing',
|
||
allApplications: 'All Applications',
|
||
licenceRegister: 'Licence Register',
|
||
certificateDesigner: 'Certificate Designer',
|
||
certificateRequirements: 'Certificate Requirements',
|
||
byType: 'By Type',
|
||
typeFreightForwarder: 'Freight Forwarder',
|
||
typeShippingAgent: 'Shipping Agent',
|
||
typeCombined: 'Combined SA + FF',
|
||
typeJointInvestment: 'Joint Investment',
|
||
typeMto: 'Multimodal Transport Operator',
|
||
typeSEAFARER_REGISTRATION: 'Seafarer Registration',
|
||
typeVESSEL_OWNERSHIP_TRANSFER: 'Vessel Ownership Transfer',
|
||
typeCERTIFICATE_OF_COMPETENCY: 'Certificate of Competency',
|
||
typeCERTIFICATE_OF_PROFICIENCY: 'Certificate of Proficiency',
|
||
typeENDORSEMENT_COC: 'CoC Endorsement',
|
||
typeENDORSEMENT_GOC: 'GOC Endorsement',
|
||
primary: 'Primary',
|
||
destinations: 'Go to',
|
||
noResults: 'Nothing found',
|
||
commandPlaceholder: 'Search screens, applications, companies, TIN…',
|
||
pending: 'Items pending',
|
||
pendingCount_one: '{{count}} pending',
|
||
pendingCount_other: '{{count}} pending',
|
||
groupSeafarer: 'Seafarer Services',
|
||
groupVessels: 'Vessels',
|
||
groupExaminations: 'Examinations',
|
||
groupShared: 'Shared Services',
|
||
groupAdministration: 'Administration',
|
||
groupAccount: 'Account',
|
||
soon: 'Soon',
|
||
details: 'Details',
|
||
licenceReview: 'Licence Applications',
|
||
menu: 'MENU',
|
||
dashboard: 'Dashboard',
|
||
userManagement: 'User Management',
|
||
seamanBookQueue: 'Seaman Book Queue',
|
||
btcQueue: 'BTC Queue',
|
||
vesselRegistrationApplicationQueue: 'Vessel Registration Queue',
|
||
vesselRegistrationQueue: 'Vessel Register',
|
||
vesselFormBuilder: 'Vessel Form Builder',
|
||
vesselRegistrationReport: 'Vessel Registration Report',
|
||
ownershipTransferQueue: 'Ownership Transfer Queue',
|
||
logisticsHeadDashboard: 'Logistics Head Dashboard',
|
||
freightForwarderLicense: 'Freight Forwarder License',
|
||
shippingAgentLicense: 'Shipping Agent License',
|
||
combinedLicense: 'Combined License',
|
||
jointInvestmentLicense: 'Joint Investment License',
|
||
mtoLicense: 'MTO License',
|
||
waiver: 'Waiver',
|
||
preWaiverQueue: 'Pre-Waiver Queue',
|
||
postWaiverQueue: 'Post-Waiver Queue',
|
||
cocQueue: 'CoC Queue',
|
||
copQueue: 'CoP Queue',
|
||
endorsementCocQueue: 'CoC Endorsement Queue',
|
||
endorsementGocQueue: 'GOC Endorsement Queue',
|
||
vesselRegistrations: 'Vessel Registration',
|
||
vesselTransfers: 'Vessel Ownership Transfer',
|
||
seafarerRegistry: 'Seafarer Registry',
|
||
seafarerRegistrationQueue: 'Seafarer Registration Queue',
|
||
applications: 'Applications',
|
||
paymentConfig: 'Payment Config',
|
||
analytics: 'Analytics',
|
||
seaServiceVerification: 'Sea Service Verification',
|
||
medicalVerification: 'Medical Verification',
|
||
locations: 'Locations',
|
||
configuration: 'Configuration',
|
||
profile: 'Profile',
|
||
questions: 'Questions',
|
||
exams: 'Examinations',
|
||
examResults: 'Exam Results',
|
||
examAppeals: 'Exam Appeals',
|
||
collapseSidebar: 'Collapse',
|
||
expandSidebar: 'Expand sidebar',
|
||
},
|
||
|
||
common: {
|
||
logout: 'Log out',
|
||
idleLogoutTitle: 'Session ended',
|
||
idleLogoutMessage: 'You were signed out after 15 minutes of inactivity.',
|
||
profile: 'Profile',
|
||
settings: 'Settings',
|
||
export: 'Export',
|
||
viewAll: 'View all',
|
||
home: 'Home',
|
||
notifications: 'Notifications',
|
||
administrator: 'Administrator',
|
||
collapse: 'Collapse',
|
||
expand: 'Expand',
|
||
toggleTheme: 'Toggle light / dark mode',
|
||
refresh: 'Refresh',
|
||
view: 'View',
|
||
toggleColumns: 'Toggle columns',
|
||
noResult: 'No results',
|
||
switchCalendar: 'Switch calendar type',
|
||
time: 'Time',
|
||
},
|
||
|
||
breadcrumbs: {
|
||
dashboard: 'Dashboard',
|
||
um: 'User Management',
|
||
home: 'Home',
|
||
},
|
||
|
||
dashboard: {
|
||
title: 'Overview',
|
||
subtitle: 'Welcome back — here\u2019s what\u2019s happening across your platform.',
|
||
kpis: {
|
||
totalUsers: 'Total Users',
|
||
activeUsers: 'Active Users',
|
||
newThisMonth: 'New This Month',
|
||
pendingApprovals: 'Pending Approvals',
|
||
},
|
||
charts: {
|
||
userRegistrations: 'User Registrations',
|
||
registrationsSubtitle: 'New sign-ups over the last 8 months',
|
||
vsPreviousPeriod: 'vs previous period',
|
||
usersByRole: 'Users by Role',
|
||
roleDistribution: 'Distribution across access levels',
|
||
totalUsers: 'Total users',
|
||
},
|
||
quickLinks: {
|
||
title: 'Quick Links',
|
||
subtitle: 'Common administrative shortcuts',
|
||
addUser: 'Add User',
|
||
addUserDesc: 'Create a new account',
|
||
rolesAndPermissions: 'Roles & Permissions',
|
||
rolesAndPermissionsDesc: 'Manage access levels',
|
||
inviteMembers: 'Invite Members',
|
||
inviteMembersDesc: 'Send email invites',
|
||
importUsers: 'Import Users',
|
||
importUsersDesc: 'Bulk CSV import',
|
||
exportData: 'Export Data',
|
||
exportDataDesc: 'Download reports',
|
||
auditLog: 'Audit Log',
|
||
auditLogDesc: 'Review activity',
|
||
},
|
||
recentUsers: {
|
||
title: 'Recent Users',
|
||
},
|
||
timeRange: {
|
||
today: 'Today',
|
||
thisWeek: 'This Week',
|
||
thisMonth: 'This Month',
|
||
},
|
||
},
|
||
|
||
exam: {
|
||
title: 'Examinations',
|
||
subtitle: 'Manage exams, assign questions, and track results',
|
||
create: 'Create Exam',
|
||
update: 'Update Exam',
|
||
add: 'Create Exam',
|
||
noItems: 'No exams found',
|
||
created: 'Exam created',
|
||
updated: 'Exam updated',
|
||
deleted: 'Exam deleted',
|
||
error: 'Operation failed',
|
||
loadError: 'Error loading exams',
|
||
cancel: 'Cancel',
|
||
delete: 'Delete',
|
||
confirmDelete: 'Delete Exam',
|
||
deleteConfirmText: 'Are you sure you want to delete {{name}}?',
|
||
print: 'Print Exam',
|
||
recordResult: 'Record Result',
|
||
manageQuestions: 'Manage Questions',
|
||
saveAssignments: 'Save Assignments',
|
||
randomSelect: 'Randomly Select',
|
||
backToExams: 'Back to Exams',
|
||
notFound: 'Exam not found.',
|
||
noQuestionsAssigned: 'No questions assigned yet. Click "Manage Questions" to assign.',
|
||
columns: {
|
||
title: 'Title',
|
||
certification: 'Certification',
|
||
date: 'Date',
|
||
type: 'Type',
|
||
form: 'Form',
|
||
venue: 'Venue',
|
||
questions: 'Questions',
|
||
status: 'Status',
|
||
},
|
||
detail: {
|
||
title: 'Exam Details',
|
||
certification: 'Certification',
|
||
type: 'Type',
|
||
form: 'Form',
|
||
venue: 'Venue',
|
||
date: 'Date',
|
||
administration: 'Administration',
|
||
evaluation: 'Evaluation',
|
||
selection: 'Selection',
|
||
timeAllowed: 'Time Allowed',
|
||
passMark: 'Pass Mark',
|
||
totalPoints: 'Total Points',
|
||
questions: 'Questions',
|
||
directions: 'Directions',
|
||
questionLabel: 'Question',
|
||
questionsSection: 'Questions ({{pts}} pts total)',
|
||
},
|
||
form: {
|
||
basicInfo: 'Basic Info',
|
||
settings: 'Settings',
|
||
certification: 'Certification',
|
||
selectCertification: 'Select certification',
|
||
titleEn: 'Title (English)',
|
||
titleEnPlaceholder: 'Exam title in English',
|
||
titleAm: 'Title (Amharic)',
|
||
titleAmPlaceholder: 'የፈተና ርዕስ',
|
||
directionEn: 'Direction (English)',
|
||
directionEnPlaceholder: 'Instructions in English',
|
||
directionAm: 'Direction (Amharic)',
|
||
directionAmPlaceholder: 'መመሪያ በአማርኛ',
|
||
examDate: 'Exam Date',
|
||
venue: 'Venue',
|
||
venuePlaceholder: 'Exam venue',
|
||
timeAllowed: 'Time Allowed',
|
||
days: 'Days',
|
||
hours: 'Hours',
|
||
minutes: 'Minutes',
|
||
written: 'Written',
|
||
oral: 'Oral',
|
||
essay: 'Essay',
|
||
choice: 'Choice',
|
||
both: 'Both',
|
||
offline: 'Offline',
|
||
online: 'Online',
|
||
onlineChoiceOnlyHint: 'Online exams are graded automatically, which only works for multiple choice.',
|
||
sum: 'Sum',
|
||
average: 'Average',
|
||
percentage: 'Percentage',
|
||
manual: 'Manual',
|
||
random: 'Random',
|
||
cuttingPoint: 'Cutting Point (Pass Mark)',
|
||
cuttingPointPlaceholder: 'Minimum score to pass',
|
||
cuttingPointPercentagePlaceholder: 'Minimum % to pass (0-100)',
|
||
cuttingPointPercentageHint: 'Percentage evaluation — capped at 100.',
|
||
fillRequiredBasic: 'Please fill all required fields in Basic Info.',
|
||
fillRequiredSettings: 'Please fill all required fields in Settings — type, form, administration method, evaluation method, and cutting point.',
|
||
directionBothLanguages: 'Direction needs text in both English and Amharic, or leave both empty.',
|
||
status: 'Status',
|
||
statusPlaceholder: 'Exam status',
|
||
pending: 'Pending',
|
||
active: 'Active',
|
||
completed: 'Completed',
|
||
cancelled: 'Cancelled',
|
||
postponed: 'Postponed',
|
||
published: 'Published',
|
||
},
|
||
assigner: {
|
||
title: 'Assign Questions to Exam',
|
||
assignedTitle: 'Assigned Questions',
|
||
available: 'Available Questions',
|
||
assigned: 'Assigned Questions',
|
||
search: 'Search...',
|
||
noQuestions: 'No questions',
|
||
assignSelected: 'Assign Selected ({{count}})',
|
||
removeSelected: 'Remove Selected ({{count}})',
|
||
randomHint: 'Randomly select questions from the pool of {{total}} eligible questions. The selection will automatically ensure total points meet the passing mark ({{pts}} pts).',
|
||
selectCount: 'Count',
|
||
},
|
||
status: {
|
||
PENDING: 'Pending',
|
||
ACTIVE: 'Active',
|
||
COMPLETED: 'Completed',
|
||
CANCELLED: 'Cancelled',
|
||
POSTPONED: 'Postponed',
|
||
PUBLISHED: 'Published',
|
||
},
|
||
type: {
|
||
WRITTEN: 'Written',
|
||
ORAL: 'Oral',
|
||
},
|
||
formType: {
|
||
ESSAY: 'Essay',
|
||
CHOICE: 'Choice',
|
||
BOTH: 'Both',
|
||
},
|
||
admin: {
|
||
OFFLINE: 'Offline',
|
||
ONLINE: 'Online',
|
||
},
|
||
eval: {
|
||
SUM: 'Sum',
|
||
AVERAGE: 'Average',
|
||
PERCENTAGE: 'Percentage',
|
||
},
|
||
selection: {
|
||
MANUAL: 'Manual',
|
||
RANDOM: 'Random',
|
||
},
|
||
candidates: {
|
||
section: 'Candidates',
|
||
admission: 'Admission №',
|
||
name: 'Candidate',
|
||
attempt: 'Attempt',
|
||
attendance: 'Attendance',
|
||
remark: 'Remark',
|
||
record: 'Record',
|
||
recorded: 'Attendance recorded',
|
||
none: 'No candidates have registered for this session yet.',
|
||
retake: 'Retake {{n}}',
|
||
firstSitting: 'First sitting',
|
||
remarkRequired: 'A reason is required for a withdrawal or a disqualification.',
|
||
regrade: 'Regrade',
|
||
regraded: 'Result created from the graded attempt.',
|
||
regradeNotEligible: 'Not auto-gradable: {{reason}}. Use Record Result instead.',
|
||
regradeError: 'Could not regrade this attempt.',
|
||
},
|
||
attendance: {
|
||
REGISTERED: 'Not called',
|
||
PRESENT: 'Present',
|
||
ABSENT: 'Absent',
|
||
LATE: 'Late',
|
||
WITHDRAWN: 'Withdrawn',
|
||
DISQUALIFIED: 'Disqualified',
|
||
},
|
||
incidents: {
|
||
section: 'Incidents',
|
||
add: 'Record incident',
|
||
type: 'Type',
|
||
candidate: 'Candidate',
|
||
wholeRoom: 'Whole session',
|
||
description: 'What happened',
|
||
occurred: 'Occurred',
|
||
status: 'Status',
|
||
resolve: 'Resolve',
|
||
resolution: 'Ruling',
|
||
outcome: 'Outcome',
|
||
none: 'No incidents recorded for this session.',
|
||
filed: 'Incident recorded',
|
||
resolved: 'Incident closed',
|
||
error: 'Operation failed',
|
||
},
|
||
incidentType: {
|
||
MISCONDUCT: 'Misconduct',
|
||
TECHNICAL_FAILURE: 'Technical failure',
|
||
MEDICAL: 'Medical',
|
||
ADMINISTRATIVE: 'Administrative',
|
||
OTHER: 'Other',
|
||
},
|
||
incidentStatus: {
|
||
OPEN: 'Open',
|
||
UNDER_REVIEW: 'Under review',
|
||
RESOLVED: 'Resolved',
|
||
DISMISSED: 'Dismissed',
|
||
},
|
||
randomHintServer:
|
||
'Questions are drawn on the server from approved bank items for this subject, so the pool is never exposed to the browser.',
|
||
randomSelected: 'Drew {{count}} approved questions',
|
||
randomError: 'Could not draw questions',
|
||
notEnoughApproved:
|
||
'Not enough approved questions in the bank for this subject.',
|
||
cannotReachCuttingPoint:
|
||
'This paper cannot reach the passing mark (max {{max}}, pass mark {{cuttingPoint}}). Add more/higher-point questions, or lower the cutting point.',
|
||
},
|
||
|
||
country: {
|
||
select: 'Select a country',
|
||
notFound: 'No countries found',
|
||
},
|
||
|
||
location: {
|
||
title: 'Locations',
|
||
hierarchy: 'Location Hierarchy',
|
||
search: 'Search locations...',
|
||
noLocations: 'No locations found. Add a root location to get started.',
|
||
selectHint: 'Select a location from the tree to view details',
|
||
addRoot: 'Add Root Location',
|
||
addSubLocation: 'Add Sub-Location',
|
||
addTitle: 'Add Location',
|
||
editTitle: 'Edit Location',
|
||
code: 'Code',
|
||
name: 'Name',
|
||
nameEn: 'Name (English)',
|
||
nameAm: 'Name (Amharic)',
|
||
type: 'Type',
|
||
level: 'Level',
|
||
parent: 'Parent',
|
||
selectType: 'Select type',
|
||
cancel: 'Cancel',
|
||
create: 'Create',
|
||
update: 'Update',
|
||
edit: 'Edit',
|
||
delete: 'Delete',
|
||
created: 'Location created successfully',
|
||
updated: 'Location updated successfully',
|
||
deleted: 'Location deleted successfully',
|
||
error: 'Something went wrong',
|
||
deleteError: 'Failed to delete location',
|
||
confirmDelete: 'Confirm Delete',
|
||
deleteConfirmText: 'Are you sure you want to delete {{name}}?',
|
||
manageTypes: 'Manage Location Types',
|
||
addType: 'Add Location Type',
|
||
noTypes: 'No location types defined yet',
|
||
typeCreated: 'Location type created',
|
||
typeUpdated: 'Location type updated',
|
||
typeDeleted: 'Location type deleted',
|
||
typeError: 'Failed to save location type',
|
||
setupRequired: 'Setup Required',
|
||
setupHint: 'You need to configure location types (e.g., Country, Region, City) before adding locations.',
|
||
configureTypes: 'Configure Location Types',
|
||
noTypesAvailable: 'No location types available for this level',
|
||
multipleTypesHint: 'Multiple types found — type is auto-selected from the lowest available level.',
|
||
validation: {
|
||
codeRequired: 'Code is required',
|
||
nameEnRequired: 'English name is required',
|
||
nameAmRequired: 'Amharic name is required',
|
||
typeRequired: 'Location type is required',
|
||
},
|
||
},
|
||
|
||
profile: {
|
||
title: 'My Profile',
|
||
subtitle: 'Manage your account details and preferences.',
|
||
personal: 'Personal information',
|
||
contact: 'Contact',
|
||
preferences: 'Preferences',
|
||
security: 'Security',
|
||
securityHint: 'Choose a strong password you do not use anywhere else.',
|
||
changePassword: 'Change password',
|
||
updatePassword: 'Update password',
|
||
updateProfile: 'Save changes',
|
||
savePreferences: 'Save preferences',
|
||
cancel: 'Cancel',
|
||
verified: 'Verified',
|
||
unverified: 'Unverified',
|
||
tabs: {
|
||
profile: 'Profile',
|
||
security: 'Security',
|
||
preferences: 'Preferences',
|
||
},
|
||
personalHint: 'Your name as it appears on official EMA documents.',
|
||
languageTitle: 'Language',
|
||
languageHint: 'Choose the language used across the admin panel.',
|
||
appearance: {
|
||
title: 'Appearance',
|
||
subtitle: 'Select how the admin panel looks on your device.',
|
||
light: 'Light',
|
||
dark: 'Dark',
|
||
system: 'System',
|
||
},
|
||
sessions: {
|
||
title: 'Active sessions',
|
||
hint: 'Devices currently signed in to your account. Revoke any you do not recognise.',
|
||
columns: {
|
||
device: 'IP address',
|
||
signedIn: 'Signed in',
|
||
expires: 'Expires',
|
||
status: 'Status',
|
||
actions: 'Actions',
|
||
},
|
||
select: 'Select',
|
||
selectAll: 'Select all sessions',
|
||
selectRow: 'Select session from {{device}}',
|
||
thisDevice: 'This device',
|
||
revoke: 'Revoke',
|
||
cannotRevokeCurrent: 'This is the session you are using now.',
|
||
revokeSelected_one: 'Revoke {{count}} selected',
|
||
revokeSelected_other: 'Revoke {{count}} selected',
|
||
signOutOthers: 'Sign out everywhere else',
|
||
empty: 'No active sessions.',
|
||
confirm: {
|
||
title: 'Revoke session',
|
||
one: 'The session from {{device}} will be signed out immediately.',
|
||
selected_one: '{{count}} session will be signed out immediately.',
|
||
selected_other: '{{count}} sessions will be signed out immediately.',
|
||
others: 'Every other session will be signed out immediately.',
|
||
unknownDevice: 'This may include the device you are using now.',
|
||
},
|
||
revoked_one: '{{count}} session revoked',
|
||
revoked_other: '{{count}} sessions revoked',
|
||
},
|
||
twoStep: {
|
||
title: 'Two-step verification',
|
||
desc: 'Require a one-time code from your phone each time you sign in.',
|
||
saved: 'Two-step verification updated',
|
||
},
|
||
layout: {
|
||
title: 'Layout',
|
||
subtitle: 'Choose how the navigation is displayed.',
|
||
top: 'Top tabs',
|
||
sidebar: 'Sidebar',
|
||
},
|
||
notifications: {
|
||
title: 'Email notifications',
|
||
desc: 'Receive updates about your account activity by email.',
|
||
},
|
||
strength: {
|
||
label: 'Password strength',
|
||
weak: 'Weak',
|
||
fair: 'Fair',
|
||
good: 'Good',
|
||
strong: 'Strong',
|
||
},
|
||
profileUpdated: 'Profile updated successfully',
|
||
passwordChanged: 'Password changed successfully',
|
||
updateFailed: 'Could not update profile. Please try again.',
|
||
passwordFailed:
|
||
'Could not change password. Check your current password and try again.',
|
||
fields: {
|
||
fullNameEn: 'Full name (English)',
|
||
fullNameAm: 'Full name (Amharic)',
|
||
username: 'Username',
|
||
usernameHint: 'Username cannot be changed',
|
||
organization: 'Organization',
|
||
email: 'Email address',
|
||
phone: 'Phone number',
|
||
address: 'Address',
|
||
language: 'Preferred language',
|
||
currentPassword: 'Current password',
|
||
newPassword: 'New password',
|
||
confirmPassword: 'Confirm new password',
|
||
},
|
||
validation: {
|
||
nameRequired: 'Name is required',
|
||
emailInvalid: 'Enter a valid email',
|
||
usernameRequired: 'Username is required',
|
||
phoneRequired: 'Phone number is required',
|
||
passwordMin: 'Password must be at least 8 characters',
|
||
passwordMismatch: 'Passwords do not match',
|
||
},
|
||
},
|
||
|
||
certification: {
|
||
title: 'Certifications',
|
||
subtitle: 'Manage certification types (e.g. CoC, CoP)',
|
||
add: 'Add Certification',
|
||
noItems: 'No certifications found',
|
||
confirmDelete: 'Delete Certification',
|
||
deleteConfirmText: 'Are you sure you want to delete {{name}}?',
|
||
created: 'Certification created',
|
||
updated: 'Certification updated',
|
||
deleted: 'Certification deleted',
|
||
error: 'Operation failed',
|
||
loadError: 'Error loading certifications',
|
||
cancel: 'Cancel',
|
||
create: 'Create',
|
||
update: 'Update',
|
||
delete: 'Delete',
|
||
columns: {
|
||
name: 'Name',
|
||
description: 'Description',
|
||
status: 'Status',
|
||
},
|
||
form: {
|
||
nameEn: 'Name (English)',
|
||
nameEnPlaceholder: 'Certificate name in English',
|
||
nameAm: 'Name (Amharic)',
|
||
nameAmPlaceholder: 'የምስክር ወረቀት ስም',
|
||
descEn: 'Description (English)',
|
||
descEnPlaceholder: 'English description',
|
||
descAm: 'Description (Amharic)',
|
||
descAmPlaceholder: 'የአማርኛ መግለጫ',
|
||
},
|
||
status: {
|
||
active: 'Active',
|
||
inactive: 'Inactive',
|
||
},
|
||
},
|
||
|
||
result: {
|
||
title: 'Exam Results',
|
||
subtitle: 'View seafarer examination results and score breakdowns',
|
||
record: 'Record Result',
|
||
noItems: 'No results found',
|
||
noData: 'No data available',
|
||
created: 'Result recorded',
|
||
updated: 'Result updated',
|
||
deleted: 'Result deleted',
|
||
error: 'Operation failed',
|
||
loadError: 'Error loading results',
|
||
cancel: 'Cancel',
|
||
delete: 'Delete',
|
||
close: 'Close',
|
||
save: 'Save',
|
||
saveResult: 'Save Result',
|
||
section: 'Results',
|
||
selectExamError: 'Please select an exam',
|
||
continue: 'Continue',
|
||
confirmDelete: 'Delete Result',
|
||
deleteConfirmText: 'Are you sure you want to delete this result?',
|
||
stats: {
|
||
totalResults: 'Total Results',
|
||
passed: 'Passed',
|
||
failed: 'Failed',
|
||
avgScore: 'Avg Score',
|
||
},
|
||
columns: {
|
||
seafarer: 'Seafarer',
|
||
exam: 'Exam',
|
||
totalScore: 'Total Score',
|
||
status: 'Status',
|
||
date: 'Date',
|
||
},
|
||
detail: {
|
||
title: 'Result Detail',
|
||
seafarerProfile: 'Seafarer Profile',
|
||
examDetails: 'Exam Details',
|
||
fullName: 'Full Name',
|
||
gender: 'Gender',
|
||
dateOfBirth: 'Date of Birth',
|
||
maritalStatus: 'Marital Status',
|
||
examTitle: 'Exam Title',
|
||
titleAm: 'Title (Amharic)',
|
||
type: 'Type',
|
||
venue: 'Venue',
|
||
date: 'Date',
|
||
passMark: 'Pass Mark',
|
||
status: 'Status',
|
||
remark: 'Remark',
|
||
scoreBreakdown: 'Score Breakdown',
|
||
question: 'Question',
|
||
max: 'Max',
|
||
score: 'Score',
|
||
remarkShort: 'Remark',
|
||
selectExam: 'Choose the exam you want to record a result for.',
|
||
exam: 'Exam',
|
||
selectExamPlaceholder: 'Select an exam',
|
||
},
|
||
recordModal: {
|
||
title: 'Record Result',
|
||
seafarer: 'Seafarer',
|
||
seafarerPlaceholder: 'Search and select a seafarer',
|
||
scorePerQuestion: 'Score per Question',
|
||
question: 'Question',
|
||
maxPoints: 'Max Points',
|
||
score: 'Score',
|
||
remark: 'Remark',
|
||
remarkOptional: 'Remark (optional)',
|
||
remarkPlaceholder: 'Officer remarks',
|
||
totalScore: 'Total Score',
|
||
passMark: 'Pass Mark',
|
||
status: 'Status',
|
||
noQuestions: 'No questions assigned to this exam. Assign questions first.',
|
||
seafarerRequired: 'Please select a seafarer',
|
||
saveSuccess: 'Result recorded',
|
||
saveError: 'Failed to save result',
|
||
passed: 'PASSED',
|
||
failed: 'FAILED',
|
||
},
|
||
status: {
|
||
PASSED: 'PASSED',
|
||
FAILED: 'FAILED',
|
||
},
|
||
action: {
|
||
viewEdit: 'View / Edit',
|
||
delete: 'Delete',
|
||
},
|
||
search: {
|
||
seafarer: 'Search seafarer...',
|
||
filterByExam: 'Filter by exam',
|
||
allExams: 'All Exams',
|
||
},
|
||
review: {
|
||
column: 'Review',
|
||
MARKED: 'Marked',
|
||
MODERATED: 'Moderated',
|
||
APPROVED: 'Approved',
|
||
PUBLISHED: 'Published',
|
||
moderate: 'Moderate',
|
||
approve: 'Approve',
|
||
return: 'Return to examiner',
|
||
publish: 'Publish session results',
|
||
adjustment: 'Adjustment to the total',
|
||
adjustmentHint:
|
||
'A signed change, e.g. 3 or -2. Zero endorses the mark as it stands.',
|
||
remark: 'Reason',
|
||
remarkRequired: 'A reason is required.',
|
||
moderated: 'Marks moderated',
|
||
approved: 'Result approved',
|
||
returned: 'Result returned to the examiner',
|
||
publishedCount: 'Published {{published}} result(s); {{skipped}} skipped.',
|
||
publishNeedsExam: 'Filter by an exam first to publish its results.',
|
||
publishConfirmText:
|
||
'This publishes every approved result for {{exam}} — not just this one — and notifies each candidate. Continue?',
|
||
lockedAfterApproval:
|
||
'This result is approved and can no longer be edited. Return it to the examiner first.',
|
||
originalScore: 'Examiner total',
|
||
derivedStatus: 'Outcome (derived from the pass mark)',
|
||
error: 'Operation failed',
|
||
},
|
||
appeals: {
|
||
title: 'Examination appeals',
|
||
subtitle: 'Candidate challenges to published results',
|
||
number: 'Appeal №',
|
||
candidate: 'Candidate',
|
||
exam: 'Examination',
|
||
reason: 'Grounds',
|
||
lodged: 'Lodged',
|
||
decide: 'Decide',
|
||
uphold: 'Uphold',
|
||
reject: 'Reject',
|
||
remark: 'Decision and reason',
|
||
decided: 'Appeal decided',
|
||
none: 'No appeals are awaiting a ruling.',
|
||
upheldHint:
|
||
'Upholding returns the result to the examiner for re-marking; the candidate stops seeing it until it is approved and published again.',
|
||
error: 'Could not record the decision',
|
||
},
|
||
},
|
||
|
||
question: {
|
||
title: 'Questions',
|
||
pool: 'Question Pool',
|
||
filterByCertification: 'Filter by certification',
|
||
noQuestions: 'No questions found',
|
||
addQuestion: 'Add Question',
|
||
editQuestion: 'Edit Question',
|
||
confirmDelete: 'Confirm Delete',
|
||
deleteConfirmText: 'Are you sure you want to delete this question?',
|
||
created: 'Question created',
|
||
updated: 'Question updated',
|
||
deleted: 'Question deleted',
|
||
error: 'Operation failed',
|
||
loadError: 'Error loading questions',
|
||
cancel: 'Cancel',
|
||
create: 'Create',
|
||
update: 'Update',
|
||
delete: 'Delete',
|
||
columns: {
|
||
title: 'Title',
|
||
certification: 'Certification',
|
||
form: 'Form',
|
||
points: 'Points',
|
||
status: 'Status',
|
||
},
|
||
form: {
|
||
certification: 'Certification',
|
||
selectCertification: 'Select certification',
|
||
titleEn: 'Title (English)',
|
||
titleEnPlaceholder: 'Question in English',
|
||
titleAm: 'Title (Amharic)',
|
||
titleAmPlaceholder: 'ጥያቄ በአማርኛ',
|
||
form: 'Form',
|
||
selectForm: 'Select form',
|
||
essay: 'Essay',
|
||
choice: 'Choice',
|
||
points: 'Points',
|
||
pointsPlaceholder: 'Points',
|
||
timeAllowed: 'Time Allowed',
|
||
days: 'Days',
|
||
hours: 'Hours',
|
||
minutes: 'Minutes',
|
||
},
|
||
status: {
|
||
active: 'Active',
|
||
inactive: 'Inactive',
|
||
},
|
||
qc: {
|
||
column: 'Approval',
|
||
DRAFT: 'Draft',
|
||
PENDING_APPROVAL: 'Awaiting approval',
|
||
APPROVED: 'Approved',
|
||
REJECTED: 'Rejected',
|
||
RETIRED: 'Retired',
|
||
submit: 'Submit for approval',
|
||
approve: 'Approve',
|
||
reject: 'Reject',
|
||
retire: 'Retire',
|
||
remark: 'Reason',
|
||
remarkRequired: 'A reason is required to reject or retire an item.',
|
||
submitted: 'Sent for approval',
|
||
reviewed: 'Decision recorded',
|
||
reviewTitle: 'Review question bank item',
|
||
onlyApprovedUsable:
|
||
'Only approved items can be placed on an examination paper.',
|
||
error: 'Operation failed',
|
||
},
|
||
options: {
|
||
title: 'Answer Options',
|
||
hint: 'Mark every correct option. Saving replaces the entire option set.',
|
||
optionLabel: 'Option {{number}}',
|
||
optionEn: 'Option {{number}} (English)',
|
||
optionAm: 'Option {{number}} (Amharic)',
|
||
correct: 'Correct',
|
||
addOption: 'Add option',
|
||
save: 'Save options',
|
||
saved: 'Options saved',
|
||
saveFirst: 'Save the question first, then add its options.',
|
||
replaceNotice:
|
||
'Correct answers are never shown here once saved — re-mark them if you edit this set again.',
|
||
needAtLeastTwo: 'A question needs at least two options.',
|
||
needOneCorrect: 'Mark at least one option as correct.',
|
||
textRequired: 'Every option needs text in both languages.',
|
||
},
|
||
},
|
||
|
||
configuration: {
|
||
title: 'Configuration',
|
||
departments: 'Departments',
|
||
professions: 'Professions',
|
||
departmentsList: 'Departments',
|
||
professionsList: 'Professions',
|
||
addDepartment: 'Add Department',
|
||
addProfession: 'Add Profession',
|
||
name: 'Name',
|
||
nameEn: 'Name (English)',
|
||
nameAm: 'Name (Amharic)',
|
||
description: 'Description',
|
||
descEn: 'Description (English)',
|
||
descAm: 'Description (Amharic)',
|
||
department: 'Department',
|
||
selectDepartment: 'Select department',
|
||
cancel: 'Cancel',
|
||
create: 'Create',
|
||
update: 'Update',
|
||
edit: 'Edit',
|
||
delete: 'Delete',
|
||
created: 'Created successfully',
|
||
updated: 'Updated successfully',
|
||
deleted: 'Deleted successfully',
|
||
error: 'Something went wrong',
|
||
confirmDelete: 'Confirm Delete',
|
||
deleteConfirmText: 'Are you sure you want to delete {{name}}?',
|
||
noDepartments: 'No departments defined yet',
|
||
noProfessions: 'No professions defined yet',
|
||
validation: {
|
||
nameEnRequired: 'English name is required',
|
||
nameAmRequired: 'Amharic name is required',
|
||
departmentRequired: 'Department is required',
|
||
},
|
||
},
|
||
|
||
queue: {
|
||
title: 'Licence applications',
|
||
// {{family}} is "Certificate"/"Document"/"Licence" — used only on a
|
||
// type-scoped queue (`/licence-review/type/:typeCode`), where the whole
|
||
// list is one family; the mixed All/Mine views keep the plain title above.
|
||
titleByFamily: '{{family}} applications',
|
||
search: 'Search',
|
||
searchPlaceholder: 'Company, TIN or number',
|
||
status: 'Status',
|
||
anyStatus: 'Any',
|
||
type: 'Type',
|
||
anyType: 'Any',
|
||
typeCol: 'Type',
|
||
statusCol: 'Status',
|
||
statusValues: {
|
||
DRAFT: 'Draft',
|
||
SUBMITTED: 'Submitted',
|
||
UNDER_REVIEW: 'Under Review',
|
||
UNDER_EVALUATION: 'Under Evaluation',
|
||
RESUBMIT_REQUIRED: 'Resubmit Required',
|
||
INSPECTION_PENDING: 'Inspection Pending',
|
||
INSPECTION_COMPLETED: 'Inspection Completed',
|
||
APPROVED: 'Approved',
|
||
REJECTED: 'Rejected',
|
||
ON_HOLD: 'On Hold',
|
||
PAYMENT_PENDING: 'Payment Pending',
|
||
PAID: 'Paid',
|
||
PAYMENT_CONFIRMED: 'Preparing Certificate',
|
||
CERTIFICATE_ISSUED: 'Certificate Issued',
|
||
COMPLETED: 'Completed',
|
||
},
|
||
submittedFrom: 'Submitted from',
|
||
submittedTo: 'Submitted to',
|
||
clearFilters: 'Clear',
|
||
refresh: 'Refresh',
|
||
export: 'Export CSV',
|
||
exportTruncated: 'Export truncated',
|
||
exportTruncatedBody: 'Exported the first {{exported}} of {{total}} rows. Narrow the filter for the rest.',
|
||
exportFailed: 'Export failed',
|
||
comfortable: 'Comfortable',
|
||
compact: 'Compact',
|
||
number: 'App #',
|
||
company: 'Company',
|
||
applicant: 'Applicant',
|
||
// Column header when the grid holds both logistics-licence rows (which
|
||
// have a company) and certificate/document rows (which have an
|
||
// applicant instead) — the mixed "All Applications" queue.
|
||
companyOrApplicant: 'Applicant / Company',
|
||
tin: 'TIN',
|
||
submitted: 'Submitted',
|
||
sla: 'Age / SLA',
|
||
claim: 'Claim',
|
||
review: 'Review',
|
||
claimed: 'Claimed',
|
||
claimedBody: 'The application is now assigned to you.',
|
||
claimFailed: 'Could not claim',
|
||
claimRace: 'Another officer already claimed it.',
|
||
bulkClaim_one: 'Claim {{count}}',
|
||
bulkClaim_other: 'Claim {{count}}',
|
||
bulkClaimed_one: '{{count}} claimed',
|
||
bulkClaimed_other: '{{count}} claimed',
|
||
bulkClaimPartial_one: '{{count}} was already taken by another officer.',
|
||
bulkClaimPartial_other: '{{count}} were already taken by another officer.',
|
||
selectAll: 'Select all',
|
||
selectRow: 'Select {{number}}',
|
||
selectedCount_one: '{{count}} selected',
|
||
selectedCount_other: '{{count}} selected',
|
||
showing: 'Showing {{from}}–{{to}} of {{total}}',
|
||
empty: 'Nothing waiting here',
|
||
emptyBody: 'New applications will appear here as they are submitted.',
|
||
emptyFiltered: 'No applications match these filters',
|
||
emptyFilteredBody: 'Try widening or clearing the filters.',
|
||
errorTitle: 'Could not load the queue',
|
||
views: {
|
||
unassigned: 'Unassigned',
|
||
mine: 'My Queue',
|
||
awaitingApplicant: 'Awaiting Applicant',
|
||
overdue: 'Overdue',
|
||
readyToIssue: 'Ready to Issue',
|
||
all: 'All',
|
||
},
|
||
},
|
||
|
||
review: {
|
||
summary: 'Summary',
|
||
officer: 'Officer',
|
||
supervisor: 'Supervisor',
|
||
officerPlaceholder: 'Select who takes this on',
|
||
noOfficers: 'No officers found',
|
||
typeToConfirm: 'Type {{number}} to confirm',
|
||
confirmMismatch: 'Does not match',
|
||
type: 'Type',
|
||
tin: 'TIN',
|
||
kind: 'Kind',
|
||
submitted: 'Submitted',
|
||
slaLabel: 'SLA',
|
||
eligibility: 'Eligibility',
|
||
statusTimeline: 'Progress',
|
||
assigned: 'Assigned',
|
||
decisionBar: 'Decision bar',
|
||
moreActions: 'More actions',
|
||
irreversible: 'Cannot be undone',
|
||
irreversibleWarning: 'This decision is final and cannot be undone from the backoffice.',
|
||
irreversibleAck: 'I understand this is final',
|
||
reasonCode: 'Reason',
|
||
reasonCodePlaceholder: 'Select a reason',
|
||
reasonDetail: 'Details for the applicant',
|
||
reasonDetailHint: 'This text is sent to the applicant verbatim.',
|
||
deficiencies: 'Items the applicant must correct',
|
||
deficienciesHint: 'Only the ticked items become editable for the applicant.',
|
||
notificationPreview: 'Message to the applicant',
|
||
notificationPreviewHint: 'Sent by SMS and email. Edit before confirming if needed.',
|
||
needsCorrection: 'Needs correction',
|
||
correctionPlaceholder: 'What must the applicant correct?',
|
||
verifiedCapital: 'Verified capital (ETB)',
|
||
capitalHint: 'Minimum {{min}} — check against the bank letter',
|
||
capitalHintNoMin: 'Checked against the bank letter',
|
||
capitalLocked: 'Capital can no longer be edited at this stage.',
|
||
belowMinimum: 'Below the {{min}} minimum',
|
||
declared: 'Applicant declared',
|
||
role: 'Role',
|
||
name: 'Name',
|
||
evidence: 'Evidence',
|
||
noInspections: 'No inspection has been scheduled yet.',
|
||
unscheduled: 'Not scheduled',
|
||
inspectionResult: 'Inspection result',
|
||
findings: 'Findings',
|
||
dateTime: 'Date and time',
|
||
schedule: 'Schedule',
|
||
pickDate: 'Pick a date and time first',
|
||
passed: 'Passed',
|
||
failed: 'Failed',
|
||
round_one: 'round {{count}}',
|
||
round_other: 'round {{count}}',
|
||
theApplicant: 'the applicant',
|
||
linkCopied: 'Link copied',
|
||
actionFailed: 'Action failed',
|
||
errorTitle: 'Could not load this application',
|
||
hideActivity: 'Hide activity',
|
||
showActivity: 'Show activity',
|
||
awaitingPayment: 'Waiting for the applicant to pay {{amount}} {{currency}}.',
|
||
tabs: {
|
||
overview: 'Overview',
|
||
financials: 'Financials',
|
||
documents: 'Documents',
|
||
staff: 'Staff',
|
||
inspection: 'Inspection',
|
||
},
|
||
actions: {
|
||
claim: 'Claim',
|
||
assign: 'Assign',
|
||
escalate: 'Escalate',
|
||
hold: 'Put on hold',
|
||
resume: 'Resume',
|
||
completeReview: 'Complete review',
|
||
approveDocuments: 'Approve documents',
|
||
scheduleInspection: 'Schedule inspection',
|
||
recordInspection: 'Record inspection result',
|
||
finalApprove: 'Approve & issue',
|
||
requestAdjustment: 'Request adjustment',
|
||
reject: 'Reject',
|
||
scheduleExam: 'Schedule exam',
|
||
recordExamOutcome: 'Record exam outcome',
|
||
confirmPayment: 'Confirm payment',
|
||
scheduleIssuance: 'Schedule pickup',
|
||
issueCertificate: 'Issue certificate',
|
||
print: 'Print dossier',
|
||
copyLink: 'Copy link',
|
||
downloadDocuments: 'Download all documents',
|
||
generateCertificate: 'Generate certificate',
|
||
auditTrail: 'Show audit trail',
|
||
},
|
||
disabled: {
|
||
wrongStatus: 'Not available at this stage',
|
||
notAssigned: 'Assigned to another officer',
|
||
noPermission: 'You do not have permission',
|
||
needsFlags: 'Flag at least one item to request a correction',
|
||
needsCapital: 'Record the verified capital first',
|
||
needsInspection: 'Requires an inspection result',
|
||
needsDocumentReviews:
|
||
'Accept all documents first — {{accepted}} of {{total}} accepted. Open the Documents tab and accept the rest.',
|
||
needsDocumentsUploaded: 'No documents uploaded to review yet',
|
||
},
|
||
reasons: {
|
||
incompleteDocuments: 'Incomplete documents',
|
||
belowCapital: 'Capital below the required minimum',
|
||
failedInspection: 'Failed inspection',
|
||
ineligibleApplicant: 'Applicant not eligible',
|
||
duplicateApplication: 'Duplicate application',
|
||
illegibleDocument: 'Document is illegible',
|
||
expiredDocument: 'Document has expired',
|
||
missingDocument: 'Document is missing',
|
||
inconsistentDetails: 'Details do not match the documents',
|
||
awaitingThirdParty: 'Awaiting third-party confirmation',
|
||
legalProceedings: 'Subject to legal proceedings',
|
||
applicantRequest: 'Requested by the applicant',
|
||
aboveAuthority: 'Above my approval authority',
|
||
policyUnclear: 'Policy guidance needed',
|
||
conflictOfInterest: 'Conflict of interest',
|
||
},
|
||
consequences: {
|
||
fallback: 'This updates application {{number}} for {{applicant}}.',
|
||
'final-approve': 'Approves application {{number}} for {{applicant}} and starts certificate issuance.',
|
||
reject: 'Rejects application {{number}} for {{applicant}}. This ends the application.',
|
||
'request-adjustment': 'Returns application {{number}} to {{applicant}} for correction.',
|
||
hold: 'Parks application {{number}} for {{applicant}}. It stays assigned to you.',
|
||
resume: 'Returns application {{number}} to the stage it was held from.',
|
||
escalate: 'Raises application {{number}} to a supervisor for a decision.',
|
||
'confirm-payment': 'Confirms settlement for application {{number}}.',
|
||
'schedule-exam': 'Assigns {{applicant}} to an exam session for application {{number}}.',
|
||
},
|
||
notifications: {
|
||
fallback: 'Dear {{applicant}}, there is an update on application {{number}}: {{action}}.',
|
||
'final-approve': 'Dear {{applicant}}, application {{number}} has been approved. Your certificate is being prepared.',
|
||
reject: 'Dear {{applicant}}, application {{number}} has not been approved. Please see the reason below.',
|
||
'request-adjustment': 'Dear {{applicant}}, application {{number}} needs corrections before it can proceed.',
|
||
},
|
||
activity: {
|
||
title: 'Activity & audit trail',
|
||
empty: 'No activity recorded yet.',
|
||
system: 'System',
|
||
officer: 'Officer',
|
||
applicant: 'Applicant',
|
||
remarkOn: 'Correction requested on {{target}}',
|
||
uploaded: 'Uploaded {{document}}',
|
||
},
|
||
documents: {
|
||
completeness: 'Required documents',
|
||
accepted: 'Accepted',
|
||
rejected: 'Rejected',
|
||
accept: 'Accept',
|
||
clear: 'Clear verdict',
|
||
confirmReject: 'Reject',
|
||
includeInAdjustment: 'Send back',
|
||
adjustmentNote: 'What must the applicant correct?',
|
||
nothingToJudge: 'Nothing uploaded to judge',
|
||
reviewedBy: 'Reviewed by {{name}}',
|
||
saveFailed: 'Could not save the verdict',
|
||
completenessLabel: '{{value}}% of required documents uploaded',
|
||
missing: 'Not yet uploaded',
|
||
flagged: 'Correction requested',
|
||
view: 'View',
|
||
preview: 'Preview',
|
||
download: 'Download',
|
||
downloadShort: 'Download',
|
||
reject: 'Reject',
|
||
rejectReason: 'Why must this document be corrected?',
|
||
reasonRequired: 'A reason is required',
|
||
noFile: 'No file',
|
||
noFileUploaded: 'Nothing uploaded yet',
|
||
noInlinePreview: 'This file type cannot be previewed in the browser.',
|
||
previewFallback: 'document',
|
||
},
|
||
inspectionStatus: {
|
||
SCHEDULED: 'Scheduled',
|
||
COMPLETED: 'Completed',
|
||
CANCELLED: 'Cancelled',
|
||
},
|
||
kindValues: {
|
||
NEW: 'New',
|
||
RENEWAL: 'Renewal',
|
||
},
|
||
checklist: {
|
||
officePremises: 'Office premises',
|
||
storageFacilities: 'Warehouse / storage facilities',
|
||
vehiclesEquipment: 'Vehicles / equipment',
|
||
safetyCompliance: 'Safety & regulatory compliance',
|
||
},
|
||
eligibilityRule: {
|
||
capitalThreshold: 'Paid-up capital ≥ {{amount}}',
|
||
notRecorded: 'Not recorded',
|
||
declaredSuffix: ' (declared)',
|
||
verifiedSuffix: ' (verified)',
|
||
inspectionCompleted: 'Physical inspection completed',
|
||
recorded: 'Recorded',
|
||
notYetRecorded: 'Not yet recorded',
|
||
},
|
||
sla: {
|
||
untracked: 'No turnaround target is set for this licence type.',
|
||
target: 'Target {{hours}}h from submission ({{date}})',
|
||
met: 'Met',
|
||
missed: 'Missed',
|
||
decidedIn: 'Decided in {{duration}}. {{target}}',
|
||
overdue: 'Overdue {{duration}}',
|
||
overdueBy: 'Overdue by {{duration}}. {{target}}',
|
||
left: '{{duration}} left',
|
||
remaining: '{{duration}} remaining. {{target}}',
|
||
},
|
||
done: {
|
||
completeReview: 'Review completed',
|
||
approveDocuments: 'Documents approved',
|
||
finalApprove: 'Approved',
|
||
requestAdjustment: 'Adjustment requested',
|
||
reject: 'Application rejected',
|
||
confirmPayment: 'Payment confirmed',
|
||
hold: 'Application placed on hold',
|
||
resume: 'Application resumed',
|
||
escalate: 'Escalated',
|
||
assign: 'Reassigned',
|
||
scheduled: 'Inspection scheduled',
|
||
inspectionPassed: 'Inspection passed',
|
||
inspectionFailed: 'Inspection failed',
|
||
},
|
||
},
|
||
|
||
error: {
|
||
reference: 'Reference',
|
||
retry: 'Try again',
|
||
},
|
||
|
||
shortcuts: {
|
||
title: 'Keyboard shortcuts',
|
||
commandPalette: 'Search everything',
|
||
moveRow: 'Move between rows',
|
||
openRow: 'Open the selected row',
|
||
claimRow: 'Claim the selected row',
|
||
dismiss: 'Clear selection / close',
|
||
help: 'Show this list',
|
||
},
|
||
|
||
designer: {
|
||
title: 'Certificate designer',
|
||
subtitle: 'Design the certificate issued to licence holders, and set how long it stays valid.',
|
||
licenceType: 'Licence type',
|
||
validityYears: 'Valid for (years)',
|
||
validityHint: 'Applied when a licence is issued',
|
||
saveValidity: 'Save validity',
|
||
validitySaved: 'Validity updated',
|
||
newVersion: 'New version',
|
||
versions: 'Versions',
|
||
name: 'Version name',
|
||
landscape: 'Landscape',
|
||
source: 'Template (Handlebars + HTML)',
|
||
variables: 'Placeholders',
|
||
variablesHint: 'Click to insert at the cursor.',
|
||
preview: 'Preview PDF',
|
||
previewFailed: 'Could not render the preview',
|
||
save: 'Save draft',
|
||
saved: 'Draft saved',
|
||
saveFirst: 'Save your changes first',
|
||
publish: 'Publish',
|
||
published: 'Design published',
|
||
publishHint: 'Makes this the live certificate design',
|
||
publishedLocked: 'This version is live and cannot be edited — certificates have been issued from it. Create a new version to make changes.',
|
||
archive: 'Withdraw',
|
||
archived: 'Design withdrawn',
|
||
delete: 'Delete draft',
|
||
deleted: 'Draft deleted',
|
||
create: 'Create',
|
||
created: 'Draft created',
|
||
newHint: 'Starts from the live design, or the built-in layout if this type has none.',
|
||
empty: 'No design yet for this licence type',
|
||
emptyBody: 'Certificates currently use the built-in layout. Create a version to take control of it.',
|
||
loadFailed: 'Could not load the designs',
|
||
actionFailed: 'Action failed',
|
||
noPermission: 'You do not have permission',
|
||
noPublishPermission: 'You cannot publish designs',
|
||
},
|
||
|
||
certReq: {
|
||
title: 'Certificate requirements',
|
||
subtitle:
|
||
'Configure the form fields and document uploads applicants must complete for a licence type, including conditions on when a requirement applies.',
|
||
licenseType: 'Licence type',
|
||
selectLicenseType: 'Select a licence type',
|
||
loading: 'Loading licence types…',
|
||
loadFailed: 'Could not load licence types',
|
||
tabSchema: 'Form schema',
|
||
tabDocuments: 'Document requirements',
|
||
cancel: 'Cancel',
|
||
delete: 'Delete',
|
||
saveChanges: 'Save changes',
|
||
actionFailed: 'Action failed',
|
||
condition: {
|
||
title: 'Visibility condition',
|
||
badge: 'conditional',
|
||
enable: 'Only apply when a condition holds',
|
||
field: 'Field path',
|
||
fieldHelp: 'Dot path into the form, e.g. sectionKey.fieldKey',
|
||
operator: 'Operator',
|
||
value: 'Value',
|
||
values: 'Any of',
|
||
removeValue: 'Click to remove',
|
||
isSet: 'is set',
|
||
isNotSet: 'is not set',
|
||
unknownField: 'This path is not a field in the current schema yet — it will still be saved as typed.',
|
||
},
|
||
schema: {
|
||
subtitle:
|
||
'Sections and fields the applicant sees for this licence type. Sections sharing a group render together on one wizard step.',
|
||
checkErrors: 'Check for errors',
|
||
noIssues: 'No issues found',
|
||
issuesFound: 'Issues found',
|
||
save: 'Save schema',
|
||
saved: 'Form schema saved',
|
||
empty: 'No sections yet',
|
||
emptyBody: "Add a section to start building this licence type's form.",
|
||
},
|
||
section: {
|
||
add: 'Add section',
|
||
edit: 'Edit section',
|
||
delete: 'Delete section',
|
||
deleteConfirm: 'Remove "{{name}}" and all of its fields from this schema?',
|
||
key: 'Section key',
|
||
keyHelp: 'Letters, numbers and underscores only',
|
||
keyLocked: 'Key cannot change once created',
|
||
keyInvalid: 'Key must start with a letter and contain only letters, numbers, underscores',
|
||
title: 'Title',
|
||
description: 'Description',
|
||
group: 'Wizard step group',
|
||
groupHelp: 'Sections sharing the same group render together on one step',
|
||
groupBadge: 'group',
|
||
groupOrder: 'Group order',
|
||
sortOrder: 'Sort order',
|
||
},
|
||
field: {
|
||
add: 'Add field',
|
||
edit: 'Edit field',
|
||
delete: 'Delete field',
|
||
deleteConfirm: 'Remove "{{name}}" from this section?',
|
||
key: 'Field key',
|
||
keyHelp: 'Letters, numbers and underscores only — becomes the form data key',
|
||
keyLocked: 'Key cannot change once created',
|
||
keyInvalid: 'Key must start with a letter and contain only letters, numbers, underscores',
|
||
label: 'Label',
|
||
type: 'Field type',
|
||
required: 'Required',
|
||
placeholder: 'Placeholder',
|
||
helpText: 'Help text',
|
||
min: 'Minimum',
|
||
max: 'Maximum',
|
||
maxLength: 'Max length',
|
||
options: 'Options',
|
||
addOption: 'Add option',
|
||
optionValue: 'Value',
|
||
optionLabel: 'Label',
|
||
},
|
||
doc: {
|
||
subtitle: 'What an applicant must upload for this licence type, split by new application and renewal.',
|
||
add: 'Add document requirement',
|
||
edit: 'Edit document requirement',
|
||
delete: 'Delete document requirement',
|
||
deleteWarning: 'Applicants already relying on this slot will no longer see it. This cannot be undone.',
|
||
deleteConfirm: 'Remove "{{name}}"?',
|
||
created: 'Document requirement added',
|
||
updated: 'Document requirement updated',
|
||
deleted: 'Document requirement removed',
|
||
loading: 'Loading document requirements…',
|
||
loadFailed: 'Could not load document requirements',
|
||
empty: 'No document requirements configured',
|
||
emptyBody: 'Add the documents an applicant must upload for this licence type.',
|
||
emptyKind: 'No document requirements for this application kind yet.',
|
||
key: 'Key',
|
||
keyHelp: 'Stable slug identifying this document slot',
|
||
keyLocked: 'Key cannot change once created',
|
||
keyRequired: 'Key is required',
|
||
name: 'Name',
|
||
description: 'Description',
|
||
applicationKind: 'Application kind',
|
||
kindNew: 'New application',
|
||
kindRenewal: 'Renewal',
|
||
kindLocked: 'Application kind cannot change once created',
|
||
mode: 'Mode',
|
||
modeAlways: 'Always required',
|
||
modeConditional: 'Required when condition holds',
|
||
modeOptional: 'Optional upload',
|
||
conditionRequired: 'A conditional requirement needs a condition',
|
||
allowedTypes: 'Allowed file types',
|
||
maxSize: 'Max file size (MB)',
|
||
requiresValidity: 'Requires validity dates',
|
||
allowMultiple: 'Allow multiple uploads',
|
||
multiple: 'multiple',
|
||
sortOrder: 'Sort order',
|
||
when: 'when',
|
||
},
|
||
},
|
||
|
||
seafarerRegistry: {
|
||
title: 'Seafarer registry',
|
||
profileCount_one: '{{count}} profile',
|
||
profileCount_other: '{{count}} profiles',
|
||
searchPlaceholder: 'Name, ID or seafarer number',
|
||
emptySearch: 'No profiles match that search.',
|
||
emptyNone: 'No seafarers registered yet.',
|
||
columns: {
|
||
name: 'Name',
|
||
number: 'Seafarer №',
|
||
department: 'Department',
|
||
idNumber: 'ID number',
|
||
phone: 'Phone',
|
||
status: 'Status',
|
||
actions: 'Actions',
|
||
},
|
||
notRegistered: 'Not registered',
|
||
incomplete: 'Incomplete',
|
||
statusAction: 'Status',
|
||
statusActionTooltip: 'Suspend / reinstate / close',
|
||
status: {
|
||
ACTIVE: 'Active',
|
||
INACTIVE: 'Inactive',
|
||
PENDING: 'Pending',
|
||
SUSPENDED: 'Suspended',
|
||
},
|
||
departments: {
|
||
DECK: 'Deck',
|
||
ENGINE: 'Engine',
|
||
CATERING: 'Catering',
|
||
},
|
||
recordStatus: {
|
||
SUBMITTED: 'Submitted',
|
||
VERIFIED: 'Verified',
|
||
REJECTED: 'Rejected',
|
||
},
|
||
drawer: {
|
||
seafarerNumber: 'Seafarer number',
|
||
department: 'Department',
|
||
status: 'Status',
|
||
notRegistered: 'NOT REGISTERED',
|
||
statusReason: 'Status reason: {{reason}}',
|
||
seaServiceTab: 'Sea Service',
|
||
medicalTab: 'Medical',
|
||
noSeaService: 'No sea-service records.',
|
||
noMedical: 'No medical certificates.',
|
||
vessel: 'Vessel',
|
||
rank: 'Rank',
|
||
period: 'Period',
|
||
imoPrefix: 'IMO {{number}}',
|
||
issuer: 'Issuer',
|
||
validity: 'Validity',
|
||
fitness: 'Fitness',
|
||
},
|
||
modal: {
|
||
title: 'Change seafarer status',
|
||
body: '{{number}} — currently {{status}}. The reason is recorded and visible to the seafarer.',
|
||
newStatus: 'New status',
|
||
suspend: 'Suspend',
|
||
close: 'Close',
|
||
reinstate: 'Reinstate',
|
||
reason: 'Reason',
|
||
cancel: 'Cancel',
|
||
confirm: 'Confirm',
|
||
updated: 'Seafarer status updated',
|
||
updateFailed: 'Could not update the status',
|
||
},
|
||
},
|
||
|
||
paymentConfig: {
|
||
title: 'Payment configuration',
|
||
subtitle: 'What each licence costs. Applicants are charged after approval, and the amount is fixed onto the application at that moment.',
|
||
changeNotice: 'A change applies to applications approved from now on. Anything already approved keeps the amount it was quoted, so an edit here can never alter what an applicant has already been asked to pay.',
|
||
loadError: 'Could not load licence types',
|
||
columns: {
|
||
type: 'Licence type',
|
||
newApplication: 'New application',
|
||
renewal: 'Renewal',
|
||
charged: 'Charged?',
|
||
},
|
||
renewalSameTooltip: 'No separate renewal fee — renewal is charged at the new-application rate',
|
||
renewalSameAsNew: '(same as new)',
|
||
chargedOnApproval: 'On approval',
|
||
chargedNotChargedTooltip: 'This licence type ends with an EMA decision and never reaches a payment stage',
|
||
chargedNotCharged: 'Not charged',
|
||
edit: 'Edit',
|
||
gateway: {
|
||
title: 'Payment gateway',
|
||
subtitle: 'Set by the payment service environment — not editable here.',
|
||
provider: 'Telebirr',
|
||
bypassTooltip: 'ALLOW_PAYMENT_BYPASS is on, so an applicant can settle a fee without paying. It is refused in production.',
|
||
bypassEnabled: 'Test bypass enabled',
|
||
bypassOff: 'Test bypass off',
|
||
},
|
||
modal: {
|
||
title: 'Fees — {{type}}',
|
||
noPaymentStage: 'This licence type concludes with an EMA decision and never reaches a payment stage, so a fee set here stays unused until that changes.',
|
||
chargeableLabel: 'This licence carries a fee',
|
||
chargeableDescription: 'Turn off for licence types applicants are never charged for.',
|
||
newFeeLabel: 'New application fee',
|
||
sameRateLabel: 'Charge renewal at the same rate',
|
||
sameRateDescription: 'Turn off to set a separate renewal fee.',
|
||
renewalFeeLabel: 'Renewal fee',
|
||
currencyLabel: 'Currency',
|
||
cancel: 'Cancel',
|
||
save: 'Save fees',
|
||
missingNewFee: 'Enter a new-application fee, or turn off "carries a fee".',
|
||
missingRenewalFee: 'Enter a renewal fee, or charge renewal at the same rate.',
|
||
updated: '{{type}} fees updated.',
|
||
saveFailed: 'Could not save the fees',
|
||
},
|
||
},
|
||
|
||
recordVerification: {
|
||
title: 'Record verification',
|
||
subtitle: 'Submitted sea-service records and medical certificates awaiting a ruling. Verified records are frozen; rejections return to the seafarer with your remark.',
|
||
tabs: {
|
||
medical: 'Medical ({{count}})',
|
||
seaService: 'Sea Service ({{count}})',
|
||
},
|
||
columns: {
|
||
seafarer: 'Seafarer',
|
||
issuer: 'Issuer',
|
||
validity: 'Validity',
|
||
fitness: 'Fitness',
|
||
vessel: 'Vessel',
|
||
rank: 'Rank',
|
||
period: 'Period',
|
||
actions: 'Actions',
|
||
},
|
||
fitness: {
|
||
FIT: 'Fit',
|
||
FIT_WITH_RESTRICTIONS: 'Fit with restrictions',
|
||
UNFIT: 'Unfit',
|
||
},
|
||
evidence: 'Evidence',
|
||
verify: 'Verify',
|
||
reject: 'Reject',
|
||
evidenceTitleMedical: 'Evidence for {{name}} Medical Certificate',
|
||
evidenceTitleSeaService: 'Evidence for {{name}} Sea Service Record',
|
||
certificateVerified: 'Certificate verified',
|
||
seaServiceVerified: 'Sea-service record verified',
|
||
certificateRejected: 'Certificate rejected',
|
||
seaServiceRejected: 'Sea-service record rejected',
|
||
rulingFailed: 'Could not record the ruling',
|
||
emptyText: 'Nothing awaiting verification.',
|
||
rejectMedicalTitle: 'Reject medical certificate',
|
||
rejectSeaServiceTitle: 'Reject sea-service record',
|
||
rejectReasonLabel: 'What must the seafarer fix?',
|
||
cancel: 'Cancel',
|
||
evidenceModalTitle: 'Evidence Attachments',
|
||
noAttachments: 'No evidence attachments uploaded for this record.',
|
||
view: 'View',
|
||
noUrl: 'No URL',
|
||
},
|
||
|
||
authShell: {
|
||
toggleTheme: 'Toggle theme',
|
||
brandTitle: 'Maritime licensing, made simple.',
|
||
brandSubtitle: 'Apply for vessel and seafarer licenses, upload documents, and track every application in one secure portal.',
|
||
feature1: 'Submit applications online, 24/7',
|
||
feature2: 'Real-time status tracking & alerts',
|
||
feature3: 'Available in English & አማርኛ',
|
||
copyright: '© 2026 Ethiopian Maritime Authority',
|
||
},
|
||
|
||
login: {
|
||
emailOrPhoneInvalid: 'Enter a valid email or phone number (+2519xxxxxxxx)',
|
||
passwordMinLength: 'Password must be at least 8 characters',
|
||
welcome: 'Welcome to {{appName}}',
|
||
subtitle: 'Sign in to access your account.',
|
||
emailOrPhoneLabel: 'Email or phone',
|
||
emailOrPhonePlaceholder: 'you@example.com',
|
||
passwordLabel: 'Password',
|
||
passwordPlaceholder: 'Your password',
|
||
rememberMe: 'Remember me',
|
||
forgotPassword: 'Forgot password?',
|
||
signIn: 'Sign in',
|
||
noAccount: "Don't have an account? ",
|
||
createOne: 'Create one',
|
||
},
|
||
|
||
signup: {
|
||
usernameMinLength: 'Username must be at least 3 characters',
|
||
nameEnRequired: 'Name (English) is required',
|
||
phoneRequired: 'Phone number is required',
|
||
confirmPasswordRequired: 'Confirm your password',
|
||
passwordsDontMatch: 'Passwords do not match',
|
||
brandTitle: "Join {{appName}}'s community.",
|
||
brandSubtitle: 'Create your account to access {{appName}} features.',
|
||
title: 'Create account',
|
||
subtitle: 'It only takes a minute to get started.',
|
||
nameEnLabel: 'Name (English)',
|
||
nameEnPlaceholder: 'Abebe Bekele',
|
||
nameAmLabel: 'Name (Amharic)',
|
||
nameAmPlaceholder: 'ስም',
|
||
emailLabel: 'Email address',
|
||
emailPlaceholder: 'you@example.com',
|
||
usernameLabel: 'Username',
|
||
usernamePlaceholder: 'Choose a username',
|
||
phoneLabel: 'Phone number',
|
||
phonePlaceholder: '+251 911 234 567',
|
||
passwordLabel: 'Password',
|
||
passwordPlaceholder: 'At least 8 characters',
|
||
confirmPasswordLabel: 'Confirm password',
|
||
confirmPasswordPlaceholder: 'Re-enter password',
|
||
agreeToThe: 'I agree to the ',
|
||
termsAndPrivacy: 'Terms & Privacy Policy',
|
||
createAccount: 'Create account',
|
||
haveAccount: 'Already have an account? ',
|
||
signIn: 'Sign in',
|
||
passwordRule: {
|
||
minLength: 'At least {{min}} characters',
|
||
lowercase: 'One lowercase letter',
|
||
uppercase: 'One uppercase letter',
|
||
number: 'One number',
|
||
special: 'One special character',
|
||
},
|
||
},
|
||
};
|
||
|
||
export type Translations = typeof en;
|