added bilingual input field for both amharic and english

This commit is contained in:
mengstabketemaw
2026-06-16 17:19:55 +03:00
parent 56bf28b583
commit 36234a2948
2 changed files with 88 additions and 10 deletions

View File

@@ -0,0 +1,76 @@
import { useState } from 'react';
import {
TextInput,
UnstyledButton,
rem,
type TextInputProps,
} from '@mantine/core';
export interface BilingualValue {
en: string;
am: string;
}
interface BilingualInputProps
extends Omit<TextInputProps, 'value' | 'onChange' | 'rightSection' | 'rightSectionWidth'> {
value: BilingualValue;
onChange: (value: BilingualValue) => void;
}
export function BilingualInput({
label,
value,
onChange,
required,
placeholder,
...rest
}: BilingualInputProps) {
const [lang, setLang] = useState<'en' | 'am'>('en');
const toggle = () => setLang((l) => (l === 'en' ? 'am' : 'en'));
return (
<TextInput
label={label}
required={required}
placeholder={placeholder ?? (lang === 'en' ? 'Enter in English' : 'በአማርኛ ያስገቡ')}
value={value[lang]}
onChange={(e) => onChange({ ...value, [lang]: e.currentTarget.value })}
rightSection={
<UnstyledButton
onClick={toggle}
aria-label={`Switch to ${lang === 'en' ? 'Amharic' : 'English'}`}
style={{
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
width: rem(28),
height: rem(20),
borderRadius: rem(4),
fontSize: rem(10),
fontWeight: 700,
letterSpacing: '0.05em',
background:
lang === 'en'
? 'var(--mantine-color-blue-1)'
: 'var(--mantine-color-teal-1)',
color:
lang === 'en'
? 'var(--mantine-color-blue-7)'
: 'var(--mantine-color-teal-7)',
cursor: 'pointer',
transition: 'background 150ms ease',
}}
>
{lang === 'en' ? 'EN' : 'AM'}
</UnstyledButton>
}
styles={{
input: {
paddingRight: rem(42),
},
}}
{...rest}
/>
);
}

View File

@@ -34,6 +34,8 @@ import {
} from '@tabler/icons-react';
import { useNavigate } from 'react-router-dom';
import { notify } from '@ema-platform/ui';
import { BilingualInput } from '../../../components/BilingualInput';
import type { BilingualValue } from '../../../components/BilingualInput';
// ---------------------------------------------------------------------------
// Dummy API
@@ -261,9 +263,9 @@ export function SeafarerRegistrationPage() {
const [submitting, setSubmitting] = useState(false);
// Step 1 — Personal Information
const [firstName, setFirstName] = useState('');
const [middleName, setMiddleName] = useState('');
const [lastName, setLastName] = useState('');
const [firstName, setFirstName] = useState<BilingualValue>({ en: '', am: '' });
const [middleName, setMiddleName] = useState<BilingualValue>({ en: '', am: '' });
const [lastName, setLastName] = useState<BilingualValue>({ en: '', am: '' });
const [gender, setGender] = useState<string | null>(null);
const [dob, setDob] = useState('');
const [placeOfBirth, setPlaceOfBirth] = useState('');
@@ -293,7 +295,7 @@ export function SeafarerRegistrationPage() {
setFiles((prev) => ({ ...prev, [key]: f }));
const canNext = () => {
if (active === 0) return !!firstName.trim() && !!lastName.trim() && !!gender && !!dob && !!placeOfBirth && !!nationality && !!nationalIdNumber.trim();
if (active === 0) return !!firstName.en.trim() && !!lastName.en.trim() && !!gender && !!dob && !!placeOfBirth && !!nationality && !!nationalIdNumber.trim();
if (active === 1) return !!mobile.trim() && !!email.trim() && !!region && !!city.trim();
if (active === 2) return !!files.nationalId && !!files.photo;
return true;
@@ -353,9 +355,9 @@ export function SeafarerRegistrationPage() {
<Stack gap="md">
<SectionHead title="Identity Details" />
<SimpleGrid cols={{ base: 1, sm: 2, lg: 3 }} spacing="md">
<TextInput label="First Name" placeholder="First name" required value={firstName} onChange={(e) => setFirstName(e.currentTarget.value)} />
<TextInput label="Middle Name" placeholder="Middle name" value={middleName} onChange={(e) => setMiddleName(e.currentTarget.value)} />
<TextInput label="Last Name" placeholder="Last name" required value={lastName} onChange={(e) => setLastName(e.currentTarget.value)} />
<BilingualInput label="First Name" required value={firstName} onChange={setFirstName} />
<BilingualInput label="Middle Name" value={middleName} onChange={setMiddleName} />
<BilingualInput label="Last Name" required value={lastName} onChange={setLastName} />
<Select label="Gender" placeholder="Select" required data={GENDERS} value={gender} onChange={setGender} />
<TextInput label="Date of Birth" type="date" required value={dob} onChange={(e) => setDob(e.currentTarget.value)} />
<TextInput label="Place of Birth" placeholder="City, Region" required value={placeOfBirth} onChange={(e) => setPlaceOfBirth(e.currentTarget.value)} />
@@ -449,9 +451,9 @@ export function SeafarerRegistrationPage() {
<Paper withBorder radius="md" p="md">
<Text fw={700} fz="sm" mb="sm">Personal Information</Text>
<SimpleGrid cols={{ base: 1, sm: 2, lg: 3 }} spacing="md">
<ReviewRow label="First Name" value={firstName} />
<ReviewRow label="Middle Name" value={middleName} />
<ReviewRow label="Last Name" value={lastName} />
<ReviewRow label="First Name" value={`${firstName.en}${firstName.am ? ` / ${firstName.am}` : ''}`} />
<ReviewRow label="Middle Name" value={`${middleName.en}${middleName.am ? ` / ${middleName.am}` : ''}`} />
<ReviewRow label="Last Name" value={`${lastName.en}${lastName.am ? ` / ${lastName.am}` : ''}`} />
<ReviewRow label="Gender" value={gender ?? ''} />
<ReviewRow label="Date of Birth" value={dob} />
<ReviewRow label="Place of Birth" value={placeOfBirth} />