diff --git a/apps/portal/src/app/features/certificates/pages/CoCApplicationPage.tsx b/apps/portal/src/app/features/certificates/pages/CoCApplicationPage.tsx
index 7eacb0124..087aae11d 100644
--- a/apps/portal/src/app/features/certificates/pages/CoCApplicationPage.tsx
+++ b/apps/portal/src/app/features/certificates/pages/CoCApplicationPage.tsx
@@ -1,5 +1,6 @@
import { useState } from 'react';
import { useNavigate } from 'react-router-dom';
+import { AmharicDatePicker } from '../../../components/AmharicDatePicker';
import {
Alert,
Badge,
@@ -999,11 +1000,10 @@ export function CoCApplicationPage() {
size="sm"
required
/>
-
setPaymentDate(e.currentTarget.value)}
+ onChange={setPaymentDate}
size="sm"
required
/>
diff --git a/apps/portal/src/app/features/endorsement/pages/EndorsementPage.tsx b/apps/portal/src/app/features/endorsement/pages/EndorsementPage.tsx
index 635c05c73..8b601eb84 100644
--- a/apps/portal/src/app/features/endorsement/pages/EndorsementPage.tsx
+++ b/apps/portal/src/app/features/endorsement/pages/EndorsementPage.tsx
@@ -1,6 +1,7 @@
import { useState } from 'react';
import { useNavigate } from 'react-router-dom';
import { CountrySelect, getCountryName } from '@ema-platform/ui';
+import { AmharicDatePicker } from '../../../components/AmharicDatePicker';
import {
Alert,
Badge,
@@ -133,8 +134,8 @@ function ApplicationWizard({ onDone }: { onDone: () => void }) {
setIssuer(e.currentTarget.value)} required />
setCocType(e.currentTarget.value)} required />
- setIssueDate(e.currentTarget.value)} required />
- setExpiryDate(e.currentTarget.value)} required />
+
+
)}
diff --git a/apps/portal/src/app/features/joint-investment-license/pages/JointInvestmentLicenseApplicationPage.tsx b/apps/portal/src/app/features/joint-investment-license/pages/JointInvestmentLicenseApplicationPage.tsx
index d1ada89b1..100b08ed2 100644
--- a/apps/portal/src/app/features/joint-investment-license/pages/JointInvestmentLicenseApplicationPage.tsx
+++ b/apps/portal/src/app/features/joint-investment-license/pages/JointInvestmentLicenseApplicationPage.tsx
@@ -1,6 +1,7 @@
import { useRef, useState } from 'react';
import { useNavigate } from 'react-router-dom';
import { useApiMutation } from '@ema-platform/api';
+import { AmharicDatePicker } from '../../../components/AmharicDatePicker';
import {
Alert,
Badge,
@@ -447,7 +448,7 @@ export function JointInvestmentLicenseApplicationPage() {
setBudgetYear(e.currentTarget.value)} />
- setLicenseValidityDate(e.currentTarget.value)} />
+
)}
diff --git a/apps/portal/src/app/features/medical/pages/MedicalCertificatePage.tsx b/apps/portal/src/app/features/medical/pages/MedicalCertificatePage.tsx
index dbf0c9f31..ec1b41b8f 100644
--- a/apps/portal/src/app/features/medical/pages/MedicalCertificatePage.tsx
+++ b/apps/portal/src/app/features/medical/pages/MedicalCertificatePage.tsx
@@ -1,4 +1,5 @@
import { useRef, useState } from 'react';
+import { AmharicDatePicker } from '../../../components/AmharicDatePicker';
import {
Alert,
Badge,
@@ -224,18 +225,16 @@ export function MedicalCertificatePage() {
size="sm"
/>
- setIssuedDate(e.currentTarget.value)}
+ onChange={setIssuedDate}
size="sm"
/>
- setExpiryDate(e.currentTarget.value)}
+ onChange={setExpiryDate}
size="sm"
/>
diff --git a/apps/portal/src/app/features/mto-license/pages/MtoLicenseApplicationPage.tsx b/apps/portal/src/app/features/mto-license/pages/MtoLicenseApplicationPage.tsx
index bcf77c176..1d6ac64f8 100644
--- a/apps/portal/src/app/features/mto-license/pages/MtoLicenseApplicationPage.tsx
+++ b/apps/portal/src/app/features/mto-license/pages/MtoLicenseApplicationPage.tsx
@@ -1,6 +1,7 @@
import { useRef, useState } from 'react';
import { useNavigate } from 'react-router-dom';
import { useApiMutation } from '@ema-platform/api';
+import { AmharicDatePicker } from '../../../components/AmharicDatePicker';
import {
Alert,
Badge,
@@ -572,8 +573,8 @@ export function MtoLicenseApplicationPage() {
- setInsuranceValidityDate(e.currentTarget.value)} />
- setBondValidityDate(e.currentTarget.value)} />
+
+
)}
diff --git a/apps/portal/src/app/features/profile/components/ProfileFormContent.tsx b/apps/portal/src/app/features/profile/components/ProfileFormContent.tsx
index 5ed92dd72..bf9b1aee1 100644
--- a/apps/portal/src/app/features/profile/components/ProfileFormContent.tsx
+++ b/apps/portal/src/app/features/profile/components/ProfileFormContent.tsx
@@ -1,6 +1,7 @@
import { Loader, Select, SimpleGrid, TextInput } from '@mantine/core';
import type { FieldErrors, UseFormRegister, UseFormSetValue, UseFormWatch, UseFormTrigger } from 'react-hook-form';
import { z } from 'zod';
+import { AmharicDatePicker } from '../../../components/AmharicDatePicker';
export const profileSchema = z.object({
professionId: z.string().min(1, 'Select your profession'),
@@ -86,11 +87,13 @@ export function ProfileFormContent({
onBlur={() => trigger('gender')}
name="gender"
/>
- setValue('dob', val, { shouldValidate: true })}
+ onBlur={() => trigger('dob')}
+ name="dob"
error={errors.dob?.message}
/>
void }) {
+ const [issueDate, setIssueDate] = useState('');
+ const [expiryDate, setExpiryDate] = useState('');
+
return (
@@ -471,8 +475,8 @@ function AddTrainingModal({ opened, onClose }: { opened: boolean; onClose: () =>
-
-
+
+
@@ -485,14 +489,17 @@ function AddTrainingModal({ opened, onClose }: { opened: boolean; onClose: () =>
}
function AddMedicalModal({ opened, onClose }: { opened: boolean; onClose: () => void }) {
+ const [issueDate, setIssueDate] = useState('');
+ const [expiryDate, setExpiryDate] = useState('');
+
return (
-
-
+
+
@@ -507,6 +514,8 @@ function AddMedicalModal({ opened, onClose }: { opened: boolean; onClose: () =>
function AddSeaServiceModal({ opened, onClose }: { opened: boolean; onClose: () => void }) {
const [flag, setFlag] = useState(null);
+ const [fromDate, setFromDate] = useState('');
+ const [toDate, setToDate] = useState('');
return (
@@ -520,8 +529,8 @@ function AddSeaServiceModal({ opened, onClose }: { opened: boolean; onClose: ()
-
-
+
+
@@ -534,6 +543,9 @@ function AddSeaServiceModal({ opened, onClose }: { opened: boolean; onClose: ()
}
function AddCertModal({ opened, onClose }: { opened: boolean; onClose: () => void }) {
+ const [issueDate, setIssueDate] = useState('');
+ const [expiryDate, setExpiryDate] = useState('');
+
return (
@@ -544,8 +556,8 @@ function AddCertModal({ opened, onClose }: { opened: boolean; onClose: () => voi
-
-
+
+
diff --git a/apps/portal/src/app/features/seafarer/pages/SeafarerRegistrationPage.tsx b/apps/portal/src/app/features/seafarer/pages/SeafarerRegistrationPage.tsx
index 077b23cc6..e849275af 100644
--- a/apps/portal/src/app/features/seafarer/pages/SeafarerRegistrationPage.tsx
+++ b/apps/portal/src/app/features/seafarer/pages/SeafarerRegistrationPage.tsx
@@ -264,7 +264,7 @@ export function SeafarerRegistrationPage() {
const [middleName, setMiddleName] = useState({ en: '', am: '' });
const [lastName, setLastName] = useState({ en: '', am: '' });
const [gender, setGender] = useState(null);
- const [dob, setDob] = useState(null);
+ const [dob, setDob] = useState('');
const [placeOfBirth, setPlaceOfBirth] = useState('');
const [nationality, setNationality] = useState('Ethiopian');
const [maritalStatus, setMaritalStatus] = useState(null);
@@ -307,7 +307,7 @@ export function SeafarerRegistrationPage() {
setSubmitting(true);
try {
const result = await submitSeafarerRegistration({
- personalInfo: { firstName, middleName, lastName, gender, dob: dob?.toISOString().split('T')[0] ?? '', placeOfBirth, nationality, maritalStatus, nationalIdNumber, passportNumber, passportExpiry },
+ personalInfo: { firstName, middleName, lastName, gender, dob, placeOfBirth, nationality, maritalStatus, nationalIdNumber, passportNumber, passportExpiry },
contactDetails: { mobile, email, locationId, permanentAddress, currentAddress, emergency: { name: emergencyName, relationship: emergencyRel, phone: emergencyPhone } },
documents: Object.fromEntries(Object.entries(files).map(([k, v]) => [k, v?.name ?? null])),
});
@@ -365,7 +365,7 @@ export function SeafarerRegistrationPage() {
setNationalIdNumber(e.currentTarget.value)} />
setPassportNumber(e.currentTarget.value)} />
- setPassportExpiry(e.currentTarget.value)} />
+
}>
@@ -458,7 +458,7 @@ export function SeafarerRegistrationPage() {
-
+
diff --git a/apps/portal/src/app/features/seaman-book/pages/SeamanBookApplicationPage.tsx b/apps/portal/src/app/features/seaman-book/pages/SeamanBookApplicationPage.tsx
index d43bc79ee..afde671f6 100644
--- a/apps/portal/src/app/features/seaman-book/pages/SeamanBookApplicationPage.tsx
+++ b/apps/portal/src/app/features/seaman-book/pages/SeamanBookApplicationPage.tsx
@@ -1,4 +1,5 @@
import { useRef, useState } from "react";
+import { AmharicDatePicker } from "../../../components/AmharicDatePicker";
import {
Alert,
Badge,
@@ -315,20 +316,18 @@ function BSTCard({
onChange={(e) => onIssuer(e.currentTarget.value)}
/>
0 ? 2 : 1} spacing="xs">
- onIssueDate(e.currentTarget.value)}
+ onChange={onIssueDate}
/>
{slot.refreshYears > 0 && (
- onExpiryDate(e.currentTarget.value)}
+ onChange={onExpiryDate}
/>
)}
@@ -665,19 +664,17 @@ export function SeamanBookApplicationPage() {
/>
- setMedIssueDate(e.currentTarget.value)}
+ onChange={setMedIssueDate}
/>
- setMedExpiryDate(e.currentTarget.value)}
+ onChange={setMedExpiryDate}
/>
@@ -1006,12 +1003,11 @@ export function SeamanBookApplicationPage() {
value={paymentRef}
onChange={(e) => setPaymentRef(e.currentTarget.value)}
/>
- setPaymentDate(e.currentTarget.value)}
+ onChange={setPaymentDate}
/>
>
diff --git a/apps/portal/src/app/features/shipping-agent-license/pages/ShippingAgentLicenseApplicationPage.tsx b/apps/portal/src/app/features/shipping-agent-license/pages/ShippingAgentLicenseApplicationPage.tsx
index d22de3fa7..5d2825987 100644
--- a/apps/portal/src/app/features/shipping-agent-license/pages/ShippingAgentLicenseApplicationPage.tsx
+++ b/apps/portal/src/app/features/shipping-agent-license/pages/ShippingAgentLicenseApplicationPage.tsx
@@ -1,6 +1,7 @@
import { useRef, useState } from 'react';
import { useNavigate } from 'react-router-dom';
import { useApiMutation } from '@ema-platform/api';
+import { AmharicDatePicker } from '../../../components/AmharicDatePicker';
import {
Alert,
Badge,
@@ -324,8 +325,8 @@ export function ShippingAgentLicenseApplicationPage() {
setShippingCompanyName(e.currentTarget.value)} />
setAgreementRefNumber(e.currentTarget.value)} />
- setAgreementStartDate(e.currentTarget.value)} />
- setAgreementEndDate(e.currentTarget.value)} />
+
+
)}
diff --git a/apps/portal/src/app/features/waiver/pages/WaiverApplicationPage.tsx b/apps/portal/src/app/features/waiver/pages/WaiverApplicationPage.tsx
index 74009b75f..396a10a87 100644
--- a/apps/portal/src/app/features/waiver/pages/WaiverApplicationPage.tsx
+++ b/apps/portal/src/app/features/waiver/pages/WaiverApplicationPage.tsx
@@ -1,6 +1,7 @@
import { useRef, useState } from 'react';
import { useNavigate } from 'react-router-dom';
import { useApiMutation } from '@ema-platform/api';
+import { AmharicDatePicker } from '../../../components/AmharicDatePicker';
import {
Alert,
Badge,
@@ -372,7 +373,7 @@ export function WaiverApplicationPage() {
setInvoiceNumber(e.currentTarget.value)} />
- setInvoiceDate(e.currentTarget.value)} />
+
@@ -393,10 +394,10 @@ export function WaiverApplicationPage() {
setCarrierName(e.currentTarget.value)} />
setBillOfLadingNumber(e.currentTarget.value)} />
{isPreWaiver && (
- setEstimatedArrivalDate(e.currentTarget.value)} />
+
)}
{isPostWaiver && (
- setActualArrivalDate(e.currentTarget.value)} />
+
)}
diff --git a/apps/portal/src/app/i18n/locales/am.ts b/apps/portal/src/app/i18n/locales/am.ts
index a23b420d6..26f8988b8 100644
--- a/apps/portal/src/app/i18n/locales/am.ts
+++ b/apps/portal/src/app/i18n/locales/am.ts
@@ -81,6 +81,7 @@ export const am: Translations = {
learnMore: 'ተጨማሪ ይወቁ',
toggleTheme: 'ብርሃን / ጨለማ ገጽታ ቀይር',
welcome: 'እንኳን ደህና መጡ',
+ switchCalendar: 'የቀን መቁጠሪያ ዓይነት ቀይር',
},
auth: {
diff --git a/apps/portal/src/app/i18n/locales/en.ts b/apps/portal/src/app/i18n/locales/en.ts
index 9ddbc3079..b7582f303 100644
--- a/apps/portal/src/app/i18n/locales/en.ts
+++ b/apps/portal/src/app/i18n/locales/en.ts
@@ -79,6 +79,7 @@ export const en = {
learnMore: 'Learn more',
toggleTheme: 'Toggle light / dark mode',
welcome: 'Welcome',
+ switchCalendar: 'Switch calendar type',
},
auth: {
diff --git a/package-lock.json b/package-lock.json
index 898069397..fde006f96 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -25,6 +25,7 @@
"country-flag-icons": "^1.6.20",
"date-fns": "^4.1.0",
"dayjs": "^1.11.20",
+ "ethiopian-calendar-date-converter": "^2.1.6",
"i18n-iso-countries": "^7.14.0",
"i18next": "^25.6.0",
"js-cookie": "^3.0.8",
@@ -2043,7 +2044,7 @@
"version": "1.10.0",
"resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.10.0.tgz",
"integrity": "sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw==",
- "devOptional": true,
+ "dev": true,
"license": "MIT",
"dependencies": {
"@emnapi/wasi-threads": "1.2.1",
@@ -2054,7 +2055,7 @@
"version": "1.10.0",
"resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.10.0.tgz",
"integrity": "sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==",
- "devOptional": true,
+ "dev": true,
"license": "MIT",
"dependencies": {
"tslib": "^2.4.0"
@@ -2064,7 +2065,7 @@
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.1.tgz",
"integrity": "sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==",
- "devOptional": true,
+ "dev": true,
"license": "MIT",
"dependencies": {
"tslib": "^2.4.0"
@@ -4133,6 +4134,7 @@
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.0.7.tgz",
"integrity": "sha512-SeDnOO0Tk7Okiq6DbXmmBODgOAb9dp9gjlphokTUxmt8U3liIP1ZsozBahH69j/RJv+Rfs6IwUKHTgQYJ/HBAw==",
+ "dev": true,
"license": "MIT",
"optional": true,
"dependencies": {
@@ -8403,6 +8405,66 @@
"node": ">=14.0.0"
}
},
+ "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/core": {
+ "version": "1.10.0",
+ "inBundle": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "@emnapi/wasi-threads": "1.2.1",
+ "tslib": "^2.4.0"
+ }
+ },
+ "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/runtime": {
+ "version": "1.10.0",
+ "inBundle": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "tslib": "^2.4.0"
+ }
+ },
+ "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/wasi-threads": {
+ "version": "1.2.1",
+ "inBundle": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "tslib": "^2.4.0"
+ }
+ },
+ "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@napi-rs/wasm-runtime": {
+ "version": "1.1.4",
+ "inBundle": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "@tybys/wasm-util": "^0.10.1"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/Brooooooklyn"
+ },
+ "peerDependencies": {
+ "@emnapi/core": "^1.7.1",
+ "@emnapi/runtime": "^1.7.1"
+ }
+ },
+ "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@tybys/wasm-util": {
+ "version": "0.10.2",
+ "inBundle": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "tslib": "^2.4.0"
+ }
+ },
+ "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/tslib": {
+ "version": "2.8.1",
+ "inBundle": true,
+ "license": "0BSD",
+ "optional": true
+ },
"node_modules/@tailwindcss/oxide-win32-arm64-msvc": {
"version": "4.3.1",
"resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.3.1.tgz",
@@ -8950,6 +9012,7 @@
"version": "0.10.2",
"resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.2.tgz",
"integrity": "sha512-RoBvJ2X0wuKlWFIjrwffGw1IqZHKQqzIchKaadZZfnNpsAYp2mM0h36JtPCjNDAHGgYez/15uMBpfGwchhiMgg==",
+ "dev": true,
"license": "MIT",
"optional": true,
"dependencies": {
diff --git a/package.json b/package.json
index e140c15bc..752aad979 100644
--- a/package.json
+++ b/package.json
@@ -30,6 +30,7 @@
"country-flag-icons": "^1.6.20",
"date-fns": "^4.1.0",
"dayjs": "^1.11.20",
+ "ethiopian-calendar-date-converter": "^2.1.6",
"i18n-iso-countries": "^7.14.0",
"i18next": "^25.6.0",
"js-cookie": "^3.0.8",