mirror of
https://github.com/Tria-plc/emaui.git
synced 2026-08-26 19:12:50 +00:00
- Implemented ExamStageActions component to manage actions related to exam booking and payment based on application status. - Added mock-base-query for development, providing a partial mock backend for various API endpoints. - Introduced mock-data for simulating responses in the mock-base-query, covering profiles, vessels, applications, licenses, exams, and notifications.
741 lines
23 KiB
TypeScript
741 lines
23 KiB
TypeScript
/**
|
|
* Dev-only sample data for the mock base query (see `mock-base-query.ts`).
|
|
*
|
|
* Throwaway preview fixtures — realistic enough to demo the four portal
|
|
* feature areas (vessel registration, seafarer registration, CoC
|
|
* certificates, exams) without a live backend. Not used unless
|
|
* `VITE_USE_MOCKS=true`.
|
|
*/
|
|
|
|
// ------------------------------------------------------------------ profile
|
|
|
|
export const mockPermissions: string[] = [
|
|
'can:View:own-profile',
|
|
'can:edit:own-profile',
|
|
'can:resubmit:license-application',
|
|
'can:upload:own-documents',
|
|
'can:View:own-documents',
|
|
'can:replace:own-documents',
|
|
'can:initiate:own-payment',
|
|
'can:View:own-payments',
|
|
'can:View:own-notifications',
|
|
'can:apply:seafarer-registration',
|
|
'can:add:own-sea-service',
|
|
'can:edit:own-sea-service',
|
|
'can:View:own-sea-service',
|
|
'can:upload:own-medical-certificate',
|
|
'can:View:own-medical-certificate',
|
|
'can:apply:seafarer-certificate',
|
|
'can:apply:exam',
|
|
'can:View:own-exam',
|
|
'can:View:own-certificates',
|
|
'can:apply:vessel-registration',
|
|
'can:View:own-vessels',
|
|
'can:report:own-vessel-incident',
|
|
'can:create:license-application',
|
|
'can:View:my-license-applications',
|
|
'can:update:license-application',
|
|
'can:submit:license-application',
|
|
];
|
|
|
|
export const mockProfile = {
|
|
id: 'profile-mock-001',
|
|
userId: 'user-mock-001',
|
|
professionId: 'profession-mock-001',
|
|
addressId: 'address-mock-001',
|
|
type: 'INDIVIDUAL',
|
|
firstName: 'Abebe',
|
|
middleName: 'Kebede',
|
|
lastName: 'Tesfaye',
|
|
gender: 'MALE',
|
|
dob: '1990-04-12',
|
|
pob: 'Addis Ababa',
|
|
maritalStatus: 'MARRIED',
|
|
isComplete: true,
|
|
seafarerNumber: 'ET-SF-2026-00147',
|
|
seafarerStatus: 'ACTIVE',
|
|
seafarerDepartment: 'DECK',
|
|
seafarerStatusReason: null,
|
|
user: {
|
|
id: 'user-mock-001',
|
|
email: 'abebe.tesfaye@example.et',
|
|
username: 'abebe.tesfaye',
|
|
phoneNumber: '+251911223344',
|
|
name: { am: 'አበበ ተስፋዬ', en: 'Abebe Tesfaye' },
|
|
status: 'ACTIVE',
|
|
sharepointId: null,
|
|
hasSetPassword: true,
|
|
hasFinishedRegistration: true,
|
|
hasFinishedDMSOnboarding: true,
|
|
isPhoneNumberVerified: true,
|
|
userType: 'PORTAL',
|
|
},
|
|
address: {
|
|
id: 'address-mock-001',
|
|
idType: 'NID',
|
|
idNumber: '1234567890123',
|
|
nationality: 'Ethiopia',
|
|
regionId: 'region-addis',
|
|
cityId: 'city-addis',
|
|
subCityId: 'subcity-bole',
|
|
woredaId: 'woreda-03',
|
|
kebeleId: null,
|
|
streetAddress: 'Bole Road',
|
|
houseNumber: '14',
|
|
primaryPhoneNumber: '+251911223344',
|
|
secondaryPhoneNumber: null,
|
|
email: 'abebe.tesfaye@example.et',
|
|
website: null,
|
|
postalAddress: null,
|
|
emergencyContactName: 'Selamawit Tesfaye',
|
|
emergencyContactPhone: '+251911998877',
|
|
emergencyContactRelation: 'Spouse',
|
|
isActive: true,
|
|
},
|
|
profession: {
|
|
id: 'profession-mock-001',
|
|
departmentId: 'department-deck',
|
|
name: { en: 'Deck Officer' },
|
|
description: { en: 'Deck department officer' },
|
|
isActive: true,
|
|
},
|
|
};
|
|
|
|
export const mockProfileMeResponse = {
|
|
profile: mockProfile,
|
|
completeness: 100,
|
|
missing: [] as string[],
|
|
permissions: mockPermissions,
|
|
};
|
|
|
|
// ------------------------------------------------------------------ vessels
|
|
|
|
export const mockVessels = [
|
|
{
|
|
id: 'vessel-mock-001',
|
|
registrationNumber: 'ET-VES-2025-000041',
|
|
name: 'MV Abay Queen',
|
|
category: 'INLAND_WATERWAY',
|
|
vesselType: 'Passenger Ferry',
|
|
imoNumber: '9876543',
|
|
hullNumber: 'HN-4471',
|
|
flagState: 'Ethiopia',
|
|
portOfRegistry: 'Bahir Dar',
|
|
grossTonnage: 420,
|
|
passengerCapacity: 120,
|
|
lengthMeters: 38.5,
|
|
yearBuilt: 2018,
|
|
engineType: 'Diesel',
|
|
enginePowerKw: 950,
|
|
numberOfEngines: 2,
|
|
hullMaterial: 'Steel',
|
|
ownerUserId: 'user-mock-001',
|
|
ownerProfileId: 'profile-mock-001',
|
|
ownerName: 'Abebe Tesfaye',
|
|
applicationId: 'app-vessel-approved-001',
|
|
licenseId: 'license-vessel-001',
|
|
status: 'REGISTERED',
|
|
statusReason: null,
|
|
statusChangedAt: null,
|
|
registeredAt: '2025-11-03T09:00:00.000Z',
|
|
},
|
|
{
|
|
id: 'vessel-mock-002',
|
|
registrationNumber: 'ET-VES-2024-000019',
|
|
name: 'MV Tana Star',
|
|
category: 'INLAND_WATERWAY',
|
|
vesselType: 'Cargo Vessel',
|
|
imoNumber: '9765432',
|
|
hullNumber: 'HN-2290',
|
|
flagState: 'Ethiopia',
|
|
portOfRegistry: 'Bahir Dar',
|
|
grossTonnage: 610,
|
|
passengerCapacity: null,
|
|
lengthMeters: 45.2,
|
|
yearBuilt: 2015,
|
|
engineType: 'Diesel',
|
|
enginePowerKw: 1200,
|
|
numberOfEngines: 2,
|
|
hullMaterial: 'Steel',
|
|
ownerUserId: 'user-mock-001',
|
|
ownerProfileId: 'profile-mock-001',
|
|
ownerName: 'Abebe Tesfaye',
|
|
applicationId: 'app-vessel-approved-002',
|
|
licenseId: 'license-vessel-002',
|
|
status: 'REGISTERED',
|
|
statusReason: null,
|
|
statusChangedAt: null,
|
|
registeredAt: '2024-06-18T09:00:00.000Z',
|
|
},
|
|
];
|
|
|
|
// -------------------------------------------------------------- applications
|
|
|
|
const nowIso = () => new Date().toISOString();
|
|
|
|
export const mockApplications: Record<string, any> = {
|
|
'app-vessel-approved-001': {
|
|
id: 'app-vessel-approved-001',
|
|
applicationNumber: 'VES-2025-000041',
|
|
licenseTypeId: 'license-type-vessel-registration',
|
|
licenseType: { id: 'license-type-vessel-registration', key: 'VESSEL_REGISTRATION', name: { en: 'Vessel Registration' } },
|
|
applicantUserId: 'user-mock-001',
|
|
kind: 'NEW',
|
|
status: 'CERTIFICATE_ISSUED',
|
|
assignedOfficerId: null,
|
|
claimedAt: null,
|
|
formData: { vesselDetails: { vesselName: 'MV Abay Queen' } },
|
|
companyName: null,
|
|
tradeName: null,
|
|
tinNumber: null,
|
|
businessAddress: null,
|
|
capitalAmountDeclared: null,
|
|
capitalAmountVerified: null,
|
|
adjustmentRound: 0,
|
|
submittedAt: '2025-10-20T08:00:00.000Z',
|
|
decidedAt: '2025-11-03T09:00:00.000Z',
|
|
rejectionReason: null,
|
|
feeAmount: '3500',
|
|
feeCurrency: 'ETB',
|
|
issuedLicenseId: 'license-vessel-001',
|
|
createdAt: '2025-10-15T08:00:00.000Z',
|
|
},
|
|
'app-vessel-approved-002': {
|
|
id: 'app-vessel-approved-002',
|
|
applicationNumber: 'VES-2024-000019',
|
|
licenseTypeId: 'license-type-vessel-registration',
|
|
licenseType: { id: 'license-type-vessel-registration', key: 'VESSEL_REGISTRATION', name: { en: 'Vessel Registration' } },
|
|
applicantUserId: 'user-mock-001',
|
|
kind: 'NEW',
|
|
status: 'CERTIFICATE_ISSUED',
|
|
assignedOfficerId: null,
|
|
claimedAt: null,
|
|
formData: { vesselDetails: { vesselName: 'MV Tana Star' } },
|
|
companyName: null,
|
|
tradeName: null,
|
|
tinNumber: null,
|
|
businessAddress: null,
|
|
capitalAmountDeclared: null,
|
|
capitalAmountVerified: null,
|
|
adjustmentRound: 0,
|
|
submittedAt: '2024-06-01T08:00:00.000Z',
|
|
decidedAt: '2024-06-18T09:00:00.000Z',
|
|
rejectionReason: null,
|
|
feeAmount: '3500',
|
|
feeCurrency: 'ETB',
|
|
issuedLicenseId: 'license-vessel-002',
|
|
createdAt: '2024-05-20T08:00:00.000Z',
|
|
},
|
|
'app-vessel-pending-003': {
|
|
id: 'app-vessel-pending-003',
|
|
applicationNumber: 'VES-2026-000123',
|
|
licenseTypeId: 'license-type-vessel-registration',
|
|
licenseType: { id: 'license-type-vessel-registration', key: 'VESSEL_REGISTRATION', name: { en: 'Vessel Registration' } },
|
|
applicantUserId: 'user-mock-001',
|
|
kind: 'NEW',
|
|
status: 'UNDER_REVIEW',
|
|
assignedOfficerId: 'officer-mock-001',
|
|
claimedAt: '2026-08-10T10:00:00.000Z',
|
|
formData: { vesselDetails: { vesselName: 'MV Zeway Pearl' } },
|
|
companyName: null,
|
|
tradeName: null,
|
|
tinNumber: null,
|
|
businessAddress: null,
|
|
capitalAmountDeclared: null,
|
|
capitalAmountVerified: null,
|
|
adjustmentRound: 0,
|
|
submittedAt: '2026-08-05T08:00:00.000Z',
|
|
decidedAt: null,
|
|
rejectionReason: null,
|
|
feeAmount: '3500',
|
|
feeCurrency: 'ETB',
|
|
issuedLicenseId: null,
|
|
createdAt: '2026-08-01T08:00:00.000Z',
|
|
},
|
|
'app-vessel-resubmit-004': {
|
|
id: 'app-vessel-resubmit-004',
|
|
applicationNumber: 'VES-2026-000098',
|
|
licenseTypeId: 'license-type-vessel-registration',
|
|
licenseType: { id: 'license-type-vessel-registration', key: 'VESSEL_REGISTRATION', name: { en: 'Vessel Registration' } },
|
|
applicantUserId: 'user-mock-001',
|
|
kind: 'NEW',
|
|
status: 'RESUBMIT_REQUIRED',
|
|
assignedOfficerId: 'officer-mock-001',
|
|
claimedAt: '2026-07-20T10:00:00.000Z',
|
|
formData: { vesselDetails: { vesselName: 'MV Koka Voyager' } },
|
|
companyName: null,
|
|
tradeName: null,
|
|
tinNumber: null,
|
|
businessAddress: null,
|
|
capitalAmountDeclared: null,
|
|
capitalAmountVerified: null,
|
|
adjustmentRound: 1,
|
|
submittedAt: '2026-07-15T08:00:00.000Z',
|
|
decidedAt: null,
|
|
rejectionReason: null,
|
|
feeAmount: '3500',
|
|
feeCurrency: 'ETB',
|
|
issuedLicenseId: null,
|
|
createdAt: '2026-07-10T08:00:00.000Z',
|
|
},
|
|
'app-seafarer-registered-005': {
|
|
id: 'app-seafarer-registered-005',
|
|
applicationNumber: 'SEA-2025-000512',
|
|
licenseTypeId: 'license-type-seafarer-registration',
|
|
licenseType: { id: 'license-type-seafarer-registration', key: 'SEAFARER_REGISTRATION', name: { en: 'Seafarer Registration' } },
|
|
applicantUserId: 'user-mock-001',
|
|
kind: 'NEW',
|
|
status: 'COMPLETED',
|
|
assignedOfficerId: null,
|
|
claimedAt: null,
|
|
formData: { account: { applicantName: 'Abebe Tesfaye' } },
|
|
companyName: null,
|
|
tradeName: null,
|
|
tinNumber: null,
|
|
businessAddress: null,
|
|
capitalAmountDeclared: null,
|
|
capitalAmountVerified: null,
|
|
adjustmentRound: 0,
|
|
submittedAt: '2025-09-01T08:00:00.000Z',
|
|
decidedAt: '2025-09-20T08:00:00.000Z',
|
|
rejectionReason: null,
|
|
feeAmount: '500',
|
|
feeCurrency: 'ETB',
|
|
issuedLicenseId: null,
|
|
createdAt: '2025-08-25T08:00:00.000Z',
|
|
},
|
|
'app-coc-issued-006': {
|
|
id: 'app-coc-issued-006',
|
|
applicationNumber: 'COC-2025-000321',
|
|
licenseTypeId: 'license-type-coc',
|
|
licenseType: { id: 'license-type-coc', key: 'CERTIFICATE_OF_COMPETENCY', name: { en: 'Certificate of Competency' } },
|
|
applicantUserId: 'user-mock-001',
|
|
kind: 'NEW',
|
|
status: 'CERTIFICATE_ISSUED',
|
|
assignedOfficerId: null,
|
|
claimedAt: null,
|
|
formData: { account: { applicantName: 'Abebe Tesfaye' } },
|
|
companyName: null,
|
|
tradeName: null,
|
|
tinNumber: null,
|
|
businessAddress: null,
|
|
capitalAmountDeclared: null,
|
|
capitalAmountVerified: null,
|
|
adjustmentRound: 0,
|
|
submittedAt: '2025-12-01T08:00:00.000Z',
|
|
decidedAt: '2026-01-10T08:00:00.000Z',
|
|
rejectionReason: null,
|
|
feeAmount: '1200',
|
|
feeCurrency: 'ETB',
|
|
issuedLicenseId: 'license-coc-001',
|
|
createdAt: '2025-11-20T08:00:00.000Z',
|
|
},
|
|
'app-coc-review-007': {
|
|
id: 'app-coc-review-007',
|
|
applicationNumber: 'COC-2026-000045',
|
|
licenseTypeId: 'license-type-coc',
|
|
licenseType: { id: 'license-type-coc', key: 'CERTIFICATE_OF_COMPETENCY', name: { en: 'Certificate of Competency' } },
|
|
applicantUserId: 'user-mock-001',
|
|
kind: 'RENEWAL',
|
|
status: 'ELIGIBILITY_APPROVED',
|
|
assignedOfficerId: 'officer-mock-002',
|
|
claimedAt: '2026-08-01T10:00:00.000Z',
|
|
formData: { account: { applicantName: 'Abebe Tesfaye' } },
|
|
companyName: null,
|
|
tradeName: null,
|
|
tinNumber: null,
|
|
businessAddress: null,
|
|
capitalAmountDeclared: null,
|
|
capitalAmountVerified: null,
|
|
adjustmentRound: 0,
|
|
submittedAt: '2026-07-28T08:00:00.000Z',
|
|
decidedAt: null,
|
|
rejectionReason: null,
|
|
feeAmount: '1200',
|
|
feeCurrency: 'ETB',
|
|
issuedLicenseId: null,
|
|
createdAt: '2026-07-25T08:00:00.000Z',
|
|
},
|
|
};
|
|
|
|
export const mockApplicationDetails: Record<string, any> = Object.fromEntries(
|
|
Object.entries(mockApplications).map(([id, application]) => [
|
|
id,
|
|
{
|
|
application,
|
|
staff: [],
|
|
attachments: [],
|
|
history: [
|
|
{
|
|
id: `hist-${id}-1`,
|
|
fromStatus: null,
|
|
toStatus: 'DRAFT',
|
|
event: 'created',
|
|
actorUserId: 'user-mock-001',
|
|
actorName: 'Abebe Tesfaye',
|
|
actorRole: 'APPLICANT',
|
|
remark: null,
|
|
metadata: null,
|
|
createdAt: application.createdAt,
|
|
},
|
|
{
|
|
id: `hist-${id}-2`,
|
|
fromStatus: 'DRAFT',
|
|
toStatus: 'SUBMITTED',
|
|
event: 'submitted',
|
|
actorUserId: 'user-mock-001',
|
|
actorName: 'Abebe Tesfaye',
|
|
actorRole: 'APPLICANT',
|
|
remark: null,
|
|
metadata: null,
|
|
createdAt: application.submittedAt ?? application.createdAt,
|
|
},
|
|
],
|
|
remarks:
|
|
application.status === 'RESUBMIT_REQUIRED'
|
|
? [
|
|
{
|
|
id: `remark-${id}-1`,
|
|
roundNumber: 1,
|
|
targetType: 'DOCUMENT',
|
|
targetKey: 'vesselOwnershipProof',
|
|
remark: 'Ownership document is blurred — please re-upload a clearer scan.',
|
|
isResolved: false,
|
|
resolvedAt: null,
|
|
createdAt: application.submittedAt ?? application.createdAt,
|
|
},
|
|
]
|
|
: [],
|
|
openRemarks:
|
|
application.status === 'RESUBMIT_REQUIRED'
|
|
? [
|
|
{
|
|
id: `remark-${id}-1`,
|
|
roundNumber: 1,
|
|
targetType: 'DOCUMENT',
|
|
targetKey: 'vesselOwnershipProof',
|
|
remark: 'Ownership document is blurred — please re-upload a clearer scan.',
|
|
isResolved: false,
|
|
resolvedAt: null,
|
|
createdAt: application.submittedAt ?? application.createdAt,
|
|
},
|
|
]
|
|
: [],
|
|
availableEvents: [],
|
|
},
|
|
]),
|
|
);
|
|
|
|
// ----------------------------------------------------------------- licenses
|
|
|
|
export const mockLicenses = [
|
|
{
|
|
id: 'license-vessel-001',
|
|
certificateNumber: 'ET-VES-CERT-2025-041',
|
|
licenseTypeId: 'license-type-vessel-registration',
|
|
licenseType: { id: 'license-type-vessel-registration', key: 'VESSEL_REGISTRATION', name: { en: 'Vessel Registration' } },
|
|
applicationId: 'app-vessel-approved-001',
|
|
companyName: null,
|
|
tinNumber: null,
|
|
issueDate: '2025-11-03',
|
|
expiryDate: '2027-11-03',
|
|
status: 'ACTIVE',
|
|
daysUntilExpiry: 445,
|
|
renewable: false,
|
|
verificationCode: 'VESQR001',
|
|
certificateFileKey: 'certs/vessel-001.pdf',
|
|
},
|
|
{
|
|
id: 'license-vessel-002',
|
|
certificateNumber: 'ET-VES-CERT-2024-019',
|
|
licenseTypeId: 'license-type-vessel-registration',
|
|
licenseType: { id: 'license-type-vessel-registration', key: 'VESSEL_REGISTRATION', name: { en: 'Vessel Registration' } },
|
|
applicationId: 'app-vessel-approved-002',
|
|
companyName: null,
|
|
tinNumber: null,
|
|
issueDate: '2024-06-18',
|
|
expiryDate: '2026-06-18',
|
|
status: 'ACTIVE',
|
|
daysUntilExpiry: 308,
|
|
renewable: true,
|
|
verificationCode: 'VESQR002',
|
|
certificateFileKey: 'certs/vessel-002.pdf',
|
|
},
|
|
{
|
|
id: 'license-coc-001',
|
|
certificateNumber: 'ET-COC-2026-000321',
|
|
licenseTypeId: 'license-type-coc',
|
|
licenseType: { id: 'license-type-coc', key: 'CERTIFICATE_OF_COMPETENCY', name: { en: 'Certificate of Competency' } },
|
|
applicationId: 'app-coc-issued-006',
|
|
companyName: null,
|
|
tinNumber: null,
|
|
issueDate: '2026-01-10',
|
|
expiryDate: '2031-01-10',
|
|
status: 'ACTIVE',
|
|
daysUntilExpiry: 1610,
|
|
renewable: false,
|
|
verificationCode: 'COCQR001',
|
|
certificateFileKey: 'certs/coc-001.pdf',
|
|
},
|
|
];
|
|
|
|
// -------------------------------------------------------------------- exams
|
|
|
|
export const mockOpenExams = [
|
|
{
|
|
id: 'exam-open-001',
|
|
title: { en: 'Officer of the Watch — Written Examination' },
|
|
date: '2026-09-15T09:00:00.000Z',
|
|
venue: 'EMA Headquarters, Addis Ababa',
|
|
status: 'OPEN',
|
|
certification: { name: { en: 'Certificate of Competency (Deck)' } },
|
|
},
|
|
{
|
|
id: 'exam-open-002',
|
|
title: { en: 'Marine Engineering Practical Assessment' },
|
|
date: '2026-10-02T09:00:00.000Z',
|
|
venue: 'Bahir Dar Maritime Training Center',
|
|
status: 'OPEN',
|
|
certification: { name: { en: 'Certificate of Competency (Engine)' } },
|
|
},
|
|
];
|
|
|
|
export const mockMyExamRegistrations = [
|
|
{
|
|
id: 'reg-mock-001',
|
|
admissionNumber: 'ADM-2026-000876',
|
|
createdAt: '2026-08-01T08:00:00.000Z',
|
|
kind: 'NEW',
|
|
attemptNumber: 1,
|
|
attendanceStatus: 'REGISTERED',
|
|
exam: mockOpenExams[0],
|
|
},
|
|
];
|
|
|
|
export const mockMyExamResults = [
|
|
{
|
|
id: 'result-mock-001',
|
|
totalScore: 82,
|
|
status: 'PASSED',
|
|
publishedAt: '2026-03-20T08:00:00.000Z',
|
|
remark: { en: 'Strong performance in navigation and safety.' },
|
|
exam: {
|
|
id: 'exam-past-001',
|
|
title: { en: 'Officer of the Watch — Written Examination' },
|
|
date: '2026-03-10T09:00:00.000Z',
|
|
venue: 'EMA Headquarters, Addis Ababa',
|
|
status: 'CLOSED',
|
|
certification: { name: { en: 'Certificate of Competency (Deck)' } },
|
|
},
|
|
},
|
|
];
|
|
|
|
export const mockMyExamAppeals: any[] = [];
|
|
|
|
// ------------------------------------------------------------ notifications
|
|
|
|
export const mockNotifications = {
|
|
count: 2,
|
|
items: [
|
|
{
|
|
id: 'notif-mock-001',
|
|
subject: { en: 'Application under review' },
|
|
content: { en: 'Your vessel registration VES-2026-000123 is now under review.' },
|
|
isSeen: false,
|
|
itemId: 'app-vessel-pending-003',
|
|
itemType: 'LicenseApplication',
|
|
metadata: null,
|
|
createdAt: '2026-08-05T09:00:00.000Z',
|
|
},
|
|
{
|
|
id: 'notif-mock-002',
|
|
subject: { en: 'Corrections requested' },
|
|
content: { en: 'Please resubmit documents for VES-2026-000098.' },
|
|
isSeen: true,
|
|
itemId: 'app-vessel-resubmit-004',
|
|
itemType: 'LicenseApplication',
|
|
metadata: null,
|
|
createdAt: '2026-07-21T09:00:00.000Z',
|
|
},
|
|
],
|
|
};
|
|
|
|
// ------------------------------------------------------------ license types
|
|
|
|
export const mockLicenseTypeRequirements: Record<string, any> = {
|
|
VESSEL_REGISTRATION: {
|
|
licenseType: {
|
|
id: 'license-type-vessel-registration',
|
|
key: 'VESSEL_REGISTRATION',
|
|
name: { en: 'Vessel Registration' },
|
|
description: { en: 'Register a vessel with the Ethiopian Maritime Authority.' },
|
|
category: 'MARITIME_PERSONNEL',
|
|
certificatePrefix: 'VES',
|
|
feeNewApplication: 3500,
|
|
feeRenewal: 2000,
|
|
feeCurrency: 'ETB',
|
|
capitalThreshold: null,
|
|
validityMonths: 24,
|
|
slaHours: 240,
|
|
inspectionRequired: true,
|
|
issuesCertificate: true,
|
|
renewalEnabled: true,
|
|
requiresOperatorMode: false,
|
|
formSchema: {
|
|
sections: [
|
|
{
|
|
key: 'vesselDetails',
|
|
title: { en: 'Vessel Details' },
|
|
fields: [
|
|
{ key: 'vesselName', label: { en: 'Vessel Name' }, type: 'TEXT', required: true, sortOrder: 1 },
|
|
{ key: 'vesselType', label: { en: 'Vessel Type' }, type: 'TEXT', required: true, sortOrder: 2 },
|
|
{ key: 'grossTonnage', label: { en: 'Gross Tonnage' }, type: 'NUMBER', required: true, sortOrder: 3 },
|
|
],
|
|
sortOrder: 1,
|
|
},
|
|
{
|
|
key: 'ownerDetails',
|
|
title: { en: 'Owner Details' },
|
|
fields: [
|
|
{ key: 'nationality', label: { en: 'Nationality' }, type: 'TEXT', required: true, sortOrder: 1 },
|
|
{ key: 'idNumber', label: { en: 'National ID (Fayda) Number' }, type: 'TEXT', required: true, sortOrder: 2 },
|
|
],
|
|
sortOrder: 2,
|
|
},
|
|
],
|
|
},
|
|
isActive: true,
|
|
sortOrder: 1,
|
|
},
|
|
applicationKind: 'NEW',
|
|
fee: 3500,
|
|
feeCurrency: 'ETB',
|
|
documentRequirements: [
|
|
{
|
|
id: 'doc-vessel-ownership',
|
|
key: 'vesselOwnershipProof',
|
|
name: { en: 'Proof of Ownership' },
|
|
applicationKind: 'NEW',
|
|
mode: 'ALWAYS',
|
|
allowedMimeTypes: ['application/pdf', 'image/jpeg', 'image/png'],
|
|
maxSizeMb: 10,
|
|
requiresValidityDates: false,
|
|
sortOrder: 1,
|
|
},
|
|
],
|
|
staffRoleRequirements: [],
|
|
},
|
|
SEAFARER_REGISTRATION: {
|
|
licenseType: {
|
|
id: 'license-type-seafarer-registration',
|
|
key: 'SEAFARER_REGISTRATION',
|
|
name: { en: 'Seafarer Registration' },
|
|
description: { en: 'Register as a seafarer with the Ethiopian Maritime Authority.' },
|
|
category: 'MARITIME_PERSONNEL',
|
|
certificatePrefix: 'SEA',
|
|
feeNewApplication: 500,
|
|
feeRenewal: null,
|
|
feeCurrency: 'ETB',
|
|
capitalThreshold: null,
|
|
validityMonths: 0,
|
|
slaHours: 120,
|
|
inspectionRequired: false,
|
|
issuesCertificate: false,
|
|
renewalEnabled: false,
|
|
requiresOperatorMode: false,
|
|
formSchema: {
|
|
sections: [
|
|
{
|
|
key: 'personalDetails',
|
|
title: { en: 'Personal Details' },
|
|
fields: [
|
|
{ key: 'applicantName', label: { en: 'Full Name' }, type: 'TEXT', required: true, sortOrder: 1 },
|
|
{ key: 'department', label: { en: 'Department' }, type: 'SELECT', required: true, options: [
|
|
{ value: 'DECK', label: { en: 'Deck' } },
|
|
{ value: 'ENGINE', label: { en: 'Engine' } },
|
|
{ value: 'CATERING', label: { en: 'Catering' } },
|
|
], sortOrder: 2 },
|
|
],
|
|
sortOrder: 1,
|
|
},
|
|
],
|
|
},
|
|
isActive: true,
|
|
sortOrder: 2,
|
|
},
|
|
applicationKind: 'NEW',
|
|
fee: 500,
|
|
feeCurrency: 'ETB',
|
|
documentRequirements: [
|
|
{
|
|
id: 'doc-seafarer-photo',
|
|
key: 'passportPhoto',
|
|
name: { en: 'Passport-size Photograph' },
|
|
applicationKind: 'NEW',
|
|
mode: 'ALWAYS',
|
|
allowedMimeTypes: ['image/jpeg', 'image/png'],
|
|
maxSizeMb: 5,
|
|
requiresValidityDates: false,
|
|
sortOrder: 1,
|
|
},
|
|
],
|
|
staffRoleRequirements: [],
|
|
},
|
|
CERTIFICATE_OF_COMPETENCY: {
|
|
licenseType: {
|
|
id: 'license-type-coc',
|
|
key: 'CERTIFICATE_OF_COMPETENCY',
|
|
name: { en: 'Certificate of Competency' },
|
|
description: { en: 'Apply for a Certificate of Competency.' },
|
|
category: 'MARITIME_PERSONNEL',
|
|
certificatePrefix: 'COC',
|
|
feeNewApplication: 1200,
|
|
feeRenewal: 800,
|
|
feeCurrency: 'ETB',
|
|
capitalThreshold: null,
|
|
validityMonths: 60,
|
|
slaHours: 168,
|
|
inspectionRequired: false,
|
|
issuesCertificate: true,
|
|
renewalEnabled: true,
|
|
requiresOperatorMode: false,
|
|
formSchema: {
|
|
sections: [
|
|
{
|
|
key: 'applicantDetails',
|
|
title: { en: 'Applicant Details' },
|
|
fields: [
|
|
{ key: 'applicantName', label: { en: 'Full Name' }, type: 'TEXT', required: true, sortOrder: 1 },
|
|
{ key: 'rank', label: { en: 'Rank Applied For' }, type: 'TEXT', required: true, sortOrder: 2 },
|
|
],
|
|
sortOrder: 1,
|
|
},
|
|
],
|
|
},
|
|
isActive: true,
|
|
sortOrder: 3,
|
|
},
|
|
applicationKind: 'NEW',
|
|
fee: 1200,
|
|
feeCurrency: 'ETB',
|
|
documentRequirements: [
|
|
{
|
|
id: 'doc-coc-seatime',
|
|
key: 'seaTimeRecord',
|
|
name: { en: 'Sea Time Record' },
|
|
applicationKind: 'NEW',
|
|
mode: 'ALWAYS',
|
|
allowedMimeTypes: ['application/pdf'],
|
|
maxSizeMb: 10,
|
|
requiresValidityDates: false,
|
|
sortOrder: 1,
|
|
},
|
|
],
|
|
staffRoleRequirements: [],
|
|
},
|
|
};
|
|
|
|
export const mockLicenseTypes = Object.values(mockLicenseTypeRequirements).map(
|
|
(r) => r.licenseType,
|
|
);
|