1 import type { Ref } from 'react';
2 import { forwardRef } from 'react';
4 import { c } from 'ttag';
6 import ErrorZone from '@proton/components/components/text/ErrorZone';
7 import { isFirstLastNameValid } from '@proton/shared/lib/contacts/property';
8 import type { VCardContact, VCardProperty, VcardNValue } from '@proton/shared/lib/interfaces/contacts/VCard';
10 import ContactFieldString from './ContactFieldString';
13 vCardContact: VCardContact;
14 vCardProperty: VCardProperty<VcardNValue>;
16 onChangeVCard: (vCardProperty: VCardProperty<VcardNValue>) => void;
24 const ContactFieldN = (
25 { vCardContact, vCardProperty, isSubmitted, onChangeVCard, ...rest }: Props,
26 firstNameFieldRef: Ref<HTMLInputElement>
28 const givenName = vCardProperty.value.givenNames[0] || '';
29 const familyName = vCardProperty.value.familyNames[0] || '';
31 // The N field is an array where the first element is the family name and the second element is the given name.
32 const handleChange = (change: VCardProperty, pos: FieldsPos) => {
33 const { value } = change;
34 const newValue = { ...vCardProperty.value };
35 if (pos === FieldsPos.familyName) {
36 newValue.familyNames[0] = value;
38 newValue.givenNames[0] = value;
41 onChangeVCard({ ...vCardProperty, field: 'n', value: newValue });
44 const givenNameTooLong = !isFirstLastNameValid(givenName);
45 const familyNameTooLong = !isFirstLastNameValid(familyName);
46 const requiredError = !vCardContact.fn?.[0].value && isSubmitted && !givenName && !familyName;
49 <div className="flex flex-column md:flex-row gap-2">
50 <div className="md:flex-1">
52 ref={firstNameFieldRef}
53 placeholder={c('Placeholder').t`First name`}
54 data-testid="First name"
55 vCardProperty={{ ...vCardProperty, field: 'givenName', value: givenName }}
56 onChange={(change) => handleChange(change, FieldsPos.givenName)}
57 error={requiredError || givenNameTooLong}
60 {givenNameTooLong ? <ErrorZone>{c('Error').t`First name is too long`}</ErrorZone> : null}
62 <div className="md:flex-1">
64 placeholder={c('Placeholder').t`Last name`}
65 data-testid="Last name"
66 vCardProperty={{ ...vCardProperty, field: 'familyName', value: familyName }}
67 onChange={(change) => handleChange(change, FieldsPos.familyName)}
68 error={requiredError || familyNameTooLong}
71 {familyNameTooLong ? <ErrorZone>{c('Error').t`Last name is too long`}</ErrorZone> : null}
77 export default forwardRef(ContactFieldN);