1 import type { FormEvent } from 'react';
2 import { useState } from 'react';
4 import { c } from 'ttag';
6 import { changeOrganizationSignature } from '@proton/account';
7 import { getIsEligibleOrganizationIdentityAddress } from '@proton/account/organizationKey/actions';
8 import { Button } from '@proton/atoms';
9 import type { ModalProps } from '@proton/components';
13 ModalTwoContent as ModalContent,
14 ModalTwoFooter as ModalFooter,
15 ModalTwoHeader as ModalHeader,
18 } from '@proton/components';
19 import SettingsLink from '@proton/components/components/link/SettingsLink';
20 import Option from '@proton/components/components/option/Option';
21 import { useAddresses, useErrorHandler, useNotifications } from '@proton/components/hooks';
22 import useLoading from '@proton/hooks/useLoading';
23 import { useDispatch } from '@proton/redux-shared-store';
24 import { getIsAddressConfirmed } from '@proton/shared/lib/helpers/address';
25 import { requiredValidator } from '@proton/shared/lib/helpers/formValidators';
27 interface Props extends ModalProps<'div'> {
28 signatureAddress?: string;
31 const EditOrganizationIdentityModal = ({ signatureAddress: initialSignatureAddress, ...rest }: Props) => {
32 const [submitting, withSubmitting] = useLoading();
33 const [addresses] = useAddresses();
34 const { validator, onFormSubmit } = useFormErrors();
35 const eligibleAddresses = (addresses || []).filter(getIsEligibleOrganizationIdentityAddress);
36 const [addressID, setAddressID] = useState<string | null>(() => {
37 return eligibleAddresses.find((address) => address.Email === initialSignatureAddress)?.ID || null;
39 const dispatch = useDispatch();
40 const errorHandler = useErrorHandler();
41 const { createNotification } = useNotifications();
43 const handleSubmit = async (event: FormEvent) => {
44 event.preventDefault();
45 event.stopPropagation();
46 if (!onFormSubmit()) {
50 const address = addresses?.find((address) => address.ID === addressID);
52 const handleSubmit = async () => {
53 await dispatch(changeOrganizationSignature({ address }));
54 createNotification({ text: c('orgidentity').t`Organization identity updated` });
57 withSubmitting(handleSubmit()).catch(errorHandler);
62 <Modal as="form" size="small" {...rest} onSubmit={handleSubmit}>
63 <ModalHeader title={c('orgidentity').t`Edit organization identity`} />
65 {initialSignatureAddress && (
66 <div className="mb-6">
67 <div className="text-semibold mb-1">{c('orgidentity').t`Current organization identity`}</div>
68 <div className="text-ellipsis" title={initialSignatureAddress}>
69 {initialSignatureAddress}
74 if (!eligibleAddresses.length) {
75 const primaryAddress = addresses?.[0];
76 if (!initialSignatureAddress && primaryAddress && !getIsAddressConfirmed(primaryAddress)) {
78 <SettingsLink path="/account-password" key="verify">
79 {c('orgidentity').t`Verify`}
82 const email = <strong key="email">({primaryAddress.Email})</strong>;
84 <div className="text-break">
86 .jt`${verify} your email address ${email} to set organization identity.`}
94 id="organizationIdentity"
95 as={SelectTwo<string | null>}
96 error={validator([requiredValidator(addressID)])}
98 onValue={(addressID: string | null) => {
100 setAddressID(addressID);
103 label={c('orgidentity').t`New organization identity`}
105 {eligibleAddresses.map((address) => (
106 <Option title={address.Email} key={address.ID} value={address.ID} />
113 <Button onClick={rest.onClose} disabled={submitting}>{c('Action').t`Cancel`}</Button>
114 <Button color="norm" type="submit" loading={submitting}>{c('Action').t`Save`}</Button>
120 export default EditOrganizationIdentityModal;